ui-soxo-bootstrap-core 2.6.39 → 2.6.40-dev.1

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 (23) hide show
  1. package/.github/workflows/npm-publish.yml +40 -33
  2. package/DEVELOPER_GUIDE.md +38 -9
  3. package/core/components/index.js +2 -11
  4. package/core/components/landing-api/landing-api.js +165 -5
  5. package/core/components/license-management/license-alert.js +97 -0
  6. package/core/lib/components/global-header/global-header.js +20 -77
  7. package/core/lib/components/index.js +2 -2
  8. package/core/lib/elements/basic/dragabble-wrapper/draggable-wrapper.js +91 -24
  9. package/core/lib/modules/generic/generic-list/ExportReactCSV.js +334 -8
  10. package/core/lib/modules/generic/generic-list/generic-list.scss +34 -0
  11. package/core/models/core-scripts/core-scripts.js +22 -1
  12. package/core/models/menus/menus.js +29 -1
  13. package/core/models/roles/components/role-add/menu-label.js +14 -0
  14. package/core/models/roles/components/role-add/menu-tree.js +127 -0
  15. package/core/models/roles/components/role-add/role-add.js +44 -167
  16. package/core/models/roles/components/role-list/role-list.js +20 -0
  17. package/core/models/users/components/assign-role/assign-role.js +23 -8
  18. package/core/modules/reporting/components/reporting-dashboard/display-columns/display-cell-renderer.js +202 -5
  19. package/core/modules/reporting/components/reporting-dashboard/display-columns/display-cell-renderer.test.js +73 -0
  20. package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.js +25 -5
  21. package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.scss +1 -0
  22. package/core/modules/reporting/components/reporting-dashboard/reporting-table.js +519 -0
  23. package/package.json +1 -1
@@ -2,136 +2,92 @@
2
2
  *
3
3
  * Global header component
4
4
  */
5
-
6
5
  import { useContext, useEffect, useRef, useState } from 'react';
7
-
8
6
  import { motion, useAnimation } from 'framer-motion';
9
-
10
7
  import { boxVariants } from './animations';
11
-
12
8
  import { GlobalContext, GlobalProvider } from './../../Store';
13
-
14
9
  import { Link, useLocation } from 'react-router-dom';
15
-
16
10
  import { Avatar, Input, Tooltip, Typography } from 'antd';
17
-
18
11
  import ProgressBar from '../progress-bar/progress-bar'; // Adjust the path as needed
19
-
20
12
  import { Button } from '../../elements';
21
-
22
13
  import GenericHeader from '../header/generic-header';
