@asaleh37/ui-base 1.2.29 → 25.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/.github/workflows/publish-npm.yml +49 -0
  2. package/README.md +51 -51
  3. package/__ODockerfile +14 -0
  4. package/dist/index.d.ts +101 -10
  5. package/dist/index.js +135 -7
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +135 -7
  8. package/dist/index.mjs.map +1 -1
  9. package/eslint.config.js +29 -29
  10. package/index.html +20 -13
  11. package/package-lock.json/342/200/216 +9040 -0
  12. package/package.json +122 -119
  13. package/public/bg.jpg +0 -0
  14. package/public/ezzsteel.png +0 -0
  15. package/public/logo.png +0 -0
  16. package/public/manifest.json +21 -0
  17. package/public/no_user.png +0 -0
  18. package/rollup.config-1748377725725.cjs +34 -34
  19. package/rollup.config.js +45 -45
  20. package/src/components/App.tsx +155 -123
  21. package/src/components/BaseApp.tsx +75 -53
  22. package/src/components/ExampleTrial.tsx +24 -0
  23. package/src/components/administration/admin/ChangePasswordPanel.tsx +128 -0
  24. package/src/components/administration/admin/CustomPersonGrid.tsx +361 -0
  25. package/src/components/administration/admin/OrgMemberRoleForm.tsx +83 -83
  26. package/src/components/administration/admin/OrgProvidedPersonGrid.tsx +347 -0
  27. package/src/components/administration/admin/OrganizationApplicationModuleGrid.tsx +107 -107
  28. package/src/components/administration/admin/OrganizationGrid.tsx +118 -82
  29. package/src/components/administration/admin/OrganizationMemberGrid.tsx +190 -176
  30. package/src/components/administration/admin/OrganizationMemberRoleGrid.tsx +87 -87
  31. package/src/components/administration/admin/OrganizationRankGrid.tsx +133 -133
  32. package/src/components/administration/admin/OrganizationUnitGrid.tsx +143 -143
  33. package/src/components/administration/admin/OrganizationUnitTypeGrid.tsx +108 -108
  34. package/src/components/administration/admin/PersonGrid.tsx +27 -231
  35. package/src/components/administration/admin/RoleAuthoritiesForm.tsx +82 -82
  36. package/src/components/administration/admin/SystemApplicationAuthorityGrid.tsx +117 -126
  37. package/src/components/administration/admin/SystemApplicationGrid.tsx +83 -83
  38. package/src/components/administration/admin/SystemApplicationModuleGrid.tsx +96 -96
  39. package/src/components/administration/admin/SystemApplicationRoleAuthorityGrid.tsx +75 -67
  40. package/src/components/administration/admin/SystemApplicationRoleGrid.tsx +116 -116
  41. package/src/components/administration/dev/AttachmentConfigGrid.tsx +224 -213
  42. package/src/components/administration/dev/AttachmentGrid.tsx +172 -172
  43. package/src/components/administration/dev/BluePrintGrid.tsx +129 -129
  44. package/src/components/administration/dev/DashboardGrid.tsx +173 -173
  45. package/src/components/administration/dev/DashboardWidgetGrid.tsx +164 -164
  46. package/src/components/administration/dev/DataQueryGrid.tsx +216 -206
  47. package/src/components/administration/dev/DataQueryParameterGrid.tsx +191 -191
  48. package/src/components/administration/dev/DataQueryParametersForm.tsx +84 -84
  49. package/src/components/administration/dev/DatasourceConnectionGrid.tsx +151 -150
  50. package/src/components/administration/dev/EntityParameterGrid.tsx +307 -279
  51. package/src/components/administration/dev/LookupGrid.tsx +120 -120
  52. package/src/components/administration/dev/MailAttachmentGrid.tsx +155 -155
  53. package/src/components/administration/dev/MailBodyGrid.tsx +216 -216
  54. package/src/components/administration/dev/MailNotificationQueueGrid.tsx +245 -245
  55. package/src/components/administration/dev/MailRecipientGrid.tsx +170 -169
  56. package/src/components/administration/dev/MailSenderConfigGrid.tsx +480 -478
  57. package/src/components/administration/dev/MailTemplateGrid.tsx +385 -384
  58. package/src/components/administration/dev/NotificationGrid.tsx +435 -432
  59. package/src/components/administration/dev/NotificationQueueGrid.tsx +222 -222
  60. package/src/components/administration/dev/ReportGrid.tsx +503 -504
  61. package/src/components/administration/dev/ReportParameterGrid.tsx +186 -186
  62. package/src/components/administration/dev/ReportParametersForm.tsx +84 -84
  63. package/src/components/administration/dev/WidgetGrid.tsx +380 -431
  64. package/src/components/administration/dev/WorkflowDocumentActionGrid.tsx +264 -264
  65. package/src/components/administration/dev/WorkflowDocumentActionHistoryGrid.tsx +172 -172
  66. package/src/components/administration/dev/WorkflowDocumentActionMailGrid.tsx +161 -161
  67. package/src/components/administration/dev/WorkflowDocumentGrid.tsx +357 -377
  68. package/src/components/administration/dev/WorkflowDocumentMailLogGrid.tsx +218 -218
  69. package/src/components/administration/dev/WorkflowDocumentStatusGrid.tsx +243 -243
  70. package/src/components/common/AzureLogin.tsx +222 -0
  71. package/src/components/common/ChangeOrgForm.tsx +85 -81
  72. package/src/components/common/Home.tsx +43 -44
  73. package/src/components/common/LanguageSwitcher.tsx +25 -25
  74. package/src/components/common/LayoutHandlers.tsx +11 -11
  75. package/src/components/common/LoadingMask.tsx +24 -24
  76. package/src/components/common/Login.tsx +268 -214
  77. package/src/components/common/MobileLogin.tsx +229 -0
  78. package/src/components/common/MyNotificationsPanel.tsx +109 -104
  79. package/src/components/common/NoLicenseComponent.tsx +79 -0
  80. package/src/components/common/NotificationItem.tsx +138 -138
  81. package/src/components/index.ts +10 -9
  82. package/src/components/msalConfig.ts +11 -0
  83. package/src/components/templates/DataEntryTemplates/DataEntryTypes.ts +361 -324
  84. package/src/components/templates/DataEntryTemplates/DataEntryUtil.ts +297 -248
  85. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormAction.tsx +60 -60
  86. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormElementField.tsx +238 -231
  87. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormElementGroup.tsx +108 -106
  88. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/CheckBox.tsx +66 -64
  89. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/ComboBox.tsx +164 -93
  90. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/Datefield.tsx +70 -65
  91. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/DatetimeField.tsx +71 -64
  92. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/FiltersPanel.tsx +237 -237
  93. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/SystemLookupCombobox.tsx +56 -55
  94. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/TemplateTextField.tsx +20 -17
  95. package/src/components/templates/DataEntryTemplates/TemplateDataForm/TemplateForm.tsx +431 -388
  96. package/src/components/templates/DataEntryTemplates/TemplateDataGrid/DataGridColumnsUtil.tsx +197 -189
  97. package/src/components/templates/DataEntryTemplates/TemplateDataGrid/TemplateGrid.tsx +1044 -998
  98. package/src/components/templates/DataEntryTemplates/TemplateDataGrid/TemplateGridMultiRecordAction.tsx +89 -89
  99. package/src/components/templates/DataEntryTemplates/TemplateDataGrid/TemplateGridRecordAction.tsx +95 -95
  100. package/src/components/templates/DataEntryTemplates/TemplateDataGrid/TemplateGridTopBar.tsx +234 -227
  101. package/src/components/templates/TransferList.tsx +256 -257
  102. package/src/components/templates/Window/ConfirmationWindow.tsx +55 -55
  103. package/src/components/templates/attachment/AttachmentCard.tsx +141 -141
  104. package/src/components/templates/attachment/AttachmentImageViewer.tsx +85 -45
  105. package/src/components/templates/attachment/AttachmentPanel.tsx +285 -271
  106. package/src/components/templates/index.ts +35 -33
  107. package/src/components/templates/report/ExcelReportViewer.tsx +71 -72
  108. package/src/components/templates/report/ReportViewer.tsx +272 -383
  109. package/src/components/templates/visuals/DashboardRouteView.tsx +9 -9
  110. package/src/components/templates/visuals/DashboardViewer.tsx +192 -148
  111. package/src/components/templates/visuals/WidgetViewer.tsx +208 -198
  112. package/src/components/templates/visuals/charts/TemplateBarChart.tsx +23 -23
  113. package/src/components/templates/visuals/charts/TemplateDataCard.tsx +35 -35
  114. package/src/components/templates/visuals/charts/TemplateGauge.tsx +21 -21
  115. package/src/components/templates/visuals/charts/TemplateLineChart.tsx +22 -22
  116. package/src/components/templates/visuals/charts/TemplateLineProgress.tsx +42 -42
  117. package/src/components/templates/visuals/charts/TemplatePieChart.tsx +24 -24
  118. package/src/components/templates/workflow/WorkflowDocumentPanel.tsx +611 -606
  119. package/src/components/templates/workflow/WorkflowDocumentTimeLine.tsx +145 -140
  120. package/src/components/templates/workflow/WorkflowRouteComponent.tsx +14 -14
  121. package/src/examples/ExampleGrid.tsx +134 -0
  122. package/src/hooks/UseConfirmationWindow.tsx +56 -54
  123. package/src/hooks/UseMobile.tsx +13 -13
  124. package/src/hooks/UseSession.tsx +59 -40
  125. package/src/hooks/UseWindow.tsx +111 -107
  126. package/src/hooks/index.ts +22 -7
  127. package/src/hooks/useApiActions.ts +124 -124
  128. package/src/hooks/useAxios.tsx +340 -316
  129. package/src/hooks/useCommonStore.tsx +29 -0
  130. package/src/hooks/useInterval.tsx +23 -23
  131. package/src/hooks/useLoadingMask.tsx +16 -16
  132. package/src/hooks/useLookupGridColumn.tsx +35 -35
  133. package/src/hooks/useParameterPanel.tsx +159 -0
  134. package/src/index.ts +4 -4
  135. package/src/layout/DrawerHeader.tsx +10 -10
  136. package/src/layout/Layout.tsx +102 -90
  137. package/src/layout/MainContent.tsx +115 -114
  138. package/src/layout/MobileDrawer.tsx +103 -103
  139. package/src/layout/NavigationTree.tsx +309 -291
  140. package/src/layout/NotificationButton.tsx +207 -207
  141. package/src/layout/RouteWrapper.tsx +63 -36
  142. package/src/layout/SideBar.tsx +85 -85
  143. package/src/layout/TopBar.tsx +317 -217
  144. package/src/locales/arabic/adminLocalsAr.json +94 -93
  145. package/src/locales/arabic/common.json +44 -44
  146. package/src/locales/arabic/devLocalsAr.json +317 -317
  147. package/src/locales/arabic/index.ts +9 -9
  148. package/src/locales/english/adminLocalsEn.json +97 -96
  149. package/src/locales/english/common.json +43 -43
  150. package/src/locales/english/devLocalsEn.json +318 -318
  151. package/src/locales/english/index.ts +9 -9
  152. package/src/locales/i18n.ts +8 -8
  153. package/src/locales/index.ts +9 -9
  154. package/src/main.tsx +41 -23
  155. package/src/navigationItems/Administration/adminNavigationItems.tsx +231 -222
  156. package/src/navigationItems/Administration/index.tsx +16 -16
  157. package/src/navigationItems/common/CommonNavigationItems.tsx +12 -12
  158. package/src/navigationItems/common/index.tsx +7 -7
  159. package/src/navigationItems/index.tsx +35 -34
  160. package/src/redux/features/administration/AdministrationStoresMetaData.ts +164 -126
  161. package/src/redux/features/common/AppInfoSlice.ts +93 -63
  162. package/src/redux/features/common/AppLayoutSlice.ts +29 -29
  163. package/src/redux/features/common/CommonStoreSlice.ts +44 -44
  164. package/src/redux/features/common/LoadingMaskSlice.ts +30 -30
  165. package/src/redux/features/common/SideBarSlice.ts +27 -27
  166. package/src/redux/features/common/UserSessionSlice.ts +54 -54
  167. package/src/redux/store.ts +29 -29
  168. package/src/routes/administration/adminRoutes.tsx +99 -99
  169. package/src/routes/administration/devRoutes.tsx +129 -129
  170. package/src/routes/administration/index.ts +8 -8
  171. package/src/routes/index.ts +5 -11
  172. package/src/routes/types/index.ts +6 -5
  173. package/src/styles/index.css +19 -19
  174. package/src/types/index.ts +8 -2
  175. package/src/util/AppUtils.ts +73 -53
  176. package/src/util/constants.ts +6 -6
  177. package/src/util/index.ts +5 -2
  178. package/tsconfig.json +135 -135
  179. package/vite.config.ts +24 -23
