asab_webui_shell 25.1.12 → 25.1.13

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 (66) hide show
  1. package/dist/components/locationReplace.js +4 -16
  2. package/dist/config/ConfigReducer.js +1 -1
  3. package/dist/config/ConfigService.js +116 -137
  4. package/dist/containers/AdvancedMode/reducer.js +2 -2
  5. package/dist/containers/Alerts/index.js +18 -30
  6. package/dist/containers/Alerts/reducer.js +5 -6
  7. package/dist/containers/Application.js +531 -673
  8. package/dist/containers/AttentionRequired/reducer.js +2 -2
  9. package/dist/containers/FullscreenMode/reducer.js +2 -2
  10. package/dist/containers/Header/ApplicationScreenTitle/ApplicationScreenTitle.js +15 -16
  11. package/dist/containers/Header/ApplicationScreenTitle/index.js +6 -6
  12. package/dist/containers/Header/Help/HelpButton.js +17 -27
  13. package/dist/containers/Header/Help/HelpService.js +13 -24
  14. package/dist/containers/Header/Preview/PreviewFlag.js +6 -5
  15. package/dist/containers/Header/Preview/PreviewService.js +13 -24
  16. package/dist/containers/Header/index.js +15 -17
  17. package/dist/containers/Header/reducer.js +4 -4
  18. package/dist/containers/Navigation/index.js +35 -55
  19. package/dist/containers/Navigation/reducer.js +7 -13
  20. package/dist/containers/RouteErrorHandler/ErrorContainer.js +17 -19
  21. package/dist/containers/RouteErrorHandler/index.js +28 -44
  22. package/dist/containers/Router/ApplicationRouter.js +14 -16
  23. package/dist/containers/Router/index.js +26 -42
  24. package/dist/containers/Router/reducer.js +3 -3
  25. package/dist/containers/Sidebar/NavbarBrand.js +14 -23
  26. package/dist/containers/Sidebar/SidebarBottomItem.js +16 -15
  27. package/dist/containers/Sidebar/SidebarIcon.js +9 -7
  28. package/dist/containers/Sidebar/SidebarItem.js +70 -85
  29. package/dist/containers/Sidebar/SidebarItemRenderer.js +20 -20
  30. package/dist/containers/Sidebar/index.js +20 -36
  31. package/dist/containers/Sidebar/reducer.js +3 -3
  32. package/dist/containers/Sidepanel/Sidepanel.js +18 -26
  33. package/dist/containers/Toast/ToastComponent.js +12 -12
  34. package/dist/containers/Toast/ToastContainer.js +19 -30
  35. package/dist/containers/Toast/reducer.js +3 -6
  36. package/dist/index.js +5 -5
  37. package/dist/modules/about/AboutScreen.js +30 -38
  38. package/dist/modules/about/index.js +8 -26
  39. package/dist/modules/auth/api.js +110 -156
  40. package/dist/modules/auth/components/SessionExpirationAlert.js +10 -9
  41. package/dist/modules/auth/header.js +25 -23
  42. package/dist/modules/auth/index.js +440 -692
  43. package/dist/modules/auth/reducer.js +2 -2
  44. package/dist/modules/auth/screens/AccessControlScreen.js +24 -25
  45. package/dist/modules/auth/screens/InvitationScreen.js +89 -128
  46. package/dist/modules/i18n/dropdown.js +24 -23
  47. package/dist/modules/i18n/index.js +20 -33
  48. package/dist/modules/i18n/reducer.js +2 -2
  49. package/dist/modules/i18n/service.js +48 -102
  50. package/dist/modules/tenant/TenantDropdown.js +28 -27
  51. package/dist/modules/tenant/access/AccessDeniedCard.js +28 -54
  52. package/dist/modules/tenant/index.js +16 -29
  53. package/dist/modules/tenant/reducer.js +1 -1
  54. package/dist/modules/tenant/service.js +123 -207
  55. package/dist/screens/InvalidRouteScreen.js +10 -9
  56. package/dist/screens/SuspenseScreen.js +11 -20
  57. package/dist/screens/UnauthorizedAccessScreen.js +18 -21
  58. package/dist/services/AttentionRequiredService.js +117 -142
  59. package/dist/services/BrandingService.js +63 -80
  60. package/dist/services/HeaderService.js +47 -66
  61. package/dist/services/ReduxService.js +11 -17
  62. package/dist/services/TitleService.js +13 -24
  63. package/dist/theme/ThemeButton.js +13 -10
  64. package/dist/theme/ThemeReducer.js +1 -1
  65. package/dist/theme/ThemeService.js +25 -38
  66. package/package.json +1 -1
@@ -1,19 +1,12 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- var _typeof = require("@babel/runtime/helpers/typeof");
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
8
- exports["default"] = void 0;
9
- var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
7
+ exports.default = void 0;
10
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
9
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
12
- var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
13
- var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
14
- var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
15
- var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
16
- var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
17
10
  var _react = _interopRequireWildcard(require("react"));
18
11
  var _reactRedux = require("react-redux");
19
12
  var _redux = require("redux");
@@ -49,16 +42,10 @@ var _ApplicationRouter = _interopRequireDefault(require("./Router/ApplicationRou
49
42
  var _SuspenseScreen = _interopRequireDefault(require("../screens/SuspenseScreen"));
50
43
  require("./Application.scss");
51
44
  var _actions = require("../actions");
52
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
53
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
54
- function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
55
- function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
56
- function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
45
+ 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); }
57
46
  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; }
