valtech-components 2.0.930 → 2.0.931

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.
@@ -2,5 +2,5 @@
2
2
  * Current version of valtech-components.
3
3
  * This is automatically updated during the publish process.
4
4
  */
5
- export const VERSION = '2.0.930';
6
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvdmVyc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDdXJyZW50IHZlcnNpb24gb2YgdmFsdGVjaC1jb21wb25lbnRzLlxuICogVGhpcyBpcyBhdXRvbWF0aWNhbGx5IHVwZGF0ZWQgZHVyaW5nIHRoZSBwdWJsaXNoIHByb2Nlc3MuXG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gJzIuMC45MzAnO1xuIl19
5
+ export const VERSION = '2.0.931';
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvdmVyc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDdXJyZW50IHZlcnNpb24gb2YgdmFsdGVjaC1jb21wb25lbnRzLlxuICogVGhpcyBpcyBhdXRvbWF0aWNhbGx5IHVwZGF0ZWQgZHVyaW5nIHRoZSBwdWJsaXNoIHByb2Nlc3MuXG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gJzIuMC45MzEnO1xuIl19
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, InjectionToken, makeEnvironmentProviders, APP_INITIALIZER, ErrorHandler, Injectable, DestroyRef, Inject, signal, computed, PLATFORM_ID, isDevMode, Optional, runInInjectionContext, effect, Pipe, TemplateRef, ViewContainerRef, input, Directive, EventEmitter, Component, Input, Output, ChangeDetectionStrategy, HostBinding, HostListener, ViewChild, ChangeDetectorRef, ContentChild, output, Injector, isSignal, ElementRef, ViewEncapsulation } from '@angular/core';
2
+ import { inject, InjectionToken, makeEnvironmentProviders, APP_INITIALIZER, ErrorHandler, Injectable, DestroyRef, Inject, signal, computed, PLATFORM_ID, isDevMode, Optional, runInInjectionContext, effect, Pipe, TemplateRef, ViewContainerRef, input, Directive, EventEmitter, Component, Input, Output, ChangeDetectionStrategy, HostBinding, HostListener, NgZone, ViewChild, ChangeDetectorRef, ContentChild, output, Injector, isSignal, ElementRef, ViewEncapsulation } from '@angular/core';
3
3
  import { BehaviorSubject, throwError, Subject, map, distinctUntilChanged, filter as filter$1, take as take$1, firstValueFrom, of, from, EMPTY, Observable, interval, debounceTime, switchMap as switchMap$1, catchError as catchError$1, takeUntil, isObservable, shareReplay, race, timer } from 'rxjs';
4
4
  import { catchError, switchMap, finalize, filter, take, map as map$1, tap, retry, timeout, debounceTime as debounceTime$1, takeUntil as takeUntil$1 } from 'rxjs/operators';
5
5
  import * as i1$3 from '@angular/common/http';
@@ -54,7 +54,7 @@ import 'prismjs/components/prism-json';
54
54
  * Current version of valtech-components.
55
55
  * This is automatically updated during the publish process.
56
56
  */
57
- const VERSION = '2.0.930';
57
+ const VERSION = '2.0.931';
58
58
 
59
59
  // Control de estado de refresco (singleton a nivel de módulo)
60
60
  let isRefreshing = false;
@@ -8081,6 +8081,13 @@ class AuthService {
8081
8081
  // cualquier listener Firestore (ej. el inbox de notificaciones) cuelga.
8082
8082
  // Fire-and-forget: NO debe demorar el resolve de initialize().
8083
8083
  void this.ensureFirebaseSessionOnBootstrap();
8084
+ // 5. Listener RBAC Firestore — re-establecer tras reload de página.
8085
+ // handleSuccessfulAuth lo configura en el login inicial, pero no sobrevive
8086
+ // recargas: initialize() restaura el state desde storage pero no el listener.
8087
+ // setupFirestoreRBACSync espera internamente a que Firebase Auth esté lista.
8088
+ if (claims?.uid) {
8089
+ this.setupFirestoreRBACSync(claims.uid);
8090
+ }
8084
8091
  }