@@ -1,606 +1,611 @@
1
- import { useEffect, useState } from "react";
2
- import { useAxios, useSession, useWindow } from "../../../hooks";
3
- import {
4
- Avatar,
5
- Box,
6
- Button,
7
- Divider,
8
- Grid2,
9
- IconButton,
10
- Paper,
11
- } from "@mui/material";
12
- import TemplateTextField from "../DataEntryTemplates/TemplateDataForm/FormFields/TemplateTextField";
13
- import ComboBox from "../DataEntryTemplates/TemplateDataForm/FormFields/ComboBox";
14
- import { useSelector } from "react-redux";
15
- import { useTranslation } from "react-i18next";
16
- import WorkflowDocumentTimeLine from "./WorkflowDocumentTimeLine";
17
- import { toast } from "react-toastify";
18
- import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
19
- import ReportViewer from "../report/ReportViewer";
20
- import AttachmentImageViewer from "../attachment/AttachmentImageViewer";
21
- import { useNavigate } from "react-router-dom";
22
-
23
- export type WorkflowDocumentPanelProps = {
24
- workFlowDocumentCode: string;
25
- refDocumentId: any;
26
- postActionCallBk?: () => void;
27
- cancelActionCallBk?: () => void;
28
- };
29
-
30
- export type workflowDocumentAction = {
31
- id: number;
32
- document_action_code: string;
33
- document_action_ar_name: string;
34
- document_action_en_name: string;
35
- post_action_endpoint?: string;
36
- pre_action_endpoint?: string;
37
- next_document_status_id?: number;
38
- next_action_takers?: Array<person>;
39
- require_comment: any;
40
- };
41
-
42
- export type person = {
43
- id: number;
44
- email: string;
45
- employeeArName: string;
46
- employeeEnName: string;
47
- mobileNumber: string;
48
- username: string;
49
- };
50
-
51
- export type workflowDocumentActionHistory = {
52
- id: number;
53
- actionTime: string;
54
- actionMethod: string;
55
- actionComment: string;
56
- documentActionArName: string;
57
- documentActionEnName: string;
58
- employeeArName: string;
59
- employeeEnName: string;
60
- personId: number;
61
- };
62
-
63
- type WorkflowDocumentInfo = {
64
- workflowDocument: any;
65
- referencedDocument: any;
66
- workflowDocumentReport: any;
67
- workflowDocumentStatus: any;
68
- actionsHistory: Array<workflowDocumentActionHistory>;
69
- nextActions: Array<workflowDocumentAction>;
70
- nextActionTakers: any;
71
- };
72
-
73
- const WorkflowDocumentPanel: React.FC<WorkflowDocumentPanelProps> = (props) => {
74
- const navigate = useNavigate();
75
- const AppLayout = useSelector((state: any) => state.AppLayout);
76
- const { isUserAuthorized, UserInfo } = useSession();
77
- const { handleGetRequest, handlePostRequest } = useAxios();
78
- const [action, setAction] = useState<workflowDocumentAction>(null);
79
- const [authorizedActions, setAuthorizedActions] = useState<
80
- Array<workflowDocumentAction>
81
- >([]);
82
- const { t } = useTranslation();
83
- const [actionComment, setActionComment] = useState(null);
84
- const [workflowDocumentInfo, setWorkflowDocumentInfo] =
85
- useState<WorkflowDocumentInfo>({
86
- referencedDocument: null,
87
- workflowDocumentReport: null,
88
- workflowDocument: null,
89
- workflowDocumentStatus: null,
90
- actionsHistory: [],
91
- nextActionTakers: null,
92
- nextActions: [],
93
- });
94
- const { Window: ReporTViewWindow, setWindowState: setReportViewWindowState } =
95
- useWindow({
96
- windowTitle:
97
- AppLayout.appDirection === "ltr"
98
- ? workflowDocumentInfo?.workflowDocument &&
99
- workflowDocumentInfo?.referencedDocument
100
- ? `${workflowDocumentInfo?.workflowDocument?.documentEnName} # ${
101
- workflowDocumentInfo?.referencedDocument[
102
- workflowDocumentInfo?.workflowDocument?.documentNumberField
103
- ]
104
- }`
105
- : "Document"
106
- : workflowDocumentInfo?.workflowDocument &&
107
- workflowDocumentInfo?.referencedDocument
108
- ? `${workflowDocumentInfo?.workflowDocument?.documentArName} # ${
109
- workflowDocumentInfo?.referencedDocument[
110
- workflowDocumentInfo?.workflowDocument?.documentNumberField
111
- ]
112
- }`
113
- : "وثيقة",
114
- windowIcon: "eye",
115
- width: "80%",
116
- });
117
- const loadWorkFlowDocumentInfo = async () => {
118
- await handleGetRequest({
119
- endPointURI: "api/v1/public/workflow/doc/info",
120
- showMask: true,
121
- parameters: {
122
- workflowDocumentCode: props.workFlowDocumentCode,
123
- refDocumentId: props.refDocumentId,
124
- },
125
- successCallBkFn: (response: any) => {
126
- setWorkflowDocumentInfo(response.data);
127
- },
128
- failureCallBkFn: () => {
129
- setWorkflowDocumentInfo({
130
- referencedDocument: null,
131
- workflowDocumentReport: null,
132
- workflowDocument: null,
133
- workflowDocumentStatus: null,
134
- actionsHistory: [],
135
- nextActions: [],
136
- nextActionTakers: null,
137
- });
138
- },
139
- });
140
- };
141
-
142
- const validateBeforeProcessWorkflowDocumentAction = async () => {
143
- if (
144
- action === undefined ||
145
- action === null ||
146
- action?.id === undefined ||
147
- action?.id === null
148
- ) {
149
- toast.error("You must select action to process");
150
- return;
151
- }
152
- if (
153
- (action.require_comment === true ||
154
- action.require_comment === 1 ||
155
- action.require_comment === "true") &&
156
- (actionComment === null || actionComment === "")
157
- ) {
158
- toast.error("You must enter comment for the action to be processed");
159
- return;
160
- }
161
- if (action?.pre_action_endpoint) {
162
- await handlePostRequest({
163
- endPointURI: action.pre_action_endpoint,
164
- showMask: true,
165
- loadingMessage: "Processing pre action validation ... please wait",
166
- parameters: {
167
- refDocumentId: props.refDocumentId,
168
- actionId: action.id,
169
- },
170
- successCallBkFn: () => {
171
- processWorkflowDocumentAction();
172
- },
173
- });
174
- return;
175
- }
176
- processWorkflowDocumentAction();
177
- };
178
- const processWorkflowDocumentAction = async () => {
179
- await handlePostRequest({
180
- endPointURI: "api/v1/public/workflow/doc/action",
181
- showMask: true,
182
- data: {
183
- workflowDocumentId: workflowDocumentInfo?.workflowDocument?.id,
184
- refDocumentId: props.refDocumentId,
185
- actionId: action.id,
186
- refDocumentStatus:
187
- workflowDocumentInfo?.workflowDocumentStatus?.documentStatusCode,
188
- actionComment: actionComment,
189
- },
190
- successCallBkFn: async (response) => {
191
- if (action?.post_action_endpoint) {
192
- await handlePostRequest({
193
- endPointURI: action.post_action_endpoint,
194
- showMask: true,
195
- loadingMessage: "Processing post action process ... please wait",
196
- parameters: {
197
- refDocumentId: props.refDocumentId,
198
- actionId: action.id,
199
- },
200
- successCallBkFn: () => {
201
- loadWorkFlowDocumentInfo();
202
- if (props?.postActionCallBk) {
203
- props.postActionCallBk();
204
- }
205
- },
206
- });
207
- return;
208
- }
209
- loadWorkFlowDocumentInfo();
210
- },
211
- });
212
- };
213
-
214
- const adjustAuthorizedActions = () => {
215
- if (workflowDocumentInfo?.nextActions?.length > 0) {
216
- setAuthorizedActions(
217
- workflowDocumentInfo.nextActions.filter((action) => {
218
- if (
219
- !(
220
- workflowDocumentInfo?.workflowDocumentStatus
221
- ?.nextActionTakersAuthority ||
222
- workflowDocumentInfo?.nextActionTakers
223
- )
224
- ) {
225
- return true;
226
- }
227
- if (
228
- workflowDocumentInfo?.workflowDocumentStatus
229
- ?.nextActionTakersAuthority
230
- ) {
231
- if (
232
- isUserAuthorized(
233
- workflowDocumentInfo.workflowDocumentStatus
234
- .nextActionTakersAuthority
235
- )
236
- ) {
237
- return true;
238
- }
239
- }
240
- if (workflowDocumentInfo?.nextActionTakers) {
241
- for (const actionTaker of workflowDocumentInfo.nextActionTakers) {
242
- if (
243
- UserInfo?.username === actionTaker?.username ||
244
- UserInfo?.username === actionTaker?.USERNAME
245
- ) {
246
- return true;
247
- }
248
- }
249
- }
250
- return false;
251
- })
252
- );
253
- } else {
254
- setAuthorizedActions([]);
255
- }
256
- };
257
-
258
- useEffect(() => {
259
- if (props.refDocumentId && props.workFlowDocumentCode) {
260
- loadWorkFlowDocumentInfo();
261
- }
262
- }, [props.refDocumentId, props.workFlowDocumentCode]);
263
-
264
- useEffect(() => {
265
- if (workflowDocumentInfo?.nextActions) {
266
- adjustAuthorizedActions();
267
- } else {
268
- setAuthorizedActions([]);
269
- }
270
- }, [workflowDocumentInfo.nextActions, workflowDocumentInfo.nextActionTakers]);
271
- return (
272
- <>
273
- {workflowDocumentInfo?.workflowDocumentReport?.id ? (
274
- <ReporTViewWindow>
275
- <ReportViewer
276
- reportCode={
277
- workflowDocumentInfo?.workflowDocumentReport?.reportCode
278
- }
279
- resultMode="App"
280
- byPassParameterEntry={true}
281
- reportParametersValues={{ doc_id: props.refDocumentId + "" }}
282
- />
283
- </ReporTViewWindow>
284
- ) : (
285
- <></>
286
- )}
287
-
288
- {workflowDocumentInfo?.workflowDocument ? (
289
- <Box
290
- sx={{
291
- width: "100%",
292
- textAlign: "center",
293
- fontSize: 20,
294
- fontWeight: "bold",
295
- display: "flex",
296
- alignItems: "center",
297
- justifyContent: "center",
298
- }}
299
- >
300
- <IconButton
301
- onClick={() => {
302
- navigate(-1, { replace: true });
303
- }}
304
- >
305
- <FontAwesomeIcon icon="arrow-left" />
306
- </IconButton>
307
- <Box sx={{ flex: 1 }}></Box>
308
- <FontAwesomeIcon
309
- icon="file"
310
- style={{ marginRight: 10, marginLeft: 10 }}
311
- />
312
- {AppLayout.appDirection === "ltr"
313
- ? `${workflowDocumentInfo?.workflowDocument?.documentEnName} # ${
314
- workflowDocumentInfo?.referencedDocument[
315
- workflowDocumentInfo?.workflowDocument?.documentNumberField
316
- ]
317
- }`
318
- : `${workflowDocumentInfo?.workflowDocument?.documentArName} # ${
319
- workflowDocumentInfo?.referencedDocument[
320
- workflowDocumentInfo?.workflowDocument?.documentNumberField
321
- ]
322
- }`}
323
- {workflowDocumentInfo?.workflowDocumentStatus
324
- ? AppLayout.appDirection === "ltr"
325
- ? ` ( ${workflowDocumentInfo?.workflowDocumentStatus?.documentStatusEnName} )`
326
- : ` ( ${workflowDocumentInfo?.workflowDocumentStatus?.documentStatusArName} )`
327
- : ""}
328
- <Box sx={{ flex: 1 }}></Box>
329
- {workflowDocumentInfo?.workflowDocumentReport?.id ? (
330
- <Button
331
- onClick={() => {
332
- setReportViewWindowState(true);
333
- }}
334
- variant="outlined"
335
- startIcon={<FontAwesomeIcon icon="eye" />}
336
- >
337
- {t("VIEW_LABEL")}
338
- </Button>
339
- ) : (
340
- <></>
341
- )}
342
- </Box>
343
- ) : (
344
- <></>
345
- )}
346
-
347
- <Box
348
- sx={{
349
- flex: 1,
350
- width: "100%",
351
- overflow: "hidden",
352
- display: "flex",
353
- // flexDirection: "column",
354
- }}
355
- >
356
- {authorizedActions?.length > 0 ? (
357
- <Paper
358
- sx={{
359
- padding: 2,
360
- display: "flex",
361
- flex: 1,
362
- margin: 1,
363
- flexDirection: "column",
364
- alignItems: "center",
365
- justifyContent: "flex-start",
366
- overflow: "hidden",
367
- }}
368
- >
369
- <ComboBox
370
- sx={{ marginBottom: 2, width: 400 }}
371
- label={t("WE_AVAILABLE_ACTIONS_LABEL")}
372
- displayField={
373
- AppLayout.appDirection === "ltr"
374
- ? "document_action_en_name"
375
- : "document_action_ar_name"
376
- }
377
- valueField={"id"}
378
- value={action?.id}
379
- options={authorizedActions}
380
- onChangeCallBack={(v, selectedRecord) => {
381
- setAction(selectedRecord);
382
- }}
383
- />
384
- {/* <ComboBox
385
- sx={{ marginBottom: 2, width: 400 }}
386
- label={t("WE_NEXT_APPROVER_LABEL")}
387
- displayField={
388
- AppLayout.appDirection === "ltr"
389
- ? "employeeEnName"
390
- : "employeeArName"
391
- }
392
- valueField={"id"}
393
- value={nextActionTaker?.id}
394
- options={action?.nextActionTakers || []}
395
- onChangeCallBack={(v, selectedRecord) => {
396
- setNextActionTaker(selectedRecord);
397
- }}
398
- /> */}
399
- <TemplateTextField
400
- sx={{ width: 400 }}
401
- rows={3}
402
- value={actionComment}
403
- onChange={(event) => {
404
- setActionComment(event.target.value);
405
- }}
406
- multiline={true}
407
- label={t("WF_COMMENT_LABEL")}
408
- />
409
- <Box
410
- sx={{
411
- display: "flex",
412
- alignItems: "center",
413
- justifyContent: "center",
414
- }}
415
- >
416
- <Button
417
- color="success"
418
- variant="contained"
419
- sx={{ width: 200, m: 1 }}
420
- onClick={validateBeforeProcessWorkflowDocumentAction}
421
- >
422
- {t("WF_TAKE_ACTION_BTN_LABEL")}
423
- </Button>
424
- {props?.cancelActionCallBk ? (
425
- <Button
426
- variant="contained"
427
- sx={{ width: 200, m: 1 }}
428
- color="error"
429
- onClick={() => {
430
- if (props?.cancelActionCallBk) {
431
- props.cancelActionCallBk();
432
- }
433
- }}
434
- >
435
- {t("WF_CANCEL_BTN_LABEL")}
436
- </Button>
437
- ) : (
438
- <></>
439
- )}
440
- </Box>
441
- {workflowDocumentInfo?.nextActionTakers &&
442
- workflowDocumentInfo.nextActionTakers.length > 0 ? (
443
- <>
444
- <Divider
445
- variant="fullWidth"
446
- flexItem
447
- sx={{ marginTop: 1, marginBottom: 1 }}
448
- >
449
- <Box
450
- sx={{
451
- width: "100%",
452
- display: "flex",
453
- alignItems: "center",
454
- justifyContent: "center",
455
- fontSize: 18,
456
- fontWeight: "bold",
457
- }}
458
- >
459
- <FontAwesomeIcon
460
- icon="users"
461
- style={{ marginRight: 10, marginLeft: 10 }}
462
- />{" "}
463
- {t("WF_WAITING_FOR_LABEL")}
464
- </Box>
465
- </Divider>
466
-
467
- <Box
468
- sx={{
469
- flex: 1,
470
- display: "flex",
471
- flexDirection: "column",
472
- alignItems: "center",
473
- overflow: "auto",
474
- padding: 1,
475
- width: "100%",
476
- }}
477
- >
478
- {workflowDocumentInfo.nextActionTakers.map(
479
- (nextActionTaker: any) => {
480
- return (
481
- <Box
482
- sx={{
483
- display: "flex",
484
- alignItems: "center",
485
- justifyContent: "center",
486
- border: "1px dotted black",
487
- width: 400,
488
- marginBottom: 2,
489
- padding: 2,
490
- }}
491
- >
492
- <AttachmentImageViewer
493
- showAsAvatar={true}
494
- attachmentCode="EMPLOYEE_PHOTOS"
495
- refKey={nextActionTaker?.id || "0"}
496
- style={{
497
- marginRight: 2,
498
- marginLeft: 2,
499
- width: 60,
500
- height: 60,
501
- }}
502
- />
503
- <Box
504
- sx={{
505
- flex: 2,
506
- display: "flex",
507
- flexDirection: "column",
508
- alignItems: "flex-start",
509
- justifyContent: "center",
510
- }}
511
- >
512
- <div>
513
- {AppLayout.appDirection === "ltr"
514
- ? nextActionTaker?.employee_en_name
515
- : nextActionTaker?.employee_ar_name}
516
- </div>
517
- <div>
518
- {nextActionTaker?.email ? (
519
- <>
520
- <FontAwesomeIcon
521
- icon="envelope"
522
- style={{ marginRight: 10, marginLeft: 10 }}
523
- />
524
- {nextActionTaker?.email}
525
- </>
526
- ) : (
527
- <></>
528
- )}
529
- </div>
530
- <div>
531
- {nextActionTaker?.mobile_number ? (
532
- <>
533
- <FontAwesomeIcon
534
- icon="mobile"
535
- style={{ marginRight: 10, marginLeft: 10 }}
536
- />
537
- {nextActionTaker?.mobile_number}
538
- </>
539
- ) : (
540
- <></>
541
- )}
542
- </div>
543
- </Box>
544
- </Box>
545
- );
546
- }
547
- )}
548
- </Box>
549
- </>
550
- ) : (
551
- <></>
552
- )}
553
- </Paper>
554
- ) : (
555
- <></>
556
- )}
557
- {workflowDocumentInfo?.actionsHistory.length > 0 ? (
558
- <WorkflowDocumentTimeLine
559
- actionHistory={workflowDocumentInfo.actionsHistory}
560
- />
561
- ) : (
562
- <Paper
563
- sx={{
564
- display: "flex",
565
- flexDirection: "column",
566
- flexGrow: 1,
567
- padding: 2,
568
- margin: 1,
569
- alignItems: "center",
570
- justifyContent: "center",
571
- }}
572
- >
573
- <Box
574
- sx={{
575
- width: "100%",
576
- display: "flex",
577
- alignItems: "center",
578
- justifyContent: "center",
579
- fontSize: 18,
580
- fontWeight: "bold",
581
- }}
582
- >
583
- <FontAwesomeIcon
584
- icon="history"
585
- style={{ marginRight: 10, marginLeft: 10 }}
586
- />
587
- {t("WF_ACTION_HISTORY_LABEL")}
588
- </Box>
589
- <Box
590
- sx={{
591
- flex: 1,
592
- display: "flex",
593
- alignItems: "center",
594
- justifyContent: "center",
595
- }}
596
- >
597
- No Action Log available
598
- </Box>
599
- </Paper>
600
- )}
601
- </Box>
602
- </>
603
- );
604
- };
605
-
606
- export default WorkflowDocumentPanel;
1
+ import { useEffect, useState } from "react";
2
+ import { useAxios, useSession, useWindow } from "../../../hooks";
3
+ import {
4
+ Avatar,
5
+ Box,
6
+ Button,
7
+ Divider,
8
+ Grid2,
9
+ IconButton,
10
+ Paper,
11
+ } from "@mui/material";
12
+ import TemplateTextField from "../DataEntryTemplates/TemplateDataForm/FormFields/TemplateTextField";
13
+ import ComboBox from "../DataEntryTemplates/TemplateDataForm/FormFields/ComboBox";
14
+ import { useSelector } from "react-redux";
15
+ import { useTranslation } from "react-i18next";
16
+ import WorkflowDocumentTimeLine from "./WorkflowDocumentTimeLine";
17
+ import { toast } from "react-toastify";
18
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
19
+ import ReportViewer from "../report/ReportViewer";
20
+ import AttachmentImageViewer from "../attachment/AttachmentImageViewer";
21
+ import { useNavigate } from "react-router-dom";
22
+
23
+ export type WorkflowDocumentPanelProps = {
24
+ workFlowDocumentCode: string;
25
+ refDocumentId: any;
26
+ postActionCallBk?: () => void;
27
+ cancelActionCallBk?: () => void;
28
+ };
29
+
30
+ export type workflowDocumentAction = {
31
+ id: number;
32
+ document_action_code: string;
33
+ document_action_ar_name: string;
34
+ document_action_en_name: string;
35
+ post_action_endpoint?: string;
36
+ pre_action_endpoint?: string;
37
+ next_document_status_id?: number;
38
+ next_action_takers?: Array<person>;
39
+ require_comment: any;
40
+ };
41
+
42
+ export type person = {
43
+ id: number;
44
+ email: string;
45
+ employeeArName: string;
46
+ employeeEnName: string;
47
+ mobileNumber: string;
48
+ username: string;
49
+ };
50
+
51
+ export type workflowDocumentActionHistory = {
52
+ id: number;
53
+ actionTime: string;
54
+ actionMethod: string;
55
+ actionComment: string;
56
+ documentActionArName: string;
57
+ documentActionEnName: string;
58
+ employeeArName: string;
59
+ employeeEnName: string;
60
+ personId: number;
61
+ };
62
+
63
+ type WorkflowDocumentInfo = {
64
+ workflowDocument: any;
65
+ referencedDocument: any;
66
+ workflowDocumentReport: any;
67
+ workflowDocumentStatus: any;
68
+ actionsHistory: Array<workflowDocumentActionHistory>;
69
+ nextActions: Array<workflowDocumentAction>;
70
+ nextActionTakers: any;
71
+ };
72
+
73
+ const WorkflowDocumentPanel: React.FC<WorkflowDocumentPanelProps> = (props) => {
74
+ const navigate = useNavigate();
75
+ const AppLayout = useSelector((state: any) => state.AppLayout);
76
+ const { isUserAuthorized, UserInfo } = useSession();
77
+ const { handleGetRequest, handlePostRequest } = useAxios();
78
+ const [action, setAction] = useState<workflowDocumentAction>(null);
79
+ const [authorizedActions, setAuthorizedActions] = useState<
80
+ Array<workflowDocumentAction>
81
+ >([]);
82
+ const { t } = useTranslation();
83
+ const [actionComment, setActionComment] = useState(null);
84
+ const [workflowDocumentInfo, setWorkflowDocumentInfo] =
85
+ useState<WorkflowDocumentInfo>({
86
+ referencedDocument: null,
87
+ workflowDocumentReport: null,
88
+ workflowDocument: null,
89
+ workflowDocumentStatus: null,
90
+ actionsHistory: [],
91
+ nextActionTakers: null,
92
+ nextActions: [],
93
+ });
94
+ const { Window: ReporTViewWindow, setWindowState: setReportViewWindowState } =
95
+ useWindow({
96
+ windowTitle:
97
+ AppLayout.appDirection === "ltr"
98
+ ? workflowDocumentInfo?.workflowDocument &&
99
+ workflowDocumentInfo?.referencedDocument
100
+ ? `${workflowDocumentInfo?.workflowDocument?.documentEnName} # ${
101
+ workflowDocumentInfo?.referencedDocument[
102
+ workflowDocumentInfo?.workflowDocument?.documentNumberField
103
+ ]
104
+ }`
105
+ : "Document"
106
+ : workflowDocumentInfo?.workflowDocument &&
107
+ workflowDocumentInfo?.referencedDocument
108
+ ? `${workflowDocumentInfo?.workflowDocument?.documentArName} # ${
109
+ workflowDocumentInfo?.referencedDocument[
110
+ workflowDocumentInfo?.workflowDocument?.documentNumberField
111
+ ]
112
+ }`
113
+ : "وثيقة",
114
+ windowIcon: "eye",
115
+ width: "80%",
116
+ });
117
+ const loadWorkFlowDocumentInfo = async () => {
118
+ await handleGetRequest({
119
+ endPointURI: "api/v1/public/workflow/doc/info",
120
+ showMask: true,
121
+ parameters: {
122
+ workflowDocumentCode: props.workFlowDocumentCode,
123
+ refDocumentId: props.refDocumentId,
124
+ },
125
+ successCallBkFn: (response: any) => {
126
+ setWorkflowDocumentInfo(structuredClone(response.data));
127
+ },
128
+ failureCallBkFn: () => {
129
+ setWorkflowDocumentInfo({
130
+ referencedDocument: null,
131
+ workflowDocumentReport: null,
132
+ workflowDocument: null,
133
+ workflowDocumentStatus: null,
134
+ actionsHistory: [],
135
+ nextActions: [],
136
+ nextActionTakers: null,
137
+ });
138
+ },
139
+ });
140
+ };
141
+
142
+ const validateBeforeProcessWorkflowDocumentAction = async () => {
143
+ if (
144
+ action === undefined ||
145
+ action === null ||
146
+ action?.id === undefined ||
147
+ action?.id === null
148
+ ) {
149
+ toast.error("You must select action to process");
150
+ return;
151
+ }
152
+ if (
153
+ (action.require_comment === true ||
154
+ action.require_comment === 1 ||
155
+ action.require_comment === "true") &&
156
+ (actionComment === null || actionComment === "")
157
+ ) {
158
+ toast.error("You must enter comment for the action to be processed");
159
+ return;
160
+ }
161
+ if (action?.pre_action_endpoint) {
162
+ await handlePostRequest({
163
+ endPointURI: action.pre_action_endpoint,
164
+ showMask: true,
165
+ loadingMessage: "Processing pre action validation ... please wait",
166
+ parameters: {
167
+ refDocumentId: props.refDocumentId,
168
+ actionId: action.id,
169
+ },
170
+ successCallBkFn: () => {
171
+ processWorkflowDocumentAction();
172
+ },
173
+ });
174
+ return;
175
+ }
176
+ processWorkflowDocumentAction();
177
+ };
178
+ const processWorkflowDocumentAction = async () => {
179
+ await handlePostRequest({
180
+ endPointURI: "api/v1/public/workflow/doc/action",
181
+ showMask: true,
182
+ data: {
183
+ workflowDocumentId: workflowDocumentInfo?.workflowDocument?.id,
184
+ refDocumentId: props.refDocumentId,
185
+ actionId: action.id,
186
+ refDocumentStatus:
187
+ workflowDocumentInfo?.workflowDocumentStatus?.documentStatusCode,
188
+ actionComment: actionComment,
189
+ },
190
+ successCallBkFn: async (response) => {
191
+ if (action?.post_action_endpoint) {
192
+ await handlePostRequest({
193
+ endPointURI: action.post_action_endpoint,
194
+ showMask: true,
195
+ loadingMessage: "Processing post action process ... please wait",
196
+ parameters: {
197
+ refDocumentId: props.refDocumentId,
198
+ actionId: action.id,
199
+ },
200
+ successCallBkFn: () => {
201
+ loadWorkFlowDocumentInfo();
202
+ if (props?.postActionCallBk) {
203
+ props.postActionCallBk();
204
+ }
205
+ },
206
+ });
207
+ return;
208
+ }
209
+ loadWorkFlowDocumentInfo();
210
+ },
211
+ });
212
+ };
213
+
214
+ const adjustAuthorizedActions = () => {
215
+ if (workflowDocumentInfo?.nextActions?.length > 0) {
216
+ setAuthorizedActions(
217
+ workflowDocumentInfo.nextActions.filter((action) => {
218
+ if (
219
+ !(
220
+ workflowDocumentInfo?.workflowDocumentStatus
221
+ ?.nextActionTakersAuthority ||
222
+ workflowDocumentInfo?.nextActionTakers
223
+ )
224
+ ) {
225
+ return true;
226
+ }
227
+ if (
228
+ workflowDocumentInfo?.workflowDocumentStatus
229
+ ?.nextActionTakersAuthority
230
+ ) {
231
+ if (
232
+ isUserAuthorized(
233
+ workflowDocumentInfo.workflowDocumentStatus
234
+ .nextActionTakersAuthority
235
+ )
236
+ ) {
237
+ return true;
238
+ }
239
+ }
240
+ if (workflowDocumentInfo?.nextActionTakers) {
241
+ for (const actionTaker of workflowDocumentInfo.nextActionTakers) {
242
+ if (
243
+ UserInfo?.username == actionTaker?.username ||
244
+ UserInfo?.username == actionTaker?.USERNAME ||
245
+ UserInfo?.email == actionTaker?.email ||
246
+ UserInfo?.email == actionTaker?.EMAIL ||
247
+ UserInfo?.employeeNumber == actionTaker?.employeeNumber ||
248
+ UserInfo?.employeeNumber == actionTaker?.EMPLOYEE_NUMBER
249
+ ) {
250
+ return true;
251
+ }
252
+ }
253
+ }
254
+ return false;
255
+ })
256
+ );
257
+ } else {
258
+ setAuthorizedActions([]);
259
+ }
260
+ };
261
+
262
+ useEffect(() => {
263
+ if (props.refDocumentId && props.workFlowDocumentCode) {
264
+ loadWorkFlowDocumentInfo();
265
+ }
266
+ }, [props.refDocumentId, props.workFlowDocumentCode]);
267
+
268
+ useEffect(() => {
269
+ if (workflowDocumentInfo?.nextActions) {
270
+ adjustAuthorizedActions();
271
+ } else {
272
+ setAuthorizedActions([]);
273
+ }
274
+ }, [workflowDocumentInfo.nextActions, workflowDocumentInfo.nextActionTakers]);
275
+ return (
276
+ <>
277
+ {workflowDocumentInfo?.workflowDocumentReport?.id ? (
278
+ <ReporTViewWindow>
279
+ <ReportViewer
280
+ reportCode={
281
+ workflowDocumentInfo?.workflowDocumentReport?.reportCode
282
+ }
283
+ resultMode="App"
284
+ byPassParameterEntry={true}
285
+ reportParametersValues={{ doc_id: props.refDocumentId + "" }}
286
+ />
287
+ </ReporTViewWindow>
288
+ ) : (
289
+ <></>
290
+ )}
291
+
292
+ {workflowDocumentInfo?.workflowDocument ? (
293
+ <Box
294
+ sx={{
295
+ width: "100%",
296
+ maxWidth: 600,
297
+ textAlign: "center",
298
+ fontSize: 16,
299
+ fontWeight: "bold",
300
+ display: "flex",
301
+ alignItems: "center",
302
+ justifyContent: "center",
303
+ }}
304
+ >
305
+ <IconButton
306
+ onClick={() => {
307
+ navigate(-1, { replace: true });
308
+ }}
309
+ >
310
+ <FontAwesomeIcon icon="arrow-left" />
311
+ </IconButton>
312
+ <Box sx={{ flex: 1 }}></Box>
313
+ <FontAwesomeIcon
314
+ icon="file"
315
+ style={{ marginRight: 10, marginLeft: 10 }}
316
+ />
317
+ {AppLayout.appDirection === "ltr"
318
+ ? `${workflowDocumentInfo?.workflowDocument?.documentEnName} # ${
319
+ workflowDocumentInfo?.referencedDocument[
320
+ workflowDocumentInfo?.workflowDocument?.documentNumberField
321
+ ]
322
+ }`
323
+ : `${workflowDocumentInfo?.workflowDocument?.documentArName} # ${
324
+ workflowDocumentInfo?.referencedDocument[
325
+ workflowDocumentInfo?.workflowDocument?.documentNumberField
326
+ ]
327
+ }`}
328
+ {workflowDocumentInfo?.workflowDocumentStatus
329
+ ? AppLayout.appDirection === "ltr"
330
+ ? ` ( ${workflowDocumentInfo?.workflowDocumentStatus?.documentStatusEnName} )`
331
+ : ` ( ${workflowDocumentInfo?.workflowDocumentStatus?.documentStatusArName} )`
332
+ : ""}
333
+ <Box sx={{ flex: 1 }}></Box>
334
+ {workflowDocumentInfo?.workflowDocumentReport?.id ? (
335
+ <Button
336
+ onClick={() => {
337
+ setReportViewWindowState(true);
338
+ }}
339
+ variant="outlined"
340
+ startIcon={<FontAwesomeIcon icon="eye" />}
341
+ >
342
+ {t("VIEW_LABEL")}
343
+ </Button>
344
+ ) : (
345
+ <></>
346
+ )}
347
+ </Box>
348
+ ) : (
349
+ <></>
350
+ )}
351
+
352
+ <Box
353
+ sx={{
354
+ flex: 1,
355
+ width: "100%",
356
+ overflow: "hidden",
357
+ display: "flex",
358
+ // flexDirection: "column",
359
+ }}
360
+ >
361
+ {authorizedActions?.length > 0 ? (
362
+ <Paper
363
+ sx={{
364
+ padding: 2,
365
+ display: "flex",
366
+ // flex: 1,
367
+ margin: 1,
368
+ flexDirection: "column",
369
+ alignItems: "center",
370
+ justifyContent: "flex-start",
371
+ overflow: "hidden",
372
+ }}
373
+ >
374
+ <ComboBox
375
+ sx={{ marginBottom: 2, width: 400 }}
376
+ label={t("WE_AVAILABLE_ACTIONS_LABEL")}
377
+ displayField={
378
+ AppLayout.appDirection === "ltr"
379
+ ? "document_action_en_name"
380
+ : "document_action_ar_name"
381
+ }
382
+ valueField={"id"}
383
+ value={action?.id}
384
+ options={authorizedActions}
385
+ onChangeCallBack={(v, selectedRecord) => {
386
+ setAction(selectedRecord);
387
+ }}
388
+ />
389
+ {/* <ComboBox
390
+ sx={{ marginBottom: 2, width: 400 }}
391
+ label={t("WE_NEXT_APPROVER_LABEL")}
392
+ displayField={
393
+ AppLayout.appDirection === "ltr"
394
+ ? "employeeEnName"
395
+ : "employeeArName"
396
+ }
397
+ valueField={"id"}
398
+ value={nextActionTaker?.id}
399
+ options={action?.nextActionTakers || []}
400
+ onChangeCallBack={(v, selectedRecord) => {
401
+ setNextActionTaker(selectedRecord);
402
+ }}
403
+ /> */}
404
+ <TemplateTextField
405
+ sx={{ width: 400 }}
406
+ rows={3}
407
+ value={actionComment}
408
+ onChange={(event) => {
409
+ setActionComment(event.target.value);
410
+ }}
411
+ multiline={true}
412
+ label={t("WF_COMMENT_LABEL")}
413
+ />
414
+ <Box
415
+ sx={{
416
+ display: "flex",
417
+ alignItems: "center",
418
+ justifyContent: "center",
419
+ }}
420
+ >
421
+ <Button
422
+ color="success"
423
+ variant="contained"
424
+ sx={{ width: 200, m: 1 }}
425
+ onClick={validateBeforeProcessWorkflowDocumentAction}
426
+ >
427
+ {t("WF_TAKE_ACTION_BTN_LABEL")}
428
+ </Button>
429
+ {props?.cancelActionCallBk ? (
430
+ <Button
431
+ variant="contained"
432
+ sx={{ width: 200, m: 1 }}
433
+ color="error"
434
+ onClick={() => {
435
+ if (props?.cancelActionCallBk) {
436
+ props.cancelActionCallBk();
437
+ }
438
+ }}
439
+ >
440
+ {t("WF_CANCEL_BTN_LABEL")}
441
+ </Button>
442
+ ) : (
443
+ <></>
444
+ )}
445
+ </Box>
446
+ {workflowDocumentInfo?.nextActionTakers &&
447
+ workflowDocumentInfo.nextActionTakers.length > 0 ? (
448
+ <>
449
+ <Divider
450
+ variant="fullWidth"
451
+ flexItem
452
+ sx={{ marginTop: 1, marginBottom: 1 }}
453
+ >
454
+ <Box
455
+ sx={{
456
+ width: "100%",
457
+ display: "flex",
458
+ alignItems: "center",
459
+ justifyContent: "center",
460
+ fontSize: 18,
461
+ fontWeight: "bold",
462
+ }}
463
+ >
464
+ <FontAwesomeIcon
465
+ icon="users"
466
+ style={{ marginRight: 10, marginLeft: 10 }}
467
+ />{" "}
468
+ {t("WF_WAITING_FOR_LABEL")}
469
+ </Box>
470
+ </Divider>
471
+
472
+ <Box
473
+ sx={{
474
+ flex: 1,
475
+ display: "flex",
476
+ flexDirection: "column",
477
+ alignItems: "center",
478
+ overflow: "auto",
479
+ padding: 1,
480
+ width: "100%",
481
+ }}
482
+ >
483
+ {workflowDocumentInfo.nextActionTakers.map(
484
+ (nextActionTaker: any) => {
485
+ return (
486
+ <Box
487
+ sx={{
488
+ display: "flex",
489
+ alignItems: "center",
490
+ justifyContent: "center",
491
+ border: "1px dotted black",
492
+ width: 400,
493
+ marginBottom: 2,
494
+ padding: 2,
495
+ }}
496
+ >
497
+ <AttachmentImageViewer
498
+ showAsAvatar={true}
499
+ attachmentCode="EMPLOYEE_PHOTOS"
500
+ refKey={nextActionTaker?.id || "0"}
501
+ style={{
502
+ marginRight: 2,
503
+ marginLeft: 2,
504
+ width: 60,
505
+ height: 60,
506
+ }}
507
+ />
508
+ <Box
509
+ sx={{
510
+ flex: 2,
511
+ display: "flex",
512
+ flexDirection: "column",
513
+ alignItems: "flex-start",
514
+ justifyContent: "center",
515
+ }}
516
+ >
517
+ <div>
518
+ {AppLayout.appDirection === "ltr"
519
+ ? nextActionTaker?.employee_en_name
520
+ : nextActionTaker?.employee_ar_name}
521
+ </div>
522
+ <div>
523
+ {nextActionTaker?.email ? (
524
+ <>
525
+ <FontAwesomeIcon
526
+ icon="envelope"
527
+ style={{ marginRight: 10, marginLeft: 10 }}
528
+ />
529
+ {nextActionTaker?.email}
530
+ </>
531
+ ) : (
532
+ <></>
533
+ )}
534
+ </div>
535
+ <div>
536
+ {nextActionTaker?.mobile_number ? (
537
+ <>
538
+ <FontAwesomeIcon
539
+ icon="mobile"
540
+ style={{ marginRight: 10, marginLeft: 10 }}
541
+ />
542
+ {nextActionTaker?.mobile_number}
543
+ </>
544
+ ) : (
545
+ <></>
546
+ )}
547
+ </div>
548
+ </Box>
549
+ </Box>
550
+ );
551
+ }
552
+ )}
553
+ </Box>
554
+ </>
555
+ ) : (
556
+ <></>
557
+ )}
558
+ </Paper>
559
+ ) : (
560
+ <></>
561
+ )}
562
+ {workflowDocumentInfo?.actionsHistory.length > 0 ? (
563
+ <WorkflowDocumentTimeLine
564
+ actionHistory={workflowDocumentInfo.actionsHistory}
565
+ />
566
+ ) : (
567
+ <Paper
568
+ sx={{
569
+ display: "flex",
570
+ flexDirection: "column",
571
+ width: 600,
572
+ padding: 2,
573
+ margin: 1,
574
+ alignItems: "center",
575
+ justifyContent: "center",
576
+ }}
577
+ >
578
+ <Box
579
+ sx={{
580
+ width: "100%",
581
+ display: "flex",
582
+ alignItems: "center",
583
+ justifyContent: "center",
584
+ fontSize: 18,
585
+ fontWeight: "bold",
586
+ }}
587
+ >
588
+ <FontAwesomeIcon
589
+ icon="history"
590
+ style={{ marginRight: 10, marginLeft: 10 }}
591
+ />
592
+ {t("WF_ACTION_HISTORY_LABEL")}
593
+ </Box>
594
+ <Box
595
+ sx={{
596
+ flex: 1,
597
+ display: "flex",
598
+ alignItems: "center",
599
+ justifyContent: "center",
600
+ }}
601
+ >
602
+ No Action Log available
603
+ </Box>
604
+ </Paper>
605
+ )}
606
+ </Box>
607
+ </>
608
+ );
609
+ };
610
+
611
+ export default WorkflowDocumentPanel;