@dsivd/prestations-ng 19.2.0-beta.5 → 19.2.0-beta.6
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
CHANGED
|
@@ -98,6 +98,9 @@ Please check the [UPGRADING_V19.md](UPGRADING_V19.md) guide for more information
|
|
|
98
98
|
|
|
99
99
|
### Fixed
|
|
100
100
|
|
|
101
|
+
- `providePrestationsNgCore()` registers again the HTTP interceptors lost with `FoehnPageModule` in 19.0.0: the
|
|
102
|
+
`foehn-transmit-waiting-modal` is displayed again during a long transmission, the warning before the expiration of
|
|
103
|
+
the session receives its date again, and a new version of the application deployed meanwhile is detected again.
|
|
101
104
|
- `foehn-select`, `foehn-radio`, `foehn-checkbox` and the autocompletes:
|
|
102
105
|
- the model is no longer set back to its previous value when the parent changes `elements` and `model`
|
|
103
106
|
at the same time
|
|
Binary file
|
|
@@ -5461,6 +5461,203 @@ class I18nForm {
|
|
|
5461
5461
|
referenceInterne = undefined;
|
|
5462
5462
|
}
|
|
5463
5463
|
|
|
5464
|
+
const APP_VERSION_HEADER = 'app-version';
|
|
5465
|
+
class AppInfoHeadersInterceptor {
|
|
5466
|
+
foehnPageService = inject(FoehnPageService);
|
|
5467
|
+
appVersion = undefined;
|
|
5468
|
+
errorListenerRegistered = false;
|
|
5469
|
+
constructor() {
|
|
5470
|
+
// Enregistrer une seule fois
|
|
5471
|
+
if (!this.errorListenerRegistered) {
|
|
5472
|
+
window.addEventListener('error', (event) => {
|
|
5473
|
+
if (event.message?.includes('ChunkLoadError') ||
|
|
5474
|
+
event.message?.includes('Loading chunk')) {
|
|
5475
|
+
this.foehnPageService.setAppVersionMismatch();
|
|
5476
|
+
}
|
|
5477
|
+
});
|
|
5478
|
+
this.errorListenerRegistered = true;
|
|
5479
|
+
}
|
|
5480
|
+
}
|
|
5481
|
+
intercept(request, next) {
|
|
5482
|
+
return next.handle(request).pipe(tap$1((httpEvent) => {
|
|
5483
|
+
if (httpEvent instanceof HttpResponse) {
|
|
5484
|
+
const appVersionInHeader = httpEvent.headers.get(APP_VERSION_HEADER);
|
|
5485
|
+
if (!this.appVersion?.length) {
|
|
5486
|
+
this.appVersion = appVersionInHeader ?? '';
|
|
5487
|
+
}
|
|
5488
|
+
else if (appVersionInHeader &&
|
|
5489
|
+
this.appVersion !== appVersionInHeader) {
|
|
5490
|
+
this.foehnPageService.setAppVersionMismatch();
|
|
5491
|
+
}
|
|
5492
|
+
}
|
|
5493
|
+
}));
|
|
5494
|
+
}
|
|
5495
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: AppInfoHeadersInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
5496
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: AppInfoHeadersInterceptor, providedIn: 'root' });
|
|
5497
|
+
}
|
|
5498
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: AppInfoHeadersInterceptor, decorators: [{
|
|
5499
|
+
type: Injectable,
|
|
5500
|
+
args: [{
|
|
5501
|
+
providedIn: 'root',
|
|
5502
|
+
}]
|
|
5503
|
+
}], ctorParameters: () => [] });
|
|
5504
|
+
const APP_INFO_HEADERS_INTERCEPTOR_PROVIDER = [
|
|
5505
|
+
{
|
|
5506
|
+
provide: HTTP_INTERCEPTORS,
|
|
5507
|
+
useExisting: AppInfoHeadersInterceptor,
|
|
5508
|
+
multi: true,
|
|
5509
|
+
},
|
|
5510
|
+
];
|
|
5511
|
+
|
|
5512
|
+
class CurrentSessionExpiration {
|
|
5513
|
+
expiration = undefined;
|
|
5514
|
+
type = undefined;
|
|
5515
|
+
}
|
|
5516
|
+
|
|
5517
|
+
class IntervalHelper {
|
|
5518
|
+
static accurateInterval(
|
|
5519
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
5520
|
+
callBack, intervalInMilliseconds,
|
|
5521
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
5522
|
+
errorCallBack) {
|
|
5523
|
+
let timeout = null;
|
|
5524
|
+
let nextAt = Date.now() + intervalInMilliseconds;
|
|
5525
|
+
const clear = () => {
|
|
5526
|
+
if (timeout !== null) {
|
|
5527
|
+
clearTimeout(timeout);
|
|
5528
|
+
}
|
|
5529
|
+
};
|
|
5530
|
+
const timerHandler = () => {
|
|
5531
|
+
nextAt += intervalInMilliseconds;
|
|
5532
|
+
// Avoid time drift by doing "nextAt - Date.now()"
|
|
5533
|
+
const calculatedTimeout = nextAt - Date.now();
|
|
5534
|
+
// Verify browser tab inactivity
|
|
5535
|
+
if (calculatedTimeout < 0) {
|
|
5536
|
+
if (errorCallBack) {
|
|
5537
|
+
clear();
|
|
5538
|
+
return errorCallBack();
|
|
5539
|
+
}
|
|
5540
|
+
}
|
|
5541
|
+
timeout = setTimeout(timerHandler, Math.max(0, nextAt - Date.now()));
|
|
5542
|
+
callBack();
|
|
5543
|
+
};
|
|
5544
|
+
// Avoid time drift by doing "nextAt - Date.now()"
|
|
5545
|
+
timeout = setTimeout(timerHandler, nextAt - Date.now());
|
|
5546
|
+
return { clear };
|
|
5547
|
+
}
|
|
5548
|
+
}
|
|
5549
|
+
|
|
5550
|
+
class DemandeExpirationService {
|
|
5551
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5552
|
+
interval;
|
|
5553
|
+
PULLING_IN_MILLISECONDS = 1000;
|
|
5554
|
+
_demandeExpirationDateTimeSubject = new BehaviorSubject(null);
|
|
5555
|
+
intervalSubject = new BehaviorSubject(undefined);
|
|
5556
|
+
shouldDisplayExpirationTimerMessage() {
|
|
5557
|
+
return combineLatest([
|
|
5558
|
+
this.getDemandeExpirationDateTime(),
|
|
5559
|
+
this.intervalSubject.asObservable(),
|
|
5560
|
+
]).pipe(map(([value]) => !dayjs().isBefore(value?.expiration)), tap((visible) => {
|
|
5561
|
+
if (visible) {
|
|
5562
|
+
this.clearPulling();
|
|
5563
|
+
}
|
|
5564
|
+
}),
|
|
5565
|
+
// Checked every second: only a change must refresh the views.
|
|
5566
|
+
distinctUntilChanged(), shareReplay(1));
|
|
5567
|
+
}
|
|
5568
|
+
setDemandeExpirationDateTime(expiration) {
|
|
5569
|
+
this._demandeExpirationDateTimeSubject.next(expiration);
|
|
5570
|
+
}
|
|
5571
|
+
getDemandeExpirationDateTime() {
|
|
5572
|
+
return this._demandeExpirationDateTimeSubject.asObservable().pipe(filter((value) => !!value?.expiration?.isValid()), tap((value) => {
|
|
5573
|
+
if (dayjs().isBefore(value.expiration)) {
|
|
5574
|
+
this.startPulling();
|
|
5575
|
+
}
|
|
5576
|
+
}), shareReplay(1));
|
|
5577
|
+
}
|
|
5578
|
+
startPulling() {
|
|
5579
|
+
this.clearPulling();
|
|
5580
|
+
this.interval = IntervalHelper.accurateInterval(() => {
|
|
5581
|
+
this.intervalSubject.next();
|
|
5582
|
+
}, this.PULLING_IN_MILLISECONDS, () => {
|
|
5583
|
+
this.startPulling();
|
|
5584
|
+
});
|
|
5585
|
+
}
|
|
5586
|
+
clearPulling() {
|
|
5587
|
+
this.interval?.clear();
|
|
5588
|
+
}
|
|
5589
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DemandeExpirationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
5590
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DemandeExpirationService, providedIn: 'root' });
|
|
5591
|
+
}
|
|
5592
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DemandeExpirationService, decorators: [{
|
|
5593
|
+
type: Injectable,
|
|
5594
|
+
args: [{
|
|
5595
|
+
providedIn: 'root',
|
|
5596
|
+
}]
|
|
5597
|
+
}] });
|
|
5598
|
+
|
|
5599
|
+
const EXPIRATION_HEADER = 'Sessions-Expirations';
|
|
5600
|
+
class DemandeExpirationInterceptor {
|
|
5601
|
+
demandeExpirationService = inject(DemandeExpirationService);
|
|
5602
|
+
intercept(request, next) {
|
|
5603
|
+
return next.handle(request).pipe(tap$1((httpEvent) => {
|
|
5604
|
+
if (httpEvent.type === HttpEventType.Sent) {
|
|
5605
|
+
return;
|
|
5606
|
+
}
|
|
5607
|
+
if (httpEvent instanceof HttpResponse) {
|
|
5608
|
+
if (httpEvent.headers.has(EXPIRATION_HEADER)) {
|
|
5609
|
+
const expirationHeader = httpEvent.headers.get(EXPIRATION_HEADER);
|
|
5610
|
+
if (expirationHeader) {
|
|
5611
|
+
this.manageDemandeExpirationHeader(expirationHeader, httpEvent.body);
|
|
5612
|
+
}
|
|
5613
|
+
}
|
|
5614
|
+
}
|
|
5615
|
+
}));
|
|
5616
|
+
}
|
|
5617
|
+
manageDemandeExpirationHeader(expirationByDemande, responseBody) {
|
|
5618
|
+
const expirationByDemandeMap = this.getExpirationByDemandeMap(expirationByDemande);
|
|
5619
|
+
const expiration = new CurrentSessionExpiration();
|
|
5620
|
+
const reference = responseBody?.meta?.reference || '';
|
|
5621
|
+
const dateTimeForReference = expirationByDemandeMap.get(reference);
|
|
5622
|
+
const dateTimeForIam = expirationByDemandeMap.get('IAM');
|
|
5623
|
+
if (dateTimeForReference) {
|
|
5624
|
+
expiration.type = 'SESSION-TOKEN';
|
|
5625
|
+
expiration.expiration = dayjs(dateTimeForReference);
|
|
5626
|
+
}
|
|
5627
|
+
else if (dateTimeForIam) {
|
|
5628
|
+
expiration.type = 'IAM';
|
|
5629
|
+
expiration.expiration = dayjs(dateTimeForIam);
|
|
5630
|
+
}
|
|
5631
|
+
if (expiration.expiration?.isValid()) {
|
|
5632
|
+
this.demandeExpirationService.setDemandeExpirationDateTime(expiration);
|
|
5633
|
+
}
|
|
5634
|
+
}
|
|
5635
|
+
getExpirationByDemandeMap(expirationByDemande) {
|
|
5636
|
+
const myMap = new Map();
|
|
5637
|
+
const expirationByDemandesAsArray = expirationByDemande.split(';');
|
|
5638
|
+
expirationByDemandesAsArray.forEach((value) => {
|
|
5639
|
+
const valueAsArray = value.split(',');
|
|
5640
|
+
myMap.set(valueAsArray[0], new Date(valueAsArray[1]));
|
|
5641
|
+
});
|
|
5642
|
+
return myMap;
|
|
5643
|
+
}
|
|
5644
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DemandeExpirationInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
5645
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DemandeExpirationInterceptor, providedIn: 'root' });
|
|
5646
|
+
}
|
|
5647
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DemandeExpirationInterceptor, decorators: [{
|
|
5648
|
+
type: Injectable,
|
|
5649
|
+
args: [{
|
|
5650
|
+
providedIn: 'root',
|
|
5651
|
+
}]
|
|
5652
|
+
}] });
|
|
5653
|
+
const DEMANDE_EXPIRATION_INTERCEPTOR_PROVIDER = [
|
|
5654
|
+
{
|
|
5655
|
+
provide: HTTP_INTERCEPTORS,
|
|
5656
|
+
useExisting: DemandeExpirationInterceptor,
|
|
5657
|
+
multi: true,
|
|
5658
|
+
},
|
|
5659
|
+
];
|
|
5660
|
+
|
|
5464
5661
|
const OIDC_ENABLED = new InjectionToken('enable.oidc.interceptor', {
|
|
5465
5662
|
factory: () => false,
|
|
5466
5663
|
});
|
|
@@ -5531,6 +5728,11 @@ function providePrestationsNgCore() {
|
|
|
5531
5728
|
useExisting: IamExpiredInterceptorService,
|
|
5532
5729
|
multi: true,
|
|
5533
5730
|
},
|
|
5731
|
+
// Formerly provided by FoehnPageModule: the version of the application changed during a deployment,
|
|
5732
|
+
// the expiration of the session and the modal displayed during the transmission
|
|
5733
|
+
APP_INFO_HEADERS_INTERCEPTOR_PROVIDER,
|
|
5734
|
+
DEMANDE_EXPIRATION_INTERCEPTOR_PROVIDER,
|
|
5735
|
+
DEMANDE_TRANSMIT_INTERCEPTOR_PROVIDER,
|
|
5534
5736
|
{
|
|
5535
5737
|
provide: ErrorHandler,
|
|
5536
5738
|
useClass: ChunkLoadErrorHandler,
|
|
@@ -7456,88 +7658,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
|
|
|
7456
7658
|
args: [{ selector: 'foehn-app-version-mis-match-modal', imports: [FoehnModalComponent, AsyncPipe, SdkDictionaryPipe], template: "<foehn-modal\n [id]=\"'foehn-app-version-mismatch-modal'\"\n [modalHeaderText]=\"\n 'foehn-app-version-mismatch-modal.title' | fromDictionary\n \"\n modalSize=\"modal-md\"\n [isModalVisible]=\"(isModalVisible | async) ?? false\"\n [closeable]=\"false\"\n>\n <div\n id=\"foehn-app-version-mismatch-modal-body\"\n [innerHTML]=\"\n 'foehn-app-version-mismatch-modal.content' | fromDictionary\n \"\n ></div>\n\n <div modal-footer class=\"w-100\">\n <div class=\"d-flex\">\n <button\n id=\"saveAndReloadBtn\"\n type=\"button\"\n class=\"btn btn-primary ms-auto\"\n [innerHTML]=\"\n (hasDemandeInProgress\n ? 'foehn-app-version-mismatch-modal.btn.save-and-reload'\n : 'foehn-app-version-mismatch-modal.btn.reload'\n ) | fromDictionary\n \"\n (click)=\"saveAndReload()\"\n ></button>\n </div>\n </div>\n</foehn-modal>\n", styles: [":host ::ng-deep .modal{z-index:10000}\n"] }]
|
|
7457
7659
|
}], ctorParameters: () => [] });
|
|
7458
7660
|
|
|
7459
|
-
class IntervalHelper {
|
|
7460
|
-
static accurateInterval(
|
|
7461
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
7462
|
-
callBack, intervalInMilliseconds,
|
|
7463
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
7464
|
-
errorCallBack) {
|
|
7465
|
-
let timeout = null;
|
|
7466
|
-
let nextAt = Date.now() + intervalInMilliseconds;
|
|
7467
|
-
const clear = () => {
|
|
7468
|
-
if (timeout !== null) {
|
|
7469
|
-
clearTimeout(timeout);
|
|
7470
|
-
}
|
|
7471
|
-
};
|
|
7472
|
-
const timerHandler = () => {
|
|
7473
|
-
nextAt += intervalInMilliseconds;
|
|
7474
|
-
// Avoid time drift by doing "nextAt - Date.now()"
|
|
7475
|
-
const calculatedTimeout = nextAt - Date.now();
|
|
7476
|
-
// Verify browser tab inactivity
|
|
7477
|
-
if (calculatedTimeout < 0) {
|
|
7478
|
-
if (errorCallBack) {
|
|
7479
|
-
clear();
|
|
7480
|
-
return errorCallBack();
|
|
7481
|
-
}
|
|
7482
|
-
}
|
|
7483
|
-
timeout = setTimeout(timerHandler, Math.max(0, nextAt - Date.now()));
|
|
7484
|
-
callBack();
|
|
7485
|
-
};
|
|
7486
|
-
// Avoid time drift by doing "nextAt - Date.now()"
|
|
7487
|
-
timeout = setTimeout(timerHandler, nextAt - Date.now());
|
|
7488
|
-
return { clear };
|
|
7489
|
-
}
|
|
7490
|
-
}
|
|
7491
|
-
|
|
7492
|
-
class DemandeExpirationService {
|
|
7493
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7494
|
-
interval;
|
|
7495
|
-
PULLING_IN_MILLISECONDS = 1000;
|
|
7496
|
-
_demandeExpirationDateTimeSubject = new BehaviorSubject(null);
|
|
7497
|
-
intervalSubject = new BehaviorSubject(undefined);
|
|
7498
|
-
shouldDisplayExpirationTimerMessage() {
|
|
7499
|
-
return combineLatest([
|
|
7500
|
-
this.getDemandeExpirationDateTime(),
|
|
7501
|
-
this.intervalSubject.asObservable(),
|
|
7502
|
-
]).pipe(map(([value]) => !dayjs().isBefore(value?.expiration)), tap((visible) => {
|
|
7503
|
-
if (visible) {
|
|
7504
|
-
this.clearPulling();
|
|
7505
|
-
}
|
|
7506
|
-
}),
|
|
7507
|
-
// Checked every second: only a change must refresh the views.
|
|
7508
|
-
distinctUntilChanged(), shareReplay(1));
|
|
7509
|
-
}
|
|
7510
|
-
setDemandeExpirationDateTime(expiration) {
|
|
7511
|
-
this._demandeExpirationDateTimeSubject.next(expiration);
|
|
7512
|
-
}
|
|
7513
|
-
getDemandeExpirationDateTime() {
|
|
7514
|
-
return this._demandeExpirationDateTimeSubject.asObservable().pipe(filter((value) => !!value?.expiration?.isValid()), tap((value) => {
|
|
7515
|
-
if (dayjs().isBefore(value.expiration)) {
|
|
7516
|
-
this.startPulling();
|
|
7517
|
-
}
|
|
7518
|
-
}), shareReplay(1));
|
|
7519
|
-
}
|
|
7520
|
-
startPulling() {
|
|
7521
|
-
this.clearPulling();
|
|
7522
|
-
this.interval = IntervalHelper.accurateInterval(() => {
|
|
7523
|
-
this.intervalSubject.next();
|
|
7524
|
-
}, this.PULLING_IN_MILLISECONDS, () => {
|
|
7525
|
-
this.startPulling();
|
|
7526
|
-
});
|
|
7527
|
-
}
|
|
7528
|
-
clearPulling() {
|
|
7529
|
-
this.interval?.clear();
|
|
7530
|
-
}
|
|
7531
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DemandeExpirationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
7532
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DemandeExpirationService, providedIn: 'root' });
|
|
7533
|
-
}
|
|
7534
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DemandeExpirationService, decorators: [{
|
|
7535
|
-
type: Injectable,
|
|
7536
|
-
args: [{
|
|
7537
|
-
providedIn: 'root',
|
|
7538
|
-
}]
|
|
7539
|
-
}] });
|
|
7540
|
-
|
|
7541
7661
|
class FoehnPageExpirationTimerComponent {
|
|
7542
7662
|
isVisible;
|
|
7543
7663
|
countDownTimeToDisplay;
|