asab_webui_shell 27.2.6 → 27.2.8

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.
@@ -75,10 +75,14 @@ class Application extends _react.Component {
75
75
  // This is important to preserve 64bit numbers from the server such as IP addresses, timestamps etc.
76
76
  this.JSONParseBigInt = new Set(props === null || props === void 0 ? void 0 : props.bigint);
77
77
  this._handleKeyUp = this._handleKeyUp.bind(this);
78
+ // Clear print-ready timeout handler
79
+ this._clearPrintReadyTimeout = this._clearPrintReadyTimeout.bind(this);
80
+ this._printReadyTimeout = null;
78
81
  this.state = {
79
82
  networking: 0,
80
83
  // If more than zero, some networking activity is happening
81
- splashscreenRequestors: 0
84
+ splashscreenRequestors: 0,
85
+ printReadyIndicators: 1 // Initial value is set to 1, because we start the application with Splashscreen. When the Splashscreen is removed, the value is extracted. If value is more than zero, some print-ready activity is happening
82
86
  };
83
87
 
84
88
  // Subscribe and unsubscribe handlers for connectivity detection
@@ -254,6 +258,7 @@ class Application extends _react.Component {
254
258
  if (!networkingIndicatorOff) {
255
259
  that.pushNetworkingIndicator();
256
260
  }
261
+ that.pushPrintReadyIndicator();
257
262
  // Remove the X-Networking-Indicator header before sending to service (its only for internal use)
258
263
  config === null || config === void 0 || (_config$headers2 = config.headers) === null || _config$headers2 === void 0 || delete _config$headers2['X-Networking-Indicator'];
259
264
  config.headers['X-App'] = "webui"; // Include X-App header in every axios API request
@@ -270,7 +275,7 @@ class Application extends _react.Component {
270
275
  if (!response.config._networkingIndicatorOff) {
271
276
  that.popNetworkingIndicator();
272
277
  }
273
-
278
+ that.popPrintReadyIndicator();
274
279
  /*
275
280
  Custom flag to control JSON parsing for specific requests.
276
281
  If 'skipJsonParsing' is set to true in the request config,
@@ -314,6 +319,7 @@ class Application extends _react.Component {
314
319
  if (!((_error$config = error.config) !== null && _error$config !== void 0 && _error$config._networkingIndicatorOff)) {
315
320
  that.popNetworkingIndicator();
316
321
  }
322
+ that.popPrintReadyIndicator();
317
323
  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'];
318
324
  // Check if the response content type is 'application/json' and data is a string
319
325
  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') {
@@ -396,7 +402,14 @@ class Application extends _react.Component {
396
402
  for (var interceptor of this.WebSocketInterceptors.keys()) {
397
403
  // Avoid pushing undefined interceptor values
398
404
  if (interceptor) {
399
- subprotocols.push(interceptor);
405
+ /*
406
+ Interceptor should be a function that returns the current subprotocol value
407
+ Otherwise use the value directly (for backward compatibility)
408
+ */
409
+ var interceptorValue = typeof interceptor === 'function' ? interceptor() : interceptor;
410
+ if (interceptorValue) {
411
+ subprotocols.push(interceptorValue);
412
+ }
400
413
  }
401
414
  }
402
415
 
@@ -416,6 +429,24 @@ class Application extends _react.Component {
416
429
  networking: prevState.networking - 1
417
430
  }));
418
431
  }
