valtech-components 2.0.969 → 2.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.
- package/esm2022/lib/components/molecules/content-reaction/content-reaction.component.mjs +2 -1
- package/esm2022/lib/components/organisms/profile-view/profile-view.component.mjs +601 -0
- package/esm2022/lib/components/organisms/profile-view/profile-view.i18n.mjs +75 -0
- package/esm2022/lib/components/organisms/profile-view/profile.routes.mjs +28 -0
- package/esm2022/lib/components/organisms/profile-view/types.mjs +2 -0
- package/esm2022/lib/version.mjs +2 -2
- package/esm2022/public-api.mjs +4 -1
- package/fesm2022/valtech-components.mjs +785 -106
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/organisms/profile-view/profile-view.component.d.ts +84 -0
- package/lib/components/organisms/profile-view/profile-view.i18n.d.ts +12 -0
- package/lib/components/organisms/profile-view/profile.routes.d.ts +23 -0
- package/lib/components/organisms/profile-view/types.d.ts +32 -0
- package/lib/version.d.ts +1 -1
- package/package.json +1 -1
- package/public-api.d.ts +3 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { AvatarUploadError, AvatarUploadMetadata, AvatarUploadResult } from '../avatar-upload/types';
|
|
2
|
+
import { EmptyStateMetadata } from '../../molecules/empty-state/types';
|
|
3
|
+
import { FormMetadata, FormSubmit } from '../../types';
|
|
4
|
+
import { GetProfileResponse } from '../../../services/auth/types';
|
|
5
|
+
import { ProfileViewConfig } from './types';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
/**
|
|
8
|
+
* `val-profile-view` — vista Perfil full-feature autocontenida (organism).
|
|
9
|
+
*
|
|
10
|
+
* Edita los campos públicos del usuario en UN solo formulario con UN solo botón
|
|
11
|
+
* "Guardar". Wireup:
|
|
12
|
+
* - Avatar — val-avatar-upload (Firebase Storage + backend sync). Separado del
|
|
13
|
+
* form porque es upload sync independiente.
|
|
14
|
+
* - Handle (@usuario) — InputType.HANDLE (val-username-input con check de
|
|
15
|
+
* disponibilidad async resuelto vía AuthService inyectado).
|
|
16
|
+
* - Nombre — InputType.TEXT.
|
|
17
|
+
* - Teléfono — InputType.PHONE.
|
|
18
|
+
*
|
|
19
|
+
* Submit handler dispatcha:
|
|
20
|
+
* 1. Si handle cambió → updateHandle PRIMERO (uniqueness).
|
|
21
|
+
* 2. Si name o phone cambió → updateProfile con ambos.
|
|
22
|
+
*
|
|
23
|
+
* Lectura del perfil: suscribe al doc Firestore /users/{uid} (mirror que mantiene
|
|
24
|
+
* el backend). Reactivo cross-tab + auto-refresca tras save. Fallback REST
|
|
25
|
+
* (auth.getProfile) si el doc no existe o el listener falla.
|
|
26
|
+
*
|
|
27
|
+
* NO renderiza ion-content — vive dentro de val-page-wrapper.
|
|
28
|
+
*
|
|
29
|
+
* Auto-registra sus defaults i18n (es/en) en el constructor si el consumer no
|
|
30
|
+
* proveyó el namespace configurado (default `Settings.Profile`).
|
|
31
|
+
*/
|
|
32
|
+
export declare class ProfileViewComponent {
|
|
33
|
+
private nav;
|
|
34
|
+
private auth;
|
|
35
|
+
private i18n;
|
|
36
|
+
private toast;
|
|
37
|
+
private errors;
|
|
38
|
+
private firebase;
|
|
39
|
+
private collections;
|
|
40
|
+
private route;
|
|
41
|
+
/**
|
|
42
|
+
* Config vía @Input (object-first). Si no se pasa, se cae al route data
|
|
43
|
+
* `profileConfig` (poblado por `provideValtechProfileRoutes`). `resolvedConfig`
|
|
44
|
+
* mergea con los defaults.
|
|
45
|
+
*/
|
|
46
|
+
config?: ProfileViewConfig;
|
|
47
|
+
/** Config mergeada con defaults. @Input gana sobre route data. */
|
|
48
|
+
readonly resolvedConfig: import("@angular/core").Signal<Required<Omit<ProfileViewConfig, "onSaved" | "onAvatarUploaded">> & Pick<ProfileViewConfig, "onSaved" | "onAvatarUploaded">>;
|
|
49
|
+
/** Namespace i18n resuelto (capturado una vez para llamadas no-reactivas). */
|
|
50
|
+
private get ns();
|
|
51
|
+
/**
|
|
52
|
+
* Colección global /users/{uid} (skipAppPrefix: true — el doc vive fuera de
|
|
53
|
+
* apps/{appId}/... porque es cross-app, ver firestore.rules).
|
|
54
|
+
*/
|
|
55
|
+
private usersCol;
|
|
56
|
+
private formCmp;
|
|
57
|
+
readonly profile: import("@angular/core").WritableSignal<GetProfileResponse>;
|
|
58
|
+
readonly loading: import("@angular/core").WritableSignal<boolean>;
|
|
59
|
+
readonly saving: import("@angular/core").WritableSignal<boolean>;
|
|
60
|
+
readonly loadError: import("@angular/core").WritableSignal<unknown>;
|
|
61
|
+
private readonly _userId;
|
|
62
|
+
readonly errorState: import("@angular/core").Signal<EmptyStateMetadata>;
|
|
63
|
+
readonly avatarProps: import("@angular/core").Signal<AvatarUploadMetadata>;
|
|
64
|
+
formMeta: FormMetadata;
|
|
65
|
+
constructor();
|
|
66
|
+
/** Construcción inicial — UNA vez. Gatea handle/phone según config. */
|
|
67
|
+
private buildFormMeta;
|
|
68
|
+
/** Re-aplica labels/hints/placeholders en cambio de idioma. */
|
|
69
|
+
private applyI18nLabels;
|
|
70
|
+
/**
|
|
71
|
+
* Fallback REST. Capa 4 (UI declarativa): NO toasteamos acá — el
|
|
72
|
+
* val-empty-state ES la UI del error.
|
|
73
|
+
*/
|
|
74
|
+
private loadFromApi;
|
|
75
|
+
private mapMirrorToProfile;
|
|
76
|
+
onSubmit(event: FormSubmit): Promise<void>;
|
|
77
|
+
onAvatarUploaded(result: AvatarUploadResult): void;
|
|
78
|
+
onAvatarError(_err: AvatarUploadError): void;
|
|
79
|
+
/** Lee del namespace configurado. */
|
|
80
|
+
protected t(key: string): string;
|
|
81
|
+
private initialsFromName;
|
|
82
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ProfileViewComponent, never>;
|
|
83
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ProfileViewComponent, "val-profile-view", never, { "config": { "alias": "config"; "required": false; }; }, {}, never, never, true, never>;
|
|
84
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { LanguagesContent } from '../../../services/i18n/types';
|
|
2
|
+
/**
|
|
3
|
+
* Defaults i18n (es/en) embebidos en `val-profile-view`. Auto-registrados en el
|
|
4
|
+
* constructor del componente si el consumer no proveyó el namespace
|
|
5
|
+
* (`Settings.Profile` por default). Garantiza que nunca haya una key faltante
|
|
6
|
+
* evaluada por cada change-detection (ver nota en valtech-components/CLAUDE.md
|
|
7
|
+
* sobre el storm de CD con `val-debug-console`). El consumer puede override
|
|
8
|
+
* registrando el mismo namespace antes de que el componente monte.
|
|
9
|
+
*
|
|
10
|
+
* SOLO incluye las keys que la vista realmente usa.
|
|
11
|
+
*/
|
|
12
|
+
export declare const PROFILE_VIEW_I18N: LanguagesContent;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Routes } from '@angular/router';
|
|
2
|
+
import { ProfileViewConfig } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Helper para montar la vista Perfil (`val-profile-view`) como ruta en una app
|
|
5
|
+
* del factory. El `config` se pasa por route `data` (`profileConfig`) y el
|
|
6
|
+
* componente lo lee como fallback de su `@Input() config`.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* // settings.routes.ts
|
|
11
|
+
* export const settingsRoutes: Routes = [
|
|
12
|
+
* ...provideValtechProfileRoutes(),
|
|
13
|
+
* { path: 'preferences', loadComponent: () => ... },
|
|
14
|
+
* ];
|
|
15
|
+
*
|
|
16
|
+
* // con config acotada:
|
|
17
|
+
* ...provideValtechProfileRoutes({ config: { showPhone: false } }),
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function provideValtechProfileRoutes(opts?: {
|
|
21
|
+
path?: string;
|
|
22
|
+
config?: ProfileViewConfig;
|
|
23
|
+
}): Routes;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { GetProfileResponse } from '../../../services/auth/types';
|
|
2
|
+
import { AvatarUploadResult } from '../avatar-upload/types';
|
|
3
|
+
/**
|
|
4
|
+
* Configuración acotada de `val-profile-view` (object-first). Ejes permitidos:
|
|
5
|
+
* - **secciones visibles** — gatean el render del avatar y de los campos
|
|
6
|
+
* handle/phone del formulario.
|
|
7
|
+
* - **branding** — `i18nNamespace` para resolver los textos (default
|
|
8
|
+
* `'Settings.Profile'`). El consumer puede registrar ese namespace para
|
|
9
|
+
* override de los defaults embebidos.
|
|
10
|
+
* - **callbacks** — hooks tras un save / avatar exitoso (además de los toasts
|
|
11
|
+
* internos).
|
|
12
|
+
*
|
|
13
|
+
* NO admite slots arbitrarios ni override del layout: la vista es full-feature
|
|
14
|
+
* y autocontenida.
|
|
15
|
+
*/
|
|
16
|
+
export interface ProfileViewConfig {
|
|
17
|
+
/** Muestra la sección de avatar (upload + meta). Default `true`. */
|
|
18
|
+
showAvatar?: boolean;
|
|
19
|
+
/** Incluye el campo `handle` (@usuario) en el formulario. Default `true`. */
|
|
20
|
+
showHandle?: boolean;
|
|
21
|
+
/** Incluye el campo `phone` en el formulario. Default `true`. */
|
|
22
|
+
showPhone?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Namespace i18n con el que la vista resuelve sus textos.
|
|
25
|
+
* Default `'Settings.Profile'`.
|
|
26
|
+
*/
|
|
27
|
+
i18nNamespace?: string;
|
|
28
|
+
/** Callback tras un guardado de perfil exitoso. */
|
|
29
|
+
onSaved?: (profile: GetProfileResponse) => void;
|
|
30
|
+
/** Callback tras subir/actualizar el avatar exitosamente. */
|
|
31
|
+
onAvatarUploaded?: (result: AvatarUploadResult) => void;
|
|
32
|
+
}
|
package/lib/version.d.ts
CHANGED
package/package.json
CHANGED
package/public-api.d.ts
CHANGED
|
@@ -263,6 +263,9 @@ export * from './lib/components/organisms/bottom-nav/bottom-nav.component';
|
|
|
263
263
|
export * from './lib/components/organisms/bottom-nav/types';
|
|
264
264
|
export * from './lib/components/organisms/avatar-upload/avatar-upload.component';
|
|
265
265
|
export * from './lib/components/organisms/avatar-upload/types';
|
|
266
|
+
export * from './lib/components/organisms/profile-view/profile-view.component';
|
|
267
|
+
export * from './lib/components/organisms/profile-view/types';
|
|
268
|
+
export * from './lib/components/organisms/profile-view/profile.routes';
|
|
266
269
|
export * from './lib/components/organisms/skeleton-layout/skeleton-layout.component';
|
|
267
270
|
export * from './lib/components/organisms/skeleton-layout/types';
|
|
268
271
|
export * from './lib/components/organisms/faq/faq.component';
|