asab_webui_shell 25.1.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.
- package/CHANGELOG.md +218 -0
- package/LICENSE +28 -0
- package/README.md +3 -0
- package/dist/actions.js +22 -0
- package/dist/components/branding/BrandImage.js +72 -0
- package/dist/components/locationReplace.js +51 -0
- package/dist/config/ConfigReducer.js +22 -0
- package/dist/config/ConfigService.js +169 -0
- package/dist/containers/AdvancedMode/reducer.js +28 -0
- package/dist/containers/Alerts/alerts.scss +9 -0
- package/dist/containers/Alerts/index.js +81 -0
- package/dist/containers/Alerts/reducer.js +68 -0
- package/dist/containers/Application.js +773 -0
- package/dist/containers/Application.scss +104 -0
- package/dist/containers/AttentionRequired/reducer.js +30 -0
- package/dist/containers/FullscreenMode/reducer.js +28 -0
- package/dist/containers/Header/ApplicationScreenTitle/ApplicationScreenTitle.js +47 -0
- package/dist/containers/Header/ApplicationScreenTitle/ApplicationScreenTitle.scss +8 -0
- package/dist/containers/Header/ApplicationScreenTitle/index.js +31 -0
- package/dist/containers/Header/Help/HelpButton.js +58 -0
- package/dist/containers/Header/Help/HelpButton.scss +15 -0
- package/dist/containers/Header/Help/HelpService.js +34 -0
- package/dist/containers/Header/Preview/PreviewFlag.js +34 -0
- package/dist/containers/Header/Preview/PreviewService.js +34 -0
- package/dist/containers/Header/header.scss +24 -0
- package/dist/containers/Header/index.js +39 -0
- package/dist/containers/Header/reducer.js +53 -0
- package/dist/containers/Navigation/index.js +66 -0
- package/dist/containers/Navigation/reducer.js +56 -0
- package/dist/containers/RouteErrorHandler/ErrorContainer.js +46 -0
- package/dist/containers/RouteErrorHandler/index.js +80 -0
- package/dist/containers/Router/ApplicationRouter.js +78 -0
- package/dist/containers/Router/index.js +50 -0
- package/dist/containers/Router/reducer.js +28 -0
- package/dist/containers/Sidebar/NavbarBrand.js +59 -0
- package/dist/containers/Sidebar/SidebarBottomItem.js +55 -0
- package/dist/containers/Sidebar/SidebarIcon.js +21 -0
- package/dist/containers/Sidebar/SidebarItem.js +209 -0
- package/dist/containers/Sidebar/SidebarItemRenderer.js +30 -0
- package/dist/containers/Sidebar/index.js +86 -0
- package/dist/containers/Sidebar/reducer.js +35 -0
- package/dist/containers/Sidebar/sidebar.scss +176 -0
- package/dist/containers/Sidepanel/Sidepanel.js +60 -0
- package/dist/containers/Sidepanel/Sidepanel.scss +20 -0
- package/dist/containers/Toast/ToastComponent.js +31 -0
- package/dist/containers/Toast/ToastComponent.jsx +28 -0
- package/dist/containers/Toast/ToastContainer.js +80 -0
- package/dist/containers/Toast/ToastContainer.jsx +59 -0
- package/dist/containers/Toast/reducer.js +55 -0
- package/dist/containers/Toast/reducer.jsx +45 -0
- package/dist/index.js +48 -0
- package/dist/modules/about/AboutScreen.js +84 -0
- package/dist/modules/about/index.js +41 -0
- package/dist/modules/auth/actions.js +11 -0
- package/dist/modules/auth/api.js +214 -0
- package/dist/modules/auth/components/SessionExpirationAlert.js +35 -0
- package/dist/modules/auth/header.js +109 -0
- package/dist/modules/auth/header.scss +9 -0
- package/dist/modules/auth/index.js +761 -0
- package/dist/modules/auth/reducer.js +36 -0
- package/dist/modules/auth/screens/AccessControlScreen.js +78 -0
- package/dist/modules/auth/screens/InvitationScreen.js +161 -0
- package/dist/modules/i18n/actions.js +7 -0
- package/dist/modules/i18n/dropdown.js +77 -0
- package/dist/modules/i18n/index.js +44 -0
- package/dist/modules/i18n/reducer.js +26 -0
- package/dist/modules/i18n/service.js +158 -0
- package/dist/modules/tenant/TenantDropdown.js +53 -0
- package/dist/modules/tenant/access/AccessDeniedCard.js +107 -0
- package/dist/modules/tenant/access/AccessDeniedCard.scss +6 -0
- package/dist/modules/tenant/actions.js +10 -0
- package/dist/modules/tenant/index.js +41 -0
- package/dist/modules/tenant/reducer.js +26 -0
- package/dist/modules/tenant/service.js +228 -0
- package/dist/screens/InvalidRouteScreen.js +30 -0
- package/dist/screens/InvalidRouteScreen.scss +19 -0
- package/dist/screens/SuspenseScreen.js +43 -0
- package/dist/screens/SuspenseScreen.scss +9 -0
- package/dist/screens/UnauthorizedAccessScreen.js +79 -0
- package/dist/screens/UnauthorizedAccessScreen.scss +19 -0
- package/dist/services/AttentionRequiredService.js +169 -0
- package/dist/services/BrandingService.js +104 -0
- package/dist/services/HeaderService.js +84 -0
- package/dist/services/ReduxService.js +25 -0
- package/dist/services/TitleService.js +45 -0
- package/dist/theme/ThemeButton.js +39 -0
- package/dist/theme/ThemeReducer.js +20 -0
- package/dist/theme/ThemeService.js +52 -0
- package/dist/theme/actions.js +7 -0
- package/package.json +41 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
|
9
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
10
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
11
|
+
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
12
|
+
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
13
|
+
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
14
|
+
var _asab_webui_components = require("asab_webui_components");
|
|
15
|
+
var _actions = require("../actions");
|
|
16
|
+
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); }
|
|
17
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
18
|
+
// Service handling attention required
|
|
19
|
+
var AttentionRequiredService = exports["default"] = /*#__PURE__*/function (_Service) {
|
|
20
|
+
function AttentionRequiredService(app) {
|
|
21
|
+
var _this;
|
|
22
|
+
var serviceName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "AttentionRequiredService";
|
|
23
|
+
(0, _classCallCheck2["default"])(this, AttentionRequiredService);
|
|
24
|
+
_this = _callSuper(this, AttentionRequiredService, [app, serviceName]);
|
|
25
|
+
_this.beaconWebSocket = null; // beacon websocket variable
|
|
26
|
+
_this.reconnectTimeout = null; // timeout variable
|
|
27
|
+
_this.reconnectInterval = 5000; // initial reconnection interval (5 seconds)
|
|
28
|
+
return _this;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Start beacon websocket connection on initialization
|
|
32
|
+
(0, _inherits2["default"])(AttentionRequiredService, _Service);
|
|
33
|
+
return (0, _createClass2["default"])(AttentionRequiredService, [{
|
|
34
|
+
key: "initialize",
|
|
35
|
+
value: function initialize() {
|
|
36
|
+
this.connectBeaconWebSocket();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Method for connection to beacon websocket
|
|
40
|
+
}, {
|
|
41
|
+
key: "connectBeaconWebSocket",
|
|
42
|
+
value: function connectBeaconWebSocket() {
|
|
43
|
+
var _this$App,
|
|
44
|
+
_this2 = this;
|
|
45
|
+
// Retrieve current tenant
|
|
46
|
+
var currentTenant = (_this$App = this.App) === null || _this$App === void 0 || (_this$App = _this$App.Services) === null || _this$App === void 0 || (_this$App = _this$App.TenantService) === null || _this$App === void 0 ? void 0 : _this$App.getCurrentTenant();
|
|
47
|
+
// Gracefully reconnect if tenant was not found
|
|
48
|
+
if (!currentTenant) {
|
|
49
|
+
console.error("Beacon WebSocket error: Tenant was not found!");
|
|
50
|
+
this.reconnectBeaconWebSocket();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
var BeaconServiceClient = this.App.createWebSocket('asab-remote-control', "/beacon/".concat(currentTenant, "/ws"));
|
|
54
|
+
this.beaconWebSocket = BeaconServiceClient;
|
|
55
|
+
this.beaconWebSocket.onopen = function () {
|
|
56
|
+
// TODO: may be removed
|
|
57
|
+
console.log('Beacon WebSocket connection established.');
|
|
58
|
+
};
|
|
59
|
+
this.beaconWebSocket.onmessage = function (message) {
|
|
60
|
+
try {
|
|
61
|
+
var data = JSON.parse(message.data);
|
|
62
|
+
// TODO: implement some type based recognition
|
|
63
|
+
_this2.distributeData(data);
|
|
64
|
+
} catch (e) {
|
|
65
|
+
console.error("Error parsing Beacon WebSocket message data:", e);
|
|
66
|
+
_this2.distributeData({});
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
this.beaconWebSocket.onerror = function (error) {
|
|
70
|
+
console.error("Beacon WebSocket error:", error);
|
|
71
|
+
console.error("Beacon WebSocket is attempting to reconnect...");
|
|
72
|
+
_this2.distributeData({});
|
|
73
|
+
_this2.reconnectBeaconWebSocket();
|
|
74
|
+
};
|
|
75
|
+
this.beaconWebSocket.onclose = function () {
|
|
76
|
+
/*
|
|
77
|
+
WebSocket connection is closed by the browser automatically when user
|
|
78
|
+
leaves the application (not the screen).
|
|
79
|
+
*/
|
|
80
|
+
if (_this2.beaconWebSocket) {
|
|
81
|
+
// Close the WebSocket connection
|
|
82
|
+
_this2.beaconWebSocket.close();
|
|
83
|
+
|
|
84
|
+
// Clean up event listeners
|
|
85
|
+
_this2.beaconWebSocket.onopen = null;
|
|
86
|
+
_this2.beaconWebSocket.onmessage = null;
|
|
87
|
+
_this2.beaconWebSocket.onerror = null;
|
|
88
|
+
_this2.beaconWebSocket.onclose = null;
|
|
89
|
+
|
|
90
|
+
// Set WebSocket reference to null to free up memory
|
|
91
|
+
_this2.beaconWebSocket = null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Clear the reconnect timeout if it exists
|
|
95
|
+
if (_this2.reconnectTimeout) {
|
|
96
|
+
clearTimeout(_this2.reconnectTimeout);
|
|
97
|
+
_this2.reconnectTimeout = null;
|
|
98
|
+
}
|
|
99
|
+
console.log("Beacon WebSocket connection closed.");
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Method for reconnection to beacon websocket
|
|
104
|
+
}, {
|
|
105
|
+
key: "reconnectBeaconWebSocket",
|
|
106
|
+
value: function reconnectBeaconWebSocket() {
|
|
107
|
+
var _this3 = this;
|
|
108
|
+
if (this.reconnectTimeout) {
|
|
109
|
+
clearTimeout(this.reconnectTimeout);
|
|
110
|
+
}
|
|
111
|
+
this.reconnectTimeout = setTimeout(function () {
|
|
112
|
+
_this3.connectBeaconWebSocket();
|
|
113
|
+
}, this.reconnectInterval); // Retry connection after the reconnection interval
|
|
114
|
+
|
|
115
|
+
// Increase reconnection time by 5s, the limit is 60s (so that we dont overload the server)
|
|
116
|
+
if (this.reconnectInterval + 5000 <= 60000) {
|
|
117
|
+
this.reconnectInterval += 5000;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Method for distributing the data into redux store
|
|
122
|
+
}, {
|
|
123
|
+
key: "distributeData",
|
|
124
|
+
value: function distributeData(data) {
|
|
125
|
+
var transformedData = this.transformData(data);
|
|
126
|
+
this.App.Store.dispatch({
|
|
127
|
+
type: _actions.SET_ATTENTION_REQUIRED_BEACON,
|
|
128
|
+
beacon: transformedData
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Transform and group beacon data
|
|
133
|
+
}, {
|
|
134
|
+
key: "transformData",
|
|
135
|
+
value: function transformData(inputData) {
|
|
136
|
+
// Validate if input data are array
|
|
137
|
+
if (!Array.isArray(inputData)) {
|
|
138
|
+
return {};
|
|
139
|
+
}
|
|
140
|
+
return inputData.reduce(function (acc, entry) {
|
|
141
|
+
var type = entry.type,
|
|
142
|
+
_c = entry._c,
|
|
143
|
+
reference_path = entry.reference_path;
|
|
144
|
+
|
|
145
|
+
// Identify the dynamic key (it could be 'library', 'configuration', 'services', etc.)
|
|
146
|
+
var dynamicKey = Object.keys(entry).find(function (key) {
|
|
147
|
+
return (0, _typeof2["default"])(entry[key]) === 'object' && entry[key] !== null && !Array.isArray(entry[key]);
|
|
148
|
+
});
|
|
149
|
+
if (!dynamicKey) {
|
|
150
|
+
// Skip if no valid dynamic key is found
|
|
151
|
+
return acc;
|
|
152
|
+
}
|
|
153
|
+
var data = entry[dynamicKey];
|
|
154
|
+
// Ensure type is present in the accumulator
|
|
155
|
+
if (!acc[type]) {
|
|
156
|
+
acc[type] = {
|
|
157
|
+
count: 0,
|
|
158
|
+
data: []
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
// Push each entry into the data array
|
|
162
|
+
acc[type].data.push(data);
|
|
163
|
+
// Increment count for the type
|
|
164
|
+
acc[type].count += 1;
|
|
165
|
+
return acc;
|
|
166
|
+
}, {});
|
|
167
|
+
}
|
|
168
|
+
}]);
|
|
169
|
+
}(_asab_webui_components.Service);
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
10
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
11
|
+
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
12
|
+
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
13
|
+
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
14
|
+
var _asab_webui_components = require("asab_webui_components");
|
|
15
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
16
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
17
|
+
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); }
|
|
18
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
19
|
+
var BrandingService = exports["default"] = /*#__PURE__*/function (_Service) {
|
|
20
|
+
/*
|
|
21
|
+
Branding service expects `header-logo-full.svg` and `header-logo-minimized.svg` SVG images
|
|
22
|
+
in `/public/media/logo/` directory:
|
|
23
|
+
* `header-logo-full.svg` dimensions: 150 x 50 pixels
|
|
24
|
+
* `header-logo-minimized.svg` dimensions: 50 x 50 pixels
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
function BrandingService(app) {
|
|
28
|
+
var _this;
|
|
29
|
+
var serviceName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "BrandingService";
|
|
30
|
+
(0, _classCallCheck2["default"])(this, BrandingService);
|
|
31
|
+
_this = _callSuper(this, BrandingService, [app, serviceName]);
|
|
32
|
+
_this.state = [];
|
|
33
|
+
_this.App = app;
|
|
34
|
+
_this.brandImage = undefined;
|
|
35
|
+
_this.defaultBrandImage = undefined;
|
|
36
|
+
_this.sidebarLogo = undefined;
|
|
37
|
+
return _this;
|
|
38
|
+
}
|
|
39
|
+
(0, _inherits2["default"])(BrandingService, _Service);
|
|
40
|
+
return (0, _createClass2["default"])(BrandingService, [{
|
|
41
|
+
key: "initialize",
|
|
42
|
+
value: function initialize() {
|
|
43
|
+
if (this.App.Services.ConfigService) {
|
|
44
|
+
this.brandImage = this.App.Config.get('brandImage');
|
|
45
|
+
this.defaultBrandImage = this.App.Config.get('defaultBrandImage');
|
|
46
|
+
this.sidebarLogo = this.App.Config.get('sidebarLogo');
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* This method returns object containing paths to branding depending on theme. It also takes care of filling in missing
|
|
51
|
+
values (e.g. when only minimized version was provided in the configuration, the method completes it with full version) */
|
|
52
|
+
}, {
|
|
53
|
+
key: "_determineSources",
|
|
54
|
+
value: function _determineSources(imgObject, theme) {
|
|
55
|
+
var _imgObject$theme, _imgObject$theme2, _imgObject$theme3, _imgObject$theme4;
|
|
56
|
+
if ((_imgObject$theme = imgObject[theme]) !== null && _imgObject$theme !== void 0 && _imgObject$theme.minimized && (_imgObject$theme2 = imgObject[theme]) !== null && _imgObject$theme2 !== void 0 && _imgObject$theme2.full) {
|
|
57
|
+
var _imgObject$href;
|
|
58
|
+
return _objectSpread(_objectSpread({}, imgObject[theme]), {}, {
|
|
59
|
+
href: (_imgObject$href = imgObject.href) !== null && _imgObject$href !== void 0 ? _imgObject$href : '/'
|
|
60
|
+
});
|
|
61
|
+
} else if ((_imgObject$theme3 = imgObject[theme]) !== null && _imgObject$theme3 !== void 0 && _imgObject$theme3.minimized) {
|
|
62
|
+
var _imgObject$otherTheme, _imgObject$otherTheme2, _imgObject$href2;
|
|
63
|
+
return {
|
|
64
|
+
full: (_imgObject$otherTheme = imgObject === null || imgObject === void 0 || (_imgObject$otherTheme2 = imgObject.otherTheme) === null || _imgObject$otherTheme2 === void 0 ? void 0 : _imgObject$otherTheme2.full) !== null && _imgObject$otherTheme !== void 0 ? _imgObject$otherTheme : this.defaultBrandImage.full,
|
|
65
|
+
minimized: imgObject[theme].minimized,
|
|
66
|
+
href: (_imgObject$href2 = imgObject === null || imgObject === void 0 ? void 0 : imgObject.href) !== null && _imgObject$href2 !== void 0 ? _imgObject$href2 : '/'
|
|
67
|
+
};
|
|
68
|
+
} else if ((_imgObject$theme4 = imgObject[theme]) !== null && _imgObject$theme4 !== void 0 && _imgObject$theme4.full) {
|
|
69
|
+
var _imgObject$otherTheme3, _imgObject$otherTheme4, _imgObject$href3;
|
|
70
|
+
return {
|
|
71
|
+
full: imgObject[theme].full,
|
|
72
|
+
minimized: (_imgObject$otherTheme3 = imgObject === null || imgObject === void 0 || (_imgObject$otherTheme4 = imgObject.otherTheme) === null || _imgObject$otherTheme4 === void 0 ? void 0 : _imgObject$otherTheme4.minimized) !== null && _imgObject$otherTheme3 !== void 0 ? _imgObject$otherTheme3 : this.defaultBrandImage.minimized,
|
|
73
|
+
href: (_imgObject$href3 = imgObject === null || imgObject === void 0 ? void 0 : imgObject.href) !== null && _imgObject$href3 !== void 0 ? _imgObject$href3 : '/'
|
|
74
|
+
};
|
|
75
|
+
} else {
|
|
76
|
+
var _imgObject$href4;
|
|
77
|
+
return _objectSpread(_objectSpread({}, this.defaultBrandImage), {}, {
|
|
78
|
+
href: (_imgObject$href4 = imgObject.href) !== null && _imgObject$href4 !== void 0 ? _imgObject$href4 : '/'
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// method getLogo returns correct brandImage object to be displayed on the front end based on theme and type (sidebbar logo or main logo)
|
|
84
|
+
}, {
|
|
85
|
+
key: "getLogo",
|
|
86
|
+
value: function getLogo(theme, type) {
|
|
87
|
+
if (type === 'sidebarLogo' && theme && this.sidebarLogo) {
|
|
88
|
+
if (this.sidebarLogo[theme]) {
|
|
89
|
+
return this.sidebarLogo[theme];
|
|
90
|
+
} else if (!this.sidebarLogo[theme]) {
|
|
91
|
+
return this.sidebarLogo[theme === 'dark' ? 'light' : 'dark'];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/* if we have theme and we've managed to obtain appropriate branding from Config's get method. (this method checks if remote,
|
|
95
|
+
local or default configurations were set up (respectively) and returns the first one it comes across) Then, the `_determineSources`
|
|
96
|
+
method comes to play. */
|
|
97
|
+
if (theme && this.brandImage) {
|
|
98
|
+
return this._determineSources(this.brandImage, theme);
|
|
99
|
+
} else {
|
|
100
|
+
return this.defaultBrandImage;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}]);
|
|
104
|
+
}(_asab_webui_components.Service);
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
9
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
10
|
+
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
11
|
+
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
12
|
+
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
13
|
+
var _asab_webui_components = require("asab_webui_components");
|
|
14
|
+
var _actions = require("../actions");
|
|
15
|
+
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); }
|
|
16
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
17
|
+
var HeaderService = exports["default"] = /*#__PURE__*/function (_Service) {
|
|
18
|
+
/*
|
|
19
|
+
Header service expects `header-logo-full.svg` and `header-logo-minimized.svg` SVG images
|
|
20
|
+
in `/public/media/logo/` directory:
|
|
21
|
+
* `header-logo-full.svg` dimensions: 150 x 50 pixels
|
|
22
|
+
* `header-logo-minimized.svg` dimensions: 50 x 50 pixels
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
function HeaderService(app) {
|
|
26
|
+
var _this;
|
|
27
|
+
var serviceName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "HeaderService";
|
|
28
|
+
(0, _classCallCheck2["default"])(this, HeaderService);
|
|
29
|
+
_this = _callSuper(this, HeaderService, [app, serviceName]);
|
|
30
|
+
_this.Items = [];
|
|
31
|
+
return _this;
|
|
32
|
+
}
|
|
33
|
+
(0, _inherits2["default"])(HeaderService, _Service);
|
|
34
|
+
return (0, _createClass2["default"])(HeaderService, [{
|
|
35
|
+
key: "initialize",
|
|
36
|
+
value: function initialize() {
|
|
37
|
+
this.App.ConfigService.addDefaults({
|
|
38
|
+
'defaultBrandImage': {
|
|
39
|
+
full: "media/logo/header-logo-full.svg",
|
|
40
|
+
minimized: "media/logo/header-logo-minimized.svg",
|
|
41
|
+
href: undefined
|
|
42
|
+
}
|
|
43
|
+
}, true);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/*
|
|
47
|
+
Adding items to the header can be done by using addComponent:
|
|
48
|
+
const headerService = app.locateService("HeaderService");
|
|
49
|
+
headerService.addComponent({
|
|
50
|
+
component: NavLink,
|
|
51
|
+
componentProps: {children: "My redirect button", href: "#/redirect", style: {marginRight: "2rem"}},
|
|
52
|
+
order: 900
|
|
53
|
+
});
|
|
54
|
+
*/
|
|
55
|
+
}, {
|
|
56
|
+
key: "addComponent",
|
|
57
|
+
value: function addComponent(component) {
|
|
58
|
+
this.Items.push({
|
|
59
|
+
'component': component.component,
|
|
60
|
+
'componentProps': component.componentProps,
|
|
61
|
+
'order': component.order,
|
|
62
|
+
'fullscreenVisible': component.fullscreenVisible
|
|
63
|
+
});
|
|
64
|
+
this.App.Store.dispatch({
|
|
65
|
+
type: _actions.SET_HEADER_NAVIGATION_ITEMS,
|
|
66
|
+
headerNavItems: this.Items
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// This function removes a component from the Header
|
|
71
|
+
}, {
|
|
72
|
+
key: "removeComponent",
|
|
73
|
+
value: function removeComponent(component) {
|
|
74
|
+
var filteredItems = this.Items.filter(function (item) {
|
|
75
|
+
return item.component !== component;
|
|
76
|
+
});
|
|
77
|
+
this.Items = filteredItems;
|
|
78
|
+
this.App.Store.dispatch({
|
|
79
|
+
type: _actions.SET_HEADER_NAVIGATION_ITEMS,
|
|
80
|
+
headerNavItems: this.Items
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}]);
|
|
84
|
+
}(_asab_webui_components.Service);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
9
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
10
|
+
var ReduxService = exports["default"] = /*#__PURE__*/function () {
|
|
11
|
+
function ReduxService() {
|
|
12
|
+
(0, _classCallCheck2["default"])(this, ReduxService);
|
|
13
|
+
this.Reducers = {};
|
|
14
|
+
}
|
|
15
|
+
return (0, _createClass2["default"])(ReduxService, [{
|
|
16
|
+
key: "addReducer",
|
|
17
|
+
value: function addReducer(name, reducer) {
|
|
18
|
+
if (name in this.Reducers) {
|
|
19
|
+
console.warn("Reducer with name ".concat(name, " already exists."));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
this.Reducers[name] = reducer;
|
|
23
|
+
}
|
|
24
|
+
}]);
|
|
25
|
+
}();
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
9
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
10
|
+
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
11
|
+
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
12
|
+
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
13
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
14
|
+
var _react = _interopRequireDefault(require("react"));
|
|
15
|
+
var _asab_webui_components = require("asab_webui_components");
|
|
16
|
+
var _actions = require("../actions");
|
|
17
|
+
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); }
|
|
18
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
19
|
+
var TitleService = exports["default"] = /*#__PURE__*/function (_Service) {
|
|
20
|
+
function TitleService(app) {
|
|
21
|
+
var _this;
|
|
22
|
+
var serviceName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "TitleService";
|
|
23
|
+
(0, _classCallCheck2["default"])(this, TitleService);
|
|
24
|
+
_this = _callSuper(this, TitleService, [app, serviceName]);
|
|
25
|
+
// Method for setting the subtitle
|
|
26
|
+
(0, _defineProperty2["default"])(_this, "setSubtitle", function (subtitle) {
|
|
27
|
+
_this._updateSubtitle(subtitle);
|
|
28
|
+
});
|
|
29
|
+
// Method for clearing the subtitle
|
|
30
|
+
(0, _defineProperty2["default"])(_this, "clearSubtitle", function () {
|
|
31
|
+
_this._updateSubtitle(undefined);
|
|
32
|
+
});
|
|
33
|
+
// Method for dispatching subtitle update to Redux store
|
|
34
|
+
(0, _defineProperty2["default"])(_this, "_updateSubtitle", function (subtitle) {
|
|
35
|
+
_this.App.Store.dispatch({
|
|
36
|
+
type: _actions.SET_SUBTITLE,
|
|
37
|
+
subtitle: subtitle
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
_this.App = app;
|
|
41
|
+
return _this;
|
|
42
|
+
}
|
|
43
|
+
(0, _inherits2["default"])(TitleService, _Service);
|
|
44
|
+
return (0, _createClass2["default"])(TitleService);
|
|
45
|
+
}(_asab_webui_components.Service);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
var _reactRedux = require("react-redux");
|
|
10
|
+
var _reactI18next = require("react-i18next");
|
|
11
|
+
var _reactstrap = require("reactstrap");
|
|
12
|
+
var _actions = require("./actions");
|
|
13
|
+
var ThemeButton = function ThemeButton(_ref) {
|
|
14
|
+
var theme = _ref.theme;
|
|
15
|
+
var _useTranslation = (0, _reactI18next.useTranslation)(),
|
|
16
|
+
t = _useTranslation.t,
|
|
17
|
+
i18n = _useTranslation.i18n;
|
|
18
|
+
var dispatch = (0, _reactRedux.useDispatch)();
|
|
19
|
+
var changeTheme = function changeTheme() {
|
|
20
|
+
var newTheme = theme == "light" ? "dark" : "light";
|
|
21
|
+
dispatch({
|
|
22
|
+
type: _actions.CHANGE_THEME,
|
|
23
|
+
theme: newTheme
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
return /*#__PURE__*/_react["default"].createElement(_reactstrap.NavLink, {
|
|
27
|
+
onClick: changeTheme,
|
|
28
|
+
title: t("General|Change theme"),
|
|
29
|
+
href: "#"
|
|
30
|
+
}, /*#__PURE__*/_react["default"].createElement("i", {
|
|
31
|
+
className: "bi bi-circle-half"
|
|
32
|
+
}));
|
|
33
|
+
};
|
|
34
|
+
function mapStateToProps(state) {
|
|
35
|
+
return {
|
|
36
|
+
theme: state.theme
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
var _default = exports["default"] = (0, _reactRedux.connect)(mapStateToProps)(ThemeButton);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = ThemeReducer;
|
|
7
|
+
var _actions = require("./actions");
|
|
8
|
+
var themeInitState = null;
|
|
9
|
+
function ThemeReducer() {
|
|
10
|
+
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : themeInitState;
|
|
11
|
+
var action = arguments.length > 1 ? arguments[1] : undefined;
|
|
12
|
+
switch (action.type) {
|
|
13
|
+
case _actions.CHANGE_THEME:
|
|
14
|
+
var root = document.querySelector(':root');
|
|
15
|
+
root.dataset.bsTheme = action.theme; // Set the theme for Bootstrap `data-bs-theme`
|
|
16
|
+
return action.theme;
|
|
17
|
+
default:
|
|
18
|
+
return state;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
9
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
10
|
+
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
11
|
+
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
12
|
+
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
13
|
+
var _asab_webui_components = require("asab_webui_components");
|
|
14
|
+
var _ThemeReducer = _interopRequireDefault(require("./ThemeReducer"));
|
|
15
|
+
var _actions = require("./actions");
|
|
16
|
+
var _ThemeButton = _interopRequireDefault(require("./ThemeButton"));
|
|
17
|
+
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); }
|
|
18
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
19
|
+
var ThemeService = exports["default"] = /*#__PURE__*/function (_Service) {
|
|
20
|
+
function ThemeService(app) {
|
|
21
|
+
var _this;
|
|
22
|
+
var serviceName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "ThemeService";
|
|
23
|
+
(0, _classCallCheck2["default"])(this, ThemeService);
|
|
24
|
+
_this = _callSuper(this, ThemeService, [app, serviceName]);
|
|
25
|
+
app.ReduxService.addReducer("theme", _ThemeReducer["default"]);
|
|
26
|
+
return _this;
|
|
27
|
+
}
|
|
28
|
+
(0, _inherits2["default"])(ThemeService, _Service);
|
|
29
|
+
return (0, _createClass2["default"])(ThemeService, [{
|
|
30
|
+
key: "initialize",
|
|
31
|
+
value: function initialize() {
|
|
32
|
+
var headerService = this.App.locateService("HeaderService");
|
|
33
|
+
headerService.addComponent({
|
|
34
|
+
component: _ThemeButton["default"],
|
|
35
|
+
order: 400,
|
|
36
|
+
fullscreenVisible: true
|
|
37
|
+
});
|
|
38
|
+
// Detect initial theme (based on color-scheme aka user prefered theme)
|
|
39
|
+
// Doesn't work in Chromiuim in Ubuntu
|
|
40
|
+
// more info https://bugs.chromium.org/p/chromium/issues/detail?id=998903
|
|
41
|
+
var prefersColorScheme = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? "dark" : "light";
|
|
42
|
+
|
|
43
|
+
// Dispatch tenants obtained from userinfo
|
|
44
|
+
this.App.Store.dispatch({
|
|
45
|
+
type: _actions.CHANGE_THEME,
|
|
46
|
+
theme: prefersColorScheme
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// TODO: Add listener to the system theme and change light/dark based on that
|
|
50
|
+
}
|
|
51
|
+
}]);
|
|
52
|
+
}(_asab_webui_components.Service);
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "asab_webui_shell",
|
|
3
|
+
"version": "25.1.1",
|
|
4
|
+
"description": "TeskaLabs ASAB WebUI Shell Application",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"publishConfig": {
|
|
10
|
+
"registry": "https://registry.npmjs.org/"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"clean": "rimraf dist",
|
|
14
|
+
"build": "babel src --extensions '.js,.jsx' --out-dir dist && copyfiles -u 1 'src/**/*.{scss,jsx}' dist"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@babel/cli": "^7.22.11",
|
|
18
|
+
"@babel/core": "^7.22.11",
|
|
19
|
+
"@babel/plugin-transform-runtime": "^7.22.10",
|
|
20
|
+
"@babel/preset-env": "^7.22.10",
|
|
21
|
+
"@babel/preset-react": "^7.22.5",
|
|
22
|
+
"babel-plugin-module-resolver": "^5.0.2",
|
|
23
|
+
"copyfiles": "^2.4.1",
|
|
24
|
+
"rimraf": "^5.0.0",
|
|
25
|
+
"i18next-browser-languagedetector": "^6.1.2"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"asab_webui_components": "git+https://github.com/TeskaLabs/asab-webui-components-lib.git#main",
|
|
29
|
+
"@babel/runtime": "^7.22.11",
|
|
30
|
+
"react": "^17.0.0",
|
|
31
|
+
"react-dom": "^17.0.0",
|
|
32
|
+
"axios": "^0.21.1",
|
|
33
|
+
"i18next": "^20.3.5",
|
|
34
|
+
"react-i18next": "^11.8.12",
|
|
35
|
+
"react-redux": "^7.2.0",
|
|
36
|
+
"react-router": "^6.16.0",
|
|
37
|
+
"react-router-dom": "^6.16.0",
|
|
38
|
+
"reactstrap": "^9.2.0",
|
|
39
|
+
"redux": "^4.0.5"
|
|
40
|
+
}
|
|
41
|
+
}
|