valtech-components 2.0.506 → 2.0.508
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/atoms/qr-code/qr-code.component.mjs +6 -4
- package/esm2022/lib/components/molecules/ad-slot/ad-slot.component.mjs +96 -39
- package/esm2022/lib/components/molecules/code-display/code-display.component.mjs +4 -2
- package/esm2022/lib/components/molecules/date-input/date-input.component.mjs +18 -7
- package/esm2022/lib/components/molecules/date-range-input/date-range-input.component.mjs +41 -16
- package/esm2022/lib/components/molecules/file-input/file-input.component.mjs +17 -6
- package/esm2022/lib/components/molecules/language-selector/language-selector.component.mjs +5 -5
- package/esm2022/lib/components/molecules/multi-select-search/multi-select-search.component.mjs +53 -27
- package/esm2022/lib/components/molecules/participant-card/participant-card.component.mjs +28 -10
- package/esm2022/lib/components/molecules/popover-selector/popover-selector.component.mjs +8 -6
- package/esm2022/lib/components/molecules/searchbar/searchbar.component.mjs +21 -7
- package/esm2022/lib/components/molecules/select-input/select-input.component.mjs +11 -7
- package/esm2022/lib/components/molecules/select-search/select-search.component.mjs +21 -7
- package/esm2022/lib/components/organisms/data-table/data-table.component.mjs +52 -17
- package/esm2022/lib/services/i18n/config.mjs +64 -4
- package/esm2022/lib/services/i18n/default-content.mjs +203 -0
- package/esm2022/lib/services/i18n/index.mjs +3 -1
- package/esm2022/lib/services/i18n/types.mjs +2 -1
- package/fesm2022/valtech-components.mjs +1180 -708
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/atoms/qr-code/qr-code.component.d.ts +1 -0
- package/lib/components/molecules/ad-slot/ad-slot.component.d.ts +5 -0
- package/lib/components/molecules/code-display/code-display.component.d.ts +2 -2
- package/lib/components/molecules/date-input/date-input.component.d.ts +5 -0
- package/lib/components/molecules/date-range-input/date-range-input.component.d.ts +11 -0
- package/lib/components/molecules/file-input/file-input.component.d.ts +3 -0
- package/lib/components/molecules/multi-select-search/multi-select-search.component.d.ts +13 -0
- package/lib/components/molecules/participant-card/participant-card.component.d.ts +9 -0
- package/lib/components/molecules/popover-selector/popover-selector.component.d.ts +1 -0
- package/lib/components/molecules/searchbar/searchbar.component.d.ts +14 -1
- package/lib/components/molecules/select-input/select-input.component.d.ts +1 -0
- package/lib/components/molecules/select-search/select-search.component.d.ts +7 -0
- package/lib/components/organisms/article/article.component.d.ts +1 -1
- package/lib/components/organisms/data-table/data-table.component.d.ts +17 -2
- package/lib/services/i18n/default-content.d.ts +30 -0
- package/lib/services/i18n/index.d.ts +1 -0
- package/lib/services/i18n/types.d.ts +35 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { EventEmitter, Component, Input, Output, Injectable, signal, makeEnvironmentProviders, APP_INITIALIZER, inject, HostListener, Pipe, ChangeDetectionStrategy,
|
|
2
|
+
import { EventEmitter, Component, Input, Output, Injectable, signal, makeEnvironmentProviders, APP_INITIALIZER, inject, HostListener, Pipe, ChangeDetectionStrategy, computed, ViewChild, ChangeDetectorRef, ElementRef, PLATFORM_ID, Inject, ErrorHandler, DestroyRef, InjectionToken, Optional, runInInjectionContext, effect } from '@angular/core';
|
|
3
3
|
import * as i2$1 from '@ionic/angular/standalone';
|
|
4
4
|
import { IonAvatar, IonCard, IonIcon, IonButton, IonSpinner, IonText, IonModal, IonHeader, IonToolbar, IonContent, IonButtons, IonTitle, IonProgressBar, IonSkeletonText, IonFab, IonFabButton, IonFabList, IonLabel, IonCardContent, IonCardHeader, IonCardTitle, IonCardSubtitle, IonCheckbox, IonTextarea, IonDatetime, IonDatetimeButton, IonInput, IonSelect, IonSelectOption, IonPopover, IonList, IonItem, IonRadioGroup, IonRadio, IonRange, IonSearchbar, IonSegment, IonSegmentButton, IonToggle, IonAccordion, IonAccordionGroup, IonTabBar, IonTabButton, IonBadge, IonBreadcrumb, IonBreadcrumbs, IonChip, IonNote, ToastController as ToastController$1, IonCol, IonRow, IonMenuButton, IonFooter, IonListHeader, IonInfiniteScroll, IonInfiniteScrollContent, IonGrid, MenuController, IonMenu, IonMenuToggle, AlertController } from '@ionic/angular/standalone';
|
|
5
5
|
import * as i1 from '@angular/common';
|
|
@@ -3120,136 +3120,703 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
3120
3120
|
}]
|
|
3121
3121
|
}] });
|
|
3122
3122
|
|
|
3123
|
-
addIcons({ downloadOutline, copyOutline, shareOutline });
|
|
3124
3123
|
/**
|
|
3125
|
-
*
|
|
3124
|
+
* Valores por defecto de configuración
|
|
3125
|
+
*/
|
|
3126
|
+
const DEFAULT_I18N_CONFIG = {
|
|
3127
|
+
defaultLanguage: 'es',
|
|
3128
|
+
supportedLanguages: ['es', 'en'],
|
|
3129
|
+
detectBrowserLanguage: true,
|
|
3130
|
+
content: {},
|
|
3131
|
+
includeDefaultContent: true,
|
|
3132
|
+
};
|
|
3133
|
+
/**
|
|
3134
|
+
* Clave para persistir idioma en localStorage
|
|
3135
|
+
*/
|
|
3136
|
+
const LANG_STORAGE_KEY$1 = 'app_lang';
|
|
3137
|
+
|
|
3138
|
+
/**
|
|
3139
|
+
* Servicio de internacionalización basado en Angular Signals.
|
|
3126
3140
|
*
|
|
3127
|
-
*
|
|
3128
|
-
*
|
|
3141
|
+
* Características:
|
|
3142
|
+
* - Sin RxJS: usa Signals para evitar memory leaks y congelamiento
|
|
3143
|
+
* - Namespace-based: organiza traducciones por contexto
|
|
3144
|
+
* - Fallback multi-nivel: namespace → _global → placeholder
|
|
3145
|
+
* - Interpolación: soporta {variable} en textos
|
|
3129
3146
|
*
|
|
3130
|
-
* @example
|
|
3131
|
-
*
|
|
3132
|
-
*
|
|
3133
|
-
* ```
|
|
3134
|
-
* ```html
|
|
3135
|
-
* <val-qr-code [props]="{ qr: qr }"></val-qr-code>
|
|
3136
|
-
* ```
|
|
3147
|
+
* @example
|
|
3148
|
+
* // En un componente
|
|
3149
|
+
* i18n = inject(I18nService);
|
|
3137
3150
|
*
|
|
3138
|
-
*
|
|
3139
|
-
*
|
|
3140
|
-
* <val-qr-code
|
|
3141
|
-
* [props]="{
|
|
3142
|
-
* qr: qr,
|
|
3143
|
-
* showDownload: true,
|
|
3144
|
-
* showCopy: true,
|
|
3145
|
-
* showShare: true,
|
|
3146
|
-
* displaySize: 200,
|
|
3147
|
-
* showBorder: true,
|
|
3148
|
-
* borderRadius: 12
|
|
3149
|
-
* }"
|
|
3150
|
-
* (actionComplete)="onAction($event)"
|
|
3151
|
-
* ></val-qr-code>
|
|
3152
|
-
* ```
|
|
3151
|
+
* // Obtener texto
|
|
3152
|
+
* const title = this.i18n.t('title', 'Login');
|
|
3153
3153
|
*
|
|
3154
|
-
*
|
|
3155
|
-
*
|
|
3156
|
-
*
|
|
3157
|
-
*
|
|
3154
|
+
* // Con interpolación
|
|
3155
|
+
* const welcome = this.i18n.t('welcome', 'Login', { name: 'Juan' });
|
|
3156
|
+
*
|
|
3157
|
+
* // Cambiar idioma
|
|
3158
|
+
* this.i18n.setLanguage('en');
|
|
3158
3159
|
*/
|
|
3159
|
-
class
|
|
3160
|
+
class I18nService {
|
|
3160
3161
|
constructor() {
|
|
3161
|
-
|
|
3162
|
-
this.
|
|
3163
|
-
this.
|
|
3164
|
-
this.
|
|
3165
|
-
|
|
3166
|
-
this.
|
|
3162
|
+
// Estado interno con Signals
|
|
3163
|
+
this._lang = signal(DEFAULT_I18N_CONFIG.defaultLanguage);
|
|
3164
|
+
this._content = signal({});
|
|
3165
|
+
this._supportedLanguages = signal(DEFAULT_I18N_CONFIG.supportedLanguages);
|
|
3166
|
+
// Públicos readonly
|
|
3167
|
+
this.lang = this._lang.asReadonly();
|
|
3168
|
+
this.supportedLanguages = this._supportedLanguages.asReadonly();
|
|
3169
|
+
// Computed para verificaciones rápidas
|
|
3170
|
+
this.isSpanish = computed(() => this._lang() === 'es');
|
|
3171
|
+
this.isEnglish = computed(() => this._lang() === 'en');
|
|
3172
|
+
this.loadStoredLanguage();
|
|
3167
3173
|
}
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3174
|
+
/**
|
|
3175
|
+
* Obtiene texto traducido (alias corto de getText)
|
|
3176
|
+
*
|
|
3177
|
+
* @param key Clave del texto
|
|
3178
|
+
* @param namespace Namespace (default: '_global')
|
|
3179
|
+
* @param data Variables para interpolación
|
|
3180
|
+
* @returns Texto traducido o placeholder [namespace.key]
|
|
3181
|
+
*
|
|
3182
|
+
* @example
|
|
3183
|
+
* i18n.t('submit'); // busca en _global
|
|
3184
|
+
* i18n.t('title', 'Login'); // busca en Login
|
|
3185
|
+
* i18n.t('welcome', 'Login', {name}); // con interpolación
|
|
3186
|
+
*/
|
|
3187
|
+
t(key, namespace, data) {
|
|
3188
|
+
return this.getText(key, namespace, data);
|
|
3171
3189
|
}
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3190
|
+
/**
|
|
3191
|
+
* Obtiene texto traducido
|
|
3192
|
+
*
|
|
3193
|
+
* Fallback order:
|
|
3194
|
+
* 1. content[namespace][lang][key]
|
|
3195
|
+
* 2. content['_global'][lang][key]
|
|
3196
|
+
* 3. "[namespace.key]" (placeholder)
|
|
3197
|
+
*/
|
|
3198
|
+
getText(key, namespace, data) {
|
|
3199
|
+
const content = this._content();
|
|
3200
|
+
const lang = this._lang();
|
|
3201
|
+
const ns = namespace || '_global';
|
|
3202
|
+
// Buscar en namespace específico
|
|
3203
|
+
let text = content[ns]?.[lang]?.[key];
|
|
3204
|
+
// Fallback a _global
|
|
3205
|
+
if (!text && ns !== '_global') {
|
|
3206
|
+
text = content['_global']?.[lang]?.[key];
|
|
3175
3207
|
}
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
}
|
|
3181
|
-
getPadding() {
|
|
3182
|
-
return this.props.padding ? `${this.props.padding}px` : '0';
|
|
3183
|
-
}
|
|
3184
|
-
getQrBorderRadius() {
|
|
3185
|
-
return this.props.qrBorderRadius ? `${this.props.qrBorderRadius}px` : '0';
|
|
3186
|
-
}
|
|
3187
|
-
getContainerClasses() {
|
|
3188
|
-
const classes = [];
|
|
3189
|
-
if (this.props.cssClass)
|
|
3190
|
-
classes.push(this.props.cssClass);
|
|
3191
|
-
if (this.props.showBorder)
|
|
3192
|
-
classes.push('with-border');
|
|
3193
|
-
if (this.props.loading)
|
|
3194
|
-
classes.push('loading');
|
|
3195
|
-
if (this.props.theme)
|
|
3196
|
-
classes.push(`theme--${this.props.theme}`);
|
|
3197
|
-
if (this.props.pulseOnHover)
|
|
3198
|
-
classes.push('pulse-on-hover');
|
|
3199
|
-
if (this.props.scaleOnHover)
|
|
3200
|
-
classes.push('scale-on-hover');
|
|
3201
|
-
if (this.props.gradient)
|
|
3202
|
-
classes.push('has-gradient');
|
|
3203
|
-
return classes.join(' ');
|
|
3204
|
-
}
|
|
3205
|
-
getContainerBackground() {
|
|
3206
|
-
if (this.props.gradient) {
|
|
3207
|
-
const { from, to, via, direction = 'to-bottom' } = this.props.gradient;
|
|
3208
|
-
const cssDirection = direction.replace(/-/g, ' ');
|
|
3209
|
-
if (via) {
|
|
3210
|
-
return `linear-gradient(${cssDirection}, ${from}, ${via}, ${to})`;
|
|
3211
|
-
}
|
|
3212
|
-
return `linear-gradient(${cssDirection}, ${from}, ${to})`;
|
|
3208
|
+
// Fallback a placeholder
|
|
3209
|
+
if (!text) {
|
|
3210
|
+
console.warn(`[i18n] Missing translation: ${ns}.${key} (${lang})`);
|
|
3211
|
+
return `[${ns}.${key}]`;
|
|
3213
3212
|
}
|
|
3214
|
-
|
|
3213
|
+
// Aplicar interpolación si hay data
|
|
3214
|
+
if (data) {
|
|
3215
|
+
return this.interpolate(text, data);
|
|
3216
|
+
}
|
|
3217
|
+
return text;
|
|
3215
3218
|
}
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
return
|
|
3226
|
-
|
|
3219
|
+
/**
|
|
3220
|
+
* Cambia el idioma de la aplicación
|
|
3221
|
+
*
|
|
3222
|
+
* @param lang Nuevo idioma
|
|
3223
|
+
* @param forceReload Si true, recarga la página (fallback si reactividad falla)
|
|
3224
|
+
*/
|
|
3225
|
+
setLanguage(lang, forceReload = false) {
|
|
3226
|
+
if (!this._supportedLanguages().includes(lang)) {
|
|
3227
|
+
console.warn(`[i18n] Language '${lang}' not in supported languages`);
|
|
3228
|
+
return;
|
|
3229
|
+
}
|
|
3230
|
+
if (lang === this._lang()) {
|
|
3231
|
+
return;
|
|
3232
|
+
}
|
|
3233
|
+
// Persistir en localStorage
|
|
3234
|
+
localStorage.setItem(LANG_STORAGE_KEY$1, lang);
|
|
3235
|
+
// Actualizar signal
|
|
3236
|
+
this._lang.set(lang);
|
|
3237
|
+
// Fallback: recargar si se solicita
|
|
3238
|
+
if (forceReload) {
|
|
3239
|
+
window.location.reload();
|
|
3240
|
+
}
|
|
3227
3241
|
}
|
|
3228
|
-
|
|
3229
|
-
|
|
3242
|
+
/**
|
|
3243
|
+
* Registra contenido de traducciones para un namespace
|
|
3244
|
+
*
|
|
3245
|
+
* @param namespace Nombre del namespace
|
|
3246
|
+
* @param content Contenido de traducciones
|
|
3247
|
+
*
|
|
3248
|
+
* @example
|
|
3249
|
+
* i18n.registerContent('Login', {
|
|
3250
|
+
* es: { title: 'Iniciar sesión' },
|
|
3251
|
+
* en: { title: 'Sign in' }
|
|
3252
|
+
* });
|
|
3253
|
+
*/
|
|
3254
|
+
registerContent(namespace, content) {
|
|
3255
|
+
this._content.update((store) => ({
|
|
3256
|
+
...store,
|
|
3257
|
+
[namespace]: content,
|
|
3258
|
+
}));
|
|
3230
3259
|
}
|
|
3231
|
-
|
|
3232
|
-
|
|
3260
|
+
/**
|
|
3261
|
+
* Registra múltiples namespaces de una vez
|
|
3262
|
+
*
|
|
3263
|
+
* @param contentStore Objeto con namespaces como keys
|
|
3264
|
+
*/
|
|
3265
|
+
registerContentBulk(contentStore) {
|
|
3266
|
+
this._content.update((store) => ({
|
|
3267
|
+
...store,
|
|
3268
|
+
...contentStore,
|
|
3269
|
+
}));
|
|
3233
3270
|
}
|
|
3234
|
-
|
|
3235
|
-
|
|
3271
|
+
/**
|
|
3272
|
+
* Configura los idiomas soportados
|
|
3273
|
+
*/
|
|
3274
|
+
setI18nLanguages(languages) {
|
|
3275
|
+
this._supportedLanguages.set(languages);
|
|
3236
3276
|
}
|
|
3237
|
-
|
|
3238
|
-
|
|
3277
|
+
/**
|
|
3278
|
+
* Obtiene todos los namespaces registrados
|
|
3279
|
+
*/
|
|
3280
|
+
getNamespaces() {
|
|
3281
|
+
return Object.keys(this._content());
|
|
3239
3282
|
}
|
|
3240
|
-
|
|
3241
|
-
|
|
3283
|
+
/**
|
|
3284
|
+
* Verifica si un namespace tiene traducciones
|
|
3285
|
+
*/
|
|
3286
|
+
hasNamespace(namespace) {
|
|
3287
|
+
return namespace in this._content();
|
|
3242
3288
|
}
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
this.
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3289
|
+
/**
|
|
3290
|
+
* Carga idioma guardado en localStorage o detecta del navegador
|
|
3291
|
+
*/
|
|
3292
|
+
loadStoredLanguage() {
|
|
3293
|
+
const stored = localStorage.getItem(LANG_STORAGE_KEY$1);
|
|
3294
|
+
if (stored && this.isValidLanguage(stored)) {
|
|
3295
|
+
this._lang.set(stored);
|
|
3296
|
+
return;
|
|
3297
|
+
}
|
|
3298
|
+
// Detectar idioma del navegador
|
|
3299
|
+
const browserLang = navigator.language.split('-')[0];
|
|
3300
|
+
if (this.isValidLanguage(browserLang)) {
|
|
3301
|
+
this._lang.set(browserLang);
|
|
3302
|
+
localStorage.setItem(LANG_STORAGE_KEY$1, browserLang);
|
|
3303
|
+
}
|
|
3304
|
+
}
|
|
3305
|
+
/**
|
|
3306
|
+
* Valida si un idioma está soportado
|
|
3307
|
+
*/
|
|
3308
|
+
isValidLanguage(lang) {
|
|
3309
|
+
return this._supportedLanguages().includes(lang);
|
|
3310
|
+
}
|
|
3311
|
+
/**
|
|
3312
|
+
* Reemplaza {variable} en texto con valores de data
|
|
3313
|
+
*
|
|
3314
|
+
* @example
|
|
3315
|
+
* interpolate('Hola {name}', { name: 'Juan' }) // 'Hola Juan'
|
|
3316
|
+
*/
|
|
3317
|
+
interpolate(text, data) {
|
|
3318
|
+
return Object.entries(data).reduce((result, [key, value]) => {
|
|
3319
|
+
const regex = new RegExp(`\\{${key}\\}`, 'g');
|
|
3320
|
+
return result.replace(regex, value);
|
|
3321
|
+
}, text);
|
|
3322
|
+
}
|
|
3323
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: I18nService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
3324
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: I18nService, providedIn: 'root' }); }
|
|
3325
|
+
}
|
|
3326
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: I18nService, decorators: [{
|
|
3327
|
+
type: Injectable,
|
|
3328
|
+
args: [{ providedIn: 'root' }]
|
|
3329
|
+
}], ctorParameters: () => [] });
|
|
3330
|
+
|
|
3331
|
+
/**
|
|
3332
|
+
* Pipe de traducción para templates.
|
|
3333
|
+
*
|
|
3334
|
+
* NOTA: Es impure para detectar cambios de idioma.
|
|
3335
|
+
* El costo es mínimo porque I18nService usa Signals internamente.
|
|
3336
|
+
*
|
|
3337
|
+
* @example
|
|
3338
|
+
* <!-- Busca en _global -->
|
|
3339
|
+
* {{ 'submit' | t }}
|
|
3340
|
+
*
|
|
3341
|
+
* <!-- Busca en namespace específico -->
|
|
3342
|
+
* {{ 'title' | t:'Login' }}
|
|
3343
|
+
*
|
|
3344
|
+
* <!-- Con interpolación -->
|
|
3345
|
+
* {{ 'welcome' | t:'Login':{ name: userName } }}
|
|
3346
|
+
*
|
|
3347
|
+
* <!-- En atributos -->
|
|
3348
|
+
* <val-button [label]="'submit' | t"></val-button>
|
|
3349
|
+
* <val-input [label]="'email' | t:'Login'"></val-input>
|
|
3350
|
+
*/
|
|
3351
|
+
class TranslatePipe {
|
|
3352
|
+
constructor() {
|
|
3353
|
+
this.i18n = inject(I18nService);
|
|
3354
|
+
}
|
|
3355
|
+
/**
|
|
3356
|
+
* Transforma una key de traducción a su valor
|
|
3357
|
+
*
|
|
3358
|
+
* @param key Clave del texto
|
|
3359
|
+
* @param namespace Namespace opcional (default: '_global')
|
|
3360
|
+
* @param data Variables para interpolación opcional
|
|
3361
|
+
* @returns Texto traducido
|
|
3362
|
+
*/
|
|
3363
|
+
transform(key, namespace, data) {
|
|
3364
|
+
return this.i18n.t(key, namespace, data);
|
|
3365
|
+
}
|
|
3366
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TranslatePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
3367
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: TranslatePipe, isStandalone: true, name: "t", pure: false }); }
|
|
3368
|
+
}
|
|
3369
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TranslatePipe, decorators: [{
|
|
3370
|
+
type: Pipe,
|
|
3371
|
+
args: [{
|
|
3372
|
+
name: 't',
|
|
3373
|
+
standalone: true,
|
|
3374
|
+
pure: false, // Impure para detectar cambios de idioma
|
|
3375
|
+
}]
|
|
3376
|
+
}] });
|
|
3377
|
+
|
|
3378
|
+
/**
|
|
3379
|
+
* Traducciones por defecto de valtech-components.
|
|
3380
|
+
*
|
|
3381
|
+
* Estas traducciones se cargan automáticamente cuando se usa provideValtechI18n()
|
|
3382
|
+
* sin necesidad de configuración adicional.
|
|
3383
|
+
*
|
|
3384
|
+
* Las apps pueden sobrescribir cualquier key pasando su propio content:
|
|
3385
|
+
*
|
|
3386
|
+
* @example Sobrescribir traducciones específicas
|
|
3387
|
+
* ```typescript
|
|
3388
|
+
* provideValtechI18n({
|
|
3389
|
+
* content: {
|
|
3390
|
+
* _global: {
|
|
3391
|
+
* es: { success: '¡Lo hicimos!' }, // Sobrescribe solo esta key
|
|
3392
|
+
* en: { success: 'We did it!' },
|
|
3393
|
+
* },
|
|
3394
|
+
* },
|
|
3395
|
+
* })
|
|
3396
|
+
* ```
|
|
3397
|
+
*
|
|
3398
|
+
* @example Desactivar traducciones por defecto
|
|
3399
|
+
* ```typescript
|
|
3400
|
+
* provideValtechI18n({
|
|
3401
|
+
* includeDefaultContent: false,
|
|
3402
|
+
* content: MY_CUSTOM_CONTENT,
|
|
3403
|
+
* })
|
|
3404
|
+
* ```
|
|
3405
|
+
*/
|
|
3406
|
+
const VALTECH_DEFAULT_CONTENT = {
|
|
3407
|
+
_global: {
|
|
3408
|
+
es: {
|
|
3409
|
+
// Acciones comunes
|
|
3410
|
+
submit: 'Enviar',
|
|
3411
|
+
cancel: 'Cancelar',
|
|
3412
|
+
save: 'Guardar',
|
|
3413
|
+
delete: 'Eliminar',
|
|
3414
|
+
edit: 'Editar',
|
|
3415
|
+
close: 'Cerrar',
|
|
3416
|
+
back: 'Volver',
|
|
3417
|
+
next: 'Siguiente',
|
|
3418
|
+
previous: 'Anterior',
|
|
3419
|
+
loading: 'Cargando...',
|
|
3420
|
+
search: 'Buscar',
|
|
3421
|
+
learnMore: 'Saber más',
|
|
3422
|
+
// Estados
|
|
3423
|
+
success: 'Éxito',
|
|
3424
|
+
error: 'Error',
|
|
3425
|
+
warning: 'Advertencia',
|
|
3426
|
+
info: 'Información',
|
|
3427
|
+
// Confirmaciones
|
|
3428
|
+
confirmDelete: '¿Estás seguro de que deseas eliminar?',
|
|
3429
|
+
confirmCancel: '¿Estás seguro de que deseas cancelar?',
|
|
3430
|
+
// Mensajes comunes
|
|
3431
|
+
noResults: 'No se encontraron resultados',
|
|
3432
|
+
required: 'Este campo es requerido',
|
|
3433
|
+
// Navegación
|
|
3434
|
+
home: 'Inicio',
|
|
3435
|
+
settings: 'Configuración',
|
|
3436
|
+
profile: 'Perfil',
|
|
3437
|
+
logout: 'Cerrar sesión',
|
|
3438
|
+
// Idiomas
|
|
3439
|
+
languageName_es: 'Español',
|
|
3440
|
+
languageName_en: 'English',
|
|
3441
|
+
// Componentes - Modales/Selects
|
|
3442
|
+
ok: 'Aceptar',
|
|
3443
|
+
selectOption: 'Seleccionar opción',
|
|
3444
|
+
selectPlaceholder: 'Seleccionar...',
|
|
3445
|
+
itemsSelected: 'elementos seleccionados',
|
|
3446
|
+
selectAll: 'Seleccionar todos',
|
|
3447
|
+
clear: 'Limpiar',
|
|
3448
|
+
apply: 'Aplicar',
|
|
3449
|
+
// Componentes - Fechas
|
|
3450
|
+
startDate: 'Fecha inicio',
|
|
3451
|
+
endDate: 'Fecha fin',
|
|
3452
|
+
day: 'día',
|
|
3453
|
+
days: 'días',
|
|
3454
|
+
// Componentes - Formularios
|
|
3455
|
+
uploadFile: 'Subir archivo',
|
|
3456
|
+
noFileSelected: 'No has seleccionado archivo',
|
|
3457
|
+
title: 'Título',
|
|
3458
|
+
description: 'Descripción',
|
|
3459
|
+
feedbackType: 'Tipo de feedback',
|
|
3460
|
+
feedbackSuccess: 'Feedback enviado exitosamente',
|
|
3461
|
+
feedbackError: 'Error al enviar el feedback',
|
|
3462
|
+
// Componentes - Búsqueda/Grid
|
|
3463
|
+
searchNumber: 'Buscar número...',
|
|
3464
|
+
selected: 'seleccionado/s',
|
|
3465
|
+
max: 'máx:',
|
|
3466
|
+
// Componentes - Listas
|
|
3467
|
+
loadMoreComments: 'Cargar más comentarios',
|
|
3468
|
+
noData: 'No hay datos',
|
|
3469
|
+
noRecordsFound: 'No se encontraron registros para mostrar.',
|
|
3470
|
+
// Componentes - Acciones
|
|
3471
|
+
copiedToClipboard: '¡Copiado al portapapeles!',
|
|
3472
|
+
language: 'Idioma',
|
|
3473
|
+
selectLanguage: 'Seleccionar idioma...',
|
|
3474
|
+
download: 'Descargar',
|
|
3475
|
+
copy: 'Copiar',
|
|
3476
|
+
share: 'Compartir',
|
|
3477
|
+
// Componentes - Data Table / Paginación
|
|
3478
|
+
actions: 'Acciones',
|
|
3479
|
+
showing: 'Mostrando',
|
|
3480
|
+
of: 'de',
|
|
3481
|
+
perPage: 'por página',
|
|
3482
|
+
firstPage: 'Primera página',
|
|
3483
|
+
previousPage: 'Página anterior',
|
|
3484
|
+
nextPage: 'Página siguiente',
|
|
3485
|
+
lastPage: 'Última página',
|
|
3486
|
+
// Componentes - Participant Card
|
|
3487
|
+
winner: 'Ganador',
|
|
3488
|
+
ticket: 'boleto',
|
|
3489
|
+
tickets: 'boletos',
|
|
3490
|
+
more: 'más',
|
|
3491
|
+
notes: 'Notas:',
|
|
3492
|
+
},
|
|
3493
|
+
en: {
|
|
3494
|
+
// Common actions
|
|
3495
|
+
submit: 'Submit',
|
|
3496
|
+
cancel: 'Cancel',
|
|
3497
|
+
save: 'Save',
|
|
3498
|
+
delete: 'Delete',
|
|
3499
|
+
edit: 'Edit',
|
|
3500
|
+
close: 'Close',
|
|
3501
|
+
back: 'Back',
|
|
3502
|
+
next: 'Next',
|
|
3503
|
+
previous: 'Previous',
|
|
3504
|
+
loading: 'Loading...',
|
|
3505
|
+
search: 'Search',
|
|
3506
|
+
learnMore: 'Learn more',
|
|
3507
|
+
// States
|
|
3508
|
+
success: 'Success',
|
|
3509
|
+
error: 'Error',
|
|
3510
|
+
warning: 'Warning',
|
|
3511
|
+
info: 'Information',
|
|
3512
|
+
// Confirmations
|
|
3513
|
+
confirmDelete: 'Are you sure you want to delete?',
|
|
3514
|
+
confirmCancel: 'Are you sure you want to cancel?',
|
|
3515
|
+
// Common messages
|
|
3516
|
+
noResults: 'No results found',
|
|
3517
|
+
required: 'This field is required',
|
|
3518
|
+
// Navigation
|
|
3519
|
+
home: 'Home',
|
|
3520
|
+
settings: 'Settings',
|
|
3521
|
+
profile: 'Profile',
|
|
3522
|
+
logout: 'Log out',
|
|
3523
|
+
// Languages
|
|
3524
|
+
languageName_es: 'Español',
|
|
3525
|
+
languageName_en: 'English',
|
|
3526
|
+
// Components - Modals/Selects
|
|
3527
|
+
ok: 'OK',
|
|
3528
|
+
selectOption: 'Select option',
|
|
3529
|
+
selectPlaceholder: 'Select...',
|
|
3530
|
+
itemsSelected: 'items selected',
|
|
3531
|
+
selectAll: 'Select all',
|
|
3532
|
+
clear: 'Clear',
|
|
3533
|
+
apply: 'Apply',
|
|
3534
|
+
// Components - Dates
|
|
3535
|
+
startDate: 'Start date',
|
|
3536
|
+
endDate: 'End date',
|
|
3537
|
+
day: 'day',
|
|
3538
|
+
days: 'days',
|
|
3539
|
+
// Components - Forms
|
|
3540
|
+
uploadFile: 'Upload file',
|
|
3541
|
+
noFileSelected: 'No file selected',
|
|
3542
|
+
title: 'Title',
|
|
3543
|
+
description: 'Description',
|
|
3544
|
+
feedbackType: 'Feedback type',
|
|
3545
|
+
feedbackSuccess: 'Feedback sent successfully',
|
|
3546
|
+
feedbackError: 'Error sending feedback',
|
|
3547
|
+
// Components - Search/Grid
|
|
3548
|
+
searchNumber: 'Search number...',
|
|
3549
|
+
selected: 'selected',
|
|
3550
|
+
max: 'max:',
|
|
3551
|
+
// Components - Lists
|
|
3552
|
+
loadMoreComments: 'Load more comments',
|
|
3553
|
+
noData: 'No data',
|
|
3554
|
+
noRecordsFound: 'No records found to display.',
|
|
3555
|
+
// Components - Actions
|
|
3556
|
+
copiedToClipboard: 'Copied to clipboard!',
|
|
3557
|
+
language: 'Language',
|
|
3558
|
+
selectLanguage: 'Select language...',
|
|
3559
|
+
download: 'Download',
|
|
3560
|
+
copy: 'Copy',
|
|
3561
|
+
share: 'Share',
|
|
3562
|
+
// Components - Data Table / Pagination
|
|
3563
|
+
actions: 'Actions',
|
|
3564
|
+
showing: 'Showing',
|
|
3565
|
+
of: 'of',
|
|
3566
|
+
perPage: 'per page',
|
|
3567
|
+
firstPage: 'First page',
|
|
3568
|
+
previousPage: 'Previous page',
|
|
3569
|
+
nextPage: 'Next page',
|
|
3570
|
+
lastPage: 'Last page',
|
|
3571
|
+
// Components - Participant Card
|
|
3572
|
+
winner: 'Winner',
|
|
3573
|
+
ticket: 'ticket',
|
|
3574
|
+
tickets: 'tickets',
|
|
3575
|
+
more: 'more',
|
|
3576
|
+
notes: 'Notes:',
|
|
3577
|
+
},
|
|
3578
|
+
},
|
|
3579
|
+
};
|
|
3580
|
+
|
|
3581
|
+
/**
|
|
3582
|
+
* Configura el sistema de internacionalización de Valtech Components.
|
|
3583
|
+
*
|
|
3584
|
+
* @param config Configuración de i18n
|
|
3585
|
+
* @returns Providers para agregar en app.config.ts
|
|
3586
|
+
*
|
|
3587
|
+
* @example
|
|
3588
|
+
* // app.config.ts
|
|
3589
|
+
* import { provideValtechI18n } from 'valtech-components';
|
|
3590
|
+
* import { GLOBAL_CONTENT } from './i18n/_global';
|
|
3591
|
+
* import { LOGIN_CONTENT } from './i18n/login.i18n';
|
|
3592
|
+
*
|
|
3593
|
+
* export const appConfig: ApplicationConfig = {
|
|
3594
|
+
* providers: [
|
|
3595
|
+
* provideValtechI18n({
|
|
3596
|
+
* defaultLanguage: 'es',
|
|
3597
|
+
* supportedLanguages: ['es', 'en'],
|
|
3598
|
+
* detectBrowserLanguage: true,
|
|
3599
|
+
* content: {
|
|
3600
|
+
* '_global': GLOBAL_CONTENT,
|
|
3601
|
+
* 'Login': LOGIN_CONTENT,
|
|
3602
|
+
* }
|
|
3603
|
+
* }),
|
|
3604
|
+
* ]
|
|
3605
|
+
* };
|
|
3606
|
+
*/
|
|
3607
|
+
function provideValtechI18n(config = {}) {
|
|
3608
|
+
const mergedConfig = { ...DEFAULT_I18N_CONFIG, ...config };
|
|
3609
|
+
return makeEnvironmentProviders([
|
|
3610
|
+
{
|
|
3611
|
+
provide: APP_INITIALIZER,
|
|
3612
|
+
useFactory: (i18n) => {
|
|
3613
|
+
return () => {
|
|
3614
|
+
// Configurar idiomas soportados
|
|
3615
|
+
i18n.setI18nLanguages(mergedConfig.supportedLanguages);
|
|
3616
|
+
// Determinar contenido a registrar
|
|
3617
|
+
let contentToRegister = {};
|
|
3618
|
+
if (mergedConfig.includeDefaultContent !== false) {
|
|
3619
|
+
// Merge: defaults + user config (user gana)
|
|
3620
|
+
contentToRegister = deepMergeContent(VALTECH_DEFAULT_CONTENT, mergedConfig.content || {});
|
|
3621
|
+
}
|
|
3622
|
+
else if (mergedConfig.content) {
|
|
3623
|
+
// Solo contenido del usuario
|
|
3624
|
+
contentToRegister = mergedConfig.content;
|
|
3625
|
+
}
|
|
3626
|
+
// Registrar contenido
|
|
3627
|
+
if (Object.keys(contentToRegister).length > 0) {
|
|
3628
|
+
i18n.registerContentBulk(contentToRegister);
|
|
3629
|
+
}
|
|
3630
|
+
};
|
|
3631
|
+
},
|
|
3632
|
+
deps: [I18nService],
|
|
3633
|
+
multi: true,
|
|
3634
|
+
},
|
|
3635
|
+
]);
|
|
3636
|
+
}
|
|
3637
|
+
/**
|
|
3638
|
+
* Deep merge de ContentStore.
|
|
3639
|
+
* El contenido de `override` sobrescribe keys específicas de `base`.
|
|
3640
|
+
*
|
|
3641
|
+
* @param base - Contenido base (defaults de valtech-components)
|
|
3642
|
+
* @param override - Contenido del usuario que sobrescribe
|
|
3643
|
+
* @returns ContentStore mergeado
|
|
3644
|
+
*
|
|
3645
|
+
* @example
|
|
3646
|
+
* const base = { _global: { es: { ok: 'Aceptar' } } };
|
|
3647
|
+
* const override = { _global: { es: { ok: 'Dale' } } };
|
|
3648
|
+
* // Resultado: { _global: { es: { ok: 'Dale' } } }
|
|
3649
|
+
*/
|
|
3650
|
+
function deepMergeContent(base, override) {
|
|
3651
|
+
const result = {};
|
|
3652
|
+
// Copiar todos los namespaces del base
|
|
3653
|
+
for (const namespace of Object.keys(base)) {
|
|
3654
|
+
result[namespace] = deepMergeLanguagesContent(base[namespace], {});
|
|
3655
|
+
}
|
|
3656
|
+
// Mergear namespaces del override
|
|
3657
|
+
for (const namespace of Object.keys(override)) {
|
|
3658
|
+
if (result[namespace]) {
|
|
3659
|
+
// Namespace existe en base, hacer deep merge
|
|
3660
|
+
result[namespace] = deepMergeLanguagesContent(result[namespace], override[namespace]);
|
|
3661
|
+
}
|
|
3662
|
+
else {
|
|
3663
|
+
// Namespace nuevo, copiar completo
|
|
3664
|
+
result[namespace] = deepMergeLanguagesContent({}, override[namespace]);
|
|
3665
|
+
}
|
|
3666
|
+
}
|
|
3667
|
+
return result;
|
|
3668
|
+
}
|
|
3669
|
+
/**
|
|
3670
|
+
* Deep merge de LanguagesContent (un namespace).
|
|
3671
|
+
*/
|
|
3672
|
+
function deepMergeLanguagesContent(base, override) {
|
|
3673
|
+
const result = {};
|
|
3674
|
+
const allLangs = new Set([
|
|
3675
|
+
...Object.keys(base),
|
|
3676
|
+
...Object.keys(override),
|
|
3677
|
+
]);
|
|
3678
|
+
for (const lang of allLangs) {
|
|
3679
|
+
result[lang] = {
|
|
3680
|
+
...(base[lang] || {}),
|
|
3681
|
+
...(override[lang] || {}),
|
|
3682
|
+
};
|
|
3683
|
+
}
|
|
3684
|
+
return result;
|
|
3685
|
+
}
|
|
3686
|
+
|
|
3687
|
+
// Types
|
|
3688
|
+
|
|
3689
|
+
addIcons({ downloadOutline, copyOutline, shareOutline });
|
|
3690
|
+
/**
|
|
3691
|
+
* val-qr-code
|
|
3692
|
+
*
|
|
3693
|
+
* A component to display QR codes generated by QrGeneratorService.
|
|
3694
|
+
* Provides optional action buttons for download, copy, and share.
|
|
3695
|
+
*
|
|
3696
|
+
* @example Basic usage
|
|
3697
|
+
* ```typescript
|
|
3698
|
+
* qr = await this.qrService.generate({ data: 'https://example.com' });
|
|
3699
|
+
* ```
|
|
3700
|
+
* ```html
|
|
3701
|
+
* <val-qr-code [props]="{ qr: qr }"></val-qr-code>
|
|
3702
|
+
* ```
|
|
3703
|
+
*
|
|
3704
|
+
* @example With actions
|
|
3705
|
+
* ```html
|
|
3706
|
+
* <val-qr-code
|
|
3707
|
+
* [props]="{
|
|
3708
|
+
* qr: qr,
|
|
3709
|
+
* showDownload: true,
|
|
3710
|
+
* showCopy: true,
|
|
3711
|
+
* showShare: true,
|
|
3712
|
+
* displaySize: 200,
|
|
3713
|
+
* showBorder: true,
|
|
3714
|
+
* borderRadius: 12
|
|
3715
|
+
* }"
|
|
3716
|
+
* (actionComplete)="onAction($event)"
|
|
3717
|
+
* ></val-qr-code>
|
|
3718
|
+
* ```
|
|
3719
|
+
*
|
|
3720
|
+
* @input props: QrCodeMetadata - Configuration for the QR display
|
|
3721
|
+
* @output actionComplete - Emits when an action (download/copy/share) completes
|
|
3722
|
+
* @output imageLoad - Emits when the QR image loads
|
|
3723
|
+
* @output imageError - Emits when the QR image fails to load
|
|
3724
|
+
*/
|
|
3725
|
+
class QrCodeComponent {
|
|
3726
|
+
constructor() {
|
|
3727
|
+
this.actionComplete = new EventEmitter();
|
|
3728
|
+
this.imageLoad = new EventEmitter();
|
|
3729
|
+
this.imageError = new EventEmitter();
|
|
3730
|
+
this.canShare = false;
|
|
3731
|
+
this.canCopy = false;
|
|
3732
|
+
this.qrService = inject(QrGeneratorService);
|
|
3733
|
+
this.i18n = inject(I18nService);
|
|
3734
|
+
}
|
|
3735
|
+
ngOnInit() {
|
|
3736
|
+
this.canShare = this.qrService.canShare();
|
|
3737
|
+
this.canCopy = this.qrService.canCopyToClipboard();
|
|
3738
|
+
}
|
|
3739
|
+
getDisplaySize() {
|
|
3740
|
+
if (this.props.displaySize) {
|
|
3741
|
+
return `${this.props.displaySize}px`;
|
|
3742
|
+
}
|
|
3743
|
+
return `${this.props.qr.config.width || 300}px`;
|
|
3744
|
+
}
|
|
3745
|
+
getBorderRadius() {
|
|
3746
|
+
return this.props.borderRadius ? `${this.props.borderRadius}px` : '0';
|
|
3747
|
+
}
|
|
3748
|
+
getPadding() {
|
|
3749
|
+
return this.props.padding ? `${this.props.padding}px` : '0';
|
|
3750
|
+
}
|
|
3751
|
+
getQrBorderRadius() {
|
|
3752
|
+
return this.props.qrBorderRadius ? `${this.props.qrBorderRadius}px` : '0';
|
|
3753
|
+
}
|
|
3754
|
+
getContainerClasses() {
|
|
3755
|
+
const classes = [];
|
|
3756
|
+
if (this.props.cssClass)
|
|
3757
|
+
classes.push(this.props.cssClass);
|
|
3758
|
+
if (this.props.showBorder)
|
|
3759
|
+
classes.push('with-border');
|
|
3760
|
+
if (this.props.loading)
|
|
3761
|
+
classes.push('loading');
|
|
3762
|
+
if (this.props.theme)
|
|
3763
|
+
classes.push(`theme--${this.props.theme}`);
|
|
3764
|
+
if (this.props.pulseOnHover)
|
|
3765
|
+
classes.push('pulse-on-hover');
|
|
3766
|
+
if (this.props.scaleOnHover)
|
|
3767
|
+
classes.push('scale-on-hover');
|
|
3768
|
+
if (this.props.gradient)
|
|
3769
|
+
classes.push('has-gradient');
|
|
3770
|
+
return classes.join(' ');
|
|
3771
|
+
}
|
|
3772
|
+
getContainerBackground() {
|
|
3773
|
+
if (this.props.gradient) {
|
|
3774
|
+
const { from, to, via, direction = 'to-bottom' } = this.props.gradient;
|
|
3775
|
+
const cssDirection = direction.replace(/-/g, ' ');
|
|
3776
|
+
if (via) {
|
|
3777
|
+
return `linear-gradient(${cssDirection}, ${from}, ${via}, ${to})`;
|
|
3778
|
+
}
|
|
3779
|
+
return `linear-gradient(${cssDirection}, ${from}, ${to})`;
|
|
3780
|
+
}
|
|
3781
|
+
return this.props.containerBackground || 'transparent';
|
|
3782
|
+
}
|
|
3783
|
+
getShadow() {
|
|
3784
|
+
const shadowMap = {
|
|
3785
|
+
none: 'none',
|
|
3786
|
+
sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
|
|
3787
|
+
md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
|
|
3788
|
+
lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
|
|
3789
|
+
xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
|
|
3790
|
+
};
|
|
3791
|
+
if (!this.props.shadow)
|
|
3792
|
+
return 'none';
|
|
3793
|
+
return shadowMap[this.props.shadow] || this.props.shadow;
|
|
3794
|
+
}
|
|
3795
|
+
getLabelFontSize() {
|
|
3796
|
+
return this.props.label?.fontSize ? `${this.props.label.fontSize}px` : '14px';
|
|
3797
|
+
}
|
|
3798
|
+
hasActions() {
|
|
3799
|
+
return !!(this.props.showDownload || this.props.showCopy || this.props.showShare);
|
|
3800
|
+
}
|
|
3801
|
+
getDownloadLabel() {
|
|
3802
|
+
return this.props.downloadLabel || this.i18n.t('download');
|
|
3803
|
+
}
|
|
3804
|
+
getCopyLabel() {
|
|
3805
|
+
return this.props.copyLabel || this.i18n.t('copy');
|
|
3806
|
+
}
|
|
3807
|
+
getShareLabel() {
|
|
3808
|
+
return this.props.shareLabel || this.i18n.t('share');
|
|
3809
|
+
}
|
|
3810
|
+
async onDownload() {
|
|
3811
|
+
try {
|
|
3812
|
+
const options = this.props.downloadFilename
|
|
3813
|
+
? { filename: this.props.downloadFilename }
|
|
3814
|
+
: undefined;
|
|
3815
|
+
await this.qrService.download(this.props.qr, options);
|
|
3816
|
+
this.actionComplete.emit({
|
|
3817
|
+
action: 'download',
|
|
3818
|
+
success: true,
|
|
3819
|
+
qr: this.props.qr,
|
|
3253
3820
|
});
|
|
3254
3821
|
}
|
|
3255
3822
|
catch (error) {
|
|
@@ -4896,7 +5463,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4896
5463
|
* @input props: DateInputMetadata - Configuration for the date input (form control, hint, etc.)
|
|
4897
5464
|
*/
|
|
4898
5465
|
class DateInputComponent {
|
|
4899
|
-
|
|
5466
|
+
/** Done button text - from props or i18n default */
|
|
5467
|
+
get doneText() {
|
|
5468
|
+
return this.props?.doneText || this.i18n.t('ok');
|
|
5469
|
+
}
|
|
5470
|
+
/** Cancel button text - from props or i18n default */
|
|
5471
|
+
get cancelText() {
|
|
5472
|
+
return this.props?.cancelText || this.i18n.t('cancel');
|
|
5473
|
+
}
|
|
5474
|
+
constructor() {
|
|
5475
|
+
this.i18n = inject(I18nService);
|
|
5476
|
+
}
|
|
4900
5477
|
ngOnInit() {
|
|
4901
5478
|
// Apply default values on initialization
|
|
4902
5479
|
if (this.props?.withDefault || this.props?.value) {
|
|
@@ -4937,8 +5514,8 @@ class DateInputComponent {
|
|
|
4937
5514
|
locale="es-ES"
|
|
4938
5515
|
[firstDayOfWeek]="1"
|
|
4939
5516
|
[showDefaultButtons]="true"
|
|
4940
|
-
doneText="
|
|
4941
|
-
cancelText="
|
|
5517
|
+
[doneText]="doneText"
|
|
5518
|
+
[cancelText]="cancelText"
|
|
4942
5519
|
formatOptions="{
|
|
4943
5520
|
date: { dateStyle: 'medium' },
|
|
4944
5521
|
time: { timeStyle: 'short' }
|
|
@@ -4965,8 +5542,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4965
5542
|
locale="es-ES"
|
|
4966
5543
|
[firstDayOfWeek]="1"
|
|
4967
5544
|
[showDefaultButtons]="true"
|
|
4968
|
-
doneText="
|
|
4969
|
-
cancelText="
|
|
5545
|
+
[doneText]="doneText"
|
|
5546
|
+
[cancelText]="cancelText"
|
|
4970
5547
|
formatOptions="{
|
|
4971
5548
|
date: { dateStyle: 'medium' },
|
|
4972
5549
|
time: { timeStyle: 'short' }
|
|
@@ -5105,502 +5682,209 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
5105
5682
|
<div class="description-container" [class.expanded]="expanded" [class.has-gradient]="!expanded && isTruncated">
|
|
5106
5683
|
<div class="content-wrapper">
|
|
5107
5684
|
<ion-text>
|
|
5108
|
-
<p class="description">
|
|
5109
|
-
<span class="content">{{ expanded ? props.content : truncatedText }}</span>
|
|
5110
|
-
</p>
|
|
5111
|
-
</ion-text>
|
|
5112
|
-
</div>
|
|
5113
|
-
@if (!expanded && isTruncated) {
|
|
5114
|
-
<span class="see-more" [style.color]="this.color()" (click)="toggleExpand()">
|
|
5115
|
-
{{ getExpandText() }}
|
|
5116
|
-
</span>
|
|
5117
|
-
}
|
|
5118
|
-
</div>
|
|
5119
|
-
`, styles: [".description-container{position:relative;overflow:hidden;transition:max-height .3s ease-in-out}.description-container:not(.expanded){max-height:10rem}.description-container.expanded{max-height:none}.content-wrapper{overflow:hidden}.description-container:not(.expanded).has-gradient .content-wrapper{-webkit-mask-image:linear-gradient(to bottom,black 50%,transparent 100%);mask-image:linear-gradient(to bottom,black 50%,transparent 100%)}.description{margin:0}.see-more{display:block;font-weight:700;cursor:pointer;margin-top:.25rem}\n"] }]
|
|
5120
|
-
}], propDecorators: { props: [{
|
|
5121
|
-
type: Input
|
|
5122
|
-
}] } });
|
|
5123
|
-
|
|
5124
|
-
/**
|
|
5125
|
-
* val-file-input
|
|
5126
|
-
*
|
|
5127
|
-
* A file input component for uploading files, integrated with Angular forms.
|
|
5128
|
-
*
|
|
5129
|
-
* @example
|
|
5130
|
-
* <val-file-input [props]="{ control: myControl, accept: 'image/*' }"></val-file-input>
|
|
5131
|
-
*
|
|
5132
|
-
* @input props: FileInputMetadata - Configuration for the file input (form control, accept types, etc.)
|
|
5133
|
-
*/
|
|
5134
|
-
class FileInputComponent {
|
|
5135
|
-
constructor() {
|
|
5136
|
-
this.contrastButton = {
|
|
5137
|
-
...PrimarySolidDefaultRoundButton('Subir archivo'),
|
|
5138
|
-
color: 'light',
|
|
5139
|
-
};
|
|
5140
|
-
}
|
|
5141
|
-
ngOnInit() { }
|
|
5142
|
-
onFileSelected(event) {
|
|
5143
|
-
this.selectedFile = event.target.files[0];
|
|
5144
|
-
this.props.control.setValue(this.selectedFile);
|
|
5145
|
-
}
|
|
5146
|
-
reset() {
|
|
5147
|
-
this.selectedFile = null;
|
|
5148
|
-
this.fileInput.nativeElement.value = '';
|
|
5149
|
-
}
|
|
5150
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FileInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5151
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: FileInputComponent, isStandalone: true, selector: "val-file-input", inputs: { props: "props" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: `
|
|
5152
|
-
<div class="file-container">
|
|
5153
|
-
<input style="display: none" type="file" (change)="onFileSelected($event)" #fileInput [accept]="props.accept" />
|
|
5154
|
-
<div class="name-container">
|
|
5155
|
-
<ion-icon [name]="selectedFile ? 'checkmark-circle-outline' : 'alert-circle-outline'"></ion-icon>
|
|
5156
|
-
<val-text
|
|
5157
|
-
style="margin-left: 4px;"
|
|
5158
|
-
[props]="{
|
|
5159
|
-
content: selectedFile ? selectedFile.name : (props.noFileText || 'No has seleccionado archivo'),
|
|
5160
|
-
color: 'dark',
|
|
5161
|
-
bold: false,
|
|
5162
|
-
size: 'medium',
|
|
5163
|
-
}"
|
|
5164
|
-
></val-text>
|
|
5165
|
-
</div>
|
|
5166
|
-
<val-button [props]="contrastButton" (onClick)="fileInput.click()"></val-button>
|
|
5167
|
-
</div>
|
|
5168
|
-
`, isInline: true, styles: [":root{--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}@media (prefers-color-scheme: dark){:root{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.section{margin-top:1rem}.input{margin:.5rem 0}@media (min-width: 768px){.input{margin:.75rem 0}}.file-container{margin-top:.25rem}.name-container{display:flex;flex-direction:row;align-items:center}\n"], dependencies: [{ kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: TextComponent, selector: "val-text", inputs: ["props"] }, { kind: "component", type: ButtonComponent, selector: "val-button", inputs: ["preset", "props"], outputs: ["onClick"] }] }); }
|
|
5169
|
-
}
|
|
5170
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FileInputComponent, decorators: [{
|
|
5171
|
-
type: Component,
|
|
5172
|
-
args: [{ selector: 'val-file-input', standalone: true, imports: [IonIcon, TextComponent, ButtonComponent], template: `
|
|
5173
|
-
<div class="file-container">
|
|
5174
|
-
<input style="display: none" type="file" (change)="onFileSelected($event)" #fileInput [accept]="props.accept" />
|
|
5175
|
-
<div class="name-container">
|
|
5176
|
-
<ion-icon [name]="selectedFile ? 'checkmark-circle-outline' : 'alert-circle-outline'"></ion-icon>
|
|
5177
|
-
<val-text
|
|
5178
|
-
style="margin-left: 4px;"
|
|
5179
|
-
[props]="{
|
|
5180
|
-
content: selectedFile ? selectedFile.name : (props.noFileText || 'No has seleccionado archivo'),
|
|
5181
|
-
color: 'dark',
|
|
5182
|
-
bold: false,
|
|
5183
|
-
size: 'medium',
|
|
5184
|
-
}"
|
|
5185
|
-
></val-text>
|
|
5186
|
-
</div>
|
|
5187
|
-
<val-button [props]="contrastButton" (onClick)="fileInput.click()"></val-button>
|
|
5188
|
-
</div>
|
|
5189
|
-
`, styles: [":root{--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}@media (prefers-color-scheme: dark){:root{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.section{margin-top:1rem}.input{margin:.5rem 0}@media (min-width: 768px){.input{margin:.75rem 0}}.file-container{margin-top:.25rem}.name-container{display:flex;flex-direction:row;align-items:center}\n"] }]
|
|
5190
|
-
}], ctorParameters: () => [], propDecorators: { props: [{
|
|
5191
|
-
type: Input
|
|
5192
|
-
}], fileInput: [{
|
|
5193
|
-
type: ViewChild,
|
|
5194
|
-
args: ['fileInput']
|
|
5195
|
-
}] } });
|
|
5196
|
-
|
|
5197
|
-
/**
|
|
5198
|
-
* val-hint
|
|
5199
|
-
*
|
|
5200
|
-
* Displays validation error messages for a form input, using Angular forms.
|
|
5201
|
-
*
|
|
5202
|
-
* @example
|
|
5203
|
-
* <val-hint [props]="{ control: myControl, errors: { required: 'Required field' } }"></val-hint>
|
|
5204
|
-
*
|
|
5205
|
-
* @input props: InputMetadata - Configuration for the input (form control, errors, etc.)
|
|
5206
|
-
*/
|
|
5207
|
-
class HintComponent {
|
|
5208
|
-
constructor() { }
|
|
5209
|
-
ngOnInit() { }
|
|
5210
|
-
get shouldShowErrors() {
|
|
5211
|
-
if (this.props.control) {
|
|
5212
|
-
// Normal field with single control
|
|
5213
|
-
return this.props.control.invalid && (this.props.control.touched || this.props.control.dirty);
|
|
5214
|
-
}
|
|
5215
|
-
else if (this.props.fromControl && this.props.toControl) {
|
|
5216
|
-
// NUMBER_FROM_TO field with separate controls
|
|
5217
|
-
const fromInvalid = this.props.fromControl.invalid && (this.props.fromControl.touched || this.props.fromControl.dirty);
|
|
5218
|
-
const toInvalid = this.props.toControl.invalid && (this.props.toControl.touched || this.props.toControl.dirty);
|
|
5219
|
-
return fromInvalid || toInvalid;
|
|
5220
|
-
}
|
|
5221
|
-
return false;
|
|
5222
|
-
}
|
|
5223
|
-
get Errors() {
|
|
5224
|
-
const keys = Object.keys(this.props.errors || {});
|
|
5225
|
-
const errors = [];
|
|
5226
|
-
keys.map((e) => {
|
|
5227
|
-
if (this.props.control && this.props.control.hasError(e)) {
|
|
5228
|
-
// Normal field
|
|
5229
|
-
errors.push(this.props.errors[e]);
|
|
5230
|
-
}
|
|
5231
|
-
else if (this.props.fromControl && this.props.toControl) {
|
|
5232
|
-
// NUMBER_FROM_TO field - check both controls
|
|
5233
|
-
const fromLabel = this.props.fromLabel || 'Inicial';
|
|
5234
|
-
const toLabel = this.props.toLabel || 'Final';
|
|
5235
|
-
if (this.props.fromControl.hasError(e)) {
|
|
5236
|
-
errors.push(`${fromLabel}: ${this.props.errors[e]}`);
|
|
5237
|
-
}
|
|
5238
|
-
if (this.props.toControl.hasError(e)) {
|
|
5239
|
-
errors.push(`${toLabel}: ${this.props.errors[e]}`);
|
|
5240
|
-
}
|
|
5241
|
-
}
|
|
5242
|
-
});
|
|
5243
|
-
return errors;
|
|
5244
|
-
}
|
|
5245
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HintComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5246
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: HintComponent, isStandalone: true, selector: "val-hint", inputs: { props: "props" }, ngImport: i0, template: `
|
|
5247
|
-
<div class="hint-container" *ngIf="shouldShowErrors">
|
|
5248
|
-
<val-text
|
|
5249
|
-
*ngFor="let e of Errors"
|
|
5250
|
-
[props]="{
|
|
5251
|
-
content: e,
|
|
5252
|
-
color: 'danger',
|
|
5253
|
-
bold: false,
|
|
5254
|
-
size: 'small',
|
|
5255
|
-
}"
|
|
5256
|
-
></val-text>
|
|
5257
|
-
</div>
|
|
5258
|
-
`, isInline: true, styles: [":root{--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}@media (prefers-color-scheme: dark){:root{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.section{margin-top:1rem}.input{margin:.5rem 0}@media (min-width: 768px){.input{margin:.75rem 0}}.hint-container{margin-top:.25rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TextComponent, selector: "val-text", inputs: ["props"] }] }); }
|
|
5259
|
-
}
|
|
5260
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HintComponent, decorators: [{
|
|
5261
|
-
type: Component,
|
|
5262
|
-
args: [{ selector: 'val-hint', standalone: true, imports: [CommonModule, TextComponent], template: `
|
|
5263
|
-
<div class="hint-container" *ngIf="shouldShowErrors">
|
|
5264
|
-
<val-text
|
|
5265
|
-
*ngFor="let e of Errors"
|
|
5266
|
-
[props]="{
|
|
5267
|
-
content: e,
|
|
5268
|
-
color: 'danger',
|
|
5269
|
-
bold: false,
|
|
5270
|
-
size: 'small',
|
|
5271
|
-
}"
|
|
5272
|
-
></val-text>
|
|
5273
|
-
</div>
|
|
5274
|
-
`, styles: [":root{--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}@media (prefers-color-scheme: dark){:root{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.section{margin-top:1rem}.input{margin:.5rem 0}@media (min-width: 768px){.input{margin:.75rem 0}}.hint-container{margin-top:.25rem}\n"] }]
|
|
5275
|
-
}], ctorParameters: () => [], propDecorators: { props: [{
|
|
5276
|
-
type: Input
|
|
5277
|
-
}] } });
|
|
5278
|
-
|
|
5279
|
-
/**
|
|
5280
|
-
* val-hour-input
|
|
5281
|
-
*
|
|
5282
|
-
* A time picker input integrated with Angular forms, using Ionic's datetime component.
|
|
5283
|
-
*
|
|
5284
|
-
* @example
|
|
5285
|
-
* <val-hour-input [props]="{ control: myControl }"></val-hour-input>
|
|
5286
|
-
*
|
|
5287
|
-
* @input props: InputMetadata - Configuration for the time input (form control, etc.)
|
|
5288
|
-
*/
|
|
5289
|
-
class HourInputComponent {
|
|
5290
|
-
constructor() { }
|
|
5291
|
-
ngOnInit() { }
|
|
5292
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HourInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5293
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: HourInputComponent, isStandalone: true, selector: "val-hour-input", inputs: { props: "props" }, ngImport: i0, template: ` <ion-datetime [formControl]="props.control" presentation="time"></ion-datetime>`, isInline: true, styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: IonDatetime, selector: "ion-datetime", inputs: ["cancelText", "clearText", "color", "dayValues", "disabled", "doneText", "firstDayOfWeek", "formatOptions", "highlightedDates", "hourCycle", "hourValues", "isDateEnabled", "locale", "max", "min", "minuteValues", "mode", "monthValues", "multiple", "name", "preferWheel", "presentation", "readonly", "showAdjacentDays", "showClearButton", "showDefaultButtons", "showDefaultTimeLabel", "showDefaultTitle", "size", "titleSelectedDatesFormatter", "value", "yearValues"] }] }); }
|
|
5294
|
-
}
|
|
5295
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HourInputComponent, decorators: [{
|
|
5296
|
-
type: Component,
|
|
5297
|
-
args: [{ selector: 'val-hour-input', standalone: true, imports: [ReactiveFormsModule, IonDatetime], template: ` <ion-datetime [formControl]="props.control" presentation="time"></ion-datetime>` }]
|
|
5298
|
-
}], ctorParameters: () => [], propDecorators: { props: [{
|
|
5685
|
+
<p class="description">
|
|
5686
|
+
<span class="content">{{ expanded ? props.content : truncatedText }}</span>
|
|
5687
|
+
</p>
|
|
5688
|
+
</ion-text>
|
|
5689
|
+
</div>
|
|
5690
|
+
@if (!expanded && isTruncated) {
|
|
5691
|
+
<span class="see-more" [style.color]="this.color()" (click)="toggleExpand()">
|
|
5692
|
+
{{ getExpandText() }}
|
|
5693
|
+
</span>
|
|
5694
|
+
}
|
|
5695
|
+
</div>
|
|
5696
|
+
`, styles: [".description-container{position:relative;overflow:hidden;transition:max-height .3s ease-in-out}.description-container:not(.expanded){max-height:10rem}.description-container.expanded{max-height:none}.content-wrapper{overflow:hidden}.description-container:not(.expanded).has-gradient .content-wrapper{-webkit-mask-image:linear-gradient(to bottom,black 50%,transparent 100%);mask-image:linear-gradient(to bottom,black 50%,transparent 100%)}.description{margin:0}.see-more{display:block;font-weight:700;cursor:pointer;margin-top:.25rem}\n"] }]
|
|
5697
|
+
}], propDecorators: { props: [{
|
|
5299
5698
|
type: Input
|
|
5300
5699
|
}] } });
|
|
5301
5700
|
|
|
5302
5701
|
/**
|
|
5303
|
-
*
|
|
5304
|
-
*/
|
|
5305
|
-
const DEFAULT_I18N_CONFIG = {
|
|
5306
|
-
defaultLanguage: 'es',
|
|
5307
|
-
supportedLanguages: ['es', 'en'],
|
|
5308
|
-
detectBrowserLanguage: true,
|
|
5309
|
-
content: {},
|
|
5310
|
-
};
|
|
5311
|
-
/**
|
|
5312
|
-
* Clave para persistir idioma en localStorage
|
|
5313
|
-
*/
|
|
5314
|
-
const LANG_STORAGE_KEY$1 = 'app_lang';
|
|
5315
|
-
|
|
5316
|
-
/**
|
|
5317
|
-
* Servicio de internacionalización basado en Angular Signals.
|
|
5702
|
+
* val-file-input
|
|
5318
5703
|
*
|
|
5319
|
-
*
|
|
5320
|
-
* - Sin RxJS: usa Signals para evitar memory leaks y congelamiento
|
|
5321
|
-
* - Namespace-based: organiza traducciones por contexto
|
|
5322
|
-
* - Fallback multi-nivel: namespace → _global → placeholder
|
|
5323
|
-
* - Interpolación: soporta {variable} en textos
|
|
5704
|
+
* A file input component for uploading files, integrated with Angular forms.
|
|
5324
5705
|
*
|
|
5325
5706
|
* @example
|
|
5326
|
-
*
|
|
5327
|
-
* i18n = inject(I18nService);
|
|
5328
|
-
*
|
|
5329
|
-
* // Obtener texto
|
|
5330
|
-
* const title = this.i18n.t('title', 'Login');
|
|
5331
|
-
*
|
|
5332
|
-
* // Con interpolación
|
|
5333
|
-
* const welcome = this.i18n.t('welcome', 'Login', { name: 'Juan' });
|
|
5707
|
+
* <val-file-input [props]="{ control: myControl, accept: 'image/*' }"></val-file-input>
|
|
5334
5708
|
*
|
|
5335
|
-
*
|
|
5336
|
-
* this.i18n.setLanguage('en');
|
|
5709
|
+
* @input props: FileInputMetadata - Configuration for the file input (form control, accept types, etc.)
|
|
5337
5710
|
*/
|
|
5338
|
-
class
|
|
5711
|
+
class FileInputComponent {
|
|
5339
5712
|
constructor() {
|
|
5340
|
-
|
|
5341
|
-
this._lang = signal(DEFAULT_I18N_CONFIG.defaultLanguage);
|
|
5342
|
-
this._content = signal({});
|
|
5343
|
-
this._supportedLanguages = signal(DEFAULT_I18N_CONFIG.supportedLanguages);
|
|
5344
|
-
// Públicos readonly
|
|
5345
|
-
this.lang = this._lang.asReadonly();
|
|
5346
|
-
this.supportedLanguages = this._supportedLanguages.asReadonly();
|
|
5347
|
-
// Computed para verificaciones rápidas
|
|
5348
|
-
this.isSpanish = computed(() => this._lang() === 'es');
|
|
5349
|
-
this.isEnglish = computed(() => this._lang() === 'en');
|
|
5350
|
-
this.loadStoredLanguage();
|
|
5351
|
-
}
|
|
5352
|
-
/**
|
|
5353
|
-
* Obtiene texto traducido (alias corto de getText)
|
|
5354
|
-
*
|
|
5355
|
-
* @param key Clave del texto
|
|
5356
|
-
* @param namespace Namespace (default: '_global')
|
|
5357
|
-
* @param data Variables para interpolación
|
|
5358
|
-
* @returns Texto traducido o placeholder [namespace.key]
|
|
5359
|
-
*
|
|
5360
|
-
* @example
|
|
5361
|
-
* i18n.t('submit'); // busca en _global
|
|
5362
|
-
* i18n.t('title', 'Login'); // busca en Login
|
|
5363
|
-
* i18n.t('welcome', 'Login', {name}); // con interpolación
|
|
5364
|
-
*/
|
|
5365
|
-
t(key, namespace, data) {
|
|
5366
|
-
return this.getText(key, namespace, data);
|
|
5367
|
-
}
|
|
5368
|
-
/**
|
|
5369
|
-
* Obtiene texto traducido
|
|
5370
|
-
*
|
|
5371
|
-
* Fallback order:
|
|
5372
|
-
* 1. content[namespace][lang][key]
|
|
5373
|
-
* 2. content['_global'][lang][key]
|
|
5374
|
-
* 3. "[namespace.key]" (placeholder)
|
|
5375
|
-
*/
|
|
5376
|
-
getText(key, namespace, data) {
|
|
5377
|
-
const content = this._content();
|
|
5378
|
-
const lang = this._lang();
|
|
5379
|
-
const ns = namespace || '_global';
|
|
5380
|
-
// Buscar en namespace específico
|
|
5381
|
-
let text = content[ns]?.[lang]?.[key];
|
|
5382
|
-
// Fallback a _global
|
|
5383
|
-
if (!text && ns !== '_global') {
|
|
5384
|
-
text = content['_global']?.[lang]?.[key];
|
|
5385
|
-
}
|
|
5386
|
-
// Fallback a placeholder
|
|
5387
|
-
if (!text) {
|
|
5388
|
-
console.warn(`[i18n] Missing translation: ${ns}.${key} (${lang})`);
|
|
5389
|
-
return `[${ns}.${key}]`;
|
|
5390
|
-
}
|
|
5391
|
-
// Aplicar interpolación si hay data
|
|
5392
|
-
if (data) {
|
|
5393
|
-
return this.interpolate(text, data);
|
|
5394
|
-
}
|
|
5395
|
-
return text;
|
|
5396
|
-
}
|
|
5397
|
-
/**
|
|
5398
|
-
* Cambia el idioma de la aplicación
|
|
5399
|
-
*
|
|
5400
|
-
* @param lang Nuevo idioma
|
|
5401
|
-
* @param forceReload Si true, recarga la página (fallback si reactividad falla)
|
|
5402
|
-
*/
|
|
5403
|
-
setLanguage(lang, forceReload = false) {
|
|
5404
|
-
if (!this._supportedLanguages().includes(lang)) {
|
|
5405
|
-
console.warn(`[i18n] Language '${lang}' not in supported languages`);
|
|
5406
|
-
return;
|
|
5407
|
-
}
|
|
5408
|
-
if (lang === this._lang()) {
|
|
5409
|
-
return;
|
|
5410
|
-
}
|
|
5411
|
-
// Persistir en localStorage
|
|
5412
|
-
localStorage.setItem(LANG_STORAGE_KEY$1, lang);
|
|
5413
|
-
// Actualizar signal
|
|
5414
|
-
this._lang.set(lang);
|
|
5415
|
-
// Fallback: recargar si se solicita
|
|
5416
|
-
if (forceReload) {
|
|
5417
|
-
window.location.reload();
|
|
5418
|
-
}
|
|
5419
|
-
}
|
|
5420
|
-
/**
|
|
5421
|
-
* Registra contenido de traducciones para un namespace
|
|
5422
|
-
*
|
|
5423
|
-
* @param namespace Nombre del namespace
|
|
5424
|
-
* @param content Contenido de traducciones
|
|
5425
|
-
*
|
|
5426
|
-
* @example
|
|
5427
|
-
* i18n.registerContent('Login', {
|
|
5428
|
-
* es: { title: 'Iniciar sesión' },
|
|
5429
|
-
* en: { title: 'Sign in' }
|
|
5430
|
-
* });
|
|
5431
|
-
*/
|
|
5432
|
-
registerContent(namespace, content) {
|
|
5433
|
-
this._content.update((store) => ({
|
|
5434
|
-
...store,
|
|
5435
|
-
[namespace]: content,
|
|
5436
|
-
}));
|
|
5437
|
-
}
|
|
5438
|
-
/**
|
|
5439
|
-
* Registra múltiples namespaces de una vez
|
|
5440
|
-
*
|
|
5441
|
-
* @param contentStore Objeto con namespaces como keys
|
|
5442
|
-
*/
|
|
5443
|
-
registerContentBulk(contentStore) {
|
|
5444
|
-
this._content.update((store) => ({
|
|
5445
|
-
...store,
|
|
5446
|
-
...contentStore,
|
|
5447
|
-
}));
|
|
5448
|
-
}
|
|
5449
|
-
/**
|
|
5450
|
-
* Configura los idiomas soportados
|
|
5451
|
-
*/
|
|
5452
|
-
setI18nLanguages(languages) {
|
|
5453
|
-
this._supportedLanguages.set(languages);
|
|
5454
|
-
}
|
|
5455
|
-
/**
|
|
5456
|
-
* Obtiene todos los namespaces registrados
|
|
5457
|
-
*/
|
|
5458
|
-
getNamespaces() {
|
|
5459
|
-
return Object.keys(this._content());
|
|
5713
|
+
this.i18n = inject(I18nService);
|
|
5460
5714
|
}
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5715
|
+
ngOnInit() {
|
|
5716
|
+
// Initialize button with i18n text
|
|
5717
|
+
this.contrastButton = {
|
|
5718
|
+
...PrimarySolidDefaultRoundButton(this.props?.buttonText || this.i18n.t('uploadFile')),
|
|
5719
|
+
color: 'light',
|
|
5720
|
+
};
|
|
5466
5721
|
}
|
|
5467
|
-
/**
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
const stored = localStorage.getItem(LANG_STORAGE_KEY$1);
|
|
5472
|
-
if (stored && this.isValidLanguage(stored)) {
|
|
5473
|
-
this._lang.set(stored);
|
|
5474
|
-
return;
|
|
5475
|
-
}
|
|
5476
|
-
// Detectar idioma del navegador
|
|
5477
|
-
const browserLang = navigator.language.split('-')[0];
|
|
5478
|
-
if (this.isValidLanguage(browserLang)) {
|
|
5479
|
-
this._lang.set(browserLang);
|
|
5480
|
-
localStorage.setItem(LANG_STORAGE_KEY$1, browserLang);
|
|
5722
|
+
/** Get display text for file status */
|
|
5723
|
+
getFileDisplayText() {
|
|
5724
|
+
if (this.selectedFile) {
|
|
5725
|
+
return this.selectedFile.name;
|
|
5481
5726
|
}
|
|
5727
|
+
return this.props?.noFileText || this.i18n.t('noFileSelected');
|
|
5482
5728
|
}
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
isValidLanguage(lang) {
|
|
5487
|
-
return this._supportedLanguages().includes(lang);
|
|
5729
|
+
onFileSelected(event) {
|
|
5730
|
+
this.selectedFile = event.target.files[0];
|
|
5731
|
+
this.props.control.setValue(this.selectedFile);
|
|
5488
5732
|
}
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
* @example
|
|
5493
|
-
* interpolate('Hola {name}', { name: 'Juan' }) // 'Hola Juan'
|
|
5494
|
-
*/
|
|
5495
|
-
interpolate(text, data) {
|
|
5496
|
-
return Object.entries(data).reduce((result, [key, value]) => {
|
|
5497
|
-
const regex = new RegExp(`\\{${key}\\}`, 'g');
|
|
5498
|
-
return result.replace(regex, value);
|
|
5499
|
-
}, text);
|
|
5733
|
+
reset() {
|
|
5734
|
+
this.selectedFile = null;
|
|
5735
|
+
this.fileInput.nativeElement.value = '';
|
|
5500
5736
|
}
|
|
5501
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type:
|
|
5502
|
-
static { this.ɵ
|
|
5737
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FileInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5738
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: FileInputComponent, isStandalone: true, selector: "val-file-input", inputs: { props: "props" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: `
|
|
5739
|
+
<div class="file-container">
|
|
5740
|
+
<input style="display: none" type="file" (change)="onFileSelected($event)" #fileInput [accept]="props.accept" />
|
|
5741
|
+
<div class="name-container">
|
|
5742
|
+
<ion-icon [name]="selectedFile ? 'checkmark-circle-outline' : 'alert-circle-outline'"></ion-icon>
|
|
5743
|
+
<val-text
|
|
5744
|
+
style="margin-left: 4px;"
|
|
5745
|
+
[props]="{
|
|
5746
|
+
content: getFileDisplayText(),
|
|
5747
|
+
color: 'dark',
|
|
5748
|
+
bold: false,
|
|
5749
|
+
size: 'medium',
|
|
5750
|
+
}"
|
|
5751
|
+
></val-text>
|
|
5752
|
+
</div>
|
|
5753
|
+
<val-button [props]="contrastButton" (onClick)="fileInput.click()"></val-button>
|
|
5754
|
+
</div>
|
|
5755
|
+
`, isInline: true, styles: [":root{--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}@media (prefers-color-scheme: dark){:root{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.section{margin-top:1rem}.input{margin:.5rem 0}@media (min-width: 768px){.input{margin:.75rem 0}}.file-container{margin-top:.25rem}.name-container{display:flex;flex-direction:row;align-items:center}\n"], dependencies: [{ kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: TextComponent, selector: "val-text", inputs: ["props"] }, { kind: "component", type: ButtonComponent, selector: "val-button", inputs: ["preset", "props"], outputs: ["onClick"] }] }); }
|
|
5503
5756
|
}
|
|
5504
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type:
|
|
5505
|
-
type:
|
|
5506
|
-
args: [{
|
|
5507
|
-
|
|
5757
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FileInputComponent, decorators: [{
|
|
5758
|
+
type: Component,
|
|
5759
|
+
args: [{ selector: 'val-file-input', standalone: true, imports: [IonIcon, TextComponent, ButtonComponent], template: `
|
|
5760
|
+
<div class="file-container">
|
|
5761
|
+
<input style="display: none" type="file" (change)="onFileSelected($event)" #fileInput [accept]="props.accept" />
|
|
5762
|
+
<div class="name-container">
|
|
5763
|
+
<ion-icon [name]="selectedFile ? 'checkmark-circle-outline' : 'alert-circle-outline'"></ion-icon>
|
|
5764
|
+
<val-text
|
|
5765
|
+
style="margin-left: 4px;"
|
|
5766
|
+
[props]="{
|
|
5767
|
+
content: getFileDisplayText(),
|
|
5768
|
+
color: 'dark',
|
|
5769
|
+
bold: false,
|
|
5770
|
+
size: 'medium',
|
|
5771
|
+
}"
|
|
5772
|
+
></val-text>
|
|
5773
|
+
</div>
|
|
5774
|
+
<val-button [props]="contrastButton" (onClick)="fileInput.click()"></val-button>
|
|
5775
|
+
</div>
|
|
5776
|
+
`, styles: [":root{--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}@media (prefers-color-scheme: dark){:root{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.section{margin-top:1rem}.input{margin:.5rem 0}@media (min-width: 768px){.input{margin:.75rem 0}}.file-container{margin-top:.25rem}.name-container{display:flex;flex-direction:row;align-items:center}\n"] }]
|
|
5777
|
+
}], ctorParameters: () => [], propDecorators: { props: [{
|
|
5778
|
+
type: Input
|
|
5779
|
+
}], fileInput: [{
|
|
5780
|
+
type: ViewChild,
|
|
5781
|
+
args: ['fileInput']
|
|
5782
|
+
}] } });
|
|
5508
5783
|
|
|
5509
5784
|
/**
|
|
5510
|
-
*
|
|
5785
|
+
* val-hint
|
|
5511
5786
|
*
|
|
5512
|
-
*
|
|
5513
|
-
* El costo es mínimo porque I18nService usa Signals internamente.
|
|
5787
|
+
* Displays validation error messages for a form input, using Angular forms.
|
|
5514
5788
|
*
|
|
5515
5789
|
* @example
|
|
5516
|
-
*
|
|
5517
|
-
* {{ 'submit' | t }}
|
|
5518
|
-
*
|
|
5519
|
-
* <!-- Busca en namespace específico -->
|
|
5520
|
-
* {{ 'title' | t:'Login' }}
|
|
5521
|
-
*
|
|
5522
|
-
* <!-- Con interpolación -->
|
|
5523
|
-
* {{ 'welcome' | t:'Login':{ name: userName } }}
|
|
5790
|
+
* <val-hint [props]="{ control: myControl, errors: { required: 'Required field' } }"></val-hint>
|
|
5524
5791
|
*
|
|
5525
|
-
*
|
|
5526
|
-
* <val-button [label]="'submit' | t"></val-button>
|
|
5527
|
-
* <val-input [label]="'email' | t:'Login'"></val-input>
|
|
5792
|
+
* @input props: InputMetadata - Configuration for the input (form control, errors, etc.)
|
|
5528
5793
|
*/
|
|
5529
|
-
class
|
|
5530
|
-
constructor() {
|
|
5531
|
-
|
|
5794
|
+
class HintComponent {
|
|
5795
|
+
constructor() { }
|
|
5796
|
+
ngOnInit() { }
|
|
5797
|
+
get shouldShowErrors() {
|
|
5798
|
+
if (this.props.control) {
|
|
5799
|
+
// Normal field with single control
|
|
5800
|
+
return this.props.control.invalid && (this.props.control.touched || this.props.control.dirty);
|
|
5801
|
+
}
|
|
5802
|
+
else if (this.props.fromControl && this.props.toControl) {
|
|
5803
|
+
// NUMBER_FROM_TO field with separate controls
|
|
5804
|
+
const fromInvalid = this.props.fromControl.invalid && (this.props.fromControl.touched || this.props.fromControl.dirty);
|
|
5805
|
+
const toInvalid = this.props.toControl.invalid && (this.props.toControl.touched || this.props.toControl.dirty);
|
|
5806
|
+
return fromInvalid || toInvalid;
|
|
5807
|
+
}
|
|
5808
|
+
return false;
|
|
5532
5809
|
}
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5810
|
+
get Errors() {
|
|
5811
|
+
const keys = Object.keys(this.props.errors || {});
|
|
5812
|
+
const errors = [];
|
|
5813
|
+
keys.map((e) => {
|
|
5814
|
+
if (this.props.control && this.props.control.hasError(e)) {
|
|
5815
|
+
// Normal field
|
|
5816
|
+
errors.push(this.props.errors[e]);
|
|
5817
|
+
}
|
|
5818
|
+
else if (this.props.fromControl && this.props.toControl) {
|
|
5819
|
+
// NUMBER_FROM_TO field - check both controls
|
|
5820
|
+
const fromLabel = this.props.fromLabel || 'Inicial';
|
|
5821
|
+
const toLabel = this.props.toLabel || 'Final';
|
|
5822
|
+
if (this.props.fromControl.hasError(e)) {
|
|
5823
|
+
errors.push(`${fromLabel}: ${this.props.errors[e]}`);
|
|
5824
|
+
}
|
|
5825
|
+
if (this.props.toControl.hasError(e)) {
|
|
5826
|
+
errors.push(`${toLabel}: ${this.props.errors[e]}`);
|
|
5827
|
+
}
|
|
5828
|
+
}
|
|
5829
|
+
});
|
|
5830
|
+
return errors;
|
|
5543
5831
|
}
|
|
5544
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type:
|
|
5545
|
-
static { this.ɵ
|
|
5832
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HintComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5833
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: HintComponent, isStandalone: true, selector: "val-hint", inputs: { props: "props" }, ngImport: i0, template: `
|
|
5834
|
+
<div class="hint-container" *ngIf="shouldShowErrors">
|
|
5835
|
+
<val-text
|
|
5836
|
+
*ngFor="let e of Errors"
|
|
5837
|
+
[props]="{
|
|
5838
|
+
content: e,
|
|
5839
|
+
color: 'danger',
|
|
5840
|
+
bold: false,
|
|
5841
|
+
size: 'small',
|
|
5842
|
+
}"
|
|
5843
|
+
></val-text>
|
|
5844
|
+
</div>
|
|
5845
|
+
`, isInline: true, styles: [":root{--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}@media (prefers-color-scheme: dark){:root{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.section{margin-top:1rem}.input{margin:.5rem 0}@media (min-width: 768px){.input{margin:.75rem 0}}.hint-container{margin-top:.25rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TextComponent, selector: "val-text", inputs: ["props"] }] }); }
|
|
5546
5846
|
}
|
|
5547
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type:
|
|
5548
|
-
type:
|
|
5549
|
-
args: [{
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5847
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HintComponent, decorators: [{
|
|
5848
|
+
type: Component,
|
|
5849
|
+
args: [{ selector: 'val-hint', standalone: true, imports: [CommonModule, TextComponent], template: `
|
|
5850
|
+
<div class="hint-container" *ngIf="shouldShowErrors">
|
|
5851
|
+
<val-text
|
|
5852
|
+
*ngFor="let e of Errors"
|
|
5853
|
+
[props]="{
|
|
5854
|
+
content: e,
|
|
5855
|
+
color: 'danger',
|
|
5856
|
+
bold: false,
|
|
5857
|
+
size: 'small',
|
|
5858
|
+
}"
|
|
5859
|
+
></val-text>
|
|
5860
|
+
</div>
|
|
5861
|
+
`, styles: [":root{--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}@media (prefers-color-scheme: dark){:root{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.section{margin-top:1rem}.input{margin:.5rem 0}@media (min-width: 768px){.input{margin:.75rem 0}}.hint-container{margin-top:.25rem}\n"] }]
|
|
5862
|
+
}], ctorParameters: () => [], propDecorators: { props: [{
|
|
5863
|
+
type: Input
|
|
5864
|
+
}] } });
|
|
5555
5865
|
|
|
5556
5866
|
/**
|
|
5557
|
-
*
|
|
5867
|
+
* val-hour-input
|
|
5558
5868
|
*
|
|
5559
|
-
*
|
|
5560
|
-
* @returns Providers para agregar en app.config.ts
|
|
5869
|
+
* A time picker input integrated with Angular forms, using Ionic's datetime component.
|
|
5561
5870
|
*
|
|
5562
5871
|
* @example
|
|
5563
|
-
*
|
|
5564
|
-
* import { provideValtechI18n } from 'valtech-components';
|
|
5565
|
-
* import { GLOBAL_CONTENT } from './i18n/_global';
|
|
5566
|
-
* import { LOGIN_CONTENT } from './i18n/login.i18n';
|
|
5872
|
+
* <val-hour-input [props]="{ control: myControl }"></val-hour-input>
|
|
5567
5873
|
*
|
|
5568
|
-
*
|
|
5569
|
-
* providers: [
|
|
5570
|
-
* provideValtechI18n({
|
|
5571
|
-
* defaultLanguage: 'es',
|
|
5572
|
-
* supportedLanguages: ['es', 'en'],
|
|
5573
|
-
* detectBrowserLanguage: true,
|
|
5574
|
-
* content: {
|
|
5575
|
-
* '_global': GLOBAL_CONTENT,
|
|
5576
|
-
* 'Login': LOGIN_CONTENT,
|
|
5577
|
-
* }
|
|
5578
|
-
* }),
|
|
5579
|
-
* ]
|
|
5580
|
-
* };
|
|
5874
|
+
* @input props: InputMetadata - Configuration for the time input (form control, etc.)
|
|
5581
5875
|
*/
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
useFactory: (i18n) => {
|
|
5588
|
-
return () => {
|
|
5589
|
-
// Configurar idiomas soportados
|
|
5590
|
-
i18n.setI18nLanguages(mergedConfig.supportedLanguages);
|
|
5591
|
-
// Registrar contenido inicial
|
|
5592
|
-
if (mergedConfig.content && Object.keys(mergedConfig.content).length > 0) {
|
|
5593
|
-
i18n.registerContentBulk(mergedConfig.content);
|
|
5594
|
-
}
|
|
5595
|
-
};
|
|
5596
|
-
},
|
|
5597
|
-
deps: [I18nService],
|
|
5598
|
-
multi: true,
|
|
5599
|
-
},
|
|
5600
|
-
]);
|
|
5876
|
+
class HourInputComponent {
|
|
5877
|
+
constructor() { }
|
|
5878
|
+
ngOnInit() { }
|
|
5879
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HourInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5880
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: HourInputComponent, isStandalone: true, selector: "val-hour-input", inputs: { props: "props" }, ngImport: i0, template: ` <ion-datetime [formControl]="props.control" presentation="time"></ion-datetime>`, isInline: true, styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: IonDatetime, selector: "ion-datetime", inputs: ["cancelText", "clearText", "color", "dayValues", "disabled", "doneText", "firstDayOfWeek", "formatOptions", "highlightedDates", "hourCycle", "hourValues", "isDateEnabled", "locale", "max", "min", "minuteValues", "mode", "monthValues", "multiple", "name", "preferWheel", "presentation", "readonly", "showAdjacentDays", "showClearButton", "showDefaultButtons", "showDefaultTimeLabel", "showDefaultTitle", "size", "titleSelectedDatesFormatter", "value", "yearValues"] }] }); }
|
|
5601
5881
|
}
|
|
5602
|
-
|
|
5603
|
-
|
|
5882
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HourInputComponent, decorators: [{
|
|
5883
|
+
type: Component,
|
|
5884
|
+
args: [{ selector: 'val-hour-input', standalone: true, imports: [ReactiveFormsModule, IonDatetime], template: ` <ion-datetime [formControl]="props.control" presentation="time"></ion-datetime>` }]
|
|
5885
|
+
}], ctorParameters: () => [], propDecorators: { props: [{
|
|
5886
|
+
type: Input
|
|
5887
|
+
}] } });
|
|
5604
5888
|
|
|
5605
5889
|
/**
|
|
5606
5890
|
* val-popover-selector
|
|
@@ -5640,6 +5924,7 @@ class PopoverSelectorComponent {
|
|
|
5640
5924
|
* Emits the selected value(s).
|
|
5641
5925
|
*/
|
|
5642
5926
|
this.selectionChange = new EventEmitter();
|
|
5927
|
+
this.i18n = inject(I18nService);
|
|
5643
5928
|
// Register required icons
|
|
5644
5929
|
addIcons({ chevronDown });
|
|
5645
5930
|
}
|
|
@@ -5647,19 +5932,19 @@ class PopoverSelectorComponent {
|
|
|
5647
5932
|
* Get placeholder text.
|
|
5648
5933
|
*/
|
|
5649
5934
|
getPlaceholderText() {
|
|
5650
|
-
return this.props.placeholder || '
|
|
5935
|
+
return this.props.placeholder || this.i18n.t('selectPlaceholder');
|
|
5651
5936
|
}
|
|
5652
5937
|
/**
|
|
5653
5938
|
* Get cancel text.
|
|
5654
5939
|
*/
|
|
5655
5940
|
getCancelText() {
|
|
5656
|
-
return this.props.cancelText || '
|
|
5941
|
+
return this.props.cancelText || this.i18n.t('cancel');
|
|
5657
5942
|
}
|
|
5658
5943
|
/**
|
|
5659
5944
|
* Get ok text.
|
|
5660
5945
|
*/
|
|
5661
5946
|
getOkText() {
|
|
5662
|
-
return this.props.okText || '
|
|
5947
|
+
return this.props.okText || this.i18n.t('ok');
|
|
5663
5948
|
}
|
|
5664
5949
|
/**
|
|
5665
5950
|
* Handle selection change from the ion-select.
|
|
@@ -5687,7 +5972,7 @@ class PopoverSelectorComponent {
|
|
|
5687
5972
|
const option = this.props.options.find(opt => opt.value === this.props.selectedValue[0]);
|
|
5688
5973
|
return option?.label || this.props.selectedValue[0];
|
|
5689
5974
|
}
|
|
5690
|
-
return `${this.props.selectedValue.length}
|
|
5975
|
+
return `${this.props.selectedValue.length} ${this.i18n.t('selected')}`;
|
|
5691
5976
|
}
|
|
5692
5977
|
// Single selection
|
|
5693
5978
|
const selectedOption = this.props.options.find(opt => opt.value === this.props.selectedValue);
|
|
@@ -5854,9 +6139,9 @@ class LanguageSelectorComponent {
|
|
|
5854
6139
|
this.popoverProps = {
|
|
5855
6140
|
options,
|
|
5856
6141
|
selectedValue: currentLanguage,
|
|
5857
|
-
label: this.props.showLabel !== false ? (this.props.label || '
|
|
6142
|
+
label: this.props.showLabel !== false ? (this.props.label || this.i18n.t('language')) : undefined,
|
|
5858
6143
|
icon: 'language',
|
|
5859
|
-
placeholder: '
|
|
6144
|
+
placeholder: this.i18n.t('selectLanguage'),
|
|
5860
6145
|
color: this.props.color || 'medium',
|
|
5861
6146
|
size: this.props.size || 'default',
|
|
5862
6147
|
fill: this.props.fill || 'outline',
|
|
@@ -5866,8 +6151,8 @@ class LanguageSelectorComponent {
|
|
|
5866
6151
|
interface: 'popover',
|
|
5867
6152
|
showCheckmark: true,
|
|
5868
6153
|
multiple: false,
|
|
5869
|
-
cancelText: '
|
|
5870
|
-
okText: '
|
|
6154
|
+
cancelText: this.i18n.t('cancel'),
|
|
6155
|
+
okText: this.i18n.t('ok'),
|
|
5871
6156
|
};
|
|
5872
6157
|
}
|
|
5873
6158
|
/** Get display name for a language code (public for template access) */
|
|
@@ -7285,6 +7570,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
7285
7570
|
* @output blurEvent - Emits when the searchbar loses focus.
|
|
7286
7571
|
*/
|
|
7287
7572
|
class SearchbarComponent {
|
|
7573
|
+
/** Get placeholder text */
|
|
7574
|
+
getPlaceholder() {
|
|
7575
|
+
return this.placeholder || this.i18n.t('search');
|
|
7576
|
+
}
|
|
7577
|
+
/** Get cancel button text */
|
|
7578
|
+
getCancelText() {
|
|
7579
|
+
return this.cancelText || this.i18n.t('cancel');
|
|
7580
|
+
}
|
|
7288
7581
|
constructor() {
|
|
7289
7582
|
/**
|
|
7290
7583
|
* Emits the search term on input.
|
|
@@ -7298,6 +7591,7 @@ class SearchbarComponent {
|
|
|
7298
7591
|
* Emits when the searchbar loses focus.
|
|
7299
7592
|
*/
|
|
7300
7593
|
this.blurEvent = new EventEmitter();
|
|
7594
|
+
this.i18n = inject(I18nService);
|
|
7301
7595
|
}
|
|
7302
7596
|
onSearch($event) {
|
|
7303
7597
|
const searchTerm = $event.detail.value;
|
|
@@ -7310,14 +7604,14 @@ class SearchbarComponent {
|
|
|
7310
7604
|
this.blurEvent.emit();
|
|
7311
7605
|
}
|
|
7312
7606
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SearchbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7313
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SearchbarComponent, isStandalone: true, selector: "val-searchbar", inputs: { disabled: "disabled" }, outputs: { filterEvent: "filterEvent", focusEvent: "focusEvent", blurEvent: "blurEvent" }, ngImport: i0, template: `
|
|
7607
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SearchbarComponent, isStandalone: true, selector: "val-searchbar", inputs: { disabled: "disabled", placeholder: "placeholder", cancelText: "cancelText" }, outputs: { filterEvent: "filterEvent", focusEvent: "focusEvent", blurEvent: "blurEvent" }, ngImport: i0, template: `
|
|
7314
7608
|
<ion-searchbar
|
|
7315
7609
|
mode="ios"
|
|
7316
7610
|
debounce="500"
|
|
7317
|
-
placeholder="
|
|
7611
|
+
[placeholder]="getPlaceholder()"
|
|
7318
7612
|
[disabled]="disabled"
|
|
7319
7613
|
showCancelButton="focus"
|
|
7320
|
-
cancelButtonText="
|
|
7614
|
+
[cancelButtonText]="getCancelText()"
|
|
7321
7615
|
(ionInput)="onSearch($event)"
|
|
7322
7616
|
(ionBlur)="onBlur()"
|
|
7323
7617
|
(ionFocus)="onFocus()"
|
|
@@ -7331,10 +7625,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
7331
7625
|
<ion-searchbar
|
|
7332
7626
|
mode="ios"
|
|
7333
7627
|
debounce="500"
|
|
7334
|
-
placeholder="
|
|
7628
|
+
[placeholder]="getPlaceholder()"
|
|
7335
7629
|
[disabled]="disabled"
|
|
7336
7630
|
showCancelButton="focus"
|
|
7337
|
-
cancelButtonText="
|
|
7631
|
+
[cancelButtonText]="getCancelText()"
|
|
7338
7632
|
(ionInput)="onSearch($event)"
|
|
7339
7633
|
(ionBlur)="onBlur()"
|
|
7340
7634
|
(ionFocus)="onFocus()"
|
|
@@ -7343,6 +7637,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
7343
7637
|
`, styles: [":root{--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}@media (prefers-color-scheme: dark){:root{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}ion-searchbar{--cancel-button-color: var(--ion-color-dark);--background: var(--ion-color-light);font-family:var(--ion-default-font),Arial,sans-serif}\n"] }]
|
|
7344
7638
|
}], ctorParameters: () => [], propDecorators: { disabled: [{
|
|
7345
7639
|
type: Input
|
|
7640
|
+
}], placeholder: [{
|
|
7641
|
+
type: Input
|
|
7642
|
+
}], cancelText: [{
|
|
7643
|
+
type: Input
|
|
7346
7644
|
}], filterEvent: [{
|
|
7347
7645
|
type: Output
|
|
7348
7646
|
}], focusEvent: [{
|
|
@@ -7368,20 +7666,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
7368
7666
|
* @input props: InputMetadata - Configuration for the select input (form control, label, options, etc.)
|
|
7369
7667
|
*/
|
|
7370
7668
|
class SearchSelectorComponent {
|
|
7669
|
+
constructor() {
|
|
7670
|
+
this.i18n = inject(I18nService);
|
|
7671
|
+
}
|
|
7371
7672
|
ngOnInit() {
|
|
7372
7673
|
if (this.props?.withDefault || this.props?.value) {
|
|
7373
7674
|
applyDefaultValueToControl(this.props);
|
|
7374
7675
|
}
|
|
7375
|
-
// Set modal header from props or use label as fallback
|
|
7376
|
-
const headerText = this.props.modalHeader || this.props.label || '
|
|
7676
|
+
// Set modal header from props or use label as fallback, then i18n default
|
|
7677
|
+
const headerText = this.props.modalHeader || this.props.label || this.i18n.t('selectOption');
|
|
7377
7678
|
this.customModalOptions = {
|
|
7378
7679
|
header: headerText,
|
|
7379
7680
|
breakpoints: [0, 0.6],
|
|
7380
7681
|
initialBreakpoint: 0.6,
|
|
7381
7682
|
};
|
|
7382
|
-
// Set button texts from props or use defaults
|
|
7383
|
-
this.cancelText = this.props.cancelText || '
|
|
7384
|
-
this.okText = this.props.okText || '
|
|
7683
|
+
// Set button texts from props or use i18n defaults
|
|
7684
|
+
this.cancelText = this.props.cancelText || this.i18n.t('cancel');
|
|
7685
|
+
this.okText = this.props.okText || this.i18n.t('ok');
|
|
7385
7686
|
}
|
|
7386
7687
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SearchSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7387
7688
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SearchSelectorComponent, isStandalone: true, selector: "val-select-input", inputs: { props: "props" }, ngImport: i0, template: `
|
|
@@ -7452,6 +7753,7 @@ class SelectSearchComponent {
|
|
|
7452
7753
|
this.placeholder = 'Seleccione una opción';
|
|
7453
7754
|
this.icon = inject(IconService);
|
|
7454
7755
|
this.changeDetector = inject(ChangeDetectorRef);
|
|
7756
|
+
this.i18n = inject(I18nService);
|
|
7455
7757
|
this.searchTerm = '';
|
|
7456
7758
|
this.filteredItems = [];
|
|
7457
7759
|
this.selectedItems = [];
|
|
@@ -7459,6 +7761,18 @@ class SelectSearchComponent {
|
|
|
7459
7761
|
this.previousOptions = [];
|
|
7460
7762
|
this.isProcessingChanges = false;
|
|
7461
7763
|
}
|
|
7764
|
+
/** Get close button text */
|
|
7765
|
+
getCloseText() {
|
|
7766
|
+
return this.i18n.t('close');
|
|
7767
|
+
}
|
|
7768
|
+
/** Get no results text */
|
|
7769
|
+
getNoResultsText() {
|
|
7770
|
+
return this.i18n.t('noResults');
|
|
7771
|
+
}
|
|
7772
|
+
/** Get items selected text */
|
|
7773
|
+
getItemsSelectedText(count) {
|
|
7774
|
+
return `${count} ${this.i18n.t('itemsSelected')}`;
|
|
7775
|
+
}
|
|
7462
7776
|
ngOnInit() {
|
|
7463
7777
|
this.applyDefaultValue();
|
|
7464
7778
|
this.initializeItems();
|
|
@@ -7662,7 +7976,7 @@ class SelectSearchComponent {
|
|
|
7662
7976
|
this.displayValue = this.selectedItems[0][this.labelProperty];
|
|
7663
7977
|
}
|
|
7664
7978
|
else {
|
|
7665
|
-
this.displayValue =
|
|
7979
|
+
this.displayValue = this.getItemsSelectedText(this.selectedItems.length);
|
|
7666
7980
|
}
|
|
7667
7981
|
}
|
|
7668
7982
|
else {
|
|
@@ -7721,7 +8035,7 @@ class SelectSearchComponent {
|
|
|
7721
8035
|
<ion-toolbar>
|
|
7722
8036
|
<ion-title>{{ label }}</ion-title>
|
|
7723
8037
|
<ion-buttons slot="end">
|
|
7724
|
-
<ion-button (click)="cancelModal()">
|
|
8038
|
+
<ion-button (click)="cancelModal()">{{ getCloseText() }}</ion-button>
|
|
7725
8039
|
</ion-buttons>
|
|
7726
8040
|
</ion-toolbar>
|
|
7727
8041
|
<ion-toolbar>
|
|
@@ -7735,13 +8049,13 @@ class SelectSearchComponent {
|
|
|
7735
8049
|
<ion-icon *ngIf="isItemSelected(item)" name="checkmark-outline" slot="end" color="primary"></ion-icon>
|
|
7736
8050
|
</ion-item>
|
|
7737
8051
|
<ion-item *ngIf="filteredItems.length === 0" lines="none">
|
|
7738
|
-
<ion-label color="dark">
|
|
8052
|
+
<ion-label color="dark">{{ getNoResultsText() }}</ion-label>
|
|
7739
8053
|
</ion-item>
|
|
7740
8054
|
</ion-list>
|
|
7741
8055
|
</ion-content>
|
|
7742
8056
|
</ng-template>
|
|
7743
8057
|
</ion-modal>
|
|
7744
|
-
`, isInline: true, styles: ["ion-header{padding:8px 8px 0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: IonicModule }, { kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonInput, selector: "ion-input", inputs: ["autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearInputIcon", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: i2.IonModal, selector: "ion-modal" }, { kind: "directive", type: i2.TextValueAccessor, selector: "ion-input:not([type=number]),ion-input-otp[type=text],ion-textarea,ion-searchbar" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "component", type: SearchbarComponent, selector: "val-searchbar", inputs: ["disabled"], outputs: ["filterEvent", "focusEvent", "blurEvent"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] }); }
|
|
8058
|
+
`, isInline: true, styles: ["ion-header{padding:8px 8px 0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: IonicModule }, { kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonInput, selector: "ion-input", inputs: ["autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearInputIcon", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: i2.IonModal, selector: "ion-modal" }, { kind: "directive", type: i2.TextValueAccessor, selector: "ion-input:not([type=number]),ion-input-otp[type=text],ion-textarea,ion-searchbar" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "component", type: SearchbarComponent, selector: "val-searchbar", inputs: ["disabled", "placeholder", "cancelText"], outputs: ["filterEvent", "focusEvent", "blurEvent"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] }); }
|
|
7745
8059
|
}
|
|
7746
8060
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SelectSearchComponent, decorators: [{
|
|
7747
8061
|
type: Component,
|
|
@@ -7768,7 +8082,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
7768
8082
|
<ion-toolbar>
|
|
7769
8083
|
<ion-title>{{ label }}</ion-title>
|
|
7770
8084
|
<ion-buttons slot="end">
|
|
7771
|
-
<ion-button (click)="cancelModal()">
|
|
8085
|
+
<ion-button (click)="cancelModal()">{{ getCloseText() }}</ion-button>
|
|
7772
8086
|
</ion-buttons>
|
|
7773
8087
|
</ion-toolbar>
|
|
7774
8088
|
<ion-toolbar>
|
|
@@ -7782,7 +8096,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
7782
8096
|
<ion-icon *ngIf="isItemSelected(item)" name="checkmark-outline" slot="end" color="primary"></ion-icon>
|
|
7783
8097
|
</ion-item>
|
|
7784
8098
|
<ion-item *ngIf="filteredItems.length === 0" lines="none">
|
|
7785
|
-
<ion-label color="dark">
|
|
8099
|
+
<ion-label color="dark">{{ getNoResultsText() }}</ion-label>
|
|
7786
8100
|
</ion-item>
|
|
7787
8101
|
</ion-list>
|
|
7788
8102
|
</ion-content>
|
|
@@ -8009,6 +8323,7 @@ class CodeDisplayComponent {
|
|
|
8009
8323
|
constructor(cdr) {
|
|
8010
8324
|
this.cdr = cdr;
|
|
8011
8325
|
this.toast = inject(ToastController);
|
|
8326
|
+
this.i18n = inject(I18nService);
|
|
8012
8327
|
this.selectedTab = 0;
|
|
8013
8328
|
}
|
|
8014
8329
|
ngOnChanges(changes) {
|
|
@@ -8036,7 +8351,7 @@ class CodeDisplayComponent {
|
|
|
8036
8351
|
try {
|
|
8037
8352
|
const code = this.props.tabs.length > 0 ? this.props.tabs[this.selectedTab]?.code : this.props.code;
|
|
8038
8353
|
await Clipboard.write({ string: code || '' });
|
|
8039
|
-
this.presentToast('
|
|
8354
|
+
this.presentToast(this.i18n.t('copiedToClipboard'));
|
|
8040
8355
|
}
|
|
8041
8356
|
catch (error) {
|
|
8042
8357
|
console.error('Error al copiar al portapapeles:', error);
|
|
@@ -10233,6 +10548,7 @@ class MultiSelectSearchComponent {
|
|
|
10233
10548
|
this.placeholder = 'Seleccione opciones';
|
|
10234
10549
|
this.icon = inject(IconService);
|
|
10235
10550
|
this.changeDetector = inject(ChangeDetectorRef);
|
|
10551
|
+
this.i18n = inject(I18nService);
|
|
10236
10552
|
this.searchTerm = '';
|
|
10237
10553
|
this.filteredItems = [];
|
|
10238
10554
|
this.selectedItems = [];
|
|
@@ -10240,6 +10556,30 @@ class MultiSelectSearchComponent {
|
|
|
10240
10556
|
this.previousOptions = [];
|
|
10241
10557
|
this.isProcessingChanges = false;
|
|
10242
10558
|
}
|
|
10559
|
+
/** Get close button text */
|
|
10560
|
+
getCloseText() {
|
|
10561
|
+
return this.i18n.t('close');
|
|
10562
|
+
}
|
|
10563
|
+
/** Get no results text */
|
|
10564
|
+
getNoResultsText() {
|
|
10565
|
+
return this.i18n.t('noResults');
|
|
10566
|
+
}
|
|
10567
|
+
/** Get select all text */
|
|
10568
|
+
getSelectAllText() {
|
|
10569
|
+
return this.i18n.t('selectAll');
|
|
10570
|
+
}
|
|
10571
|
+
/** Get clear text */
|
|
10572
|
+
getClearText() {
|
|
10573
|
+
return this.i18n.t('clear');
|
|
10574
|
+
}
|
|
10575
|
+
/** Get apply text */
|
|
10576
|
+
getApplyText() {
|
|
10577
|
+
return this.i18n.t('apply');
|
|
10578
|
+
}
|
|
10579
|
+
/** Get items selected text */
|
|
10580
|
+
getItemsSelectedText(count) {
|
|
10581
|
+
return `${count} ${this.i18n.t('itemsSelected')}`;
|
|
10582
|
+
}
|
|
10243
10583
|
ngOnInit() {
|
|
10244
10584
|
this.applyDefaultValue();
|
|
10245
10585
|
this.initializeItems();
|
|
@@ -10452,7 +10792,7 @@ class MultiSelectSearchComponent {
|
|
|
10452
10792
|
this.displayValue = this.selectedItems[0][this.labelProperty];
|
|
10453
10793
|
}
|
|
10454
10794
|
else {
|
|
10455
|
-
this.displayValue =
|
|
10795
|
+
this.displayValue = this.getItemsSelectedText(this.selectedItems.length);
|
|
10456
10796
|
}
|
|
10457
10797
|
}
|
|
10458
10798
|
applyChanges() {
|
|
@@ -10509,7 +10849,7 @@ class MultiSelectSearchComponent {
|
|
|
10509
10849
|
<ion-toolbar>
|
|
10510
10850
|
<ion-title>{{ label }}</ion-title>
|
|
10511
10851
|
<ion-buttons slot="end">
|
|
10512
|
-
<ion-button (click)="cancelModal()">
|
|
10852
|
+
<ion-button (click)="cancelModal()">{{ getCloseText() }}</ion-button>
|
|
10513
10853
|
</ion-buttons>
|
|
10514
10854
|
</ion-toolbar>
|
|
10515
10855
|
<ion-toolbar>
|
|
@@ -10519,22 +10859,22 @@ class MultiSelectSearchComponent {
|
|
|
10519
10859
|
<ion-content>
|
|
10520
10860
|
<!-- Action buttons for multi-select -->
|
|
10521
10861
|
<div class="actions-container" style="padding: 16px; border-bottom: 1px solid var(--ion-color-light-shade);">
|
|
10522
|
-
<ion-button
|
|
10523
|
-
fill="clear"
|
|
10524
|
-
size="small"
|
|
10862
|
+
<ion-button
|
|
10863
|
+
fill="clear"
|
|
10864
|
+
size="small"
|
|
10525
10865
|
(click)="selectAll()"
|
|
10526
10866
|
[disabled]="filteredItems.length === 0"
|
|
10527
10867
|
>
|
|
10528
|
-
|
|
10868
|
+
{{ getSelectAllText() }}
|
|
10529
10869
|
</ion-button>
|
|
10530
|
-
<ion-button
|
|
10531
|
-
fill="clear"
|
|
10532
|
-
size="small"
|
|
10533
|
-
color="medium"
|
|
10870
|
+
<ion-button
|
|
10871
|
+
fill="clear"
|
|
10872
|
+
size="small"
|
|
10873
|
+
color="medium"
|
|
10534
10874
|
(click)="clearAll()"
|
|
10535
10875
|
[disabled]="selectedItems.length === 0"
|
|
10536
10876
|
>
|
|
10537
|
-
|
|
10877
|
+
{{ getClearText() }}
|
|
10538
10878
|
</ion-button>
|
|
10539
10879
|
</div>
|
|
10540
10880
|
|
|
@@ -10547,20 +10887,20 @@ class MultiSelectSearchComponent {
|
|
|
10547
10887
|
<ion-label>{{ item[labelProperty] }}</ion-label>
|
|
10548
10888
|
</ion-item>
|
|
10549
10889
|
<ion-item *ngIf="filteredItems.length === 0" lines="none">
|
|
10550
|
-
<ion-label color="dark">
|
|
10890
|
+
<ion-label color="dark">{{ getNoResultsText() }}</ion-label>
|
|
10551
10891
|
</ion-item>
|
|
10552
10892
|
</ion-list>
|
|
10553
10893
|
</ion-content>
|
|
10554
10894
|
<ion-footer>
|
|
10555
10895
|
<ion-toolbar>
|
|
10556
10896
|
<ion-button expand="full" (click)="applyAndClose()">
|
|
10557
|
-
|
|
10897
|
+
{{ getApplyText() }}
|
|
10558
10898
|
</ion-button>
|
|
10559
10899
|
</ion-toolbar>
|
|
10560
10900
|
</ion-footer>
|
|
10561
10901
|
</ng-template>
|
|
10562
10902
|
</ion-modal>
|
|
10563
|
-
`, isInline: true, styles: ["ion-header{padding:8px 8px 0}.actions-container{display:flex;justify-content:space-between;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: IonicModule }, { kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2.IonCheckbox, selector: "ion-checkbox", inputs: ["alignment", "checked", "color", "disabled", "errorText", "helperText", "indeterminate", "justify", "labelPlacement", "mode", "name", "required", "value"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonInput, selector: "ion-input", inputs: ["autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearInputIcon", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: i2.IonModal, selector: "ion-modal" }, { kind: "directive", type: i2.BooleanValueAccessor, selector: "ion-checkbox,ion-toggle" }, { kind: "directive", type: i2.TextValueAccessor, selector: "ion-input:not([type=number]),ion-input-otp[type=text],ion-textarea,ion-searchbar" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "component", type: SearchbarComponent, selector: "val-searchbar", inputs: ["disabled"], outputs: ["filterEvent", "focusEvent", "blurEvent"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] }); }
|
|
10903
|
+
`, isInline: true, styles: ["ion-header{padding:8px 8px 0}.actions-container{display:flex;justify-content:space-between;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: IonicModule }, { kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2.IonCheckbox, selector: "ion-checkbox", inputs: ["alignment", "checked", "color", "disabled", "errorText", "helperText", "indeterminate", "justify", "labelPlacement", "mode", "name", "required", "value"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonInput, selector: "ion-input", inputs: ["autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearInputIcon", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: i2.IonModal, selector: "ion-modal" }, { kind: "directive", type: i2.BooleanValueAccessor, selector: "ion-checkbox,ion-toggle" }, { kind: "directive", type: i2.TextValueAccessor, selector: "ion-input:not([type=number]),ion-input-otp[type=text],ion-textarea,ion-searchbar" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "component", type: SearchbarComponent, selector: "val-searchbar", inputs: ["disabled", "placeholder", "cancelText"], outputs: ["filterEvent", "focusEvent", "blurEvent"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] }); }
|
|
10564
10904
|
}
|
|
10565
10905
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MultiSelectSearchComponent, decorators: [{
|
|
10566
10906
|
type: Component,
|
|
@@ -10587,7 +10927,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
10587
10927
|
<ion-toolbar>
|
|
10588
10928
|
<ion-title>{{ label }}</ion-title>
|
|
10589
10929
|
<ion-buttons slot="end">
|
|
10590
|
-
<ion-button (click)="cancelModal()">
|
|
10930
|
+
<ion-button (click)="cancelModal()">{{ getCloseText() }}</ion-button>
|
|
10591
10931
|
</ion-buttons>
|
|
10592
10932
|
</ion-toolbar>
|
|
10593
10933
|
<ion-toolbar>
|
|
@@ -10597,22 +10937,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
10597
10937
|
<ion-content>
|
|
10598
10938
|
<!-- Action buttons for multi-select -->
|
|
10599
10939
|
<div class="actions-container" style="padding: 16px; border-bottom: 1px solid var(--ion-color-light-shade);">
|
|
10600
|
-
<ion-button
|
|
10601
|
-
fill="clear"
|
|
10602
|
-
size="small"
|
|
10940
|
+
<ion-button
|
|
10941
|
+
fill="clear"
|
|
10942
|
+
size="small"
|
|
10603
10943
|
(click)="selectAll()"
|
|
10604
10944
|
[disabled]="filteredItems.length === 0"
|
|
10605
10945
|
>
|
|
10606
|
-
|
|
10946
|
+
{{ getSelectAllText() }}
|
|
10607
10947
|
</ion-button>
|
|
10608
|
-
<ion-button
|
|
10609
|
-
fill="clear"
|
|
10610
|
-
size="small"
|
|
10611
|
-
color="medium"
|
|
10948
|
+
<ion-button
|
|
10949
|
+
fill="clear"
|
|
10950
|
+
size="small"
|
|
10951
|
+
color="medium"
|
|
10612
10952
|
(click)="clearAll()"
|
|
10613
10953
|
[disabled]="selectedItems.length === 0"
|
|
10614
10954
|
>
|
|
10615
|
-
|
|
10955
|
+
{{ getClearText() }}
|
|
10616
10956
|
</ion-button>
|
|
10617
10957
|
</div>
|
|
10618
10958
|
|
|
@@ -10625,14 +10965,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
10625
10965
|
<ion-label>{{ item[labelProperty] }}</ion-label>
|
|
10626
10966
|
</ion-item>
|
|
10627
10967
|
<ion-item *ngIf="filteredItems.length === 0" lines="none">
|
|
10628
|
-
<ion-label color="dark">
|
|
10968
|
+
<ion-label color="dark">{{ getNoResultsText() }}</ion-label>
|
|
10629
10969
|
</ion-item>
|
|
10630
10970
|
</ion-list>
|
|
10631
10971
|
</ion-content>
|
|
10632
10972
|
<ion-footer>
|
|
10633
10973
|
<ion-toolbar>
|
|
10634
10974
|
<ion-button expand="full" (click)="applyAndClose()">
|
|
10635
|
-
|
|
10975
|
+
{{ getApplyText() }}
|
|
10636
10976
|
</ion-button>
|
|
10637
10977
|
</ion-toolbar>
|
|
10638
10978
|
</ion-footer>
|
|
@@ -11700,8 +12040,32 @@ class DateRangeInputComponent {
|
|
|
11700
12040
|
this.startDatetimeId = `start-datetime-${Math.random().toString(36).substr(2, 9)}`;
|
|
11701
12041
|
this.endDatetimeId = `end-datetime-${Math.random().toString(36).substr(2, 9)}`;
|
|
11702
12042
|
this.showDayCount = true;
|
|
12043
|
+
this.i18n = inject(I18nService);
|
|
11703
12044
|
this.valueSubscription = null;
|
|
11704
12045
|
}
|
|
12046
|
+
/** Get done button text from props or i18n */
|
|
12047
|
+
getDoneText() {
|
|
12048
|
+
return this.props.doneText || this.i18n.t('ok');
|
|
12049
|
+
}
|
|
12050
|
+
/** Get cancel button text from props or i18n */
|
|
12051
|
+
getCancelText() {
|
|
12052
|
+
return this.props.cancelText || this.i18n.t('cancel');
|
|
12053
|
+
}
|
|
12054
|
+
/** Get start date fallback label */
|
|
12055
|
+
getStartDateFallback() {
|
|
12056
|
+
return this.i18n.t('startDate', '_global') || 'Start date';
|
|
12057
|
+
}
|
|
12058
|
+
/** Get end date fallback label */
|
|
12059
|
+
getEndDateFallback() {
|
|
12060
|
+
return this.i18n.t('endDate', '_global') || 'End date';
|
|
12061
|
+
}
|
|
12062
|
+
/** Get day/days label based on count */
|
|
12063
|
+
getDayLabel() {
|
|
12064
|
+
if (this.dayCount === 1) {
|
|
12065
|
+
return this.i18n.t('day', '_global') || 'day';
|
|
12066
|
+
}
|
|
12067
|
+
return this.i18n.t('days', '_global') || 'days';
|
|
12068
|
+
}
|
|
11705
12069
|
ngOnInit() {
|
|
11706
12070
|
// Use provided controls or internal ones
|
|
11707
12071
|
if (this.props.startControl) {
|
|
@@ -11874,11 +12238,11 @@ class DateRangeInputComponent {
|
|
|
11874
12238
|
[min]="getMinDate()"
|
|
11875
12239
|
[max]="getMaxStartDate()"
|
|
11876
12240
|
[showDefaultButtons]="true"
|
|
11877
|
-
[doneText]="
|
|
11878
|
-
[cancelText]="
|
|
12241
|
+
[doneText]="getDoneText()"
|
|
12242
|
+
[cancelText]="getCancelText()"
|
|
11879
12243
|
(ionChange)="onStartDateChange($event)"
|
|
11880
12244
|
>
|
|
11881
|
-
<span slot="title">{{ getStartLabel() ||
|
|
12245
|
+
<span slot="title">{{ getStartLabel() || getStartDateFallback() }}</span>
|
|
11882
12246
|
</ion-datetime>
|
|
11883
12247
|
</ng-template>
|
|
11884
12248
|
</ion-modal>
|
|
@@ -11908,11 +12272,11 @@ class DateRangeInputComponent {
|
|
|
11908
12272
|
[min]="getMinEndDate()"
|
|
11909
12273
|
[max]="getMaxDate()"
|
|
11910
12274
|
[showDefaultButtons]="true"
|
|
11911
|
-
[doneText]="
|
|
11912
|
-
[cancelText]="
|
|
12275
|
+
[doneText]="getDoneText()"
|
|
12276
|
+
[cancelText]="getCancelText()"
|
|
11913
12277
|
(ionChange)="onEndDateChange($event)"
|
|
11914
12278
|
>
|
|
11915
|
-
<span slot="title">{{ getEndLabel() ||
|
|
12279
|
+
<span slot="title">{{ getEndLabel() || getEndDateFallback() }}</span>
|
|
11916
12280
|
</ion-datetime>
|
|
11917
12281
|
</ng-template>
|
|
11918
12282
|
</ion-modal>
|
|
@@ -11921,7 +12285,7 @@ class DateRangeInputComponent {
|
|
|
11921
12285
|
|
|
11922
12286
|
@if (showDayCount && dayCount !== null) {
|
|
11923
12287
|
<div class="day-count">
|
|
11924
|
-
{{ dayCount }} {{
|
|
12288
|
+
{{ dayCount }} {{ getDayLabel() }}
|
|
11925
12289
|
</div>
|
|
11926
12290
|
}
|
|
11927
12291
|
|
|
@@ -11972,11 +12336,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
11972
12336
|
[min]="getMinDate()"
|
|
11973
12337
|
[max]="getMaxStartDate()"
|
|
11974
12338
|
[showDefaultButtons]="true"
|
|
11975
|
-
[doneText]="
|
|
11976
|
-
[cancelText]="
|
|
12339
|
+
[doneText]="getDoneText()"
|
|
12340
|
+
[cancelText]="getCancelText()"
|
|
11977
12341
|
(ionChange)="onStartDateChange($event)"
|
|
11978
12342
|
>
|
|
11979
|
-
<span slot="title">{{ getStartLabel() ||
|
|
12343
|
+
<span slot="title">{{ getStartLabel() || getStartDateFallback() }}</span>
|
|
11980
12344
|
</ion-datetime>
|
|
11981
12345
|
</ng-template>
|
|
11982
12346
|
</ion-modal>
|
|
@@ -12006,11 +12370,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
12006
12370
|
[min]="getMinEndDate()"
|
|
12007
12371
|
[max]="getMaxDate()"
|
|
12008
12372
|
[showDefaultButtons]="true"
|
|
12009
|
-
[doneText]="
|
|
12010
|
-
[cancelText]="
|
|
12373
|
+
[doneText]="getDoneText()"
|
|
12374
|
+
[cancelText]="getCancelText()"
|
|
12011
12375
|
(ionChange)="onEndDateChange($event)"
|
|
12012
12376
|
>
|
|
12013
|
-
<span slot="title">{{ getEndLabel() ||
|
|
12377
|
+
<span slot="title">{{ getEndLabel() || getEndDateFallback() }}</span>
|
|
12014
12378
|
</ion-datetime>
|
|
12015
12379
|
</ng-template>
|
|
12016
12380
|
</ion-modal>
|
|
@@ -12019,7 +12383,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
12019
12383
|
|
|
12020
12384
|
@if (showDayCount && dayCount !== null) {
|
|
12021
12385
|
<div class="day-count">
|
|
12022
|
-
{{ dayCount }} {{
|
|
12386
|
+
{{ dayCount }} {{ getDayLabel() }}
|
|
12023
12387
|
</div>
|
|
12024
12388
|
}
|
|
12025
12389
|
|
|
@@ -14186,8 +14550,25 @@ class ParticipantCardComponent {
|
|
|
14186
14550
|
constructor() {
|
|
14187
14551
|
this.cardClick = new EventEmitter();
|
|
14188
14552
|
this.actionClick = new EventEmitter();
|
|
14553
|
+
this.i18n = inject(I18nService);
|
|
14189
14554
|
this.showAllTickets = false;
|
|
14190
14555
|
}
|
|
14556
|
+
/** Get winner badge text */
|
|
14557
|
+
getWinnerText() {
|
|
14558
|
+
return this.i18n.t('winner');
|
|
14559
|
+
}
|
|
14560
|
+
/** Get tickets count text */
|
|
14561
|
+
getTicketsCountText(count) {
|
|
14562
|
+
return `${count} ${count !== 1 ? this.i18n.t('tickets') : this.i18n.t('ticket')}`;
|
|
14563
|
+
}
|
|
14564
|
+
/** Get more tickets text */
|
|
14565
|
+
getMoreText(count) {
|
|
14566
|
+
return `+${count} ${this.i18n.t('more')}`;
|
|
14567
|
+
}
|
|
14568
|
+
/** Get notes label */
|
|
14569
|
+
getNotesLabel() {
|
|
14570
|
+
return this.i18n.t('notes');
|
|
14571
|
+
}
|
|
14191
14572
|
get ticketNumbers() {
|
|
14192
14573
|
return this.props.participant.tickets || [];
|
|
14193
14574
|
}
|
|
@@ -14312,7 +14693,7 @@ class ParticipantCardComponent {
|
|
|
14312
14693
|
@if (props.participant.isWinner && props.highlightWinner !== false) {
|
|
14313
14694
|
<div class="winner-badge">
|
|
14314
14695
|
<ion-icon name="trophy-outline"></ion-icon>
|
|
14315
|
-
<span>
|
|
14696
|
+
<span>{{ getWinnerText() }}</span>
|
|
14316
14697
|
</div>
|
|
14317
14698
|
}
|
|
14318
14699
|
|
|
@@ -14397,7 +14778,7 @@ class ParticipantCardComponent {
|
|
|
14397
14778
|
<div class="tickets-section">
|
|
14398
14779
|
<div class="tickets-header">
|
|
14399
14780
|
<ion-icon name="ticket-outline"></ion-icon>
|
|
14400
|
-
<span>{{ ticketNumbers.length }}
|
|
14781
|
+
<span>{{ getTicketsCountText(ticketNumbers.length) }}</span>
|
|
14401
14782
|
</div>
|
|
14402
14783
|
|
|
14403
14784
|
<div class="tickets-list">
|
|
@@ -14420,7 +14801,7 @@ class ParticipantCardComponent {
|
|
|
14420
14801
|
class="more-tickets"
|
|
14421
14802
|
(click)="toggleShowAllTickets($event)"
|
|
14422
14803
|
>
|
|
14423
|
-
|
|
14804
|
+
{{ getMoreText(hiddenTicketsCount) }}
|
|
14424
14805
|
</ion-chip>
|
|
14425
14806
|
}
|
|
14426
14807
|
</div>
|
|
@@ -14430,7 +14811,7 @@ class ParticipantCardComponent {
|
|
|
14430
14811
|
<!-- Notes (admin variant) -->
|
|
14431
14812
|
@if (props.variant === 'admin' && props.participant.notes) {
|
|
14432
14813
|
<div class="notes-section">
|
|
14433
|
-
<span class="notes-label">
|
|
14814
|
+
<span class="notes-label">{{ getNotesLabel() }}</span>
|
|
14434
14815
|
<p class="notes-text">{{ props.participant.notes }}</p>
|
|
14435
14816
|
</div>
|
|
14436
14817
|
}
|
|
@@ -14458,7 +14839,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
14458
14839
|
@if (props.participant.isWinner && props.highlightWinner !== false) {
|
|
14459
14840
|
<div class="winner-badge">
|
|
14460
14841
|
<ion-icon name="trophy-outline"></ion-icon>
|
|
14461
|
-
<span>
|
|
14842
|
+
<span>{{ getWinnerText() }}</span>
|
|
14462
14843
|
</div>
|
|
14463
14844
|
}
|
|
14464
14845
|
|
|
@@ -14543,7 +14924,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
14543
14924
|
<div class="tickets-section">
|
|
14544
14925
|
<div class="tickets-header">
|
|
14545
14926
|
<ion-icon name="ticket-outline"></ion-icon>
|
|
14546
|
-
<span>{{ ticketNumbers.length }}
|
|
14927
|
+
<span>{{ getTicketsCountText(ticketNumbers.length) }}</span>
|
|
14547
14928
|
</div>
|
|
14548
14929
|
|
|
14549
14930
|
<div class="tickets-list">
|
|
@@ -14566,7 +14947,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
14566
14947
|
class="more-tickets"
|
|
14567
14948
|
(click)="toggleShowAllTickets($event)"
|
|
14568
14949
|
>
|
|
14569
|
-
|
|
14950
|
+
{{ getMoreText(hiddenTicketsCount) }}
|
|
14570
14951
|
</ion-chip>
|
|
14571
14952
|
}
|
|
14572
14953
|
</div>
|
|
@@ -14576,7 +14957,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
14576
14957
|
<!-- Notes (admin variant) -->
|
|
14577
14958
|
@if (props.variant === 'admin' && props.participant.notes) {
|
|
14578
14959
|
<div class="notes-section">
|
|
14579
|
-
<span class="notes-label">
|
|
14960
|
+
<span class="notes-label">{{ getNotesLabel() }}</span>
|
|
14580
14961
|
<p class="notes-text">{{ props.participant.notes }}</p>
|
|
14581
14962
|
</div>
|
|
14582
14963
|
}
|
|
@@ -18706,6 +19087,7 @@ class DataTableComponent {
|
|
|
18706
19087
|
/** Cached visible columns for performance */
|
|
18707
19088
|
this._visibleColumns = [];
|
|
18708
19089
|
this.cdr = inject(ChangeDetectorRef);
|
|
19090
|
+
this.i18n = inject(I18nService);
|
|
18709
19091
|
}
|
|
18710
19092
|
ngOnInit() {
|
|
18711
19093
|
this.initializeState();
|
|
@@ -18785,7 +19167,40 @@ class DataTableComponent {
|
|
|
18785
19167
|
return count;
|
|
18786
19168
|
}
|
|
18787
19169
|
get emptyState() {
|
|
18788
|
-
|
|
19170
|
+
const defaultEmptyState = {
|
|
19171
|
+
icon: 'document-outline',
|
|
19172
|
+
title: this.i18n.t('noData'),
|
|
19173
|
+
description: this.i18n.t('noRecordsFound'),
|
|
19174
|
+
};
|
|
19175
|
+
return this.props.emptyState || defaultEmptyState;
|
|
19176
|
+
}
|
|
19177
|
+
/** Get actions column label */
|
|
19178
|
+
getActionsLabel() {
|
|
19179
|
+
return this.props.actionsLabel || this.i18n.t('actions');
|
|
19180
|
+
}
|
|
19181
|
+
/** Get pagination info text */
|
|
19182
|
+
getPaginationInfoText() {
|
|
19183
|
+
return `${this.i18n.t('showing')} ${this.paginationStart}-${this.paginationEnd} ${this.i18n.t('of')} ${this.props.pagination?.total}`;
|
|
19184
|
+
}
|
|
19185
|
+
/** Get per page text */
|
|
19186
|
+
getPerPageText(size) {
|
|
19187
|
+
return `${size} ${this.i18n.t('perPage')}`;
|
|
19188
|
+
}
|
|
19189
|
+
/** Get first page aria label */
|
|
19190
|
+
getFirstPageLabel() {
|
|
19191
|
+
return this.i18n.t('firstPage');
|
|
19192
|
+
}
|
|
19193
|
+
/** Get previous page aria label */
|
|
19194
|
+
getPreviousPageLabel() {
|
|
19195
|
+
return this.i18n.t('previousPage');
|
|
19196
|
+
}
|
|
19197
|
+
/** Get next page aria label */
|
|
19198
|
+
getNextPageLabel() {
|
|
19199
|
+
return this.i18n.t('nextPage');
|
|
19200
|
+
}
|
|
19201
|
+
/** Get last page aria label */
|
|
19202
|
+
getLastPageLabel() {
|
|
19203
|
+
return this.i18n.t('lastPage');
|
|
18789
19204
|
}
|
|
18790
19205
|
get pageSizeOptions() {
|
|
18791
19206
|
return this.props.pagination?.pageSizeOptions || DEFAULT_PAGE_SIZE_OPTIONS;
|
|
@@ -19073,7 +19488,7 @@ class DataTableComponent {
|
|
|
19073
19488
|
<!-- Actions column -->
|
|
19074
19489
|
@if (props.actionsTemplate) {
|
|
19075
19490
|
<th class="actions-cell" [style.width]="props.actionsWidth || '100px'">
|
|
19076
|
-
{{
|
|
19491
|
+
{{ getActionsLabel() }}
|
|
19077
19492
|
</th>
|
|
19078
19493
|
}
|
|
19079
19494
|
</tr>
|
|
@@ -19244,7 +19659,7 @@ class DataTableComponent {
|
|
|
19244
19659
|
<div class="pagination-container">
|
|
19245
19660
|
<div class="pagination-info">
|
|
19246
19661
|
<span>
|
|
19247
|
-
|
|
19662
|
+
{{ getPaginationInfoText() }}
|
|
19248
19663
|
</span>
|
|
19249
19664
|
|
|
19250
19665
|
@if (pageSizeOptions.length > 1) {
|
|
@@ -19255,7 +19670,7 @@ class DataTableComponent {
|
|
|
19255
19670
|
class="page-size-select"
|
|
19256
19671
|
>
|
|
19257
19672
|
@for (size of pageSizeOptions; track size) {
|
|
19258
|
-
<ion-select-option [value]="size">{{ size }}
|
|
19673
|
+
<ion-select-option [value]="size">{{ getPerPageText(size) }}</ion-select-option>
|
|
19259
19674
|
}
|
|
19260
19675
|
</ion-select>
|
|
19261
19676
|
}
|
|
@@ -19267,7 +19682,7 @@ class DataTableComponent {
|
|
|
19267
19682
|
size="small"
|
|
19268
19683
|
[disabled]="props.pagination.page === 0"
|
|
19269
19684
|
(click)="goToPage(0)"
|
|
19270
|
-
aria-label="
|
|
19685
|
+
[attr.aria-label]="getFirstPageLabel()"
|
|
19271
19686
|
>
|
|
19272
19687
|
<ion-icon slot="icon-only" name="chevron-back-outline"></ion-icon>
|
|
19273
19688
|
<ion-icon slot="icon-only" name="chevron-back-outline" style="margin-left: -12px"></ion-icon>
|
|
@@ -19278,7 +19693,7 @@ class DataTableComponent {
|
|
|
19278
19693
|
size="small"
|
|
19279
19694
|
[disabled]="props.pagination.page === 0"
|
|
19280
19695
|
(click)="goToPage(props.pagination.page - 1)"
|
|
19281
|
-
aria-label="
|
|
19696
|
+
[attr.aria-label]="getPreviousPageLabel()"
|
|
19282
19697
|
>
|
|
19283
19698
|
<ion-icon slot="icon-only" name="chevron-back-outline"></ion-icon>
|
|
19284
19699
|
</ion-button>
|
|
@@ -19292,7 +19707,7 @@ class DataTableComponent {
|
|
|
19292
19707
|
size="small"
|
|
19293
19708
|
[disabled]="props.pagination.page >= totalPages - 1"
|
|
19294
19709
|
(click)="goToPage(props.pagination.page + 1)"
|
|
19295
|
-
aria-label="
|
|
19710
|
+
[attr.aria-label]="getNextPageLabel()"
|
|
19296
19711
|
>
|
|
19297
19712
|
<ion-icon slot="icon-only" name="chevron-forward-outline"></ion-icon>
|
|
19298
19713
|
</ion-button>
|
|
@@ -19302,7 +19717,7 @@ class DataTableComponent {
|
|
|
19302
19717
|
size="small"
|
|
19303
19718
|
[disabled]="props.pagination.page >= totalPages - 1"
|
|
19304
19719
|
(click)="goToPage(totalPages - 1)"
|
|
19305
|
-
aria-label="
|
|
19720
|
+
[attr.aria-label]="getLastPageLabel()"
|
|
19306
19721
|
>
|
|
19307
19722
|
<ion-icon slot="icon-only" name="chevron-forward-outline"></ion-icon>
|
|
19308
19723
|
<ion-icon slot="icon-only" name="chevron-forward-outline" style="margin-left: -12px"></ion-icon>
|
|
@@ -19427,7 +19842,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
19427
19842
|
<!-- Actions column -->
|
|
19428
19843
|
@if (props.actionsTemplate) {
|
|
19429
19844
|
<th class="actions-cell" [style.width]="props.actionsWidth || '100px'">
|
|
19430
|
-
{{
|
|
19845
|
+
{{ getActionsLabel() }}
|
|
19431
19846
|
</th>
|
|
19432
19847
|
}
|
|
19433
19848
|
</tr>
|
|
@@ -19598,7 +20013,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
19598
20013
|
<div class="pagination-container">
|
|
19599
20014
|
<div class="pagination-info">
|
|
19600
20015
|
<span>
|
|
19601
|
-
|
|
20016
|
+
{{ getPaginationInfoText() }}
|
|
19602
20017
|
</span>
|
|
19603
20018
|
|
|
19604
20019
|
@if (pageSizeOptions.length > 1) {
|
|
@@ -19609,7 +20024,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
19609
20024
|
class="page-size-select"
|
|
19610
20025
|
>
|
|
19611
20026
|
@for (size of pageSizeOptions; track size) {
|
|
19612
|
-
<ion-select-option [value]="size">{{ size }}
|
|
20027
|
+
<ion-select-option [value]="size">{{ getPerPageText(size) }}</ion-select-option>
|
|
19613
20028
|
}
|
|
19614
20029
|
</ion-select>
|
|
19615
20030
|
}
|
|
@@ -19621,7 +20036,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
19621
20036
|
size="small"
|
|
19622
20037
|
[disabled]="props.pagination.page === 0"
|
|
19623
20038
|
(click)="goToPage(0)"
|
|
19624
|
-
aria-label="
|
|
20039
|
+
[attr.aria-label]="getFirstPageLabel()"
|
|
19625
20040
|
>
|
|
19626
20041
|
<ion-icon slot="icon-only" name="chevron-back-outline"></ion-icon>
|
|
19627
20042
|
<ion-icon slot="icon-only" name="chevron-back-outline" style="margin-left: -12px"></ion-icon>
|
|
@@ -19632,7 +20047,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
19632
20047
|
size="small"
|
|
19633
20048
|
[disabled]="props.pagination.page === 0"
|
|
19634
20049
|
(click)="goToPage(props.pagination.page - 1)"
|
|
19635
|
-
aria-label="
|
|
20050
|
+
[attr.aria-label]="getPreviousPageLabel()"
|
|
19636
20051
|
>
|
|
19637
20052
|
<ion-icon slot="icon-only" name="chevron-back-outline"></ion-icon>
|
|
19638
20053
|
</ion-button>
|
|
@@ -19646,7 +20061,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
19646
20061
|
size="small"
|
|
19647
20062
|
[disabled]="props.pagination.page >= totalPages - 1"
|
|
19648
20063
|
(click)="goToPage(props.pagination.page + 1)"
|
|
19649
|
-
aria-label="
|
|
20064
|
+
[attr.aria-label]="getNextPageLabel()"
|
|
19650
20065
|
>
|
|
19651
20066
|
<ion-icon slot="icon-only" name="chevron-forward-outline"></ion-icon>
|
|
19652
20067
|
</ion-button>
|
|
@@ -19656,7 +20071,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
19656
20071
|
size="small"
|
|
19657
20072
|
[disabled]="props.pagination.page >= totalPages - 1"
|
|
19658
20073
|
(click)="goToPage(totalPages - 1)"
|
|
19659
|
-
aria-label="
|
|
20074
|
+
[attr.aria-label]="getLastPageLabel()"
|
|
19660
20075
|
>
|
|
19661
20076
|
<ion-icon slot="icon-only" name="chevron-forward-outline"></ion-icon>
|
|
19662
20077
|
<ion-icon slot="icon-only" name="chevron-forward-outline" style="margin-left: -12px"></ion-icon>
|
|
@@ -28958,6 +29373,22 @@ class AdSlotComponent {
|
|
|
28958
29373
|
}
|
|
28959
29374
|
return true;
|
|
28960
29375
|
});
|
|
29376
|
+
/**
|
|
29377
|
+
* Indica si debe mostrar placeholder en vez de ad real.
|
|
29378
|
+
* Activo en localhost o con Publisher ID placeholder.
|
|
29379
|
+
*/
|
|
29380
|
+
this.isPlaceholderMode = computed(() => {
|
|
29381
|
+
if (!isPlatformBrowser(this.platformId)) {
|
|
29382
|
+
return false;
|
|
29383
|
+
}
|
|
29384
|
+
const adClient = this.adsService.adClient();
|
|
29385
|
+
const isLocalhost = window.location.hostname === 'localhost' ||
|
|
29386
|
+
window.location.hostname === '127.0.0.1';
|
|
29387
|
+
const isPlaceholderClient = !adClient ||
|
|
29388
|
+
adClient === 'ca-pub-0000000000000000' ||
|
|
29389
|
+
adClient.includes('0000000000');
|
|
29390
|
+
return isLocalhost || isPlaceholderClient;
|
|
29391
|
+
});
|
|
28961
29392
|
}
|
|
28962
29393
|
// ===========================================================================
|
|
28963
29394
|
// LIFECYCLE
|
|
@@ -28972,6 +29403,15 @@ class AdSlotComponent {
|
|
|
28972
29403
|
if (!this.shouldRender() || this.adInitialized) {
|
|
28973
29404
|
return;
|
|
28974
29405
|
}
|
|
29406
|
+
// En modo placeholder, solo marcar como rendered
|
|
29407
|
+
if (this.isPlaceholderMode()) {
|
|
29408
|
+
this._state.set('rendered');
|
|
29409
|
+
this.adInitialized = true;
|
|
29410
|
+
if (this.adsService.isDebugMode()) {
|
|
29411
|
+
console.log(`[ValtechAds] Ad slot '${this.slotId}' in PLACEHOLDER mode (localhost or invalid adClient)`);
|
|
29412
|
+
}
|
|
29413
|
+
return;
|
|
29414
|
+
}
|
|
28975
29415
|
await this.initializeAd();
|
|
28976
29416
|
}
|
|
28977
29417
|
ngOnDestroy() {
|
|
@@ -29014,37 +29454,53 @@ class AdSlotComponent {
|
|
|
29014
29454
|
[class.val-ad-slot--rendered]="state() === 'rendered'"
|
|
29015
29455
|
[class.val-ad-slot--empty]="state() === 'empty'"
|
|
29016
29456
|
[class.val-ad-slot--hidden]="state() === 'hidden'"
|
|
29457
|
+
[class.val-ad-slot--placeholder]="isPlaceholderMode()"
|
|
29017
29458
|
[class]="cssClass"
|
|
29018
29459
|
[style.min-height]="minHeight"
|
|
29019
29460
|
>
|
|
29020
|
-
<!--
|
|
29021
|
-
@if (
|
|
29022
|
-
<div
|
|
29023
|
-
class="val-ad-
|
|
29024
|
-
|
|
29025
|
-
|
|
29026
|
-
|
|
29027
|
-
|
|
29028
|
-
|
|
29029
|
-
|
|
29030
|
-
|
|
29031
|
-
|
|
29032
|
-
|
|
29033
|
-
|
|
29034
|
-
|
|
29035
|
-
|
|
29036
|
-
|
|
29037
|
-
|
|
29461
|
+
<!-- Placeholder mode (desarrollo local) -->
|
|
29462
|
+
@if (isPlaceholderMode()) {
|
|
29463
|
+
<div class="val-ad-slot__placeholder" [style.height]="minHeight">
|
|
29464
|
+
<div class="val-ad-slot__placeholder-content">
|
|
29465
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
29466
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"/>
|
|
29467
|
+
<line x1="3" y1="9" x2="21" y2="9"/>
|
|
29468
|
+
<line x1="9" y1="21" x2="9" y2="9"/>
|
|
29469
|
+
</svg>
|
|
29470
|
+
<span class="val-ad-slot__placeholder-label">Ad Placeholder</span>
|
|
29471
|
+
<span class="val-ad-slot__placeholder-info">{{ slotId }} | {{ format }}</span>
|
|
29472
|
+
</div>
|
|
29473
|
+
</div>
|
|
29474
|
+
} @else {
|
|
29475
|
+
<!-- Skeleton mientras carga -->
|
|
29476
|
+
@if (showSkeleton && state() === 'loading') {
|
|
29477
|
+
<div
|
|
29478
|
+
class="val-ad-slot__skeleton"
|
|
29479
|
+
[style.height]="minHeight"
|
|
29480
|
+
></div>
|
|
29481
|
+
}
|
|
29482
|
+
|
|
29483
|
+
<!-- AdSense ins element -->
|
|
29484
|
+
<ins
|
|
29485
|
+
class="adsbygoogle val-ad-slot__container"
|
|
29486
|
+
[class.val-ad-slot__container--hidden]="state() === 'loading' && showSkeleton"
|
|
29487
|
+
[style.display]="'block'"
|
|
29488
|
+
[attr.data-ad-client]="adsService.adClient()"
|
|
29489
|
+
[attr.data-ad-slot]="adSlot || null"
|
|
29490
|
+
[attr.data-ad-format]="format"
|
|
29491
|
+
[attr.data-full-width-responsive]="fullWidth ? 'true' : null"
|
|
29492
|
+
></ins>
|
|
29493
|
+
}
|
|
29038
29494
|
|
|
29039
29495
|
<!-- Debug info -->
|
|
29040
29496
|
@if (adsService.isDebugMode()) {
|
|
29041
29497
|
<div class="val-ad-slot__debug">
|
|
29042
|
-
<small>{{ slotId }} | {{ format }} | {{ state() }}</small>
|
|
29498
|
+
<small>{{ slotId }} | {{ format }} | {{ state() }}{{ isPlaceholderMode() ? ' | PLACEHOLDER' : '' }}</small>
|
|
29043
29499
|
</div>
|
|
29044
29500
|
}
|
|
29045
29501
|
</div>
|
|
29046
29502
|
}
|
|
29047
|
-
`, isInline: true, styles: [".val-ad-slot{position:relative;display:flex;justify-content:center;align-items:center;overflow:hidden;width:100%}.val-ad-slot--loading{background-color:var(--ion-color-light, #f4f4f4)}.val-ad-slot--empty,.val-ad-slot--hidden{display:none!important}.val-ad-slot__skeleton{width:100%;background:linear-gradient(90deg,var(--ion-color-light, #f4f4f4) 25%,var(--ion-color-light-shade, #e0e0e0) 50%,var(--ion-color-light, #f4f4f4) 75%);background-size:200% 100%;animation:skeleton-loading 1.5s infinite;border-radius:4px}.val-ad-slot__container{width:100%}.val-ad-slot__container--hidden{visibility:hidden;position:absolute}.val-ad-slot__debug{position:absolute;bottom:0;left:0;background:#000000b3;color:#fff;padding:2px 6px;font-size:10px;z-index:1000;font-family:monospace}@keyframes skeleton-loading{0%{background-position:200% 0}to{background-position:-200% 0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
29503
|
+
`, isInline: true, styles: [".val-ad-slot{position:relative;display:flex;justify-content:center;align-items:center;overflow:hidden;width:100%}.val-ad-slot--loading{background-color:var(--ion-color-light, #f4f4f4)}.val-ad-slot--empty,.val-ad-slot--hidden{display:none!important}.val-ad-slot__skeleton{width:100%;background:linear-gradient(90deg,var(--ion-color-light, #f4f4f4) 25%,var(--ion-color-light-shade, #e0e0e0) 50%,var(--ion-color-light, #f4f4f4) 75%);background-size:200% 100%;animation:skeleton-loading 1.5s infinite;border-radius:4px}.val-ad-slot__container{width:100%}.val-ad-slot__container--hidden{visibility:hidden;position:absolute}.val-ad-slot__placeholder{width:100%;background:linear-gradient(135deg,#667eea,#764ba2);border-radius:8px;display:flex;align-items:center;justify-content:center;color:#fff;border:2px dashed rgba(255,255,255,.4)}.val-ad-slot__placeholder-content{display:flex;flex-direction:column;align-items:center;gap:8px;padding:16px;text-align:center}.val-ad-slot__placeholder-content svg{opacity:.8}.val-ad-slot__placeholder-label{font-weight:600;font-size:14px;letter-spacing:.5px}.val-ad-slot__placeholder-info{font-size:11px;opacity:.7;font-family:monospace}.val-ad-slot__debug{position:absolute;bottom:0;left:0;background:#000000b3;color:#fff;padding:2px 6px;font-size:10px;z-index:1000;font-family:monospace}@keyframes skeleton-loading{0%{background-position:200% 0}to{background-position:-200% 0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
29048
29504
|
}
|
|
29049
29505
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AdSlotComponent, decorators: [{
|
|
29050
29506
|
type: Component,
|
|
@@ -29056,37 +29512,53 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
29056
29512
|
[class.val-ad-slot--rendered]="state() === 'rendered'"
|
|
29057
29513
|
[class.val-ad-slot--empty]="state() === 'empty'"
|
|
29058
29514
|
[class.val-ad-slot--hidden]="state() === 'hidden'"
|
|
29515
|
+
[class.val-ad-slot--placeholder]="isPlaceholderMode()"
|
|
29059
29516
|
[class]="cssClass"
|
|
29060
29517
|
[style.min-height]="minHeight"
|
|
29061
29518
|
>
|
|
29062
|
-
<!--
|
|
29063
|
-
@if (
|
|
29064
|
-
<div
|
|
29065
|
-
class="val-ad-
|
|
29066
|
-
|
|
29067
|
-
|
|
29068
|
-
|
|
29069
|
-
|
|
29070
|
-
|
|
29071
|
-
|
|
29072
|
-
|
|
29073
|
-
|
|
29074
|
-
|
|
29075
|
-
|
|
29076
|
-
|
|
29077
|
-
|
|
29078
|
-
|
|
29079
|
-
|
|
29519
|
+
<!-- Placeholder mode (desarrollo local) -->
|
|
29520
|
+
@if (isPlaceholderMode()) {
|
|
29521
|
+
<div class="val-ad-slot__placeholder" [style.height]="minHeight">
|
|
29522
|
+
<div class="val-ad-slot__placeholder-content">
|
|
29523
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
29524
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"/>
|
|
29525
|
+
<line x1="3" y1="9" x2="21" y2="9"/>
|
|
29526
|
+
<line x1="9" y1="21" x2="9" y2="9"/>
|
|
29527
|
+
</svg>
|
|
29528
|
+
<span class="val-ad-slot__placeholder-label">Ad Placeholder</span>
|
|
29529
|
+
<span class="val-ad-slot__placeholder-info">{{ slotId }} | {{ format }}</span>
|
|
29530
|
+
</div>
|
|
29531
|
+
</div>
|
|
29532
|
+
} @else {
|
|
29533
|
+
<!-- Skeleton mientras carga -->
|
|
29534
|
+
@if (showSkeleton && state() === 'loading') {
|
|
29535
|
+
<div
|
|
29536
|
+
class="val-ad-slot__skeleton"
|
|
29537
|
+
[style.height]="minHeight"
|
|
29538
|
+
></div>
|
|
29539
|
+
}
|
|
29540
|
+
|
|
29541
|
+
<!-- AdSense ins element -->
|
|
29542
|
+
<ins
|
|
29543
|
+
class="adsbygoogle val-ad-slot__container"
|
|
29544
|
+
[class.val-ad-slot__container--hidden]="state() === 'loading' && showSkeleton"
|
|
29545
|
+
[style.display]="'block'"
|
|
29546
|
+
[attr.data-ad-client]="adsService.adClient()"
|
|
29547
|
+
[attr.data-ad-slot]="adSlot || null"
|
|
29548
|
+
[attr.data-ad-format]="format"
|
|
29549
|
+
[attr.data-full-width-responsive]="fullWidth ? 'true' : null"
|
|
29550
|
+
></ins>
|
|
29551
|
+
}
|
|
29080
29552
|
|
|
29081
29553
|
<!-- Debug info -->
|
|
29082
29554
|
@if (adsService.isDebugMode()) {
|
|
29083
29555
|
<div class="val-ad-slot__debug">
|
|
29084
|
-
<small>{{ slotId }} | {{ format }} | {{ state() }}</small>
|
|
29556
|
+
<small>{{ slotId }} | {{ format }} | {{ state() }}{{ isPlaceholderMode() ? ' | PLACEHOLDER' : '' }}</small>
|
|
29085
29557
|
</div>
|
|
29086
29558
|
}
|
|
29087
29559
|
</div>
|
|
29088
29560
|
}
|
|
29089
|
-
`, styles: [".val-ad-slot{position:relative;display:flex;justify-content:center;align-items:center;overflow:hidden;width:100%}.val-ad-slot--loading{background-color:var(--ion-color-light, #f4f4f4)}.val-ad-slot--empty,.val-ad-slot--hidden{display:none!important}.val-ad-slot__skeleton{width:100%;background:linear-gradient(90deg,var(--ion-color-light, #f4f4f4) 25%,var(--ion-color-light-shade, #e0e0e0) 50%,var(--ion-color-light, #f4f4f4) 75%);background-size:200% 100%;animation:skeleton-loading 1.5s infinite;border-radius:4px}.val-ad-slot__container{width:100%}.val-ad-slot__container--hidden{visibility:hidden;position:absolute}.val-ad-slot__debug{position:absolute;bottom:0;left:0;background:#000000b3;color:#fff;padding:2px 6px;font-size:10px;z-index:1000;font-family:monospace}@keyframes skeleton-loading{0%{background-position:200% 0}to{background-position:-200% 0}}\n"] }]
|
|
29561
|
+
`, styles: [".val-ad-slot{position:relative;display:flex;justify-content:center;align-items:center;overflow:hidden;width:100%}.val-ad-slot--loading{background-color:var(--ion-color-light, #f4f4f4)}.val-ad-slot--empty,.val-ad-slot--hidden{display:none!important}.val-ad-slot__skeleton{width:100%;background:linear-gradient(90deg,var(--ion-color-light, #f4f4f4) 25%,var(--ion-color-light-shade, #e0e0e0) 50%,var(--ion-color-light, #f4f4f4) 75%);background-size:200% 100%;animation:skeleton-loading 1.5s infinite;border-radius:4px}.val-ad-slot__container{width:100%}.val-ad-slot__container--hidden{visibility:hidden;position:absolute}.val-ad-slot__placeholder{width:100%;background:linear-gradient(135deg,#667eea,#764ba2);border-radius:8px;display:flex;align-items:center;justify-content:center;color:#fff;border:2px dashed rgba(255,255,255,.4)}.val-ad-slot__placeholder-content{display:flex;flex-direction:column;align-items:center;gap:8px;padding:16px;text-align:center}.val-ad-slot__placeholder-content svg{opacity:.8}.val-ad-slot__placeholder-label{font-weight:600;font-size:14px;letter-spacing:.5px}.val-ad-slot__placeholder-info{font-size:11px;opacity:.7;font-family:monospace}.val-ad-slot__debug{position:absolute;bottom:0;left:0;background:#000000b3;color:#fff;padding:2px 6px;font-size:10px;z-index:1000;font-family:monospace}@keyframes skeleton-loading{0%{background-position:200% 0}to{background-position:-200% 0}}\n"] }]
|
|
29090
29562
|
}], propDecorators: { slotId: [{
|
|
29091
29563
|
type: Input,
|
|
29092
29564
|
args: [{ required: true }]
|
|
@@ -29112,5 +29584,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
29112
29584
|
* Generated bundle index. Do not edit.
|
|
29113
29585
|
*/
|
|
29114
29586
|
|
|
29115
|
-
export { AD_SIZE_MAP, ARTICLE_SPACING, AccordionComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, ArticleBuilder, ArticleComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, BannerComponent, BaseDefault, BoxComponent, BreadcrumbComponent, ButtonComponent, ButtonGroupComponent, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CURRENCY_INFO, CardComponent, CardSection, CardType, CardsCarouselComponent, CheckInputComponent, ChipGroupComponent, ClearDefault, ClearDefaultBlock, ClearDefaultFull, ClearDefaultRound, ClearDefaultRoundBlock, ClearDefaultRoundFull, CodeDisplayComponent, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ContentLoaderComponent, CountdownComponent, CurrencyInputComponent, DEFAULT_ADS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CANCEL_BUTTON, DEFAULT_CONFIRM_BUTTON, DEFAULT_COUNTDOWN_LABELS, DEFAULT_COUNTDOWN_LABELS_EN, DEFAULT_EMPTY_STATE, DEFAULT_LEGEND_LABELS, DEFAULT_MODAL_CANCEL_BUTTON, DEFAULT_MODAL_CONFIRM_BUTTON, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PAYMENT_STATUS_COLORS, DEFAULT_PAYMENT_STATUS_LABELS, DEFAULT_PLATFORMS, DEFAULT_STATUS_COLORS, DEFAULT_STATUS_LABELS, DEFAULT_WINNER_LABELS, DataTableComponent, DateInputComponent, DateRangeInputComponent, DeviceService, DisplayComponent, DividerComponent, DownloadService, EmailInputComponent, ExpandableTextComponent, FabComponent, FileInputComponent, FirebaseService, FirestoreCollectionFactory, FirestoreService, FooterComponent, FooterLinksComponent, FormComponent, FormFooterComponent, FunHeaderComponent, GlowCardComponent, HeaderComponent, HintComponent, HorizontalScrollComponent, HourInputComponent, HrefComponent, I18nService, INITIAL_AUTH_STATE, INITIAL_MFA_STATE, Icon, IconComponent, IconService, ImageComponent, InAppBrowserService, InfoComponent, InputType, ItemListComponent, LANG_STORAGE_KEY$1 as LANG_STORAGE_KEY, LanguageSelectorComponent, LayeredCardComponent, LayoutComponent, LinkComponent, LinkProcessorService, LinksAccordionComponent, LinksCakeComponent, LocalStorageService, LocaleService, MODAL_SIZES, MOTION, MenuComponent, MessagingService, ModalService, MultiSelectSearchComponent, NavigationService, NoContentComponent, NotesBoxComponent, NotificationsService, NumberFromToComponent, NumberInputComponent, NumberStepperComponent, OAuthCallbackComponent, OAuthService, OutlineDefault, OutlineDefaultBlock, OutlineDefaultFull, OutlineDefaultRound, OutlineDefaultRoundBlock, OutlineDefaultRoundFull, PLATFORM_CONFIGS, PageContentComponent, PageTemplateComponent, PageWrapperComponent, PaginationComponent, ParticipantCardComponent, PasswordInputComponent, PhoneInputComponent, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, PresetService, PriceTagComponent, PrimarySolidBlockButton, PrimarySolidBlockHrefButton, PrimarySolidBlockIconButton, PrimarySolidBlockIconHrefButton, PrimarySolidDefaultRoundButton, PrimarySolidDefaultRoundHrefButton, PrimarySolidDefaultRoundIconButton, PrimarySolidDefaultRoundIconHrefButton, PrimarySolidFullButton, PrimarySolidFullHrefButton, PrimarySolidFullIconButton, PrimarySolidFullIconHrefButton, PrimarySolidLargeRoundButton, PrimarySolidLargeRoundHrefButton, PrimarySolidLargeRoundIconButton, PrimarySolidLargeRoundIconHrefButton, PrimarySolidSmallRoundButton, PrimarySolidSmallRoundHrefButton, PrimarySolidSmallRoundIconButton, PrimarySolidSmallRoundIconHrefButton, ProcessLinksPipe, ProgressBarComponent, ProgressRingComponent, ProgressStatusComponent, PrompterComponent, QR_PRESETS, QrCodeComponent, QrGeneratorService, QueryBuilder, QuoteBoxComponent, RadioInputComponent, RaffleStatusCardComponent, RangeInputComponent, RatingComponent, RecapCardComponent, RightsFooterComponent, SKELETON_PRESETS, SearchSelectorComponent, SearchbarComponent, SecondarySolidBlockButton, SecondarySolidBlockHrefButton, SecondarySolidBlockIconButton, SecondarySolidBlockIconHrefButton, SecondarySolidDefaultRoundButton, SecondarySolidDefaultRoundHrefButton, SecondarySolidDefaultRoundIconButton, SecondarySolidDefaultRoundIconHrefButton, SecondarySolidFullButton, SecondarySolidFullHrefButton, SecondarySolidFullIconButton, SecondarySolidFullIconHrefButton, SecondarySolidLargeRoundButton, SecondarySolidLargeRoundHrefButton, SecondarySolidLargeRoundIconButton, SecondarySolidLargeRoundIconHrefButton, SecondarySolidSmallRoundButton, SecondarySolidSmallRoundHrefButton, SecondarySolidSmallRoundIconButton, SecondarySolidSmallRoundIconHrefButton, SegmentControlComponent, SelectSearchComponent, SessionService, ShareButtonsComponent, SimpleComponent, SkeletonComponent, SolidBlockButton, SolidDefault, SolidDefaultBlock, SolidDefaultButton, SolidDefaultFull, SolidDefaultRound, SolidDefaultRoundBlock, SolidDefaultRoundButton, SolidDefaultRoundFull, SolidFullButton, SolidLargeButton, SolidLargeRoundButton, SolidSmallButton, SolidSmallRoundButton, StatsCardComponent, StepperComponent, StorageService, SwipeCarouselComponent, TabbedContentComponent, TabsComponent, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeService, TicketGridComponent, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TranslatePipe, TypedCollection, VALTECH_ADS_CONFIG, VALTECH_AUTH_CONFIG, VALTECH_FIREBASE_CONFIG, WinnerDisplayComponent, WizardComponent, WizardFooterComponent, applyDefaultValueToControl, authGuard, authInterceptor, buildPath, collections, createFirebaseConfig, createGlowCardProps, createNumberFromToField, createTitleProps, extractPathParams, getCollectionPath, getDocumentId, goToTop, guestGuard, hasEmulators, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isValidPath, joinPath, maxLength, permissionGuard, permissionGuardFromRoute, provideValtechAds, provideValtechAuth, provideValtechAuthInterceptor, provideValtechFirebase, provideValtechI18n, provideValtechPresets, query, replaceSpecialChars, resolveColor, resolveInputDefaultValue, roleGuard, storagePaths, superAdminGuard };
|
|
29587
|
+
export { AD_SIZE_MAP, ARTICLE_SPACING, AccordionComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, ArticleBuilder, ArticleComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, BannerComponent, BaseDefault, BoxComponent, BreadcrumbComponent, ButtonComponent, ButtonGroupComponent, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CURRENCY_INFO, CardComponent, CardSection, CardType, CardsCarouselComponent, CheckInputComponent, ChipGroupComponent, ClearDefault, ClearDefaultBlock, ClearDefaultFull, ClearDefaultRound, ClearDefaultRoundBlock, ClearDefaultRoundFull, CodeDisplayComponent, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ContentLoaderComponent, CountdownComponent, CurrencyInputComponent, DEFAULT_ADS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CANCEL_BUTTON, DEFAULT_CONFIRM_BUTTON, DEFAULT_COUNTDOWN_LABELS, DEFAULT_COUNTDOWN_LABELS_EN, DEFAULT_EMPTY_STATE, DEFAULT_LEGEND_LABELS, DEFAULT_MODAL_CANCEL_BUTTON, DEFAULT_MODAL_CONFIRM_BUTTON, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PAYMENT_STATUS_COLORS, DEFAULT_PAYMENT_STATUS_LABELS, DEFAULT_PLATFORMS, DEFAULT_STATUS_COLORS, DEFAULT_STATUS_LABELS, DEFAULT_WINNER_LABELS, DataTableComponent, DateInputComponent, DateRangeInputComponent, DeviceService, DisplayComponent, DividerComponent, DownloadService, EmailInputComponent, ExpandableTextComponent, FabComponent, FileInputComponent, FirebaseService, FirestoreCollectionFactory, FirestoreService, FooterComponent, FooterLinksComponent, FormComponent, FormFooterComponent, FunHeaderComponent, GlowCardComponent, HeaderComponent, HintComponent, HorizontalScrollComponent, HourInputComponent, HrefComponent, I18nService, INITIAL_AUTH_STATE, INITIAL_MFA_STATE, Icon, IconComponent, IconService, ImageComponent, InAppBrowserService, InfoComponent, InputType, ItemListComponent, LANG_STORAGE_KEY$1 as LANG_STORAGE_KEY, LanguageSelectorComponent, LayeredCardComponent, LayoutComponent, LinkComponent, LinkProcessorService, LinksAccordionComponent, LinksCakeComponent, LocalStorageService, LocaleService, MODAL_SIZES, MOTION, MenuComponent, MessagingService, ModalService, MultiSelectSearchComponent, NavigationService, NoContentComponent, NotesBoxComponent, NotificationsService, NumberFromToComponent, NumberInputComponent, NumberStepperComponent, OAuthCallbackComponent, OAuthService, OutlineDefault, OutlineDefaultBlock, OutlineDefaultFull, OutlineDefaultRound, OutlineDefaultRoundBlock, OutlineDefaultRoundFull, PLATFORM_CONFIGS, PageContentComponent, PageTemplateComponent, PageWrapperComponent, PaginationComponent, ParticipantCardComponent, PasswordInputComponent, PhoneInputComponent, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, PresetService, PriceTagComponent, PrimarySolidBlockButton, PrimarySolidBlockHrefButton, PrimarySolidBlockIconButton, PrimarySolidBlockIconHrefButton, PrimarySolidDefaultRoundButton, PrimarySolidDefaultRoundHrefButton, PrimarySolidDefaultRoundIconButton, PrimarySolidDefaultRoundIconHrefButton, PrimarySolidFullButton, PrimarySolidFullHrefButton, PrimarySolidFullIconButton, PrimarySolidFullIconHrefButton, PrimarySolidLargeRoundButton, PrimarySolidLargeRoundHrefButton, PrimarySolidLargeRoundIconButton, PrimarySolidLargeRoundIconHrefButton, PrimarySolidSmallRoundButton, PrimarySolidSmallRoundHrefButton, PrimarySolidSmallRoundIconButton, PrimarySolidSmallRoundIconHrefButton, ProcessLinksPipe, ProgressBarComponent, ProgressRingComponent, ProgressStatusComponent, PrompterComponent, QR_PRESETS, QrCodeComponent, QrGeneratorService, QueryBuilder, QuoteBoxComponent, RadioInputComponent, RaffleStatusCardComponent, RangeInputComponent, RatingComponent, RecapCardComponent, RightsFooterComponent, SKELETON_PRESETS, SearchSelectorComponent, SearchbarComponent, SecondarySolidBlockButton, SecondarySolidBlockHrefButton, SecondarySolidBlockIconButton, SecondarySolidBlockIconHrefButton, SecondarySolidDefaultRoundButton, SecondarySolidDefaultRoundHrefButton, SecondarySolidDefaultRoundIconButton, SecondarySolidDefaultRoundIconHrefButton, SecondarySolidFullButton, SecondarySolidFullHrefButton, SecondarySolidFullIconButton, SecondarySolidFullIconHrefButton, SecondarySolidLargeRoundButton, SecondarySolidLargeRoundHrefButton, SecondarySolidLargeRoundIconButton, SecondarySolidLargeRoundIconHrefButton, SecondarySolidSmallRoundButton, SecondarySolidSmallRoundHrefButton, SecondarySolidSmallRoundIconButton, SecondarySolidSmallRoundIconHrefButton, SegmentControlComponent, SelectSearchComponent, SessionService, ShareButtonsComponent, SimpleComponent, SkeletonComponent, SolidBlockButton, SolidDefault, SolidDefaultBlock, SolidDefaultButton, SolidDefaultFull, SolidDefaultRound, SolidDefaultRoundBlock, SolidDefaultRoundButton, SolidDefaultRoundFull, SolidFullButton, SolidLargeButton, SolidLargeRoundButton, SolidSmallButton, SolidSmallRoundButton, StatsCardComponent, StepperComponent, StorageService, SwipeCarouselComponent, TabbedContentComponent, TabsComponent, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeService, TicketGridComponent, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TranslatePipe, TypedCollection, VALTECH_ADS_CONFIG, VALTECH_AUTH_CONFIG, VALTECH_DEFAULT_CONTENT, VALTECH_FIREBASE_CONFIG, WinnerDisplayComponent, WizardComponent, WizardFooterComponent, applyDefaultValueToControl, authGuard, authInterceptor, buildPath, collections, createFirebaseConfig, createGlowCardProps, createNumberFromToField, createTitleProps, extractPathParams, getCollectionPath, getDocumentId, goToTop, guestGuard, hasEmulators, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isValidPath, joinPath, maxLength, permissionGuard, permissionGuardFromRoute, provideValtechAds, provideValtechAuth, provideValtechAuthInterceptor, provideValtechFirebase, provideValtechI18n, provideValtechPresets, query, replaceSpecialChars, resolveColor, resolveInputDefaultValue, roleGuard, storagePaths, superAdminGuard };
|
|
29116
29588
|
//# sourceMappingURL=valtech-components.mjs.map
|