432
+
433
+ // Display and hide print-ready indication
434
+ pushPrintReadyIndicator() {
435
+ this.setState(prevState => ({
436
+ printReadyIndicators: prevState.printReadyIndicators + 1
437
+ }));
438
+ }
439
+ popPrintReadyIndicator() {
440
+ this.setState(prevState => {
441
+ var nextValue = prevState.printReadyIndicators - 1;
442
+ if (nextValue < 0) {
443
+ console.warn('printReadyIndicators would go negative, setting its value to 0. The value was:', nextValue);
444
+ }
445
+ return {
446
+ printReadyIndicators: Math.max(nextValue, 0)
447
+ };
448
+ });
449
+ }
419
450
  registerService(service) {
420
451
  if (service.Name in this.Services) {
421
452
  console.warn("Service ".concat(service.Name, " is already registered."));
@@ -448,12 +479,30 @@ class Application extends _react.Component {
448
479
 
449
480
  // Subscribe to Application.status! once PubSub is available
450
481
  this._initConnectivitySubscription();
451
-
452
482
  // Add print-landscape class to body if not present
453
483
  if (!document.body.classList.contains('print-landscape')) {
454
484
  document.body.classList.add('print-landscape');
455
485
  }
456
486
  }
487
+ componentDidUpdate(prevProps, prevState) {
488
+ if (prevState.printReadyIndicators === this.state.printReadyIndicators) {
489
+ return;
490
+ }
491
+
492
+ // Setting a print-ready attribute to the body of the application element
493
+ if (this.state.printReadyIndicators === 0) {
494
+ this._clearPrintReadyTimeout();
495
+ this._printReadyTimeout = setTimeout(() => {
496
+ if (this.state.printReadyIndicators === 0) {
497
+ document.body.setAttribute('print-ready', 'true');
498
+ this._printReadyTimeout = null;
499
+ }
500
+ }, 500); // Add 500ms delay to ensure that the print-ready attribute is set after the last print-ready indicator is popped
501
+ } else {
502
+ this._clearPrintReadyTimeout();
503
+ document.body.setAttribute('print-ready', 'false');
504
+ }
505
+ }
457
506
  componentWillUnmount() {
458
507
  document.removeEventListener("keyup", this._handleKeyUp, false);
459
508
 
@@ -462,11 +511,23 @@ class Application extends _react.Component {
462
511
  this._unsubscribeConnectivity();
463
512
  this._unsubscribeConnectivity = null;
464
513
  }
514
+ this._clearPrintReadyTimeout();
515
+ document.body.removeAttribute('print-ready');
516
+ }
517
+ _clearPrintReadyTimeout() {
518
+ if (this._printReadyTimeout !== null) {
519
+ clearTimeout(this._printReadyTimeout);
520
+ this._printReadyTimeout = null;
521
+ }
465
522
  }
466
523
 
467
524
  // Splash screen
468
525
 
469
526
  addSplashScreenRequestor(obj) {
527
+ /*
528
+ For print-ready, the initial value is set to 1, because we always start the application
529
+ with Splashscreen and therefore we dont need to increment the print-ready number here.
530
+ */
470
531
  var origLen = this.SplashscreenRequestors.size;
471
532
  this.SplashscreenRequestors.add(obj);
472
533
  if (origLen != this.SplashscreenRequestors.size) {
@@ -486,6 +547,8 @@ class Application extends _react.Component {
486
547
  if (this.SplashscreenRequestors.size == 0) {
487
548
  var splashscreen = document.getElementById('app-splashscreen'); // See public/index.html
488
549
  splashscreen === null || splashscreen === void 0 || splashscreen.classList.add("d-none");
550
+ // Decrement print-ready indicator value if no splash screen requestors are present
551
+ this.popPrintReadyIndicator();
489
552
  }
490
553
  }
491
554
 
@@ -195,7 +195,8 @@ class AuthModule extends _asab_webui_components.Module {
195
195
  return interceptor;
196
196
  }
197
197
  webSocketAuthInterceptor() {
198
- return "access_token_".concat(this.OAuthTokens['access_token']);
198
+ // Return a function to ensure that the token is always current and not static
199
+ return () => "access_token_".concat(this.OAuthTokens['access_token']);
199
200
  }
200
201
  simulateUserinfo(mock_userinfo) {
201
202
  var _this2 = this;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "asab_webui_shell",
3
- "version": "27.2.6",
3
+ "version": "27.2.8",
4
4
  "license": "BSD-3-Clause",
5
5
  "description": "TeskaLabs ASAB WebUI Shell Application",
6
6
  "contributors": [