@asaleh37/ui-base 1.2.25 → 1.2.27

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asaleh37/ui-base",
3
- "version": "1.2.25",
3
+ "version": "1.2.27",
4
4
  "description": "",
5
5
  "license": "ISC",
6
6
  "author": "Ahmed Saleh Mohamed",
@@ -1,16 +1,16 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var resolve = require('@rollup/plugin-node-resolve');
6
- var commonjs = require('@rollup/plugin-commonjs');
7
- var typescript = require('@rollup/plugin-typescript');
8
- var dts = require('rollup-plugin-dts');
9
- var terser = require('@rollup/plugin-terser');
10
- var json = require('@rollup/plugin-json');
11
- var peerDepsExternal = require('rollup-plugin-peer-deps-external');
12
- var postcss = require('rollup-plugin-postcss');
13
-
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var resolve = require('@rollup/plugin-node-resolve');
6
+ var commonjs = require('@rollup/plugin-commonjs');
7
+ var typescript = require('@rollup/plugin-typescript');
8
+ var dts = require('rollup-plugin-dts');
9
+ var terser = require('@rollup/plugin-terser');
10
+ var json = require('@rollup/plugin-json');
11
+ var peerDepsExternal = require('rollup-plugin-peer-deps-external');
12
+ var postcss = require('rollup-plugin-postcss');
13
+
14
14
  const packageJson = require("./package.json");
15
15
 
16
16
  var rollup_config = [
@@ -45,6 +45,6 @@ var rollup_config = [
45
45
  plugins: [dts.default()],
46
46
  external: [/\.css$/],
47
47
  },
48
- ];
49
-
50
- exports.default = rollup_config;
48
+ ];
49
+
50
+ exports.default = rollup_config;
@@ -2,12 +2,14 @@ import { useState } from "react";
2
2
  import TemplateGrid from "../../templates/DataEntryTemplates/TemplateDataGrid/TemplateGrid";
3
3
  import { FormElementProps } from "../../templates/DataEntryTemplates/DataEntryTypes";
4
4
  import { useTranslation } from "react-i18next";
5
- import { useApiActions } from "../../../hooks";
5
+ import { useApiActions, useAxios, useConfirmationWindow } from "../../../hooks";
6
6
  import { useSelector } from "react-redux";
7
7
 
