asab_webui_shell 27.7.0 → 27.7.2
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/dist/containers/Application.js +68 -9
- package/dist/modules/attentionrequired/components/OfflineIndication.js +4 -2
- package/dist/modules/attentionrequired/components/OfflineIndication.jsx +2 -2
- package/dist/styles/constants/index.scss +11 -0
- package/dist/utils/statusAlerts.js +27 -0
- package/dist/utils/statusAlerts.jsx +21 -0
- package/package.json +1 -1
|
@@ -11,6 +11,7 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
11
11
|
var _axios = _interopRequireDefault(require("axios"));
|
|
12
12
|
var _asab_webui_components = require("asab_webui_components");
|
|
13
13
|
var _jsonParseWithBigInt2 = require("../utils/jsonParseWithBigInt");
|
|
14
|
+
var _statusAlerts = require("../utils/statusAlerts.js");
|
|
14
15
|
var _Header = _interopRequireDefault(require("./Header"));
|
|
15
16
|
var _Sidebar = _interopRequireDefault(require("./Sidebar"));
|
|
16
17
|
var _ToastContainer = _interopRequireDefault(require("./Toast/ToastContainer.js"));
|
|
@@ -35,6 +36,7 @@ var _HelpService = _interopRequireDefault(require("./Header/Help/HelpService"));
|
|
|
35
36
|
var _AccessDeniedCard = _interopRequireDefault(require("../modules/tenant/access/AccessDeniedCard"));
|
|
36
37
|
var _ApplicationRouter = _interopRequireDefault(require("./Router/ApplicationRouter"));
|
|
37
38
|
var _SuspenseScreen = _interopRequireDefault(require("../screens/SuspenseScreen"));
|
|
39
|
+
var _OfflineIndication = require("../modules/attentionrequired/components/OfflineIndication.js");
|
|
38
40
|
require("./Application.scss");
|
|
39
41
|
var _actions = require("../actions");
|
|
40
42
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
@@ -93,6 +95,7 @@ class Application extends _react.Component {
|
|
|
93
95
|
// Clear print-ready timeout handler
|
|
94
96
|
this._clearPrintReadyTimeout = this._clearPrintReadyTimeout.bind(this);
|
|
95
97
|
this._printReadyTimeout = null;
|
|
98
|
+
this._offlineIndicationTimeout = null;
|
|
96
99
|
this.state = {
|
|
97
100
|
networking: 0,
|
|
98
101
|
// If more than zero, some networking activity is happening
|
|
@@ -549,6 +552,7 @@ class Application extends _react.Component {
|
|
|
549
552
|
this._unsubscribeConnectivity();
|
|
550
553
|
this._unsubscribeConnectivity = null;
|
|
551
554
|
}
|
|
555
|
+
this._clearOfflineIndicationTimeout();
|
|
552
556
|
this._clearPrintReadyTimeout();
|
|
553
557
|
document.body.removeAttribute('print-ready');
|
|
554
558
|
}
|
|
@@ -558,6 +562,12 @@ class Application extends _react.Component {
|
|
|
558
562
|
this._printReadyTimeout = null;
|
|
559
563
|
}
|
|
560
564
|
}
|
|
565
|
+
_clearOfflineIndicationTimeout() {
|
|
566
|
+
if (this._offlineIndicationTimeout !== null) {
|
|
567
|
+
clearTimeout(this._offlineIndicationTimeout);
|
|
568
|
+
this._offlineIndicationTimeout = null;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
561
571
|
|
|
562
572
|
// Splash screen
|
|
563
573
|
|
|
@@ -625,30 +635,50 @@ class Application extends _react.Component {
|
|
|
625
635
|
addAlertFromException will always use "danger" color as its background and the full exception will be printed into the console
|
|
626
636
|
*/
|
|
627
637
|
addAlertFromException(exception, message) {
|
|
628
|
-
var _exception$response, _this$AppStore$
|
|
638
|
+
var _exception$response, _exception$response2, _this$AppStore$dispat3, _this$AppStore3;
|
|
629
639
|
var expire = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 30;
|
|
630
640
|
var shouldBeTranslated = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
631
641
|
var component = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
632
642
|
console.error(exception); // Log the whole exception in the browser
|
|
643
|
+
|
|
644
|
+
var exceptionStatus = exception === null || exception === void 0 || (_exception$response = exception.response) === null || _exception$response === void 0 ? void 0 : _exception$response.status;
|
|
645
|
+
// Indicate gateway timeout if the response status is 502, 503 or 504 and if so, then dont continue with the alert and display the offline indication
|
|
646
|
+
if ((exceptionStatus === 502 || exceptionStatus === 503 || exceptionStatus === 504) && this._indicateGatewayTimeout()) {
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
// Handle specific response statuses and set the appropriate level and message
|
|
650
|
+
var statusAlert = _statusAlerts.STATUS_ALERTS[exceptionStatus];
|
|
651
|
+
if (statusAlert) {
|
|
652
|
+
var _this$AppStore$dispat2, _this$AppStore2;
|
|
653
|
+
(_this$AppStore$dispat2 = (_this$AppStore2 = this.AppStore).dispatch) === null || _this$AppStore$dispat2 === void 0 || _this$AppStore$dispat2.call(_this$AppStore2, {
|
|
654
|
+
type: _actions.ADD_ALERT,
|
|
655
|
+
level: statusAlert.level,
|
|
656
|
+
message: statusAlert.message,
|
|
657
|
+
expire: expire,
|
|
658
|
+
shouldBeTranslated: true,
|
|
659
|
+
component: component
|
|
660
|
+
});
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
633
663
|
var exceptionMessage = /*#__PURE__*/_react.default.createElement("span", null, message);
|
|
634
664
|
/*
|
|
635
665
|
If the exception has an error_dict in the response data (error in the new format),
|
|
636
666
|
the ErrorHandler component is used to display the error,
|
|
637
667
|
along with the exception message in the form-text class.
|
|
638
668
|
*/
|
|
639
|
-
if (exception !== null && exception !== void 0 && (_exception$
|
|
669
|
+
if (exception !== null && exception !== void 0 && (_exception$response2 = exception.response) !== null && _exception$response2 !== void 0 && (_exception$response2 = _exception$response2.data) !== null && _exception$response2 !== void 0 && _exception$response2.error_dict) {
|
|
640
670
|
exceptionMessage = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_asab_webui_components.ErrorHandler, {
|
|
641
671
|
error: exception.response.data
|
|
642
672
|
}), (exception === null || exception === void 0 ? void 0 : exception.message) && /*#__PURE__*/_react.default.createElement("div", {
|
|
643
673
|
className: "form-text"
|
|
644
674
|
}, exception.message));
|
|
645
675
|
} else {
|
|
646
|
-
var _exception$
|
|
676
|
+
var _exception$response3;
|
|
647
677
|
/*
|
|
648
678
|
Capture the cases when service returns a message in the exception response data.
|
|
649
679
|
Add hoc messages are displayed in form-text class on the new line
|
|
650
680
|
*/
|
|
651
|
-
if (exception !== null && exception !== void 0 && (_exception$
|
|
681
|
+
if (exception !== null && exception !== void 0 && (_exception$response3 = exception.response) !== null && _exception$response3 !== void 0 && (_exception$response3 = _exception$response3.data) !== null && _exception$response3 !== void 0 && _exception$response3.message) {
|
|
652
682
|
exceptionMessage = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("h5", null, exceptionMessage), /*#__PURE__*/_react.default.createElement("div", {
|
|
653
683
|
className: "mt-2",
|
|
654
684
|
style: {
|
|
@@ -662,7 +692,7 @@ class Application extends _react.Component {
|
|
|
662
692
|
}, exception.message));
|
|
663
693
|
}
|
|
664
694
|
}
|
|
665
|
-
(_this$AppStore$
|
|
695
|
+
(_this$AppStore$dispat3 = (_this$AppStore3 = this.AppStore).dispatch) === null || _this$AppStore$dispat3 === void 0 || _this$AppStore$dispat3.call(_this$AppStore3, {
|
|
666
696
|
type: _actions.ADD_ALERT,
|
|
667
697
|
level: "danger",
|
|
668
698
|
message: exceptionMessage,
|
|
@@ -672,17 +702,46 @@ class Application extends _react.Component {
|
|
|
672
702
|
});
|
|
673
703
|
}
|
|
674
704
|
|
|
705
|
+
/*
|
|
706
|
+
Show OfflineIndication in the header for a limited time
|
|
707
|
+
Each subsequent 504 resets the timer so the badge stays visible while gateway timeouts keep occurring
|
|
708
|
+
Returns true when the indication was shown, false when HeaderService is unavailable
|
|
709
|
+
*/
|
|
710
|
+
_indicateGatewayTimeout() {
|
|
711
|
+
var durationMs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 30000;
|
|
712
|
+
var headerService = this.locateService('HeaderService');
|
|
713
|
+
if (!headerService) {
|
|
714
|
+
return false;
|
|
715
|
+
}
|
|
716
|
+
var isVisible = headerService.Items.some(item => item.component === _OfflineIndication.OfflineIndication);
|
|
717
|
+
if (!isVisible) {
|
|
718
|
+
headerService.addComponent({
|
|
719
|
+
component: _OfflineIndication.OfflineIndication,
|
|
720
|
+
componentProps: {
|
|
721
|
+
title: 'General|Full or partial loss of connectivity to a server'
|
|
722
|
+
},
|
|
723
|
+
order: 100
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
this._clearOfflineIndicationTimeout();
|
|
727
|
+
this._offlineIndicationTimeout = setTimeout(() => {
|
|
728
|
+
headerService.removeComponent(_OfflineIndication.OfflineIndication);
|
|
729
|
+
this._offlineIndicationTimeout = null;
|
|
730
|
+
}, durationMs);
|
|
731
|
+
return true;
|
|
732
|
+
}
|
|
733
|
+
|
|
675
734
|
/*
|
|
676
735
|
This method toggles the full-screen mode of the application container.
|
|
677
736
|
It takes a parameter called "status" to indicate whether to turn the full-screen mode on or off.
|
|
678
737
|
*/
|
|
679
738
|
setFullScreenMode(status) {
|
|
680
|
-
var _state$fullscreenmode, _this$AppStore$
|
|
739
|
+
var _state$fullscreenmode, _this$AppStore$dispat4, _this$AppStore4;
|
|
681
740
|
var state = this.AppStore.getState();
|
|
682
741
|
if (status === 'on' && (state === null || state === void 0 || (_state$fullscreenmode = state.fullscreenmode) === null || _state$fullscreenmode === void 0 ? void 0 : _state$fullscreenmode.status) === 'on') {
|
|
683
742
|
status = 'off';
|
|
684
743
|
}
|
|
685
|
-
(_this$AppStore$
|
|
744
|
+
(_this$AppStore$dispat4 = (_this$AppStore4 = this.AppStore).dispatch) === null || _this$AppStore$dispat4 === void 0 || _this$AppStore$dispat4.call(_this$AppStore4, {
|
|
686
745
|
type: _actions.SET_FULLSCREEN_MODE,
|
|
687
746
|
status: status
|
|
688
747
|
});
|
|
@@ -754,9 +813,9 @@ Application.prototype._initConnectivitySubscription = function () {
|
|
|
754
813
|
if (this.PubSub && typeof this.PubSub.subscribe === 'function') {
|
|
755
814
|
if (!this._unsubscribeConnectivity) {
|
|
756
815
|
this._unsubscribeConnectivity = this.PubSub.subscribe('Application.status!', value => {
|
|
757
|
-
var _this$AppStore$
|
|
816
|
+
var _this$AppStore$dispat5, _this$AppStore5;
|
|
758
817
|
// Prefer store so UI updates predictably
|
|
759
|
-
(_this$AppStore$
|
|
818
|
+
(_this$AppStore$dispat5 = (_this$AppStore5 = this.AppStore).dispatch) === null || _this$AppStore$dispat5 === void 0 || _this$AppStore$dispat5.call(_this$AppStore5, {
|
|
760
819
|
type: _actions.SET_CONNECTIVITY_STATUS,
|
|
761
820
|
status: value.status
|
|
762
821
|
});
|
|
@@ -8,11 +8,13 @@ exports.OfflineIndication = OfflineIndication;
|
|
|
8
8
|
var _react = _interopRequireDefault(require("react"));
|
|
9
9
|
var _reactI18next = require("react-i18next");
|
|
10
10
|
// Header badge for displaying offline status
|
|
11
|
-
function OfflineIndication() {
|
|
11
|
+
function OfflineIndication(_ref) {
|
|
12
|
+
var _ref$title = _ref.title,
|
|
13
|
+
title = _ref$title === void 0 ? 'General|You are offline. Functionality of the Application may be limited.' : _ref$title;
|
|
12
14
|
var _useTranslation = (0, _reactI18next.useTranslation)(),
|
|
13
15
|
t = _useTranslation.t;
|
|
14
16
|
return /*#__PURE__*/_react.default.createElement("i", {
|
|
15
|
-
title: t(
|
|
17
|
+
title: t(title),
|
|
16
18
|
className: "bi bi-wifi-off mx-3",
|
|
17
19
|
style: {
|
|
18
20
|
fontSize: '16px'
|
|
@@ -2,11 +2,11 @@ import React from 'react';
|
|
|
2
2
|
import { useTranslation } from 'react-i18next';
|
|
3
3
|
|
|
4
4
|
// Header badge for displaying offline status
|
|
5
|
-
export function OfflineIndication() {
|
|
5
|
+
export function OfflineIndication({ title = 'General|You are offline. Functionality of the Application may be limited.' }) {
|
|
6
6
|
const { t } = useTranslation();
|
|
7
7
|
|
|
8
8
|
return <i
|
|
9
|
-
title={t(
|
|
9
|
+
title={t(title)}
|
|
10
10
|
className='bi bi-wifi-off mx-3'
|
|
11
11
|
style={{ fontSize: '16px' }} // Align with fontsize of navitems of Header
|
|
12
12
|
/>
|
|
@@ -57,6 +57,17 @@
|
|
|
57
57
|
--bs-dropdown-bg: var(--bs-element-bg-color);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
.tooltip {
|
|
61
|
+
--bs-tooltip-bg: rgba(var(--bs-body-bg-rgb), 0.9);
|
|
62
|
+
--bs-tooltip-color: var(--bs-body-color);
|
|
63
|
+
--bs-tooltip-border-radius: var(--bs-border-radius);
|
|
64
|
+
|
|
65
|
+
.tooltip-inner {
|
|
66
|
+
border: 1px solid var(--bs-border-color);
|
|
67
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
60
71
|
.input-group-text {
|
|
61
72
|
border-radius: 0;
|
|
62
73
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.STATUS_ALERTS = void 0;
|
|
7
|
+
/*
|
|
8
|
+
Status-specific alerts shown instead of the generic exception alert.
|
|
9
|
+
This is a extension to the addAlertFromException function in the Application.js file.
|
|
10
|
+
|
|
11
|
+
The 502, 503 and 504 errors are handled directly in the Application.js file, since it does not render an alert at all.
|
|
12
|
+
*/
|
|
13
|
+
var STATUS_ALERTS = exports.STATUS_ALERTS = {
|
|
14
|
+
408: {
|
|
15
|
+
level: 'warning',
|
|
16
|
+
message: 'General|The request timed out. Please try again.'
|
|
17
|
+
},
|
|
18
|
+
413: {
|
|
19
|
+
level: 'warning',
|
|
20
|
+
message: 'General|The request is too large for the server to process. If you are uploading a file, please choose a smaller one.'
|
|
21
|
+
},
|
|
22
|
+
429: {
|
|
23
|
+
level: 'warning',
|
|
24
|
+
message: 'General|Too many requests. Please wait a moment and try again.'
|
|
25
|
+
}
|
|
26
|
+
// TODO: add more response statuses if needed
|
|
27
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Status-specific alerts shown instead of the generic exception alert.
|
|
3
|
+
This is a extension to the addAlertFromException function in the Application.js file.
|
|
4
|
+
|
|
5
|
+
The 502, 503 and 504 errors are handled directly in the Application.js file, since it does not render an alert at all.
|
|
6
|
+
*/
|
|
7
|
+
export const STATUS_ALERTS = {
|
|
8
|
+
408: {
|
|
9
|
+
level: 'warning',
|
|
10
|
+
message: 'General|The request timed out. Please try again.',
|
|
11
|
+
},
|
|
12
|
+
413: {
|
|
13
|
+
level: 'warning',
|
|
14
|
+
message: 'General|The request is too large for the server to process. If you are uploading a file, please choose a smaller one.',
|
|
15
|
+
},
|
|
16
|
+
429: {
|
|
17
|
+
level: 'warning',
|
|
18
|
+
message: 'General|Too many requests. Please wait a moment and try again.',
|
|
19
|
+
},
|
|
20
|
+
// TODO: add more response statuses if needed
|
|
21
|
+
};
|