8085
8092
  else if (storedState.refreshToken) {
8086
8093
  // 4. Token expirado pero hay refresh token.
@@ -8107,6 +8114,9 @@ class AuthService {
8107
8114
  if (expiredClaims.org) {
8108
8115
  this.stateService.updateActiveOrg(expiredClaims.org);
8109
8116
  }
8117
+ if (expiredClaims.uid) {
8118
+ this.setupFirestoreRBACSync(expiredClaims.uid);
8119
+ }
8110
8120
  }
8111
8121
  // Refresh en segundo plano — NO se hace await: initialize() resuelve ya.
8112
8122
  firstValueFrom(this.refreshAccessToken()).catch(() => {
@@ -8854,6 +8864,20 @@ class AuthService {
8854
8864
  if (!this.config?.enableFirestoreRBAC || !this.firestoreInstance)
8855
8865
  return;
8856
8866
  this.teardownFirestoreRBACSync();
8867
+ if (!this.firebaseService || this.firebaseService.firebaseAuthReady()) {
8868
+ // Firebase not used or already authenticated — attach listener now.
8869
+ this._attachFirestoreRBACListener(userId);
8870
+ }
8871
+ else {
8872
+ // Firebase Auth not ready yet. Firestore permission-denied errors terminate
8873
+ // onSnapshot permanently (no automatic retry when auth state changes).
8874
+ // Wait until the user is authenticated, then attach.
8875
+ this.firebaseService.firebaseAuthReady$
8876
+ .pipe(filter(ready => ready), take(1))
8877
+ .subscribe(() => this._attachFirestoreRBACListener(userId));
8878
+ }
8879
+ }
8880
+ _attachFirestoreRBACListener(userId) {
8857
8881
  const docRef = doc(this.firestoreInstance, 'users', userId);
8858
8882
  this.firestoreRBACUnsubscribe = onSnapshot(docRef, snap => {
8859
8883
  const rbac = snap.data()?.['rbac'];
@@ -14341,6 +14365,7 @@ class PatternComponent {
14341
14365
  }
14342
14366
  constructor() {
14343
14367
  this.sanitizer = inject(DomSanitizer);
14368
+ this.ngZone = inject(NgZone);
14344
14369
  this.cols = signal(12);
14345
14370
  this.rows = signal(4);
14346
14371
  this.seed = signal(this.randomSeed());
@@ -14391,6 +14416,8 @@ class PatternComponent {
14391
14416
  // con un seed nuevo. Visualmente: el patrón cambia de vez en cuando.
14392
14417
  // Si `tilesPerTick > 0` y < total tiles, hace staggered (reemplaza solo
14393
14418
  // N tiles en vez de toda la grid). Default tilesPerTick=0 → reseed total.
14419
+ // El setInterval corre FUERA de Zone.js para no disparar un CD completo
14420
+ // de toda la app en cada tick — solo val-pattern se actualiza vía señales.
14394
14421
  effect(onCleanup => {
14395
14422
  const isAnimated = this.animated();
14396
14423
  const interval = this.reshuffleInterval();
@@ -14400,14 +14427,16 @@ class PatternComponent {
14400
14427
  this.timer = undefined;
14401
14428
  if (!isAnimated)
14402
14429
  return;
14403
- this.timer = setInterval(() => {
14404
- if (perTick > 0) {
14405
- this.mutateRandomTiles(perTick);
14406
- }
14407
- else {
14408
- this.seed.set(this.randomSeed());
14409
- }
14410
- }, interval);
14430
+ this.ngZone.runOutsideAngular(() => {
14431
+ this.timer = setInterval(() => {
14432
+ if (perTick > 0) {
14433
+ this.mutateRandomTiles(perTick);
14434
+ }
14435
+ else {
14436
+ this.seed.set(this.randomSeed());
14437
+ }
14438
+ }, interval);
14439
+ });
14411
14440
  onCleanup(() => {
14412
14441
  if (this.timer) {
14413
14442
  clearInterval(this.timer);