valtech-components 4.0.990 → 4.0.992
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/components/organisms/survey-builder/survey-builder.component.mjs +12 -4
- package/esm2022/lib/components/organisms/survey-builder/types.mjs +1 -1
- package/esm2022/lib/services/errors/error-logging.interceptor.mjs +30 -5
- package/esm2022/lib/services/i18n/i18n.service.mjs +17 -4
- package/esm2022/lib/version.mjs +2 -2
- package/fesm2022/valtech-components.mjs +57 -11
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/atoms/rights-footer/rights-footer.component.d.ts +2 -2
- package/lib/components/molecules/cta-card/cta-card.component.d.ts +1 -1
- package/lib/components/molecules/features-list/features-list.component.d.ts +1 -1
- package/lib/components/molecules/load-more/load-more.component.d.ts +1 -1
- package/lib/components/molecules/metric-card/metric-card.component.d.ts +1 -1
- package/lib/components/molecules/operation-reference/operation-reference.component.d.ts +1 -1
- package/lib/components/organisms/account-view/account-view.component.d.ts +1 -1
- package/lib/components/organisms/article/article.component.d.ts +5 -5
- package/lib/components/organisms/auth-cta/auth-cta.component.d.ts +1 -1
- package/lib/components/organisms/notification-preferences-view/notification-preferences-view.component.d.ts +1 -1
- package/lib/components/organisms/organization-view/organization-view.component.d.ts +1 -1
- package/lib/components/organisms/survey-builder/survey-builder.component.d.ts +1 -0
- package/lib/components/organisms/survey-builder/types.d.ts +10 -0
- package/lib/services/errors/error-logging.interceptor.d.ts +9 -1
- package/lib/services/i18n/i18n.service.d.ts +14 -1
- package/lib/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { InjectionToken, makeEnvironmentProviders, inject, APP_INITIALIZER, ErrorHandler, Injectable, DestroyRef, Inject, signal, computed, PLATFORM_ID, isDevMode, Optional, runInInjectionContext, effect, Pipe, Component, Input, ChangeDetectionStrategy, input, output, Injector, TemplateRef, ViewContainerRef, Directive, ElementRef, Renderer2, HostListener, EventEmitter, Output, HostBinding, SecurityContext, NgZone, ViewChild, ChangeDetectorRef, ContentChild, model, ViewEncapsulation, untracked, ViewChildren, viewChild, isSignal } from '@angular/core';
|
|
3
|
-
import { BehaviorSubject, throwError, Subject, map, distinctUntilChanged, filter as filter$1, take as take$1, firstValueFrom, timeout as timeout$1, catchError as catchError$1, of, from, EMPTY, Observable, interval, defer,
|
|
4
|
-
import { catchError, switchMap, finalize, filter, take, timeout, map as map$1, tap, shareReplay, distinctUntilChanged as distinctUntilChanged$1,
|
|
3
|
+
import { BehaviorSubject, throwError, timer, Subject, map, distinctUntilChanged, filter as filter$1, take as take$1, firstValueFrom, timeout as timeout$1, catchError as catchError$1, of, from, EMPTY, Observable, interval, defer, merge, concat, debounceTime, switchMap as switchMap$1, takeUntil, isObservable, forkJoin, race, shareReplay as shareReplay$1, tap as tap$1 } from 'rxjs';
|
|
4
|
+
import { catchError, switchMap, finalize, filter, take, timeout, retry, map as map$1, tap, shareReplay, distinctUntilChanged as distinctUntilChanged$1, debounceTime as debounceTime$1, takeUntil as takeUntil$1 } from 'rxjs/operators';
|
|
5
5
|
import * as i1$3 from '@angular/common/http';
|
|
6
6
|
import { provideHttpClient, withInterceptors, HttpContextToken, HttpClient, HttpErrorResponse, HttpContext, HttpParams } from '@angular/common/http';
|
|
7
7
|
import * as i1$1 from '@angular/fire/firestore';
|
|
@@ -70,7 +70,7 @@ import fixWebmDuration from 'fix-webm-duration';
|
|
|
70
70
|
* Current version of valtech-components.
|
|
71
71
|
* This is automatically updated during the publish process.
|
|
72
72
|
*/
|
|
73
|
-
const VERSION = '4.0.
|
|
73
|
+
const VERSION = '4.0.992';
|
|
74
74
|
|
|
75
75
|
function evaluateValtechAccess(rule, context, features = {}, visitedFeatures = new Set()) {
|
|
76
76
|
if (rule == null)
|
|
@@ -1500,6 +1500,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
1500
1500
|
args: [PLATFORM_ID]
|
|
1501
1501
|
}] }] });
|
|
1502
1502
|
|
|
1503
|
+
/**
|
|
1504
|
+
* Códigos de status que ameritan reintento — cold-start / infra tibia, no un
|
|
1505
|
+
* error de negocio. Nunca 4xx: eso es la app pidiendo algo mal, reintentar no
|
|
1506
|
+
* lo arregla.
|
|
1507
|
+
*/
|
|
1508
|
+
const RETRYABLE_STATUSES = new Set([502, 503, 504]);
|
|
1509
|
+
/** Backoff corto entre reintentos — no queremos que la UI perciba una espera larga. */
|
|
1510
|
+
const RETRY_DELAY_MS = 400;
|
|
1503
1511
|
/**
|
|
1504
1512
|
* Marca un request cuyo 404 es un ESTADO ESPERADO del dominio, no un error —
|
|
1505
1513
|
* ej. `GET /v1/game-profile/me` cuando el usuario todavía no creó su perfil
|
|
@@ -1517,7 +1525,15 @@ const EXPECTED_NOT_FOUND = new HttpContextToken(() => false);
|
|
|
1517
1525
|
* Interceptor HTTP de observabilidad (Capa 1 del estándar de manejo de errores).
|
|
1518
1526
|
*
|
|
1519
1527
|
* Para CADA respuesta HTTP con error:
|
|
1520
|
-
*
|
|
1528
|
+
* 0. Si es un GET (idempotente) que falló con 502/503/504, reintenta hasta 2
|
|
1529
|
+
* veces con un backoff corto (400ms/800ms) ANTES de pasar al resto del
|
|
1530
|
+
* pipeline — el caso típico es un cold-start de Lambda en dev: 3-4
|
|
1531
|
+
* requests en paralelo al bootstrap (auth/profile + runs + org/{id})
|
|
1532
|
+
* pegan contra lambdas frías al mismo tiempo, todas 504, y ~2s después ya
|
|
1533
|
+
* están tibias y funcionan. Detectado en Merotz dev 2026-08-17. Nunca
|
|
1534
|
+
* reintenta POST/PUT/DELETE/PATCH (no son idempotentes) ni 4xx (error de
|
|
1535
|
+
* negocio, reintentar no lo arregla).
|
|
1536
|
+
* 1. Si sigue fallando tras los reintentos: normaliza el error con `interpretError`.
|
|
1521
1537
|
* 2. Loguea un evento estructurado a consola con el prefijo `[HTTP]`.
|
|
1522
1538
|
* 3. Reporta el error a Firebase Analytics (`source: 'http'`), si hay analytics.
|
|
1523
1539
|
*
|
|
@@ -1541,7 +1557,16 @@ const errorLoggingInterceptor = (request, next) => {
|
|
|
1541
1557
|
// `AnalyticsService` puede no estar provisto (apps sin Firebase). El inject
|
|
1542
1558
|
// funcional con `optional: true` devuelve `null` en ese caso.
|
|
1543
1559
|
const analytics = inject(AnalyticsService, { optional: true });
|
|
1544
|
-
return next(request).pipe(
|
|
1560
|
+
return next(request).pipe(retry({
|
|
1561
|
+
count: 2,
|
|
1562
|
+
delay: (error, retryCount) => {
|
|
1563
|
+
const status = error?.status;
|
|
1564
|
+
if (request.method !== 'GET' || !RETRYABLE_STATUSES.has(status)) {
|
|
1565
|
+
return throwError(() => error);
|
|
1566
|
+
}
|
|
1567
|
+
return timer(RETRY_DELAY_MS * retryCount);
|
|
1568
|
+
},
|
|
1569
|
+
}), catchError((error) => {
|
|
1545
1570
|
const interpreted = interpretError(error);
|
|
1546
1571
|
const status = interpreted.status ?? error?.status;
|
|
1547
1572
|
// 401 → ruido del refresh de auth. Log informativo, sin Analytics.
|
|
@@ -1933,7 +1958,20 @@ class I18nService {
|
|
|
1933
1958
|
return namespace in this._content();
|
|
1934
1959
|
}
|
|
1935
1960
|
/**
|
|
1936
|
-
* Carga idioma guardado en localStorage o
|
|
1961
|
+
* Carga el idioma guardado en localStorage, o adivina desde el navegador.
|
|
1962
|
+
*
|
|
1963
|
+
* La detección de acá es PROVISIONAL y NO se persiste, a propósito. El
|
|
1964
|
+
* constructor corre antes que el APP_INITIALIZER de `provideValtechI18n`,
|
|
1965
|
+
* que es quien conoce la config real de la app. Cuando esto persistía el
|
|
1966
|
+
* idioma detectado, el initializer leía esa misma clave un instante después,
|
|
1967
|
+
* la tomaba por preferencia guardada del usuario y entraba por la rama
|
|
1968
|
+
* `stored` — así que `detectBrowserLanguage: false` no tenía efecto en
|
|
1969
|
+
* ninguna app del factory. Escribir acá fabricaba una preferencia que el
|
|
1970
|
+
* usuario nunca expresó.
|
|
1971
|
+
*
|
|
1972
|
+
* Persistir es responsabilidad de `setLanguage()`, que se llama cuando la
|
|
1973
|
+
* elección sí es del usuario (o cuando el initializer ya decidió con la
|
|
1974
|
+
* config a la vista).
|
|
1937
1975
|
*/
|
|
1938
1976
|
loadStoredLanguage() {
|
|
1939
1977
|
// SSR: sin localStorage/navigator. Mantenemos el default; el browser
|
|
@@ -1946,11 +1984,11 @@ class I18nService {
|
|
|
1946
1984
|
this._lang.set(stored);
|
|
1947
1985
|
return;
|
|
1948
1986
|
}
|
|
1949
|
-
//
|
|
1987
|
+
// Adivinanza provisional mientras el initializer no haya corrido. Sin
|
|
1988
|
+
// persistir: ver el comentario del método.
|
|
1950
1989
|
const browserLang = navigator.language.split('-')[0];
|
|
1951
1990
|
if (this.isValidLanguage(browserLang)) {
|
|
1952
1991
|
this._lang.set(browserLang);
|
|
1953
|
-
localStorage.setItem(LANG_STORAGE_KEY$1, browserLang);
|
|
1954
1992
|
}
|
|
1955
1993
|
}
|
|
1956
1994
|
/**
|
|
@@ -40767,13 +40805,16 @@ class SurveyBuilderComponent {
|
|
|
40767
40805
|
}
|
|
40768
40806
|
}
|
|
40769
40807
|
async ngOnInit() {
|
|
40808
|
+
// Sembrado directo: la app ya tenía la encuesta, no hace falta leerla.
|
|
40809
|
+
if (this.props.initial) {
|
|
40810
|
+
this.hydrate(this.props.initial.label, this.props.initial.subtitle, this.props.initial.questions);
|
|
40811
|
+
return;
|
|
40812
|
+
}
|
|
40770
40813
|
if (!this.props.typeId)
|
|
40771
40814
|
return;
|
|
40772
40815
|
try {
|
|
40773
40816
|
const cfg = await firstValueFrom(this.requests.getRequestType(this.props.typeId));
|
|
40774
|
-
this.
|
|
40775
|
-
this.subtitleControl.setValue(cfg.subtitle ?? '');
|
|
40776
|
-
this.questions.set([...cfg.fieldSchema].sort((a, b) => a.order - b.order).map(f => this.rowFromField(f)));
|
|
40817
|
+
this.hydrate(cfg.label, cfg.subtitle ?? '', cfg.fieldSchema);
|
|
40777
40818
|
}
|
|
40778
40819
|
catch (err) {
|
|
40779
40820
|
this.errors.handle(err, {
|
|
@@ -40960,6 +41001,11 @@ class SurveyBuilderComponent {
|
|
|
40960
41001
|
});
|
|
40961
41002
|
}
|
|
40962
41003
|
}
|
|
41004
|
+
hydrate(label, subtitle, questions) {
|
|
41005
|
+
this.titleControl.setValue(label ?? '');
|
|
41006
|
+
this.subtitleControl.setValue(subtitle ?? '');
|
|
41007
|
+
this.questions.set([...(questions ?? [])].sort((a, b) => a.order - b.order).map(f => this.rowFromField(f)));
|
|
41008
|
+
}
|
|
40963
41009
|
rowFromField(f) {
|
|
40964
41010
|
return {
|
|
40965
41011
|
id: `row-${rowUid++}`,
|