@@ -8,6 +8,9 @@ import StepModal from "components/StepModal";
88import { Search , TacoButton } from "lowcoder-design" ;
99import { Table } from "../../components/Table" ;
1010import { timestampToHumanReadable } from "../../util/dateTimeUtils" ;
11+ import { Avatar , Flex , Tooltip } from "antd" ;
12+ import { buildSupportTicketLink } from "constants/routesURL" ;
13+ import history from "util/history" ;
1114
1215const SupportWrapper = styled . div `
1316 display: flex;
@@ -45,6 +48,16 @@ const AddBtn = styled(TacoButton)`
4548 height: 32px;
4649` ;
4750
51+ const ReloadBtn = styled ( TacoButton ) `
52+ min-width: 96px;
53+ width: fit-content;
54+ height: 32px;
55+ ` ;
56+
57+ const EditBtn = styled ( TacoButton ) `
58+
59+ ` ;
60+
4861const BodyWrapper = styled . div `
4962 width: 100%;
5063 flex-grow: 1;
@@ -61,6 +74,15 @@ const SubColumnCell = styled.div`
6174 color: #8b8fa3;
6275` ;
6376
77+ const StatusDot = styled . span < { active : boolean } > `
78+ display: inline-block;
79+ margin-left: 14px;
80+ width: 8px;
81+ height: 8px;
82+ border-radius: 50%;
83+ background-color: ${ ( props ) => ( props . active ? "green" : "gray" ) } ;
84+ ` ;
85+
6486function formatDateToMinute ( dateString : string ) : string {
6587 // Create a Date object from the string
6688 const date = new Date ( dateString ) ;
@@ -76,6 +98,11 @@ function formatDateToMinute(dateString: string): string {
7698 return `${ year } -${ month } -${ day } ${ hour } :${ minute } ` ;
7799}
78100
101+ // Function to handle edit button click
102+ const handleEditClick = ( ticketId : string ) => {
103+ history . push ( buildSupportTicketLink ( ticketId ) ) ;
104+ } ;
105+
79106export function SupportOverview ( ) {
80107 const { orgID, currentUser, domain } = useUserDetails ( ) ;
81108 const [ supportTickets , setSupportTickets ] = useState < any > ( [ ] ) ;
@@ -84,19 +111,21 @@ export function SupportOverview() {
84111 const [ searchValue , setSearchValue ] = useState ( "" ) ;
85112 const [ isCreateFormShow , showCreateForm ] = useState ( false ) ;
86113
87- useEffect ( ( ) => {
88- const fetchSupportTickets = async ( ) => {
89- try {
90- const ticketData = await searchCustomerTickets ( orgID , currentUser . id , domain ) ;
91- setSupportTickets ( ticketData ) ;
92- } catch ( err ) {
93- setError ( "Failed to fetch support tickets." ) ;
94- console . error ( err ) ;
95- } finally {
96- setLoading ( false ) ;
97- }
98- } ;
114+ // Function to fetch support tickets
115+ const fetchSupportTickets = async ( ) => {
116+ setLoading ( true ) ; // Set loading to true while fetching data
117+ try {
118+ const ticketData = await searchCustomerTickets ( orgID , currentUser . id , domain ) ;
119+ setSupportTickets ( ticketData ) ;
120+ } catch ( err ) {
121+ setError ( "Failed to fetch support tickets." ) ;
122+ console . error ( err ) ;
123+ } finally {
124+ setLoading ( false ) ; // Set loading to false after fetching data
125+ }
126+ } ;
99127
128+ useEffect ( ( ) => {
100129 fetchSupportTickets ( ) ;
101130 } , [ orgID , currentUser . id , domain ] ) ;
102131
@@ -112,7 +141,7 @@ export function SupportOverview() {
112141
113142 return (
114143 < >
115- < Helmet > < title > { trans ( "home .supportTitle" ) } </ title > </ Helmet >
144+ < Helmet > < title > { trans ( "support .supportTitle" ) } </ title > </ Helmet >
116145 < SupportWrapper >
117146
118147 < StepModal
@@ -135,56 +164,70 @@ export function SupportOverview() {
135164 ] } />
136165
137166 < HeaderWrapper >
138- < Title > { trans ( "home.supportTickets" ) } </ Title >
139- < Search
140- placeholder = { trans ( "search" ) }
141- value = { searchValue }
142- onChange = { ( e ) => setSearchValue ( e . target . value ) }
143- style = { { width : "192px" , height : "32px" , margin : "0 12px 0 0" } } />
144- < AddBtn buttonType = { "primary" } onClick = { ( ) => showCreateForm ( true ) } >
145- { trans ( "home.newSupportTicket" ) }
146- </ AddBtn >
167+ < Title > { trans ( "support.supportTitle" ) } </ Title >
168+ < Flex gap = "12px" >
169+ < Search
170+ placeholder = { trans ( "search" ) }
171+ value = { searchValue }
172+ onChange = { ( e ) => setSearchValue ( e . target . value ) }
173+ style = { { width : "192px" , height : "32px" , margin : "0 12px 0 0" } } />
174+ < AddBtn buttonType = { "primary" } onClick = { ( ) => showCreateForm ( true ) } >
175+ { trans ( "support.newSupportTicket" ) }
176+ </ AddBtn >
177+ < ReloadBtn buttonType = { "normal" } onClick = { ( ) => fetchSupportTickets ( ) } >
178+ { trans ( "support.reloadTickets" ) }
179+ </ ReloadBtn >
180+ </ Flex >
147181 </ HeaderWrapper >
148182 < BodyWrapper >
149- { ! loading ? (
150183 < StyledTable
184+ loading = { loading }
151185 rowClassName = "datasource-can-not-edit"
152186 tableLayout = { "auto" }
153187 scroll = { { x : "100%" } }
154188 pagination = { false }
155189 columns = { [
156190 {
157- title : trans ( "home .ticketTitle" ) ,
191+ title : trans ( "support .ticketTitle" ) ,
158192 dataIndex : "title" ,
159193 ellipsis : true ,
160194 sorter : ( a : any , b : any ) => a . title . localeCompare ( b . title ) ,
161195 } ,
162196 {
163- title : trans ( "home .priority" ) ,
197+ title : trans ( "support .priority" ) ,
164198 dataIndex : "priority" ,
165199 ellipsis : true ,
166200 width : "192px" ,
167201 sorter : ( a : any , b : any ) => a . priority . name . localeCompare ( b . priority . name ) ,
168202 render : ( priority : any ) => < SubColumnCell > { priority . name } </ SubColumnCell > ,
169203 } ,
170204 {
171- title : trans ( "home .assignee" ) ,
205+ title : trans ( "support .assignee" ) ,
172206 dataIndex : "assignee" ,
173207 ellipsis : true ,
174208 width : "192px" ,
175- sorter : ( a : any , b : any ) => a . assignee . email . localeCompare ( b . assignee . email ) ,
176- render : ( assignee : any ) => < SubColumnCell > { assignee . email } </ SubColumnCell > ,
209+ render : ( assignee : any ) => (
210+ < SubColumnCell >
211+ < Tooltip title = { "Support Member is active in: " +
212+ assignee . timeZone + ", " +
213+ ( assignee . email || trans ( "support.noEmail" ) )
214+ } >
215+ < Avatar src = { assignee . avatar } alt = { assignee . email } />
216+ </ Tooltip >
217+ < StatusDot active = { assignee . active } />
218+ </ SubColumnCell >
219+ ) ,
177220 } ,
178221 {
179- title : trans ( "home .status" ) ,
222+ title : trans ( "support .status" ) ,
180223 dataIndex : "status" ,
181224 ellipsis : true ,
182- width : "192px " ,
225+ width : "220px " ,
183226 sorter : ( a : any , b : any ) => a . status . name . localeCompare ( b . status . name ) ,
184227 render : ( status : any ) => < SubColumnCell > { status . name } </ SubColumnCell > ,
185228 } ,
186229 {
187- title : trans ( "home .updatedTime" ) ,
230+ title : trans ( "support .updatedTime" ) ,
188231 dataIndex : "updated" ,
189232 ellipsis : true ,
190233 width : "192px" ,
@@ -195,6 +238,19 @@ export function SupportOverview() {
195238 </ SubColumnCell >
196239 ) ,
197240 } ,
241+ {
242+ title : trans ( "support.details" ) ,
243+ dataIndex : "actions" ,
244+ width : "120px" ,
245+ render : ( key : string ) => (
246+ < EditBtn
247+ buttonType = { "normal" }
248+ onClick = { ( ) => handleEditClick ( key ) }
249+ >
250+ { trans ( "support.details" ) }
251+ </ EditBtn >
252+ ) ,
253+ } ,
198254 ] }
199255 dataSource = { filteredTickets . map ( ( ticket : any , index : number ) => ( {
200256 key : index ,
@@ -203,11 +259,9 @@ export function SupportOverview() {
203259 assignee : ticket . assignee ,
204260 status : ticket . status ,
205261 updated : ticket . updated ,
262+ actions : ticket . key ,
206263 } ) ) }
207264 />
208- ) : (
209- < div > Loading...</ div >
210- ) }
211265 { error && < div > Error: { error } </ div > }
212266 </ BodyWrapper >
213267 </ SupportWrapper >
0 commit comments