valtech-components 4.0.969 → 4.0.971

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.
Files changed (29) hide show
  1. package/esm2022/lib/components/organisms/comms-preferences-settings/comms-preferences-settings.component.mjs +153 -0
  2. package/esm2022/lib/components/organisms/comms-preferences-settings/comms-preferences-settings.i18n.mjs +25 -0
  3. package/esm2022/lib/components/organisms/comms-preferences-settings/types.mjs +2 -0
  4. package/esm2022/lib/components/organisms/page-block/page-block.component.mjs +254 -0
  5. package/esm2022/lib/components/organisms/page-block/types.mjs +20 -0
  6. package/esm2022/lib/components/organisms/video-player/types.mjs +12 -0
  7. package/esm2022/lib/components/organisms/video-player/video-player.component.mjs +235 -0
  8. package/esm2022/lib/services/comms-preferences/comms-preferences.service.mjs +38 -0
  9. package/esm2022/lib/services/comms-preferences/config.mjs +18 -0
  10. package/esm2022/lib/services/comms-preferences/index.mjs +4 -0
  11. package/esm2022/lib/services/comms-preferences/types.mjs +2 -0
  12. package/esm2022/lib/version.mjs +2 -2
  13. package/esm2022/public-api.mjs +13 -1
  14. package/fesm2022/valtech-components.mjs +780 -63
  15. package/fesm2022/valtech-components.mjs.map +1 -1
  16. package/lib/components/organisms/comms-preferences-settings/comms-preferences-settings.component.d.ts +29 -0
  17. package/lib/components/organisms/comms-preferences-settings/comms-preferences-settings.i18n.d.ts +24 -0
  18. package/lib/components/organisms/comms-preferences-settings/types.d.ts +4 -0
  19. package/lib/components/organisms/page-block/page-block.component.d.ts +65 -0
  20. package/lib/components/organisms/page-block/types.d.ts +102 -0
  21. package/lib/components/organisms/video-player/types.d.ts +45 -0
  22. package/lib/components/organisms/video-player/video-player.component.d.ts +42 -0
  23. package/lib/services/comms-preferences/comms-preferences.service.d.ts +15 -0
  24. package/lib/services/comms-preferences/config.d.ts +14 -0
  25. package/lib/services/comms-preferences/index.d.ts +3 -0
  26. package/lib/services/comms-preferences/types.d.ts +21 -0
  27. package/lib/version.d.ts +1 -1
  28. package/package.json +1 -1
  29. package/public-api.d.ts +7 -0
