ui-soxo-bootstrap-core 2.6.43 → 2.6.44
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/index.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
1
|
import LandingAPI from './landing-api/landing-api';
|
|
6
2
|
|
|
7
3
|
import ExtraInfoDetail from './extra-info/extra-info-details';
|
|
@@ -11,11 +7,6 @@ import RootApplicationAPI from './root-application-api/root-application-api';
|
|
|
11
7
|
import { HomePageAPI } from '../modules';
|
|
12
8
|
|
|
13
9
|
import { ExternalWindow } from './external-window/external-window';
|
|
10
|
+
import LicenseAlert from './license-management/license-alert';
|
|
14
11
|
|
|
15
|
-
export {
|
|
16
|
-
LandingAPI,
|
|
17
|
-
RootApplicationAPI,
|
|
18
|
-
ExtraInfoDetail,
|
|
19
|
-
HomePageAPI,
|
|
20
|
-
ExternalWindow
|
|
21
|
-
}
|
|
12
|
+
export { LandingAPI, RootApplicationAPI, ExtraInfoDetail, HomePageAPI, ExternalWindow, LicenseAlert };
|
|
@@ -59,11 +59,29 @@ export default function LandingApi({ history, CustomComponents, CustomModels, ap
|
|
|
59
59
|
|
|
60
60
|
const [meta, setMeta] = useState({});
|
|
61
61
|
const [loadingMessage, setLoadingMessage] = useState('');
|
|
62
|
+
const [licenseData, setLicenseData] = useState(null);
|
|
63
|
+
const [licAlert, setLicAlert] = useState(false);
|
|
62
64
|
|
|
63
65
|
// const [reports, setReports] = useState([]);
|
|
64
66
|
|
|
65
67
|
var config = {};
|
|
66
68
|
|
|
69
|
+
//fetch license summary
|
|
70
|
+
const fetchSummary = async () => {
|
|
71
|
+
try {
|
|
72
|
+
const res = await MenusAPI.getSummary();
|
|
73
|
+
if (res?.data) {
|
|
74
|
+
setLicenseData(res?.data);
|
|
75
|
+
setLicAlert(true);
|
|
76
|
+
} else {
|
|
77
|
+
setLicenseData(null);
|
|
78
|
+
setLicAlert(false);
|
|
79
|
+
}
|
|
80
|
+
} catch (err) {
|
|
81
|
+
console.error(err);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
67
85
|
// Variable decides the control of homepage
|
|
68
86
|
// #TODO This is a temporary fix - Homemage
|
|
69
87
|
|
|
@@ -138,9 +156,12 @@ export default function LandingApi({ history, CustomComponents, CustomModels, ap
|
|
|
138
156
|
*/
|
|
139
157
|
async function initializeUserMenus() {
|
|
140
158
|
// need to find what implement, with a login who has the respective value ("wug_custreportids")
|
|
159
|
+
|
|
141
160
|
const report = await loadScripts(user);
|
|
142
161
|
|
|
143
162
|
await loadMenus(report);
|
|
163
|
+
// fetch license summary
|
|
164
|
+
fetchSummary();
|
|
144
165
|
}
|
|
145
166
|
|
|
146
167
|
// const keyMap = {
|
|
@@ -292,6 +313,8 @@ export default function LandingApi({ history, CustomComponents, CustomModels, ap
|
|
|
292
313
|
modules={allModules}
|
|
293
314
|
user={user}
|
|
294
315
|
history={history}
|
|
316
|
+
licenseData={licenseData}
|
|
317
|
+
licAlert={licAlert}
|
|
295
318
|
>
|
|
296
319
|
{loader ? (
|
|
297
320
|
<Card className="skeleton-card">
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Alert } from 'antd';
|
|
2
|
+
import React, { useState, useEffect } from 'react';
|
|
3
|
+
|
|
4
|
+
export default function LicenseAlert({ data }) {
|
|
5
|
+
// setting visibility of alert based on license status
|
|
6
|
+
const [visible, setVisible] = useState(true);
|
|
7
|
+
// resolve alert configuration based on license data
|
|
8
|
+
const alertConfig = resolveLicenseAlert(data);
|
|
9
|
+
// auto-hide alert after 10 seconds or when data changes
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (alertConfig) {
|
|
12
|
+
setVisible(true);
|
|
13
|
+
|
|
14
|
+
const timer = setTimeout(() => {
|
|
15
|
+
setVisible(false);
|
|
16
|
+
}, 10000); // 10 seconds
|
|
17
|
+
|
|
18
|
+
return () => {
|
|
19
|
+
clearTimeout(timer);
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
}, [data]);
|
|
23
|
+
// if no alert configuration or not visible, render nothing
|
|
24
|
+
if (!alertConfig || !visible) return null;
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
// render the alert with appropriate type, message, and description
|
|
28
|
+
<Alert
|
|
29
|
+
type={alertConfig.type}
|
|
30
|
+
message={alertConfig.message}
|
|
31
|
+
description={alertConfig.description}
|
|
32
|
+
showIcon
|
|
33
|
+
closable
|
|
34
|
+
onClose={() => setVisible(false)}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
// function to determine alert configuration based on license data
|
|
39
|
+
function resolveLicenseAlert(data) {
|
|
40
|
+
if (!data) return null;
|
|
41
|
+
// destructure relevant fields from license data
|
|
42
|
+
const { status, expiresInDays, isExpiringSoon, gracePeriod } = data;
|
|
43
|
+
|
|
44
|
+
// ===== NOT INSTALLED =====
|
|
45
|
+
if (status === 'NOT_INSTALLED') {
|
|
46
|
+
return {
|
|
47
|
+
type: 'error',
|
|
48
|
+
message: 'License not found',
|
|
49
|
+
description: 'Please install a valid license to continue.',
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// ===== GRACE PERIOD =====
|
|
54
|
+
if (gracePeriod) {
|
|
55
|
+
return {
|
|
56
|
+
type: 'warning',
|
|
57
|
+
message: 'Grace period mode',
|
|
58
|
+
description: 'License expired. Running in read-only mode.',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ===== EXPIRING SOON =====
|
|
63
|
+
if (status === 'ACTIVE' && isExpiringSoon) {
|
|
64
|
+
let descriptionText = '';
|
|
65
|
+
// customize message based on how soon the license is expiring
|
|
66
|
+
if (expiresInDays === 0) {
|
|
67
|
+
descriptionText = 'Your license will expire today. Please renew immediately.';
|
|
68
|
+
} else {
|
|
69
|
+
descriptionText = `Your license will expire in ${expiresInDays} days. Please plan for renewal.`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
type: 'warning',
|
|
74
|
+
message: 'License expiring soon',
|
|
75
|
+
description: descriptionText,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ===== NOT INSTALLED =====
|
|
80
|
+
if (status === 'NOT_INSTALLED') {
|
|
81
|
+
return {
|
|
82
|
+
type: 'error',
|
|
83
|
+
message: 'License not found',
|
|
84
|
+
description: 'Please install a valid license to continue.',
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// =====EXPIRED=====
|
|
88
|
+
if (status === 'EXPIRED') {
|
|
89
|
+
return {
|
|
90
|
+
type: 'error',
|
|
91
|
+
message: 'License expired',
|
|
92
|
+
description: 'Your license has expired. Please renew or install a new license.',
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
@@ -2,136 +2,93 @@
|
|
|
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';
|
|
23
|
+
import LicenseAlert from '../../../components/license-management/license-alert';
|
|
41
24
|
|
|
42
25
|
const { Title } = Typography;
|
|
43
|
-
|
|
44
|
-
|
|
26
|
+
function GlobalHeaderContent({ loading, appSettings, children, isConnected, history, modules = [], sidemenu = [], reload, meta = {}, licAlert,
|
|
27
|
+
licenseData,...props }) {
|
|
45
28
|
let location = useLocation();
|
|
46
29
|
// let location = {};
|
|
47
|
-
|
|
48
30
|
const { isMobile, user = { locations: [] }, kiosk, state, settings } = useContext(GlobalContext);
|
|
49
|
-
|
|
50
31
|
const [visible, setVisible] = useState(false);
|
|
51
32
|
const helpDeskSetting = settings?.HELPATR || {};
|
|
52
|
-
|
|
53
33
|
// Variable to handle toggling of menu
|
|
54
34
|
const [collapsed, setCollapsed] = useState(false);
|
|
55
35
|
// varibale handle branch switcher
|
|
56
|
-
|
|
57
36
|
// const [searchModalVisible, setSearchModalVisible] = useState(false);
|
|
58
|
-
|
|
59
37
|
const { globalCustomerHeader = () => {} } = appSettings;
|
|
60
|
-
|
|
61
38
|
const { t, i18n } = useTranslation();
|
|
62
|
-
|
|
63
39
|
const spotlightRef = useRef();
|
|
64
|
-
|
|
65
40
|
useEffect(() => {
|
|
66
41
|
setTimeout(() => {
|
|
67
42
|
i18n.changeLanguage(localStorage.selectedLanguage);
|
|
68
43
|
}, 0);
|
|
69
44
|
}, []);
|
|
70
|
-
|
|
71
45
|
/**
|
|
72
46
|
* Function to handle toggling of menu
|
|
73
47
|
*/
|
|
74
|
-
|
|
75
48
|
const toggleCollapsed = () => {
|
|
76
49
|
setVisible(true);
|
|
77
|
-
|
|
78
50
|
collapsed === true ? setCollapsed(false) : setCollapsed(true);
|
|
79
51
|
};
|
|
80
|
-
|
|
81
52
|
const openSearchModal = () => {
|
|
82
53
|
// input to avoid typing
|
|
83
54
|
SettingsUtil.openSpotlightModal();
|
|
84
55
|
};
|
|
85
|
-
|
|
86
56
|
/**
|
|
87
57
|
* Function to remove toggling on mobile view
|
|
88
58
|
*/
|
|
89
59
|
const hideToggle = () => {
|
|
90
60
|
setVisible(true);
|
|
91
|
-
|
|
92
61
|
setCollapsed(false);
|
|
93
62
|
};
|
|
94
|
-
|
|
95
63
|
/**
|
|
96
64
|
* onClose Function
|
|
97
65
|
*/
|
|
98
|
-
|
|
99
66
|
const onClose = () => {
|
|
100
67
|
setVisible(false);
|
|
101
68
|
};
|
|
102
|
-
|
|
103
69
|
// const { model = {} } = menu;
|
|
104
|
-
|
|
105
70
|
const { model: BaseModel = {}, menu = {} } = meta;
|
|
106
|
-
|
|
107
71
|
const { model = {} } = menu;
|
|
108
|
-
|
|
109
72
|
//Animations//
|
|
110
73
|
const boxControls = useAnimation();
|
|
111
|
-
|
|
112
74
|
async function animate() {
|
|
113
75
|
await boxControls.start('entered');
|
|
114
|
-
|
|
115
76
|
//await boxControls.start("show");
|
|
116
77
|
}
|
|
117
|
-
|
|
118
78
|
useEffect(() => {
|
|
119
79
|
animate();
|
|
120
80
|
}, []);
|
|
121
|
-
|
|
122
81
|
useEffect(() => {}, [state.theme]);
|
|
123
|
-
|
|
124
82
|
return (
|
|
83
|
+
<>
|
|
125
84
|
<div
|
|
126
85
|
className={`global-header ${process.env.REACT_APP_THEME} ${isConnected && !kiosk ? 'connected' : ''}`}
|
|
127
86
|
style={{
|
|
128
87
|
// background: state.theme.colors.bodyBackground,
|
|
129
|
-
|
|
130
|
-
height: 10,
|
|
88
|
+
height: auto,
|
|
131
89
|
}}
|
|
132
90
|
>
|
|
133
91
|
{/* <MenuOutlined style={{left:'1%',top:'1%', fontSize:18, position:'absolute', zIndex:999}} onClick={showSidebar}/> */}
|
|
134
|
-
|
|
135
92
|
<div className="layout-content">
|
|
136
93
|
<div
|
|
137
94
|
//whileHover="hover"
|
|
@@ -174,7 +131,6 @@ function GlobalHeaderContent({ loading, appSettings, children, isConnected, hist
|
|
|
174
131
|
</Drawer>
|
|
175
132
|
)}
|
|
176
133
|
</div>
|
|
177
|
-
|
|
178
134
|
{/* Right Section of the Component Loader */}
|
|
179
135
|
<div
|
|
180
136
|
className={`right-section ${!collapsed ? 'open' : 'close'} ${kiosk ? 'kioskon' : ''}`}
|
|
@@ -189,11 +145,9 @@ function GlobalHeaderContent({ loading, appSettings, children, isConnected, hist
|
|
|
189
145
|
{/* */}
|
|
190
146
|
<div className="page-header-name">
|
|
191
147
|
<ProgressBar isLoading={loading} />
|
|
192
|
-
|
|
193
148
|
<span type onClick={!isMobile ? toggleCollapsed : hideToggle} className="toggle-box toggle-menu">
|
|
194
149
|
<MenuOutlined />
|
|
195
150
|
</span>
|
|
196
|
-
|
|
197
151
|
{/* Back Button */}
|
|
198
152
|
{location.pathname !== '/' ? (
|
|
199
153
|
<span
|
|
@@ -206,39 +160,30 @@ function GlobalHeaderContent({ loading, appSettings, children, isConnected, hist
|
|
|
206
160
|
</span>
|
|
207
161
|
) : null}
|
|
208
162
|
{/* Back Button Ends */}
|
|
209
|
-
|
|
210
163
|
{location.pathname !== '/' ? (
|
|
211
164
|
<h4 className="menu-caption header-caption" style={{ color: state.theme.colors.headerColor }}>
|
|
212
165
|
{menu.caption}
|
|
213
166
|
</h4>
|
|
214
167
|
) : null}
|
|
215
168
|
</div>
|
|
216
|
-
|
|
217
169
|
{/* Page Menu Actions */}
|
|
218
|
-
|
|
219
170
|
{user.role || user.id ? (
|
|
220
171
|
<div className="page-menu">
|
|
221
172
|
{/* Search Input in header start */}
|
|
222
173
|
{!isMobile && (
|
|
223
174
|
<div>
|
|
224
175
|
<Input placeholder="Search (Shift + F)" prefix={<SearchOutlined />} onClick={openSearchModal} readOnly style={{ width: 250 }} />
|
|
225
|
-
|
|
226
176
|
<SpotlightSearch ref={(elem) => SettingsUtil.registerModal(elem)} props={props} />
|
|
227
177
|
</div>
|
|
228
178
|
)}
|
|
229
179
|
{/* Search Input in header start */}
|
|
230
|
-
|
|
231
180
|
{/** branchswitcher Option */}
|
|
232
181
|
{/* branch switcher controlled with env for matria and nura */}
|
|
233
182
|
{!process.env.REACT_APP_SHOW_BRANCH_SWITCHER ? <div className="branch-switcher">{globalCustomerHeader()}</div> : null}
|
|
234
183
|
{/* <div className="branch-switcher">{globalCustomerHeader()}</div> */}
|
|
235
|
-
|
|
236
184
|
{/* Search Option */}
|
|
237
|
-
|
|
238
185
|
{/* <ModalSearch /> */}
|
|
239
|
-
|
|
240
186
|
{/* Search Option Ends */}
|
|
241
|
-
|
|
242
187
|
{/* Configurator Actions */}
|
|
243
188
|
{user.isAdmin ? (
|
|
244
189
|
<>
|
|
@@ -252,13 +197,9 @@ function GlobalHeaderContent({ loading, appSettings, children, isConnected, hist
|
|
|
252
197
|
</>
|
|
253
198
|
) : null}
|
|
254
199
|
{/* Configurator Actions Ends */}
|
|
255
|
-
|
|
256
200
|
{/* Reload Button */}
|
|
257
|
-
|
|
258
201
|
<Button onClick={reload} icon={<ReloadOutlined />} type="default" size={'small'}></Button>
|
|
259
|
-
|
|
260
202
|
{/* Reload Button Ends */}
|
|
261
|
-
|
|
262
203
|
{/* Help-desk-btn */}
|
|
263
204
|
{helpDeskSetting?.showSupportBtn
|
|
264
205
|
? (() => {
|
|
@@ -277,11 +218,9 @@ function GlobalHeaderContent({ loading, appSettings, children, isConnected, hist
|
|
|
277
218
|
);
|
|
278
219
|
})()
|
|
279
220
|
: null}
|
|
280
|
-
|
|
281
221
|
{/** Switch Languages starts */}
|
|
282
222
|
{process.env.REACT_APP_ENABLE_LANGUAGE_SWITCHER ? <LanguageSwitcher /> : null}
|
|
283
223
|
{/** Switch Languages ends */}
|
|
284
|
-
|
|
285
224
|
{/* User Profile */}
|
|
286
225
|
<div style={{ padding: '10px' }}>
|
|
287
226
|
<ProfileAvatar />
|
|
@@ -290,11 +229,9 @@ function GlobalHeaderContent({ loading, appSettings, children, isConnected, hist
|
|
|
290
229
|
{/* User Profile Ends */}
|
|
291
230
|
</div>
|
|
292
231
|
) : null}
|
|
293
|
-
|
|
294
232
|
{/* Page Menu Actions Ends */}
|
|
295
233
|
</div>
|
|
296
234
|
) : null}
|
|
297
|
-
|
|
298
235
|
{/* The children is rendered */}
|
|
299
236
|
{children}
|
|
300
237
|
{/* The children is rendered */}
|
|
@@ -302,32 +239,40 @@ function GlobalHeaderContent({ loading, appSettings, children, isConnected, hist
|
|
|
302
239
|
{/* Right Section of the Component Loader Ends */}
|
|
303
240
|
</div>
|
|
304
241
|
</div>
|
|
242
|
+
{licAlert && licenseData && (
|
|
243
|
+
<div
|
|
244
|
+
style={{
|
|
245
|
+
top: 0,
|
|
246
|
+
marginTop: '3rem',
|
|
247
|
+
right: '2%',
|
|
248
|
+
position: 'absolute',
|
|
249
|
+
zIndex: 1008,
|
|
250
|
+
}}
|
|
251
|
+
>
|
|
252
|
+
<LicenseAlert data={licenseData} />
|
|
253
|
+
</div>
|
|
254
|
+
)}
|
|
255
|
+
</>
|
|
305
256
|
);
|
|
306
257
|
}
|
|
307
|
-
|
|
308
258
|
export default function GlobalHeader(props) {
|
|
309
259
|
const context = useContext(GlobalContext);
|
|
310
|
-
|
|
311
260
|
if (context.dispatch) {
|
|
312
261
|
return <GlobalHeaderContent {...props} />;
|
|
313
262
|
}
|
|
314
|
-
|
|
315
263
|
return (
|
|
316
264
|
<GlobalProvider {...props} appSettings={props.appSettings}>
|
|
317
265
|
<GlobalHeaderContent {...props} />
|
|
318
266
|
</GlobalProvider>
|
|
319
267
|
);
|
|
320
268
|
}
|
|
321
|
-
|
|
322
269
|
/**
|
|
323
270
|
*
|
|
324
271
|
* @returns
|
|
325
272
|
*/
|
|
326
273
|
function ProfileAvatar() {
|
|
327
274
|
const { user = { locations: [] } } = useContext(GlobalContext);
|
|
328
|
-
|
|
329
275
|
useEffect(() => {}, []);
|
|
330
|
-
|
|
331
276
|
return (
|
|
332
277
|
<Link className="profile-avatar" to="/profile">
|
|
333
278
|
{user.photograph ? (
|
|
@@ -337,7 +282,6 @@ function ProfileAvatar() {
|
|
|
337
282
|
) : (
|
|
338
283
|
<Avatar shape="square" size="small" icon={<UserOutlined />} />
|
|
339
284
|
)}
|
|
340
|
-
|
|
341
285
|
{/* {user.name} */}
|
|
342
286
|
</Link>
|
|
343
287
|
);
|