@asaleh37/ui-base 26.2.131 → 27.5.26

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 (176) hide show
  1. package/.env.development +1 -1
  2. package/.github/workflows/publish-npm.yml +49 -49
  3. package/README.md +51 -51
  4. package/__ODockerfile +14 -14
  5. package/dist/index.js +2 -2
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +2 -2
  8. package/dist/index.mjs.map +1 -1
  9. package/eslint.config.js +29 -29
  10. package/index.html +20 -20
  11. package/package.json +122 -122
  12. package/public/manifest.json +21 -21
  13. package/rollup.config-1748377725725.cjs +50 -50
  14. package/rollup.config.js +45 -45
  15. package/src/components/App.tsx +155 -155
  16. package/src/components/BaseApp.tsx +75 -75
  17. package/src/components/ExampleTrial.tsx +24 -24
  18. package/src/components/administration/admin/ChangePasswordPanel.tsx +128 -128
  19. package/src/components/administration/admin/CustomPersonGrid.tsx +361 -361
  20. package/src/components/administration/admin/OrgMemberRoleForm.tsx +83 -83
  21. package/src/components/administration/admin/OrgProvidedPersonGrid.tsx +347 -347
  22. package/src/components/administration/admin/OrganizationApplicationModuleGrid.tsx +107 -107
  23. package/src/components/administration/admin/OrganizationGrid.tsx +118 -118
  24. package/src/components/administration/admin/OrganizationMemberGrid.tsx +190 -190
  25. package/src/components/administration/admin/OrganizationMemberRoleGrid.tsx +87 -87
  26. package/src/components/administration/admin/OrganizationRankGrid.tsx +133 -133
  27. package/src/components/administration/admin/OrganizationUnitGrid.tsx +143 -143
  28. package/src/components/administration/admin/OrganizationUnitTypeGrid.tsx +108 -108
  29. package/src/components/administration/admin/PersonGrid.tsx +27 -27
  30. package/src/components/administration/admin/RoleAuthoritiesForm.tsx +82 -82
  31. package/src/components/administration/admin/SystemApplicationAuthorityGrid.tsx +117 -117
  32. package/src/components/administration/admin/SystemApplicationGrid.tsx +83 -83
  33. package/src/components/administration/admin/SystemApplicationModuleGrid.tsx +96 -96
  34. package/src/components/administration/admin/SystemApplicationRoleAuthorityGrid.tsx +75 -75
  35. package/src/components/administration/admin/SystemApplicationRoleGrid.tsx +116 -116
  36. package/src/components/administration/dev/AttachmentConfigGrid.tsx +224 -224
  37. package/src/components/administration/dev/AttachmentGrid.tsx +172 -172
  38. package/src/components/administration/dev/BluePrintGrid.tsx +129 -129
  39. package/src/components/administration/dev/DashboardGrid.tsx +173 -173
  40. package/src/components/administration/dev/DashboardWidgetGrid.tsx +164 -164
  41. package/src/components/administration/dev/DataQueryGrid.tsx +216 -216
  42. package/src/components/administration/dev/DataQueryParameterGrid.tsx +191 -191
  43. package/src/components/administration/dev/DataQueryParametersForm.tsx +84 -84
  44. package/src/components/administration/dev/DatasourceConnectionGrid.tsx +151 -151
  45. package/src/components/administration/dev/EntityParameterGrid.tsx +322 -322
  46. package/src/components/administration/dev/LookupGrid.tsx +120 -120
  47. package/src/components/administration/dev/MailAttachmentGrid.tsx +172 -155
  48. package/src/components/administration/dev/MailBodyGrid.tsx +216 -216
  49. package/src/components/administration/dev/MailNotificationQueueGrid.tsx +245 -245
  50. package/src/components/administration/dev/MailRecipientGrid.tsx +170 -170
  51. package/src/components/administration/dev/MailSenderConfigGrid.tsx +486 -486
  52. package/src/components/administration/dev/MailTemplateGrid.tsx +385 -385
  53. package/src/components/administration/dev/NotificationGrid.tsx +435 -435
  54. package/src/components/administration/dev/NotificationQueueGrid.tsx +222 -222
  55. package/src/components/administration/dev/ReportGrid.tsx +503 -503
  56. package/src/components/administration/dev/ReportParameterGrid.tsx +186 -186
  57. package/src/components/administration/dev/ReportParametersForm.tsx +84 -84
  58. package/src/components/administration/dev/WidgetGrid.tsx +380 -380
  59. package/src/components/administration/dev/WorkflowDocumentActionGrid.tsx +264 -264
  60. package/src/components/administration/dev/WorkflowDocumentActionHistoryGrid.tsx +172 -172
  61. package/src/components/administration/dev/WorkflowDocumentActionMailGrid.tsx +161 -161
  62. package/src/components/administration/dev/WorkflowDocumentGrid.tsx +357 -357
  63. package/src/components/administration/dev/WorkflowDocumentMailLogGrid.tsx +218 -218
  64. package/src/components/administration/dev/WorkflowDocumentStatusGrid.tsx +243 -243
  65. package/src/components/common/AzureLogin.tsx +222 -222
  66. package/src/components/common/ChangeOrgForm.tsx +85 -85
  67. package/src/components/common/Home.tsx +43 -43
  68. package/src/components/common/LanguageSwitcher.tsx +25 -25
  69. package/src/components/common/LayoutHandlers.tsx +11 -11
  70. package/src/components/common/LoadingMask.tsx +24 -24
  71. package/src/components/common/Login.tsx +268 -268
  72. package/src/components/common/MobileLogin.tsx +229 -229
  73. package/src/components/common/MyNotificationsPanel.tsx +109 -109
  74. package/src/components/common/NoLicenseComponent.tsx +79 -79
  75. package/src/components/common/NotificationItem.tsx +138 -138
  76. package/src/components/index.ts +10 -10
  77. package/src/components/msalConfig.ts +11 -11
  78. package/src/components/templates/DataEntryTemplates/DataEntryTypes.ts +361 -361
  79. package/src/components/templates/DataEntryTemplates/DataEntryUtil.ts +297 -297
  80. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormAction.tsx +60 -60
  81. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormElementField.tsx +238 -238
  82. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormElementGroup.tsx +108 -108
  83. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/CheckBox.tsx +66 -66
  84. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/ComboBox.tsx +164 -164
  85. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/Datefield.tsx +70 -70
  86. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/DatetimeField.tsx +71 -71
  87. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/FiltersPanel.tsx +237 -237
  88. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/SystemLookupCombobox.tsx +56 -56
  89. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/TemplateTextField.tsx +20 -20
  90. package/src/components/templates/DataEntryTemplates/TemplateDataForm/TemplateForm.tsx +431 -431
  91. package/src/components/templates/DataEntryTemplates/TemplateDataGrid/DataGridColumnsUtil.tsx +197 -197
  92. package/src/components/templates/DataEntryTemplates/TemplateDataGrid/TemplateGrid.tsx +1044 -1044
  93. package/src/components/templates/DataEntryTemplates/TemplateDataGrid/TemplateGridMultiRecordAction.tsx +89 -89
  94. package/src/components/templates/DataEntryTemplates/TemplateDataGrid/TemplateGridRecordAction.tsx +95 -95
  95. package/src/components/templates/DataEntryTemplates/TemplateDataGrid/TemplateGridTopBar.tsx +251 -251
  96. package/src/components/templates/TransferList.tsx +256 -256
  97. package/src/components/templates/Window/ConfirmationWindow.tsx +55 -55
  98. package/src/components/templates/attachment/AttachmentCard.tsx +141 -141
  99. package/src/components/templates/attachment/AttachmentImageViewer.tsx +85 -85
  100. package/src/components/templates/attachment/AttachmentPanel.tsx +285 -285
  101. package/src/components/templates/index.ts +35 -35
  102. package/src/components/templates/report/ExcelReportViewer.tsx +71 -71
  103. package/src/components/templates/report/ReportViewer.tsx +261 -261
  104. package/src/components/templates/report/ReportViewerRoute.tsx +9 -9
  105. package/src/components/templates/visuals/DashboardRouteView.tsx +9 -9
  106. package/src/components/templates/visuals/DashboardViewer.tsx +192 -192
  107. package/src/components/templates/visuals/WidgetViewer.tsx +208 -208
  108. package/src/components/templates/visuals/charts/TemplateBarChart.tsx +23 -23
  109. package/src/components/templates/visuals/charts/TemplateDataCard.tsx +35 -35
  110. package/src/components/templates/visuals/charts/TemplateGauge.tsx +21 -21
  111. package/src/components/templates/visuals/charts/TemplateLineChart.tsx +22 -22
  112. package/src/components/templates/visuals/charts/TemplateLineProgress.tsx +42 -42
  113. package/src/components/templates/visuals/charts/TemplatePieChart.tsx +24 -24
  114. package/src/components/templates/workflow/WorkflowDocumentPanel.tsx +611 -611
  115. package/src/components/templates/workflow/WorkflowDocumentTimeLine.tsx +145 -145
  116. package/src/components/templates/workflow/WorkflowRouteComponent.tsx +14 -14
  117. package/src/examples/ExampleGrid.tsx +134 -134
  118. package/src/hooks/UseConfirmationWindow.tsx +56 -56
  119. package/src/hooks/UseMobile.tsx +13 -13
  120. package/src/hooks/UseSession.tsx +59 -59
  121. package/src/hooks/UseWindow.tsx +111 -111
  122. package/src/hooks/index.ts +22 -22
  123. package/src/hooks/useApiActions.ts +124 -124
  124. package/src/hooks/useAxios.tsx +340 -340
  125. package/src/hooks/useCommonStore.tsx +29 -29
  126. package/src/hooks/useInterval.tsx +23 -23
  127. package/src/hooks/useLoadingMask.tsx +16 -16
  128. package/src/hooks/useLookupGridColumn.tsx +35 -35
  129. package/src/hooks/useParameterPanel.tsx +171 -171
  130. package/src/index.ts +4 -4
  131. package/src/layout/DrawerHeader.tsx +10 -10
  132. package/src/layout/Layout.tsx +102 -102
  133. package/src/layout/MainContent.tsx +115 -115
  134. package/src/layout/MobileDrawer.tsx +103 -103
  135. package/src/layout/NavigationTree.tsx +360 -360
  136. package/src/layout/NotificationButton.tsx +207 -207
  137. package/src/layout/RouteWrapper.tsx +63 -63
  138. package/src/layout/SideBar.tsx +85 -85
  139. package/src/layout/TopBar.tsx +317 -317
  140. package/src/locales/arabic/adminLocalsAr.json +94 -94
  141. package/src/locales/arabic/common.json +44 -44
  142. package/src/locales/arabic/devLocalsAr.json +317 -317
  143. package/src/locales/arabic/index.ts +9 -9
  144. package/src/locales/english/adminLocalsEn.json +97 -97
  145. package/src/locales/english/common.json +43 -43
  146. package/src/locales/english/devLocalsEn.json +318 -318
  147. package/src/locales/english/index.ts +9 -9
  148. package/src/locales/i18n.ts +8 -8
  149. package/src/locales/index.ts +9 -9
  150. package/src/main.tsx +41 -41
  151. package/src/navigationItems/Administration/adminNavigationItems.tsx +231 -231
  152. package/src/navigationItems/Administration/index.tsx +16 -16
  153. package/src/navigationItems/common/CommonNavigationItems.tsx +12 -12
  154. package/src/navigationItems/common/index.tsx +7 -7
  155. package/src/navigationItems/index.tsx +35 -35
  156. package/src/redux/features/administration/AdministrationStoresMetaData.ts +164 -164
  157. package/src/redux/features/common/AppInfoSlice.ts +95 -95
  158. package/src/redux/features/common/AppLayoutSlice.ts +29 -29
  159. package/src/redux/features/common/CommonStoreSlice.ts +44 -44
  160. package/src/redux/features/common/LoadingMaskSlice.ts +30 -30
  161. package/src/redux/features/common/SideBarSlice.ts +27 -27
  162. package/src/redux/features/common/UserSessionSlice.ts +54 -54
  163. package/src/redux/store.ts +29 -29
  164. package/src/routes/administration/adminRoutes.tsx +99 -99
  165. package/src/routes/administration/devRoutes.tsx +129 -129
  166. package/src/routes/administration/index.ts +10 -10
  167. package/src/routes/index.ts +5 -5
  168. package/src/routes/types/index.ts +6 -6
  169. package/src/styles/index.css +19 -19
  170. package/src/types/index.ts +8 -8
  171. package/src/util/AppUtils.ts +73 -73
  172. package/src/util/constants.ts +6 -6
  173. package/src/util/index.ts +5 -5
  174. package/tsconfig.json +135 -135
  175. package/vite.config.ts +24 -24
  176. package/package-lock.json/342/200/216 +0 -9040
@@ -1,611 +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(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;
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;