@@ -0,0 +1,29 @@
1
+ import { ToggleInputMetadata } from '../../molecules/toggle-input/types';
2
+ import { CommunicationSetting } from '../../../services/comms-preferences/types';
3
+ import { CommsPreferencesSettingsConfig } from './types';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * `val-comms-preferences-settings` (ADR-089) — la organización enciende o
7
+ * apaga comunicaciones transaccionales configurables (hoy: bingo-transfer-
8
+ * pending; el catálogo crece sin tocar este componente). Un toggle por
9
+ * comunicación, guardado inmediato (sin botón "Guardar" aparte) con
10
+ * rollback optimista si falla.
11
+ */
12
+ export declare class CommsPreferencesSettingsComponent {
13
+ private i18n;
14
+ private nav;
15
+ private toast;
16
+ private svc;
17
+ config?: CommsPreferencesSettingsConfig;
18
+ private get ns();
19
+ readonly settings: import("@angular/core").WritableSignal<CommunicationSetting[]>;
20
+ private readonly controls;
21
+ readonly page: import("../../../services/page-state/page-state").PageState;
22
+ constructor();
23
+ private controlFor;
24
+ toggleProps(templateId: string): ToggleInputMetadata;
25
+ private onToggle;
26
+ protected tt(key: string): string;
27
+ static ɵfac: i0.ɵɵFactoryDeclaration<CommsPreferencesSettingsComponent, never>;
28
+ static ɵcmp: i0.ɵɵComponentDeclaration<CommsPreferencesSettingsComponent, "val-comms-preferences-settings", never, { "config": { "alias": "config"; "required": false; }; }, {}, never, never, true, never>;
29
+ }
@@ -0,0 +1,24 @@
1
+ export declare const COMMS_PREFERENCES_SETTINGS_I18N: {
2
+ es: {
3
+ pageTitle: string;
4
+ pageDescription: string;
5
+ empty: string;
6
+ savedOk: string;
7
+ saveError: string;
8
+ errorTitle: string;
9
+ offlineTitle: string;
10
+ offlineHint: string;
11
+ retry: string;
12
+ };
13
+ en: {
14
+ pageTitle: string;
15
+ pageDescription: string;
16
+ empty: string;
17
+ savedOk: string;
18
+ saveError: string;
19
+ errorTitle: string;
20
+ offlineTitle: string;
21
+ offlineHint: string;
22
+ retry: string;
23
+ };
24
+ };
@@ -0,0 +1,4 @@
1
+ export interface CommsPreferencesSettingsConfig {
2
+ /** Namespace i18n de textos propios (pageTitle/pageDescription/etc). Default `Settings.Comms`. */
3
+ i18nNamespace?: string;
4
+ }
@@ -0,0 +1,65 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import { FaqCategory } from '../faq/types';
3
+ import { PageBlock, PageCTABlockProps, PageCTAIntent, PageFAQBlockProps, PageGalleryBlockProps, PageHeroBlockProps, PageTextBlockProps } from './types';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * `val-page-block`
7
+ *
8
+ * Organism que renderiza UN bloque del constructor de páginas de plataforma
9
+ * (ADR-077, `services/page` en el backend). Es el punto de la lib donde el
10
+ * catálogo de bloques (`hero`, `text`, `gallery`, `cta`, `faq`) mapea 1:1 a
11
+ * componentes reales — la razón de ser del ADR: "un rediseño de la lib
12
+ * mejora todas las páginas publicadas sin tocar sus datos".
13
+ *
14
+ * Presentacional puro: recibe `props` ya tipados (espejo exacto del `Block`
15
+ * del backend), sin llamadas HTTP propias ni conocimiento de a qué app
16
+ * pertenece la página. El bloque `cta` NO navega — emite `(ctaAction)` con
17
+ * la intención cruda (`{ action }`) para que el consumidor (la app) la
18
+ * resuelva contra su propio routing (ADR-077: "el CTA guarda una intención,
19
+ * nunca una URL").
20
+ *
21
+ * El caller típico itera `Page.Blocks` y renderiza uno de estos por bloque:
22
+ *
23
+ * @example
24
+ * ```html
25
+ * @for (block of page().blocks; track $index) {
26
+ * <val-page-block [props]="block" (ctaAction)="onCtaAction($event)" />
27
+ * }
28
+ * ```
29
+ */
30
+ export declare class PageBlockComponent {
31
+ /** El bloque a renderizar — espejo de `page.Block` (backend). */
32
+ props: PageBlock;
33
+ /**
34
+ * Emite la intención cruda del CTA al hacer click (`{ action }`, nunca una
35
+ * URL — ver comentario de clase). El consumidor decide qué hacer con
36
+ * `action`; este componente no la interpreta.
37
+ */
38
+ ctaAction: EventEmitter<PageCTAIntent>;
39
+ /** Fallback de imagen rota (convención de la lib) — un slot, una signal. */
40
+ readonly heroImageFailed: import("@angular/core").WritableSignal<boolean>;
41
+ /** Índices de `gallery.images` cuya carga falló (`error` del `<img>`). */
42
+ readonly failedGalleryImages: import("@angular/core").WritableSignal<Set<number>>;
43
+ get hero(): PageHeroBlockProps;
44
+ get text(): PageTextBlockProps;
45
+ get gallery(): PageGalleryBlockProps;
46
+ get cta(): PageCTABlockProps;
47
+ get faq(): PageFAQBlockProps;
48
+ /**
49
+ * `text.body` es texto plano (no markdown — a diferencia de
50
+ * `val-article`/`val-faq`, `blocks_validate.go` solo exige un string no
51
+ * vacío). Partido por línea para que `val-text` (un `<p>` por línea)
52
+ * respete los saltos que el autor escribió, sin interpretar sintaxis.
53
+ */
54
+ textParagraphs(): string[];
55
+ /**
56
+ * `val-faq` agrupa por categoría; el bloque `faq` de `services/page` no
57
+ * tiene categorías (solo `items` planos) — se envuelve en una única
58
+ * categoría sin label (`hideSingleCategoryLabel` default `true` la oculta).
59
+ */
60
+ faqCategories(): FaqCategory[];
61
+ onCtaClick(): void;
62
+ onGalleryImageError(index: number): void;
63
+ static ɵfac: i0.ɵɵFactoryDeclaration<PageBlockComponent, never>;
64
+ static ɵcmp: i0.ɵɵComponentDeclaration<PageBlockComponent, "val-page-block", never, { "props": { "alias": "props"; "required": false; }; }, { "ctaAction": "ctaAction"; }, never, never, true, never>;
65
+ }
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Tipos del organism `val-page-block` — constructor de páginas de plataforma
3
+ * (ADR-077: `docs/adr/077-constructor-de-paginas-de-plataforma.md`, primera
4
+ * aplicación real en Eklesee, Bloque 4:
5
+ * `docs/eklesee/03-roadmap-y-abiertos.md`).
6
+ *
7
+ * Espejo 1:1 de `Block`/`Props` en `backend/go/services/page/types.go` +
8
+ * `backend/go/services/page/blocks_validate.go` — la forma de cada `props`
9
+ * sale de ahí, no se inventa acá. El catálogo de esta primera pasada son 5
10
+ * tipos (`hero`, `text`, `gallery`, `cta`, `faq`); `countdown`/`sponsors`/
11
+ * `progress` (catálogo completo del ADR) quedan fuera hasta que Bingo migre.
12
+ *
13
+ * El componente es i18n-agnóstico y agnóstico al dominio a propósito (mismo
14
+ * criterio que `val-faq`/`val-article`): recibe `props` ya resueltos, sin
15
+ * llamadas HTTP propias ni conocimiento de rutas de ninguna app. La app que
16
+ * lo consume (Eklesee) resuelve `PageCTAIntent.action` a una ruta real —
17
+ * este organism solo la emite via `(ctaAction)`.
18
+ */
19
+ /** hero — props: `title` (requerido), `subtitle`/`image`/`align` (opcionales). */
20
+ export interface PageHeroBlockProps {
21
+ title: string;
22
+ subtitle?: string;
23
+ /** URL de la imagen de fondo/acompañante. */
24
+ image?: string;
25
+ align?: 'left' | 'center' | 'right';
26
+ }
27
+ /** text — props: `body` (requerido), `heading` (opcional). */
28
+ export interface PageTextBlockProps {
29
+ body: string;
30
+ heading?: string;
31
+ }
32
+ /** gallery — props: `images` (requerido, 1..20 URLs, validado en backend). */
33
+ export interface PageGalleryBlockProps {
34
+ images: string[];
35
+ }
36
+ /**
37
+ * Intención del CTA, NUNCA una URL (ADR-077: "el link del vendedor puede
38
+ * regenerarse... sin dejar páginas publicadas apuntando a un token muerto").
39
+ * El catálogo de `action` es del backend (`page.CTAAction`, hoy solo
40
+ * `apply_membership` — ver `services/page/types.go`). Este componente NO
41
+ * resuelve la intención a una ruta: solo la recibe y la reemite tal cual via
42
+ * `(ctaAction)` para que la app la resuelva contra su propio routing.
43
+ */
44
+ export interface PageCTAIntent {
45
+ action: string;
46
+ }
47
+ /** cta — props: `label` (requerido), `intent.action` (requerido). */
48
+ export interface PageCTABlockProps {
49
+ label: string;
50
+ intent: PageCTAIntent;
51
+ }
52
+ /** Un ítem de FAQ (pregunta + respuesta en texto plano). */
53
+ export interface PageFAQItemProps {
54
+ question: string;
55
+ answer: string;
56
+ }
57
+ /** faq — props: `items` (requerido, 1..50, validado en backend). */
58
+ export interface PageFAQBlockProps {
59
+ items: PageFAQItemProps[];
60
+ }
61
+ /** Discriminador de bloque — espejo de `page.BlockType` (backend). */
62
+ export type PageBlockType = 'hero' | 'text' | 'gallery' | 'cta' | 'faq';
63
+ interface PageBlockBase {
64
+ /**
65
+ * Orden de renderizado dentro de `Page.Blocks`. El backend lo re-estampa
66
+ * SIEMPRE a partir de la posición del array al guardar (`SetBlocks` —
67
+ * regla #7 backend/go/CLAUDE.md: nunca confiar en un `order` que venga del
68
+ * cliente). Opcional acá: el consumidor típico ya itera el array en el
69
+ * orden real, este campo es informativo.
70
+ */
71
+ order?: number;
72
+ }
73
+ export interface PageHeroBlock extends PageBlockBase {
74
+ type: 'hero';
75
+ props: PageHeroBlockProps;
76
+ }
77
+ export interface PageTextBlock extends PageBlockBase {
78
+ type: 'text';
79
+ props: PageTextBlockProps;
80
+ }
81
+ export interface PageGalleryBlock extends PageBlockBase {
82
+ type: 'gallery';
83
+ props: PageGalleryBlockProps;
84
+ }
85
+ export interface PageCTABlock extends PageBlockBase {
86
+ type: 'cta';
87
+ props: PageCTABlockProps;
88
+ }
89
+ export interface PageFAQBlock extends PageBlockBase {
90
+ type: 'faq';
91
+ props: PageFAQBlockProps;
92
+ }
93
+ /** Unión discriminada — espejo de `page.Block` (backend, `Props map[string]any` tipado por `Type`). */
94
+ export type PageBlock = PageHeroBlock | PageTextBlock | PageGalleryBlock | PageCTABlock | PageFAQBlock;
95
+ /**
96
+ * Props de `<val-page-block>`. Alias de `PageBlock` con el nombre
97
+ * `*Metadata` que sigue el resto de la lib (`convención: Props interface
98
+ * → *Metadata`) — mismo tipo, dos nombres para dos contextos de uso (el
99
+ * array de la página vs. el `@Input` de un componente puntual).
100
+ */
101
+ export type PageBlockMetadata = PageBlock;
102
+ export {};
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Tipos de `val-video-player` (ADR-087 — video como servicio de plataforma).
3
+ *
4
+ * Espejo agnóstico al dominio de `content.VideoAsset` (backend Go,
5
+ * `backend/go/services/content/video.go`) — mismos nombres de campo en
6
+ * camelCase. Cualquier app pasa acá el `VideoAsset` que le devuelve SU propio
7
+ * backend (sermón en Eklesee, receta en Okhelia, animal en Chesed, artículo de
8
+ * ayuda) con un mapeo trivial; el componente no conoce ni le importa de qué
9
+ * dominio viene.
10
+ */
11
+ export type VideoPlayerSource = 'upload' | 'link';
12
+ /** Solo aplica a `source: 'upload'`. Un link normalizado con éxito nace en 'ready'. */
13
+ export type VideoPlayerStatus = 'uploading' | 'processing' | 'ready' | 'failed' | 'rejected';
14
+ export interface VideoPlayerCaption {
15
+ locale: string;
16
+ url: string;
17
+ }
18
+ export interface VideoPlayerAsset {
19
+ source: VideoPlayerSource;
20
+ /**
21
+ * `source:'upload'` → URL de reproducción ya presignada por el backend
22
+ * (TTL corto, ~15 min — ADR-087 §6). Úsala directo, no la cachees ni la
23
+ * persistas: se recalcula en cada lectura del documento.
24
+ * `source:'link'` → URL normalizada del proveedor (no se usa para el
25
+ * embed, ver `externalId`).
26
+ */
27
+ url?: string;
28
+ /** `'youtube' | 'vimeo'` — solo si `source: 'link'`. */
29
+ provider?: string;
30
+ /**
31
+ * ID ya normalizado por el backend — el ÚNICO dato que arma el iframe de
32
+ * embed. El componente NUNCA arma un `src` con datos crudos del usuario.
33
+ */
34
+ externalId?: string;
35
+ durationSec?: number;
36
+ /** Portada — se muestra mientras el video no está `ready` (mejor percepción de carga). */
37
+ thumbnail?: string;
38
+ captions?: VideoPlayerCaption[];
39
+ status?: VideoPlayerStatus;
40
+ /**
41
+ * Motivo legible de `failed`/`rejected`, ya en el idioma que decidió el
42
+ * backend (es-CL) — se muestra tal cual, no es un código a traducir.
43
+ */
44
+ failReason?: string;
45
+ }
@@ -0,0 +1,42 @@
1
+ import { SafeResourceUrl } from '@angular/platform-browser';
2
+ import { VideoPlayerAsset } from './types';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * `val-video-player` — reproductor de video de plataforma (ADR-087, "Fase 1 —
6
+ * Reproducción"). Presentacional/dumb: recibe un `VideoPlayerAsset` YA
7
+ * RESUELTO por el backend de turno y decide el render, sin fetch propio.
8
+ *
9
+ * - `source:'upload'` + `status:'ready'` → `<video>` nativo (`preload="none"`
10
+ * + portada — ADR-087 §8, cero bytes de video hasta que alguien le da play).
11
+ * - `source:'upload'` + `uploading|processing` → portada (si hay) + mensaje.
12
+ * - `source:'upload'` + `failed|rejected` → mensaje legible con `failReason`
13
+ * (texto ya resuelto por el backend, se muestra tal cual).
14
+ * - `source:'link'` → iframe **siempre** contra un patrón fijo por proveedor
15
+ * conocido (`youtube-nocookie.com/embed/{id}` · `player.vimeo.com/video/{id}`),
16
+ * nunca un `src` armado con datos crudos del usuario. Proveedor no
17
+ * reconocido → mensaje, nunca un iframe "por si acaso".
18
+ *
19
+ * @example
20
+ * <val-video-player [video]="doc.video" />
21
+ */
22
+ export declare class VideoPlayerComponent {
23
+ private readonly i18n;
24
+ private readonly sanitizer;
25
+ /** El `VideoAsset` ya resuelto por el backend. `null`/`undefined` → no renderiza nada. */
26
+ readonly video: import("@angular/core").InputSignal<VideoPlayerAsset>;
27
+ readonly asset: import("@angular/core").Signal<VideoPlayerAsset>;
28
+ readonly thumbFailed: import("@angular/core").WritableSignal<boolean>;
29
+ /**
30
+ * Arma el embed SIEMPRE contra un patrón fijo por proveedor conocido — el
31
+ * `externalId` es el único dato del backend que entra en el `src`. Un
32
+ * proveedor no reconocido devuelve `null` (el template cae al mensaje, no a
33
+ * un iframe "por si acaso"). `bypassSecurityTrustResourceUrl` es seguro acá
34
+ * porque el string completo lo arma este componente, nunca el usuario.
35
+ */
36
+ readonly embedUrl: import("@angular/core").Signal<SafeResourceUrl>;
37
+ constructor();
38
+ private buildEmbedUrl;
39
+ t(key: string): string;
40
+ static ɵfac: i0.ɵɵFactoryDeclaration<VideoPlayerComponent, never>;
41
+ static ɵcmp: i0.ɵɵComponentDeclaration<VideoPlayerComponent, "val-video-player", never, { "video": { "alias": "video"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
42
+ }
@@ -0,0 +1,15 @@
1
+ import { HttpClient } from '@angular/common/http';
2
+ import { Observable } from 'rxjs';
3
+ import { ListCommsSettingsResponse, SetCommsEnabledResponse, ValtechCommsPreferencesConfig } from './types';
4
+ import * as i0 from "@angular/core";
5
+ export declare class CommsPreferencesService {
6
+ private readonly http;
7
+ private readonly config;
8
+ private readonly baseUrl;
9
+ private readonly appId;
10
+ constructor(http: HttpClient, config: ValtechCommsPreferencesConfig | null);
11
+ list(): Observable<ListCommsSettingsResponse>;
12
+ setEnabled(templateId: string, enabled: boolean): Observable<SetCommsEnabledResponse>;
13
+ static ɵfac: i0.ɵɵFactoryDeclaration<CommsPreferencesService, [null, { optional: true; }]>;
14
+ static ɵprov: i0.ɵɵInjectableDeclaration<CommsPreferencesService>;
15
+ }
@@ -0,0 +1,14 @@
1
+ import { EnvironmentProviders, InjectionToken } from '@angular/core';
2
+ import { ValtechCommsPreferencesConfig } from './types';
3
+ export declare const VALTECH_COMMS_PREFERENCES_CONFIG: InjectionToken<ValtechCommsPreferencesConfig>;
4
+ /**
5
+ * Provee el servicio de comms-preferences (ADR-089) a la aplicacion Angular.
6
+ *
7
+ * @example
8
+ * bootstrapApplication(AppComponent, {
9
+ * providers: [
10
+ * provideValtechCommsPreferences({ apiUrl: environment.apiUrl, appId: 'bingo' }),
11
+ * ],
12
+ * });
13
+ */
14
+ export declare function provideValtechCommsPreferences(config: ValtechCommsPreferencesConfig): EnvironmentProviders;
@@ -0,0 +1,3 @@
1
+ export * from './comms-preferences.service';
2
+ export * from './config';
3
+ export * from './types';
@@ -0,0 +1,21 @@
1
+ export interface ValtechCommsPreferencesConfig {
2
+ apiUrl: string;
3
+ appId: string;
4
+ }
5
+ export interface CommunicationSetting {
6
+ templateId: string;
7
+ label: string;
8
+ labelEn: string;
9
+ audience: string;
10
+ enabled: boolean;
11
+ isDefault: boolean;
12
+ }
13
+ export interface ListCommsSettingsResponse {
14
+ operationId: string;
15
+ settings: CommunicationSetting[];
16
+ }
17
+ export interface SetCommsEnabledResponse {
18
+ operationId: string;
19
+ templateId: string;
20
+ enabled: boolean;
21
+ }
package/lib/version.d.ts CHANGED
@@ -2,4 +2,4 @@
2
2
  * Current version of valtech-components.
3
3
  * This is automatically updated during the publish process.
4
4
  */
5
- export declare const VERSION = "4.0.969";
5
+ export declare const VERSION = "4.0.971";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "valtech-components",
3
- "version": "4.0.969",
3
+ "version": "4.0.971",
4
4
  "private": false,
5
5
  "bin": {
6
6
  "valtech-firebase-config": "./src/lib/services/firebase/scripts/generate-sw-config.js"
package/public-api.d.ts CHANGED
@@ -498,6 +498,9 @@ export * from './lib/components/molecules/content-reaction/content-reaction-moda
498
498
  export * from './lib/components/molecules/content-reaction/types';
499
499
  export * from './lib/services/reactions/index';
500
500
  export * from './lib/services/collections';
501
+ export * from './lib/services/comms-preferences';
502
+ export * from './lib/components/organisms/comms-preferences-settings/comms-preferences-settings.component';
503
+ export * from './lib/components/organisms/comms-preferences-settings/types';
501
504
  export * from './lib/services/entity-feed/index';
502
505
  export * from './lib/components/molecules/reaction-bar/reaction-bar.component';
503
506
  export * from './lib/components/molecules/reaction-bar/types';
@@ -577,3 +580,7 @@ export { ThreadPanelComponent } from './lib/components/organisms/thread-panel/th
577
580
  export * from './lib/services/forms';
578
581
  export * from './lib/services/metering.service';
579
582
  export { ValQuotaWarningComponent } from './lib/components/val-quota-warning/val-quota-warning.component';
583
+ export * from './lib/components/organisms/page-block/page-block.component';
584
+ export * from './lib/components/organisms/page-block/types';
585
+ export * from './lib/components/organisms/video-player/video-player.component';
586
+ export * from './lib/components/organisms/video-player/types';