@hmcts/ccd-case-ui-toolkit 7.3.53-exui-2906-activity-tracker-13 → 7.3.53-exui-2906-activity-tracker-15

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.
@@ -11,7 +11,7 @@ import { NG_VALUE_ACCESSOR, NG_VALIDATORS, FormArray, FormGroup, FormControl, Va
11
11
  import { BehaviorSubject, throwError, Subject, EMPTY, Observable, ReplaySubject, of, timer, skip, forkJoin, fromEvent, Subscription, combineLatest } from 'rxjs';
12
12
  import * as i1$2 from '@angular/common/http';
13
13
  import { HttpErrorResponse, HttpHeaders, HttpParams } from '@angular/common/http';
14
- import { distinctUntilChanged, catchError, filter, map, publish, refCount, delay, switchMap, finalize, timeout, mergeMap, retryWhen, tap, delayWhen, publishReplay, take, debounceTime, first, takeUntil } from 'rxjs/operators';
14
+ import { distinctUntilChanged, catchError, filter, map, publish, refCount, delay, switchMap, finalize, timeout, mergeMap, retryWhen, tap, delayWhen, publishReplay, take, debounceTime, first, takeUntil, skip as skip$1 } from 'rxjs/operators';
15
15
  import { connect } from 'socket.io-client';
16
16
  import { polling } from 'rx-polling-hmcts';
17
17
  import { Type, Exclude, Expose, plainToClassFromExist, plainToClass } from 'class-transformer';
@@ -2264,7 +2264,8 @@ class ActivityComponent {
2264
2264
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ActivityComponent, { className: "ActivityComponent", filePath: "lib/shared/components/activity/activity.component.ts", lineNumber: 12 }); })();
2265
2265
 
2266
2266
  const ACTIVITY_SOCKET_SHARED_STATE_KEY = '__ccdActivitySocketSharedState__';
2267
- const ACTIVITY_SOCKET_RECONNECT_DELAY_MS = 1000 * 2;
2267
+ const ACTIVITY_SOCKET_RECONNECT_DELAY_MIN_MS = 1000;
2268
+ const ACTIVITY_SOCKET_RECONNECT_DELAY_MAX_MS = 20000;
2268
2269
  class ActivitySocketService {
2269
2270
  sessionStorageService;
2270
2271
  activityService;
@@ -2544,16 +2545,32 @@ class ActivitySocketService {
2544
2545
  if (!state.allowWebSockets || socket !== state.socket || state.owners.size === 0 || state.reconnectTimer) {
2545
2546
  return;
2546
2547
  }
2548
+ console.warn('Activity socket connection lost, scheduling reconnect...');
2547
2549
  state.reconnectTimer = setTimeout(() => {
2548
2550
  state.reconnectTimer = undefined;
2549
2551
  if (socket === state.socket && state.owners.size > 0 && !ActivitySocketService.isSocketActive(socket)) {
2550
2552
  socket.connect();
2551
2553
  }
2552
- }, ACTIVITY_SOCKET_RECONNECT_DELAY_MS);
2554
+ }, ActivitySocketService.getReconnectDelayMs());
2553
2555
  if (ActivitySocketService.isSocketActive(socket)) {
2554
2556
  socket.disconnect();
2555
2557
  }
2556
2558
  }
2559
+ static getReconnectDelayMs() {
2560
+ const delayRange = ACTIVITY_SOCKET_RECONNECT_DELAY_MAX_MS - ACTIVITY_SOCKET_RECONNECT_DELAY_MIN_MS + 1;
2561
+ const randomDelay = ActivitySocketService.getCryptoRandomInt(delayRange) + ACTIVITY_SOCKET_RECONNECT_DELAY_MIN_MS;
2562
+ console.log(`Activity socket reconnect scheduled in ${randomDelay}ms`);
2563
+ return randomDelay;
2564
+ }
2565
+ // Returns an unbiased crypto-random integer from 0 inclusive to exclusiveMax exclusive.
2566
+ static getCryptoRandomInt(exclusiveMax) {
2567
+ const randomValue = new Uint32Array(1);
2568
+ const maxUnbiasedValue = Math.floor(0x100000000 / exclusiveMax) * exclusiveMax;
2569
+ do {
2570
+ globalThis.crypto.getRandomValues(randomValue);
2571
+ } while (randomValue[0] >= maxUnbiasedValue);
2572
+ return randomValue[0] % exclusiveMax;
2573
+ }
2557
2574
  // Treats connected, connecting, opening, and open sockets as active.
2558
2575
  static isSocketActive(socket) {
2559
2576
  if (!socket) {
@@ -41720,6 +41737,7 @@ class SearchResultComponent {
41720
41737
  selectedCases = [];
41721
41738
  lastWatchedCaseIds = [];
41722
41739
  lastWatchedCaseIdsKey = null;
41740
+ socketConnectSubscription;
41723
41741
  alphabeticalCompare = (left, right) => left.localeCompare(right);
41724
41742
  constructor(searchResultViewItemComparatorFactory, appConfig, activityService, caseReferencePipe, placeholderService, browserService, sessionStorageService, activitySocketService) {
41725
41743
  this.activityService = activityService;
@@ -41742,8 +41760,14 @@ class SearchResultComponent {
41742
41760
  }
41743
41761
  this.sessionStorageService.removeItem('eventUrl');
41744
41762
  this.selection.emit(this.selectedCases);
41763
+ if (!isSolicitorUser(this.sessionStorageService)) {
41764
+ this.socketConnectSubscription = this.activitySocketService.connected
41765
+ .pipe(skip$1(1), distinctUntilChanged(), filter(connected => connected))
41766
+ .subscribe(() => this.watchResults(true));
41767
+ }
41745
41768
  }
41746
41769
  ngOnDestroy() {
41770
+ this.socketConnectSubscription?.unsubscribe();
41747
41771
  if (this.activitySocketService.isEnabled && this.lastWatchedCaseIdsKey !== null) {
41748
41772
  this.activitySocketService.stopAllCase(this.lastWatchedCaseIds, true);
41749
41773
  }
@@ -42034,11 +42058,11 @@ class SearchResultComponent {
42034
42058
  }
42035
42059
  }
42036
42060
  }
42037
- watchResults() {
42061
+ watchResults(force = false) {
42038
42062
  if (this.activitySocketService.isEnabled) {
42039
42063
  const caseIds = this.resultView?.results?.map(value => value.case_id) ?? [];
42040
42064
  const watchKey = [...caseIds].sort(this.alphabeticalCompare).join(',');
42041
- if (watchKey === this.lastWatchedCaseIdsKey) {
42065
+ if (!force && watchKey === this.lastWatchedCaseIdsKey) {
42042
42066
  return;
42043
42067
  }
42044
42068
  this.lastWatchedCaseIdsKey = watchKey;
@@ -42097,7 +42121,7 @@ class SearchResultComponent {
42097
42121
  }], sortHandler: [{
42098
42122
  type: Output
42099
42123
  }] }); })();
42100
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SearchResultComponent, { className: "SearchResultComponent", filePath: "lib/shared/components/search-result/search-result.component.ts", lineNumber: 20 }); })();
42124
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SearchResultComponent, { className: "SearchResultComponent", filePath: "lib/shared/components/search-result/search-result.component.ts", lineNumber: 22 }); })();
42101
42125
 
42102
42126
  class SearchResultModule {
42103
42127
  static ɵfac = function SearchResultModule_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SearchResultModule)(); };