58
- 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; }
59
- 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)); }
60
- function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
61
- var Application = /*#__PURE__*/function (_Component) {
47
+ 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; }
48
+ class Application extends _react.Component {
62
49
  /*
63
50
  Example of use hasSidebar.
64
51
  It must be set in Application.
@@ -95,737 +82,608 @@ var Application = /*#__PURE__*/function (_Component) {
95
82
  ...
96
83
  */
97
84
 
98
- function Application(props) {
99
- var _this;
100
- (0, _classCallCheck2["default"])(this, Application);
101
- _this = _callSuper(this, Application, [props]);
102
- _this.Modules = [];
103
- _this.Services = {};
104
- _this.ReduxService = new _ReduxService["default"](_this, "ReduxService");
105
- _this.ConfigService = new _ConfigService["default"](_this, "ConfigService");
106
- _this.Config = _this.ConfigService.Config;
107
- _this.Router = new _Router["default"](_this);
108
- _this.Navigation = new _Navigation["default"](_this);
109
- _this.SplashscreenRequestors = new Set(); // If not empty, the splash screen will be rendered
110
- _this.AxiosInterceptors = new Set();
111
- _this.WebSocketInterceptors = new Set();
112
- _this.AttentionRequiredService = new _AttentionRequiredService["default"](_this, "AttentionRequired");
113
- _this.HeaderService = new _HeaderService["default"](_this, "HeaderService");
114
- _this.ThemeService = new _ThemeService["default"](_this, "ThemeService");
115
- _this.BrandingService = new _BrandingService["default"](_this, "BrandingService");
116
- _this.TitleService = new _TitleService["default"](_this, "TitleService");
117
- _this.HelpService = new _HelpService["default"](_this, "HelpService");
118
- _this.PreviewService = new _PreviewService["default"](_this, "PreviewService");
119
- _this.ReduxService.addReducer("attentionrequired", _reducer8["default"]);
120
- _this.ReduxService.addReducer("alerts", _reducer["default"]);
121
- _this.ReduxService.addReducer("advmode", _reducer7["default"]);
122
- _this.ReduxService.addReducer("fullscreenmode", _reducer6["default"]);
123
- _this.ReduxService.addReducer("header", _reducer3["default"]);
124
- _this.ReduxService.addReducer("sidebar", _reducer2["default"]);
125
- _this.ReduxService.addReducer("navigation", _reducer4["default"]);
126
- _this.ReduxService.addReducer("router", _reducer5["default"]);
85
+ constructor(props) {
86
+ super(props);
87
+ this.Modules = [];
88
+ this.Services = {};
89
+ this.ReduxService = new _ReduxService.default(this, "ReduxService");
90
+ this.ConfigService = new _ConfigService.default(this, "ConfigService");
91
+ this.Config = this.ConfigService.Config;
92
+ this.Router = new _Router.default(this);
93
+ this.Navigation = new _Navigation.default(this);
94
+ this.SplashscreenRequestors = new Set(); // If not empty, the splash screen will be rendered
95
+ this.AxiosInterceptors = new Set();
96
+ this.WebSocketInterceptors = new Set();
97
+ this.AttentionRequiredService = new _AttentionRequiredService.default(this, "AttentionRequired");
98
+ this.HeaderService = new _HeaderService.default(this, "HeaderService");
99
+ this.ThemeService = new _ThemeService.default(this, "ThemeService");
100
+ this.BrandingService = new _BrandingService.default(this, "BrandingService");
101
+ this.TitleService = new _TitleService.default(this, "TitleService");
102
+ this.HelpService = new _HelpService.default(this, "HelpService");
103
+ this.PreviewService = new _PreviewService.default(this, "PreviewService");
104
+ this.ReduxService.addReducer("attentionrequired", _reducer8.default);
105
+ this.ReduxService.addReducer("alerts", _reducer.default);
106
+ this.ReduxService.addReducer("advmode", _reducer7.default);
107
+ this.ReduxService.addReducer("fullscreenmode", _reducer6.default);
108
+ this.ReduxService.addReducer("header", _reducer3.default);
109
+ this.ReduxService.addReducer("sidebar", _reducer2.default);
110
+ this.ReduxService.addReducer("navigation", _reducer4.default);
111
+ this.ReduxService.addReducer("router", _reducer5.default);
127
112
 
128
113
  // The application can provide a list of keys that should be automatically parsed as BigInt, when received from the server in Axios call
129
114
  // This is important to preserve 64bit numbers from the server such as IP addresses, timestamps etc.
130
- _this.JSONParseBigInt = new Set(props === null || props === void 0 ? void 0 : props.bigint);
131
- _this._handleKeyUp = _this._handleKeyUp.bind(_this);
132
- _this.state = {
115
+ this.JSONParseBigInt = new Set(props === null || props === void 0 ? void 0 : props.bigint);
116
+ this._handleKeyUp = this._handleKeyUp.bind(this);
117
+ this.state = {
133
118
  networking: 0,
134
119
  // If more than zero, some networking activity is happening
135
120
  splashscreenRequestors: 0
136
121
  };
137
122
  var composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || _redux.compose;
138
- _this.Store = (0, _redux.createStore)((0, _redux.combineReducers)(_this.ReduxService.Reducers), composeEnhancers((0, _redux.applyMiddleware)()));
139
- _this.ConfigService.addDefaults(props.configdefaults);
140
- _this.Config.dispatch(_this.Store);
141
- _this.addSplashScreenRequestor(_this);
142
- _this.state.splashscreenRequestors = _this.SplashscreenRequestors.size;
143
- var that = _this;
123
+ this.Store = (0, _redux.createStore)((0, _redux.combineReducers)(this.ReduxService.Reducers), composeEnhancers((0, _redux.applyMiddleware)()));
124
+ this.ConfigService.addDefaults(props.configdefaults);
125
+ this.Config.dispatch(this.Store);
126
+ this.addSplashScreenRequestor(this);
127
+ this.state.splashscreenRequestors = this.SplashscreenRequestors.size;
128
+ var that = this;
144
129
  function modules_init() {
145
130
  return _modules_init.apply(this, arguments);
146
131
  }
147
132
  function _modules_init() {
148
- _modules_init = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee2() {
149
- var i, modcandidate, modloaded, mod, _mod, ret;
150
- return _regenerator["default"].wrap(function _callee2$(_context2) {
151
- while (1) switch (_context2.prev = _context2.next) {
152
- case 0:
153
- _context2.t0 = _regenerator["default"].keys(props.modules);
154
- case 1:
155
- if ((_context2.t1 = _context2.t0()).done) {
156
- _context2.next = 29;
157
- break;
158
- }
159
- i = _context2.t1.value;
160
- // The candidate can be:
161
- // 1. { Module } from "asab_webui_components"
162
- // 2. A promise that loads the remote module from the federated application
163
- modcandidate = props.modules[i];
164
- modloaded = void 0;
165
- if (!(modcandidate.prototype instanceof _asab_webui_components.Module)) {
166
- _context2.next = 10;
167
- break;
168
- }
169
- // This is a Module from "asab_webui_components"
170
- mod = new modcandidate(that);
171
- that.Modules.push(mod);
172
- _context2.next = 25;
173
- break;
174
- case 10:
175
- _context2.prev = 10;
176
- _context2.next = 13;
177
- return Promise.resolve(modcandidate);
178
- case 13:
179
- modloaded = _context2.sent;
180
- _context2.next = 20;
181
- break;
182
- case 16:
183
- _context2.prev = 16;
184
- _context2.t2 = _context2["catch"](10);
185
- if (_context2.t2 instanceof Error && _context2.t2.name == 'ScriptExternalLoadError') {
133
+ _modules_init = (0, _asyncToGenerator2.default)(function* () {
134
+ // Instantiate statically imported modules
135
+ for (var i in props.modules) {
136
+ // The candidate can be:
137
+ // 1. { Module } from "asab_webui_components"
138
+ // 2. A promise that loads the remote module from the federated application
139
+ var modcandidate = props.modules[i];
140
+ var modloaded = void 0;
141
+ if (modcandidate.prototype instanceof _asab_webui_components.Module) {
142
+ // This is a Module from "asab_webui_components"
143
+ var mod = new modcandidate(that);
144
+ that.Modules.push(mod);
145
+ } else {
146
+ // This is load of the remote module from a federated application using promise
147
+ try {
148
+ modloaded = yield Promise.resolve(modcandidate);
149
+ } catch (error) {
150
+ if (error instanceof Error && error.name == 'ScriptExternalLoadError') {
186
151
  // The initial load of the remote failed; it is ok in development environment
187
- console.warn("Failed to load a remote module: ScriptExternalLoadError:", _context2.t2.message);
152
+ console.warn("Failed to load a remote module: ScriptExternalLoadError:", error.message);
188
153
  } else {
189
- console.error(_context2.t2);
190
- }
191
- return _context2.abrupt("continue", 1);
192
- case 20:
193
- if (!(!modloaded["default"].prototype instanceof _asab_webui_components.Module)) {
194
- _context2.next = 23;
195
- break;
154
+ console.error(error);
196
155
  }
156
+ continue;
157
+ }
158
+
159
+ // Sanity check
160
+ if (!modloaded.default.prototype instanceof _asab_webui_components.Module) {
197
161
  console.error("The default object from the remote is not a Module - skipping");
198
- return _context2.abrupt("continue", 1);
199
- case 23:
200
- _mod = new modloaded["default"](that); // We expect 'export default class ...Module extends Module'
201
- that.Modules.push(_mod);
202
- case 25:
203
- that.Store.replaceReducer((0, _redux.combineReducers)(that.ReduxService.Reducers));
204
- that.Config.dispatch(that.Store);
205
- _context2.next = 1;
206
- break;
207
- case 29:
208
- _context2.t3 = _regenerator["default"].keys(that.Modules);
209
- case 30:
210
- if ((_context2.t4 = _context2.t3()).done) {
211
- _context2.next = 37;
212
- break;
213
- }
214
- i = _context2.t4.value;
215
- ret = that.Modules[i].initialize(); // Transform result in the promise
216
- // It unifies synchronous and asynchronous `initialize()` calls
217
- _context2.next = 35;
218
- return Promise.resolve(ret);
219
- case 35:
220
- _context2.next = 30;
221
- break;
222
- case 37:
223
- case "end":
224
- return _context2.stop();
162
+ continue; // The load of the remote failed
163
+ }
164
+ var _mod = new modloaded.default(that); // We expect 'export default class ...Module extends Module'
165
+ that.Modules.push(_mod);
225
166
  }
226
- }, _callee2, null, [[10, 16]]);
227
- }));
167
+ that.Store.replaceReducer((0, _redux.combineReducers)(that.ReduxService.Reducers));
168
+ that.Config.dispatch(that.Store);
169
+ }
170
+
171
+ // Initialize statically imported modules
172
+ for (var i in that.Modules) {
173
+ var ret = that.Modules[i].initialize();
174
+
175
+ // Transform result in the promise
176
+ // It unifies synchronous and asynchronous `initialize()` calls
177
+ yield Promise.resolve(ret);
178
+ }
179
+ });
228
180
  return _modules_init.apply(this, arguments);
229
181
  }
230
- modules_init().then(/*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee() {
231
- var i, ret;
232
- return _regenerator["default"].wrap(function _callee$(_context) {
233
- while (1) switch (_context.prev = _context.next) {
234
- case 0:
235
- that.Store.replaceReducer((0, _redux.combineReducers)(that.ReduxService.Reducers));
236
- that.Config.dispatch(that.Store);
237
-
238
- // Initialize all services
239
- _context.t0 = _regenerator["default"].keys(that.Services);
240
- case 3:
241
- if ((_context.t1 = _context.t0()).done) {
242
- _context.next = 11;
243
- break;
244
- }
245
- i = _context.t1.value;
246
- ret = that.Services[i].initialize(); // Transform result in the promise
247
- // It unifies synchronous and asynchronous `initialize()` calls
248
- _context.next = 8;
249
- return Promise.resolve(ret);
250
- case 8:
251
- that.Config.dispatch(that.Store);
252
- _context.next = 3;
253
- break;
254
- case 11:
255
- that.removeSplashScreenRequestor(that);
256
- case 12:
257
- case "end":
258
- return _context.stop();
259
- }
260
- }, _callee);
261
- })));
262
- return _this;
263
- }
264
- (0, _inherits2["default"])(Application, _Component);
265
- return (0, _createClass2["default"])(Application, [{
266
- key: "getServiceURL",
267
- value: function getServiceURL(service) {
268
- // Handle if service is unknown => return undefined
269
- if (service == undefined) {
270
- console.warn("Service is undefined!");
271
- return undefined;
182
+ modules_init().then(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () {
183
+ that.Store.replaceReducer((0, _redux.combineReducers)(that.ReduxService.Reducers));
184
+ that.Config.dispatch(that.Store);
185
+
186
+ // Initialize all services
187
+ for (var i in that.Services) {
188
+ var ret = that.Services[i].initialize();
189
+
190
+ // Transform result in the promise
191
+ // It unifies synchronous and asynchronous `initialize()` calls
192
+ yield Promise.resolve(ret);
193
+ that.Config.dispatch(that.Store);
272
194
  }
195
+ that.removeSplashScreenRequestor(that);
196
+ }));
197
+ }
198
+ getServiceURL(service) {
199
+ // Handle if service is unknown => return undefined
200
+ if (service == undefined) {
201
+ console.warn("Service is undefined!");
202
+ return undefined;
203
+ }
273
204
 
274
- // Handle if SERVICES not provided, empty object will be used as default
275
- var services = this.Config.get('SERVICES') ? this.Config.get('SERVICES') : {};
205
+ // Handle if SERVICES not provided, empty object will be used as default
206
+ var services = this.Config.get('SERVICES') ? this.Config.get('SERVICES') : {};
276
207
 
277
- // Handle if service is not in SERVICES => use service as service_path
278
- var service_path = services[service] ? services[service] : service;
208
+ // Handle if service is not in SERVICES => use service as service_path
209
+ var service_path = services[service] ? services[service] : service;
279
210
 
280
- // If service_path is complete URL, then return that URL
281
- if (service_path.toString().indexOf('http://') !== -1 || service_path.toString().indexOf('https://') !== -1) {
282
- return service_path;
283
- }
284
- // If service_path is complete WebSocket URL, then return that URL
285
- if (service_path.toString().indexOf('ws://') !== -1 || service_path.toString().indexOf('wss://') !== -1) {
286
- return service_path;
287
- }
211
+ // If service_path is complete URL, then return that URL
212
+ if (service_path.toString().indexOf('http://') !== -1 || service_path.toString().indexOf('https://') !== -1) {
213
+ return service_path;
214
+ }
215
+ // If service_path is complete WebSocket URL, then return that URL
216
+ if (service_path.toString().indexOf('ws://') !== -1 || service_path.toString().indexOf('wss://') !== -1) {
217
+ return service_path;
218
+ }
288
219
 
289
- // Obtain BASE_URL
290
- var BASE_URL = undefined;
291
- if (this.Config.get('BASE_URL') == undefined) {
292
- // If BASE_URL has not been defined => take browser URL as BASE_URL
293
- BASE_URL = window.location.protocol + '//' + window.location.host + window.location.pathname.replace(/\/$/, '');
294
- } else if (this.Config.get('BASE_URL').toString().indexOf('http://') !== -1 || this.Config.get('BASE_URL').toString().indexOf('https://') !== -1) {
295
- // If BASE_URL has been defined => take defined BASE_URL as BASE_URL
296
- BASE_URL = this.Config.get('BASE_URL');
297
- } else {
298
- // If BASE_URL has been defined but with relative path => take browser URL as BASE_URL and append relative path from BASE_URL behind the browser URL
299
- var relative_base_url = this.Config.get('BASE_URL');
300
- // Check if trailing slash has been added on first place of a BASE_URL string and if so, remove it
301
- if (relative_base_url.indexOf("/", 0) == 0) {
302
- relative_base_url = relative_base_url.substring(1);
303
- }
304
- BASE_URL = window.location.protocol + '//' + window.location.host + window.location.pathname.replace(/\/$/, '') + '/' + relative_base_url.replace(/\/$/, '');
220
+ // Obtain BASE_URL
221
+ var BASE_URL = undefined;
222
+ if (this.Config.get('BASE_URL') == undefined) {
223
+ // If BASE_URL has not been defined => take browser URL as BASE_URL
224
+ BASE_URL = window.location.protocol + '//' + window.location.host + window.location.pathname.replace(/\/$/, '');
225
+ } else if (this.Config.get('BASE_URL').toString().indexOf('http://') !== -1 || this.Config.get('BASE_URL').toString().indexOf('https://') !== -1) {
226
+ // If BASE_URL has been defined => take defined BASE_URL as BASE_URL
227
+ BASE_URL = this.Config.get('BASE_URL');
228
+ } else {
229
+ // If BASE_URL has been defined but with relative path => take browser URL as BASE_URL and append relative path from BASE_URL behind the browser URL
230
+ var relative_base_url = this.Config.get('BASE_URL');
231
+ // Check if trailing slash has been added on first place of a BASE_URL string and if so, remove it
232
+ if (relative_base_url.indexOf("/", 0) == 0) {
233
+ relative_base_url = relative_base_url.substring(1);
305
234
  }
235
+ BASE_URL = window.location.protocol + '//' + window.location.host + window.location.pathname.replace(/\/$/, '') + '/' + relative_base_url.replace(/\/$/, '');
236
+ }
306
237
 
307
- // Compose service_url
308
- var service_url = undefined;
309
- if (this.Config.get('API_PATH') == undefined) {
310
- // If API_PATH has not been defined => use /api to compose service_url
311
- service_url = BASE_URL.replace(/\/$/, '') + '/api';
312
- } else if (this.Config.get('API_PATH').toString().indexOf('http://') !== -1 || this.Config.get('API_PATH').toString().indexOf('https://') !== -1) {
313
- // If API_PATH has been defined but with absolute URL => use API_PATH as service_url
314
- service_url = this.Config.get('API_PATH');
315
- } else {
316
- // If API_PATH has been defined => use API_PATH to compose service_url
317
- var api_path = this.Config.get('API_PATH');
318
- // Check if trailing slash has been added on first place of a API_PATH string and if so, remove it
319
- if (api_path.indexOf("/", 0) == 0) {
320
- api_path = api_path.substring(1);
321
- }
322
- service_url = BASE_URL.replace(/\/$/, '') + "/" + api_path;
238
+ // Compose service_url
239
+ var service_url = undefined;
240
+ if (this.Config.get('API_PATH') == undefined) {
241
+ // If API_PATH has not been defined => use /api to compose service_url
242
+ service_url = BASE_URL.replace(/\/$/, '') + '/api';
243
+ } else if (this.Config.get('API_PATH').toString().indexOf('http://') !== -1 || this.Config.get('API_PATH').toString().indexOf('https://') !== -1) {
244
+ // If API_PATH has been defined but with absolute URL => use API_PATH as service_url
245
+ service_url = this.Config.get('API_PATH');
246
+ } else {
247
+ // If API_PATH has been defined => use API_PATH to compose service_url
248
+ var api_path = this.Config.get('API_PATH');
249
+ // Check if trailing slash has been added on first place of a API_PATH string and if so, remove it
250
+ if (api_path.indexOf("/", 0) == 0) {
251
+ api_path = api_path.substring(1);
323
252
  }
324
- return service_url.replace(/\/$/, '') + "/" + service_path;
253
+ service_url = BASE_URL.replace(/\/$/, '') + "/" + api_path;
325
254
  }
255
+ return service_url.replace(/\/$/, '') + "/" + service_path;
256
+ }
326
257
 
327
- /*
328
- * Creates an AXIOS object for communication with TeskaLabs API's
329
- *
330
- * IMPORTANT NOTE:
331
- * Bearer token will be sent to any URL specified in the API / Services configuration.
332
- * axiosCreate must only be used for creating http sessions
333
- * towards TeskaLabs API's, since it adds Bearer token to all calls.
334
- */
335
- }, {
336
- key: "axiosCreate",
337
- value: function axiosCreate(service, props) {
338
- var service_url = this.getServiceURL(service);
339
- if (service_url == undefined) {
340
- this.addAlert('danger', "ASABApplicationContainer|Service URL is undefined, please check service paths passed to axios", 5, true);
341
- return undefined;
342
- }
343
- var axios = _axios["default"].create(_objectSpread(_objectSpread({}, props), {}, {
344
- transformResponse: function transformResponse(res) {
345
- return res;
346
- },
347
- // Disable implicit JSON parsing, we explicitly parse JSON in the interceptor ( https://stackoverflow.com/questions/41013082/disable-json-parsing-in-axios )
348
- baseURL: service_url
349
- }));
350
-
351
- // Iterate through custom interceptors
352
- var _iterator = _createForOfIteratorHelper(this.AxiosInterceptors.keys()),
353
- _step;
354
- try {
355
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
356
- var interceptor = _step.value;
357
- this.interceptorRequest(axios, interceptor);
358
- }
359
- } catch (err) {
360
- _iterator.e(err);
361
- } finally {
362
- _iterator.f();
363
- }
364
- var that = this;
258
+ /*
259
+ * Creates an AXIOS object for communication with TeskaLabs API's
260
+ *
261
+ * IMPORTANT NOTE:
262
+ * Bearer token will be sent to any URL specified in the API / Services configuration.
263
+ * axiosCreate must only be used for creating http sessions
264
+ * towards TeskaLabs API's, since it adds Bearer token to all calls.
265
+ */
266
+ axiosCreate(service, props) {
267
+ var service_url = this.getServiceURL(service);
268
+ if (service_url == undefined) {
269
+ this.addAlert('danger', "ASABApplicationContainer|Service URL is undefined, please check service paths passed to axios", 5, true);
270
+ return undefined;
271
+ }
272
+ var axios = _axios.default.create(_objectSpread(_objectSpread({}, props), {}, {
273
+ transformResponse: res => res,
274
+ // Disable implicit JSON parsing, we explicitly parse JSON in the interceptor ( https://stackoverflow.com/questions/41013082/disable-json-parsing-in-axios )
275
+ baseURL: service_url
276
+ }));
365
277
 
366
- /*
367
- We want to be notified when networking activity is taking place,
368
- thus we use pushNetworkingIndicator.
369
- Default request headers are X-App and X-Request-Id which
370
- define recognition of the requests from the service perspective
371
- */
372
- axios.interceptors.request.use(function (config) {
373
- that.pushNetworkingIndicator();
374
- config.headers['X-App'] = "webui"; // Include X-App header in every axios API request
375
- config.headers['X-Request-Id'] = that._generateUID(); // Include X-Request-Id header in every axios API request
376
- return config;
377
- }, function (error) {
378
- return Promise.reject(error);
379
- });
278
+ // Iterate through custom interceptors
279
+ for (var interceptor of this.AxiosInterceptors.keys()) {
280
+ this.interceptorRequest(axios, interceptor);
281
+ }
282
+ var that = this;
380
283
 
381
- // We want to remove the networking indicator when we receive the response
382
- axios.interceptors.response.use(function (response) {
383
- var _response$headers$con;
384
- // Call the `popNetworkingIndicator` method to remove the networking indicator (e.g., loading spinner)
385
- that.popNetworkingIndicator();
386
-
387
- /*
388
- Custom flag to control JSON parsing for specific requests.
389
- If 'skipJsonParsing' is set to true in the request config,
390
- we return the raw response and skip automatic JSON parsing in the interceptor.
391
- This is useful when we need to get the response as plain text (e.g., for retrieving raw content).
392
- */
393
- if (response.config.skipJsonParsing) {
394
- return response;
395
- }
284
+ /*
285
+ We want to be notified when networking activity is taking place,
286
+ thus we use pushNetworkingIndicator.
287
+ Default request headers are X-App and X-Request-Id which
288
+ define recognition of the requests from the service perspective
289
+ */
290
+ axios.interceptors.request.use(function (config) {
291
+ that.pushNetworkingIndicator();
292
+ config.headers['X-App'] = "webui"; // Include X-App header in every axios API request
293
+ config.headers['X-Request-Id'] = that._generateUID(); // Include X-Request-Id header in every axios API request
294
+ return config;
295
+ }, function (error) {
296
+ return Promise.reject(error);
297
+ });
396
298
 
397
- // Check if the response content type is 'application/json' or starts with 'application/json'
398
- if (response !== null && response !== void 0 && (_response$headers$con = response.headers['content-type']) !== null && _response$headers$con !== void 0 && _response$headers$con.startsWith('application/json')) {
399
- // If the response is JSON, then parse it with respect to BigInt
400
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
401
- try {
402
- // Parse the response data using a custom reviver function
403
- response.data = JSON.parse(response.data,
404
- // Custom reviver function to handle BigInt values
405
- function (key, value, context) {
406
- // If there is no data in the JSONParseBigInt, return the value immediately
407
- if (that.JSONParseBigInt.size === 0) {
408
- return value;
409
- }
410
- // Check if the key is in the `JSONParseBigInt` set and the value is a number
411
- if (that.JSONParseBigInt.has(key) && typeof value === 'number') {
412
- // Convert the number to a BigInt
413
- return BigInt(context.source);
414
- }
415
- // Return the original value if no conversion is needed
416
- return value;
417
- });
418
- } catch (e) {
419
- // Log any errors that occur during JSON parsing
420
- console.error("Error in axios.interceptors.response", e);
421
- }
422
- }
423
- // If the request was satisfied (application/json and presence of BigInt) return the modified object. If not, we return unchanged object
424
- return response;
425
- }, function (error) {
426
- var _error$response, _error$response2;
427
- that.popNetworkingIndicator();
428
- var contentType = error === null || error === void 0 || (_error$response = error.response) === null || _error$response === void 0 || (_error$response = _error$response.headers) === null || _error$response === void 0 ? void 0 : _error$response['content-type'];
429
- // Check if the response content type is 'application/json' and data is a string
430
- if (contentType !== null && contentType !== void 0 && contentType.startsWith('application/json') && typeof (error === null || error === void 0 || (_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.data) === 'string') {
431
- try {
432
- error.response.data = JSON.parse(error.response.data);
433
- } catch (e) {
434
- console.error("Error parsing error of the error body:", e);
435
- }
436
- }
437
- return Promise.reject(error);
438
- });
439
- return axios;
440
- }
299
+ // We want to remove the networking indicator when we receive the response
300
+ axios.interceptors.response.use(function (response) {
301
+ var _response$headers$con;
302
+ // Call the `popNetworkingIndicator` method to remove the networking indicator (e.g., loading spinner)
303
+ that.popNetworkingIndicator();
441
304
 
442
- // Internal method for generating random UID's
443
- }, {
444
- key: "_generateUID",
445
- value: function _generateUID() {
446
305
  /*
447
- - Math.random() * 0x100000000: Generates a random floating-point number between 0 and 0x100000000.
448
- - >>> 0: Applies a bitwise unsigned right shift by 0, effectively converting the floating-point number to a 32-bit unsigned integer.
449
- - toString(36): Converts the integer to a base-36 string, using the digits 0-9 and letters a-z.
306
+ Custom flag to control JSON parsing for specific requests.
307
+ If 'skipJsonParsing' is set to true in the request config,
308
+ we return the raw response and skip automatic JSON parsing in the interceptor.
309
+ This is useful when we need to get the response as plain text (e.g., for retrieving raw content).
450
310
  */
451
- return (Math.random() * 0x100000000 >>> 0).toString(36) + (Math.random() * 0x100000000 >>> 0).toString(36) + (Math.random() * 0x100000000 >>> 0).toString(36) + (Math.random() * 0x100000000 >>> 0).toString(36);
452
- }
453
- }, {
454
- key: "interceptorRequest",
455
- value: function interceptorRequest(axios, interceptor) {
456
- // Add a request interceptor
457
- axios.interceptors.request.use(interceptor, function (error) {
458
- return Promise.reject(error);
459
- });
460
- }
461
- }, {
462
- key: "addAxiosInterceptor",
463
- value: function addAxiosInterceptor(interceptor) {
464
- this.AxiosInterceptors.add(interceptor);
465
- }
466
- }, {
467
- key: "removeAxiosInterceptor",
468
- value: function removeAxiosInterceptor(interceptor) {
469
- this.AxiosInterceptors["delete"](interceptor);
470
- }
471
- }, {
472
- key: "addWebSocketInterceptor",
473
- value: function addWebSocketInterceptor(interceptor) {
474
- this.WebSocketInterceptors.add(interceptor);
475
- }
476
- }, {
477
- key: "removeWebSocketInterceptor",
478
- value: function removeWebSocketInterceptor(interceptor) {
479
- this.WebSocketInterceptors["delete"](interceptor);
480
- }
481
- }, {
482
- key: "getWebSocketURL",
483
- value: function getWebSocketURL(service, subpath) {
484
- // Handle if service is unknown => return undefined
485
- var service_url = this.getServiceURL(service);
486
- if (service_url == undefined) {
487
- return undefined;
311
+ if (response.config.skipJsonParsing) {
312
+ return response;
488
313
  }
489
314
 
490
- // Handle if subpath is unknown => subpath = ""
491
- if (subpath == undefined) {
492
- subpath = "";
315
+ // Check if the response content type is 'application/json' or starts with 'application/json'
316
+ if (response !== null && response !== void 0 && (_response$headers$con = response.headers['content-type']) !== null && _response$headers$con !== void 0 && _response$headers$con.startsWith('application/json')) {
317
+ // If the response is JSON, then parse it with respect to BigInt
318
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
319
+ try {
320
+ // Parse the response data using a custom reviver function
321
+ response.data = JSON.parse(response.data,
322
+ // Custom reviver function to handle BigInt values
323
+ (key, value, context) => {
324
+ // If there is no data in the JSONParseBigInt, return the value immediately
325
+ if (that.JSONParseBigInt.size === 0) {
326
+ return value;
327
+ }
328
+ // Check if the key is in the `JSONParseBigInt` set and the value is a number
329
+ if (that.JSONParseBigInt.has(key) && typeof value === 'number') {
330
+ // Convert the number to a BigInt
331
+ return BigInt(context.source);
332
+ }
333
+ // Return the original value if no conversion is needed
334
+ return value;
335
+ });
336
+ } catch (e) {
337
+ // Log any errors that occur during JSON parsing
338
+ console.error("Error in axios.interceptors.response", e);
339
+ }
493
340
  }
494
-
495
- // If service_path is complete WebSocket URL, then return that URL
496
- if (service_url.toString().indexOf('ws://') !== -1 || service_url.toString().indexOf('wss://') !== -1) {
497
- return service_url;
341
+ // If the request was satisfied (application/json and presence of BigInt) return the modified object. If not, we return unchanged object
342
+ return response;
343
+ }, function (error) {
344
+ var _error$response, _error$response2;
345
+ that.popNetworkingIndicator();
346
+ var contentType = error === null || error === void 0 || (_error$response = error.response) === null || _error$response === void 0 || (_error$response = _error$response.headers) === null || _error$response === void 0 ? void 0 : _error$response['content-type'];
347
+ // Check if the response content type is 'application/json' and data is a string
348
+ if (contentType !== null && contentType !== void 0 && contentType.startsWith('application/json') && typeof (error === null || error === void 0 || (_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.data) === 'string') {
349
+ try {
350
+ error.response.data = JSON.parse(error.response.data);
351
+ } catch (e) {
352
+ console.error("Error parsing error of the error body:", e);
353
+ }
498
354
  }
355
+ return Promise.reject(error);
356
+ });
357
+ return axios;
358
+ }
499
359
 
500
- // Replace http:// or https:// protocol with ws:// or wss://
501
- var ws_service_url = service_url.replace(/(http)(s)?\:\/\//, "ws$2://");
502
- return ws_service_url + subpath;
360
+ // Internal method for generating random UID's
361
+ _generateUID() {
362
+ /*
363
+ - Math.random() * 0x100000000: Generates a random floating-point number between 0 and 0x100000000.
364
+ - >>> 0: Applies a bitwise unsigned right shift by 0, effectively converting the floating-point number to a 32-bit unsigned integer.
365
+ - toString(36): Converts the integer to a base-36 string, using the digits 0-9 and letters a-z.
366
+ */
367
+ return (Math.random() * 0x100000000 >>> 0).toString(36) + (Math.random() * 0x100000000 >>> 0).toString(36) + (Math.random() * 0x100000000 >>> 0).toString(36) + (Math.random() * 0x100000000 >>> 0).toString(36);
368
+ }
369
+ interceptorRequest(axios, interceptor) {
370
+ // Add a request interceptor
371
+ axios.interceptors.request.use(interceptor, function (error) {
372
+ return Promise.reject(error);
373
+ });
374
+ }
375
+ addAxiosInterceptor(interceptor) {
376
+ this.AxiosInterceptors.add(interceptor);
377
+ }
378
+ removeAxiosInterceptor(interceptor) {
379
+ this.AxiosInterceptors.delete(interceptor);
380
+ }
381
+ addWebSocketInterceptor(interceptor) {
382
+ this.WebSocketInterceptors.add(interceptor);
383
+ }
384
+ removeWebSocketInterceptor(interceptor) {
385
+ this.WebSocketInterceptors.delete(interceptor);
386
+ }
387
+ getWebSocketURL(service, subpath) {
388
+ // Handle if service is unknown => return undefined
389
+ var service_url = this.getServiceURL(service);
390
+ if (service_url == undefined) {
391
+ return undefined;
503
392
  }
504
- }, {
505
- key: "createWebSocket",
506
- value: function createWebSocket(service, subpath) {
507
- var socket_url = this.getWebSocketURL(service, subpath);
508
- if (socket_url == undefined) {
509
- this.addAlert('danger', "ASABApplicationContainer|WebSocket URL is undefined, please check service and subpath passed to WebSocket", 5, true);
510
- return undefined;
511
- }
512
-
513
- /*
514
- Adding ws interceptors to the ws subprotocols (e.g. to pass auth token).
515
- "asab" subprotocol is given by default for consumer (any websocket service)
516
- which require this particular value to authenticate websocket connection,
517
- since some browsers (Chrome, Safari, ...) requires Sec-Websocket-Accept
518
- response header.
519
- Another default subprotocols are "app_webui" and "request_id_<uid>"
520
- which define recognition of the requests from the service perspective
521
- */
522
- var subprotocols = ["asab", "app_webui", "request_id_".concat(this._generateUID())];
523
- var _iterator2 = _createForOfIteratorHelper(this.WebSocketInterceptors.keys()),
524
- _step2;
525
- try {
526
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
527
- var interceptor = _step2.value;
528
- // Avoid pushing undefined interceptor values
529
- if (interceptor) {
530
- subprotocols.push(interceptor);
531
- }
532
- }
533
393
 
534
- // Create new WebSocket based on socket URL
535
- } catch (err) {
536
- _iterator2.e(err);
537
- } finally {
538
- _iterator2.f();
539
- }
540
- var socket = new WebSocket(socket_url, subprotocols);
541
- return socket;
394
+ // Handle if subpath is unknown => subpath = ""
395
+ if (subpath == undefined) {
396
+ subpath = "";
542
397
  }
543
398
 
544
- // Display and hide networking indicator
545
- }, {
546
- key: "pushNetworkingIndicator",
547
- value: function pushNetworkingIndicator() {
548
- this.setState(function (prevState, props) {
549
- return {
550
- networking: prevState.networking + 1
551
- };
552
- });
553
- }
554
- }, {
555
- key: "popNetworkingIndicator",
556
- value: function popNetworkingIndicator() {
557
- this.setState(function (prevState, props) {
558
- return {
559
- networking: prevState.networking - 1
560
- };
561
- });
399
+ // If service_path is complete WebSocket URL, then return that URL
400
+ if (service_url.toString().indexOf('ws://') !== -1 || service_url.toString().indexOf('wss://') !== -1) {
401
+ return service_url;
562
402
  }
563
- }, {
564
- key: "registerService",
565
- value: function registerService(service) {
566
- if (service.Name in this.Services) {
567
- console.warn("Service ".concat(service.Name, " is already registered."));
568
- return;
569
- }
570
- this.Services[service.Name] = service;
403
+
404
+ // Replace http:// or https:// protocol with ws:// or wss://
405
+ var ws_service_url = service_url.replace(/(http)(s)?\:\/\//, "ws$2://");
406
+ return ws_service_url + subpath;
407
+ }
408
+ createWebSocket(service, subpath) {
409
+ var socket_url = this.getWebSocketURL(service, subpath);
410
+ if (socket_url == undefined) {
411
+ this.addAlert('danger', "ASABApplicationContainer|WebSocket URL is undefined, please check service and subpath passed to WebSocket", 5, true);
412
+ return undefined;
571
413
  }
572
- }, {
573
- key: "locateService",
574
- value: function locateService(name) {
575
- if (!name in this.Services) {
576
- console.warn("Service ".concat(name, " doesn't exist."));
577
- return null;
414
+
415
+ /*
416
+ Adding ws interceptors to the ws subprotocols (e.g. to pass auth token).
417
+ "asab" subprotocol is given by default for consumer (any websocket service)
418
+ which require this particular value to authenticate websocket connection,
419
+ since some browsers (Chrome, Safari, ...) requires Sec-Websocket-Accept
420
+ response header.
421
+ Another default subprotocols are "app_webui" and "request_id_<uid>"
422
+ which define recognition of the requests from the service perspective
423
+ */
424
+ var subprotocols = ["asab", "app_webui", "request_id_".concat(this._generateUID())];
425
+ for (var interceptor of this.WebSocketInterceptors.keys()) {
426
+ // Avoid pushing undefined interceptor values
427
+ if (interceptor) {
428
+ subprotocols.push(interceptor);
578
429
  }
579
- return this.Services[name];
580
430
  }
581
431
 
582
- // This function handles keystroke events and performs enabling/disabling of mods
583
- }, {
584
- key: "_handleKeyUp",
585
- value: function _handleKeyUp(event) {
586
- // CTRL+SHIFT+F enables the fullscreen mode
587
- if (event.ctrlKey && event.shiftKey && event.code === 'KeyF') {
588
- this.setFullScreenMode('on');
589
- }
432
+ // Create new WebSocket based on socket URL
433
+ var socket = new WebSocket(socket_url, subprotocols);
434
+ return socket;
435
+ }
590
436
 
591
- // CTRL+Q (Windows) or CTRL+1 (Linux) enables the advanced mode
592
- if (event.ctrlKey && event.code === 'KeyQ' || event.code === 'Digit1' && event.ctrlKey) {
593
- this.setAdvancedMode(0);
594
- }
595
- }
596
- }, {
597
- key: "componentDidMount",
598
- value: function componentDidMount() {
599
- document.addEventListener("keyup", this._handleKeyUp, false);
437
+ // Display and hide networking indicator
438
+ pushNetworkingIndicator() {
439
+ this.setState((prevState, props) => ({
440
+ networking: prevState.networking + 1
441
+ }));
442
+ }
443
+ popNetworkingIndicator() {
444
+ this.setState((prevState, props) => ({
445
+ networking: prevState.networking - 1
446
+ }));
447
+ }
448
+ registerService(service) {
449
+ if (service.Name in this.Services) {
450
+ console.warn("Service ".concat(service.Name, " is already registered."));
451
+ return;
600
452
  }
601
- }, {
602
- key: "componentWillUnmount",
603
- value: function componentWillUnmount() {
604
- document.removeEventListener("keyup", this._handleKeyUp, false);
453
+ this.Services[service.Name] = service;
454
+ }
455
+ locateService(name) {
456
+ if (!name in this.Services) {
457
+ console.warn("Service ".concat(name, " doesn't exist."));
458
+ return null;
605
459
  }
460
+ return this.Services[name];
461
+ }
606
462
 
607
- // Splash screen
608
- }, {
609
- key: "addSplashScreenRequestor",
610
- value: function addSplashScreenRequestor(obj) {
611
- var origLen = this.SplashscreenRequestors.size;
612
- this.SplashscreenRequestors.add(obj);
613
- if (origLen != this.SplashscreenRequestors.size) {
614
- this.state.splashscreenRequestors = this.SplashscreenRequestors.size;
615
- }
616
- var splashscreen = document.getElementById('app-splashscreen'); // See public/index.html`
617
- splashscreen === null || splashscreen === void 0 || splashscreen.classList.remove("d-none");
463
+ // This function handles keystroke events and performs enabling/disabling of mods
464
+ _handleKeyUp(event) {
465
+ // CTRL+SHIFT+F enables the fullscreen mode
466
+ if (event.ctrlKey && event.shiftKey && event.code === 'KeyF') {
467
+ this.setFullScreenMode('on');
618
468
  }
619
- }, {
620
- key: "removeSplashScreenRequestor",
621
- value: function removeSplashScreenRequestor(obj) {
622
- var origLen = this.SplashscreenRequestors.size;
623
- this.SplashscreenRequestors["delete"](obj);
624
- if (origLen != this.SplashscreenRequestors.size) {
625
- this.setState({
626
- splashscreenRequestors: this.SplashscreenRequestors.size
627
- });
628
- }
629
- if (this.SplashscreenRequestors.size == 0) {
630
- var splashscreen = document.getElementById('app-splashscreen'); // See public/index.html
631
- splashscreen === null || splashscreen === void 0 || splashscreen.classList.add("d-none");
632
- }
469
+
470
+ // CTRL+Q (Windows) or CTRL+1 (Linux) enables the advanced mode
471
+ if (event.ctrlKey && event.code === 'KeyQ' || event.code === 'Digit1' && event.ctrlKey) {
472
+ this.setAdvancedMode(0);
633
473
  }
474
+ }
475
+ componentDidMount() {
476
+ document.addEventListener("keyup", this._handleKeyUp, false);
477
+ }
478
+ componentWillUnmount() {
479
+ document.removeEventListener("keyup", this._handleKeyUp, false);
480
+ }
634
481
 
635
- // Alerts
636
- /*
637
- levels:
638
- * danger
639
- * warning
640
- * info
641
- * success
642
- */
643
- }, {
644
- key: "addAlert",
645
- value: function addAlert(level, message) {
646
- var expire = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 5;
647
- var shouldBeTranslated = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
648
- var component = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
649
- this.Store.dispatch({
650
- type: _actions.ADD_ALERT,
651
- level: level,
652
- message: message,
653
- expire: expire,
654
- shouldBeTranslated: shouldBeTranslated,
655
- component: component
482
+ // Splash screen
483
+
484
+ addSplashScreenRequestor(obj) {
485
+ var origLen = this.SplashscreenRequestors.size;
486
+ this.SplashscreenRequestors.add(obj);
487
+ if (origLen != this.SplashscreenRequestors.size) {
488
+ this.state.splashscreenRequestors = this.SplashscreenRequestors.size;
489
+ }
490
+ var splashscreen = document.getElementById('app-splashscreen'); // See public/index.html`
491
+ splashscreen === null || splashscreen === void 0 || splashscreen.classList.remove("d-none");
492
+ }
493
+ removeSplashScreenRequestor(obj) {
494
+ var origLen = this.SplashscreenRequestors.size;
495
+ this.SplashscreenRequestors.delete(obj);
496
+ if (origLen != this.SplashscreenRequestors.size) {
497
+ this.setState({
498
+ splashscreenRequestors: this.SplashscreenRequestors.size
656
499
  });
657
500
  }
501
+ if (this.SplashscreenRequestors.size == 0) {
502
+ var splashscreen = document.getElementById('app-splashscreen'); // See public/index.html
503
+ splashscreen === null || splashscreen === void 0 || splashscreen.classList.add("d-none");
504
+ }
505
+ }
506
+
507
+ // Alerts
508
+ /*
509
+ levels:
510
+ * danger
511
+ * warning
512
+ * info
513
+ * success
514
+ */
515
+ addAlert(level, message) {
516
+ var expire = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 5;
517
+ var shouldBeTranslated = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
518
+ var component = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
519
+ this.Store.dispatch({
520
+ type: _actions.ADD_ALERT,
521
+ level: level,
522
+ message: message,
523
+ expire: expire,
524
+ shouldBeTranslated: shouldBeTranslated,
525
+ component: component
526
+ });
527
+ }
658
528
 
529
+ /*
530
+ Alert from exception suppose to be used ONLY for exception cases.
531
+ By default it requires:
532
+ - exception - this is comming from the try{...}catch(exception){...} . It is important to pass the whole exception.
533
+ - message - this is the custom message written by developer based on the situation
534
+ Additional options are:
535
+ - expire - expiration of the aler (by default set to 30s)
536
+ - shouldBeTranslated - boolean for cases where is not possible to use useTranslation hook (by default false)
537
+ - component - option to pass additional component of the alert message e.g. button (by default null)
538
+ addAlertFromException will always use "danger" color as its background and the full exception will be printed into the console
539
+ */
540
+ addAlertFromException(exception, message) {
541
+ var _exception$response;
542
+ var expire = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 30;
543
+ var shouldBeTranslated = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
544
+ var component = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
545
+ console.error(exception); // Log the whole exception in the browser
546
+ var exceptionMessage = /*#__PURE__*/_react.default.createElement("span", null, message);
659
547
  /*
660
- Alert from exception suppose to be used ONLY for exception cases.
661
- By default it requires:
662
- - exception - this is comming from the try{...}catch(exception){...} . It is important to pass the whole exception.
663
- - message - this is the custom message written by developer based on the situation
664
- Additional options are:
665
- - expire - expiration of the aler (by default set to 30s)
666
- - shouldBeTranslated - boolean for cases where is not possible to use useTranslation hook (by default false)
667
- - component - option to pass additional component of the alert message e.g. button (by default null)
668
- addAlertFromException will always use "danger" color as its background and the full exception will be printed into the console
548
+ If the exception has an error_dict in the response data (error in the new format),
549
+ the ErrorHandler component is used to display the error,
550
+ along with the exception message in the form-text class.
669
551
  */
670
- }, {
671
- key: "addAlertFromException",
672
- value: function addAlertFromException(exception, message) {
673
- var _exception$response;
674
- var expire = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 30;
675
- var shouldBeTranslated = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
676
- var component = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
677
- console.error(exception); // Log the whole exception in the browser
678
- var exceptionMessage = /*#__PURE__*/_react["default"].createElement("span", null, message);
552
+ if (exception !== null && exception !== void 0 && (_exception$response = exception.response) !== null && _exception$response !== void 0 && (_exception$response = _exception$response.data) !== null && _exception$response !== void 0 && _exception$response.error_dict) {
553
+ exceptionMessage = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_asab_webui_components.ErrorHandler, {
554
+ error: exception.response.data
555
+ }), (exception === null || exception === void 0 ? void 0 : exception.message) && /*#__PURE__*/_react.default.createElement("div", {
556
+ className: "form-text"
557
+ }, exception.message));
558
+ } else {
559
+ var _exception$response2;
679
560
  /*
680
- If the exception has an error_dict in the response data (error in the new format),
681
- the ErrorHandler component is used to display the error,
682
- along with the exception message in the form-text class.
561
+ Capture the cases when service returns a message in the exception response data.
562
+ Add hoc messages are displayed in form-text class on the new line
683
563
  */
684
- if (exception !== null && exception !== void 0 && (_exception$response = exception.response) !== null && _exception$response !== void 0 && (_exception$response = _exception$response.data) !== null && _exception$response !== void 0 && _exception$response.error_dict) {
685
- exceptionMessage = /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(_asab_webui_components.ErrorHandler, {
686
- error: exception.response.data
687
- }), (exception === null || exception === void 0 ? void 0 : exception.message) && /*#__PURE__*/_react["default"].createElement("div", {
688
- className: "form-text"
689
- }, exception.message));
564
+ 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.message) {
565
+ exceptionMessage = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("h5", null, exceptionMessage), /*#__PURE__*/_react.default.createElement("div", {
566
+ className: "mt-2",
567
+ style: {
568
+ whiteSpace: 'pre-wrap'
569
+ }
570
+ }, exception.response.data.message));
690
571
  } else {
691
- var _exception$response2;
692
- /*
693
- Capture the cases when service returns a message in the exception response data.
694
- Add hoc messages are displayed in form-text class on the new line
695
- */
696
- 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.message) {
697
- exceptionMessage = /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("h5", null, exceptionMessage), /*#__PURE__*/_react["default"].createElement("div", {
698
- className: "mt-2",
699
- style: {
700
- whiteSpace: 'pre-wrap'
701
- }
702
- }, exception.response.data.message));
703
- } else {
704
- // Exception message is always present in the exception
705
- exceptionMessage = /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("h5", null, exceptionMessage), (exception === null || exception === void 0 ? void 0 : exception.message) && /*#__PURE__*/_react["default"].createElement("div", {
706
- className: "mt-2"
707
- }, exception.message));
708
- }
572
+ // Exception message is always present in the exception
573
+ exceptionMessage = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("h5", null, exceptionMessage), (exception === null || exception === void 0 ? void 0 : exception.message) && /*#__PURE__*/_react.default.createElement("div", {
574
+ className: "mt-2"
575
+ }, exception.message));
709
576
  }
710
- this.Store.dispatch({
711
- type: _actions.ADD_ALERT,
712
- level: "danger",
713
- message: exceptionMessage,
714
- expire: expire,
715
- shouldBeTranslated: shouldBeTranslated,
716
- component: component
717
- });
718
577
  }
719
- }, {
720
- key: "setAdvancedMode",
721
- value: function setAdvancedMode(enabled) {
722
- if (enabled === 0) {
723
- var state = this.Store.getState();
724
- enabled = !state.advmode.enabled;
725
- }
726
- this.Store.dispatch({
727
- type: _actions.SET_ADVANCED_MODE,
728
- enabled: enabled
729
- });
730
- if (enabled) {
731
- this.addAlert('warning', "ASABApplicationContainer|Advanced mode enabled", 1, true);
732
- } else {
733
- this.addAlert('success', "ASABApplicationContainer|Advanced mode disabled", 1, true);
734
- }
578
+ this.Store.dispatch({
579
+ type: _actions.ADD_ALERT,
580
+ level: "danger",
581
+ message: exceptionMessage,
582
+ expire: expire,
583
+ shouldBeTranslated: shouldBeTranslated,
584
+ component: component
585
+ });
586
+ }
587
+ setAdvancedMode(enabled) {
588
+ if (enabled === 0) {
589
+ var state = this.Store.getState();
590
+ enabled = !state.advmode.enabled;
591
+ }
592
+ this.Store.dispatch({
593
+ type: _actions.SET_ADVANCED_MODE,
594
+ enabled: enabled
595
+ });
596
+ if (enabled) {
597
+ this.addAlert('warning', "ASABApplicationContainer|Advanced mode enabled", 1, true);
598
+ } else {
599
+ this.addAlert('success', "ASABApplicationContainer|Advanced mode disabled", 1, true);
735
600
  }
601
+ }
736
602
 
737
- /*
738
- This method toggles the full-screen mode of the application container.
739
- It takes a parameter called "status" to indicate whether to turn the full-screen mode on or off.
740
- */
741
- }, {
742
- key: "setFullScreenMode",
743
- value: function setFullScreenMode(status) {
744
- var state = this.Store.getState();
745
- if (status === 'on' && state.fullscreenmode.status === 'on') {
746
- status = 'off';
747
- }
603
+ /*
604
+ This method toggles the full-screen mode of the application container.
605
+ It takes a parameter called "status" to indicate whether to turn the full-screen mode on or off.
606
+ */
607
+ setFullScreenMode(status) {
608
+ var state = this.Store.getState();
609
+ if (status === 'on' && state.fullscreenmode.status === 'on') {
610
+ status = 'off';
611
+ }
612
+ this.Store.dispatch({
613
+ type: _actions.SET_FULLSCREEN_MODE,
614
+ status: status
615
+ });
616
+ if (status === 'on') {
617
+ document.body.classList.add('fullscreen');
618
+ this.addAlert('info', 'ASABApplicationContainer|Fullscreen mode turned on. To turn it off, press CTRL + SHIFT + F.', 30, true);
619
+ } else {
620
+ document.body.classList.remove('fullscreen');
621
+ this.addAlert('info', 'ASABApplicationContainer|Fullscreen mode turned off', 30, true);
622
+ }
623
+ }
624
+ setFlag(name) {
625
+ (0, _react.useEffect)(() => {
748
626
  this.Store.dispatch({
749
- type: _actions.SET_FULLSCREEN_MODE,
750
- status: status
627
+ type: _actions.SET_FLAG,
628
+ flag: name
751
629
  });
752
- if (status === 'on') {
753
- document.body.classList.add('fullscreen');
754
- this.addAlert('info', 'ASABApplicationContainer|Fullscreen mode turned on. To turn it off, press CTRL + SHIFT + F.', 30, true);
755
- } else {
756
- document.body.classList.remove('fullscreen');
757
- this.addAlert('info', 'ASABApplicationContainer|Fullscreen mode turned off', 30, true);
758
- }
759
- }
760
- }, {
761
- key: "setFlag",
762
- value: function setFlag(name) {
763
- var _this2 = this;
764
- (0, _react.useEffect)(function () {
765
- _this2.Store.dispatch({
630
+ return () => {
631
+ this.Store.dispatch({
766
632
  type: _actions.SET_FLAG,
767
- flag: name
633
+ flag: undefined
768
634
  });
769
- return function () {
770
- _this2.Store.dispatch({
771
- type: _actions.SET_FLAG,
772
- flag: undefined
773
- });
774
- };
775
- }, [name]);
776
- }
777
- }, {
778
- key: "render",
779
- value: function render() {
780
- if (this.state.splashscreenRequestors > 0) return (
781
- /*#__PURE__*/
782
- // When splashscreenRequestors is requested, the application is not rendered.
783
- // This prevents race conditions during application init time.
784
- _react["default"].createElement(_asab_webui_components.PubSubProvider, {
785
- app: this
786
- }, /*#__PURE__*/_react["default"].createElement(_reactRedux.Provider, {
787
- store: this.Store
788
- }, /*#__PURE__*/_react["default"].createElement(_react.Suspense, {
789
- fallback: /*#__PURE__*/_react["default"].createElement("div", null)
790
- }, /*#__PURE__*/_react["default"].createElement(_Alerts["default"], {
791
- app: this
792
- }), /*#__PURE__*/_react["default"].createElement("main", {
793
- id: "app-main"
794
- }, /*#__PURE__*/_react["default"].createElement(_AccessDeniedCard["default"], {
795
- app: this
796
- })))))
797
- );
798
- return /*#__PURE__*/_react["default"].createElement(_asab_webui_components.PubSubProvider, {
635
+ };
636
+ }, [name]);
637
+ }
638
+ render() {
639
+ if (this.state.splashscreenRequestors > 0) return (
640
+ /*#__PURE__*/
641
+ // When splashscreenRequestors is requested, the application is not rendered.
642
+ // This prevents race conditions during application init time.
643
+ _react.default.createElement(_asab_webui_components.PubSubProvider, {
799
644
  app: this
800
- }, /*#__PURE__*/_react["default"].createElement(_reactRedux.Provider, {
645
+ }, /*#__PURE__*/_react.default.createElement(_reactRedux.Provider, {
801
646
  store: this.Store
802
- }, /*#__PURE__*/_react["default"].createElement(_react.Suspense, {
803
- fallback: /*#__PURE__*/_react["default"].createElement("div", null)
804
- }, /*#__PURE__*/_react["default"].createElement("div", {
805
- id: "app-networking-indicator",
806
- className: "progress-bar progress-bar-animated progress-bar-striped" + (this.state.networking == 0 ? " transparent" : "")
807
- }), /*#__PURE__*/_react["default"].createElement(_Alerts["default"], {
808
- app: this
809
- }), /*#__PURE__*/_react["default"].createElement(_NavbarBrand["default"], {
810
- app: this
811
- }), /*#__PURE__*/_react["default"].createElement(_Sidebar["default"], {
647
+ }, /*#__PURE__*/_react.default.createElement(_react.Suspense, {
648
+ fallback: /*#__PURE__*/_react.default.createElement("div", null)
649
+ }, /*#__PURE__*/_react.default.createElement(_Alerts.default, {
812
650
  app: this
813
- }), /*#__PURE__*/_react["default"].createElement(_ToastContainer["default"], {
814
- app: this
815
- }), /*#__PURE__*/_react["default"].createElement(_Header["default"], {
816
- app: this
817
- }), /*#__PURE__*/_react["default"].createElement("main", {
651
+ }), /*#__PURE__*/_react.default.createElement("main", {
818
652
  id: "app-main"
819
- }, /*#__PURE__*/_react["default"].createElement(_react.Suspense, {
820
- fallback: /*#__PURE__*/_react["default"].createElement(_SuspenseScreen["default"], {
821
- app: this
822
- }) /*The suspense that captures lazy loading of the federated apps*/
823
- }, /*#__PURE__*/_react["default"].createElement(_ApplicationRouter["default"], {
653
+ }, /*#__PURE__*/_react.default.createElement(_AccessDeniedCard.default, {
824
654
  app: this
825
- }))), /*#__PURE__*/_react["default"].createElement(_Sidepanel["default"], {
655
+ })))))
656
+ );
657
+ return /*#__PURE__*/_react.default.createElement(_asab_webui_components.PubSubProvider, {
658
+ app: this
659
+ }, /*#__PURE__*/_react.default.createElement(_reactRedux.Provider, {
660
+ store: this.Store
661
+ }, /*#__PURE__*/_react.default.createElement(_react.Suspense, {
662
+ fallback: /*#__PURE__*/_react.default.createElement("div", null)
663
+ }, /*#__PURE__*/_react.default.createElement("div", {
664
+ id: "app-networking-indicator",
665
+ className: "progress-bar progress-bar-animated progress-bar-striped" + (this.state.networking == 0 ? " transparent" : "")
666
+ }), /*#__PURE__*/_react.default.createElement(_Alerts.default, {
667
+ app: this
668
+ }), /*#__PURE__*/_react.default.createElement(_NavbarBrand.default, {
669
+ app: this
670
+ }), /*#__PURE__*/_react.default.createElement(_Sidebar.default, {
671
+ app: this
672
+ }), /*#__PURE__*/_react.default.createElement(_ToastContainer.default, {
673
+ app: this
674
+ }), /*#__PURE__*/_react.default.createElement(_Header.default, {
675
+ app: this
676
+ }), /*#__PURE__*/_react.default.createElement("main", {
677
+ id: "app-main"
678
+ }, /*#__PURE__*/_react.default.createElement(_react.Suspense, {
679
+ fallback: /*#__PURE__*/_react.default.createElement(_SuspenseScreen.default, {
826
680
  app: this
827
- }))));
828
- }
829
- }]);
830
- }(_react.Component);
831
- var _default = exports["default"] = Application;
681
+ }) /*The suspense that captures lazy loading of the federated apps*/
682
+ }, /*#__PURE__*/_react.default.createElement(_ApplicationRouter.default, {
683
+ app: this
684
+ }))), /*#__PURE__*/_react.default.createElement(_Sidepanel.default, {
685
+ app: this
686
+ }))));
687
+ }
688
+ }
689
+ var _default = exports.default = Application;