ui-soxo-bootstrap-core 2.6.1-dev.3 → 2.6.1-dev.31
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/core/components/extra-info/extra-info-details.js +2 -2
- package/core/components/index.js +2 -11
- package/core/components/landing-api/landing-api.js +216 -18
- package/core/components/landing-api/landing-api.scss +22 -0
- package/core/components/license-management/license-alert.js +97 -0
- package/core/lib/Store.js +8 -4
- package/core/lib/components/global-header/global-header.js +217 -242
- package/core/lib/components/index.js +2 -2
- package/core/lib/components/sidemenu/sidemenu.js +19 -13
- package/core/lib/components/sidemenu/sidemenu.scss +1 -1
- package/core/lib/elements/basic/country-phone-input/country-phone-input.js +14 -9
- package/core/lib/elements/basic/dragabble-wrapper/draggable-wrapper.js +1 -1
- package/core/lib/elements/basic/menu-tree/menu-tree.js +26 -13
- package/core/lib/models/forms/components/form-creator/form-creator.js +525 -468
- package/core/lib/models/forms/components/form-creator/form-creator.scss +30 -26
- package/core/lib/models/menus/components/menu-list/menu-list.js +424 -467
- package/core/lib/models/process/components/process-dashboard/process-dashboard.js +469 -3
- package/core/lib/models/process/components/process-dashboard/process-dashboard.scss +4 -0
- package/core/lib/modules/generic/generic-list/ExportReactCSV.js +28 -2
- package/core/lib/pages/change-password/change-password.js +17 -24
- package/core/lib/pages/change-password/change-password.scss +45 -48
- package/core/lib/pages/login/commnication-mode-selection.js +2 -2
- package/core/lib/pages/login/login.js +53 -64
- package/core/lib/pages/login/login.scss +9 -0
- package/core/lib/pages/login/reset-password.js +17 -17
- package/core/lib/pages/login/reset-password.scss +10 -1
- package/core/lib/pages/profile/themes.json +4 -4
- package/core/lib/utils/api/api.utils.js +53 -45
- package/core/lib/utils/common/common.utils.js +49 -35
- package/core/lib/utils/generic/generic.utils.js +2 -1
- package/core/lib/utils/http/http.utils.js +33 -4
- package/core/lib/utils/index.js +4 -1
- package/core/models/base/base.js +7 -3
- package/core/models/core-scripts/core-scripts.js +147 -126
- package/core/models/doctor/components/doctor-add/doctor-add.js +9 -4
- package/core/models/menus/components/menu-add/menu-add.js +1 -1
- package/core/models/menus/components/menu-lists/menu-lists.js +53 -54
- package/core/models/menus/menus.js +49 -2
- package/core/models/roles/components/role-add/role-add.js +92 -59
- package/core/models/roles/components/role-list/role-list.js +1 -1
- package/core/models/staff/components/staff-add/staff-add.js +20 -32
- package/core/models/users/components/assign-role/assign-role.js +145 -50
- package/core/models/users/components/assign-role/assign-role.scss +209 -45
- package/core/models/users/components/assign-role/avatar-props.js +45 -0
- package/core/models/users/components/user-add/user-add.js +46 -55
- package/core/models/users/components/user-add/user-edit.js +25 -4
- package/core/models/users/users.js +9 -1
- package/core/modules/dashboard/components/dashboard-card/menu-dashboard-card.js +1 -1
- package/core/modules/reporting/components/reporting-dashboard/README.md +316 -0
- package/core/modules/reporting/components/reporting-dashboard/adavance-search/advance-search.js +174 -0
- package/core/modules/reporting/components/reporting-dashboard/adavance-search/advance-search.scss +76 -0
- package/core/modules/reporting/components/reporting-dashboard/display-columns/build-display-columns.js +90 -0
- package/core/modules/reporting/components/reporting-dashboard/display-columns/build-display-columns.test.js +74 -0
- package/core/modules/reporting/components/reporting-dashboard/display-columns/display-cell-renderer.js +448 -0
- package/core/modules/reporting/components/reporting-dashboard/display-columns/display-cell-renderer.test.js +199 -0
- package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.js +195 -822
- package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.scss +43 -0
- package/core/modules/reporting/components/reporting-dashboard/reporting-table.js +517 -0
- package/core/modules/steps/action-buttons.js +30 -16
- package/core/modules/steps/action-buttons.scss +55 -9
- package/core/modules/steps/chat-assistant.js +141 -0
- package/core/modules/steps/openai-realtime.js +275 -0
- package/core/modules/steps/readme.md +167 -0
- package/core/modules/steps/steps.js +1286 -60
- package/core/modules/steps/steps.scss +703 -86
- package/core/modules/steps/timeline.js +21 -19
- package/core/modules/steps/voice-navigation.js +709 -0
- package/package.json +2 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useState, useCallback, useEffect } from 'react';
|
|
2
|
-
import { Space, Popconfirm, Input, Drawer, Skeleton, Collapse, message } from 'antd';
|
|
2
|
+
import { Space, Popconfirm, Input, Drawer, Skeleton, Collapse, message, Tag, Empty } from 'antd';
|
|
3
3
|
import { ReloadOutlined, DeleteOutlined, EditOutlined, PlusCircleFilled, CopyOutlined } from '@ant-design/icons';
|
|
4
4
|
import { Button, Card, Switch, DraggableWrapper } from '../../../../lib';
|
|
5
5
|
// for draggable menu list import { DndProvider } from "react-dnd";
|
|
@@ -55,7 +55,6 @@ const MenuLists = ({ model, match, relativeAdd = false, additional_queries = [],
|
|
|
55
55
|
.catch(() => setLoading(false));
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
-
console.log('record', records);
|
|
59
58
|
/**
|
|
60
59
|
*
|
|
61
60
|
*/
|
|
@@ -204,9 +203,9 @@ const MenuLists = ({ model, match, relativeAdd = false, additional_queries = [],
|
|
|
204
203
|
model.delete(rec).then(loadMenus);
|
|
205
204
|
};
|
|
206
205
|
|
|
207
|
-
const filtered = records.filter((r) => r.
|
|
206
|
+
const filtered = records.filter((r) => r.caption?.toUpperCase().includes(query.toUpperCase()));
|
|
208
207
|
|
|
209
|
-
const visibleItems =
|
|
208
|
+
const visibleItems = filtered;
|
|
210
209
|
|
|
211
210
|
const onSearch = (event) => {
|
|
212
211
|
setQuery(event.target.value);
|
|
@@ -363,50 +362,53 @@ const MenuLists = ({ model, match, relativeAdd = false, additional_queries = [],
|
|
|
363
362
|
<Card>
|
|
364
363
|
<DndProvider backend={HTML5Backend}>
|
|
365
364
|
<Collapse accordion>
|
|
366
|
-
{visibleItems.
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
365
|
+
{visibleItems && visibleItems.length > 0 ? (
|
|
366
|
+
visibleItems.map((item, index) => (
|
|
367
|
+
<Panel
|
|
368
|
+
key={item.id}
|
|
369
|
+
header={
|
|
370
|
+
<DraggableWrapper
|
|
371
|
+
id={item.id}
|
|
372
|
+
index={index}
|
|
373
|
+
movePanel={movePanel}
|
|
374
|
+
item={item}
|
|
375
|
+
dragEnabled={dragMode}
|
|
376
|
+
level={1}
|
|
377
|
+
parentId={null}
|
|
378
|
+
onCrossLevelMove={handleCrossLevelMove}
|
|
379
|
+
canAcceptChildren={true}
|
|
380
|
+
/>
|
|
381
|
+
}
|
|
382
|
+
showArrow={item.sub_menus && item.sub_menus.length > 0}
|
|
383
|
+
extra={panelActions(item, model, setSelectedRecord, setDrawerTitle, setDrawerVisible, deleteRecord)}
|
|
384
|
+
>
|
|
385
|
+
{item.sub_menus && item.sub_menus.length > 0 && (
|
|
386
|
+
<NestedMenu
|
|
387
|
+
parentId={item.id}
|
|
388
|
+
step={item.step + 1}
|
|
389
|
+
items={item.sub_menus || []}
|
|
390
|
+
model={model}
|
|
391
|
+
dragMode={dragMode}
|
|
392
|
+
setSelectedRecord={setSelectedRecord}
|
|
393
|
+
setDrawerTitle={setDrawerTitle}
|
|
394
|
+
setDrawerVisible={setDrawerVisible}
|
|
395
|
+
deleteRecord={deleteRecord}
|
|
396
|
+
level={2}
|
|
397
|
+
onCrossLevelMove={handleCrossLevelMove}
|
|
398
|
+
onChange={(subMenus) => {
|
|
399
|
+
const updated = records.map((r) => (r.id === item.id ? { ...r, sub_menus: subMenus } : r));
|
|
400
|
+
setRecords(updated);
|
|
401
|
+
setOrderChanged(true);
|
|
402
|
+
}}
|
|
403
|
+
/>
|
|
404
|
+
)}
|
|
405
|
+
</Panel>
|
|
406
|
+
))
|
|
407
|
+
) : (
|
|
408
|
+
<div style={{ textAlign: 'center', padding: '40px 0' }}>
|
|
409
|
+
<Empty description="No Menu Items" />
|
|
410
|
+
</div>
|
|
411
|
+
)}
|
|
410
412
|
</Collapse>
|
|
411
413
|
</DndProvider>
|
|
412
414
|
</Card>
|
|
@@ -440,7 +442,7 @@ const MenuLists = ({ model, match, relativeAdd = false, additional_queries = [],
|
|
|
440
442
|
function panelActions(item, model, setSelectedRecord, setDrawerTitle, setDrawerVisible, deleteRecord) {
|
|
441
443
|
return (
|
|
442
444
|
<Space onClick={(e) => e.stopPropagation()}>
|
|
443
|
-
{
|
|
445
|
+
<Tag color={item.is_visible === true ? 'green' : 'blue'}>{item.is_visible === true ? 'VISIBLE' : 'HIDDEN'}</Tag>{' '}
|
|
444
446
|
<Button
|
|
445
447
|
size="small"
|
|
446
448
|
type="dashed"
|
|
@@ -459,7 +461,6 @@ function panelActions(item, model, setSelectedRecord, setDrawerTitle, setDrawerV
|
|
|
459
461
|
<PlusCircleFilled />
|
|
460
462
|
Add Sub Menu
|
|
461
463
|
</Button>
|
|
462
|
-
|
|
463
464
|
{model.ModalAddComponent && (
|
|
464
465
|
<Button
|
|
465
466
|
size="small"
|
|
@@ -473,8 +474,7 @@ function panelActions(item, model, setSelectedRecord, setDrawerTitle, setDrawerV
|
|
|
473
474
|
<EditOutlined />
|
|
474
475
|
</Button>
|
|
475
476
|
)}
|
|
476
|
-
|
|
477
|
-
{/* <Button
|
|
477
|
+
<Button
|
|
478
478
|
size="small"
|
|
479
479
|
type="default"
|
|
480
480
|
onClick={() => {
|
|
@@ -484,8 +484,7 @@ function panelActions(item, model, setSelectedRecord, setDrawerTitle, setDrawerV
|
|
|
484
484
|
}}
|
|
485
485
|
>
|
|
486
486
|
<CopyOutlined />
|
|
487
|
-
</Button>
|
|
488
|
-
|
|
487
|
+
</Button>
|
|
489
488
|
<Popconfirm title="Are you sure?" onConfirm={() => deleteRecord(item)}>
|
|
490
489
|
<Button danger size="small" type="default">
|
|
491
490
|
<DeleteOutlined />
|
|
@@ -160,6 +160,29 @@ class MenusAPI extends Base {
|
|
|
160
160
|
});
|
|
161
161
|
};
|
|
162
162
|
|
|
163
|
+
getBranches = () => {
|
|
164
|
+
return ApiUtils.get({
|
|
165
|
+
url: 'branches',
|
|
166
|
+
});
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
switchBranch = (formBody, dbPtr) => {
|
|
170
|
+
return ApiUtils.post({
|
|
171
|
+
url: `auth/switch-branch`,
|
|
172
|
+
headers: { db_ptr: dbPtr },
|
|
173
|
+
formBody,
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
getProfile = (token) => {
|
|
178
|
+
return ApiUtils.get({
|
|
179
|
+
url: 'auth/profile',
|
|
180
|
+
headers: {
|
|
181
|
+
Authorization: `Bearer ${token}`,
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
};
|
|
185
|
+
|
|
163
186
|
/**
|
|
164
187
|
* create menu
|
|
165
188
|
*/
|
|
@@ -177,28 +200,46 @@ class MenusAPI extends Base {
|
|
|
177
200
|
* @param {*} menu
|
|
178
201
|
* @returns
|
|
179
202
|
*/
|
|
180
|
-
getMenus = (config) => {
|
|
203
|
+
getMenus = (config, dbPtr = null) => {
|
|
181
204
|
// Use 'core-menus' endpoint if REACT_APP_USE_CORE_MENUS is true (used for Matria)
|
|
182
205
|
const url =
|
|
183
206
|
process.env.REACT_APP_USE_CORE_MENUS === 'true'
|
|
184
207
|
? 'core-menus/get-menus' // Matria
|
|
185
208
|
: 'menus/get-menus'; // NURA
|
|
186
209
|
|
|
210
|
+
if (!dbPtr) dbPtr = localStorage.db_ptr;
|
|
187
211
|
return this.get({
|
|
188
212
|
url,
|
|
189
213
|
config,
|
|
214
|
+
headers: {
|
|
215
|
+
db_ptr: dbPtr,
|
|
216
|
+
},
|
|
217
|
+
}).then((result) => result);
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
getMenubyUser = (user_id) => {
|
|
221
|
+
const url = `menus/get-menus?userId=${user_id}`;
|
|
222
|
+
return this.get({
|
|
223
|
+
url,
|
|
190
224
|
}).then((result) => result);
|
|
191
225
|
};
|
|
192
226
|
|
|
193
227
|
// get core-menu list with submenu
|
|
194
228
|
getCoreMenuLists = () => {
|
|
195
229
|
const url = 'core-menus/core-menus?step=1&header_id=null';
|
|
196
|
-
|
|
197
230
|
return this.get({
|
|
198
231
|
url,
|
|
199
232
|
}).then((result) => result);
|
|
200
233
|
};
|
|
201
234
|
|
|
235
|
+
getCoreMenuByRoleId = async (role_id) => {
|
|
236
|
+
const url = `menus/get-menus-by-role/${role_id}`;
|
|
237
|
+
const result = await this.get({
|
|
238
|
+
url,
|
|
239
|
+
});
|
|
240
|
+
return result;
|
|
241
|
+
};
|
|
242
|
+
|
|
202
243
|
getCoreMenus = () => {
|
|
203
244
|
return [
|
|
204
245
|
// {
|
|
@@ -286,6 +327,12 @@ class MenusAPI extends Base {
|
|
|
286
327
|
// }
|
|
287
328
|
];
|
|
288
329
|
};
|
|
330
|
+
// license summary api call
|
|
331
|
+
getSummary = () => {
|
|
332
|
+
return ApiUtils.get({
|
|
333
|
+
url: 'license/summary',
|
|
334
|
+
});
|
|
335
|
+
};
|
|
289
336
|
}
|
|
290
337
|
|
|
291
338
|
export default MenusAPI;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState, useEffect, useContext } from 'react';
|
|
2
2
|
import { useLocation, useParams } from 'react-router-dom';
|
|
3
|
-
import { Skeleton, Typography, message, Form, Input, Collapse, Checkbox } from 'antd';
|
|
3
|
+
import { Skeleton, Typography, message, Form, Input, Collapse, Checkbox, Tag } from 'antd';
|
|
4
4
|
import { GlobalContext } from './../../../../lib';
|
|
5
5
|
import { Button } from './../../../../lib';
|
|
6
6
|
import { ModelsAPI, PagesAPI, RolesAPI, MenusAPI } from '../../..';
|
|
@@ -29,7 +29,9 @@ const RoleAdd = ({ model, callback, edit, formContent = {}, match, additional_qu
|
|
|
29
29
|
formContent.attributes = {};
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
const
|
|
32
|
+
const isEdit = !!(formContent.id || formContent.copy);
|
|
33
|
+
const [initialLoading, setInitialLoading] = useState(isEdit);
|
|
34
|
+
const [loading, setLoading] = useState(false);
|
|
33
35
|
const [form] = Form.useForm();
|
|
34
36
|
const [pages, setPages] = useState([]);
|
|
35
37
|
const [models, setModels] = useState([]);
|
|
@@ -49,36 +51,43 @@ const RoleAdd = ({ model, callback, edit, formContent = {}, match, additional_qu
|
|
|
49
51
|
|
|
50
52
|
// On component mount
|
|
51
53
|
useEffect(() => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
54
|
+
const fetchData = async () => {
|
|
55
|
+
if (isEdit) setInitialLoading(true);
|
|
56
|
+
try {
|
|
57
|
+
await Promise.all([getPages(), getModels(), loadMenus()]);
|
|
58
|
+
setShowMenus(true);
|
|
59
|
+
|
|
60
|
+
// Preselect menus when editing
|
|
61
|
+
if (formContent && formContent.menu_ids) {
|
|
62
|
+
let menus = formContent.menu_ids;
|
|
63
|
+
|
|
64
|
+
setSelectedMenus(menus);
|
|
65
|
+
// keep original copy for deselect comparison
|
|
66
|
+
setOriginalMenus(menus);
|
|
67
|
+
}
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.error('Error fetching data:', error);
|
|
70
|
+
} finally {
|
|
71
|
+
setInitialLoading(false);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
65
74
|
|
|
66
|
-
|
|
67
|
-
}, [formContent]);
|
|
75
|
+
fetchData();
|
|
76
|
+
}, [formContent, isEdit]);
|
|
68
77
|
|
|
69
78
|
// Load pages
|
|
70
79
|
const getPages = () => {
|
|
71
|
-
PagesAPI.getPages().then((res) => setPages(res.result || []));
|
|
80
|
+
return PagesAPI.getPages().then((res) => setPages(res.result || []));
|
|
72
81
|
};
|
|
73
82
|
|
|
74
83
|
// Load models
|
|
75
84
|
const getModels = () => {
|
|
76
|
-
ModelsAPI.get().then((res) => setModels(res.result || []));
|
|
85
|
+
return ModelsAPI.get().then((res) => setModels(res.result || []));
|
|
77
86
|
};
|
|
78
87
|
|
|
79
88
|
// Load top-level menus
|
|
80
89
|
const loadMenus = () => {
|
|
81
|
-
MenusAPI.getCoreMenuLists()
|
|
90
|
+
return MenusAPI.getCoreMenuLists()
|
|
82
91
|
.then((res) => setMenuList(res.result || []))
|
|
83
92
|
.catch(console.error);
|
|
84
93
|
};
|
|
@@ -156,13 +165,13 @@ const RoleAdd = ({ model, callback, edit, formContent = {}, match, additional_qu
|
|
|
156
165
|
|
|
157
166
|
return (
|
|
158
167
|
<section className="collection-add">
|
|
159
|
-
{
|
|
160
|
-
<Skeleton />
|
|
168
|
+
{initialLoading ? (
|
|
169
|
+
<Skeleton active paragraph={{ rows: 12 }} />
|
|
161
170
|
) : (
|
|
162
171
|
<Form initialValues={{ ...formContent }} form={form} layout="vertical" onFinish={onSubmit}>
|
|
163
172
|
{/* Role Name */}
|
|
164
173
|
<Form.Item name="name" label="Enter Role Name" rules={[{ required: true, message: 'Role name is required' }]}>
|
|
165
|
-
<Input placeholder="Enter name" />
|
|
174
|
+
<Input placeholder="Enter name" autoocus />
|
|
166
175
|
</Form.Item>
|
|
167
176
|
|
|
168
177
|
{/* Description */}
|
|
@@ -180,19 +189,31 @@ const RoleAdd = ({ model, callback, edit, formContent = {}, match, additional_qu
|
|
|
180
189
|
{/* MENU TREE */}
|
|
181
190
|
{showMenus && menuList.length > 0 && (
|
|
182
191
|
<div style={{ marginTop: 30 }}>
|
|
183
|
-
<
|
|
184
|
-
|
|
192
|
+
<div
|
|
193
|
+
style={{
|
|
194
|
+
display: 'flex',
|
|
195
|
+
justifyContent: 'space-between',
|
|
196
|
+
alignItems: 'center',
|
|
197
|
+
marginBottom: 16,
|
|
198
|
+
}}
|
|
199
|
+
>
|
|
200
|
+
<div>
|
|
201
|
+
<Title level={5} style={{ marginBottom: 0 }}>
|
|
202
|
+
Menu List
|
|
203
|
+
</Title>
|
|
204
|
+
<p style={{ color: '#999', marginBottom: 0 }}>Choose menus and set permissions</p>
|
|
205
|
+
</div>
|
|
206
|
+
|
|
207
|
+
<Form.Item style={{ marginBottom: 0 }}>
|
|
208
|
+
<Button loading={loading} htmlType="submit" type="primary">
|
|
209
|
+
Save
|
|
210
|
+
</Button>
|
|
211
|
+
</Form.Item>
|
|
212
|
+
</div>
|
|
185
213
|
|
|
186
214
|
<MenuTree menus={menuList} selectedMenus={selectedMenus} toggleMenu={toggleMenu} />
|
|
187
215
|
</div>
|
|
188
216
|
)}
|
|
189
|
-
|
|
190
|
-
{/* Submit Button */}
|
|
191
|
-
<Form.Item style={{ marginTop: 20 }}>
|
|
192
|
-
<Button loading={loading} htmlType="submit" type="primary">
|
|
193
|
-
Save
|
|
194
|
-
</Button>
|
|
195
|
-
</Form.Item>
|
|
196
217
|
</Form>
|
|
197
218
|
)}
|
|
198
219
|
</section>
|
|
@@ -248,32 +269,41 @@ const MenuTree = ({ menus, selectedMenus, toggleMenu, parentId = null }) => {
|
|
|
248
269
|
if (children.length === 0) {
|
|
249
270
|
return (
|
|
250
271
|
<div
|
|
251
|
-
key={menu.id}
|
|
252
272
|
style={{
|
|
273
|
+
justifyContent: 'space-between',
|
|
274
|
+
display: 'flex',
|
|
275
|
+
alignItems: 'center',
|
|
253
276
|
border: '1px solid rgba(198, 195, 195, 0.85)',
|
|
254
277
|
// borderRadius: 6,
|
|
255
278
|
padding: '12px 16px',
|
|
256
279
|
marginBottom: 6,
|
|
257
280
|
background: '#fff',
|
|
258
|
-
display: 'flex',
|
|
259
|
-
alignItems: 'center',
|
|
260
|
-
gap: 8,
|
|
261
281
|
}}
|
|
262
282
|
>
|
|
263
|
-
<
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
// ✅ FORCE parent selection
|
|
271
|
-
if (checked && parentId) {
|
|
272
|
-
toggleMenu(parentId, true);
|
|
273
|
-
}
|
|
283
|
+
<div
|
|
284
|
+
key={menu.id}
|
|
285
|
+
style={{
|
|
286
|
+
display: 'flex',
|
|
287
|
+
alignItems: 'center',
|
|
288
|
+
gap: 8,
|
|
274
289
|
}}
|
|
275
|
-
|
|
276
|
-
|
|
290
|
+
>
|
|
291
|
+
<Checkbox
|
|
292
|
+
checked={selectedMenus.includes(menu.id)}
|
|
293
|
+
onChange={(e) => {
|
|
294
|
+
const checked = e.target.checked;
|
|
295
|
+
|
|
296
|
+
toggleMenu(menu.id, checked);
|
|
297
|
+
|
|
298
|
+
// FORCE parent selection
|
|
299
|
+
if (checked && parentId) {
|
|
300
|
+
toggleMenu(parentId, true);
|
|
301
|
+
}
|
|
302
|
+
}}
|
|
303
|
+
/>
|
|
304
|
+
<span>{menu.caption}</span>
|
|
305
|
+
</div>
|
|
306
|
+
<Tag color={menu.is_visible === true ? 'green' : 'blue'}>{menu.is_visible === true ? 'VISIBLE' : 'HIDDEN'}</Tag>{' '}
|
|
277
307
|
</div>
|
|
278
308
|
);
|
|
279
309
|
}
|
|
@@ -287,16 +317,19 @@ const MenuTree = ({ menus, selectedMenus, toggleMenu, parentId = null }) => {
|
|
|
287
317
|
<Panel
|
|
288
318
|
key={menu.id}
|
|
289
319
|
header={
|
|
290
|
-
<div
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
320
|
+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
|
321
|
+
<div
|
|
322
|
+
style={{
|
|
323
|
+
display: 'flex',
|
|
324
|
+
alignItems: 'center',
|
|
325
|
+
gap: 8,
|
|
326
|
+
}}
|
|
327
|
+
onClick={(e) => e.stopPropagation()}
|
|
328
|
+
>
|
|
329
|
+
<Checkbox checked={parentChecked} indeterminate={parentIndeterminate} onChange={(e) => onParentChange(e.target.checked)} />
|
|
330
|
+
<span>{menu.caption}</span>
|
|
331
|
+
</div>
|
|
332
|
+
<Tag color={menu.is_visible === true ? 'green' : 'blue'}>{menu.is_visible === true ? 'VISIBLE' : 'HIDDEN'}</Tag>{' '}
|
|
300
333
|
</div>
|
|
301
334
|
}
|
|
302
335
|
>
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React, { useState, useEffect, useRef } from 'react';
|
|
2
2
|
|
|
3
3
|
import { Modal, Tabs, Input, Form, Row, Col, message, Checkbox, Select } from 'antd';
|
|
4
|
-
import { useTranslation, Button } from './../../../../lib/';
|
|
4
|
+
import { useTranslation, Button, CountryPhoneInput, phoneValidator as libPhoneValidator, formatPhoneForForm } from './../../../../lib/';
|
|
5
5
|
import { UsersAPI } from '../../..';
|
|
6
|
+
import { formatPhoneWithCountryCode } from '../../../../lib/utils/common/common.utils';
|
|
6
7
|
|
|
7
8
|
const StaffAdd = ({ visible, onCancel, staffId, staffData, onSuccess }) => {
|
|
8
9
|
const [form] = Form.useForm();
|
|
@@ -61,18 +62,6 @@ const StaffAdd = ({ visible, onCancel, staffId, staffData, onSuccess }) => {
|
|
|
61
62
|
}
|
|
62
63
|
}, [visible]);
|
|
63
64
|
|
|
64
|
-
const phoneValidator = (_, value) => {
|
|
65
|
-
if (!value) {
|
|
66
|
-
return Promise.resolve(); // not required
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (!/^\d{10}$/.test(value)) {
|
|
70
|
-
return Promise.reject('Phone number must be 10 digits');
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return Promise.resolve();
|
|
74
|
-
};
|
|
75
|
-
|
|
76
65
|
/** -------------------------------
|
|
77
66
|
* API CALL – Designations
|
|
78
67
|
* ------------------------------- */
|
|
@@ -201,8 +190,8 @@ const StaffAdd = ({ visible, onCancel, staffId, staffData, onSuccess }) => {
|
|
|
201
190
|
shortName: data.shortName,
|
|
202
191
|
description: data.description,
|
|
203
192
|
designation: data.designationPtr,
|
|
204
|
-
phone1: data.phone || data.mobile,
|
|
205
|
-
phone2: data.alternateMobile,
|
|
193
|
+
phone1: formatPhoneForForm(data.phone || data.mobile),
|
|
194
|
+
phone2: formatPhoneForForm(data.alternateMobile),
|
|
206
195
|
email1: data.email,
|
|
207
196
|
email2: data.alternateEmail,
|
|
208
197
|
slno: data.slNo,
|
|
@@ -223,14 +212,17 @@ const StaffAdd = ({ visible, onCancel, staffId, staffData, onSuccess }) => {
|
|
|
223
212
|
const handleFinish = async (values) => {
|
|
224
213
|
setLoading(true);
|
|
225
214
|
|
|
215
|
+
let phone1Value = formatPhoneWithCountryCode(values.phone1);
|
|
216
|
+
let phone2Value = formatPhoneWithCountryCode(values.phone2);
|
|
217
|
+
|
|
226
218
|
const payload = {
|
|
227
219
|
id: values.id,
|
|
228
220
|
shortName: values.shortName,
|
|
229
221
|
description: values.description,
|
|
230
222
|
designationPtr: values.designation ?? existing.designationPtr ?? null,
|
|
231
|
-
phone:
|
|
232
|
-
mobile:
|
|
233
|
-
alternateMobile:
|
|
223
|
+
phone: phone1Value ?? existing.phone ?? null,
|
|
224
|
+
mobile: phone1Value ?? existing.mobile ?? null,
|
|
225
|
+
alternateMobile: phone2Value ?? existing.alternateMobile ?? null,
|
|
234
226
|
email: values.email1 ?? existing.email ?? null,
|
|
235
227
|
alternateEmail: values.email2 ?? existing.alternateEmail ?? null,
|
|
236
228
|
remarks: values.remarks ?? existing.remarks ?? null,
|
|
@@ -331,26 +323,22 @@ const StaffAdd = ({ visible, onCancel, staffId, staffData, onSuccess }) => {
|
|
|
331
323
|
</Form.Item>
|
|
332
324
|
</Col> */}
|
|
333
325
|
<Col span={6}>
|
|
334
|
-
<Form.Item label="Phone Number" name="phone1" rules={[{ validator:
|
|
335
|
-
<
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
inputMode="numeric"
|
|
340
|
-
onChange={(e) => (e.target.value = e.target.value.replace(/\D/g, ''))}
|
|
326
|
+
<Form.Item label="Phone Number" name="phone1" validateTrigger="onBlur" rules={[{ validator: libPhoneValidator }]}>
|
|
327
|
+
<CountryPhoneInput
|
|
328
|
+
defaultCountryCode={process.env.REACT_APP_COUNTRYCODE}
|
|
329
|
+
enableSearch
|
|
330
|
+
inputStyle={{ width: '100%' }}
|
|
341
331
|
onKeyDown={handleEnterKey}
|
|
342
332
|
/>
|
|
343
333
|
</Form.Item>
|
|
344
334
|
</Col>
|
|
345
335
|
|
|
346
336
|
<Col span={6}>
|
|
347
|
-
<Form.Item label="Alternate Phone Number" name="phone2" rules={[{ validator:
|
|
348
|
-
<
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
inputMode="numeric"
|
|
353
|
-
onChange={(e) => (e.target.value = e.target.value.replace(/\D/g, ''))}
|
|
337
|
+
<Form.Item label="Alternate Phone Number" name="phone2" validateTrigger="onBlur" rules={[{ validator: libPhoneValidator }]}>
|
|
338
|
+
<CountryPhoneInput
|
|
339
|
+
defaultCountryCode={process.env.REACT_APP_COUNTRYCODE}
|
|
340
|
+
enableSearch
|
|
341
|
+
inputStyle={{ width: '100%' }}
|
|
354
342
|
onKeyDown={handleEnterKey}
|
|
355
343
|
/>
|
|
356
344
|
</Form.Item>
|