valtech-components 2.0.729 → 2.0.731
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/bottom-nav/bottom-nav.component.mjs +4 -4
- package/esm2022/lib/components/organisms/bottom-nav/types.mjs +2 -2
- package/esm2022/lib/config/company-footer.config.mjs +34 -20
- package/esm2022/lib/services/legal-link/legal-link.service.mjs +68 -0
- package/esm2022/lib/services/markdown-article/legal-content.service.mjs +65 -14
- package/esm2022/lib/services/markdown-article/markdown-article-parser.mjs +266 -0
- package/esm2022/lib/services/markdown-article/markdown-article-parser.service.mjs +6 -275
- package/esm2022/lib/services/preferences/index.mjs +3 -0
- package/esm2022/lib/services/preferences/preferences.service.mjs +164 -0
- package/esm2022/lib/services/preferences/preferences.types.mjs +7 -0
- package/esm2022/lib/version.mjs +2 -2
- package/esm2022/public-api.mjs +10 -1
- package/fesm2022/valtech-components.mjs +555 -267
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/atoms/rights-footer/rights-footer.component.d.ts +1 -1
- package/lib/components/atoms/text/text.component.d.ts +1 -1
- package/lib/components/molecules/features-list/features-list.component.d.ts +1 -1
- package/lib/components/organisms/article/article.component.d.ts +3 -3
- package/lib/components/organisms/bottom-nav/bottom-nav.component.d.ts +1 -1
- package/lib/components/organisms/bottom-nav/types.d.ts +1 -1
- package/lib/components/organisms/toolbar/toolbar.component.d.ts +1 -1
- package/lib/config/company-footer.config.d.ts +24 -4
- package/lib/services/legal-link/legal-link.service.d.ts +59 -0
- package/lib/services/markdown-article/legal-content.service.d.ts +49 -7
- package/lib/services/markdown-article/markdown-article-parser.d.ts +16 -0
- package/lib/services/markdown-article/markdown-article-parser.service.d.ts +3 -22
- package/lib/services/preferences/index.d.ts +2 -0
- package/lib/services/preferences/preferences.service.d.ts +51 -0
- package/lib/services/preferences/preferences.types.d.ts +35 -0
- package/lib/version.d.ts +1 -1
- package/package.json +1 -1
- package/public-api.d.ts +3 -0
|
@@ -43,7 +43,7 @@ export declare class RightsFooterComponent {
|
|
|
43
43
|
/**
|
|
44
44
|
* Computed helper for color prop in template.
|
|
45
45
|
*/
|
|
46
|
-
propsColor: import("@angular/core").Signal<"primary" | "secondary" | "tertiary" | "success" | "warning" | "danger" | "light" | "
|
|
46
|
+
propsColor: import("@angular/core").Signal<"medium" | "primary" | "secondary" | "tertiary" | "success" | "warning" | "danger" | "light" | "dark">;
|
|
47
47
|
/**
|
|
48
48
|
* Computed helper for withMargin prop in template.
|
|
49
49
|
*/
|
|
@@ -11,7 +11,7 @@ export declare class TextComponent {
|
|
|
11
11
|
*/
|
|
12
12
|
displayContent: import("@angular/core").Signal<string>;
|
|
13
13
|
propsColor: import("@angular/core").Signal<import("@ionic/core").Color>;
|
|
14
|
-
propsSize: import("@angular/core").Signal<"
|
|
14
|
+
propsSize: import("@angular/core").Signal<"small" | "medium" | "large" | "xlarge">;
|
|
15
15
|
propsBold: import("@angular/core").Signal<boolean>;
|
|
16
16
|
propsProcessLinks: import("@angular/core").Signal<boolean>;
|
|
17
17
|
propsAllowPartialBold: import("@angular/core").Signal<boolean>;
|
|
@@ -48,7 +48,7 @@ export declare class FeaturesListComponent {
|
|
|
48
48
|
iconColor: string;
|
|
49
49
|
iconSize: number;
|
|
50
50
|
mode: "horizontal" | "vertical";
|
|
51
|
-
gap: "
|
|
51
|
+
gap: "small" | "medium" | "large";
|
|
52
52
|
alignment: "start" | "center";
|
|
53
53
|
}>;
|
|
54
54
|
/** Resolved icon color (handles Ionic colors and CSS colors) */
|
|
@@ -45,7 +45,7 @@ export declare class ArticleComponent implements OnInit {
|
|
|
45
45
|
getVideoElement(element: ArticleElement): ArticleVideoElement;
|
|
46
46
|
getCustomElement(element: ArticleElement): ArticleCustomElement;
|
|
47
47
|
getQuoteTextProps(element: ArticleElement): {
|
|
48
|
-
size: "
|
|
48
|
+
size: "small" | "medium" | "large" | "xlarge";
|
|
49
49
|
color: import("@ionic/core").Color;
|
|
50
50
|
content?: string;
|
|
51
51
|
bold: boolean;
|
|
@@ -61,7 +61,7 @@ export declare class ArticleComponent implements OnInit {
|
|
|
61
61
|
showQuoteMark?: boolean;
|
|
62
62
|
};
|
|
63
63
|
getHighlightTextProps(element: ArticleElement): {
|
|
64
|
-
size: "
|
|
64
|
+
size: "small" | "medium" | "large" | "xlarge";
|
|
65
65
|
color: import("@ionic/core").Color;
|
|
66
66
|
content?: string;
|
|
67
67
|
bold: boolean;
|
|
@@ -90,7 +90,7 @@ export declare class ArticleComponent implements OnInit {
|
|
|
90
90
|
contentInterpolation?: Record<string, string | number>;
|
|
91
91
|
icon?: import("valtech-components").IconMetada;
|
|
92
92
|
shape?: "round";
|
|
93
|
-
size?: "small" | "
|
|
93
|
+
size?: "small" | "large" | "default";
|
|
94
94
|
fill?: "default" | "clear" | "outline" | "solid";
|
|
95
95
|
type: "button" | "submit" | "reset";
|
|
96
96
|
token?: string;
|
|
@@ -63,7 +63,7 @@ export declare class BottomNavComponent implements OnInit, OnDestroy {
|
|
|
63
63
|
i18nNamespace?: string;
|
|
64
64
|
hideLabels: boolean;
|
|
65
65
|
safeArea: boolean;
|
|
66
|
-
animation: "
|
|
66
|
+
animation: "none" | "slide" | "fade" | "scale";
|
|
67
67
|
maxWidth: string;
|
|
68
68
|
}>;
|
|
69
69
|
/** Computed tabs with FAB inserted if present */
|
|
@@ -109,7 +109,7 @@ export interface BottomNavMetadata {
|
|
|
109
109
|
safeArea?: boolean;
|
|
110
110
|
/** Animation style */
|
|
111
111
|
animation?: 'fade' | 'scale' | 'slide' | 'none';
|
|
112
|
-
/** Cap del ancho de la barra. Token sm|md|lg|xl|full o valor CSS crudo. Default: '
|
|
112
|
+
/** Cap del ancho de la barra. Token sm|md|lg|xl|full o valor CSS crudo. Default: 'md' (720px) — bottom-nav típicamente tiene pocos tabs y se ve mejor estrecho aunque el contenido use 'xl' */
|
|
113
113
|
maxWidth?: 'sm' | 'md' | 'lg' | 'xl' | 'full' | string;
|
|
114
114
|
}
|
|
115
115
|
/**
|
|
@@ -72,7 +72,7 @@ export declare class ToolbarComponent implements OnInit {
|
|
|
72
72
|
};
|
|
73
73
|
showFlags?: boolean;
|
|
74
74
|
color: import("@ionic/core").Color;
|
|
75
|
-
size?: "small" | "
|
|
75
|
+
size?: "small" | "large" | "default";
|
|
76
76
|
fill?: "default" | "clear" | "outline" | "solid";
|
|
77
77
|
shape?: "round";
|
|
78
78
|
expand?: "full" | "block";
|
|
@@ -31,9 +31,19 @@ export declare const VALTECH_FOOTER_LOGO: {
|
|
|
31
31
|
export interface CompanyLink {
|
|
32
32
|
/** i18n key for the link text */
|
|
33
33
|
key: string;
|
|
34
|
-
/** URL path or
|
|
34
|
+
/** URL path (relative) or absolute URL */
|
|
35
35
|
url: string;
|
|
36
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* Hint for `LegalLinkService` about which app owns this link in a multi-app factory:
|
|
38
|
+
* - `'legal'` — canonical legal content (terms, privacy, …) — lives on main site
|
|
39
|
+
* - `'site'` — marketing/info pages (about, blog, …) — lives on main site
|
|
40
|
+
* - `'support'` — support/help — typically per-app (each product has own support)
|
|
41
|
+
*
|
|
42
|
+
* In satellite apps with `provideValtechLegal({ baseUrl })`, links with kind
|
|
43
|
+
* `'legal'` or `'site'` get rewritten to the main site URL.
|
|
44
|
+
*/
|
|
45
|
+
kind?: 'legal' | 'site' | 'support';
|
|
46
|
+
/** Force opens in a new tab. Resolver may also set this when rewriting cross-origin. */
|
|
37
47
|
external?: boolean;
|
|
38
48
|
}
|
|
39
49
|
/**
|
|
@@ -82,12 +92,22 @@ export declare const VALTECH_LANGUAGE_SELECTOR: {
|
|
|
82
92
|
size: "default";
|
|
83
93
|
};
|
|
84
94
|
/**
|
|
85
|
-
*
|
|
95
|
+
* Optional URL resolver applied per link (e.g. `LegalLinkService.resolve.bind(svc)`).
|
|
96
|
+
* Returns `{ url, external? }` to allow cross-origin rewrites.
|
|
97
|
+
*/
|
|
98
|
+
export type CompanyLinkResolver = (link: CompanyLink) => {
|
|
99
|
+
url: string;
|
|
100
|
+
external?: boolean;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Helper to build footer links from company links config.
|
|
104
|
+
*
|
|
86
105
|
* @param links - Array of company links
|
|
87
106
|
* @param t - Translation function (key: string) => string
|
|
107
|
+
* @param resolver - Optional resolver — typically `(link) => ({ url: legalLink.resolve(link.url), external: legalLink.isExternal(link.url) && (link.kind === 'legal' || link.kind === 'site') })` to point cross-app legal/site links to the main site.
|
|
88
108
|
* @returns Array of link objects ready for FooterLinksMetadata
|
|
89
109
|
*/
|
|
90
|
-
export declare function buildFooterLinks(links: CompanyLink[], t: (key: string) => string): Array<{
|
|
110
|
+
export declare function buildFooterLinks(links: CompanyLink[], t: (key: string) => string, resolver?: CompanyLinkResolver): Array<{
|
|
91
111
|
url: string;
|
|
92
112
|
text: string;
|
|
93
113
|
color: string;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { InjectionToken, Provider } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
/**
|
|
4
|
+
* Config for cross-app legal/site link resolution.
|
|
5
|
+
*
|
|
6
|
+
* Used by satellite apps (showcase, sigify, admin-portal, …) to point their legal
|
|
7
|
+
* and site links (terms, privacy, about, contact, …) to the main marketing site,
|
|
8
|
+
* which owns the canonical legal content. The main site itself does NOT call
|
|
9
|
+
* `provideValtechLegal` — its links stay relative.
|
|
10
|
+
*/
|
|
11
|
+
export interface ValtechLegalConfig {
|
|
12
|
+
/**
|
|
13
|
+
* Absolute base URL of the main site (no trailing slash).
|
|
14
|
+
* @example 'https://myvaltech.com'
|
|
15
|
+
*/
|
|
16
|
+
baseUrl?: string;
|
|
17
|
+
/** Open resolved external links in a new tab. Defaults to `true` when `baseUrl` is set. */
|
|
18
|
+
openInNewTab?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare const VALTECH_LEGAL_CONFIG: InjectionToken<ValtechLegalConfig>;
|
|
21
|
+
/**
|
|
22
|
+
* Resolves legal/site paths against a configurable main-site base URL.
|
|
23
|
+
*
|
|
24
|
+
* - **Main site mode**: no `provideValtechLegal` called → `resolve('/legal/terms')` returns `/legal/terms` (relative).
|
|
25
|
+
* - **Satellite mode**: `provideValtechLegal({ baseUrl: 'https://myvaltech.com' })` → `resolve('/legal/terms')` returns `'https://myvaltech.com/legal/terms'` and `isExternal('/legal/terms')` returns `true`.
|
|
26
|
+
*
|
|
27
|
+
* Absolute URLs passed in are returned unchanged (no double-prefix).
|
|
28
|
+
*/
|
|
29
|
+
export declare class LegalLinkService {
|
|
30
|
+
private readonly config;
|
|
31
|
+
/** Effective base URL (null if running as main site). */
|
|
32
|
+
get baseUrl(): string | null;
|
|
33
|
+
/** Whether resolved external links should open in a new tab. */
|
|
34
|
+
get openInNewTab(): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Returns the URL to use for a given internal path. Absolute URLs pass through.
|
|
37
|
+
* @example
|
|
38
|
+
* resolve('/legal/terms') // main site: '/legal/terms'
|
|
39
|
+
* // satellite: 'https://myvaltech.com/legal/terms'
|
|
40
|
+
* resolve('https://x.com/y') // unchanged
|
|
41
|
+
*/
|
|
42
|
+
resolve(path: string): string;
|
|
43
|
+
/** `true` if the path would be resolved to a cross-origin URL. */
|
|
44
|
+
isExternal(path: string): boolean;
|
|
45
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<LegalLinkService, never>;
|
|
46
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<LegalLinkService>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Wires `LegalLinkService` for satellite apps. Omit in the main site (the one
|
|
50
|
+
* that hosts the canonical /legal/* routes) so links stay relative.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* // main.ts of showcase / sigify / etc.
|
|
54
|
+
* provideValtechLegal({
|
|
55
|
+
* baseUrl: 'https://myvaltech.com',
|
|
56
|
+
* openInNewTab: true,
|
|
57
|
+
* }),
|
|
58
|
+
*/
|
|
59
|
+
export declare function provideValtechLegal(config: ValtechLegalConfig): Provider;
|
|
@@ -1,31 +1,73 @@
|
|
|
1
|
+
import { InjectionToken, Provider } from '@angular/core';
|
|
1
2
|
import { Observable } from 'rxjs';
|
|
2
3
|
import { ArticleMetadata } from '../../components/organisms/article/types';
|
|
3
4
|
import * as i0 from "@angular/core";
|
|
4
5
|
export type LegalSlug = 'terms' | 'privacy' | 'cookies' | 'data-usage' | 'legal-notice' | string;
|
|
6
|
+
/**
|
|
7
|
+
* Factory that returns a Record<slug, ArticleMetadata> for a given locale.
|
|
8
|
+
* Use a dynamic `import()` so each locale module is code-split by the bundler.
|
|
9
|
+
*/
|
|
10
|
+
export type LegalContentFactory = () => Promise<Record<string, ArticleMetadata>>;
|
|
11
|
+
export interface LegalContentConfig {
|
|
12
|
+
/** Pre-generated content factories keyed by locale (e.g. `{ es: () => import('./generated/legal-content.es') ... }`). */
|
|
13
|
+
factories?: Record<string, LegalContentFactory>;
|
|
14
|
+
/** Override default `/assets/legal` base path used when no factory matches. */
|
|
15
|
+
basePath?: string;
|
|
16
|
+
/** Fallback locale (default `es`). Set null to disable. */
|
|
17
|
+
fallbackLocale?: string | null;
|
|
18
|
+
}
|
|
19
|
+
export declare const LEGAL_CONTENT_CONFIG: InjectionToken<LegalContentConfig>;
|
|
5
20
|
export interface LegalLoadOptions {
|
|
6
|
-
/** Two-letter locale code (es, en, pt).
|
|
21
|
+
/** Two-letter locale code (es, en, pt). */
|
|
7
22
|
locale?: string;
|
|
8
|
-
/** Override base path (default `/assets/legal`). */
|
|
23
|
+
/** Override base path for runtime mode (default `/assets/legal`). */
|
|
9
24
|
basePath?: string;
|
|
10
25
|
/** Fallback locale tried when the requested one is missing. Set null to disable. */
|
|
11
26
|
fallbackLocale?: string | null;
|
|
12
27
|
}
|
|
13
28
|
/**
|
|
14
|
-
* Loads
|
|
15
|
-
*
|
|
16
|
-
*
|
|
29
|
+
* Loads legal articles via one of two modes:
|
|
30
|
+
*
|
|
31
|
+
* 1. **Build-time** (preferred): when the app provides `LEGAL_CONTENT_CONFIG.factories`
|
|
32
|
+
* via `provideLegalContent()`, the service dynamically imports the matching
|
|
33
|
+
* locale module and returns the pre-parsed `ArticleMetadata` synchronously
|
|
34
|
+
* (wrapped in an Observable). Each locale is code-split.
|
|
35
|
+
*
|
|
36
|
+
* 2. **Runtime**: when no factory matches, falls back to fetching
|
|
37
|
+
* `/assets/legal/{locale}/{slug}.md` and parsing on the fly.
|
|
38
|
+
*
|
|
39
|
+
* Both modes cache by `locale:slug` so concurrent loads share one promise/HTTP request.
|
|
17
40
|
*/
|
|
18
41
|
export declare class LegalContentService {
|
|
19
42
|
private readonly http;
|
|
20
43
|
private readonly parser;
|
|
44
|
+
private readonly config;
|
|
21
45
|
private readonly DEFAULT_BASE;
|
|
22
46
|
private readonly cache;
|
|
47
|
+
private readonly factoryCache;
|
|
23
48
|
load(slug: LegalSlug, options?: LegalLoadOptions): Observable<ArticleMetadata>;
|
|
24
|
-
/**
|
|
49
|
+
/** Raw Markdown — only available in runtime mode (HTTP). */
|
|
25
50
|
raw(slug: LegalSlug, options?: LegalLoadOptions): Observable<string>;
|
|
26
|
-
/** Clears
|
|
51
|
+
/** Clears in-memory caches. Call on runtime locale change. */
|
|
27
52
|
invalidate(): void;
|
|
53
|
+
private loadOne;
|
|
54
|
+
private runFactory;
|
|
28
55
|
private fetchAndParse;
|
|
29
56
|
static ɵfac: i0.ɵɵFactoryDeclaration<LegalContentService, never>;
|
|
30
57
|
static ɵprov: i0.ɵɵInjectableDeclaration<LegalContentService>;
|
|
31
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Wires pre-generated legal content into `LegalContentService`. Call from `main.ts`
|
|
61
|
+
* (or any `providers: []` array). The factories use dynamic `import()` so each
|
|
62
|
+
* locale is code-split — only the active locale's bundle is loaded.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* provideLegalContent({
|
|
66
|
+
* factories: {
|
|
67
|
+
* es: () => import('./app/generated/legal-content.es').then((m) => m.LEGAL_CONTENT_ES),
|
|
68
|
+
* en: () => import('./app/generated/legal-content.en').then((m) => m.LEGAL_CONTENT_EN),
|
|
69
|
+
* pt: () => import('./app/generated/legal-content.pt').then((m) => m.LEGAL_CONTENT_PT),
|
|
70
|
+
* },
|
|
71
|
+
* })
|
|
72
|
+
*/
|
|
73
|
+
export declare function provideLegalContent(config: LegalContentConfig): Provider;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ArticleMetadata } from '../../components/organisms/article/types';
|
|
2
|
+
/**
|
|
3
|
+
* Pure Markdown → ArticleMetadata parser. No Angular deps — usable from Node scripts
|
|
4
|
+
* (build-time generation) and from the Angular `MarkdownArticleParserService` wrapper.
|
|
5
|
+
*
|
|
6
|
+
* Supported syntax:
|
|
7
|
+
* - Headings (#, ##, ### …) → title / subtitle
|
|
8
|
+
* - Paragraphs → paragraph (with `processLinks` + `allowPartialBold`)
|
|
9
|
+
* - Lists (-, *, 1.) → unordered / ordered list (- [ ] / - [x] for checklist)
|
|
10
|
+
* - Blockquotes (>) → quote, with GitHub callouts `> [!NOTE|TIP|INFO|WARNING|CAUTION|IMPORTANT]` mapped to notes
|
|
11
|
+
* - Code fences (```lang) → code
|
|
12
|
+
* - Box-drawing ASCII art (┌┐└┘│─) auto-wrapped as code
|
|
13
|
+
* - Tables → flattened into paragraphs with bold keys
|
|
14
|
+
* - Horizontal rules (---, ***, ___) → separator
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseMarkdownArticle(markdown: string, config?: Partial<ArticleMetadata>): ArticleMetadata;
|
|
@@ -1,31 +1,12 @@
|
|
|
1
1
|
import { ArticleMetadata } from '../../components/organisms/article/types';
|
|
2
2
|
import * as i0 from "@angular/core";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* - Headings (#, ##, ### …) → title / subtitle
|
|
8
|
-
* - Paragraphs → paragraph (with `processLinks` + `allowPartialBold`)
|
|
9
|
-
* - Lists (-, *, 1.) → unordered / ordered list (- [ ] / - [x] for checklist)
|
|
10
|
-
* - Blockquotes (>) → quote, with GitHub callouts `> [!NOTE|TIP|INFO|WARNING|CAUTION|IMPORTANT]` mapped to notes
|
|
11
|
-
* - Code fences (```lang) → code
|
|
12
|
-
* - Box-drawing ASCII art (┌┐└┘│─) auto-wrapped as code
|
|
13
|
-
* - Tables → flattened into paragraphs with bold keys
|
|
14
|
-
* - Horizontal rules (---, ***, ___) → separator
|
|
4
|
+
* Angular service wrapper for the pure {@link parseMarkdownArticle} function.
|
|
5
|
+
* Provided in root so it can be injected anywhere. The actual parsing logic lives in
|
|
6
|
+
* `markdown-article-parser.ts` and is also usable from Node scripts (build-time generation).
|
|
15
7
|
*/
|
|
16
8
|
export declare class MarkdownArticleParserService {
|
|
17
9
|
parse(markdown: string, config?: Partial<ArticleMetadata>): ArticleMetadata;
|
|
18
|
-
private normalize;
|
|
19
|
-
private startsNewBlock;
|
|
20
|
-
private makeHeading;
|
|
21
|
-
private makeQuoteOrCallout;
|
|
22
|
-
private makeNote;
|
|
23
|
-
/**
|
|
24
|
-
* Tables are flattened into a header subtitle (if present) followed by one paragraph per
|
|
25
|
-
* data row using `**col[0]:** col[1] · **col[2]:** col[3] …` format. val-article has no
|
|
26
|
-
* native table element so this preserves the information without breaking the layout.
|
|
27
|
-
*/
|
|
28
|
-
private makeTable;
|
|
29
10
|
static ɵfac: i0.ɵɵFactoryDeclaration<MarkdownArticleParserService, never>;
|
|
30
11
|
static ɵprov: i0.ɵɵInjectableDeclaration<MarkdownArticleParserService>;
|
|
31
12
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { HttpClient } from '@angular/common/http';
|
|
2
|
+
import { AuthService } from '../auth/auth.service';
|
|
3
|
+
import { ValtechAuthConfig } from '../auth/types';
|
|
4
|
+
import { FirestoreService } from '../firebase/firestore.service';
|
|
5
|
+
import { I18nService } from '../i18n/i18n.service';
|
|
6
|
+
import { ThemeService } from '../theme.service';
|
|
7
|
+
import { PreferencesLanguage, PreferencesTheme, PreferencesUpdate, PreferencesUpdateResponse } from './preferences.types';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
/**
|
|
10
|
+
* PreferencesService — preferencias del user en el doc canónico Firestore
|
|
11
|
+
* `/apps/{appId}/users/{uid}/preferences/main`.
|
|
12
|
+
*
|
|
13
|
+
* Read reactivo (signals) via listener Firestore.
|
|
14
|
+
* Write via `PUT /v2/auth/preferences` (cliente NUNCA escribe Firestore directo —
|
|
15
|
+
* ver memoria `feedback_no_direct_firestore_writes`).
|
|
16
|
+
*
|
|
17
|
+
* Side-effects automáticos:
|
|
18
|
+
* - Cuando `theme()` cambia → `ThemeService.Theme = ...`
|
|
19
|
+
* - Cuando `language()` cambia → `I18nService.setLanguage(...)`
|
|
20
|
+
*
|
|
21
|
+
* Auto-bind al user actual via `AuthService.user()`. Sin user (logout) → unbind.
|
|
22
|
+
*/
|
|
23
|
+
export declare class PreferencesService {
|
|
24
|
+
private config;
|
|
25
|
+
private firestore;
|
|
26
|
+
private auth;
|
|
27
|
+
private http;
|
|
28
|
+
private themeService;
|
|
29
|
+
private i18n;
|
|
30
|
+
private readonly _theme;
|
|
31
|
+
private readonly _language;
|
|
32
|
+
private readonly _notificationsMaster;
|
|
33
|
+
/** `true` después del primer snapshot Firestore. Antes, defaults sin side-effects. */
|
|
34
|
+
private readonly _synced;
|
|
35
|
+
readonly theme: import("@angular/core").Signal<PreferencesTheme>;
|
|
36
|
+
readonly language: import("@angular/core").Signal<PreferencesLanguage>;
|
|
37
|
+
readonly notificationsMaster: import("@angular/core").Signal<boolean>;
|
|
38
|
+
readonly synced: import("@angular/core").Signal<boolean>;
|
|
39
|
+
private subscription?;
|
|
40
|
+
private currentUserId?;
|
|
41
|
+
constructor(config: ValtechAuthConfig, firestore: FirestoreService, auth: AuthService, http: HttpClient, themeService: ThemeService | null, i18n: I18nService | null);
|
|
42
|
+
/** Actualiza preferencias via backend. Optimistic UI: aplica local, revierte si falla. */
|
|
43
|
+
update(partial: PreferencesUpdate): Promise<PreferencesUpdateResponse>;
|
|
44
|
+
setTheme(theme: PreferencesTheme): Promise<PreferencesUpdateResponse>;
|
|
45
|
+
setLanguage(language: PreferencesLanguage): Promise<PreferencesUpdateResponse>;
|
|
46
|
+
setNotificationsMaster(enabled: boolean): Promise<PreferencesUpdateResponse>;
|
|
47
|
+
private bindToUser;
|
|
48
|
+
private unbind;
|
|
49
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PreferencesService, [null, null, null, null, { optional: true; }, { optional: true; }]>;
|
|
50
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<PreferencesService>;
|
|
51
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preferences types — Fase 1 schema simple (theme + language + notifications.master).
|
|
3
|
+
* Doc canónico: /apps/{appId}/users/{uid}/preferences/main
|
|
4
|
+
* Cliente NUNCA escribe directo — todas las mutaciones via PUT /v2/auth/preferences.
|
|
5
|
+
*/
|
|
6
|
+
export type PreferencesTheme = 'light' | 'dark' | 'auto';
|
|
7
|
+
export type PreferencesLanguage = 'es' | 'en' | 'pt';
|
|
8
|
+
/** Forma del doc tal como lo escribe el backend (Admin SDK). */
|
|
9
|
+
export interface PreferencesDocument {
|
|
10
|
+
theme?: PreferencesTheme;
|
|
11
|
+
language?: PreferencesLanguage;
|
|
12
|
+
notifications?: {
|
|
13
|
+
master?: boolean;
|
|
14
|
+
};
|
|
15
|
+
/** serverTimestamp escrito por el backend en cada sync. */
|
|
16
|
+
syncedAt?: unknown;
|
|
17
|
+
}
|
|
18
|
+
/** Payload aceptado por `PUT /v2/auth/preferences` — partial update. */
|
|
19
|
+
export interface PreferencesUpdate {
|
|
20
|
+
theme?: PreferencesTheme;
|
|
21
|
+
language?: PreferencesLanguage;
|
|
22
|
+
notifications?: {
|
|
23
|
+
master?: boolean;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/** Response del backend tras el PUT. */
|
|
27
|
+
export interface PreferencesUpdateResponse {
|
|
28
|
+
operationId: string;
|
|
29
|
+
theme: PreferencesTheme | '';
|
|
30
|
+
language: PreferencesLanguage | '';
|
|
31
|
+
notifications: {
|
|
32
|
+
master?: boolean;
|
|
33
|
+
};
|
|
34
|
+
updated: boolean;
|
|
35
|
+
}
|
package/lib/version.d.ts
CHANGED
package/package.json
CHANGED
package/public-api.d.ts
CHANGED
|
@@ -239,11 +239,14 @@ export * from './lib/services/qr-generator/types';
|
|
|
239
239
|
export * from './lib/services/modal/modal.service';
|
|
240
240
|
export * from './lib/services/modal/types';
|
|
241
241
|
export * from './lib/services/meta';
|
|
242
|
+
export * from './lib/services/markdown-article/markdown-article-parser';
|
|
242
243
|
export * from './lib/services/markdown-article/markdown-article-parser.service';
|
|
243
244
|
export * from './lib/services/markdown-article/legal-content.service';
|
|
245
|
+
export * from './lib/services/legal-link/legal-link.service';
|
|
244
246
|
export * from './lib/services/firebase';
|
|
245
247
|
export * from './lib/services/auth';
|
|
246
248
|
export * from './lib/services/i18n';
|
|
249
|
+
export * from './lib/services/preferences';
|
|
247
250
|
export * from './lib/services/app-config';
|
|
248
251
|
export * from './lib/services/presets';
|
|
249
252
|
export * from './lib/services/skeleton';
|