8
8
  const MailNotificationQueueGrid: React.FC = () => {
9
9
  const { t } = useTranslation();
10
10
  const [data, setData] = useState([]);
11
+ const { handlePostRequest } = useAxios();
12
+
11
13
  const apiActions = useApiActions({
12
14
  findAll: "api/v1/dev/mailnotificationqueue/all",
13
15
  deleteById: "api/v1/dev/mailnotificationqueue",
@@ -19,6 +21,19 @@ const MailNotificationQueueGrid: React.FC = () => {
19
21
  (state: any) => state.commonStores.stores.SystemMailTemplates.data
20
22
  );
21
23
 
24
+ const resendMail = async (id: any) => {
25
+ await handlePostRequest({
26
+ endPointURI: "api/v1/public/mailNotification/resend",
27
+ showMask: true,
28
+ parameters: {
29
+ mailNotificationQueueId: id,
30
+ },
31
+ successCallBkFn: (response: any) => {
32
+ apiActions.reloadData();
33
+ },
34
+ });
35
+ };
36
+
22
37
  const formElements: Array<FormElementProps> = [
23
38
  {
24
39
  type: "field",
@@ -201,6 +216,17 @@ const MailNotificationQueueGrid: React.FC = () => {
201
216
  setData={setData}
202
217
  editMode={{ editMode: "none" }}
203
218
  formElements={formElements}
219
+ rowActions={[
220
+ {
221
+ actionFn: async (data) => {
222
+ resendMail(data.id);
223
+ },
224
+ label: "Resend",
225
+ icon: "repeat",
226
+ confirmationMessage: "Are you sure you want to resend this email ?",
227
+ isConfirmationRequired: true,
228
+ },
229
+ ]}
204
230
  keyColumnName={"id"}
205
231
  gridTitle={t("MAIL_NOTIFICATION_QUEUE_PLURAL")}
206
232
  girdIcon="table-cells"
@@ -14,6 +14,9 @@ const MailTemplateGrid: React.FC = () => {
14
14
  const SystemDataQueries = useSelector(
15
15
  (state: any) => state.commonStores.stores.SystemDataQueries.data
16
16
  );
17
+ const SystemTimeIntervals = useSelector(
18
+ (state: any) => state.commonStores.stores.SystemTimeIntervals.data
19
+ );
17
20
  const [selectedRecord, setSelectedRecord] = useState<any>(null);
18
21
  const {
19
22
  Window: MailRecipentsWindow,
@@ -246,14 +249,7 @@ const MailTemplateGrid: React.FC = () => {
246
249
  props: {
247
250
  fieldLabel: "MAIL_TEMPLATE_PERIOD_TYPE",
248
251
  fieldName: "periodType",
249
- options: [
250
- { value: "Year" },
251
- { value: "Month" },
252
- { value: "Day" },
253
- { value: "Hour" },
254
- { value: "Minute" },
255
- { value: "Second" },
256
- ],
252
+ options: SystemTimeIntervals,
257
253
  optionDisplayField: "value",
258
254
  optionValueField: "value",
259
255
  required: false,
@@ -93,16 +93,22 @@ const TemplateGrid: React.FC<TemplateGridProps> = (props) => {
93
93
  width: "fit-content",
94
94
  height: "fit-content",
95
95
  minHeight: 500,
96
- minWidth: 400,
96
+ minWidth: "50%",
97
+ onCloseCallBack: () => {
98
+ props?.apiActions?.reloadData(props.gridLoadParametersValues);
99
+ },
97
100
  });
98
101
  const { Window: WorkFlowWindow, setWindowState: setWorkFlowWindowState } =
99
102
  useWindow({
100
- windowTitle: t(props.gridTitle) + " Attachments",
101
- windowIcon: "paperclip",
103
+ windowTitle: t(props.gridTitle) + " Approvals",
104
+ windowIcon: "stamp",
102
105
  width: "fit-content",
103
106
  height: "fit-content",
104
107
  minHeight: 500,
105
- minWidth: 400,
108
+ minWidth: "80%",
109
+ onCloseCallBack: () => {
110
+ props?.apiActions?.reloadData(props.gridLoadParametersValues);
111
+ },
106
112
  });
107
113
  const [generatedColumns, setGeneratedColumns] = useState<
108
114
  Array<TemplateGridColDef>
@@ -632,7 +638,11 @@ const TemplateGrid: React.FC<TemplateGridProps> = (props) => {
632
638
  />
633
639
  );
634
640
  }
635
- if (props?.rowActions) {
641
+ if (
642
+ record[props?.keyColumnName || "id"] &&
643
+ record[props?.keyColumnName || "id"] > 0 &&
644
+ props?.rowActions
645
+ ) {
636
646
  for (const rowAction of props.rowActions) {
637
647
  if (
638
648
  !(
@@ -917,11 +927,13 @@ const TemplateGrid: React.FC<TemplateGridProps> = (props) => {
917
927
  workFlowDocumentCode={props.workFlowDocumentCode}
918
928
  refDocumentId={selectedRecord[props?.keyColumnName || "id"]}
919
929
  postActionCallBk={() => {
930
+ debugger;
920
931
  setWorkFlowWindowState(false);
921
932
  props.apiActions.reloadData(props.gridLoadParametersValues);
922
933
  }}
923
934
  cancelActionCallBk={() => {
924
935
  setWorkFlowWindowState(false);
936
+ props.apiActions.reloadData(props.gridLoadParametersValues);
925
937
  }}
926
938
  />
927
939
  </WorkFlowWindow>
@@ -950,6 +962,11 @@ const TemplateGrid: React.FC<TemplateGridProps> = (props) => {
950
962
  columns={adjustedColumns}
951
963
  checkboxSelection
952
964
  editMode="row"
965
+ onRowEditStop={(params, event) => {
966
+ if (params.reason === "rowFocusOut") {
967
+ event.defaultMuiPrevented = true;
968
+ }
969
+ }}
953
970
  rowModesModel={
954
971
  props.editMode.editMode == "row" ? rowModesModel : undefined
955
972
  }
@@ -6,7 +6,7 @@ import Button from "@mui/material/Button";
6
6
  import Typography from "@mui/material/Typography";
7
7
  import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
8
8
  import { IconButton, Tooltip } from "@mui/material";
9
- import { useAxios, useConfirmationWindow } from "../../../hooks";
9
+ import { useAxios, useConfirmationWindow, useSession } from "../../../hooks";
10
10
  import AttachmentImageViewer from "./AttachmentImageViewer";
11
11
 
12
12
  export type attachment = {
@@ -19,12 +19,18 @@ export type attachment = {
19
19
  docType: string;
20
20
  fileName: string;
21
21
  refKey: string;
22
+ allowDelete?: boolean;
23
+ downloadAuthorityKey?: string;
22
24
  remark: string;
23
25
  };
24
26
 
25
27
  const AttachmentCard: React.FC<attachment> = (props) => {
26
28
  const { handleGetRequest, handleDeleteRequest } = useAxios();
27
-
29
+ const { isUserAuthorized } = useSession();
30
+ let allowDownload = true;
31
+ if (props?.downloadAuthorityKey) {
32
+ allowDownload = isUserAuthorized(props.downloadAuthorityKey);
33
+ }
28
34
  const handleDelete = async () => {
29
35
  await handleDeleteRequest({
30
36
  endPointURI: "api/v1/attachment/archive",
@@ -101,22 +107,31 @@ const AttachmentCard: React.FC<attachment> = (props) => {
101
107
  </Typography>
102
108
  </CardContent>
103
109
  <CardActions>
104
- <IconButton
105
- size="small"
106
- onClick={() => {
107
- setOpen(true);
108
- }}
109
- >
110
- <Tooltip title="Delete Attachment">
111
- <FontAwesomeIcon icon="trash" />
112
- </Tooltip>
113
- </IconButton>
110
+ {props?.allowDelete ? (
111
+ <IconButton
112
+ size="small"
113
+ onClick={() => {
114
+ setOpen(true);
115
+ }}
116
+ >
117
+ <Tooltip title="Delete Attachment">
118
+ <FontAwesomeIcon icon="trash" />
119
+ </Tooltip>
120
+ </IconButton>
121
+ ) : (
122
+ <></>
123
+ )}
124
+
114
125
  <div style={{ flex: 1 }}></div>
115
- <IconButton size="small" onClick={handleDownload}>
116
- <Tooltip title="Download Attachment">
117
- <FontAwesomeIcon icon="download" />
118
- </Tooltip>
119
- </IconButton>
126
+ {allowDownload ? (
127
+ <IconButton size="small" onClick={handleDownload}>
128
+ <Tooltip title="Download Attachment">
129
+ <FontAwesomeIcon icon="download" />
130
+ </Tooltip>
131
+ </IconButton>
132
+ ) : (
133
+ <></>
134
+ )}
120
135
  </CardActions>
121
136
  </Card>
122
137
  </>
@@ -1,6 +1,6 @@
1
1
  import { useState } from "react";
2
2
  import { useSelector } from "react-redux";
3
- import { Avatar } from "@mui/material";
3
+ import { Avatar, SxProps } from "@mui/material";
4
4
 
5
5
  type AttachmentImageViewerProps = {
6
6
  attachmentId?: number;
@@ -8,6 +8,7 @@ type AttachmentImageViewerProps = {
8
8
  refKey?: string;
9
9
  category?: string;
10
10
  showAsAvatar?: boolean;
11
+ style?: SxProps;
11
12
  };
12
13
 
13
14
  const AttachmentImageViewer: React.FC<AttachmentImageViewerProps> = (props) => {
@@ -25,7 +26,7 @@ const AttachmentImageViewer: React.FC<AttachmentImageViewerProps> = (props) => {
25
26
  }
26
27
  const [imgSrc, setImgSrc] = useState(imagePath);
27
28
  return props?.showAsAvatar ? (
28
- <Avatar src={imgSrc} />
29
+ <Avatar src={imgSrc} sx={props.style} />
29
30
  ) : (
30
31
  <img
31
32
  src={imgSrc}
@@ -144,7 +144,7 @@ const AttachmentPanel: React.FC<AttachmentPanelProps> = (props) => {
144
144
  !isUserAuthorized(attachmentConfig?.downloadAuthorityKey)
145
145
  ) {
146
146
  showAttachments = false;
147
- }
147
+ }
148
148
  let allowUpload = true;
149
149
  if (props?.enableAttachment === false) {
150
150
  allowUpload = false;
@@ -253,6 +253,8 @@ const AttachmentPanel: React.FC<AttachmentPanelProps> = (props) => {
253
253
  {...refKeyAttachment}
254
254
  attachmentCode={props.attachmentCode}
255
255
  setAttachmentConfig={setAttachmentConfig}
256
+ downloadAuthorityKey={attachmentConfig.downloadAuthorityKey}
257
+ allowDelete={allowUpload}
256
258
  />
257
259
  </Grid2>
258
260
  );
@@ -33,10 +33,16 @@ const getGridColumnsFromRecord = (data: Array<any>) => {
33
33
  };
34
34
 
35
35
  const ExcelReportViewer: React.FC<ExcelReportViewerProps> = (props) => {
36
- console.log("reportdata", props.reportData);
36
+ const [data, setData] = useState([]);
37
+ useEffect(() => {
38
+ const newData = props.reportData.map((record, index) => {
39
+ return { ...record, report_record_data_key: index };
40
+ });
41
+ setData(newData);
42
+ }, [props.reportData]);
37
43
  return (
38
44
  <TemplateGrid
39
- data={props.reportData}
45
+ data={data}
40
46
  disableDefaultAction={true}
41
47
  setData={props.setReportData}
42
48
  formElements={getGridColumnsFromRecord(props.reportData)}
@@ -47,6 +53,7 @@ const ExcelReportViewer: React.FC<ExcelReportViewerProps> = (props) => {
47
53
  girdIcon={"file-excel"}
48
54
  gridTitle="Report"
49
55
  autoLoad={true}
56
+ keyColumnName={"report_record_data_key"}
50
57
  hideInfoBar={true}
51
58
  apiActions={{
52
59
  deleteRecordById: async () => {
@@ -99,7 +99,7 @@ const ReportViewer: React.FC<ReportViewerProps> = (props) => {
99
99
  const loadReportData = async () => {
100
100
  setReportViewerState("LOADING_METADATA");
101
101
  await handleGetRequest({
102
- endPointURI: "api/v1/dev/report/metadata",
102
+ endPointURI: "api/v1/public/report/metadata",
103
103
  showMask: true,
104
104
  parameters: { reportCode: props.reportCode },
105
105
  successCallBkFn: (response: any) => {
@@ -130,7 +130,7 @@ const ReportViewer: React.FC<ReportViewerProps> = (props) => {
130
130
  setReportViewerState("WAITING_RESULT");
131
131
  if (reportInfoProp?.reportType === "Excel") {
132
132
  await handlePostRequest({
133
- endPointURI: "api/v1/dev/report/run",
133
+ endPointURI: "api/v1/public/report/run",
134
134
  showMask: true,
135
135
  data: {
136
136
  reportCode: props.reportCode,
@@ -145,7 +145,7 @@ const ReportViewer: React.FC<ReportViewerProps> = (props) => {
145
145
  });
146
146
  } else if (reportInfoProp?.reportType) {
147
147
  await HandleDownloadHTTPPostPDF({
148
- endPointURI: "api/v1/dev/report/run",
148
+ endPointURI: "api/v1/public/report/run",
149
149
  showMask: true,
150
150
  data: {
151
151
  reportCode: props.reportCode,
@@ -156,6 +156,7 @@ const ReportViewer: React.FC<ReportViewerProps> = (props) => {
156
156
  successCallBkFn: (response: any) => {
157
157
  setReportViewerState("SHOWING_RESULT");
158
158
  const contentDisposition = response.headers["content-disposition"];
159
+ debugger;
159
160
  let filename = "downloaded_file";
160
161
  if (
161
162
  contentDisposition &&
@@ -1,6 +1,14 @@
1
1
  import { useEffect, useState } from "react";
2
2
  import { useAxios, useSession, useWindow } from "../../../hooks";
3
- import { Avatar, Box, Button, Divider, Grid2, Paper } from "@mui/material";
3
+ import {
4
+ Avatar,
5
+ Box,
6
+ Button,
7
+ Divider,
8
+ Grid2,
9
+ IconButton,
10
+ Paper,
11
+ } from "@mui/material";
4
12
  import TemplateTextField from "../DataEntryTemplates/TemplateDataForm/FormFields/TemplateTextField";
5
13
  import ComboBox from "../DataEntryTemplates/TemplateDataForm/FormFields/ComboBox";
6
14
  import { useSelector } from "react-redux";
@@ -9,6 +17,8 @@ import WorkflowDocumentTimeLine from "./WorkflowDocumentTimeLine";
9
17
  import { toast } from "react-toastify";
10
18
  import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
11
19
  import ReportViewer from "../report/ReportViewer";
20
+ import AttachmentImageViewer from "../attachment/AttachmentImageViewer";
21
+ import { useNavigate } from "react-router-dom";
12
22
 
13
23
  export type WorkflowDocumentPanelProps = {
14
24
  workFlowDocumentCode: string;
@@ -47,6 +57,7 @@ export type workflowDocumentActionHistory = {
47
57
  documentActionEnName: string;
48
58
  employeeArName: string;
49
59
  employeeEnName: string;
60
+ personId: number;
50
61
  };
51
62
 
52
63
  type WorkflowDocumentInfo = {
@@ -60,6 +71,7 @@ type WorkflowDocumentInfo = {
60
71
  };
61
72
 
62
73
  const WorkflowDocumentPanel: React.FC<WorkflowDocumentPanelProps> = (props) => {
74
+ const navigate = useNavigate();
63
75
  const AppLayout = useSelector((state: any) => state.AppLayout);
64
76
  const { isUserAuthorized, UserInfo } = useSession();
65
77
  const { handleGetRequest, handlePostRequest } = useAxios();
@@ -187,6 +199,9 @@ const WorkflowDocumentPanel: React.FC<WorkflowDocumentPanelProps> = (props) => {
187
199
  },
188
200
  successCallBkFn: () => {
189
201
  loadWorkFlowDocumentInfo();
202
+ if (props?.postActionCallBk) {
203
+ props.postActionCallBk();
204
+ }
190
205
  },
191
206
  });
192
207
  return;
@@ -282,6 +297,13 @@ const WorkflowDocumentPanel: React.FC<WorkflowDocumentPanelProps> = (props) => {
282
297
  justifyContent: "center",
283
298
  }}
284
299
  >
300
+ <IconButton
301
+ onClick={() => {
302
+ navigate(-1, { replace: true });
303
+ }}
304
+ >
305
+ <FontAwesomeIcon icon="arrow-left" />
306
+ </IconButton>
285
307
  <Box sx={{ flex: 1 }}></Box>
286
308
  <FontAwesomeIcon
287
309
  icon="file"
@@ -467,8 +489,11 @@ const WorkflowDocumentPanel: React.FC<WorkflowDocumentPanelProps> = (props) => {
467
489
  padding: 2,
468
490
  }}
469
491
  >
470
- <Avatar
471
- sx={{
492
+ <AttachmentImageViewer
493
+ showAsAvatar={true}
494
+ attachmentCode="EMPLOYEE_PHOTOS"
495
+ refKey={nextActionTaker?.id || "0"}
496
+ style={{
472
497
  marginRight: 2,
473
498
  marginLeft: 2,
474
499
  width: 60,
@@ -4,6 +4,7 @@ import { useSelector } from "react-redux";
4
4
  import { Avatar, Box, Divider, Paper, Stack } from "@mui/material";
5
5
  import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
6
6
  import { useTranslation } from "react-i18next";
7
+ import AttachmentImageViewer from "../attachment/AttachmentImageViewer";
7
8
 
8
9
  type WorkflowDocumentTimeLineProp = {
9
10
  actionHistory: Array<workflowDocumentActionHistory>;
@@ -92,7 +93,12 @@ const WorkflowDocumentTimeLine: React.FC<WorkflowDocumentTimeLineProp> = (
92
93
  marginLeft: 2,
93
94
  }}
94
95
  >
95
- <Avatar sx={{ m: 1, width: 70, height: 70 }} />
96
+ <AttachmentImageViewer
97
+ showAsAvatar={true}
98
+ attachmentCode="EMPLOYEE_PHOTOS"
99
+ refKey={actionHistoryRecord?.personId + "" || "0"}
100
+ style={{ m: 1, width: 70, height: 70 }}
101
+ />
96
102
  {index !== props.actionHistory.length - 1 ? (
97
103
  <Box sx={{ marginTop: 11, position: "absolute" }}>|</Box>
98
104
  ) : (
@@ -48,7 +48,7 @@ const NotificationButton: React.FC = () => {
48
48
  ? `You have new notifications`
49
49
  : `لديك اشعارات جديدة`,
50
50
  {
51
- autoClose: false,
51
+ autoClose: 3000,
52
52
  position:
53
53
  AppLayout.appDirection === "ltr"
54
54
  ? "bottom-right"
@@ -196,7 +196,7 @@ const TopBar: React.FC = () => {
196
196
  <NotificationButton />
197
197
  <AttachmentImageViewer
198
198
  showAsAvatar={true}
199
- attachmentCode="PERSON_IMG"
199
+ attachmentCode="EMPLOYEE_PHOTOS"
200
200
  refKey={UserSession.value?.id + ""}
201
201
  />
202
202
  <div style={{ marginLeft: 5, marginRight: 5 }}>
@@ -0,0 +1,8 @@
1
+ {
2
+ "book":"book",
3
+ "WF_DOC_SINGULAR":"wfdoc",
4
+ "WF_DOC_PLURAL":"wfdocs",
5
+ "WF_DOC_DOC_NUM":"Doc num",
6
+ "WF_DOC_DOC_STATUS":"Doc status",
7
+ "WF_DOC_DOC_TYPE":"Doc type",
8
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "book":"book",
3
+ "WF_DOC_SINGULAR":"wfdoc",
4
+ "WF_DOC_PLURAL":"wfdocs",
5
+ "WF_DOC_DOC_NUM":"Doc num",
6
+ "WF_DOC_DOC_STATUS":"Doc status",
7
+ "WF_DOC_DOC_TYPE":"Doc type",
8
+ }
package/src/main.tsx CHANGED
@@ -1,11 +1,10 @@
1
- import { StrictMode } from "react";
2
1
  import { createRoot } from "react-dom/client";
3
2
  import { BaseApp } from "./components";
4
- // import logo from "./assets/logo.png";
3
+
5
4
 
6
5
  createRoot(document.getElementById("root")!).render(
7
6
  <BaseApp
8
- apiBaseUrl="http://localhost:8080/api-base"
7
+ apiBaseUrl="http://localhost:8080/ezz-residual"
9
8
  appLogo={"/public/logo.png"}
10
9
  appName="UI Base Library"
11
10
  appVersion="0.0"