23
-
24
-
25
14
  import { CustomerServiceOutlined, MenuOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons';
26
-
27
15
  import { Drawer } from 'antd';
28
-
29
16
  import { ReloadOutlined, SearchOutlined } from '@ant-design/icons';
30
-
31
17
  import SideMenu from './../sidemenu/sidemenu';
32
-
33
18
  import './global-header.scss';
34
-
35
19
  import LanguageSwitcher from '../language-switcher/language-switcher';
36
-
37
20
  import { useTranslation } from 'react-i18next';
38
-
39
21
  import SettingsUtil from '../../../utils/settings.utils';
40
22
  import SpotlightSearch from '../spotlight-search/spotlight-search.component';
41
-
23
+ import { LicenseAlert } from '../../../components';
42
24
  const { Title } = Typography;
43
-
44
- function GlobalHeaderContent({ loading, appSettings, children, isConnected, history, modules = [], sidemenu = [], reload, meta = {}, ...props }) {
25
+ function GlobalHeaderContent({ loading, appSettings, children, isConnected, history, modules = [], sidemenu = [], reload, meta = {}, licAlert,
26
+ licenseData ,...props }) {
45
27
  let location = useLocation();
46
28
  // let location = {};
47
-
48
29
  const { isMobile, user = { locations: [] }, kiosk, state, settings } = useContext(GlobalContext);
49
-
50
30
  const [visible, setVisible] = useState(false);
51
31
  const helpDeskSetting = settings?.HELPATR || {};
52
-
53
32
  // Variable to handle toggling of menu
54
33
  const [collapsed, setCollapsed] = useState(false);
55
34
  // varibale handle branch switcher
56
-
57
35
  // const [searchModalVisible, setSearchModalVisible] = useState(false);
58
-
59
36
  const { globalCustomerHeader = () => {} } = appSettings;
60
-
61
37
  const { t, i18n } = useTranslation();
62
-
63
38
  const spotlightRef = useRef();
64
-
65
39
  useEffect(() => {
66
40
  setTimeout(() => {
67
41
  i18n.changeLanguage(localStorage.selectedLanguage);
68
42
  }, 0);
69
43
  }, []);
70
-
71
44
  /**
72
45
  * Function to handle toggling of menu
73
46
  */
74
-
75
47
  const toggleCollapsed = () => {
76
48
  setVisible(true);
77
-
78
49
  collapsed === true ? setCollapsed(false) : setCollapsed(true);
79
50
  };
80
-
81
51
  const openSearchModal = () => {
82
52
  // input to avoid typing
83
53
  SettingsUtil.openSpotlightModal();
84
54
  };
85
-
86
55
  /**
87
56
  * Function to remove toggling on mobile view
88
57
  */
89
58
  const hideToggle = () => {
90
59
  setVisible(true);
91
-
92
60
  setCollapsed(false);
93
61
  };
94
-
95
62
  /**
96
63
  * onClose Function
97
64
  */
98
-
99
65
  const onClose = () => {
100
66
  setVisible(false);
101
67
  };
102
-
103
68
  // const { model = {} } = menu;
104
-
105
69
  const { model: BaseModel = {}, menu = {} } = meta;
106
-
107
70
  const { model = {} } = menu;
108
-
109
71
  //Animations//
110
72
  const boxControls = useAnimation();
111
-
112
73
  async function animate() {
113
74
  await boxControls.start('entered');
114
-
115
75
  //await boxControls.start("show");
116
76
  }
117
-
118
77
  useEffect(() => {
119
78
  animate();
120
79
  }, []);
121
-
122
80
  useEffect(() => {}, [state.theme]);
123
-
124
81
  return (
82
+ <>
125
83
  <div
126
84
  className={`global-header ${process.env.REACT_APP_THEME} ${isConnected && !kiosk ? 'connected' : ''}`}
127
85
  style={{
128
86
  // background: state.theme.colors.bodyBackground,
129
-
130
- height: 10,
87
+ height: 'auto',
131
88
  }}
132
89
  >
133
90
  {/* <MenuOutlined style={{left:'1%',top:'1%', fontSize:18, position:'absolute', zIndex:999}} onClick={showSidebar}/> */}
134
-
135
91
  <div className="layout-content">
136
92
  <div
137
93
  //whileHover="hover"
@@ -174,7 +130,6 @@ function GlobalHeaderContent({ loading, appSettings, children, isConnected, hist
174
130
  </Drawer>
175
131
  )}
176
132
  </div>
177
-
178
133
  {/* Right Section of the Component Loader */}
179
134
  <div
180
135
  className={`right-section ${!collapsed ? 'open' : 'close'} ${kiosk ? 'kioskon' : ''}`}
@@ -189,11 +144,9 @@ function GlobalHeaderContent({ loading, appSettings, children, isConnected, hist
189
144
  {/* */}
190
145
  <div className="page-header-name">
191
146
  <ProgressBar isLoading={loading} />
192
-
193
147
  <span type onClick={!isMobile ? toggleCollapsed : hideToggle} className="toggle-box toggle-menu">
194
148
  <MenuOutlined />
195
149
  </span>
196
-
197
150
  {/* Back Button */}
198
151
  {location.pathname !== '/' ? (
199
152
  <span
@@ -206,39 +159,30 @@ function GlobalHeaderContent({ loading, appSettings, children, isConnected, hist
206
159
  </span>
207
160
  ) : null}
208
161
  {/* Back Button Ends */}
209
-
210
162
  {location.pathname !== '/' ? (
211
163
  <h4 className="menu-caption header-caption" style={{ color: state.theme.colors.headerColor }}>
212
164
  {menu.caption}
213
165
  </h4>
214
166
  ) : null}
215
167
  </div>
216
-
217
168
  {/* Page Menu Actions */}
218
-
219
169
  {user.role || user.id ? (
220
170
  <div className="page-menu">
221
171
  {/* Search Input in header start */}
222
172
  {!isMobile && (
223
173
  <div>
224
174
  <Input placeholder="Search (Shift + F)" prefix={<SearchOutlined />} onClick={openSearchModal} readOnly style={{ width: 250 }} />
225
-
226
175
  <SpotlightSearch ref={(elem) => SettingsUtil.registerModal(elem)} props={props} />
227
176
  </div>
228
177
  )}
229
178
  {/* Search Input in header start */}
230
-
231
179
  {/** branchswitcher Option */}
232
180
  {/* branch switcher controlled with env for matria and nura */}
233
181
  {!process.env.REACT_APP_SHOW_BRANCH_SWITCHER ? <div className="branch-switcher">{globalCustomerHeader()}</div> : null}
234
182
  {/* <div className="branch-switcher">{globalCustomerHeader()}</div> */}
235
-
236
183
  {/* Search Option */}
237
-
238
184
  {/* <ModalSearch /> */}
239
-
240
185
  {/* Search Option Ends */}
241
-
242
186
  {/* Configurator Actions */}
243
187
  {user.isAdmin ? (
244
188
  <>
@@ -252,13 +196,9 @@ function GlobalHeaderContent({ loading, appSettings, children, isConnected, hist
252
196
  </>
253
197
  ) : null}
254
198
  {/* Configurator Actions Ends */}
255
-
256
199
  {/* Reload Button */}
257
-
258
200
  <Button onClick={reload} icon={<ReloadOutlined />} type="default" size={'small'}></Button>
259
-
260
201
  {/* Reload Button Ends */}
261
-
262
202
  {/* Help-desk-btn */}
263
203
  {helpDeskSetting?.showSupportBtn
264
204
  ? (() => {
@@ -277,11 +217,9 @@ function GlobalHeaderContent({ loading, appSettings, children, isConnected, hist
277
217
  );
278
218
  })()
279
219
  : null}
280
-
281
220
  {/** Switch Languages starts */}
282
221
  {process.env.REACT_APP_ENABLE_LANGUAGE_SWITCHER ? <LanguageSwitcher /> : null}
283
222
  {/** Switch Languages ends */}
284
-
285
223
  {/* User Profile */}
286
224
  <div style={{ padding: '10px' }}>
287
225
  <ProfileAvatar />
@@ -290,11 +228,9 @@ function GlobalHeaderContent({ loading, appSettings, children, isConnected, hist
290
228
  {/* User Profile Ends */}
291
229
  </div>
292
230
  ) : null}
293
-
294
231
  {/* Page Menu Actions Ends */}
295
232
  </div>
296
233
  ) : null}
297
-
298
234
  {/* The children is rendered */}
299
235
  {children}
300
236
  {/* The children is rendered */}
@@ -302,32 +238,40 @@ function GlobalHeaderContent({ loading, appSettings, children, isConnected, hist
302
238
  {/* Right Section of the Component Loader Ends */}
303
239
  </div>
304
240
  </div>
241
+ {licAlert && licenseData && (
242
+ <div
243
+ style={{
244
+ top: 0,
245
+ marginTop: '3rem',
246
+ right: '2%',
247
+ position: 'absolute',
248
+ zIndex: 1008,
249
+ }}
250
+ >
251
+ <LicenseAlert data={licenseData} />
252
+ </div>
253
+ )}
254
+ </>
305
255
  );
306
256
  }
307
-
308
257
  export default function GlobalHeader(props) {
309
258
  const context = useContext(GlobalContext);
310
-
311
259
  if (context.dispatch) {
312
260
  return <GlobalHeaderContent {...props} />;
313
261
  }
314
-
315
262
  return (
316
263
  <GlobalProvider {...props} appSettings={props.appSettings}>
317
264
  <GlobalHeaderContent {...props} />
318
265
  </GlobalProvider>
319
266
  );
320
267
  }
321
-
322
268
  /**
323
269
  *
324
270
  * @returns
325
271
  */
326
272
  function ProfileAvatar() {
327
273
  const { user = { locations: [] } } = useContext(GlobalContext);
328
-
329
274
  useEffect(() => {}, []);
330
-
331
275
  return (
332
276
  <Link className="profile-avatar" to="/profile">
333
277
  {user.photograph ? (
@@ -337,8 +281,7 @@ function ProfileAvatar() {
337
281
  ) : (
338
282
  <Avatar shape="square" size="small" icon={<UserOutlined />} />
339
283
  )}
340
-
341
284
  {/* {user.name} */}
342
285
  </Link>
343
286
  );
344
- }
287
+ }
@@ -109,7 +109,7 @@ import ConsentComponent from './consent/consent'
109
109
  import TaskOverviewLegacy from './../models/process/components/task-overview-legacy/task-overview-legacy'
110
110
 
111
111
  import ReportingDashboard from '../../modules/reporting/components/reporting-dashboard/reporting-dashboard';
112
-
112
+ import ReportingTable from '../../modules/reporting/components/reporting-dashboard/reporting-table'
113
113
  import ProcessStepsPage from '../../modules/steps/steps'
114
114
  export {
115
115
 
@@ -198,7 +198,7 @@ export {
198
198
  TaskOverviewLegacy,
199
199
  // WebCamera,
200
200
  ConsentComponent,
201
-
201
+ ReportingTable,
202
202
  ReportingDashboard,
203
203
  ProcessStepsPage
204
204
 
@@ -1,26 +1,27 @@
1
- import React, { useRef } from 'react';
1
+ import React, { useRef, useEffect } from 'react';
2
2
  import { useDrag, useDrop } from 'react-dnd';
3
3
 
4
- export default function DraggableWrapper({ id, index, movePanel, item, dragEnabled, level, parentId, onCrossLevelMove, canAcceptChildren }) {
5
- const autoScrollWindow = (monitor) => {
6
- const offset = monitor.getClientOffset();
7
- if (!offset) return;
8
-
9
- const EDGE = 80;
10
- const SPEED = 20;
11
-
12
- const viewportHeight = window.innerHeight;
13
-
14
- // 🔼 scroll UP
15
- if (offset.y < EDGE) {
16
- window.scrollBy(0, -SPEED);
17
- }
4
+ // Walk up the DOM to find the nearest vertically-scrollable ancestor.
5
+ // Returns null when the page (window) is the scroller.
6
+ function getScrollableAncestor(node) {
7
+ let el = node?.parentElement;
8
+ while (el) {
9
+ const { overflowY } = window.getComputedStyle(el);
10
+ const scrollable = overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'overlay';
11
+ if (scrollable && el.scrollHeight > el.clientHeight) return el;
12
+ el = el.parentElement;
13
+ }
14
+ return null;
15
+ }
18
16
 
19
- // 🔽 scroll DOWN
20
- if (offset.y > viewportHeight - EDGE) {
21
- window.scrollBy(0, SPEED);
22
- }
23
- };
17
+ export default function DraggableWrapper({ id, index, movePanel, item, dragEnabled, level, parentId, onCrossLevelMove, canAcceptChildren }) {
18
+ // Root DOM node, used to locate the scrollable ancestor at drag time
19
+ const rootRef = useRef(null);
20
+ // Latest pointer Y, fed by a document-level `dragover` listener (see effect below)
21
+ const pointerY = useRef(0);
22
+ const rafRef = useRef(null);
23
+ // The scrollable container to auto-scroll (resolved when a drag starts)
24
+ const scrollContainerRef = useRef(null);
24
25
 
25
26
  const [{ isDragging }, drag] = useDrag({
26
27
  type: 'PANEL',
@@ -31,12 +32,78 @@ export default function DraggableWrapper({ id, index, movePanel, item, dragEnabl
31
32
  }),
32
33
  });
33
34
 
35
+ /**
36
+ * Continuous edge auto-scroll while THIS item is being dragged.
37
+ *
38
+ * Driven by a document-level `dragover` listener + requestAnimationFrame loop
39
+ * rather than the drop target's `hover` handler. `hover` only fires while the
40
+ * pointer is over a droppable panel and only on movement, so scrolling UP
41
+ * failed: the top of the viewport is the (non-droppable) header, and holding
42
+ * the pointer still at an edge produced no events. The rAF loop keeps
43
+ * scrolling from the last known pointer position regardless of what's beneath.
44
+ *
45
+ * The list may scroll inside an overflow container rather than the window, so
46
+ * we resolve the nearest scrollable ancestor and scroll that (falling back to
47
+ * the window), computing the edges from the container's own bounds.
48
+ */
49
+ useEffect(() => {
50
+ if (!isDragging) return;
51
+
52
+ const EDGE = 80;
53
+ const SPEED = 20;
54
+
55
+ scrollContainerRef.current = getScrollableAncestor(rootRef.current);
56
+
57
+ const onDragOver = (e) => {
58
+ pointerY.current = e.clientY;
59
+ };
60
+
61
+ const tick = () => {
62
+ const y = pointerY.current;
63
+
64
+ if (y > 0) {
65
+ const container = scrollContainerRef.current;
66
+
67
+ if (container) {
68
+ const rect = container.getBoundingClientRect();
69
+ // near container top
70
+ if (y < rect.top + EDGE) {
71
+ container.scrollTop -= SPEED;
72
+ }
73
+ // near container bottom
74
+ else if (y > rect.bottom - EDGE) {
75
+ container.scrollTop += SPEED;
76
+ }
77
+ } else {
78
+ const viewportHeight = window.innerHeight;
79
+ // near viewport top
80
+ if (y < EDGE) {
81
+ window.scrollBy(0, -SPEED);
82
+ }
83
+ // near viewport bottom
84
+ else if (y > viewportHeight - EDGE) {
85
+ window.scrollBy(0, SPEED);
86
+ }
87
+ }
88
+ }
89
+
90
+ rafRef.current = requestAnimationFrame(tick);
91
+ };
92
+
93
+ window.addEventListener('dragover', onDragOver);
94
+ rafRef.current = requestAnimationFrame(tick);
95
+
96
+ return () => {
97
+ window.removeEventListener('dragover', onDragOver);
98
+ if (rafRef.current) cancelAnimationFrame(rafRef.current);
99
+ pointerY.current = 0;
100
+ scrollContainerRef.current = null;
101
+ };
102
+ }, [isDragging]);
103
+
34
104
  const [{ isOver, canDrop }, drop] = useDrop({
35
105
  accept: 'PANEL',
36
106
  hover: (dragItem, monitor) => {
37
- // THIS FIXES BOTTOM → TOP
38
- autoScrollWindow(monitor);
39
-
40
107
  if (dragItem.index === index) return;
41
108
 
42
109
  if (dragItem.level === level && dragItem.parentId === parentId) {
@@ -85,7 +152,7 @@ export default function DraggableWrapper({ id, index, movePanel, item, dragEnabl
85
152
  const childZoneBackgroundColor = isOverChild && canDropChild ? '#d4f4dd' : 'transparent';
86
153
 
87
154
  return (
88
- <div style={{ width: '100%', display: 'flex' }}>
155
+ <div ref={rootRef} style={{ width: '100%', display: 'flex' }}>
89
156
  {/* HEADER DROP — reorder only */}
90
157
  <div ref={drop}>
91
158
  <div