ngx-lift 1.7.2 → 1.7.3
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/esm2022/lib/pipes/array-join.pipe.mjs +3 -3
- package/esm2022/lib/pipes/byte-converter.pipe.mjs +3 -3
- package/esm2022/lib/pipes/is-https.pipe.mjs +3 -3
- package/esm2022/lib/pipes/mask.pipe.mjs +3 -3
- package/esm2022/lib/pipes/range.pipe.mjs +3 -3
- package/esm2022/lib/utils/idle-detection/idle-detection.config.mjs +7 -0
- package/esm2022/lib/utils/idle-detection/idle-detection.module.mjs +25 -0
- package/esm2022/lib/utils/idle-detection/idle-detection.service.mjs +187 -0
- package/esm2022/lib/utils/idle-detection/index.mjs +4 -0
- package/esm2022/lib/utils/index.mjs +2 -1
- package/fesm2022/ngx-lift.mjs +229 -18
- package/fesm2022/ngx-lift.mjs.map +1 -1
- package/lib/utils/idle-detection/idle-detection.config.d.ts +5 -0
- package/lib/utils/idle-detection/idle-detection.module.d.ts +13 -0
- package/lib/utils/idle-detection/idle-detection.service.d.ts +116 -0
- package/lib/utils/idle-detection/index.d.ts +3 -0
- package/lib/utils/index.d.ts +1 -0
- package/package.json +1 -1
package/fesm2022/ngx-lift.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { startWith, Subject, combineLatest, pipe, tap, map, catchError, of, Observable, timer, EMPTY, isObservable, merge, exhaustMap, from, share, switchMap, identity, distinctUntilChanged, switchAll, mergeAll, concatAll, exhaustAll } from 'rxjs';
|
|
1
|
+
import { startWith, Subject, combineLatest, pipe, tap, map, catchError, of, Observable, timer, EMPTY, isObservable, merge, exhaustMap, from, share, switchMap, fromEvent, throttleTime, identity, distinctUntilChanged, switchAll, mergeAll, concatAll, exhaustAll } from 'rxjs';
|
|
2
2
|
import { toObservable, toSignal } from '@angular/core/rxjs-interop';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { Pipe, inject, LOCALE_ID, assertInInjectionContext, isSignal, untracked, computed, DestroyRef, signal, effect } from '@angular/core';
|
|
4
|
+
import { Pipe, inject, LOCALE_ID, makeEnvironmentProviders, NgModule, Injectable, Optional, assertInInjectionContext, isSignal, untracked, computed, DestroyRef, signal, effect } from '@angular/core';
|
|
5
5
|
import { Validators, FormArray } from '@angular/forms';
|
|
6
6
|
import { ActivatedRoute } from '@angular/router';
|
|
7
7
|
|
|
@@ -295,10 +295,10 @@ class ArrayJoinPipe {
|
|
|
295
295
|
// For non-array cases or unexpected types, return the value as is
|
|
296
296
|
return value;
|
|
297
297
|
}
|
|
298
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
299
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.
|
|
298
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ArrayJoinPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
299
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.7", ngImport: i0, type: ArrayJoinPipe, isStandalone: true, name: "arrayJoin" }); }
|
|
300
300
|
}
|
|
301
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
301
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ArrayJoinPipe, decorators: [{
|
|
302
302
|
type: Pipe,
|
|
303
303
|
args: [{
|
|
304
304
|
name: 'arrayJoin',
|
|
@@ -356,10 +356,10 @@ class ByteConverterPipe {
|
|
|
356
356
|
formatNumber(value) {
|
|
357
357
|
return new Intl.NumberFormat(this.locale, { maximumFractionDigits: 2 }).format(value);
|
|
358
358
|
}
|
|
359
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
360
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.
|
|
359
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ByteConverterPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
360
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.7", ngImport: i0, type: ByteConverterPipe, isStandalone: true, name: "byteConverter" }); }
|
|
361
361
|
}
|
|
362
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
362
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ByteConverterPipe, decorators: [{
|
|
363
363
|
type: Pipe,
|
|
364
364
|
args: [{
|
|
365
365
|
name: 'byteConverter',
|
|
@@ -533,6 +533,217 @@ function composeValidators(control, validatorFn) {
|
|
|
533
533
|
return Validators.compose(validatorFns)?.(control) || null;
|
|
534
534
|
}
|
|
535
535
|
|
|
536
|
+
class IdleDetectionConfig {
|
|
537
|
+
}
|
|
538
|
+
function provideIdleDetectionConfig(config) {
|
|
539
|
+
return makeEnvironmentProviders([{ provide: IdleDetectionConfig, useValue: config }]);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Idle detection module.
|
|
544
|
+
* @deprecated use provideIdleDetectionConfig(config: IdleDetectionConfig) instead
|
|
545
|
+
*/
|
|
546
|
+
class IdleDetectionModule {
|
|
547
|
+
static forRoot(config) {
|
|
548
|
+
return {
|
|
549
|
+
ngModule: IdleDetectionModule,
|
|
550
|
+
providers: [provideIdleDetectionConfig(config)],
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: IdleDetectionModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
554
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.7", ngImport: i0, type: IdleDetectionModule }); }
|
|
555
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: IdleDetectionModule }); }
|
|
556
|
+
}
|
|
557
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: IdleDetectionModule, decorators: [{
|
|
558
|
+
type: NgModule,
|
|
559
|
+
args: [{
|
|
560
|
+
imports: [],
|
|
561
|
+
}]
|
|
562
|
+
}] });
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Service for detecting user idle time and implementing a countdown.
|
|
566
|
+
*/
|
|
567
|
+
class IdleDetectionService {
|
|
568
|
+
/**
|
|
569
|
+
* Constructs the IdleDetectionService.
|
|
570
|
+
* @param config - Optional configuration for idle and timeout durations.
|
|
571
|
+
*/
|
|
572
|
+
constructor(config) {
|
|
573
|
+
/**
|
|
574
|
+
* The list of interruption events that will end the idle detection.
|
|
575
|
+
*/
|
|
576
|
+
this.interruptionEvents = [
|
|
577
|
+
'click',
|
|
578
|
+
'keydown',
|
|
579
|
+
'keypress',
|
|
580
|
+
'mousemove',
|
|
581
|
+
'mousedown',
|
|
582
|
+
'scroll',
|
|
583
|
+
'wheel',
|
|
584
|
+
'touchmove',
|
|
585
|
+
'pointermove',
|
|
586
|
+
'resize',
|
|
587
|
+
];
|
|
588
|
+
/**
|
|
589
|
+
* The default idle duration in seconds (19 minutes).
|
|
590
|
+
*/
|
|
591
|
+
this.idleDuration = 19 * 60;
|
|
592
|
+
/**
|
|
593
|
+
* The default timeout duration in seconds (1 minute).
|
|
594
|
+
*/
|
|
595
|
+
this.timeoutDuration = 60;
|
|
596
|
+
/**
|
|
597
|
+
* Flag to indicate if countdown is in progress.
|
|
598
|
+
*/
|
|
599
|
+
this.isCountingDown = false;
|
|
600
|
+
/**
|
|
601
|
+
* The current countdown value.
|
|
602
|
+
*/
|
|
603
|
+
this.countdown = this.timeoutDuration;
|
|
604
|
+
/**
|
|
605
|
+
* Subject to emit when idle period ends.
|
|
606
|
+
*/
|
|
607
|
+
this.idleEndSubject = new Subject();
|
|
608
|
+
/**
|
|
609
|
+
* Subject to emit the countdown value.
|
|
610
|
+
*/
|
|
611
|
+
this.countdownSubject = new Subject();
|
|
612
|
+
/**
|
|
613
|
+
* Subject to emit when countdown ends.
|
|
614
|
+
*/
|
|
615
|
+
this.countdownEndSubject = new Subject();
|
|
616
|
+
if (config) {
|
|
617
|
+
this.setConfig(config);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Starts to watch for user inactivity.
|
|
622
|
+
*/
|
|
623
|
+
startWatching() {
|
|
624
|
+
this.setupInterruptionEvents();
|
|
625
|
+
this.startIdleTimer();
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Resets the idle timer when user activity is detected.
|
|
629
|
+
*/
|
|
630
|
+
resetTimer() {
|
|
631
|
+
this.startIdleTimer();
|
|
632
|
+
if (this.isCountingDown) {
|
|
633
|
+
this.stopCountdown();
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Sets up the interruption events that will end the idle detection.
|
|
638
|
+
* Listens to a set of events on the document (e.g. click, keydown, mousemove, etc.).
|
|
639
|
+
* When any of these events is triggered, the idle timer is reset.
|
|
640
|
+
* Uses `throttleTime` operator to only trigger the reset when the events are spaced
|
|
641
|
+
* out by at least 1000ms (1 second).
|
|
642
|
+
* @private
|
|
643
|
+
*/
|
|
644
|
+
setupInterruptionEvents() {
|
|
645
|
+
if (!this.interruptionSubscription) {
|
|
646
|
+
const throttledInterruptionEvents = this.interruptionEvents.map((eventName) => fromEvent(document, eventName).pipe(throttleTime(1000)));
|
|
647
|
+
this.interruptionSubscription = merge(...throttledInterruptionEvents).subscribe(() => this.resetTimer());
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Starts the idle timer.
|
|
652
|
+
* When the timer expires, it emits an event through onIdleEnd() and starts the countdown.
|
|
653
|
+
*/
|
|
654
|
+
startIdleTimer() {
|
|
655
|
+
clearTimeout(this.idleTimer);
|
|
656
|
+
this.idleTimer = window.setTimeout(() => {
|
|
657
|
+
// after idle period, user inactivity detected
|
|
658
|
+
this.idleEndSubject.next();
|
|
659
|
+
this.startCountdown();
|
|
660
|
+
}, this.idleDuration * 1000);
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Starts the countdown.
|
|
664
|
+
*/
|
|
665
|
+
startCountdown() {
|
|
666
|
+
this.isCountingDown = true;
|
|
667
|
+
this.countdownSubject.next(this.countdown);
|
|
668
|
+
this.countdownTimer = window.setInterval(() => {
|
|
669
|
+
this.countdown--;
|
|
670
|
+
this.countdownSubject.next(this.countdown);
|
|
671
|
+
if (this.countdown <= 0) {
|
|
672
|
+
this.stopCountdown();
|
|
673
|
+
this.countdownEndSubject.next();
|
|
674
|
+
}
|
|
675
|
+
}, 1000);
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Stops the countdown.
|
|
679
|
+
*/
|
|
680
|
+
stopCountdown() {
|
|
681
|
+
clearInterval(this.countdownTimer);
|
|
682
|
+
this.isCountingDown = false;
|
|
683
|
+
// reset countdown
|
|
684
|
+
this.countdown = this.timeoutDuration;
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Returns an observable that emits when the user has been idle for a long period.
|
|
688
|
+
* Developers can use this to perform actions like opening a dialog.
|
|
689
|
+
*
|
|
690
|
+
* user has been inactive for a long period (idleDuration), at this moment, idle detection phase ends, onIdleEnd event is emitted, and then enter countdown/timeout phase.
|
|
691
|
+
* During the countdown phase:
|
|
692
|
+
* - if user has any activity, countdown phase immediately ends and restart the idle detection phase.
|
|
693
|
+
* - else, countdownEnd event will be emitted when timeoutDuration is over.
|
|
694
|
+
* @returns {Observable<void>} - Observable for idle end event.
|
|
695
|
+
*/
|
|
696
|
+
onIdleEnd() {
|
|
697
|
+
return this.idleEndSubject.asObservable();
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Returns an observable that emits when the countdown ends.
|
|
701
|
+
* Usually means the user has been inactive for a very long time and should be logged out.
|
|
702
|
+
* @returns {Observable<void>} - Observable for countdown end event.
|
|
703
|
+
*/
|
|
704
|
+
onTimeoutEnd() {
|
|
705
|
+
return this.countdownEndSubject.asObservable();
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Returns an observable that emits the countdown value every second.
|
|
709
|
+
* @returns {Observable<number>} - Observable for countdown value.
|
|
710
|
+
*/
|
|
711
|
+
onCountDown() {
|
|
712
|
+
return this.countdownSubject.asObservable();
|
|
713
|
+
}
|
|
714
|
+
/**
|
|
715
|
+
* Clears all timers when the component is destroyed.
|
|
716
|
+
*/
|
|
717
|
+
clearTimers() {
|
|
718
|
+
clearTimeout(this.idleTimer);
|
|
719
|
+
clearInterval(this.countdownTimer);
|
|
720
|
+
this.interruptionSubscription?.unsubscribe();
|
|
721
|
+
this.interruptionSubscription = undefined;
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Sets the idle and timeout durations based on the provided configuration.
|
|
725
|
+
* @param config - Configuration object with idle and timeout durations.
|
|
726
|
+
*/
|
|
727
|
+
setConfig(config) {
|
|
728
|
+
if (config.idleDurationInSeconds) {
|
|
729
|
+
this.idleDuration = config.idleDurationInSeconds;
|
|
730
|
+
}
|
|
731
|
+
if (config.timeoutDurationInSeconds) {
|
|
732
|
+
this.countdown = this.timeoutDuration = config.timeoutDurationInSeconds;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: IdleDetectionService, deps: [{ token: IdleDetectionConfig, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
736
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: IdleDetectionService, providedIn: 'root' }); }
|
|
737
|
+
}
|
|
738
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: IdleDetectionService, decorators: [{
|
|
739
|
+
type: Injectable,
|
|
740
|
+
args: [{
|
|
741
|
+
providedIn: 'root',
|
|
742
|
+
}]
|
|
743
|
+
}], ctorParameters: () => [{ type: IdleDetectionConfig, decorators: [{
|
|
744
|
+
type: Optional
|
|
745
|
+
}] }] });
|
|
746
|
+
|
|
536
747
|
/**
|
|
537
748
|
* Check if a value is empty.
|
|
538
749
|
* @param {T | undefined | null} value - The value to check for emptiness.
|
|
@@ -676,10 +887,10 @@ class IsHttpsPipe {
|
|
|
676
887
|
transform(value) {
|
|
677
888
|
return isHttps(value);
|
|
678
889
|
}
|
|
679
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
680
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.
|
|
890
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: IsHttpsPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
891
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.7", ngImport: i0, type: IsHttpsPipe, isStandalone: true, name: "isHttps" }); }
|
|
681
892
|
}
|
|
682
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
893
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: IsHttpsPipe, decorators: [{
|
|
683
894
|
type: Pipe,
|
|
684
895
|
args: [{
|
|
685
896
|
name: 'isHttps',
|
|
@@ -710,10 +921,10 @@ class MaskPipe {
|
|
|
710
921
|
.map((char, i) => (i < unmaskedPrefixLength || i > value.length - unmaskedSuffixLength - 1 ? char : maskChar))
|
|
711
922
|
.join('');
|
|
712
923
|
}
|
|
713
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
714
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.
|
|
924
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: MaskPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
925
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.7", ngImport: i0, type: MaskPipe, isStandalone: true, name: "mask" }); }
|
|
715
926
|
}
|
|
716
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
927
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: MaskPipe, decorators: [{
|
|
717
928
|
type: Pipe,
|
|
718
929
|
args: [{
|
|
719
930
|
name: 'mask',
|
|
@@ -726,10 +937,10 @@ class RangePipe {
|
|
|
726
937
|
const input = value;
|
|
727
938
|
return range(...input);
|
|
728
939
|
}
|
|
729
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
730
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.
|
|
940
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: RangePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
941
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.7", ngImport: i0, type: RangePipe, isStandalone: true, name: "range" }); }
|
|
731
942
|
}
|
|
732
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
943
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: RangePipe, decorators: [{
|
|
733
944
|
type: Pipe,
|
|
734
945
|
args: [{
|
|
735
946
|
name: 'range',
|
|
@@ -1209,5 +1420,5 @@ function httpsValidator(control) {
|
|
|
1209
1420
|
* Generated bundle index. Do not edit.
|
|
1210
1421
|
*/
|
|
1211
1422
|
|
|
1212
|
-
export { ArrayJoinPipe, ByteConverterPipe, IsHttpsPipe, MaskPipe, RangePipe, UniqueValidator, combineFrom, combineLatestEager, computedAsync, createAsyncState, createTrigger, dateRangeValidator, differenceInDays, distinctOnChange, httpsValidator, ifAsyncValidator, ifValidator, injectParams, injectQueryParams, intersectionValidator, isEmpty, isEqual, isFQDN, isHttps, isIP, isURL, logger, mergeFrom, omitBy, pickBy, poll, range, startWithTap, switchMapWithAsyncState, urlValidator };
|
|
1423
|
+
export { ArrayJoinPipe, ByteConverterPipe, IdleDetectionConfig, IdleDetectionModule, IdleDetectionService, IsHttpsPipe, MaskPipe, RangePipe, UniqueValidator, combineFrom, combineLatestEager, computedAsync, createAsyncState, createTrigger, dateRangeValidator, differenceInDays, distinctOnChange, httpsValidator, ifAsyncValidator, ifValidator, injectParams, injectQueryParams, intersectionValidator, isEmpty, isEqual, isFQDN, isHttps, isIP, isURL, logger, mergeFrom, omitBy, pickBy, poll, provideIdleDetectionConfig, range, startWithTap, switchMapWithAsyncState, urlValidator };
|
|
1213
1424
|
//# sourceMappingURL=ngx-lift.mjs.map
|