@decaf-ts/for-angular 0.0.41 → 0.0.42
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/README.md +23 -3
- package/fesm2022/decaf-ts-for-angular.mjs +1731 -707
- package/fesm2022/decaf-ts-for-angular.mjs.map +1 -1
- package/index.d.ts +837 -138
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { UIKeys, HTML5InputTypes, parseValueByType, HTML5CheckTypes, escapeHtml, parseToNumber, RenderingEngine, RenderingError, UIMediaBreakPoints } from '@decaf-ts/ui-decorators';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
3
|
import { InjectionToken, NgModule, isDevMode, reflectComponentType, Injector, createEnvironmentInjector, runInInjectionContext, createComponent, inject, NgZone, Injectable, ChangeDetectorRef, Renderer2, EventEmitter, ElementRef, Input, Output, ViewChild, Inject, Directive, EnvironmentInjector, ViewContainerRef, TemplateRef, Component, HostListener, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
4
|
+
import * as i1$1 from '@angular/common';
|
|
4
5
|
import { CommonModule, Location, NgComponentOutlet } from '@angular/common';
|
|
5
6
|
import { VALIDATION_PARENT_KEY, ValidationKeys, DEFAULT_PATTERNS, Validation, Primitives, ComparisonValidationKeys, PathProxyEngine, Model, ModelKeys, isValidDate as isValidDate$1, parseDate, sf, ReservedModels } from '@decaf-ts/decorator-validation';
|
|
6
7
|
import { InternalError, OperationKeys, NotFoundError } from '@decaf-ts/db-decorators';
|
|
@@ -16,14 +17,12 @@ import { forkJoin, Subject, BehaviorSubject, fromEvent, merge, of, Observable, t
|
|
|
16
17
|
import { provideHttpClient, HttpClient } from '@angular/common/http';
|
|
17
18
|
import { map, distinctUntilChanged, takeUntil, shareReplay, tap, switchMap } from 'rxjs/operators';
|
|
18
19
|
import { __decorate, __metadata } from 'tslib';
|
|
19
|
-
import { IonInput, IonItem, IonCheckbox, IonRadioGroup, IonRadio, IonSelect, IonSelectOption, IonLabel, IonText, IonTextarea, IonCard, IonCardHeader, IonCardContent, IonCardTitle, IonCardSubtitle,
|
|
20
|
+
import { IonModal, IonSpinner, IonButton, IonButtons, IonContent, IonHeader, IonTitle, IonToolbar, IonInput, IonItem, IonCheckbox, IonRadioGroup, IonRadio, IonSelect, IonSelectOption, IonLabel, IonText, IonTextarea, IonCard, IonCardHeader, IonCardContent, IonCardTitle, IonCardSubtitle, IonIcon, IonAccordionGroup, IonAccordion, IonList, IonReorder, IonReorderGroup, IonSearchbar, IonChip, IonRefresher, IonThumbnail, IonSkeletonText, IonRefresherContent, IonInfiniteScroll, IonInfiniteScrollContent, IonListHeader, IonItemSliding, IonItemOptions, IonItemOption, IonPopover } from '@ionic/angular/standalone';
|
|
20
21
|
import { addIcons } from 'ionicons';
|
|
21
22
|
import * as allIcons from 'ionicons/icons';
|
|
22
23
|
import { chevronUpOutline, chevronDownOutline, createOutline, trashOutline, addOutline, alertCircleOutline, arrowUpOutline, arrowDownOutline, searchOutline, closeOutline, chevronForwardOutline, chevronBackOutline, arrowBackOutline, arrowForwardOutline } from 'ionicons/icons';
|
|
23
24
|
import { apply, metadata } from '@decaf-ts/reflection';
|
|
24
25
|
import { DomSanitizer, Title } from '@angular/platform-browser';
|
|
25
|
-
import { modalController } from '@ionic/core';
|
|
26
|
-
import { NgxMediaService as NgxMediaService$1 } from 'src/lib/engine';
|
|
27
26
|
import { MenuController } from '@ionic/angular';
|
|
28
27
|
|
|
29
28
|
/**
|
|
@@ -89,7 +88,7 @@ const FormConstants = {
|
|
|
89
88
|
* @summary Contains constants for standardized event names used throughout the application.
|
|
90
89
|
* These constants ensure consistent event naming across components and make it easier to
|
|
91
90
|
* track and handle events. Each constant represents a specific application event type.
|
|
92
|
-
* @typedef {Object}
|
|
91
|
+
* @typedef {Object} ComponentEventNames
|
|
93
92
|
* @property {string} BACK_BUTTON_NAVIGATION - Event fired when back button navigation ends
|
|
94
93
|
* @property {string} REFRESH - Event fired when a refresh action occurs
|
|
95
94
|
* @property {string} CLICK - Event fired when a click action occurs
|
|
@@ -98,13 +97,14 @@ const FormConstants = {
|
|
|
98
97
|
* @property {string} FIELDSET_ADD_GROUP - Event fired when adding a group to a fieldset
|
|
99
98
|
* @property {string} FIELDSET_UPDATE_GROUP - Event fired when updating a fieldset group
|
|
100
99
|
* @property {string} FIELDSET_REMOVE_GROUP - Event fired when removing a fieldset group
|
|
101
|
-
* @const
|
|
100
|
+
* @const ComponentEventNames
|
|
102
101
|
* @memberOf module:lib/engine/constants
|
|
103
102
|
*/
|
|
104
|
-
const
|
|
103
|
+
const ComponentEventNames = {
|
|
105
104
|
BACK_BUTTON_NAVIGATION: 'backButtonNavigationEndEvent',
|
|
106
105
|
REFRESH: 'RefreshEvent',
|
|
107
106
|
CLICK: 'ClickEvent',
|
|
107
|
+
CHANGE: 'ChangeEvent',
|
|
108
108
|
SUBMIT: 'SubmitEvent',
|
|
109
109
|
VALIDATION_ERROR: 'validationErrorEvent',
|
|
110
110
|
FIELDSET_ADD_GROUP: 'fieldsetAddGroupEvent',
|
|
@@ -321,6 +321,7 @@ const ElementSizes = {
|
|
|
321
321
|
xsmall: 'xsmall',
|
|
322
322
|
small: 'small',
|
|
323
323
|
medium: 'medium',
|
|
324
|
+
default: 'default',
|
|
324
325
|
large: 'large',
|
|
325
326
|
xLarge: 'xlarge',
|
|
326
327
|
'2xLarge': '2xlarge',
|
|
@@ -328,6 +329,13 @@ const ElementSizes = {
|
|
|
328
329
|
expand: 'expand',
|
|
329
330
|
block: 'block',
|
|
330
331
|
};
|
|
332
|
+
const ElementPositions = {
|
|
333
|
+
left: 'left',
|
|
334
|
+
center: 'center',
|
|
335
|
+
right: 'right',
|
|
336
|
+
top: 'top',
|
|
337
|
+
bottom: 'bottom',
|
|
338
|
+
};
|
|
331
339
|
const LayoutGridGaps = {
|
|
332
340
|
small: 'small',
|
|
333
341
|
medium: 'medium',
|
|
@@ -335,6 +343,13 @@ const LayoutGridGaps = {
|
|
|
335
343
|
collapse: 'collapse',
|
|
336
344
|
none: ''
|
|
337
345
|
};
|
|
346
|
+
const ListItemPositions = {
|
|
347
|
+
uid: 'uid',
|
|
348
|
+
title: 'title',
|
|
349
|
+
description: 'description',
|
|
350
|
+
info: 'info',
|
|
351
|
+
subinfo: 'subinfo',
|
|
352
|
+
};
|
|
338
353
|
|
|
339
354
|
/**
|
|
340
355
|
* @module module:lib/engine/ValidatorFactory
|
|
@@ -502,7 +517,7 @@ const CPTKN = new InjectionToken('CPTKN', { providedIn: 'root', factory: () => '
|
|
|
502
517
|
* @summary Used to provide configuration for internationalization resources, including
|
|
503
518
|
* translation file locations and supported languages. This token configures how the
|
|
504
519
|
* application loads and manages translation resources.
|
|
505
|
-
* @const {InjectionToken<
|
|
520
|
+
* @const {InjectionToken<I18nToken>}
|
|
506
521
|
* @memberOf module:lib/for-angular-common.module
|
|
507
522
|
*/
|
|
508
523
|
const I18N_CONFIG_TOKEN = new InjectionToken('I18N_CONFIG_TOKEN');
|
|
@@ -511,8 +526,8 @@ const I18N_CONFIG_TOKEN = new InjectionToken('I18N_CONFIG_TOKEN');
|
|
|
511
526
|
* @summary Helper function to package component constructors for registration with the
|
|
512
527
|
* rendering engine. This function accepts component classes and returns them as an array
|
|
513
528
|
* suitable for use with the CPTKN injection token.
|
|
514
|
-
* @param {...Constructor
|
|
515
|
-
* @return {Constructor
|
|
529
|
+
* @param {...Constructor[]} components - Component constructor classes to register
|
|
530
|
+
* @return {Constructor} Array of component constructors
|
|
516
531
|
* @memberOf module:lib/for-angular-common.module
|
|
517
532
|
* @example
|
|
518
533
|
* // Register multiple custom components
|
|
@@ -1388,7 +1403,7 @@ class NgxFormService {
|
|
|
1388
1403
|
const parts = path.split('.');
|
|
1389
1404
|
const controlName = parts.pop();
|
|
1390
1405
|
const { childOf } = componentProps;
|
|
1391
|
-
|
|
1406
|
+
const currentGroup = formGroup;
|
|
1392
1407
|
function setArrayComponentProps(formGroupArray) {
|
|
1393
1408
|
const props = formGroupArray?.[BaseComponentProps.FORM_GROUP_COMPONENT_PROPS] || {};
|
|
1394
1409
|
if (!props[ModelKeys.MODEL][controlName])
|
|
@@ -1396,7 +1411,7 @@ class NgxFormService {
|
|
|
1396
1411
|
}
|
|
1397
1412
|
for (const part of parts) {
|
|
1398
1413
|
if (!currentGroup.get(part)) {
|
|
1399
|
-
const partFormGroup = (isMultiple && part === childOf) ? new FormArray([new FormGroup({})]) : new FormGroup({});
|
|
1414
|
+
const partFormGroup = (isMultiple && (part === childOf || childOf?.endsWith(`${part}`))) ? new FormArray([new FormGroup({})]) : new FormGroup({});
|
|
1400
1415
|
const pk = componentProps?.pk || parentProps?.pk || '';
|
|
1401
1416
|
partFormGroup[BaseComponentProps.FORM_GROUP_COMPONENT_PROPS] = {
|
|
1402
1417
|
childOf: childOf || '',
|
|
@@ -1420,7 +1435,7 @@ class NgxFormService {
|
|
|
1420
1435
|
}
|
|
1421
1436
|
if (childOf && currentGroup instanceof FormArray)
|
|
1422
1437
|
setArrayComponentProps(currentGroup);
|
|
1423
|
-
|
|
1438
|
+
return [currentGroup.get(part), controlName];
|
|
1424
1439
|
}
|
|
1425
1440
|
return [currentGroup, controlName];
|
|
1426
1441
|
}
|
|
@@ -1587,7 +1602,7 @@ class NgxFormService {
|
|
|
1587
1602
|
*/
|
|
1588
1603
|
static addFormControl(formGroup, componentProps, parentProps = {}, index = 0) {
|
|
1589
1604
|
const isMultiple = parentProps?.['multiple'] || parentProps?.['type'] === 'Array' || false;
|
|
1590
|
-
const { name, childOf
|
|
1605
|
+
const { name, childOf } = componentProps;
|
|
1591
1606
|
if (isMultiple)
|
|
1592
1607
|
componentProps['pk'] = componentProps['pk'] || parentProps?.['pk'] || '';
|
|
1593
1608
|
const fullPath = childOf ? isMultiple ? `${childOf}.${index}.${name}` : `${childOf}.${name}` : name;
|
|
@@ -1608,11 +1623,16 @@ class NgxFormService {
|
|
|
1608
1623
|
}
|
|
1609
1624
|
}
|
|
1610
1625
|
}
|
|
1611
|
-
|
|
1612
|
-
|
|
1626
|
+
let rootGroup = parentGroup;
|
|
1627
|
+
if (rootGroup instanceof FormArray)
|
|
1628
|
+
rootGroup = parentGroup.controls[componentProps?.['page'] - 1];
|
|
1629
|
+
// if(childOf?.includes("."))
|
|
1630
|
+
// rootGroup = (rootGroup as FormGroup)?.parent as FormArray
|
|
1631
|
+
// componentProps['formGroup'] = root as FormGroup;
|
|
1632
|
+
componentProps['formGroup'] = rootGroup;
|
|
1613
1633
|
componentProps['formControl'] = parentGroup.get(controlName);
|
|
1614
1634
|
// componentProps['multiple'] = isMultiple;
|
|
1615
|
-
return
|
|
1635
|
+
return parentGroup;
|
|
1616
1636
|
}
|
|
1617
1637
|
/**
|
|
1618
1638
|
* @description Retrieves a control from a registered form.
|
|
@@ -1841,6 +1861,8 @@ class NgxFormService {
|
|
|
1841
1861
|
const control = formGroup.controls[key];
|
|
1842
1862
|
const parentProps = NgxFormService.getPropsFromControl(formGroup);
|
|
1843
1863
|
if (!(control instanceof FormControl)) {
|
|
1864
|
+
if (control.disabled)
|
|
1865
|
+
continue;
|
|
1844
1866
|
const value = NgxFormService.getFormData(control);
|
|
1845
1867
|
const isValid = control.valid;
|
|
1846
1868
|
if (parentProps.multiple) {
|
|
@@ -1932,7 +1954,7 @@ class NgxFormService {
|
|
|
1932
1954
|
throw new Error(`Unknown control type at: ${path || 'root'}`);
|
|
1933
1955
|
control.markAsTouched();
|
|
1934
1956
|
control.markAsDirty();
|
|
1935
|
-
control.updateValueAndValidity();
|
|
1957
|
+
control.updateValueAndValidity({ emitEvent: true });
|
|
1936
1958
|
if (control instanceof FormGroup) {
|
|
1937
1959
|
Object.values(control.controls).forEach(childControl => {
|
|
1938
1960
|
this.validateFields(childControl);
|
|
@@ -1967,7 +1989,7 @@ class NgxFormService {
|
|
|
1967
1989
|
// return null;
|
|
1968
1990
|
// return Object.keys(group.controls).find(name => control === group.get(name)) || null;
|
|
1969
1991
|
// }
|
|
1970
|
-
return control.valid;
|
|
1992
|
+
return control?.disabled ? true : control.valid;
|
|
1971
1993
|
}
|
|
1972
1994
|
/**
|
|
1973
1995
|
* @description Generates validators from component properties.
|
|
@@ -2825,6 +2847,20 @@ var component = {
|
|
|
2825
2847
|
previous: "Previous",
|
|
2826
2848
|
submit: "Submit",
|
|
2827
2849
|
cancel: "Cancel"
|
|
2850
|
+
},
|
|
2851
|
+
file_upload: {
|
|
2852
|
+
drag_file: "Drag and drop your image here",
|
|
2853
|
+
buttons: {
|
|
2854
|
+
select: "Select File",
|
|
2855
|
+
preview: "Preview",
|
|
2856
|
+
clear: "Clear"
|
|
2857
|
+
},
|
|
2858
|
+
selection: "{0} file(s) selected with success",
|
|
2859
|
+
selection_error: "{0} file(s) failed validation and will not be uploaded.",
|
|
2860
|
+
errors: {
|
|
2861
|
+
not_allowed: "File {0} is not allowed.",
|
|
2862
|
+
max_size: "The maximum allowed file size is {0} MB"
|
|
2863
|
+
}
|
|
2828
2864
|
}
|
|
2829
2865
|
};
|
|
2830
2866
|
var en = {
|
|
@@ -2842,6 +2878,15 @@ var en = {
|
|
|
2842
2878
|
*
|
|
2843
2879
|
* @link {@link I18nLoader}
|
|
2844
2880
|
*/
|
|
2881
|
+
const libLanguage = { en };
|
|
2882
|
+
/**
|
|
2883
|
+
* @description Retrieves the locale context for a given class, object, or string.
|
|
2884
|
+
* @summary Resolves the locale context by extracting the class name or using the provided suffix.
|
|
2885
|
+
*
|
|
2886
|
+
* @param {FunctionLike | object | string} clazz - The class, object, or string to derive the locale context from.
|
|
2887
|
+
* @param {string} [suffix] - An optional suffix to append to the locale context.
|
|
2888
|
+
* @returns {string} - The resolved locale context string.
|
|
2889
|
+
*/
|
|
2845
2890
|
function getLocaleContext(clazz, suffix) {
|
|
2846
2891
|
return getLocaleFromClassName(clazz, suffix);
|
|
2847
2892
|
}
|
|
@@ -2867,36 +2912,81 @@ function getLocaleContextByKey(locale, phrase) {
|
|
|
2867
2912
|
const parts = phrase.split(' ');
|
|
2868
2913
|
return `${locale}.${cleanSpaces(parts.join('.'), true)}`;
|
|
2869
2914
|
}
|
|
2915
|
+
/**
|
|
2916
|
+
* @description Factory function for creating an instance of I18nLoader.
|
|
2917
|
+
* @summary Configures and returns an I18nLoader instance with the specified HTTP client and translation resources.
|
|
2918
|
+
*
|
|
2919
|
+
* @param {HttpClient} http - The HTTP client used to fetch translation resources.
|
|
2920
|
+
* @returns {TranslateLoader} - An instance of I18nLoader configured with the provided HTTP client and resources.
|
|
2921
|
+
*/
|
|
2870
2922
|
function I18nLoaderFactory(http) {
|
|
2871
2923
|
const { resources, versionedSuffix } = inject(I18N_CONFIG_TOKEN, { optional: true }) ?? provideI18nLoader().useValue;
|
|
2872
2924
|
return new I18nLoader(http, resources?.length ? resources : [{ prefix: './app/assets/i18n/', suffix: '.json' }], versionedSuffix);
|
|
2873
2925
|
}
|
|
2926
|
+
/**
|
|
2927
|
+
* @description Provides the I18nLoader configuration.
|
|
2928
|
+
* @summary Configures the translation resources and versioned suffix for the I18nLoader.
|
|
2929
|
+
*
|
|
2930
|
+
* @param {I18nResourceConfigType} [resources=[]] - The translation resources to be used by the loader.
|
|
2931
|
+
* @param {boolean} [versionedSuffix=false] - Whether to append a versioned suffix to resource URLs.
|
|
2932
|
+
* @returns {object} - The configuration object for the I18nLoader.
|
|
2933
|
+
*/
|
|
2874
2934
|
function provideI18nLoader(resources = [], versionedSuffix = false) {
|
|
2875
|
-
if (!Array.isArray(resources))
|
|
2935
|
+
if (!Array.isArray(resources)) {
|
|
2876
2936
|
resources = [resources];
|
|
2937
|
+
}
|
|
2877
2938
|
return {
|
|
2878
2939
|
provide: I18N_CONFIG_TOKEN,
|
|
2879
|
-
useValue: { resources: [
|
|
2880
|
-
...resources
|
|
2881
|
-
], versionedSuffix }
|
|
2940
|
+
useValue: { resources: [...resources], versionedSuffix },
|
|
2882
2941
|
};
|
|
2883
2942
|
}
|
|
2884
|
-
|
|
2943
|
+
/**
|
|
2944
|
+
* @description Custom implementation of TranslateLoader for loading translations.
|
|
2945
|
+
* @summary Fetches and merges translation resources, supporting versioned suffixes and recursive merging.
|
|
2946
|
+
*/
|
|
2885
2947
|
class I18nLoader {
|
|
2948
|
+
/**
|
|
2949
|
+
* @param {HttpClient} http - The HTTP client used to fetch translation resources.
|
|
2950
|
+
* @param {I18nResourceConfig[]} [resources=[]] - The translation resources to be loaded.
|
|
2951
|
+
* @param {boolean} [versionedSuffix=false] - Whether to append a versioned suffix to resource URLs.
|
|
2952
|
+
*/
|
|
2886
2953
|
constructor(http, resources = [], versionedSuffix = false) {
|
|
2887
2954
|
this.http = http;
|
|
2888
2955
|
this.resources = resources;
|
|
2889
2956
|
this.versionedSuffix = versionedSuffix;
|
|
2890
2957
|
}
|
|
2958
|
+
/**
|
|
2959
|
+
* @description Appends a versioned suffix to the resource URL if enabled.
|
|
2960
|
+
* @summary Generates a versioned suffix based on the current date.
|
|
2961
|
+
*
|
|
2962
|
+
* @param {string} suffix - The original suffix of the resource URL.
|
|
2963
|
+
* @returns {string} - The modified suffix with a version string appended.
|
|
2964
|
+
*/
|
|
2891
2965
|
getSuffix(suffix) {
|
|
2892
|
-
if (!this.versionedSuffix)
|
|
2966
|
+
if (!this.versionedSuffix) {
|
|
2893
2967
|
return suffix;
|
|
2968
|
+
}
|
|
2894
2969
|
const today = new Date();
|
|
2895
2970
|
return `${suffix}?version=${today.getFullYear()}${today.getMonth()}${today.getDay()}`;
|
|
2896
2971
|
}
|
|
2972
|
+
/**
|
|
2973
|
+
* @description Fetches and merges translations for the specified language.
|
|
2974
|
+
* @summary Loads translation resources, merges them recursively, and includes library keys.
|
|
2975
|
+
*
|
|
2976
|
+
* @param {string} lang - The language code for the translations to load.
|
|
2977
|
+
* @returns {Observable<TranslationObject>} - An observable that emits the merged translation object.
|
|
2978
|
+
*/
|
|
2897
2979
|
getTranslation(lang) {
|
|
2898
|
-
const libKeys = libLanguage[lang] || libLanguage[
|
|
2899
|
-
const httpRequests$ = forkJoin(this.resources.map(config => this.http.get(`${config.prefix}${lang}${this.getSuffix(config.suffix)}`)));
|
|
2980
|
+
const libKeys = libLanguage[lang] || libLanguage['en'] || {};
|
|
2981
|
+
const httpRequests$ = forkJoin(this.resources.map(config => this.http.get(`${config.prefix}${lang}${this.getSuffix(config.suffix || '.json')}`)));
|
|
2982
|
+
/**
|
|
2983
|
+
* @description Recursively merges two translation objects.
|
|
2984
|
+
* @summary Combines the properties of the source object into the target object.
|
|
2985
|
+
*
|
|
2986
|
+
* @param {KeyValue} target - The target object to merge into.
|
|
2987
|
+
* @param {KeyValue} source - The source object to merge from.
|
|
2988
|
+
* @returns {KeyValue} - The merged object.
|
|
2989
|
+
*/
|
|
2900
2990
|
function recursiveMerge(target, source) {
|
|
2901
2991
|
for (const key of Object.keys(source)) {
|
|
2902
2992
|
if (source[key] instanceof Object) {
|
|
@@ -2916,24 +3006,47 @@ class I18nLoader {
|
|
|
2916
3006
|
...res.reduce((acc, current) => {
|
|
2917
3007
|
for (const key in current) {
|
|
2918
3008
|
let value = current[key] || {};
|
|
2919
|
-
if (libKeys[key])
|
|
3009
|
+
if (libKeys[key]) {
|
|
2920
3010
|
value = { ...libKeys[key], ...recursiveMerge(libKeys[key], current[key]) };
|
|
3011
|
+
}
|
|
2921
3012
|
acc[key] = value;
|
|
2922
3013
|
}
|
|
2923
3014
|
return acc;
|
|
2924
|
-
}, {})
|
|
3015
|
+
}, {}),
|
|
2925
3016
|
};
|
|
2926
3017
|
return merged;
|
|
2927
3018
|
}));
|
|
2928
3019
|
}
|
|
2929
3020
|
}
|
|
3021
|
+
/**
|
|
3022
|
+
* @description Custom implementation of TranslateParser for interpolation.
|
|
3023
|
+
* @summary Extends TranslateParser to support string formatting with parameters.
|
|
3024
|
+
*/
|
|
2930
3025
|
class I18nParser extends TranslateParser {
|
|
3026
|
+
/**
|
|
3027
|
+
* @description Interpolates a translation string with parameters.
|
|
3028
|
+
* @summary Replaces placeholders in the translation string with parameter values.
|
|
3029
|
+
*
|
|
3030
|
+
* @param {string} value - The translation string to interpolate.
|
|
3031
|
+
* @param {object | string} [params={}] - The parameters to replace placeholders with.
|
|
3032
|
+
* @returns {string} - The interpolated translation string.
|
|
3033
|
+
*/
|
|
2931
3034
|
interpolate(value, params = {}) {
|
|
2932
|
-
if (typeof params === Primitives.STRING)
|
|
2933
|
-
params = {
|
|
3035
|
+
if (typeof params === Primitives.STRING) {
|
|
3036
|
+
params = { '0': params };
|
|
3037
|
+
}
|
|
2934
3038
|
return sf(value, ...Object.values(params));
|
|
2935
3039
|
}
|
|
2936
3040
|
}
|
|
3041
|
+
/**
|
|
3042
|
+
* @description Provides the internationalization (i18n) configuration for the application.
|
|
3043
|
+
* @summary Configures the translation service with a fallback language, default language, custom parser, and loader.
|
|
3044
|
+
*
|
|
3045
|
+
* @param {RootTranslateServiceConfig} [config={fallbackLang: 'en', lang: 'en'}] - The configuration for the translation service, including fallback and default languages.
|
|
3046
|
+
* @param {I18nResourceConfigType} [resources=[]] - The translation resources to be used by the loader.
|
|
3047
|
+
* @param {boolean} [versionedSuffix=false] - Whether to append a versioned suffix to resource URLs.
|
|
3048
|
+
* @returns {Array} - An array of providers for the translation service and loader.
|
|
3049
|
+
*/
|
|
2937
3050
|
function provideI18n(config = { fallbackLang: 'en', lang: 'en' }, resources = [], versionedSuffix = false) {
|
|
2938
3051
|
return [
|
|
2939
3052
|
provideHttpClient(),
|
|
@@ -2947,7 +3060,7 @@ function provideI18n(config = { fallbackLang: 'en', lang: 'en' }, resources = []
|
|
|
2947
3060
|
deps: [HttpClient],
|
|
2948
3061
|
},
|
|
2949
3062
|
}),
|
|
2950
|
-
provideI18nLoader(resources, versionedSuffix)
|
|
3063
|
+
provideI18nLoader(resources, versionedSuffix),
|
|
2951
3064
|
];
|
|
2952
3065
|
}
|
|
2953
3066
|
|
|
@@ -3961,7 +4074,7 @@ class NgxComponentDirective extends LoggedClass {
|
|
|
3961
4074
|
return this.router.navigateByUrl(page);
|
|
3962
4075
|
}
|
|
3963
4076
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgxComponentDirective, deps: [{ token: CPTKN }, { token: CPTKN }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
3964
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.9", type: NgxComponentDirective, isStandalone: true, inputs: { enableDarkMode: "enableDarkMode", isDarkMode: "isDarkMode", name: "name", childOf: "childOf", uid: "uid", model: "model", modelId: "modelId", pk: "pk", mapper: "mapper", operations: "operations", operation: "operation", row: "row", col: "col", className: "className", locale: "locale", item: "item", props: "props", route: "route" }, outputs: { listenEvent: "listenEvent" }, host: { properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0 }); }
|
|
4077
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.9", type: NgxComponentDirective, isStandalone: true, inputs: { enableDarkMode: "enableDarkMode", isDarkMode: "isDarkMode", name: "name", childOf: "childOf", uid: "uid", model: "model", modelId: "modelId", pk: "pk", mapper: "mapper", operations: "operations", operation: "operation", row: "row", col: "col", className: "className", locale: "locale", item: "item", props: "props", route: "route", isModalChild: "isModalChild" }, outputs: { listenEvent: "listenEvent" }, host: { properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0 }); }
|
|
3965
4078
|
}
|
|
3966
4079
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgxComponentDirective, decorators: [{
|
|
3967
4080
|
type: Directive,
|
|
@@ -4013,6 +4126,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
|
|
|
4013
4126
|
type: Input
|
|
4014
4127
|
}], route: [{
|
|
4015
4128
|
type: Input
|
|
4129
|
+
}], isModalChild: [{
|
|
4130
|
+
type: Input
|
|
4016
4131
|
}] } });
|
|
4017
4132
|
|
|
4018
4133
|
class NgxRenderableComponentDirective extends NgxComponentDirective {
|
|
@@ -4104,8 +4219,11 @@ class NgxRenderableComponentDirective extends NgxComponentDirective {
|
|
|
4104
4219
|
* @return {void}
|
|
4105
4220
|
* @memberOf NgxComponentDirective
|
|
4106
4221
|
*/
|
|
4107
|
-
async subscribeEvents() {
|
|
4108
|
-
|
|
4222
|
+
async subscribeEvents(component) {
|
|
4223
|
+
if (!component)
|
|
4224
|
+
component = this?.output?.component;
|
|
4225
|
+
if (!this.instance && component)
|
|
4226
|
+
this.instance = component;
|
|
4109
4227
|
if (this.instance && component) {
|
|
4110
4228
|
const componentKeys = Object.keys(this.instance);
|
|
4111
4229
|
for (const key of componentKeys) {
|
|
@@ -4320,14 +4438,14 @@ class ComponentRendererComponent extends NgxRenderableComponentDirective {
|
|
|
4320
4438
|
// const projectable = (this.children?.length && this.projectable);
|
|
4321
4439
|
// const template = projectable ? this.vcr.createEmbeddedView(this.inner as TemplateRef<unknown>, this.injector).rootNodes : [];
|
|
4322
4440
|
this.instance = NgxRenderingEngine.createComponent(component, props, this.injector, metadata, this.vcr, []);
|
|
4323
|
-
this.subscribeEvents();
|
|
4441
|
+
this.subscribeEvents(component);
|
|
4324
4442
|
}
|
|
4325
4443
|
createParentComponent() {
|
|
4326
4444
|
const { component, inputs } = this.parent;
|
|
4327
4445
|
const metadata = reflectComponentType(component);
|
|
4328
4446
|
const template = this.projectable ? this.vcr.createEmbeddedView(this.inner, this.injector).rootNodes : [];
|
|
4329
4447
|
this.instance = NgxRenderingEngine.createComponent(component, inputs, this.injector, metadata, this.vcr, template);
|
|
4330
|
-
this.subscribeEvents();
|
|
4448
|
+
this.subscribeEvents(component);
|
|
4331
4449
|
}
|
|
4332
4450
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ComponentRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
4333
4451
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: ComponentRendererComponent, isStandalone: true, selector: "ngx-decaf-component-renderer", inputs: { tag: "tag", children: "children", projectable: "projectable", parent: "parent" }, host: { properties: { "attr.id": "uid" } }, usesInheritance: true, ngImport: i0, template: "<!-- Keep to avoid id conflicts -->\n\n<ng-template #componentOuter></ng-template>\n\n<ng-template #componentInner>\n @if (parent?.children?.length) {\n @for(child of parent.children; track child) {\n @if (!child.children?.length) {\n <ng-container\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n } @else {\n <ngx-decaf-component-renderer [parent]=\"child\"> </ngx-decaf-component-renderer>\n }\n }\n }\n @if (projectable) {\n @if (children?.length) {\n @for(child of children; track child) {\n @if (child.children?.length) {\n <ng-container\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n } @else {\n <ng-container\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n }\n }\n }\n }\n\n</ng-template>\n\n", styles: [""], dependencies: [{ kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "children", "projectable", "parent"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }] }); }
|
|
@@ -4608,7 +4726,7 @@ class NgxFormFieldDirective extends NgxComponentDirective {
|
|
|
4608
4726
|
}));
|
|
4609
4727
|
if (errors.length) {
|
|
4610
4728
|
if (accordionComponent && !this.validationErrorEventDispatched) {
|
|
4611
|
-
const validationErrorEvent = new CustomEvent(
|
|
4729
|
+
const validationErrorEvent = new CustomEvent(ComponentEventNames.VALIDATION_ERROR, {
|
|
4612
4730
|
detail: { fieldName: this.name, hasErrors: true },
|
|
4613
4731
|
bubbles: true
|
|
4614
4732
|
});
|
|
@@ -4676,104 +4794,621 @@ function Dynamic() {
|
|
|
4676
4794
|
}
|
|
4677
4795
|
|
|
4678
4796
|
/**
|
|
4679
|
-
* @
|
|
4680
|
-
* @
|
|
4681
|
-
*
|
|
4682
|
-
*
|
|
4683
|
-
*
|
|
4684
|
-
* options, making it suitable for building dynamic forms for create, read, update, and delete
|
|
4685
|
-
* operations.
|
|
4686
|
-
*
|
|
4687
|
-
* @param {CrudOperations} operation - The CRUD operation being performed (create, read, update, delete)
|
|
4688
|
-
* @param {string} name - The field name, used as form control identifier
|
|
4689
|
-
* @param {PossibleInputTypes} type - The input type (text, number, date, select, etc.)
|
|
4690
|
-
* @param {string|number|Date} value - The initial value of the field
|
|
4691
|
-
* @param {boolean} disabled - Whether the field is disabled
|
|
4692
|
-
* @param {string} label - The display label for the field
|
|
4693
|
-
* @param {string} placeholder - Placeholder text when field is empty
|
|
4694
|
-
* @param {string} format - Format pattern for the field value
|
|
4695
|
-
* @param {boolean} hidden - Whether the field should be hidden
|
|
4696
|
-
* @param {number|Date} max - Maximum allowed value
|
|
4697
|
-
* @param {number} maxlength - Maximum allowed length
|
|
4698
|
-
* @param {number|Date} min - Minimum allowed value
|
|
4699
|
-
* @param {number} minlength - Minimum allowed length
|
|
4700
|
-
* @param {string} pattern - Validation pattern
|
|
4701
|
-
* @param {boolean} readonly - Whether the field is read-only
|
|
4702
|
-
* @param {boolean} required - Whether the field is required
|
|
4703
|
-
* @param {number} step - Step value for number inputs
|
|
4704
|
-
* @param {FormGroup} formGroup - The parent form group
|
|
4705
|
-
* @param {StringOrBoolean} translatable - Whether field labels should be translated
|
|
4797
|
+
* @module module:lib/components/model-renderer/model-renderer.component
|
|
4798
|
+
* @description Model renderer component module.
|
|
4799
|
+
* @summary Exposes `ModelRendererComponent` which dynamically renders UI components
|
|
4800
|
+
* from model definitions using the `NgxRenderingEngine`. It handles model changes,
|
|
4801
|
+
* event subscription and lifecycle for the rendered output.
|
|
4706
4802
|
*
|
|
4707
|
-
* @
|
|
4803
|
+
* @link {@link ModelRendererComponent}
|
|
4804
|
+
*/
|
|
4805
|
+
/**
|
|
4806
|
+
* @description Component for rendering dynamic models
|
|
4807
|
+
* @summary This component is responsible for dynamically rendering models,
|
|
4808
|
+
* handling model changes, and managing event subscriptions for the rendered components.
|
|
4809
|
+
* It uses the NgxRenderingEngine to render the models and supports both string and Model inputs.
|
|
4810
|
+
* @class
|
|
4811
|
+
* @template M - Type extending Model
|
|
4812
|
+
* @param {Injector} injector - Angular Injector for dependency injection
|
|
4708
4813
|
* @example
|
|
4709
|
-
* <ngx-decaf-
|
|
4710
|
-
*
|
|
4711
|
-
*
|
|
4712
|
-
*
|
|
4713
|
-
*
|
|
4714
|
-
*
|
|
4715
|
-
*
|
|
4716
|
-
*
|
|
4814
|
+
* <ngx-decaf-model-renderer
|
|
4815
|
+
* [model]="myModel"
|
|
4816
|
+
* [globals]="globalVariables"
|
|
4817
|
+
* (listenEvent)="handleEvent($event)">
|
|
4818
|
+
* </ngx-decaf-model-renderer>
|
|
4819
|
+
* @mermaid
|
|
4820
|
+
* sequenceDiagram
|
|
4821
|
+
* participant App
|
|
4822
|
+
* participant ModelRenderer
|
|
4823
|
+
* participant RenderingEngine
|
|
4824
|
+
* participant Model
|
|
4825
|
+
* App->>ModelRenderer: Input model
|
|
4826
|
+
* ModelRenderer->>Model: Parse if string
|
|
4827
|
+
* Model-->>ModelRenderer: Parsed model
|
|
4828
|
+
* ModelRenderer->>RenderingEngine: Render model
|
|
4829
|
+
* RenderingEngine-->>ModelRenderer: Rendered output
|
|
4830
|
+
* ModelRenderer->>ModelRenderer: Subscribe to events
|
|
4831
|
+
* ModelRenderer-->>App: Emit events
|
|
4832
|
+
*/
|
|
4833
|
+
class ModelRendererComponent extends NgxRenderableComponentDirective {
|
|
4834
|
+
constructor() {
|
|
4835
|
+
super(...arguments);
|
|
4836
|
+
/**
|
|
4837
|
+
* @description Set if render content projection is allowed
|
|
4838
|
+
* @default true
|
|
4839
|
+
*/
|
|
4840
|
+
this.projectable = true;
|
|
4841
|
+
}
|
|
4842
|
+
// private injector: Injector = inject(Injector);
|
|
4843
|
+
// constructor() {}
|
|
4844
|
+
/**
|
|
4845
|
+
* @description Refreshes the rendered model
|
|
4846
|
+
* @param {string | M} model - The model to be rendered
|
|
4847
|
+
*/
|
|
4848
|
+
refresh(model) {
|
|
4849
|
+
model =
|
|
4850
|
+
typeof model === 'string'
|
|
4851
|
+
? Model.build({}, model)
|
|
4852
|
+
: model;
|
|
4853
|
+
this.output = model.render(this.globals || {}, this.vcr, this.injector, this.inner, this.projectable);
|
|
4854
|
+
if (this.output?.inputs)
|
|
4855
|
+
this.rendererId = sf(AngularEngineKeys.RENDERED_ID, this.output.inputs['rendererId']);
|
|
4856
|
+
this.instance = this.output?.component;
|
|
4857
|
+
this.subscribeEvents();
|
|
4858
|
+
}
|
|
4859
|
+
/**
|
|
4860
|
+
* @description Lifecycle hook that is called when data-bound properties of a directive change
|
|
4861
|
+
* @param {SimpleChanges} changes - Object containing changes
|
|
4862
|
+
*/
|
|
4863
|
+
ngOnChanges(changes) {
|
|
4864
|
+
if (changes[BaseComponentProps.MODEL]) {
|
|
4865
|
+
const { currentValue } = changes[BaseComponentProps.MODEL];
|
|
4866
|
+
this.refresh(currentValue);
|
|
4867
|
+
}
|
|
4868
|
+
}
|
|
4869
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ModelRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
4870
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: ModelRendererComponent, isStandalone: true, selector: "ngx-decaf-model-renderer", inputs: { projectable: "projectable" }, host: { properties: { "attr.id": "uid" } }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: " <!-- Keep to avoid id conflicts -->\n <div class=\"dcf-hidden\" [id]=\"uid\"></div>\n\n <ng-template #componentOuter></ng-template>\n <!-- <ng-template #inner>\n <div class=\"dcf-grid dcf-grid-small dcf-model-renderer-component dcf-child-width-1-1\" [id]=\"rendererId || ''\">\n @for (child of output?.children; track child) {\n @if (child?.children?.length) {\n <ngx-decaf-component-renderer [parent]=\"child\" />\n } @else {\n <ng-container\n #childComponents\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n }\n }\n </div>\n </ng-template> -->\n", styles: [""] }); }
|
|
4871
|
+
}
|
|
4872
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ModelRendererComponent, decorators: [{
|
|
4873
|
+
type: Component,
|
|
4874
|
+
args: [{ standalone: true, imports: [], selector: 'ngx-decaf-model-renderer', host: { '[attr.id]': 'uid' }, template: " <!-- Keep to avoid id conflicts -->\n <div class=\"dcf-hidden\" [id]=\"uid\"></div>\n\n <ng-template #componentOuter></ng-template>\n <!-- <ng-template #inner>\n <div class=\"dcf-grid dcf-grid-small dcf-model-renderer-component dcf-child-width-1-1\" [id]=\"rendererId || ''\">\n @for (child of output?.children; track child) {\n @if (child?.children?.length) {\n <ngx-decaf-component-renderer [parent]=\"child\" />\n } @else {\n <ng-container\n #childComponents\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n }\n }\n </div>\n </ng-template> -->\n" }]
|
|
4875
|
+
}], propDecorators: { projectable: [{
|
|
4876
|
+
type: Input
|
|
4877
|
+
}] } });
|
|
4878
|
+
|
|
4879
|
+
/**
|
|
4880
|
+
* @module module:lib/engine/NgxParentComponentDirective
|
|
4881
|
+
* @description Directive base for parent container components used by the rendering system.
|
|
4882
|
+
* @summary Provides NgxParentComponentDirective which offers inputs for children metadata,
|
|
4883
|
+
* column/row configuration and parent component wiring used by layout and container components.
|
|
4717
4884
|
*
|
|
4885
|
+
* @link {@link NgxParentComponentDirective}
|
|
4886
|
+
*/
|
|
4887
|
+
/**
|
|
4888
|
+
* @description Layout component for creating responsive grid layouts in Angular applications.
|
|
4889
|
+
* @summary This component provides a flexible grid system that can be configured with dynamic
|
|
4890
|
+
* rows and columns. It supports responsive breakpoints and can render child components within
|
|
4891
|
+
* the grid structure. The component extends NgxComponentDirective to inherit common functionality
|
|
4892
|
+
* and integrates with the model and component renderer systems.
|
|
4718
4893
|
*
|
|
4719
|
-
* @
|
|
4894
|
+
* @class NgxParentComponentDirective
|
|
4895
|
+
* @extends {NgxComponentDirective}
|
|
4896
|
+
* @implements {OnInit}
|
|
4720
4897
|
*/
|
|
4721
|
-
|
|
4898
|
+
class NgxParentComponentDirective extends NgxComponentDirective {
|
|
4722
4899
|
constructor() {
|
|
4723
4900
|
super(...arguments);
|
|
4724
|
-
this.className = 'dcf-width-1-1';
|
|
4725
4901
|
/**
|
|
4726
|
-
|
|
4727
|
-
|
|
4902
|
+
* @description Unique identifier for the current record.
|
|
4903
|
+
* @summary A unique identifier for the current record being displayed or manipulated.
|
|
4904
|
+
* This is typically used in conjunction with the primary key for operations on specific records.
|
|
4905
|
+
*
|
|
4906
|
+
* @type {string | number}
|
|
4907
|
+
*/
|
|
4908
|
+
this.page = 1;
|
|
4909
|
+
/**
|
|
4910
|
+
* @description Unique identifier for the current record.
|
|
4911
|
+
* @summary A unique identifier for the current record being displayed or manipulated.
|
|
4912
|
+
* This is typically used in conjunction with the primary key for operations on specific records.
|
|
4728
4913
|
*
|
|
4729
|
-
* @type {string}
|
|
4730
|
-
* @memberOf CrudFieldComponent
|
|
4914
|
+
* @type {string | number}
|
|
4731
4915
|
*/
|
|
4916
|
+
this.pages = 1;
|
|
4732
4917
|
/**
|
|
4733
|
-
* @description
|
|
4734
|
-
* @summary
|
|
4735
|
-
*
|
|
4736
|
-
*
|
|
4918
|
+
* @description Array of UI model metadata for the currently active page.
|
|
4919
|
+
* @summary Contains only the UI model metadata for fields that should be displayed
|
|
4920
|
+
* on the currently active page. This is a filtered subset of the children array,
|
|
4921
|
+
* updated whenever the user navigates between pages.
|
|
4737
4922
|
*
|
|
4738
|
-
* @type {
|
|
4739
|
-
* @default ''
|
|
4740
|
-
* @memberOf CrudFieldComponent
|
|
4923
|
+
* @type { UIModelMetadata | UIModelMetadata[] | FieldDefinition | FieldDefinition[] | undefined }
|
|
4741
4924
|
*/
|
|
4742
|
-
this.
|
|
4925
|
+
this.activePage = undefined;
|
|
4743
4926
|
/**
|
|
4744
|
-
* @description The
|
|
4745
|
-
* @summary
|
|
4746
|
-
*
|
|
4927
|
+
* @description The currently active page number.
|
|
4928
|
+
* @summary Tracks which page of the multi-step form is currently being displayed.
|
|
4929
|
+
* This property is updated as users navigate through the form steps using
|
|
4930
|
+
* the next/back buttons or programmatic navigation.
|
|
4747
4931
|
*
|
|
4748
|
-
* @type {
|
|
4749
|
-
* @default ''
|
|
4750
|
-
* @memberOf CrudFieldComponent
|
|
4932
|
+
* @type {number}
|
|
4751
4933
|
*/
|
|
4752
|
-
this.
|
|
4934
|
+
this.activeIndex = 1;
|
|
4753
4935
|
/**
|
|
4754
|
-
* @description
|
|
4755
|
-
* @summary
|
|
4756
|
-
*
|
|
4936
|
+
* @description Array of UI model metadata for all form fields.
|
|
4937
|
+
* @summary Contains the complete collection of UI model metadata that defines
|
|
4938
|
+
* the structure, validation, and presentation of form fields across all pages.
|
|
4939
|
+
* Each metadata object contains information about field type, validation rules,
|
|
4940
|
+
* page assignment, and display properties.
|
|
4757
4941
|
*
|
|
4758
|
-
* @type {
|
|
4759
|
-
* @memberOf CrudFieldComponent
|
|
4942
|
+
* @type {UIModelMetadata[]}
|
|
4760
4943
|
*/
|
|
4761
|
-
this.
|
|
4944
|
+
this.children = [];
|
|
4762
4945
|
/**
|
|
4763
|
-
* @description
|
|
4764
|
-
* @summary
|
|
4765
|
-
*
|
|
4946
|
+
* @description Number of columns or array of column definitions for the grid layout.
|
|
4947
|
+
* @summary Defines the column structure of the grid. When a number is provided, it creates
|
|
4948
|
+
* that many equal-width columns. When an array is provided, each element can define specific
|
|
4949
|
+
* column properties or sizing. This allows for flexible grid layouts that can adapt to
|
|
4950
|
+
* different content requirements.
|
|
4766
4951
|
*
|
|
4767
|
-
* @type {
|
|
4768
|
-
* @
|
|
4952
|
+
* @type {(number | string[])}
|
|
4953
|
+
* @default 1
|
|
4769
4954
|
*/
|
|
4770
|
-
this.
|
|
4955
|
+
this.cols = 1;
|
|
4771
4956
|
/**
|
|
4772
|
-
* @description
|
|
4773
|
-
* @summary
|
|
4774
|
-
*
|
|
4775
|
-
*
|
|
4776
|
-
*
|
|
4957
|
+
* @description Number of rows or array of row definitions for the grid layout.
|
|
4958
|
+
* @summary Defines the row structure of the grid. When a number is provided, it creates
|
|
4959
|
+
* that many equal-height rows. When an array is provided, each element can define specific
|
|
4960
|
+
* row properties or sizing. This provides control over vertical spacing and content organization.
|
|
4961
|
+
*
|
|
4962
|
+
* @type {(number | string[])}
|
|
4963
|
+
* @default 1
|
|
4964
|
+
*/
|
|
4965
|
+
this.rows = 1;
|
|
4966
|
+
/**
|
|
4967
|
+
* @description Defines the body style of the card.
|
|
4968
|
+
* @summary Specifies the appearance of the card body, allowing customization
|
|
4969
|
+
* between default, small, or blank styles. This input is used to control the
|
|
4970
|
+
* visual presentation of the card content.
|
|
4971
|
+
* @type {'default' | 'small' | 'blank'}
|
|
4972
|
+
* @default 'default'
|
|
4973
|
+
*/
|
|
4974
|
+
this.cardBody = 'default';
|
|
4975
|
+
/**
|
|
4976
|
+
* @description Specifies the type of the card.
|
|
4977
|
+
* @summary Determines the card's visual style, such as clear or shadowed.
|
|
4978
|
+
* This input allows for flexible styling of the card component to match
|
|
4979
|
+
* different design requirements.
|
|
4980
|
+
* @type {'clear' | 'shadow'}
|
|
4981
|
+
* @default 'clear'
|
|
4982
|
+
*/
|
|
4983
|
+
this.cardType = 'clear';
|
|
4984
|
+
/**
|
|
4985
|
+
* @description Controls whether borders are displayed around the fieldset.
|
|
4986
|
+
* @summary Boolean flag that determines if the fieldset should be visually outlined with borders.
|
|
4987
|
+
* When true, borders are shown to visually separate the fieldset from surrounding content.
|
|
4988
|
+
*
|
|
4989
|
+
* @type {boolean}
|
|
4990
|
+
* @default true
|
|
4991
|
+
*/
|
|
4992
|
+
this.borders = false;
|
|
4993
|
+
/**
|
|
4994
|
+
* @description Media breakpoint for responsive behavior.
|
|
4995
|
+
* @summary Determines the responsive breakpoint at which the layout should adapt.
|
|
4996
|
+
* This affects how the grid behaves on different screen sizes, allowing for
|
|
4997
|
+
* mobile-first or desktop-first responsive design patterns. The breakpoint
|
|
4998
|
+
* is automatically processed to ensure compatibility with the UI framework.
|
|
4999
|
+
*
|
|
5000
|
+
* @type {UIMediaBreakPointsType}
|
|
5001
|
+
* @default 'medium'
|
|
5002
|
+
*/
|
|
5003
|
+
this.breakpoint = UIMediaBreakPoints.MEDIUM;
|
|
5004
|
+
/**
|
|
5005
|
+
* @description Determines if the layout should match the parent container's size or configuration.
|
|
5006
|
+
* @summary Boolean flag that controls whether the component should adapt its layout to match its parent.
|
|
5007
|
+
* When true, the component will attempt to align or size itself according to the parent container.
|
|
5008
|
+
*
|
|
5009
|
+
* @type {boolean}
|
|
5010
|
+
* @default true
|
|
5011
|
+
*/
|
|
5012
|
+
this.match = true;
|
|
5013
|
+
/**
|
|
5014
|
+
* @description Preloads card placeholders for rendering.
|
|
5015
|
+
* @summary Used to create an array of placeholder elements for card components,
|
|
5016
|
+
* typically to reserve space or trigger rendering logic before actual data is loaded.
|
|
5017
|
+
*
|
|
5018
|
+
* @type {any[]}
|
|
5019
|
+
* @default [undefined]
|
|
5020
|
+
*/
|
|
5021
|
+
this.preloadCards = new Array(1);
|
|
5022
|
+
}
|
|
5023
|
+
async ngOnInit(model) {
|
|
5024
|
+
if (model)
|
|
5025
|
+
this.model = model;
|
|
5026
|
+
if (this.model && !this.repository)
|
|
5027
|
+
this._repository = this.repository;
|
|
5028
|
+
}
|
|
5029
|
+
ngOnDestroy() {
|
|
5030
|
+
super.ngOnDestroy();
|
|
5031
|
+
if (this.timerSubscription)
|
|
5032
|
+
this.timerSubscription.unsubscribe();
|
|
5033
|
+
}
|
|
5034
|
+
getActivePage(page) {
|
|
5035
|
+
const content = this.children[page];
|
|
5036
|
+
this.activePage = undefined;
|
|
5037
|
+
this.preloadCards = [...new Array(1)];
|
|
5038
|
+
this.timerSubscription = timer(1).subscribe(() => this.activePage = { ...this.children[page] });
|
|
5039
|
+
this.activeIndex = page;
|
|
5040
|
+
if (content)
|
|
5041
|
+
return content;
|
|
5042
|
+
return undefined;
|
|
5043
|
+
}
|
|
5044
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgxParentComponentDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
5045
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.9", type: NgxParentComponentDirective, isStandalone: true, inputs: { page: "page", pages: "pages", parentForm: "parentForm", children: "children", cols: "cols", rows: "rows", cardBody: "cardBody", cardType: "cardType", borders: "borders", breakpoint: "breakpoint", match: "match" }, usesInheritance: true, ngImport: i0 }); }
|
|
5046
|
+
}
|
|
5047
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgxParentComponentDirective, decorators: [{
|
|
5048
|
+
type: Directive
|
|
5049
|
+
}], propDecorators: { page: [{
|
|
5050
|
+
type: Input
|
|
5051
|
+
}], pages: [{
|
|
5052
|
+
type: Input
|
|
5053
|
+
}], parentForm: [{
|
|
5054
|
+
type: Input
|
|
5055
|
+
}], children: [{
|
|
5056
|
+
type: Input
|
|
5057
|
+
}], cols: [{
|
|
5058
|
+
type: Input
|
|
5059
|
+
}], rows: [{
|
|
5060
|
+
type: Input
|
|
5061
|
+
}], cardBody: [{
|
|
5062
|
+
type: Input
|
|
5063
|
+
}], cardType: [{
|
|
5064
|
+
type: Input
|
|
5065
|
+
}], borders: [{
|
|
5066
|
+
type: Input
|
|
5067
|
+
}], breakpoint: [{
|
|
5068
|
+
type: Input
|
|
5069
|
+
}], match: [{
|
|
5070
|
+
type: Input
|
|
5071
|
+
}] } });
|
|
5072
|
+
|
|
5073
|
+
/**
|
|
5074
|
+
* @description Modal component for displaying dynamic content in a modal dialog.
|
|
5075
|
+
* @summary This component provides a flexible and reusable modal dialog implementation
|
|
5076
|
+
* for Angular applications. It supports dynamic content rendering, customizable options,
|
|
5077
|
+
* and event handling for modal lifecycle events. The modal can be used for various purposes,
|
|
5078
|
+
* such as displaying forms, lightboxes, or selection dialogs.
|
|
5079
|
+
*
|
|
5080
|
+
* @class ModalComponent
|
|
5081
|
+
* @example
|
|
5082
|
+
* ```typescript
|
|
5083
|
+
* <ngx-decaf-modal [isOpen]="true" [title]="'Example Modal'"></ngx-decaf-modal>
|
|
5084
|
+
* ```
|
|
5085
|
+
* @mermaid
|
|
5086
|
+
* sequenceDiagram
|
|
5087
|
+
* participant User
|
|
5088
|
+
* participant ModalComponent
|
|
5089
|
+
* User->>ModalComponent: Open modal
|
|
5090
|
+
* ModalComponent->>ModalController: Initialize modal
|
|
5091
|
+
* ModalController-->>ModalComponent: Modal options set
|
|
5092
|
+
* User->>ModalComponent: Interact with modal
|
|
5093
|
+
* ModalComponent->>ModalController: Handle dismiss event
|
|
5094
|
+
*/
|
|
5095
|
+
let ModalComponent = class ModalComponent extends NgxParentComponentDirective {
|
|
5096
|
+
constructor() {
|
|
5097
|
+
super("ModalComponent");
|
|
5098
|
+
/**
|
|
5099
|
+
* @description Determines whether the modal is open.
|
|
5100
|
+
* @summary Controls the visibility of the modal dialog. When set to true, the modal is displayed.
|
|
5101
|
+
* @type {boolean}
|
|
5102
|
+
* @default false
|
|
5103
|
+
*/
|
|
5104
|
+
this.isOpen = false;
|
|
5105
|
+
/**
|
|
5106
|
+
* @description Position of the inline content within the modal.
|
|
5107
|
+
* @summary Determines whether the inline content is displayed at the top or bottom of the modal.
|
|
5108
|
+
* @type {'top' | 'bottom'}
|
|
5109
|
+
* @default 'bottom'
|
|
5110
|
+
*/
|
|
5111
|
+
this.inlineContentPosition = 'bottom';
|
|
5112
|
+
/**
|
|
5113
|
+
* @description Enables fullscreen mode for the modal.
|
|
5114
|
+
* @summary When set to true, the modal occupies the entire screen.
|
|
5115
|
+
* @type {boolean}
|
|
5116
|
+
* @default false
|
|
5117
|
+
*/
|
|
5118
|
+
this.fullscreen = false;
|
|
5119
|
+
/**
|
|
5120
|
+
* @description Enables lightbox mode for the modal.
|
|
5121
|
+
* @summary When set to true, the modal is displayed as a lightbox.
|
|
5122
|
+
* @type {boolean}
|
|
5123
|
+
* @default false
|
|
5124
|
+
*/
|
|
5125
|
+
this.lightBox = false;
|
|
5126
|
+
/**
|
|
5127
|
+
* @description Event emitted when the modal is about to be dismissed.
|
|
5128
|
+
* @summary Emits an OverlayEventDetail object containing details about the dismiss event.
|
|
5129
|
+
* @type {EventEmitter<OverlayEventDetail>}
|
|
5130
|
+
*/
|
|
5131
|
+
this.willDismissEvent = new EventEmitter();
|
|
5132
|
+
/**
|
|
5133
|
+
* @description Sanitizer instance for bypassing security and sanitizing HTML content.
|
|
5134
|
+
* @summary Used to sanitize dynamic HTML content, ensuring it is safe to render in the DOM.
|
|
5135
|
+
* @type {DomSanitizer}
|
|
5136
|
+
*/
|
|
5137
|
+
this.domSanitizer = inject(DomSanitizer);
|
|
5138
|
+
addIcons(allIcons);
|
|
5139
|
+
}
|
|
5140
|
+
/**
|
|
5141
|
+
* @description Lifecycle hook that initializes the modal component.
|
|
5142
|
+
* @summary Sets up the modal controller and sanitizes inline content if provided.
|
|
5143
|
+
*
|
|
5144
|
+
* @returns {Promise<void>} - A promise that resolves when initialization is complete.
|
|
5145
|
+
*/
|
|
5146
|
+
async ngOnInit() {
|
|
5147
|
+
if (this.inlineContent && typeof this.inlineContent === Primitives.STRING) {
|
|
5148
|
+
this.inlineContent = this.domSanitizer.bypassSecurityTrustHtml(this.inlineContent);
|
|
5149
|
+
}
|
|
5150
|
+
}
|
|
5151
|
+
/**
|
|
5152
|
+
* @description Initializes the modal with the provided options.
|
|
5153
|
+
* @summary Merges default options with user-provided options and sets global configuration.
|
|
5154
|
+
*
|
|
5155
|
+
* @param {KeyValue} [options={}] - Additional options for modal initialization.
|
|
5156
|
+
* @returns {Promise<void>} - A promise that resolves when initialization is complete.
|
|
5157
|
+
*/
|
|
5158
|
+
async initialize(options = {}) {
|
|
5159
|
+
this.options = Object.assign({}, DefaultModalOptions, this.options, options);
|
|
5160
|
+
this.globals = Object.assign({}, this.globals || {}, { isModalChild: true });
|
|
5161
|
+
this.initialized = true;
|
|
5162
|
+
}
|
|
5163
|
+
/**
|
|
5164
|
+
* @description Creates and presents the modal.
|
|
5165
|
+
* @summary Initializes the modal with the provided properties and displays it.
|
|
5166
|
+
*
|
|
5167
|
+
* @param {KeyValue} [props={}] - Properties to initialize the modal.
|
|
5168
|
+
* @returns {Promise<ModalComponent>} - A promise that resolves with the modal instance.
|
|
5169
|
+
*/
|
|
5170
|
+
async create(props = {}) {
|
|
5171
|
+
await this.initialize(props);
|
|
5172
|
+
await this.present();
|
|
5173
|
+
return this;
|
|
5174
|
+
}
|
|
5175
|
+
/**
|
|
5176
|
+
* @description Presents the modal.
|
|
5177
|
+
* @summary Sets the modal's visibility to true and triggers change detection.
|
|
5178
|
+
*
|
|
5179
|
+
* @returns {Promise<void>} - A promise that resolves when the modal is presented.
|
|
5180
|
+
*/
|
|
5181
|
+
async present() {
|
|
5182
|
+
this.isOpen = true;
|
|
5183
|
+
this.changeDetectorRef.detectChanges();
|
|
5184
|
+
}
|
|
5185
|
+
/**
|
|
5186
|
+
* @description Handles custom events for the modal.
|
|
5187
|
+
* @summary Stops event propagation and triggers confirm or cancel actions based on event data.
|
|
5188
|
+
*
|
|
5189
|
+
* @param {IBaseCustomEvent} event - The custom event to handle.
|
|
5190
|
+
* @returns {Promise<void>} - A promise that resolves when the event is handled.
|
|
5191
|
+
*/
|
|
5192
|
+
async handleEvent(event) {
|
|
5193
|
+
if (event instanceof Event) {
|
|
5194
|
+
event.stopImmediatePropagation();
|
|
5195
|
+
}
|
|
5196
|
+
await (event?.data ? this.confirm(event) : this.cancel());
|
|
5197
|
+
}
|
|
5198
|
+
/**
|
|
5199
|
+
* @description Handles the modal dismiss event.
|
|
5200
|
+
* @summary This method is triggered when the modal is about to be dismissed. It emits the `willDismissEvent` with the event details.
|
|
5201
|
+
*
|
|
5202
|
+
* @param {CustomEvent<OverlayEventDetail>} event - The dismiss event containing overlay details.
|
|
5203
|
+
* @returns {Promise<OverlayEventDetail>} - A promise that resolves with the overlay event details.
|
|
5204
|
+
*/
|
|
5205
|
+
async handleWillDismiss(event) {
|
|
5206
|
+
const { detail } = event;
|
|
5207
|
+
this.willDismissEvent.emit(event);
|
|
5208
|
+
return detail;
|
|
5209
|
+
}
|
|
5210
|
+
/**
|
|
5211
|
+
* @description Cancels the modal and dismisses it with a cancel action.
|
|
5212
|
+
* @summary This method is used to programmatically close the modal with a cancel action.
|
|
5213
|
+
*
|
|
5214
|
+
* @returns {Promise<void>} - A promise that resolves when the modal is dismissed.
|
|
5215
|
+
*/
|
|
5216
|
+
async cancel() {
|
|
5217
|
+
await this.modal.dismiss(undefined, ActionRoles.cancel);
|
|
5218
|
+
}
|
|
5219
|
+
/**
|
|
5220
|
+
* @description Confirms the modal and dismisses it with a confirm action.
|
|
5221
|
+
* @summary This method is used to programmatically close the modal with a confirm action, passing optional event data.
|
|
5222
|
+
*
|
|
5223
|
+
* @param {IBaseCustomEvent} event - The custom event containing data to pass during confirmation.
|
|
5224
|
+
* @returns {Promise<void>} - A promise that resolves when the modal is dismissed.
|
|
5225
|
+
*/
|
|
5226
|
+
async confirm(event) {
|
|
5227
|
+
await this.modal.dismiss(event?.data || undefined, ActionRoles.confirm);
|
|
5228
|
+
}
|
|
5229
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5230
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: ModalComponent, isStandalone: true, selector: "ngx-decaf-modal", inputs: { title: "title", isOpen: "isOpen", tag: "tag", options: "options", globals: "globals", inlineContent: "inlineContent", inlineContentPosition: "inlineContentPosition", fullscreen: "fullscreen", lightBox: "lightBox" }, outputs: { willDismissEvent: "willDismissEvent" }, host: { properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "modal", first: true, predicate: ["component"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<ion-modal\n [id]=\"uid\"\n [isOpen]=\"isOpen\"\n (willDismiss)=\"handleWillDismiss($event)\"\n [backdropDismiss]=\"options?.backdropDismiss\"\n [showBackdrop]=\"options?.showBackdrop\"\n [animated]=\"options?.animated\"\n [canDismiss]=\"options?.canDismiss\"\n [class.dcf-fullscreen-modal]=\"fullscreen\"\n [class.dcf-lightbox-modal]=\"lightBox\"\n class=\"dcf-modal-component\"\n #component\n>\n <ng-template>\n <ion-header [transparent]=\"lightBox\">\n <ion-toolbar>\n @if (title) {\n <ion-title>{{ title | translate }}</ion-title>\n }\n <ion-buttons slot=\"end\">\n <ion-button size=\"small\" type=\"button\" class=\"dcf-button-close\" (click)=\"cancel()\">\n <ion-icon name=\"close-outline\" aria-hidden=\"true\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n\n <ion-content>\n <section class=\"dcf-modal-body\">\n @if (!tag && !model && !inlineContent) {\n <div class=\"dcf-loading-container\">\n <ion-spinner name=\"crescent\" color=\"primary\"></ion-spinner>\n </div>\n } @else {\n @if (inlineContent && inlineContentPosition === \"top\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n @if (model) {\n <ngx-decaf-model-renderer\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"globals\"\n />\n }\n @if(tag && globals) {\n <ngx-decaf-component-renderer\n [tag]=\"tag\"\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"{props: globals}\"\n />\n }\n @if (inlineContent && inlineContentPosition === \"bottom\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n }\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n", styles: [".dcf-modal-component.dcf-fullscreen-modal{--height: 100%;--width: 100%;--max-width: 100%;--border-radius: 0}.dcf-modal-component.dcf-fullscreen-modal.dcf-lightbox-modal{padding:var(--dcf-padding-small)}.dcf-modal-component.dcf-lightbox-modal{--background: transparent;--box-shadow: none !important}@media (max-width: 767px){.dcf-modal-component.dcf-lightbox-modal{padding:var(--dcf-padding-xsmall)}.dcf-modal-component.dcf-lightbox-modal ion-button{transform:translate(2px,2px)!important}}.dcf-modal-component.dcf-lightbox-modal ion-header{--background: transparent !important;background-color:transparent;box-shadow:none!important;padding:unset!important;margin:unset!important;height:30px}.dcf-modal-component.dcf-lightbox-modal ion-header ion-button{margin:0!important;width:32px!important;height:25px!important;--background: var(--dcf-color-light) !important;transform:translate(2px);--border-radius: var(--dcf-border-radius-small) !important}.dcf-modal-component.dcf-lightbox-modal ion-header ion-button *{margin:-5px}.dcf-modal-component.dcf-lightbox-modal ion-header ion-toolbar{--background: transparent !important;padding:unset!important;margin:unset!important}.dcf-modal-component.dcf-lightbox-modal ion-content{--background: transparent !important}.dcf-modal-component.dcf-lightbox-modal .dcf-modal-body{display:flex;height:auto;justify-content:center;align-items:center;background:#fff!important}.dcf-modal-component:not(.dcf-lightbox-modal) .dcf-modal-body{height:100%;padding:1.5rem 1rem}.dcf-modal-component .dcf-loading-container{height:50%;display:flex;justify-content:center;align-items:center}.dcf-modal-component .dcf-loading-container ion-spinner{width:60px;height:60px}\n"], dependencies: [{ kind: "component", type: IonModal, selector: "ion-modal" }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "children", "projectable", "parent"] }, { kind: "component", type: ModelRendererComponent, selector: "ngx-decaf-model-renderer", inputs: ["projectable"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: 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: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
5231
|
+
};
|
|
5232
|
+
ModalComponent = __decorate([
|
|
5233
|
+
Dynamic(),
|
|
5234
|
+
__metadata("design:paramtypes", [])
|
|
5235
|
+
], ModalComponent);
|
|
5236
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ModalComponent, decorators: [{
|
|
5237
|
+
type: Component,
|
|
5238
|
+
args: [{ selector: 'ngx-decaf-modal', standalone: true, imports: [IonModal, ComponentRendererComponent, ModelRendererComponent, TranslatePipe, IonSpinner, IonButton, IonButtons, IonContent, IonHeader, IonTitle, IonToolbar], host: { '[attr.id]': 'uid' }, template: "<ion-modal\n [id]=\"uid\"\n [isOpen]=\"isOpen\"\n (willDismiss)=\"handleWillDismiss($event)\"\n [backdropDismiss]=\"options?.backdropDismiss\"\n [showBackdrop]=\"options?.showBackdrop\"\n [animated]=\"options?.animated\"\n [canDismiss]=\"options?.canDismiss\"\n [class.dcf-fullscreen-modal]=\"fullscreen\"\n [class.dcf-lightbox-modal]=\"lightBox\"\n class=\"dcf-modal-component\"\n #component\n>\n <ng-template>\n <ion-header [transparent]=\"lightBox\">\n <ion-toolbar>\n @if (title) {\n <ion-title>{{ title | translate }}</ion-title>\n }\n <ion-buttons slot=\"end\">\n <ion-button size=\"small\" type=\"button\" class=\"dcf-button-close\" (click)=\"cancel()\">\n <ion-icon name=\"close-outline\" aria-hidden=\"true\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n\n <ion-content>\n <section class=\"dcf-modal-body\">\n @if (!tag && !model && !inlineContent) {\n <div class=\"dcf-loading-container\">\n <ion-spinner name=\"crescent\" color=\"primary\"></ion-spinner>\n </div>\n } @else {\n @if (inlineContent && inlineContentPosition === \"top\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n @if (model) {\n <ngx-decaf-model-renderer\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"globals\"\n />\n }\n @if(tag && globals) {\n <ngx-decaf-component-renderer\n [tag]=\"tag\"\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"{props: globals}\"\n />\n }\n @if (inlineContent && inlineContentPosition === \"bottom\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n }\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n", styles: [".dcf-modal-component.dcf-fullscreen-modal{--height: 100%;--width: 100%;--max-width: 100%;--border-radius: 0}.dcf-modal-component.dcf-fullscreen-modal.dcf-lightbox-modal{padding:var(--dcf-padding-small)}.dcf-modal-component.dcf-lightbox-modal{--background: transparent;--box-shadow: none !important}@media (max-width: 767px){.dcf-modal-component.dcf-lightbox-modal{padding:var(--dcf-padding-xsmall)}.dcf-modal-component.dcf-lightbox-modal ion-button{transform:translate(2px,2px)!important}}.dcf-modal-component.dcf-lightbox-modal ion-header{--background: transparent !important;background-color:transparent;box-shadow:none!important;padding:unset!important;margin:unset!important;height:30px}.dcf-modal-component.dcf-lightbox-modal ion-header ion-button{margin:0!important;width:32px!important;height:25px!important;--background: var(--dcf-color-light) !important;transform:translate(2px);--border-radius: var(--dcf-border-radius-small) !important}.dcf-modal-component.dcf-lightbox-modal ion-header ion-button *{margin:-5px}.dcf-modal-component.dcf-lightbox-modal ion-header ion-toolbar{--background: transparent !important;padding:unset!important;margin:unset!important}.dcf-modal-component.dcf-lightbox-modal ion-content{--background: transparent !important}.dcf-modal-component.dcf-lightbox-modal .dcf-modal-body{display:flex;height:auto;justify-content:center;align-items:center;background:#fff!important}.dcf-modal-component:not(.dcf-lightbox-modal) .dcf-modal-body{height:100%;padding:1.5rem 1rem}.dcf-modal-component .dcf-loading-container{height:50%;display:flex;justify-content:center;align-items:center}.dcf-modal-component .dcf-loading-container ion-spinner{width:60px;height:60px}\n"] }]
|
|
5239
|
+
}], ctorParameters: () => [], propDecorators: { modal: [{
|
|
5240
|
+
type: ViewChild,
|
|
5241
|
+
args: ['component']
|
|
5242
|
+
}], title: [{
|
|
5243
|
+
type: Input
|
|
5244
|
+
}], isOpen: [{
|
|
5245
|
+
type: Input
|
|
5246
|
+
}], tag: [{
|
|
5247
|
+
type: Input
|
|
5248
|
+
}], options: [{
|
|
5249
|
+
type: Input
|
|
5250
|
+
}], globals: [{
|
|
5251
|
+
type: Input
|
|
5252
|
+
}], inlineContent: [{
|
|
5253
|
+
type: Input
|
|
5254
|
+
}], inlineContentPosition: [{
|
|
5255
|
+
type: Input
|
|
5256
|
+
}], fullscreen: [{
|
|
5257
|
+
type: Input
|
|
5258
|
+
}], lightBox: [{
|
|
5259
|
+
type: Input
|
|
5260
|
+
}], willDismissEvent: [{
|
|
5261
|
+
type: Output
|
|
5262
|
+
}] } });
|
|
5263
|
+
/**
|
|
5264
|
+
* @description Retrieves a modal component instance.
|
|
5265
|
+
* @summary Creates and initializes a modal component with the provided properties and options.
|
|
5266
|
+
*
|
|
5267
|
+
* @param {Partial<ModalComponent>} [props={}] - Properties to initialize the modal component.
|
|
5268
|
+
* @param {Partial<ModalOptions>} [modalProps={}] - Additional modal options.
|
|
5269
|
+
* @param {EnvironmentInjector} [injector] - Optional environment injector for dependency injection.
|
|
5270
|
+
* @returns {Promise<IonModal>} - A promise that resolves with the modal instance.
|
|
5271
|
+
*/
|
|
5272
|
+
async function getNgxModalComponent(props = {}, modalProps = {}, injector) {
|
|
5273
|
+
const { globals } = { ...props };
|
|
5274
|
+
if (!globals || !globals?.['operation']) {
|
|
5275
|
+
props.globals = { ...(globals || {}), operation: OperationKeys.CREATE };
|
|
5276
|
+
}
|
|
5277
|
+
const component = await NgxRenderingEngine.createComponent(ModalComponent, props, injector || undefined).create(modalProps);
|
|
5278
|
+
return component.modal;
|
|
5279
|
+
}
|
|
5280
|
+
/**
|
|
5281
|
+
* @description Presents a lightbox modal with inline content.
|
|
5282
|
+
* @summary Displays a modal in lightbox mode with the specified content and properties.
|
|
5283
|
+
*
|
|
5284
|
+
* @param {string | SafeHtml} inlineContent - The content to display in the lightbox modal.
|
|
5285
|
+
* @param {Partial<ModalComponent>} [props={}] - Properties to initialize the modal component.
|
|
5286
|
+
* @param {EnvironmentInjector} [injector] - Optional environment injector for dependency injection.
|
|
5287
|
+
* @returns {Promise<void>} - A promise that resolves when the modal is presented.
|
|
5288
|
+
*/
|
|
5289
|
+
async function presentNgxLightBoxModal(inlineContent, props = {}, injector) {
|
|
5290
|
+
return (await getNgxModalComponent({ props, ...{ inlineContent, lightBox: true } }, {}, injector || undefined)).present();
|
|
5291
|
+
}
|
|
5292
|
+
/**
|
|
5293
|
+
* @description Retrieves a modal for selecting options.
|
|
5294
|
+
* @summary Creates and initializes a modal component for displaying a list of selectable options.
|
|
5295
|
+
*
|
|
5296
|
+
* @param {SelectOption[]} options - The list of options to display in the modal.
|
|
5297
|
+
* @param {EnvironmentInjector} [injector] - Optional environment injector for dependency injection.
|
|
5298
|
+
* @returns {Promise<IonModal>} - A promise that resolves with the modal instance.
|
|
5299
|
+
*/
|
|
5300
|
+
async function getNgxSelectOptionsModal(options, injector) {
|
|
5301
|
+
const props = {
|
|
5302
|
+
tag: 'ngx-decaf-list',
|
|
5303
|
+
globals: {
|
|
5304
|
+
data: options,
|
|
5305
|
+
item: { tag: true },
|
|
5306
|
+
pk: 'value',
|
|
5307
|
+
mapper: { title: 'text', uid: 'value' },
|
|
5308
|
+
},
|
|
5309
|
+
};
|
|
5310
|
+
return (await getNgxModalComponent(props, {}, injector || undefined));
|
|
5311
|
+
}
|
|
5312
|
+
|
|
5313
|
+
/**
|
|
5314
|
+
* @description A dynamic form field component for CRUD operations.
|
|
5315
|
+
* @summary The CrudFieldComponent is a versatile form field component that adapts to different
|
|
5316
|
+
* input types and CRUD operations. It extends NgxFormFieldDirective to inherit form handling capabilities
|
|
5317
|
+
* and implements lifecycle hooks to properly initialize, render, and clean up. This component
|
|
5318
|
+
* supports various input types (text, number, date, select, etc.), validation rules, and styling
|
|
5319
|
+
* options, making it suitable for building dynamic forms for create, read, update, and delete
|
|
5320
|
+
* operations.
|
|
5321
|
+
*
|
|
5322
|
+
* @param {CrudOperations} operation - The CRUD operation being performed (create, read, update, delete)
|
|
5323
|
+
* @param {string} name - The field name, used as form control identifier
|
|
5324
|
+
* @param {PossibleInputTypes} type - The input type (text, number, date, select, etc.)
|
|
5325
|
+
* @param {string|number|Date} value - The initial value of the field
|
|
5326
|
+
* @param {boolean} disabled - Whether the field is disabled
|
|
5327
|
+
* @param {string} label - The display label for the field
|
|
5328
|
+
* @param {string} placeholder - Placeholder text when field is empty
|
|
5329
|
+
* @param {string} format - Format pattern for the field value
|
|
5330
|
+
* @param {boolean} hidden - Whether the field should be hidden
|
|
5331
|
+
* @param {number|Date} max - Maximum allowed value
|
|
5332
|
+
* @param {number} maxlength - Maximum allowed length
|
|
5333
|
+
* @param {number|Date} min - Minimum allowed value
|
|
5334
|
+
* @param {number} minlength - Minimum allowed length
|
|
5335
|
+
* @param {string} pattern - Validation pattern
|
|
5336
|
+
* @param {boolean} readonly - Whether the field is read-only
|
|
5337
|
+
* @param {boolean} required - Whether the field is required
|
|
5338
|
+
* @param {number} step - Step value for number inputs
|
|
5339
|
+
* @param {FormGroup} formGroup - The parent form group
|
|
5340
|
+
* @param {StringOrBoolean} translatable - Whether field labels should be translated
|
|
5341
|
+
*
|
|
5342
|
+
* @component CrudFieldComponent
|
|
5343
|
+
* @example
|
|
5344
|
+
* <ngx-decaf-crud-field
|
|
5345
|
+
* operation="create"
|
|
5346
|
+
* name="firstName"
|
|
5347
|
+
* type="text"
|
|
5348
|
+
* label="<NAME>"
|
|
5349
|
+
* placeholder="<NAME>"
|
|
5350
|
+
* [value]="model.firstName"
|
|
5351
|
+
* [disabled]="model.readOnly">
|
|
5352
|
+
*
|
|
5353
|
+
*
|
|
5354
|
+
* @memberOf module:for-angular
|
|
5355
|
+
*/
|
|
5356
|
+
let CrudFieldComponent = class CrudFieldComponent extends NgxFormFieldDirective {
|
|
5357
|
+
constructor() {
|
|
5358
|
+
super(...arguments);
|
|
5359
|
+
this.className = 'dcf-width-1-1';
|
|
5360
|
+
/**
|
|
5361
|
+
* @description The parent field path, if this field is nested.
|
|
5362
|
+
* @summary Specifies the full dot-delimited path of the parent field. This is only set when the field is nested.
|
|
5363
|
+
*
|
|
5364
|
+
* @type {string}
|
|
5365
|
+
* @memberOf CrudFieldComponent
|
|
5366
|
+
*/
|
|
5367
|
+
/**
|
|
5368
|
+
* @description The parent field path for nested field structures.
|
|
5369
|
+
* @summary Specifies the full dot-delimited path of the parent field when this field
|
|
5370
|
+
* is part of a nested structure. This is used for hierarchical form organization
|
|
5371
|
+
* and proper form control resolution in complex form structures.
|
|
5372
|
+
*
|
|
5373
|
+
* @type {string}
|
|
5374
|
+
* @default ''
|
|
5375
|
+
* @memberOf CrudFieldComponent
|
|
5376
|
+
*/
|
|
5377
|
+
this.childOf = '';
|
|
5378
|
+
/**
|
|
5379
|
+
* @description The initial value of the field.
|
|
5380
|
+
* @summary Sets the initial value of the form field. This can be a string, number, or Date
|
|
5381
|
+
* depending on the field type. For select fields, this should match one of the option values.
|
|
5382
|
+
*
|
|
5383
|
+
* @type {string | number | Date}
|
|
5384
|
+
* @default ''
|
|
5385
|
+
* @memberOf CrudFieldComponent
|
|
5386
|
+
*/
|
|
5387
|
+
this.value = '';
|
|
5388
|
+
/**
|
|
5389
|
+
* @description Whether the field should be hidden.
|
|
5390
|
+
* @summary When true, the field will not be visible in the UI but will still be part of the form model.
|
|
5391
|
+
* This is useful for fields that need to be included in form submission but should not be displayed to the user.
|
|
5392
|
+
*
|
|
5393
|
+
* @type {boolean}
|
|
5394
|
+
* @memberOf CrudFieldComponent
|
|
5395
|
+
*/
|
|
5396
|
+
this.hidden = false;
|
|
5397
|
+
/**
|
|
5398
|
+
* @description Interface style for select inputs.
|
|
5399
|
+
* @summary Specifies the interface style for select inputs, such as 'alert', 'action-sheet', or 'popover'.
|
|
5400
|
+
* This determines how the select options are presented to the user.
|
|
5401
|
+
*
|
|
5402
|
+
* @type {SelectInterface}
|
|
5403
|
+
* @memberOf CrudFieldComponent
|
|
5404
|
+
*/
|
|
5405
|
+
this.interface = 'popover';
|
|
5406
|
+
/**
|
|
5407
|
+
* @description Spellcheck attribute for text inputs.
|
|
5408
|
+
* @summary Enables or disables spellchecking for text inputs.
|
|
5409
|
+
* When true, the browser will check the spelling of the input text.
|
|
5410
|
+
*
|
|
5411
|
+
* @type {boolean}
|
|
4777
5412
|
* @default false
|
|
4778
5413
|
* @memberOf CrudFieldComponent
|
|
4779
5414
|
*/
|
|
@@ -4869,7 +5504,6 @@ let CrudFieldComponent = class CrudFieldComponent extends NgxFormFieldDirective
|
|
|
4869
5504
|
* @memberOf CrudFieldComponent
|
|
4870
5505
|
*/
|
|
4871
5506
|
async ngOnInit() {
|
|
4872
|
-
console.log(this.enableDarkMode, this.operation, this.name);
|
|
4873
5507
|
this.options = await this.getOptions();
|
|
4874
5508
|
addIcons({ chevronDownOutline, chevronUpOutline });
|
|
4875
5509
|
if (Array.isArray(this.hidden) && !this.hidden.includes(this.operation)) {
|
|
@@ -4947,6 +5581,16 @@ let CrudFieldComponent = class CrudFieldComponent extends NgxFormFieldDirective
|
|
|
4947
5581
|
this.interface = 'modal';
|
|
4948
5582
|
return this.options;
|
|
4949
5583
|
}
|
|
5584
|
+
async openSelectOptions(event, selectInterface) {
|
|
5585
|
+
if (selectInterface === 'modal') {
|
|
5586
|
+
event.preventDefault();
|
|
5587
|
+
event.stopImmediatePropagation();
|
|
5588
|
+
const modal = await getNgxSelectOptionsModal(this.options);
|
|
5589
|
+
const { data, role } = await modal.onWillDismiss();
|
|
5590
|
+
if (role === ActionRoles.confirm && data !== this.value)
|
|
5591
|
+
this.setValue(data);
|
|
5592
|
+
}
|
|
5593
|
+
}
|
|
4950
5594
|
/**
|
|
4951
5595
|
* @description Component after view initialization lifecycle method.
|
|
4952
5596
|
* @summary Calls the parent afterViewInit method for READ and DELETE operations.
|
|
@@ -5011,7 +5655,7 @@ let CrudFieldComponent = class CrudFieldComponent extends NgxFormFieldDirective
|
|
|
5011
5655
|
this.value = this.formControl.value;
|
|
5012
5656
|
}
|
|
5013
5657
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CrudFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
5014
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: CrudFieldComponent, isStandalone: true, selector: "ngx-decaf-crud-field", inputs: { operation: "operation", name: "name", className: "className", path: "path", childOf: "childOf", type: "type", value: "value", disabled: "disabled", label: "label", placeholder: "placeholder", format: "format", hidden: "hidden", max: "max", maxlength: "maxlength", min: "min", minlength: "minlength", pattern: "pattern", readonly: "readonly", required: "required", step: "step", equals: "equals", different: "different", lessThan: "lessThan", lessThanOrEqual: "lessThanOrEqual", greaterThan: "greaterThan", greaterThanOrEqual: "greaterThanOrEqual", alignment: "alignment", checked: "checked", justify: "justify", cancelText: "cancelText", interface: "interface", options: "options", mode: "mode", spellcheck: "spellcheck", inputmode: "inputmode", autocomplete: "autocomplete", fill: "fill", labelPlacement: "labelPlacement", updateOn: "updateOn", formGroup: "formGroup", formControl: "formControl", multiple: "multiple", uid: "uid", page: "page", translatable: "translatable" }, host: { listeners: { "window:fieldsetUpdateGroupEvent": "handleFieldsetUpdateGroupEvent($event)" }, properties: { "attr.id": "uid", "attr.class": "className" } }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef }], usesInheritance: true, ngImport: i0, template: "@if (operation === 'read' || operation === 'delete') {\n <ng-container>\n <div>\n <ion-item [class]=\"'dcf-input-item ' + operation\" #component>\n <ion-label>\n {{ label | translate }}<br />\n @if (value) {\n <ion-text [innerHTML]=\"type === 'password' ? '********' : value\"></ion-text>\n } @else {\n @if (['checkbox'].includes(type)) {\n <ion-icon class=\"dcf-margin-small-top\" [color]=\"!isDarkMode ? 'primary' : 'light'\" size=\"large\" name=\"checkmark-circle-outline\"></ion-icon>\n } @else {\n <br />\n }\n }\n </ion-label>\n </ion-item>\n </div>\n </ng-container>\n} @else {\n @if (formControl) {\n <ng-container [formGroup]=\"multiple ? activeFormGroup : formControl.parent\">\n <div\n\n [id]=\"uid\" #container\n [class]=\"'dcf-input-item ' + (operation || 'create')\"\n (createGroupEvent)=\"multiple ? handleFieldsetCreateGroupEvent($event) : ''\"\n [class.dcf-field-required]=\"required\"\n >\n @if (type === 'textarea') {\n <ion-textarea\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [autoGrow]=\"true\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [inputmode]=\"inputmode\"\n [spellcheck]=\"spellcheck\"\n [rows]=\"rows\"\n [labelPlacement]=\"labelPlacement\"\n [value]=\"value\"\n [fill]=\"fill\"\n [errorText]=\"getErrors(container)\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [label]=\"label | translate\"\n #component>\n </ion-textarea>\n }\n @else if (type === 'checkbox') {\n @if (!options?.length) {\n <ion-item class=\"dcf-width-1-1\" [hidden]=\"hidden\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [errorText]=\"getErrors(container)\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify || 'start'\"\n [value]=\"value\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\"\n #component>\n <span>{{label | translate}}</span>\n </ion-checkbox>\n\n </ion-item>\n } @else {\n <div class=\"dcf-checkbox-group\">\n <label class=\"dcf-label\" [for]=\"path\">{{ label | translate }}</label>\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-item class=\"dcf-width-1-1\" [button]=\"true\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"option.text\"\n [mode]=\"'md'\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [value]=\"option.value\"\n [readonly]=\"readonly\"\n [checked]=\"isOptionChecked(option.value)\"\n (ionChange)=\"toggleOptionSelection(option.value, $event)\"\n #component>\n <span>{{ $index + 1 }}. {{ option?.text | translate }}</span>\n </ion-checkbox>\n </ion-item>\n }\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n }\n\n }\n @else if (type === 'radio' && options?.length) {\n <ion-radio-group class=\"dcf-width-1-1\" [formControlName]=\"name\" [value]=\"value\" #component>\n <label class=\"dcf-radio-group-label\" [for]=\"path\">{{label | translate}}</label>\n @for(option of options; track $index) {\n <ion-item>\n <ion-radio\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [errorText]=\"getErrors(container)\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [readonly]=\"readonly\"\n [value]=\"option.value\"\n >{{ option?.text | translate }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if (type === 'select') {\n <div>\n <ion-select\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [interface]=\"interface\"\n [mode]=\"'md'\"\n [hidden]=\"hidden || !options?.length\"\n [labelPlacement]=\"labelPlacement\"\n [label]=\"label | translate\"\n [value]=\"value\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [interface]=\"interface\" #component>\n @if (options?.length) {\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-select-option [value]=\"option.value\">\n {{ option.text | translate }}\n </ion-select-option>\n }\n }\n </ion-select>\n <div class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></div>\n @if (!options?.length) {\n <ion-text color=\"danger\">\n * {{ 'errors.empty_options' | translate:{'0': name} }}\n </ion-text>\n }\n </div>\n }\n @else {\n <ion-input\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [type]=\"type\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [labelPlacement]=\"labelPlacement\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [max]=\"max !== undefined ? max : null\"\n [min]=\"min !== undefined ? min : null\"\n [pattern]=\"pattern !== undefined ? pattern : null\"\n [step]=\"step !== undefined ? step : null\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [label]=\"label | translate\" #component />\n }\n </div>\n </ng-container>\n } @else {\n <div>\n <p class=\"dcf-error\">\n {{ 'errors.form.control' | translate:{'0': name} }}\n </p>\n </div>\n }\n\n}\n\n", styles: ["ion-item{--border-color: transparent}ion-item:not(.dcf-input-item){--inner-padding-start: 0rem;--padding-start: 0rem}ion-item.dcf-input-item{--padding-end: 0rem;--padding-start: 0px !important;--padding-top: 0px !important;--inner-padding-start: .75rem;--background: transparent;--background-hover-opacity: .1;--background-activated-opacity: .15;--background-focused-opacity: .15;--background-hover: var(--dcf-color-primary);--background-focused: var(--dcf-color-primary);--border-color: var(--dcf-color-gray-2)}ion-item.dcf-input-item.dcf-palette-dark{--border-color: var(--dcf-color-gray-6) !important}ion-item.dcf-input-item.read,ion-item.dcf-input-item.delete{--min-height: 30px;padding:unset;margin:unset!important;margin-bottom:var(--dcf-margin-xsmall)!important}ion-item.dcf-input-item.read ion-label,ion-item.dcf-input-item.delete ion-label{font-weight:600;margin-top:0!important;margin-bottom:.25rem!important;font-size:.925rem}ion-item.dcf-input-item.read ion-label:not(:first-of-type),ion-item.dcf-input-item.delete ion-label:not(:first-of-type){margin:100rem}ion-item.dcf-input-item.read span,ion-item.dcf-input-item.read ion-text,ion-item.dcf-input-item.delete span,ion-item.dcf-input-item.delete ion-text{font-weight:400!important;font-size:.825rem;min-height:.5rem!important}ion-item.dcf-input-item.read span:not(.dcf-display-block),ion-item.dcf-input-item.read ion-text:not(.dcf-display-block),ion-item.dcf-input-item.delete span:not(.dcf-display-block),ion-item.dcf-input-item.delete ion-text:not(.dcf-display-block){display:inline-block}ion-item.dcf-input-item.read span.dcf-display-block,ion-item.dcf-input-item.read ion-text.dcf-display-block,ion-item.dcf-input-item.delete span.dcf-display-block,ion-item.dcf-input-item.delete ion-text.dcf-display-block{display:block!important}ion-item.dcf-input-item>*,ion-item.dcf-input-item ion-select{width:100%!important}ion-item.dcf-input-item.create.checkbox+.checkbox,ion-item.dcf-input-item.update.checkbox+.checkbox{margin-top:-.25rem!important}ion-item.dcf-input-item.create ion-item,ion-item.dcf-input-item.update ion-item{--border-color: transparent}ion-item.dcf-input-item.create ion-item.dcf-text-wrap ion-label>*,ion-item.dcf-input-item.update ion-item.dcf-text-wrap ion-label>*{white-space:wrap!important;word-break:break-all!important}ion-textarea textarea{scrollbar-width:thin!important;margin-bottom:.5rem!important}ion-select.dcf-select-label-placement-floating::part(label){line-height:1.2rem!important}.dcf-proccessing,.dcf-proccessing *{pointer-events:none;touch-action:none;cursor:text}ion-checkbox::part(container){border:2px solid var(--dcf-color-primary);margin-left:.5rem;margin-right:.5rem;border-radius:var(--dcf-border-radius-small);padding:3px}ion-checkbox{--size: 1.5rem;--checkbox-background-checked: var(--dcf-color-primary);--checkmark-width: 2px}ion-radio-group .dcf-radio-group-label{font-weight:600}ion-radio-group .dcf-radio-group-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}ion-radio-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-checkbox-group{width:100%}.dcf-checkbox-group .dcf-label{font-weight:600}.dcf-checkbox-group .dcf-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}.dcf-checkbox-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-error{position:absolute;color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:500!important;line-height:1.1rem;z-index:9999}.dcf-error .ti,.dcf-error ion-icon{position:relative;top:2px!important;min-width:20px;font-size:1rem!important;text-align:left}.dcf-helper{font-size:.875rem!important;font-weight:500;margin-top:.25rem;margin-bottom:-.75rem}.dcf-helper.dcf-has-action{cursor:pointer;text-decoration:underline}.dcf-error+.dcf-helper{padding-top:1rem}::ng-deep ion-textarea{min-height:80px!important;scrollbar-color:#888 #f0f0f0;scrollbar-width:thin}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "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", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCheckbox, selector: "ion-checkbox", inputs: ["checked", "color", "disabled", "errorText", "helperText", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonRadioGroup, selector: "ion-radio-group", inputs: ["allowEmptySelection", "compareWith", "errorText", "helperText", "name", "value"] }, { kind: "component", type: IonRadio, selector: "ion-radio", inputs: ["alignment", "color", "disabled", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "errorText", "expandedIcon", "fill", "helperText", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: IonTextarea, selector: "ion-textarea", inputs: ["autoGrow", "autocapitalize", "autofocus", "clearOnEdit", "color", "cols", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "maxlength", "minlength", "mode", "name", "placeholder", "readonly", "required", "rows", "shape", "spellcheck", "value", "wrap"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
5658
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: CrudFieldComponent, isStandalone: true, selector: "ngx-decaf-crud-field", inputs: { operation: "operation", name: "name", className: "className", path: "path", childOf: "childOf", type: "type", value: "value", disabled: "disabled", label: "label", placeholder: "placeholder", format: "format", hidden: "hidden", max: "max", maxlength: "maxlength", min: "min", minlength: "minlength", pattern: "pattern", readonly: "readonly", required: "required", step: "step", equals: "equals", different: "different", lessThan: "lessThan", lessThanOrEqual: "lessThanOrEqual", greaterThan: "greaterThan", greaterThanOrEqual: "greaterThanOrEqual", alignment: "alignment", checked: "checked", justify: "justify", cancelText: "cancelText", interface: "interface", options: "options", mode: "mode", spellcheck: "spellcheck", inputmode: "inputmode", autocomplete: "autocomplete", fill: "fill", labelPlacement: "labelPlacement", updateOn: "updateOn", formGroup: "formGroup", formControl: "formControl", multiple: "multiple", uid: "uid", page: "page", translatable: "translatable" }, host: { listeners: { "window:fieldsetUpdateGroupEvent": "handleFieldsetUpdateGroupEvent($event)" }, properties: { "attr.id": "uid", "attr.class": "className" } }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef }], usesInheritance: true, ngImport: i0, template: "@if (operation === 'read' || operation === 'delete') {\n <ng-container>\n <div>\n <ion-item [class]=\"'dcf-input-item ' + operation\" #component>\n <ion-label>\n {{ label | translate }}<br />\n @if (value) {\n <ion-text [innerHTML]=\"type === 'password' ? '********' : value\"></ion-text>\n } @else {\n @if (['checkbox'].includes(type)) {\n <ion-icon aria-hidden=\"true\" class=\"dcf-margin-small-top\" [color]=\"!isDarkMode ? 'primary' : 'light'\" size=\"large\" name=\"checkmark-circle-outline\"></ion-icon>\n } @else {\n <br />\n }\n }\n </ion-label>\n </ion-item>\n </div>\n </ng-container>\n} @else {\n @if (formControl) {\n <ng-container [formGroup]=\"multiple ? activeFormGroup : formControl.parent\">\n <div\n\n [id]=\"uid\" #container\n [class]=\"'dcf-input-item ' + (operation || 'create')\"\n [class.dcf-field-required]=\"required\"\n >\n @if (type === 'textarea') {\n <ion-textarea\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [autoGrow]=\"true\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [inputmode]=\"inputmode\"\n [spellcheck]=\"spellcheck\"\n [rows]=\"rows\"\n [labelPlacement]=\"labelPlacement\"\n [value]=\"value\"\n [fill]=\"fill\"\n [errorText]=\"getErrors(container)\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [label]=\"label | translate\"\n #component>\n </ion-textarea>\n }\n @else if (type === 'checkbox') {\n @if (!options?.length) {\n <ion-item class=\"dcf-width-1-1\" [hidden]=\"hidden\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [errorText]=\"getErrors(container)\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify || 'start'\"\n [value]=\"value\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\"\n #component>\n <span>{{label | translate}}</span>\n </ion-checkbox>\n\n </ion-item>\n } @else {\n <div class=\"dcf-checkbox-group\">\n <label class=\"dcf-label\" [for]=\"path\">{{ label | translate }}</label>\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-item class=\"dcf-width-1-1\" [button]=\"true\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"option.text\"\n [mode]=\"'md'\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [value]=\"option.value\"\n [readonly]=\"readonly\"\n [checked]=\"isOptionChecked(option.value)\"\n (ionChange)=\"toggleOptionSelection(option.value, $event)\"\n #component>\n <span>{{ $index + 1 }}. {{ option?.text | translate }}</span>\n </ion-checkbox>\n </ion-item>\n }\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n }\n\n }\n @else if (type === 'radio' && options?.length) {\n <ion-radio-group class=\"dcf-width-1-1\" [formControlName]=\"name\" [value]=\"value\" #component>\n <label class=\"dcf-radio-group-label\" [for]=\"path\">{{label | translate}}</label>\n @for(option of options; track $index) {\n <ion-item>\n <ion-radio\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [errorText]=\"getErrors(container)\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [readonly]=\"readonly\"\n [value]=\"option.value\"\n >{{ option?.text | translate }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if (type === 'select') {\n <div>\n <ion-select\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [interface]=\"interface\"\n [mode]=\"'md'\"\n [hidden]=\"hidden || !options?.length\"\n [labelPlacement]=\"labelPlacement\"\n [label]=\"label | translate\"\n [value]=\"value\"\n (click)=\"openSelectOptions($event, interface)\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [interface]=\"interface\" #component>\n @if (options?.length) {\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-select-option [value]=\"option.value\">\n {{ option.text | translate }}\n </ion-select-option>\n }\n }\n </ion-select>\n <div class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></div>\n @if (!options?.length) {\n <ion-text color=\"danger\">\n * {{ 'errors.empty_options' | translate:{'0': name} }}\n </ion-text>\n }\n </div>\n }\n @else {\n <ion-input\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [type]=\"type\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [labelPlacement]=\"labelPlacement\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [max]=\"max !== undefined ? max : null\"\n [min]=\"min !== undefined ? min : null\"\n [pattern]=\"pattern !== undefined ? pattern : null\"\n [step]=\"step !== undefined ? step : null\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [label]=\"label | translate\" #component />\n }\n </div>\n </ng-container>\n } @else {\n <div>\n <p class=\"dcf-error\">\n {{ 'errors.form.control' | translate:{'0': name} }}\n </p>\n </div>\n }\n\n}\n\n", styles: ["ion-item{--border-color: transparent}ion-item:not(.dcf-input-item){--inner-padding-start: 0rem;--padding-start: 0rem;--background: transparent}ion-item.dcf-input-item{--padding-end: 0rem;--padding-start: 0px !important;--padding-top: 0px !important;--inner-padding-start: .75rem;--background: transparent;--background-hover-opacity: .1;--background-activated-opacity: .15;--background-focused-opacity: .15;--background-hover: var(--dcf-color-primary);--background-focused: var(--dcf-color-primary);--border-color: var(--dcf-color-gray-2)}ion-item.dcf-input-item.dcf-palette-dark{--border-color: var(--dcf-color-gray-6) !important}ion-item.dcf-input-item.read,ion-item.dcf-input-item.delete{--min-height: 30px;padding:unset;margin:unset!important;margin-bottom:var(--dcf-margin-xsmall)!important}ion-item.dcf-input-item.read ion-label,ion-item.dcf-input-item.delete ion-label{font-weight:600;margin-top:0!important;margin-bottom:.25rem!important;font-size:.925rem}ion-item.dcf-input-item.read ion-label:not(:first-of-type),ion-item.dcf-input-item.delete ion-label:not(:first-of-type){margin:100rem}ion-item.dcf-input-item.read span,ion-item.dcf-input-item.read ion-text,ion-item.dcf-input-item.delete span,ion-item.dcf-input-item.delete ion-text{font-weight:400!important;font-size:.825rem;min-height:.5rem!important}ion-item.dcf-input-item.read span:not(.dcf-display-block),ion-item.dcf-input-item.read ion-text:not(.dcf-display-block),ion-item.dcf-input-item.delete span:not(.dcf-display-block),ion-item.dcf-input-item.delete ion-text:not(.dcf-display-block){display:inline-block}ion-item.dcf-input-item.read span.dcf-display-block,ion-item.dcf-input-item.read ion-text.dcf-display-block,ion-item.dcf-input-item.delete span.dcf-display-block,ion-item.dcf-input-item.delete ion-text.dcf-display-block{display:block!important}ion-item.dcf-input-item>*,ion-item.dcf-input-item ion-select{width:100%!important}ion-item.dcf-input-item.create.checkbox+.checkbox,ion-item.dcf-input-item.update.checkbox+.checkbox{margin-top:-.25rem!important}ion-item.dcf-input-item.create ion-item,ion-item.dcf-input-item.update ion-item{--border-color: transparent}ion-item.dcf-input-item.create ion-item.dcf-text-wrap ion-label>*,ion-item.dcf-input-item.update ion-item.dcf-text-wrap ion-label>*{white-space:wrap!important;word-break:break-all!important}ion-textarea textarea{scrollbar-width:thin!important;margin-bottom:.5rem!important}ion-select.dcf-select-label-placement-floating::part(label){line-height:1.2rem!important}.dcf-proccessing,.dcf-proccessing *{pointer-events:none;touch-action:none;cursor:text}ion-checkbox::part(container){border:2px solid var(--dcf-color-primary);margin-left:.5rem;margin-right:.5rem;border-radius:var(--dcf-border-radius-small);padding:3px}ion-checkbox{--size: 1.5rem;--checkbox-background-checked: var(--dcf-color-primary);--checkmark-width: 2px}ion-radio-group .dcf-radio-group-label{font-weight:600}ion-radio-group .dcf-radio-group-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}ion-radio-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-checkbox-group{width:100%}.dcf-checkbox-group .dcf-label{font-weight:600}.dcf-checkbox-group .dcf-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}.dcf-checkbox-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-error{position:absolute;color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:500!important;line-height:1.1rem;z-index:9999}.dcf-error .ti,.dcf-error ion-icon{position:relative;top:2px!important;min-width:20px;font-size:1rem!important;text-align:left}.dcf-helper{font-size:.875rem!important;font-weight:500;margin-top:.25rem;margin-bottom:-.75rem}.dcf-helper.dcf-has-action{cursor:pointer;text-decoration:underline}.dcf-error+.dcf-helper{padding-top:1rem}::ng-deep ion-textarea{min-height:80px!important;scrollbar-color:#888 #f0f0f0;scrollbar-width:thin}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "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", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCheckbox, selector: "ion-checkbox", inputs: ["checked", "color", "disabled", "errorText", "helperText", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonRadioGroup, selector: "ion-radio-group", inputs: ["allowEmptySelection", "compareWith", "errorText", "helperText", "name", "value"] }, { kind: "component", type: IonRadio, selector: "ion-radio", inputs: ["alignment", "color", "disabled", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "errorText", "expandedIcon", "fill", "helperText", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: IonTextarea, selector: "ion-textarea", inputs: ["autoGrow", "autocapitalize", "autofocus", "clearOnEdit", "color", "cols", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "maxlength", "minlength", "mode", "name", "placeholder", "readonly", "required", "rows", "shape", "spellcheck", "value", "wrap"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
5015
5659
|
};
|
|
5016
5660
|
CrudFieldComponent = __decorate([
|
|
5017
5661
|
Dynamic()
|
|
@@ -5031,7 +5675,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
|
|
|
5031
5675
|
IonLabel,
|
|
5032
5676
|
IonText,
|
|
5033
5677
|
IonTextarea
|
|
5034
|
-
], selector: 'ngx-decaf-crud-field', schemas: [CUSTOM_ELEMENTS_SCHEMA], host: { '[attr.id]': 'uid', '[attr.class]': 'className' }, template: "@if (operation === 'read' || operation === 'delete') {\n <ng-container>\n <div>\n <ion-item [class]=\"'dcf-input-item ' + operation\" #component>\n <ion-label>\n {{ label | translate }}<br />\n @if (value) {\n <ion-text [innerHTML]=\"type === 'password' ? '********' : value\"></ion-text>\n } @else {\n @if (['checkbox'].includes(type)) {\n <ion-icon class=\"dcf-margin-small-top\" [color]=\"!isDarkMode ? 'primary' : 'light'\" size=\"large\" name=\"checkmark-circle-outline\"></ion-icon>\n } @else {\n <br />\n }\n }\n </ion-label>\n </ion-item>\n </div>\n </ng-container>\n} @else {\n @if (formControl) {\n <ng-container [formGroup]=\"multiple ? activeFormGroup : formControl.parent\">\n <div\n\n [id]=\"uid\" #container\n [class]=\"'dcf-input-item ' + (operation || 'create')\"\n (createGroupEvent)=\"multiple ? handleFieldsetCreateGroupEvent($event) : ''\"\n [class.dcf-field-required]=\"required\"\n >\n @if (type === 'textarea') {\n <ion-textarea\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [autoGrow]=\"true\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [inputmode]=\"inputmode\"\n [spellcheck]=\"spellcheck\"\n [rows]=\"rows\"\n [labelPlacement]=\"labelPlacement\"\n [value]=\"value\"\n [fill]=\"fill\"\n [errorText]=\"getErrors(container)\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [label]=\"label | translate\"\n #component>\n </ion-textarea>\n }\n @else if (type === 'checkbox') {\n @if (!options?.length) {\n <ion-item class=\"dcf-width-1-1\" [hidden]=\"hidden\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [errorText]=\"getErrors(container)\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify || 'start'\"\n [value]=\"value\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\"\n #component>\n <span>{{label | translate}}</span>\n </ion-checkbox>\n\n </ion-item>\n } @else {\n <div class=\"dcf-checkbox-group\">\n <label class=\"dcf-label\" [for]=\"path\">{{ label | translate }}</label>\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-item class=\"dcf-width-1-1\" [button]=\"true\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"option.text\"\n [mode]=\"'md'\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [value]=\"option.value\"\n [readonly]=\"readonly\"\n [checked]=\"isOptionChecked(option.value)\"\n (ionChange)=\"toggleOptionSelection(option.value, $event)\"\n #component>\n <span>{{ $index + 1 }}. {{ option?.text | translate }}</span>\n </ion-checkbox>\n </ion-item>\n }\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n }\n\n }\n @else if (type === 'radio' && options?.length) {\n <ion-radio-group class=\"dcf-width-1-1\" [formControlName]=\"name\" [value]=\"value\" #component>\n <label class=\"dcf-radio-group-label\" [for]=\"path\">{{label | translate}}</label>\n @for(option of options; track $index) {\n <ion-item>\n <ion-radio\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [errorText]=\"getErrors(container)\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [readonly]=\"readonly\"\n [value]=\"option.value\"\n >{{ option?.text | translate }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if (type === 'select') {\n <div>\n <ion-select\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [interface]=\"interface\"\n [mode]=\"'md'\"\n [hidden]=\"hidden || !options?.length\"\n [labelPlacement]=\"labelPlacement\"\n [label]=\"label | translate\"\n [value]=\"value\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [interface]=\"interface\" #component>\n @if (options?.length) {\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-select-option [value]=\"option.value\">\n {{ option.text | translate }}\n </ion-select-option>\n }\n }\n </ion-select>\n <div class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></div>\n @if (!options?.length) {\n <ion-text color=\"danger\">\n * {{ 'errors.empty_options' | translate:{'0': name} }}\n </ion-text>\n }\n </div>\n }\n @else {\n <ion-input\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [type]=\"type\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [labelPlacement]=\"labelPlacement\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [max]=\"max !== undefined ? max : null\"\n [min]=\"min !== undefined ? min : null\"\n [pattern]=\"pattern !== undefined ? pattern : null\"\n [step]=\"step !== undefined ? step : null\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [label]=\"label | translate\" #component />\n }\n </div>\n </ng-container>\n } @else {\n <div>\n <p class=\"dcf-error\">\n {{ 'errors.form.control' | translate:{'0': name} }}\n </p>\n </div>\n }\n\n}\n\n", styles: ["ion-item{--border-color: transparent}ion-item:not(.dcf-input-item){--inner-padding-start: 0rem;--padding-start: 0rem}ion-item.dcf-input-item{--padding-end: 0rem;--padding-start: 0px !important;--padding-top: 0px !important;--inner-padding-start: .75rem;--background: transparent;--background-hover-opacity: .1;--background-activated-opacity: .15;--background-focused-opacity: .15;--background-hover: var(--dcf-color-primary);--background-focused: var(--dcf-color-primary);--border-color: var(--dcf-color-gray-2)}ion-item.dcf-input-item.dcf-palette-dark{--border-color: var(--dcf-color-gray-6) !important}ion-item.dcf-input-item.read,ion-item.dcf-input-item.delete{--min-height: 30px;padding:unset;margin:unset!important;margin-bottom:var(--dcf-margin-xsmall)!important}ion-item.dcf-input-item.read ion-label,ion-item.dcf-input-item.delete ion-label{font-weight:600;margin-top:0!important;margin-bottom:.25rem!important;font-size:.925rem}ion-item.dcf-input-item.read ion-label:not(:first-of-type),ion-item.dcf-input-item.delete ion-label:not(:first-of-type){margin:100rem}ion-item.dcf-input-item.read span,ion-item.dcf-input-item.read ion-text,ion-item.dcf-input-item.delete span,ion-item.dcf-input-item.delete ion-text{font-weight:400!important;font-size:.825rem;min-height:.5rem!important}ion-item.dcf-input-item.read span:not(.dcf-display-block),ion-item.dcf-input-item.read ion-text:not(.dcf-display-block),ion-item.dcf-input-item.delete span:not(.dcf-display-block),ion-item.dcf-input-item.delete ion-text:not(.dcf-display-block){display:inline-block}ion-item.dcf-input-item.read span.dcf-display-block,ion-item.dcf-input-item.read ion-text.dcf-display-block,ion-item.dcf-input-item.delete span.dcf-display-block,ion-item.dcf-input-item.delete ion-text.dcf-display-block{display:block!important}ion-item.dcf-input-item>*,ion-item.dcf-input-item ion-select{width:100%!important}ion-item.dcf-input-item.create.checkbox+.checkbox,ion-item.dcf-input-item.update.checkbox+.checkbox{margin-top:-.25rem!important}ion-item.dcf-input-item.create ion-item,ion-item.dcf-input-item.update ion-item{--border-color: transparent}ion-item.dcf-input-item.create ion-item.dcf-text-wrap ion-label>*,ion-item.dcf-input-item.update ion-item.dcf-text-wrap ion-label>*{white-space:wrap!important;word-break:break-all!important}ion-textarea textarea{scrollbar-width:thin!important;margin-bottom:.5rem!important}ion-select.dcf-select-label-placement-floating::part(label){line-height:1.2rem!important}.dcf-proccessing,.dcf-proccessing *{pointer-events:none;touch-action:none;cursor:text}ion-checkbox::part(container){border:2px solid var(--dcf-color-primary);margin-left:.5rem;margin-right:.5rem;border-radius:var(--dcf-border-radius-small);padding:3px}ion-checkbox{--size: 1.5rem;--checkbox-background-checked: var(--dcf-color-primary);--checkmark-width: 2px}ion-radio-group .dcf-radio-group-label{font-weight:600}ion-radio-group .dcf-radio-group-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}ion-radio-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-checkbox-group{width:100%}.dcf-checkbox-group .dcf-label{font-weight:600}.dcf-checkbox-group .dcf-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}.dcf-checkbox-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-error{position:absolute;color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:500!important;line-height:1.1rem;z-index:9999}.dcf-error .ti,.dcf-error ion-icon{position:relative;top:2px!important;min-width:20px;font-size:1rem!important;text-align:left}.dcf-helper{font-size:.875rem!important;font-weight:500;margin-top:.25rem;margin-bottom:-.75rem}.dcf-helper.dcf-has-action{cursor:pointer;text-decoration:underline}.dcf-error+.dcf-helper{padding-top:1rem}::ng-deep ion-textarea{min-height:80px!important;scrollbar-color:#888 #f0f0f0;scrollbar-width:thin}\n"] }]
|
|
5678
|
+
], selector: 'ngx-decaf-crud-field', schemas: [CUSTOM_ELEMENTS_SCHEMA], host: { '[attr.id]': 'uid', '[attr.class]': 'className' }, template: "@if (operation === 'read' || operation === 'delete') {\n <ng-container>\n <div>\n <ion-item [class]=\"'dcf-input-item ' + operation\" #component>\n <ion-label>\n {{ label | translate }}<br />\n @if (value) {\n <ion-text [innerHTML]=\"type === 'password' ? '********' : value\"></ion-text>\n } @else {\n @if (['checkbox'].includes(type)) {\n <ion-icon aria-hidden=\"true\" class=\"dcf-margin-small-top\" [color]=\"!isDarkMode ? 'primary' : 'light'\" size=\"large\" name=\"checkmark-circle-outline\"></ion-icon>\n } @else {\n <br />\n }\n }\n </ion-label>\n </ion-item>\n </div>\n </ng-container>\n} @else {\n @if (formControl) {\n <ng-container [formGroup]=\"multiple ? activeFormGroup : formControl.parent\">\n <div\n\n [id]=\"uid\" #container\n [class]=\"'dcf-input-item ' + (operation || 'create')\"\n [class.dcf-field-required]=\"required\"\n >\n @if (type === 'textarea') {\n <ion-textarea\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [autoGrow]=\"true\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [inputmode]=\"inputmode\"\n [spellcheck]=\"spellcheck\"\n [rows]=\"rows\"\n [labelPlacement]=\"labelPlacement\"\n [value]=\"value\"\n [fill]=\"fill\"\n [errorText]=\"getErrors(container)\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [label]=\"label | translate\"\n #component>\n </ion-textarea>\n }\n @else if (type === 'checkbox') {\n @if (!options?.length) {\n <ion-item class=\"dcf-width-1-1\" [hidden]=\"hidden\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [errorText]=\"getErrors(container)\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify || 'start'\"\n [value]=\"value\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\"\n #component>\n <span>{{label | translate}}</span>\n </ion-checkbox>\n\n </ion-item>\n } @else {\n <div class=\"dcf-checkbox-group\">\n <label class=\"dcf-label\" [for]=\"path\">{{ label | translate }}</label>\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-item class=\"dcf-width-1-1\" [button]=\"true\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"option.text\"\n [mode]=\"'md'\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [value]=\"option.value\"\n [readonly]=\"readonly\"\n [checked]=\"isOptionChecked(option.value)\"\n (ionChange)=\"toggleOptionSelection(option.value, $event)\"\n #component>\n <span>{{ $index + 1 }}. {{ option?.text | translate }}</span>\n </ion-checkbox>\n </ion-item>\n }\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n }\n\n }\n @else if (type === 'radio' && options?.length) {\n <ion-radio-group class=\"dcf-width-1-1\" [formControlName]=\"name\" [value]=\"value\" #component>\n <label class=\"dcf-radio-group-label\" [for]=\"path\">{{label | translate}}</label>\n @for(option of options; track $index) {\n <ion-item>\n <ion-radio\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [errorText]=\"getErrors(container)\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [readonly]=\"readonly\"\n [value]=\"option.value\"\n >{{ option?.text | translate }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if (type === 'select') {\n <div>\n <ion-select\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [interface]=\"interface\"\n [mode]=\"'md'\"\n [hidden]=\"hidden || !options?.length\"\n [labelPlacement]=\"labelPlacement\"\n [label]=\"label | translate\"\n [value]=\"value\"\n (click)=\"openSelectOptions($event, interface)\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [interface]=\"interface\" #component>\n @if (options?.length) {\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-select-option [value]=\"option.value\">\n {{ option.text | translate }}\n </ion-select-option>\n }\n }\n </ion-select>\n <div class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></div>\n @if (!options?.length) {\n <ion-text color=\"danger\">\n * {{ 'errors.empty_options' | translate:{'0': name} }}\n </ion-text>\n }\n </div>\n }\n @else {\n <ion-input\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [type]=\"type\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [labelPlacement]=\"labelPlacement\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [max]=\"max !== undefined ? max : null\"\n [min]=\"min !== undefined ? min : null\"\n [pattern]=\"pattern !== undefined ? pattern : null\"\n [step]=\"step !== undefined ? step : null\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [label]=\"label | translate\" #component />\n }\n </div>\n </ng-container>\n } @else {\n <div>\n <p class=\"dcf-error\">\n {{ 'errors.form.control' | translate:{'0': name} }}\n </p>\n </div>\n }\n\n}\n\n", styles: ["ion-item{--border-color: transparent}ion-item:not(.dcf-input-item){--inner-padding-start: 0rem;--padding-start: 0rem;--background: transparent}ion-item.dcf-input-item{--padding-end: 0rem;--padding-start: 0px !important;--padding-top: 0px !important;--inner-padding-start: .75rem;--background: transparent;--background-hover-opacity: .1;--background-activated-opacity: .15;--background-focused-opacity: .15;--background-hover: var(--dcf-color-primary);--background-focused: var(--dcf-color-primary);--border-color: var(--dcf-color-gray-2)}ion-item.dcf-input-item.dcf-palette-dark{--border-color: var(--dcf-color-gray-6) !important}ion-item.dcf-input-item.read,ion-item.dcf-input-item.delete{--min-height: 30px;padding:unset;margin:unset!important;margin-bottom:var(--dcf-margin-xsmall)!important}ion-item.dcf-input-item.read ion-label,ion-item.dcf-input-item.delete ion-label{font-weight:600;margin-top:0!important;margin-bottom:.25rem!important;font-size:.925rem}ion-item.dcf-input-item.read ion-label:not(:first-of-type),ion-item.dcf-input-item.delete ion-label:not(:first-of-type){margin:100rem}ion-item.dcf-input-item.read span,ion-item.dcf-input-item.read ion-text,ion-item.dcf-input-item.delete span,ion-item.dcf-input-item.delete ion-text{font-weight:400!important;font-size:.825rem;min-height:.5rem!important}ion-item.dcf-input-item.read span:not(.dcf-display-block),ion-item.dcf-input-item.read ion-text:not(.dcf-display-block),ion-item.dcf-input-item.delete span:not(.dcf-display-block),ion-item.dcf-input-item.delete ion-text:not(.dcf-display-block){display:inline-block}ion-item.dcf-input-item.read span.dcf-display-block,ion-item.dcf-input-item.read ion-text.dcf-display-block,ion-item.dcf-input-item.delete span.dcf-display-block,ion-item.dcf-input-item.delete ion-text.dcf-display-block{display:block!important}ion-item.dcf-input-item>*,ion-item.dcf-input-item ion-select{width:100%!important}ion-item.dcf-input-item.create.checkbox+.checkbox,ion-item.dcf-input-item.update.checkbox+.checkbox{margin-top:-.25rem!important}ion-item.dcf-input-item.create ion-item,ion-item.dcf-input-item.update ion-item{--border-color: transparent}ion-item.dcf-input-item.create ion-item.dcf-text-wrap ion-label>*,ion-item.dcf-input-item.update ion-item.dcf-text-wrap ion-label>*{white-space:wrap!important;word-break:break-all!important}ion-textarea textarea{scrollbar-width:thin!important;margin-bottom:.5rem!important}ion-select.dcf-select-label-placement-floating::part(label){line-height:1.2rem!important}.dcf-proccessing,.dcf-proccessing *{pointer-events:none;touch-action:none;cursor:text}ion-checkbox::part(container){border:2px solid var(--dcf-color-primary);margin-left:.5rem;margin-right:.5rem;border-radius:var(--dcf-border-radius-small);padding:3px}ion-checkbox{--size: 1.5rem;--checkbox-background-checked: var(--dcf-color-primary);--checkmark-width: 2px}ion-radio-group .dcf-radio-group-label{font-weight:600}ion-radio-group .dcf-radio-group-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}ion-radio-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-checkbox-group{width:100%}.dcf-checkbox-group .dcf-label{font-weight:600}.dcf-checkbox-group .dcf-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}.dcf-checkbox-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-error{position:absolute;color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:500!important;line-height:1.1rem;z-index:9999}.dcf-error .ti,.dcf-error ion-icon{position:relative;top:2px!important;min-width:20px;font-size:1rem!important;text-align:left}.dcf-helper{font-size:.875rem!important;font-weight:500;margin-top:.25rem;margin-bottom:-.75rem}.dcf-helper.dcf-has-action{cursor:pointer;text-decoration:underline}.dcf-error+.dcf-helper{padding-top:1rem}::ng-deep ion-textarea{min-height:80px!important;scrollbar-color:#888 #f0f0f0;scrollbar-width:thin}\n"] }]
|
|
5035
5679
|
}], propDecorators: { operation: [{
|
|
5036
5680
|
type: Input,
|
|
5037
5681
|
args: [{ required: true }]
|
|
@@ -5120,138 +5764,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
|
|
|
5120
5764
|
args: ['component', { read: ElementRef }]
|
|
5121
5765
|
}], formGroup: [{
|
|
5122
5766
|
type: Input
|
|
5123
|
-
}], formControl: [{
|
|
5124
|
-
type: Input
|
|
5125
|
-
}], multiple: [{
|
|
5126
|
-
type: Input
|
|
5127
|
-
}], uid: [{
|
|
5128
|
-
type: Input
|
|
5129
|
-
}], page: [{
|
|
5130
|
-
type: Input
|
|
5131
|
-
}], translatable: [{
|
|
5132
|
-
type: Input
|
|
5133
|
-
}], handleFieldsetUpdateGroupEvent: [{
|
|
5134
|
-
type: HostListener,
|
|
5135
|
-
args: ['window:fieldsetUpdateGroupEvent', ['$event']]
|
|
5136
|
-
}] } });
|
|
5137
|
-
|
|
5138
|
-
/**
|
|
5139
|
-
* @module module:lib/engine/NgxParentComponentDirective
|
|
5140
|
-
* @description Directive base for parent container components used by the rendering system.
|
|
5141
|
-
* @summary Provides NgxParentComponentDirective which offers inputs for children metadata,
|
|
5142
|
-
* column/row configuration and parent component wiring used by layout and container components.
|
|
5143
|
-
*
|
|
5144
|
-
* @link {@link NgxParentComponentDirective}
|
|
5145
|
-
*/
|
|
5146
|
-
/**
|
|
5147
|
-
* @description Layout component for creating responsive grid layouts in Angular applications.
|
|
5148
|
-
* @summary This component provides a flexible grid system that can be configured with dynamic
|
|
5149
|
-
* rows and columns. It supports responsive breakpoints and can render child components within
|
|
5150
|
-
* the grid structure. The component extends NgxComponentDirective to inherit common functionality
|
|
5151
|
-
* and integrates with the model and component renderer systems.
|
|
5152
|
-
*
|
|
5153
|
-
* @class NgxParentComponentDirective
|
|
5154
|
-
* @extends {NgxComponentDirective}
|
|
5155
|
-
* @implements {OnInit}
|
|
5156
|
-
*/
|
|
5157
|
-
class NgxParentComponentDirective extends NgxComponentDirective {
|
|
5158
|
-
constructor() {
|
|
5159
|
-
super(...arguments);
|
|
5160
|
-
/**
|
|
5161
|
-
* @description Unique identifier for the current record.
|
|
5162
|
-
* @summary A unique identifier for the current record being displayed or manipulated.
|
|
5163
|
-
* This is typically used in conjunction with the primary key for operations on specific records.
|
|
5164
|
-
*
|
|
5165
|
-
* @type {string | number}
|
|
5166
|
-
*/
|
|
5167
|
-
this.page = 1;
|
|
5168
|
-
/**
|
|
5169
|
-
* @description Unique identifier for the current record.
|
|
5170
|
-
* @summary A unique identifier for the current record being displayed or manipulated.
|
|
5171
|
-
* This is typically used in conjunction with the primary key for operations on specific records.
|
|
5172
|
-
*
|
|
5173
|
-
* @type {string | number}
|
|
5174
|
-
*/
|
|
5175
|
-
this.pages = 1;
|
|
5176
|
-
/**
|
|
5177
|
-
* @description Array of UI model metadata for the currently active page.
|
|
5178
|
-
* @summary Contains only the UI model metadata for fields that should be displayed
|
|
5179
|
-
* on the currently active page. This is a filtered subset of the children array,
|
|
5180
|
-
* updated whenever the user navigates between pages.
|
|
5181
|
-
*
|
|
5182
|
-
* @type {UIModelMetadata | UIModelMetadata[] | undefined}
|
|
5183
|
-
*/
|
|
5184
|
-
this.activeContent = undefined;
|
|
5185
|
-
/**
|
|
5186
|
-
* @description The currently active page number.
|
|
5187
|
-
* @summary Tracks which page of the multi-step form is currently being displayed.
|
|
5188
|
-
* This property is updated as users navigate through the form steps using
|
|
5189
|
-
* the next/back buttons or programmatic navigation.
|
|
5190
|
-
*
|
|
5191
|
-
* @type {number}
|
|
5192
|
-
*/
|
|
5193
|
-
this.activeIndex = 1;
|
|
5194
|
-
/**
|
|
5195
|
-
* @description Array of UI model metadata for all form fields.
|
|
5196
|
-
* @summary Contains the complete collection of UI model metadata that defines
|
|
5197
|
-
* the structure, validation, and presentation of form fields across all pages.
|
|
5198
|
-
* Each metadata object contains information about field type, validation rules,
|
|
5199
|
-
* page assignment, and display properties.
|
|
5200
|
-
*
|
|
5201
|
-
* @type {UIModelMetadata[]}
|
|
5202
|
-
*/
|
|
5203
|
-
this.children = [];
|
|
5204
|
-
/**
|
|
5205
|
-
* @description Number of columns or array of column definitions for the grid layout.
|
|
5206
|
-
* @summary Defines the column structure of the grid. When a number is provided, it creates
|
|
5207
|
-
* that many equal-width columns. When an array is provided, each element can define specific
|
|
5208
|
-
* column properties or sizing. This allows for flexible grid layouts that can adapt to
|
|
5209
|
-
* different content requirements.
|
|
5210
|
-
*
|
|
5211
|
-
* @type {(number | string[])}
|
|
5212
|
-
* @default 1
|
|
5213
|
-
*/
|
|
5214
|
-
this.cols = 1;
|
|
5215
|
-
/**
|
|
5216
|
-
* @description Number of rows or array of row definitions for the grid layout.
|
|
5217
|
-
* @summary Defines the row structure of the grid. When a number is provided, it creates
|
|
5218
|
-
* that many equal-height rows. When an array is provided, each element can define specific
|
|
5219
|
-
* row properties or sizing. This provides control over vertical spacing and content organization.
|
|
5220
|
-
*
|
|
5221
|
-
* @type {(number | string[])}
|
|
5222
|
-
* @default 1
|
|
5223
|
-
*/
|
|
5224
|
-
this.rows = 1;
|
|
5225
|
-
}
|
|
5226
|
-
async ngOnInit(model) {
|
|
5227
|
-
if (model)
|
|
5228
|
-
this.model = model;
|
|
5229
|
-
if (this.model && !this.repository)
|
|
5230
|
-
this._repository = this.repository;
|
|
5231
|
-
}
|
|
5232
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgxParentComponentDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
5233
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.9", type: NgxParentComponentDirective, isStandalone: true, inputs: { page: "page", pages: "pages", parentForm: "parentForm", children: "children", cols: "cols", rows: "rows" }, usesInheritance: true, ngImport: i0 }); }
|
|
5234
|
-
}
|
|
5235
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgxParentComponentDirective, decorators: [{
|
|
5236
|
-
type: Directive
|
|
5237
|
-
}], propDecorators: { page: [{
|
|
5238
|
-
type: Input
|
|
5239
|
-
}], pages: [{
|
|
5767
|
+
}], formControl: [{
|
|
5240
5768
|
type: Input
|
|
5241
|
-
}],
|
|
5769
|
+
}], multiple: [{
|
|
5242
5770
|
type: Input
|
|
5243
|
-
}],
|
|
5771
|
+
}], uid: [{
|
|
5244
5772
|
type: Input
|
|
5245
|
-
}],
|
|
5773
|
+
}], page: [{
|
|
5246
5774
|
type: Input
|
|
5247
|
-
}],
|
|
5775
|
+
}], translatable: [{
|
|
5248
5776
|
type: Input
|
|
5777
|
+
}], handleFieldsetUpdateGroupEvent: [{
|
|
5778
|
+
type: HostListener,
|
|
5779
|
+
args: ['window:fieldsetUpdateGroupEvent', ['$event']]
|
|
5249
5780
|
}] } });
|
|
5250
5781
|
|
|
5251
5782
|
class NgxFormDirective extends NgxParentComponentDirective {
|
|
5252
5783
|
constructor() {
|
|
5253
5784
|
super(...arguments);
|
|
5254
|
-
this.crudFieldComponent = ComponentsTagNames.CRUD_FIELD;
|
|
5255
5785
|
/**
|
|
5256
5786
|
* @description Indicates whether this form is being used inside a modal dialog.
|
|
5257
5787
|
* @summary When true, the form may alter its submit/reset behavior to integrate
|
|
@@ -5336,6 +5866,7 @@ class NgxFormDirective extends NgxParentComponentDirective {
|
|
|
5336
5866
|
* @default Randomly generated 12-character string
|
|
5337
5867
|
*/
|
|
5338
5868
|
this.allowClear = true;
|
|
5869
|
+
this.match = false;
|
|
5339
5870
|
// protected override enableDarkMode: boolean = true;
|
|
5340
5871
|
// /**
|
|
5341
5872
|
// * @description Angular change detection service.
|
|
@@ -5386,14 +5917,14 @@ class NgxFormDirective extends NgxParentComponentDirective {
|
|
|
5386
5917
|
*/
|
|
5387
5918
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
5388
5919
|
async ngOnInit(model) {
|
|
5389
|
-
this.uid
|
|
5920
|
+
if (!this.uid)
|
|
5921
|
+
this.uid = generateRandomValue(12);
|
|
5390
5922
|
// dont call super.ngOnInit to model conflicts
|
|
5391
5923
|
if (this.operation === OperationKeys.READ || this.operation === OperationKeys.DELETE)
|
|
5392
5924
|
this.formGroup = undefined;
|
|
5393
5925
|
this.initialized = true;
|
|
5394
5926
|
}
|
|
5395
5927
|
ngAfterViewInit() {
|
|
5396
|
-
this.isModalChild = this.component.nativeElement?.closest('ion-modal') ? true : false;
|
|
5397
5928
|
if (this.isModalChild)
|
|
5398
5929
|
this.changeDetectorRef.detectChanges();
|
|
5399
5930
|
}
|
|
@@ -5411,9 +5942,14 @@ class NgxFormDirective extends NgxParentComponentDirective {
|
|
|
5411
5942
|
NgxFormService.unregister(this.formGroup);
|
|
5412
5943
|
}
|
|
5413
5944
|
getFormArrayIndex(index) {
|
|
5414
|
-
if (!(this.formGroup instanceof FormArray) && this.formGroup)
|
|
5945
|
+
if (!(this.formGroup instanceof FormArray) && this.formGroup) {
|
|
5946
|
+
if (this.formGroup.disabled)
|
|
5947
|
+
this.formGroup.enable();
|
|
5415
5948
|
return this.formGroup;
|
|
5949
|
+
}
|
|
5416
5950
|
const formGroup = this.formGroup.at(index);
|
|
5951
|
+
if (formGroup.disabled)
|
|
5952
|
+
formGroup.enable();
|
|
5417
5953
|
if (formGroup) {
|
|
5418
5954
|
if (this.children.length) {
|
|
5419
5955
|
const children = [...this.children];
|
|
@@ -5464,18 +6000,54 @@ class NgxFormDirective extends NgxParentComponentDirective {
|
|
|
5464
6000
|
const isValid = NgxFormService.validateFields(this.formGroup);
|
|
5465
6001
|
if (this.isModalChild)
|
|
5466
6002
|
this.changeDetectorRef.detectChanges();
|
|
5467
|
-
if (!isValid)
|
|
6003
|
+
if (!isValid) {
|
|
5468
6004
|
return false;
|
|
6005
|
+
}
|
|
5469
6006
|
const data = NgxFormService.getFormData(this.formGroup);
|
|
5470
6007
|
this.submitEvent.emit({
|
|
5471
6008
|
data,
|
|
5472
6009
|
component: componentName || this.componentName,
|
|
5473
|
-
name: eventName || this.action ||
|
|
6010
|
+
name: eventName || this.action || ComponentEventNames.SUBMIT,
|
|
5474
6011
|
handlers: this.handlers,
|
|
5475
6012
|
});
|
|
5476
6013
|
}
|
|
6014
|
+
/**
|
|
6015
|
+
* @description Updates the active form group and children for the specified page.
|
|
6016
|
+
* @summary Extracts the FormGroup for the given page from the FormArray and filters
|
|
6017
|
+
* the children to show only fields belonging to that page. Uses a timer to ensure
|
|
6018
|
+
* proper Angular change detection when updating the activeContent.
|
|
6019
|
+
*
|
|
6020
|
+
* @param {number} page - The page number to activate
|
|
6021
|
+
* @return {UIModelMetadata | UIModelMetadata[] | FieldDefinition | undefined}
|
|
6022
|
+
*
|
|
6023
|
+
* @private
|
|
6024
|
+
* @mermaid
|
|
6025
|
+
* sequenceDiagram
|
|
6026
|
+
* participant S as SteppedFormComponent
|
|
6027
|
+
* participant F as FormArray
|
|
6028
|
+
* participant T as Timer
|
|
6029
|
+
*
|
|
6030
|
+
* S->>F: Extract FormGroup at index (page - 1)
|
|
6031
|
+
* F-->>S: Return page FormGroup
|
|
6032
|
+
* S->>S: Set activeContent = undefined
|
|
6033
|
+
* S->>T: timer(10).subscribe()
|
|
6034
|
+
* T-->>S: Filter children for active page
|
|
6035
|
+
* S->>S: Set activeContent
|
|
6036
|
+
*
|
|
6037
|
+
* @memberOf SteppedFormComponent
|
|
6038
|
+
*/
|
|
6039
|
+
getActivePage(page) {
|
|
6040
|
+
if (!(this.formGroup instanceof FormArray))
|
|
6041
|
+
this.formGroup = this.formGroup?.parent;
|
|
6042
|
+
this.formGroup = this.formGroup.at(page - 1);
|
|
6043
|
+
this.activePage = undefined;
|
|
6044
|
+
this.timerSubscription = timer(10).subscribe(() => this.activePage = this.children.filter(c => c.props?.['page'] === page));
|
|
6045
|
+
if (this.activePage)
|
|
6046
|
+
return this.activePage;
|
|
6047
|
+
return undefined;
|
|
6048
|
+
}
|
|
5477
6049
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgxFormDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
5478
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.9", type: NgxFormDirective, isStandalone: true, inputs: { parentFormId: "parentFormId", modalForm: "modalForm", updateOn: "updateOn", target: "target", method: "method", options: "options", action: "action", operation: "operation", handlers: "handlers", formGroup: "formGroup", rendererId: "rendererId", allowClear: "allowClear" }, outputs: { submitEvent: "submitEvent" }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef }], usesInheritance: true, ngImport: i0 }); }
|
|
6050
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.9", type: NgxFormDirective, isStandalone: true, inputs: { parentFormId: "parentFormId", modalForm: "modalForm", updateOn: "updateOn", target: "target", method: "method", options: "options", action: "action", operation: "operation", handlers: "handlers", formGroup: "formGroup", rendererId: "rendererId", allowClear: "allowClear", match: "match" }, outputs: { submitEvent: "submitEvent" }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef }], usesInheritance: true, ngImport: i0 }); }
|
|
5479
6051
|
}
|
|
5480
6052
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgxFormDirective, decorators: [{
|
|
5481
6053
|
type: Directive
|
|
@@ -5509,97 +6081,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
|
|
|
5509
6081
|
type: Output
|
|
5510
6082
|
}], allowClear: [{
|
|
5511
6083
|
type: Input
|
|
5512
|
-
}]
|
|
5513
|
-
|
|
5514
|
-
/**
|
|
5515
|
-
* @module module:lib/components/model-renderer/model-renderer.component
|
|
5516
|
-
* @description Model renderer component module.
|
|
5517
|
-
* @summary Exposes `ModelRendererComponent` which dynamically renders UI components
|
|
5518
|
-
* from model definitions using the `NgxRenderingEngine`. It handles model changes,
|
|
5519
|
-
* event subscription and lifecycle for the rendered output.
|
|
5520
|
-
*
|
|
5521
|
-
* @link {@link ModelRendererComponent}
|
|
5522
|
-
*/
|
|
5523
|
-
/**
|
|
5524
|
-
* @description Component for rendering dynamic models
|
|
5525
|
-
* @summary This component is responsible for dynamically rendering models,
|
|
5526
|
-
* handling model changes, and managing event subscriptions for the rendered components.
|
|
5527
|
-
* It uses the NgxRenderingEngine to render the models and supports both string and Model inputs.
|
|
5528
|
-
* @class
|
|
5529
|
-
* @template M - Type extending Model
|
|
5530
|
-
* @param {Injector} injector - Angular Injector for dependency injection
|
|
5531
|
-
* @example
|
|
5532
|
-
* <ngx-decaf-model-renderer
|
|
5533
|
-
* [model]="myModel"
|
|
5534
|
-
* [globals]="globalVariables"
|
|
5535
|
-
* (listenEvent)="handleEvent($event)">
|
|
5536
|
-
* </ngx-decaf-model-renderer>
|
|
5537
|
-
* @mermaid
|
|
5538
|
-
* sequenceDiagram
|
|
5539
|
-
* participant App
|
|
5540
|
-
* participant ModelRenderer
|
|
5541
|
-
* participant RenderingEngine
|
|
5542
|
-
* participant Model
|
|
5543
|
-
* App->>ModelRenderer: Input model
|
|
5544
|
-
* ModelRenderer->>Model: Parse if string
|
|
5545
|
-
* Model-->>ModelRenderer: Parsed model
|
|
5546
|
-
* ModelRenderer->>RenderingEngine: Render model
|
|
5547
|
-
* RenderingEngine-->>ModelRenderer: Rendered output
|
|
5548
|
-
* ModelRenderer->>ModelRenderer: Subscribe to events
|
|
5549
|
-
* ModelRenderer-->>App: Emit events
|
|
5550
|
-
*/
|
|
5551
|
-
class ModelRendererComponent extends NgxRenderableComponentDirective {
|
|
5552
|
-
constructor() {
|
|
5553
|
-
super(...arguments);
|
|
5554
|
-
/**
|
|
5555
|
-
* @description Set if render content projection is allowed
|
|
5556
|
-
* @default true
|
|
5557
|
-
*/
|
|
5558
|
-
this.projectable = true;
|
|
5559
|
-
}
|
|
5560
|
-
// private injector: Injector = inject(Injector);
|
|
5561
|
-
// constructor() {}
|
|
5562
|
-
/**
|
|
5563
|
-
* @description Refreshes the rendered model
|
|
5564
|
-
* @param {string | M} model - The model to be rendered
|
|
5565
|
-
*/
|
|
5566
|
-
refresh(model) {
|
|
5567
|
-
model =
|
|
5568
|
-
typeof model === 'string'
|
|
5569
|
-
? Model.build({}, model)
|
|
5570
|
-
: model;
|
|
5571
|
-
this.output = model.render(this.globals || {}, this.vcr, this.injector, this.inner, this.projectable);
|
|
5572
|
-
if (this.output?.inputs)
|
|
5573
|
-
this.rendererId = sf(AngularEngineKeys.RENDERED_ID, this.output.inputs['rendererId']);
|
|
5574
|
-
this.instance = this.output?.component;
|
|
5575
|
-
this.subscribeEvents();
|
|
5576
|
-
}
|
|
5577
|
-
/**
|
|
5578
|
-
* @description Lifecycle hook that is called when data-bound properties of a directive change
|
|
5579
|
-
* @param {SimpleChanges} changes - Object containing changes
|
|
5580
|
-
*/
|
|
5581
|
-
ngOnChanges(changes) {
|
|
5582
|
-
if (changes[BaseComponentProps.MODEL]) {
|
|
5583
|
-
const { currentValue } = changes[BaseComponentProps.MODEL];
|
|
5584
|
-
this.refresh(currentValue);
|
|
5585
|
-
}
|
|
5586
|
-
}
|
|
5587
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ModelRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
5588
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: ModelRendererComponent, isStandalone: true, selector: "ngx-decaf-model-renderer", inputs: { projectable: "projectable" }, host: { properties: { "attr.id": "uid" } }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: " <!-- Keep to avoid id conflicts -->\n <div class=\"dcf-hidden\" [id]=\"uid\"></div>\n\n <ng-template #componentOuter></ng-template>\n <!-- <ng-template #inner>\n <div class=\"dcf-grid dcf-grid-small dcf-model-renderer-component dcf-child-width-1-1\" [id]=\"rendererId || ''\">\n @for (child of output?.children; track child) {\n @if (child?.children?.length) {\n <ngx-decaf-component-renderer [parent]=\"child\" />\n } @else {\n <ng-container\n #childComponents\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n }\n }\n </div>\n </ng-template> -->\n", styles: [""] }); }
|
|
5589
|
-
}
|
|
5590
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ModelRendererComponent, decorators: [{
|
|
5591
|
-
type: Component,
|
|
5592
|
-
args: [{ standalone: true, imports: [], selector: 'ngx-decaf-model-renderer', host: { '[attr.id]': 'uid' }, template: " <!-- Keep to avoid id conflicts -->\n <div class=\"dcf-hidden\" [id]=\"uid\"></div>\n\n <ng-template #componentOuter></ng-template>\n <!-- <ng-template #inner>\n <div class=\"dcf-grid dcf-grid-small dcf-model-renderer-component dcf-child-width-1-1\" [id]=\"rendererId || ''\">\n @for (child of output?.children; track child) {\n @if (child?.children?.length) {\n <ngx-decaf-component-renderer [parent]=\"child\" />\n } @else {\n <ng-container\n #childComponents\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n }\n }\n </div>\n </ng-template> -->\n" }]
|
|
5593
|
-
}], propDecorators: { projectable: [{
|
|
6084
|
+
}], match: [{
|
|
5594
6085
|
type: Input
|
|
5595
6086
|
}] } });
|
|
5596
6087
|
|
|
5597
6088
|
let CardComponent = class CardComponent extends NgxComponentDirective {
|
|
5598
6089
|
constructor() {
|
|
5599
6090
|
super(...arguments);
|
|
5600
|
-
this.type = '
|
|
6091
|
+
this.type = 'clear';
|
|
5601
6092
|
this.title = '';
|
|
5602
|
-
this.body = '
|
|
6093
|
+
this.body = 'default';
|
|
5603
6094
|
this.subtitle = '';
|
|
5604
6095
|
this.color = '';
|
|
5605
6096
|
this.separator = false;
|
|
@@ -5608,18 +6099,21 @@ let CardComponent = class CardComponent extends NgxComponentDirective {
|
|
|
5608
6099
|
this.componentName = 'CardComponent';
|
|
5609
6100
|
}
|
|
5610
6101
|
ngOnInit() {
|
|
5611
|
-
console.log(this.componentName, this.type);
|
|
5612
6102
|
this.initialized = true;
|
|
6103
|
+
this.mediaService.isDarkMode().subscribe(isDark => {
|
|
6104
|
+
this.isDarkMode = isDark;
|
|
6105
|
+
this.mediaService.toggleClass([this.component], AngularEngineKeys.DARK_PALETTE_CLASS, this.isDarkMode);
|
|
6106
|
+
});
|
|
5613
6107
|
}
|
|
5614
6108
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CardComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
5615
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: CardComponent, isStandalone: true, selector: "ngx-decaf-card", inputs: { type: "type", title: "title", body: "body", subtitle: "subtitle", color: "color", separator: "separator", borders: "borders", inlineContent: "inlineContent", inlineContentPosition: "inlineContentPosition" }, usesInheritance: true, ngImport: i0, template: "
|
|
6109
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: CardComponent, isStandalone: true, selector: "ngx-decaf-card", inputs: { type: "type", title: "title", body: "body", subtitle: "subtitle", color: "color", separator: "separator", borders: "borders", inlineContent: "inlineContent", inlineContentPosition: "inlineContentPosition" }, usesInheritance: true, ngImport: i0, template: "<ion-card\n [class]=\"'dcf-card ' + className + ' ' + 'dcf-card-' + body\"\n [color]=\"color\"\n mode=\"md\"\n [class.dcf-card-separator]=\"separator\"\n [class.dcf-card-shadow]=\"type === 'shadow'\"\n [class.dcf-card-bordered]=\"borders\"\n [class.dcf-card-separator]=\"separator\"\n #component\n>\n @if (title || subtitle) {\n <ion-card-header>\n @if (title) {\n <ion-card-title>{{\n locale ? (title | translate) : title\n }}</ion-card-title>\n }\n @if (subtitle) {\n <ion-card-subtitle>{{\n locale ? (subtitle | translate) : subtitle\n }}</ion-card-subtitle>\n }\n </ion-card-header>\n }\n <ion-card-content>\n @if (inlineContent && inlineContentPosition === \"top\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n\n <ng-content slot=\"content\"></ng-content>\n\n @if (inlineContent && inlineContentPosition === \"bottom\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n </ion-card-content>\n</ion-card>\n", styles: [".dcf-card{display:flow-root;border-radius:var(--dcf-border-radius-small)}.dcf-card .dcf-card{border-radius:0!important}.dcf-card:not(.dcf-card-shadow){box-shadow:none!important}.dcf-card:not(.dcf-card-shadow).dcf-card-bordered .dcf-card-bordered{border-color:transparent!important}.dcf-card.dcf-card-separator,.dcf-card.dcf-card-blank{padding:0!important;margin:0!important;background:transparent!important}.dcf-card.dcf-card-separator>*,.dcf-card.dcf-card-blank>*{padding:0!important;margin:0!important}.dcf-card.dcf-card-separator ion-card-header{padding:unset!important;margin:unset!important}.dcf-card.dcf-card-separator ion-card-title{padding:unset!important;margin:unset!important;font-weight:500;font-size:1rem;line-height:1.5rem}.dcf-card.dcf-card-separator.dcf-card-bordered{border-color:transparent!important}.dcf-card.dcf-card-small ion-card-header{padding:var(--dcf-padding-xsmall) 0!important}.dcf-card.dcf-card-small ion-card-content{padding:var(--dcf-padding-xsmall)!important}.dcf-card>*{width:100%!important}.dcf-card ion-card-content{padding:var(--dcf-padding)}.dcf-card ion-card-header+ion-card-content{padding-top:0!important;margin-top:var(--dcf-margin-small)}.dcf-card ion-card-header{padding-left:1.25rem}@media (max-width: 575px){.dcf-card ion-card-header{padding-left:.2rem!important}.dcf-card ion-card-header+ion-card-content{margin-top:var(--dcf-margin-small)}.dcf-card ion-card-content{padding:var(--dcf-margin) var(--dcf-margin-small)}.dcf-card.dcf-card-small ion-content{padding:var(--dcf-padding-xsmall)}}.dcf-card.dcf-height-1-1{display:flex;align-items:center;justify-content:center}.dcf-card.dcf-height-1-1.dcf-card-layout{height:calc(100% - 1.5rem)}.dcf-card.dcf-card-shadow{box-shadow:var(--dcf-card-box-shadow)!important}.dcf-card.dcf-card-bordered{border:1px solid var(--dcf-color-gray-2)}.dcf-card ion-card-title{padding:var(--dcf-padding-small) var(--dcf-spacement) 0rem var(--dcf-spacement)!important;font-weight:500;font-size:1.125rem;line-height:1.75rem}.dcf-card ion-card-subtitle{padding:0rem var(--dcf-spacement);color:var(--ion-color-gray-4);margin-top:0!important}.dcf-palette-dark.dcf-card-bordered{border-color:transparent!important}::ng-deep ngx-decaf-list ion-list{padding:0!important;margin:0!important}\n"], dependencies: [{ kind: "component", type: IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: IonCardSubtitle, selector: "ion-card-subtitle", inputs: ["color", "mode"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
5616
6110
|
};
|
|
5617
6111
|
CardComponent = __decorate([
|
|
5618
6112
|
Dynamic()
|
|
5619
6113
|
], CardComponent);
|
|
5620
6114
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CardComponent, decorators: [{
|
|
5621
6115
|
type: Component,
|
|
5622
|
-
args: [{ selector: 'ngx-decaf-card', imports: [TranslatePipe, IonCard, IonCardHeader, IonCardContent, IonCardTitle, IonCardSubtitle], standalone: true, template: "
|
|
6116
|
+
args: [{ selector: 'ngx-decaf-card', imports: [TranslatePipe, IonCard, IonCardHeader, IonCardContent, IonCardTitle, IonCardSubtitle], standalone: true, template: "<ion-card\n [class]=\"'dcf-card ' + className + ' ' + 'dcf-card-' + body\"\n [color]=\"color\"\n mode=\"md\"\n [class.dcf-card-separator]=\"separator\"\n [class.dcf-card-shadow]=\"type === 'shadow'\"\n [class.dcf-card-bordered]=\"borders\"\n [class.dcf-card-separator]=\"separator\"\n #component\n>\n @if (title || subtitle) {\n <ion-card-header>\n @if (title) {\n <ion-card-title>{{\n locale ? (title | translate) : title\n }}</ion-card-title>\n }\n @if (subtitle) {\n <ion-card-subtitle>{{\n locale ? (subtitle | translate) : subtitle\n }}</ion-card-subtitle>\n }\n </ion-card-header>\n }\n <ion-card-content>\n @if (inlineContent && inlineContentPosition === \"top\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n\n <ng-content slot=\"content\"></ng-content>\n\n @if (inlineContent && inlineContentPosition === \"bottom\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n </ion-card-content>\n</ion-card>\n", styles: [".dcf-card{display:flow-root;border-radius:var(--dcf-border-radius-small)}.dcf-card .dcf-card{border-radius:0!important}.dcf-card:not(.dcf-card-shadow){box-shadow:none!important}.dcf-card:not(.dcf-card-shadow).dcf-card-bordered .dcf-card-bordered{border-color:transparent!important}.dcf-card.dcf-card-separator,.dcf-card.dcf-card-blank{padding:0!important;margin:0!important;background:transparent!important}.dcf-card.dcf-card-separator>*,.dcf-card.dcf-card-blank>*{padding:0!important;margin:0!important}.dcf-card.dcf-card-separator ion-card-header{padding:unset!important;margin:unset!important}.dcf-card.dcf-card-separator ion-card-title{padding:unset!important;margin:unset!important;font-weight:500;font-size:1rem;line-height:1.5rem}.dcf-card.dcf-card-separator.dcf-card-bordered{border-color:transparent!important}.dcf-card.dcf-card-small ion-card-header{padding:var(--dcf-padding-xsmall) 0!important}.dcf-card.dcf-card-small ion-card-content{padding:var(--dcf-padding-xsmall)!important}.dcf-card>*{width:100%!important}.dcf-card ion-card-content{padding:var(--dcf-padding)}.dcf-card ion-card-header+ion-card-content{padding-top:0!important;margin-top:var(--dcf-margin-small)}.dcf-card ion-card-header{padding-left:1.25rem}@media (max-width: 575px){.dcf-card ion-card-header{padding-left:.2rem!important}.dcf-card ion-card-header+ion-card-content{margin-top:var(--dcf-margin-small)}.dcf-card ion-card-content{padding:var(--dcf-margin) var(--dcf-margin-small)}.dcf-card.dcf-card-small ion-content{padding:var(--dcf-padding-xsmall)}}.dcf-card.dcf-height-1-1{display:flex;align-items:center;justify-content:center}.dcf-card.dcf-height-1-1.dcf-card-layout{height:calc(100% - 1.5rem)}.dcf-card.dcf-card-shadow{box-shadow:var(--dcf-card-box-shadow)!important}.dcf-card.dcf-card-bordered{border:1px solid var(--dcf-color-gray-2)}.dcf-card ion-card-title{padding:var(--dcf-padding-small) var(--dcf-spacement) 0rem var(--dcf-spacement)!important;font-weight:500;font-size:1.125rem;line-height:1.75rem}.dcf-card ion-card-subtitle{padding:0rem var(--dcf-spacement);color:var(--ion-color-gray-4);margin-top:0!important}.dcf-palette-dark.dcf-card-bordered{border-color:transparent!important}::ng-deep ngx-decaf-list ion-list{padding:0!important;margin:0!important}\n"] }]
|
|
5623
6117
|
}], propDecorators: { type: [{
|
|
5624
6118
|
type: Input
|
|
5625
6119
|
}], title: [{
|
|
@@ -5675,18 +6169,6 @@ let LayoutComponent = class LayoutComponent extends NgxParentComponentDirective
|
|
|
5675
6169
|
* @memberOf LayoutComponent
|
|
5676
6170
|
*/
|
|
5677
6171
|
this.gap = LayoutGridGaps.collapse;
|
|
5678
|
-
/**
|
|
5679
|
-
* @description Media breakpoint for responsive behavior.
|
|
5680
|
-
* @summary Determines the responsive breakpoint at which the layout should adapt.
|
|
5681
|
-
* This affects how the grid behaves on different screen sizes, allowing for
|
|
5682
|
-
* mobile-first or desktop-first responsive design patterns. The breakpoint
|
|
5683
|
-
* is automatically processed to ensure compatibility with the UI framework.
|
|
5684
|
-
*
|
|
5685
|
-
* @type {UIMediaBreakPointsType}
|
|
5686
|
-
* @default 'medium'
|
|
5687
|
-
* @memberOf LayoutComponent
|
|
5688
|
-
*/
|
|
5689
|
-
this.breakpoint = UIMediaBreakPoints.MEDIUM;
|
|
5690
6172
|
/**
|
|
5691
6173
|
* @description Media breakpoint for responsive behavior.
|
|
5692
6174
|
* @summary Determines the responsive breakpoint at which the layout should adapt.
|
|
@@ -5699,18 +6181,6 @@ let LayoutComponent = class LayoutComponent extends NgxParentComponentDirective
|
|
|
5699
6181
|
* @memberOf LayoutComponent
|
|
5700
6182
|
*/
|
|
5701
6183
|
this.grid = true;
|
|
5702
|
-
/**
|
|
5703
|
-
* @description Media breakpoint for responsive behavior.
|
|
5704
|
-
* @summary Determines the responsive breakpoint at which the layout should adapt.
|
|
5705
|
-
* This affects how the grid behaves on different screen sizes, allowing for
|
|
5706
|
-
* mobile-first or desktop-first responsive design patterns. The breakpoint
|
|
5707
|
-
* is automatically processed to ensure compatibility with the UI framework.
|
|
5708
|
-
*
|
|
5709
|
-
* @type {UIMediaBreakPointsType}
|
|
5710
|
-
* @default 'medium'
|
|
5711
|
-
* @memberOf LayoutComponent
|
|
5712
|
-
*/
|
|
5713
|
-
this.match = true;
|
|
5714
6184
|
/**
|
|
5715
6185
|
* @description Media breakpoint for responsive behavior.
|
|
5716
6186
|
* @summary Determines the responsive breakpoint at which the layout should adapt.
|
|
@@ -5760,6 +6230,10 @@ let LayoutComponent = class LayoutComponent extends NgxParentComponentDirective
|
|
|
5760
6230
|
*/
|
|
5761
6231
|
get _cols() {
|
|
5762
6232
|
let cols = this.cols;
|
|
6233
|
+
if (typeof cols === Primitives.BOOLEAN) {
|
|
6234
|
+
cols = 1;
|
|
6235
|
+
this.flexMode = true;
|
|
6236
|
+
}
|
|
5763
6237
|
if (typeof cols === Primitives.NUMBER)
|
|
5764
6238
|
cols = Array.from({ length: Number(cols) }, () => '');
|
|
5765
6239
|
return cols;
|
|
@@ -5832,7 +6306,7 @@ let LayoutComponent = class LayoutComponent extends NgxParentComponentDirective
|
|
|
5832
6306
|
return child;
|
|
5833
6307
|
})
|
|
5834
6308
|
};
|
|
5835
|
-
}).map(row => {
|
|
6309
|
+
}).map((row, index) => {
|
|
5836
6310
|
const colsLength = this.getRowColsLength(row);
|
|
5837
6311
|
row.cols = row.cols.map((c) => {
|
|
5838
6312
|
let { col } = c;
|
|
@@ -5845,9 +6319,8 @@ let LayoutComponent = class LayoutComponent extends NgxParentComponentDirective
|
|
|
5845
6319
|
}
|
|
5846
6320
|
}
|
|
5847
6321
|
else {
|
|
5848
|
-
if (typeof col === Primitives.NUMBER)
|
|
5849
|
-
col = `${col}-${colsLength}`;
|
|
5850
|
-
}
|
|
6322
|
+
if (typeof col === Primitives.NUMBER)
|
|
6323
|
+
col = (colsLength <= this.maxColsLength) ? `${col}-${colsLength}` : `${index + 1}-${col}`;
|
|
5851
6324
|
col = ['2-4', '3-6'].includes(col) ? `1-2` : col;
|
|
5852
6325
|
}
|
|
5853
6326
|
col = `dcf-child-${col}-${this.breakpoint} dcf-width-${col}`;
|
|
@@ -5872,7 +6345,7 @@ let LayoutComponent = class LayoutComponent extends NgxParentComponentDirective
|
|
|
5872
6345
|
async ngOnInit() {
|
|
5873
6346
|
super.parseProps(this);
|
|
5874
6347
|
if (this.breakpoint)
|
|
5875
|
-
this.breakpoint = `${this.breakpoint}`.toLowerCase();
|
|
6348
|
+
this.breakpoint = `${this.breakpoint.startsWith('x') ? this.breakpoint.substring(0, 2) : this.breakpoint.substring(0, 1)}`.toLowerCase();
|
|
5876
6349
|
this.cols = this._cols;
|
|
5877
6350
|
this.rows = this._rows;
|
|
5878
6351
|
// if (this._rows.length === 1)
|
|
@@ -5880,9 +6353,10 @@ let LayoutComponent = class LayoutComponent extends NgxParentComponentDirective
|
|
|
5880
6353
|
// if (this._cols.length === 1)
|
|
5881
6354
|
// this.grid = false;
|
|
5882
6355
|
this.initialized = true;
|
|
6356
|
+
this.changeDetectorRef.detectChanges();
|
|
5883
6357
|
}
|
|
5884
6358
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: LayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5885
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: LayoutComponent, isStandalone: true, selector: "ngx-decaf-layout", inputs: { gap: "gap",
|
|
6359
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: LayoutComponent, isStandalone: true, selector: "ngx-decaf-layout", inputs: { gap: "gap", grid: "grid", flexMode: "flexMode", rowCard: "rowCard", maxColsLength: "maxColsLength" }, usesInheritance: true, ngImport: i0, template: "<section class=\"dcf-layout-container\">\n @if (initialized) {\n @for (row of rows; track trackItemFn($index, row); let rowIndex = $index) {\n @if (row?.cols?.length) {\n <div\n [id]=\"uid\"\n [class]=\"\n (!grid\n ? 'dcf-layout-row '\n : 'dcf-layout-row dcf-grid ' + 'dcf-grid-' + gap) +\n ' ' +\n (className || '')\n \"\n [class.dcf-grid-match]=\"match\"\n [class.dcf-grid-bordered]=\"borders\"\n >\n @if (row?.title?.length) {\n <div class=\"dcf-width-1-1 dcf-grid-title\">\n <h3 class=\"\">{{ row.title | translate }}</h3>\n </div>\n }\n @for (\n child of row.cols;\n track trackItemFn($index, child.col);\n let colIndex = $index\n ) {\n\n <div\n [class]=\"'dcf-grid-col ' + child.colClass\"\n [class.dcf-first-column]=\"$index === 0\"\n [class.dcf-layout-separator]=\"child.props?.separator ?? false\"\n >\n <div>\n\n @if (child.tag === \"ngx-decaf-crud-form\") {\n\n <ngx-decaf-card\n [className]=\"\n (match ? 'dcf-height-1-1 dcf-card-layout' : '') +\n className\n \"\n [body]=\"cardBody\"\n [type]=\"cardType\"\n >\n <ngx-decaf-model-renderer\n [model]=\"child.props.name\"\n (listenEvent)=\"handleEvent($event)\"\n />\n </ngx-decaf-card>\n } @else {\n\n <ngx-decaf-component-renderer\n [tag]=\"child.tag\"\n [className]=\"\n (match ? 'dcf-height-1-1 dcf-card-layout' : '') +\n className\n \"\n [parentForm]=\"parentForm || child.parentForm || child?.formGroup\"\n [children]=\"child?.children || []\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]=\"{ props: child.props }\"\n />\n }\n </div>\n </div>\n }\n </div>\n }\n }\n }\n</section>\n", styles: [".dcf-layout-container{display:flow-root}.dcf-grid.dcf-grid-bordered>div>div{padding:var(--dcf-padding);border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-2)}.dcf-grid .dcf-grid-title{padding:unset;margin:unset}.dcf-grid .dcf-grid-title>*{padding:unset;margin:unset;padding-left:var(--dcf-padding-small);font-size:1.05rem!important;font-weight:600;background:none;box-shadow:none;display:flex;align-items:center;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.dcf-grid.dcf-grid-match ::ng-deep ngx-decaf-component-renderer>*>*{height:100%!important}.dcf-grid.dcf-grid-small.dcf-grid-nested{padding:0 .5rem!important}.dcf-grid.dcf-grid-small>div{margin-bottom:1.75rem}.dcf-grid.dcf-grid-small>div.dcf-layout-separator{margin-bottom:1rem}.dcf-grid.dcf-grid-small>div.dcf-grid-bordered:last-child{margin-bottom:0}.dcf-grid.dcf-grid-small+.dcf-grid-small{margin-bottom:1.75rem}.dcf-grid.dcf-grid-small+.dcf-grid-small.dcf-layout-separator{margin-bottom:1rem}::ng-deep ngx-decaf-component-renderer>*>div{margin-bottom:0!important}\n"], dependencies: [{ kind: "component", type: CardComponent, selector: "ngx-decaf-card", inputs: ["type", "title", "body", "subtitle", "color", "separator", "borders", "inlineContent", "inlineContentPosition"] }, { kind: "component", type: ModelRendererComponent, selector: "ngx-decaf-model-renderer", inputs: ["projectable"] }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "children", "projectable", "parent"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
5886
6360
|
};
|
|
5887
6361
|
LayoutComponent = __decorate([
|
|
5888
6362
|
Dynamic(),
|
|
@@ -5890,15 +6364,11 @@ LayoutComponent = __decorate([
|
|
|
5890
6364
|
], LayoutComponent);
|
|
5891
6365
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: LayoutComponent, decorators: [{
|
|
5892
6366
|
type: Component,
|
|
5893
|
-
args: [{ selector: 'ngx-decaf-layout', imports: [TranslatePipe, CardComponent, ModelRendererComponent, ComponentRendererComponent], standalone: true, template: "<section class=\"dcf-layout-container\">\n @if (initialized) {\n @for (row of rows; track trackItemFn($index, row); let rowIndex = $index) {\n @if (row?.cols?.length) {\n <div\n [id]=\"uid\"\n [class]=\"
|
|
6367
|
+
args: [{ selector: 'ngx-decaf-layout', imports: [TranslatePipe, CardComponent, ModelRendererComponent, ComponentRendererComponent], standalone: true, template: "<section class=\"dcf-layout-container\">\n @if (initialized) {\n @for (row of rows; track trackItemFn($index, row); let rowIndex = $index) {\n @if (row?.cols?.length) {\n <div\n [id]=\"uid\"\n [class]=\"\n (!grid\n ? 'dcf-layout-row '\n : 'dcf-layout-row dcf-grid ' + 'dcf-grid-' + gap) +\n ' ' +\n (className || '')\n \"\n [class.dcf-grid-match]=\"match\"\n [class.dcf-grid-bordered]=\"borders\"\n >\n @if (row?.title?.length) {\n <div class=\"dcf-width-1-1 dcf-grid-title\">\n <h3 class=\"\">{{ row.title | translate }}</h3>\n </div>\n }\n @for (\n child of row.cols;\n track trackItemFn($index, child.col);\n let colIndex = $index\n ) {\n\n <div\n [class]=\"'dcf-grid-col ' + child.colClass\"\n [class.dcf-first-column]=\"$index === 0\"\n [class.dcf-layout-separator]=\"child.props?.separator ?? false\"\n >\n <div>\n\n @if (child.tag === \"ngx-decaf-crud-form\") {\n\n <ngx-decaf-card\n [className]=\"\n (match ? 'dcf-height-1-1 dcf-card-layout' : '') +\n className\n \"\n [body]=\"cardBody\"\n [type]=\"cardType\"\n >\n <ngx-decaf-model-renderer\n [model]=\"child.props.name\"\n (listenEvent)=\"handleEvent($event)\"\n />\n </ngx-decaf-card>\n } @else {\n\n <ngx-decaf-component-renderer\n [tag]=\"child.tag\"\n [className]=\"\n (match ? 'dcf-height-1-1 dcf-card-layout' : '') +\n className\n \"\n [parentForm]=\"parentForm || child.parentForm || child?.formGroup\"\n [children]=\"child?.children || []\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]=\"{ props: child.props }\"\n />\n }\n </div>\n </div>\n }\n </div>\n }\n }\n }\n</section>\n", styles: [".dcf-layout-container{display:flow-root}.dcf-grid.dcf-grid-bordered>div>div{padding:var(--dcf-padding);border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-2)}.dcf-grid .dcf-grid-title{padding:unset;margin:unset}.dcf-grid .dcf-grid-title>*{padding:unset;margin:unset;padding-left:var(--dcf-padding-small);font-size:1.05rem!important;font-weight:600;background:none;box-shadow:none;display:flex;align-items:center;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.dcf-grid.dcf-grid-match ::ng-deep ngx-decaf-component-renderer>*>*{height:100%!important}.dcf-grid.dcf-grid-small.dcf-grid-nested{padding:0 .5rem!important}.dcf-grid.dcf-grid-small>div{margin-bottom:1.75rem}.dcf-grid.dcf-grid-small>div.dcf-layout-separator{margin-bottom:1rem}.dcf-grid.dcf-grid-small>div.dcf-grid-bordered:last-child{margin-bottom:0}.dcf-grid.dcf-grid-small+.dcf-grid-small{margin-bottom:1.75rem}.dcf-grid.dcf-grid-small+.dcf-grid-small.dcf-layout-separator{margin-bottom:1rem}::ng-deep ngx-decaf-component-renderer>*>div{margin-bottom:0!important}\n"] }]
|
|
5894
6368
|
}], ctorParameters: () => [], propDecorators: { gap: [{
|
|
5895
6369
|
type: Input
|
|
5896
|
-
}], breakpoint: [{
|
|
5897
|
-
type: Input
|
|
5898
6370
|
}], grid: [{
|
|
5899
6371
|
type: Input
|
|
5900
|
-
}], match: [{
|
|
5901
|
-
type: Input
|
|
5902
6372
|
}], flexMode: [{
|
|
5903
6373
|
type: Input
|
|
5904
6374
|
}], rowCard: [{
|
|
@@ -5939,11 +6409,11 @@ let CrudFormComponent = class CrudFormComponent extends NgxFormDirective {
|
|
|
5939
6409
|
this.submitEvent.emit({
|
|
5940
6410
|
data: this.modelId,
|
|
5941
6411
|
component: 'CrudFormComponent',
|
|
5942
|
-
name:
|
|
6412
|
+
name: ComponentEventNames.SUBMIT,
|
|
5943
6413
|
});
|
|
5944
6414
|
}
|
|
5945
6415
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CrudFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5946
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: CrudFormComponent, isStandalone: true, selector: "ngx-decaf-crud-form", usesInheritance: true, ngImport: i0, template: "@if (operation !== 'read' && operation !== 'delete') {\n <form\n [class]=\"'dcf-form-grid ' + operation\" #component\n [id]=\"rendererId\"\n [formGroup]=\"formGroup\"\n (ngSubmit)=\"handleSubmit($event)\"\n novalidate\n [target]=\"target\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n <ngx-decaf-layout\n [className]=\"'dcf-crud-form-grid dcf-grid-nested '\"\n [children]=\"children || []\"\n [parentForm]=\"formGroup || parentForm\"\n [match]=\"false\"\n [gap]=\"'small'\"\n [flexMode]=\"props.flexMode || false\"\n [rows]=\"rows\"\n [cols]=\"cols\" />\n }\n @if (initialized) {\n <div class=\"dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left\">\n <div>\n <ion-button type=\"submit\" [expand]=\"action ? 'block' : 'default'\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{ action ? action : options.buttons.submit.text}}\n </ion-button>\n </div>\n @if (!action) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n Back\n </ion-button>\n </div>\n }\n </div>\n }\n\n </form>\n} @else {\n <section [class]=\"'dcf-grid dcf-grid-small dcf-child-width-1-1 dcf-form-grid ' + operation\" #component [id]=\"uid\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n @for (child of children; track $index) {\n <div class=\"dcf-form-item\">\n <ngx-decaf-component-renderer\n [tag]=\"child?.tag\"\n [projectable]=\"false\"\n [children]=\"child?.children || []\"\n [globals]=\"{props: child.props}\"\n />\n </div>\n }\n }\n </section>\n <section [class]=\"'dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left ' + operation\" [id]=\"uid\">\n @if ([OperationKeys.READ, OperationKeys.DELETE].includes(operation) && modelId) {\n <div>\n <ion-button\n (click)=\"handleDelete()\"\n color=\"danger\"\n type=\"button\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n Delete\n </ion-button>\n </div>\n\n }\n @if (operation === OperationKeys.CREATE || operation === OperationKeys.UPDATE) {\n\n <div>\n <ion-button\n type=\"submit\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{options.buttons.submit.text}}\n </ion-button>\n </div>\n }\n\n @if (options.buttons.clear) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n {{ [OperationKeys.DELETE, OperationKeys.READ, OperationKeys.UPDATE].includes(operation) ? 'Back' : options.buttons.clear?.text}}\n </ion-button>\n </div>\n\n }\n </section>\n}\n\n", styles: [".dcf-buttons-grid{margin-top:var(--dcf-margin-medium);margin-bottom:var(--dcf-margin)}@media (min-width: 577px){.dcf-buttons-grid.dcf-flex{flex-direction:row-reverse}}@media (max-width: 576px){.dcf-buttons-grid.dcf-flex>div{width:100%}.dcf-buttons-grid.dcf-flex>div+div{margin-top:1rem}.dcf-buttons-grid.dcf-flex ion-button{width:100%}}.dcf-form-grid.create,.dcf-form-grid.update{margin-top:var(--dcf-margin-small)}.dcf-form-grid .dcf-form-item{margin-top:0!important}.dcf-form-grid.read .dcf-form-item{margin-bottom:var(--dcf-margin-small)}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: LayoutComponent, selector: "ngx-decaf-layout", inputs: ["gap", "
|
|
6416
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: CrudFormComponent, isStandalone: true, selector: "ngx-decaf-crud-form", host: { properties: { "attr.id": "uid" } }, usesInheritance: true, ngImport: i0, template: "@if (operation !== 'read' && operation !== 'delete') {\n <form\n [class]=\"'dcf-form-grid ' + operation\" #component\n [id]=\"rendererId\"\n [formGroup]=\"formGroup\"\n (ngSubmit)=\"handleSubmit($event)\"\n novalidate\n [target]=\"target\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n <ngx-decaf-layout\n [className]=\"'dcf-crud-form-grid dcf-grid-nested '\"\n [children]=\"children || []\"\n [parentForm]=\"formGroup || parentForm\"\n [match]=\"match ?? false\"\n [gap]=\"'small'\"\n [flexMode]=\"props.flexMode || false\"\n [rows]=\"rows\"\n [borders]=\"borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [cols]=\"cols\" />\n }\n @if (initialized) {\n <div class=\"dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left\">\n <div>\n <ion-button type=\"submit\" [expand]=\"action ? 'block' : 'default'\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{ action ? action : options.buttons.submit.text}}\n </ion-button>\n </div>\n @if (!action) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n Back\n </ion-button>\n </div>\n }\n </div>\n }\n\n </form>\n} @else {\n <section [class]=\"'dcf-grid dcf-grid-small dcf-child-width-1-1 dcf-form-grid ' + operation\" #component [id]=\"uid\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n @for (child of children; track $index) {\n <div class=\"dcf-form-item\">\n <ngx-decaf-component-renderer\n [tag]=\"child?.tag\"\n [projectable]=\"false\"\n [children]=\"child?.children || []\"\n [globals]=\"{props: child.props}\"\n />\n </div>\n }\n }\n </section>\n <section [class]=\"'dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left ' + operation\" [id]=\"uid\">\n @if ([OperationKeys.READ, OperationKeys.DELETE].includes(operation) && modelId) {\n <div>\n <ion-button\n (click)=\"handleDelete()\"\n color=\"danger\"\n type=\"button\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n Delete\n </ion-button>\n </div>\n\n }\n @if (operation === OperationKeys.CREATE || operation === OperationKeys.UPDATE) {\n\n <div>\n <ion-button\n type=\"submit\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{options.buttons.submit.text}}\n </ion-button>\n </div>\n }\n\n @if (options.buttons.clear) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n {{ [OperationKeys.DELETE, OperationKeys.READ, OperationKeys.UPDATE].includes(operation) ? 'Back' : options.buttons.clear?.text}}\n </ion-button>\n </div>\n\n }\n </section>\n}\n\n", styles: [".dcf-buttons-grid{margin-top:var(--dcf-margin-medium);margin-bottom:var(--dcf-margin)}@media (min-width: 577px){.dcf-buttons-grid.dcf-flex{flex-direction:row-reverse}}@media (max-width: 576px){.dcf-buttons-grid.dcf-flex>div{width:100%}.dcf-buttons-grid.dcf-flex>div+div{margin-top:1rem}.dcf-buttons-grid.dcf-flex ion-button{width:100%}}.dcf-form-grid.create,.dcf-form-grid.update{margin-top:var(--dcf-margin-small)}.dcf-form-grid .dcf-form-item{margin-top:0!important}.dcf-form-grid.read .dcf-form-item{margin-bottom:var(--dcf-margin-small)}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: LayoutComponent, selector: "ngx-decaf-layout", inputs: ["gap", "grid", "flexMode", "rowCard", "maxColsLength"] }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "children", "projectable", "parent"] }, { kind: "component", type: 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: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }] }); }
|
|
5947
6417
|
};
|
|
5948
6418
|
CrudFormComponent = __decorate([
|
|
5949
6419
|
Dynamic(),
|
|
@@ -5951,9 +6421,97 @@ CrudFormComponent = __decorate([
|
|
|
5951
6421
|
], CrudFormComponent);
|
|
5952
6422
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CrudFormComponent, decorators: [{
|
|
5953
6423
|
type: Component,
|
|
5954
|
-
args: [{ standalone: true, selector: 'ngx-decaf-crud-form', imports: [ReactiveFormsModule, LayoutComponent, ComponentRendererComponent, IonButton, IonIcon], template: "@if (operation !== 'read' && operation !== 'delete') {\n <form\n [class]=\"'dcf-form-grid ' + operation\" #component\n [id]=\"rendererId\"\n [formGroup]=\"formGroup\"\n (ngSubmit)=\"handleSubmit($event)\"\n novalidate\n [target]=\"target\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n <ngx-decaf-layout\n [className]=\"'dcf-crud-form-grid dcf-grid-nested '\"\n [children]=\"children || []\"\n [parentForm]=\"formGroup || parentForm\"\n [match]=\"false\"\n [gap]=\"'small'\"\n [flexMode]=\"props.flexMode || false\"\n [rows]=\"rows\"\n [cols]=\"cols\" />\n }\n @if (initialized) {\n <div class=\"dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left\">\n <div>\n <ion-button type=\"submit\" [expand]=\"action ? 'block' : 'default'\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{ action ? action : options.buttons.submit.text}}\n </ion-button>\n </div>\n @if (!action) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n Back\n </ion-button>\n </div>\n }\n </div>\n }\n\n </form>\n} @else {\n <section [class]=\"'dcf-grid dcf-grid-small dcf-child-width-1-1 dcf-form-grid ' + operation\" #component [id]=\"uid\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n @for (child of children; track $index) {\n <div class=\"dcf-form-item\">\n <ngx-decaf-component-renderer\n [tag]=\"child?.tag\"\n [projectable]=\"false\"\n [children]=\"child?.children || []\"\n [globals]=\"{props: child.props}\"\n />\n </div>\n }\n }\n </section>\n <section [class]=\"'dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left ' + operation\" [id]=\"uid\">\n @if ([OperationKeys.READ, OperationKeys.DELETE].includes(operation) && modelId) {\n <div>\n <ion-button\n (click)=\"handleDelete()\"\n color=\"danger\"\n type=\"button\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n Delete\n </ion-button>\n </div>\n\n }\n @if (operation === OperationKeys.CREATE || operation === OperationKeys.UPDATE) {\n\n <div>\n <ion-button\n type=\"submit\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{options.buttons.submit.text}}\n </ion-button>\n </div>\n }\n\n @if (options.buttons.clear) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n {{ [OperationKeys.DELETE, OperationKeys.READ, OperationKeys.UPDATE].includes(operation) ? 'Back' : options.buttons.clear?.text}}\n </ion-button>\n </div>\n\n }\n </section>\n}\n\n", styles: [".dcf-buttons-grid{margin-top:var(--dcf-margin-medium);margin-bottom:var(--dcf-margin)}@media (min-width: 577px){.dcf-buttons-grid.dcf-flex{flex-direction:row-reverse}}@media (max-width: 576px){.dcf-buttons-grid.dcf-flex>div{width:100%}.dcf-buttons-grid.dcf-flex>div+div{margin-top:1rem}.dcf-buttons-grid.dcf-flex ion-button{width:100%}}.dcf-form-grid.create,.dcf-form-grid.update{margin-top:var(--dcf-margin-small)}.dcf-form-grid .dcf-form-item{margin-top:0!important}.dcf-form-grid.read .dcf-form-item{margin-bottom:var(--dcf-margin-small)}\n"] }]
|
|
6424
|
+
args: [{ standalone: true, selector: 'ngx-decaf-crud-form', imports: [ReactiveFormsModule, LayoutComponent, ComponentRendererComponent, IonButton, IonIcon], host: { '[attr.id]': 'uid' }, template: "@if (operation !== 'read' && operation !== 'delete') {\n <form\n [class]=\"'dcf-form-grid ' + operation\" #component\n [id]=\"rendererId\"\n [formGroup]=\"formGroup\"\n (ngSubmit)=\"handleSubmit($event)\"\n novalidate\n [target]=\"target\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n <ngx-decaf-layout\n [className]=\"'dcf-crud-form-grid dcf-grid-nested '\"\n [children]=\"children || []\"\n [parentForm]=\"formGroup || parentForm\"\n [match]=\"match ?? false\"\n [gap]=\"'small'\"\n [flexMode]=\"props.flexMode || false\"\n [rows]=\"rows\"\n [borders]=\"borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [cols]=\"cols\" />\n }\n @if (initialized) {\n <div class=\"dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left\">\n <div>\n <ion-button type=\"submit\" [expand]=\"action ? 'block' : 'default'\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{ action ? action : options.buttons.submit.text}}\n </ion-button>\n </div>\n @if (!action) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n Back\n </ion-button>\n </div>\n }\n </div>\n }\n\n </form>\n} @else {\n <section [class]=\"'dcf-grid dcf-grid-small dcf-child-width-1-1 dcf-form-grid ' + operation\" #component [id]=\"uid\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n @for (child of children; track $index) {\n <div class=\"dcf-form-item\">\n <ngx-decaf-component-renderer\n [tag]=\"child?.tag\"\n [projectable]=\"false\"\n [children]=\"child?.children || []\"\n [globals]=\"{props: child.props}\"\n />\n </div>\n }\n }\n </section>\n <section [class]=\"'dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left ' + operation\" [id]=\"uid\">\n @if ([OperationKeys.READ, OperationKeys.DELETE].includes(operation) && modelId) {\n <div>\n <ion-button\n (click)=\"handleDelete()\"\n color=\"danger\"\n type=\"button\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n Delete\n </ion-button>\n </div>\n\n }\n @if (operation === OperationKeys.CREATE || operation === OperationKeys.UPDATE) {\n\n <div>\n <ion-button\n type=\"submit\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{options.buttons.submit.text}}\n </ion-button>\n </div>\n }\n\n @if (options.buttons.clear) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n {{ [OperationKeys.DELETE, OperationKeys.READ, OperationKeys.UPDATE].includes(operation) ? 'Back' : options.buttons.clear?.text}}\n </ion-button>\n </div>\n\n }\n </section>\n}\n\n", styles: [".dcf-buttons-grid{margin-top:var(--dcf-margin-medium);margin-bottom:var(--dcf-margin)}@media (min-width: 577px){.dcf-buttons-grid.dcf-flex{flex-direction:row-reverse}}@media (max-width: 576px){.dcf-buttons-grid.dcf-flex>div{width:100%}.dcf-buttons-grid.dcf-flex>div+div{margin-top:1rem}.dcf-buttons-grid.dcf-flex ion-button{width:100%}}.dcf-form-grid.create,.dcf-form-grid.update{margin-top:var(--dcf-margin-small)}.dcf-form-grid .dcf-form-item{margin-top:0!important}.dcf-form-grid.read .dcf-form-item{margin-bottom:var(--dcf-margin-small)}\n"] }]
|
|
5955
6425
|
}], ctorParameters: () => [] });
|
|
5956
6426
|
|
|
6427
|
+
class NgxSvgDirective {
|
|
6428
|
+
constructor() {
|
|
6429
|
+
this.mediaService = inject(NgxMediaService);
|
|
6430
|
+
this.element = inject(ElementRef);
|
|
6431
|
+
this.http = inject(HttpClient);
|
|
6432
|
+
}
|
|
6433
|
+
ngOnInit() {
|
|
6434
|
+
this.path = this.path?.trim() || this.element?.nativeElement?.getAttribute('src')?.trim() || '';
|
|
6435
|
+
if (this.path)
|
|
6436
|
+
this.mediaService.loadSvgObserver(this.http, this.path, this.element.nativeElement);
|
|
6437
|
+
}
|
|
6438
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgxSvgDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
6439
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.9", type: NgxSvgDirective, isStandalone: true, selector: "[ngx-decaf-svg]", inputs: { path: ["ngx-decaf-svg", "path"] }, ngImport: i0 }); }
|
|
6440
|
+
}
|
|
6441
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgxSvgDirective, decorators: [{
|
|
6442
|
+
type: Directive,
|
|
6443
|
+
args: [{
|
|
6444
|
+
selector: '[ngx-decaf-svg]',
|
|
6445
|
+
standalone: true
|
|
6446
|
+
}]
|
|
6447
|
+
}], propDecorators: { path: [{
|
|
6448
|
+
type: Input,
|
|
6449
|
+
args: ['ngx-decaf-svg']
|
|
6450
|
+
}] } });
|
|
6451
|
+
|
|
6452
|
+
let IconComponent = class IconComponent {
|
|
6453
|
+
constructor() {
|
|
6454
|
+
this.color = "dark";
|
|
6455
|
+
this.slot = 'icon-only';
|
|
6456
|
+
this.button = false;
|
|
6457
|
+
this.buttonFill = 'clear';
|
|
6458
|
+
this.buttonShape = 'round';
|
|
6459
|
+
this.size = 'default';
|
|
6460
|
+
this.type = 'ionic';
|
|
6461
|
+
this.isSvg = false;
|
|
6462
|
+
this.initialized = false;
|
|
6463
|
+
this.inline = false;
|
|
6464
|
+
this.isDarkMode = false;
|
|
6465
|
+
this.mediaService = new NgxMediaService();
|
|
6466
|
+
addIcons(allIcons);
|
|
6467
|
+
}
|
|
6468
|
+
ngOnInit() {
|
|
6469
|
+
if (this.button)
|
|
6470
|
+
this.slot = 'icon-only';
|
|
6471
|
+
if (this.name?.includes('.')) {
|
|
6472
|
+
this.type = 'image';
|
|
6473
|
+
this.isSvg = this.name.endsWith('.svg');
|
|
6474
|
+
}
|
|
6475
|
+
this.initialized = true;
|
|
6476
|
+
}
|
|
6477
|
+
ngAfterViewInit() {
|
|
6478
|
+
this.mediaService.isDarkMode().subscribe(isDark => {
|
|
6479
|
+
this.isDarkMode = isDark;
|
|
6480
|
+
});
|
|
6481
|
+
}
|
|
6482
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: IconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6483
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: IconComponent, isStandalone: true, selector: "ngx-decaf-icon", inputs: { name: "name", color: "color", slot: "slot", button: "button", buttonFill: "buttonFill", buttonShape: "buttonShape", width: "width", size: "size", inline: "inline" }, host: { properties: { "attr.id": "uid", "attr.aria-hidden": "!button" } }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div class=\"dcf-icon\" #component>\n @if (initialized) {\n @if (button) {\n <ion-button [fill]=\"buttonFill\" [shape]=\"buttonShape\" [color]=\"isDarkMode ? 'light' : color\" [size]=\"size\">\n @if (type === \"image\") {\n @if (isSvg) {\n <span\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [class]=\"color ? 'dcf-color-' + color : ''\"\n [style.width]=\"width\"\n [ngx-decaf-svg]=\"name\"\n >\n ></span\n >\n } @else {\n <img\n aria-hidden=\"true\"\n [alt]=\"name\"\n [title]=\"name\"\n [slot]=\"slot\"\n [src]=\"name\"\n [style.width]=\"width\"\n title=\"icon\"\n />\n }\n } @else {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [ios]=\"name\"\n [md]=\"name\"\n [color]=\"isDarkMode ? 'light' : color\"\n [name]=\"name\"\n />\n }\n </ion-button>\n } @else {\n @if (type === \"image\") {\n @if (isSvg) {\n <span\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [class]=\"color ? 'dcf-color-' + color : ''\"\n [style.width]=\"width\"\n [ngx-decaf-svg]=\"name\"\n >\n </span>\n } @else {\n <img\n aria-hidden=\"true\"\n [alt]=\"name\"\n [title]=\"name\"\n [slot]=\"slot\"\n [src]=\"name\"\n [style.width]=\"width\"\n title=\"icon\"\n />\n }\n }\n @if (type === \"ionic\") {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [ios]=\"name\"\n [md]=\"name\"\n [size]=\"size\"\n [color]=\"isDarkMode ? 'light' : color\"\n [name]=\"name\"\n />\n }\n }\n }\n</div>\n", styles: ["::ng-deep .dcf-icon.dcf-palette-dark ion-icon{color:var(--dcf-text-color)!important}::ng-deep .dcf-icon.dcf-palette-dark svg{fill:var(--dcf-text-color);fill-opacity:.25!important;stroke:var(--dcf-text-color)!important}::ng-deep .dcf-icon.dcf-palette-dark svg *{fill:var(--dcf-color-primary)!important;stroke:var(--dcf-color-gray-1)!important}ion-button{cursor:pointer!important}.dcf-icon ion-icon:not([size]){font-size:1.35rem!important}\n"], dependencies: [{ kind: "directive", type: NgxSvgDirective, selector: "[ngx-decaf-svg]", inputs: ["ngx-decaf-svg"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }] }); }
|
|
6484
|
+
};
|
|
6485
|
+
IconComponent = __decorate([
|
|
6486
|
+
Dynamic(),
|
|
6487
|
+
__metadata("design:paramtypes", [])
|
|
6488
|
+
], IconComponent);
|
|
6489
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: IconComponent, decorators: [{
|
|
6490
|
+
type: Component,
|
|
6491
|
+
args: [{ selector: 'ngx-decaf-icon', imports: [NgxSvgDirective, IonIcon, IonButton], standalone: true, host: { '[attr.id]': 'uid', '[attr.aria-hidden]': '!button' }, template: "<div class=\"dcf-icon\" #component>\n @if (initialized) {\n @if (button) {\n <ion-button [fill]=\"buttonFill\" [shape]=\"buttonShape\" [color]=\"isDarkMode ? 'light' : color\" [size]=\"size\">\n @if (type === \"image\") {\n @if (isSvg) {\n <span\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [class]=\"color ? 'dcf-color-' + color : ''\"\n [style.width]=\"width\"\n [ngx-decaf-svg]=\"name\"\n >\n ></span\n >\n } @else {\n <img\n aria-hidden=\"true\"\n [alt]=\"name\"\n [title]=\"name\"\n [slot]=\"slot\"\n [src]=\"name\"\n [style.width]=\"width\"\n title=\"icon\"\n />\n }\n } @else {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [ios]=\"name\"\n [md]=\"name\"\n [color]=\"isDarkMode ? 'light' : color\"\n [name]=\"name\"\n />\n }\n </ion-button>\n } @else {\n @if (type === \"image\") {\n @if (isSvg) {\n <span\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [class]=\"color ? 'dcf-color-' + color : ''\"\n [style.width]=\"width\"\n [ngx-decaf-svg]=\"name\"\n >\n </span>\n } @else {\n <img\n aria-hidden=\"true\"\n [alt]=\"name\"\n [title]=\"name\"\n [slot]=\"slot\"\n [src]=\"name\"\n [style.width]=\"width\"\n title=\"icon\"\n />\n }\n }\n @if (type === \"ionic\") {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [ios]=\"name\"\n [md]=\"name\"\n [size]=\"size\"\n [color]=\"isDarkMode ? 'light' : color\"\n [name]=\"name\"\n />\n }\n }\n }\n</div>\n", styles: ["::ng-deep .dcf-icon.dcf-palette-dark ion-icon{color:var(--dcf-text-color)!important}::ng-deep .dcf-icon.dcf-palette-dark svg{fill:var(--dcf-text-color);fill-opacity:.25!important;stroke:var(--dcf-text-color)!important}::ng-deep .dcf-icon.dcf-palette-dark svg *{fill:var(--dcf-color-primary)!important;stroke:var(--dcf-color-gray-1)!important}ion-button{cursor:pointer!important}.dcf-icon ion-icon:not([size]){font-size:1.35rem!important}\n"] }]
|
|
6492
|
+
}], ctorParameters: () => [], propDecorators: { component: [{
|
|
6493
|
+
type: ViewChild,
|
|
6494
|
+
args: ['component', { read: ElementRef, static: false }]
|
|
6495
|
+
}], name: [{
|
|
6496
|
+
type: Input
|
|
6497
|
+
}], color: [{
|
|
6498
|
+
type: Input
|
|
6499
|
+
}], slot: [{
|
|
6500
|
+
type: Input
|
|
6501
|
+
}], button: [{
|
|
6502
|
+
type: Input
|
|
6503
|
+
}], buttonFill: [{
|
|
6504
|
+
type: Input
|
|
6505
|
+
}], buttonShape: [{
|
|
6506
|
+
type: Input
|
|
6507
|
+
}], width: [{
|
|
6508
|
+
type: Input
|
|
6509
|
+
}], size: [{
|
|
6510
|
+
type: Input
|
|
6511
|
+
}], inline: [{
|
|
6512
|
+
type: Input
|
|
6513
|
+
}] } });
|
|
6514
|
+
|
|
5957
6515
|
/**
|
|
5958
6516
|
* @description Component for displaying empty state messages with optional actions.
|
|
5959
6517
|
* @summary This component provides a standardized way to display empty state messages
|
|
@@ -6074,13 +6632,13 @@ let EmptyStateComponent = class EmptyStateComponent extends CardComponent {
|
|
|
6074
6632
|
* @default 'large'
|
|
6075
6633
|
* @memberOf EmptyStateComponent
|
|
6076
6634
|
*/
|
|
6077
|
-
this.iconSize =
|
|
6635
|
+
this.iconSize = ElementSizes.large;
|
|
6078
6636
|
/**
|
|
6079
6637
|
* @description The color of the displayed icon.
|
|
6080
6638
|
* @summary Specifies the color for the icon using Ionic's predefined color system.
|
|
6081
6639
|
* This allows the icon to match the application's color scheme.
|
|
6082
6640
|
*
|
|
6083
|
-
* @type {
|
|
6641
|
+
* @type {string}
|
|
6084
6642
|
* @default 'medium'
|
|
6085
6643
|
* @memberOf EmptyStateComponent
|
|
6086
6644
|
*/
|
|
@@ -6131,8 +6689,7 @@ let EmptyStateComponent = class EmptyStateComponent extends CardComponent {
|
|
|
6131
6689
|
* @memberOf EmptyStateComponent
|
|
6132
6690
|
*/
|
|
6133
6691
|
this.enableCreationByModelRoute = false;
|
|
6134
|
-
|
|
6135
|
-
this.type = 'default';
|
|
6692
|
+
this.type = 'clear';
|
|
6136
6693
|
this.componentName = "EmptyStateComponent";
|
|
6137
6694
|
this.enableDarkMode = true;
|
|
6138
6695
|
}
|
|
@@ -6167,8 +6724,8 @@ let EmptyStateComponent = class EmptyStateComponent extends CardComponent {
|
|
|
6167
6724
|
super.ngOnInit();
|
|
6168
6725
|
this.initialize();
|
|
6169
6726
|
this.showIcon = stringToBoolean(this.showIcon);
|
|
6170
|
-
this.titleColor = `dcf-title color-${this.titleColor}`;
|
|
6171
|
-
this.subtitleColor = `dcf-subtitle color-${this.
|
|
6727
|
+
this.titleColor = `dcf-title dcf-color-${this.titleColor}`;
|
|
6728
|
+
this.subtitleColor = `dcf-subtitle dcf-color-${this.subtitleColor}`;
|
|
6172
6729
|
if (this.searchValue)
|
|
6173
6730
|
this.searchSubtitle = await this.getSearchSubtitle(this.subtitle);
|
|
6174
6731
|
if (!this.buttonLink && this.model && this.route)
|
|
@@ -6244,7 +6801,7 @@ let EmptyStateComponent = class EmptyStateComponent extends CardComponent {
|
|
|
6244
6801
|
return this.sanitizer.bypassSecurityTrustHtml(result);
|
|
6245
6802
|
}
|
|
6246
6803
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: EmptyStateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6247
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: EmptyStateComponent, isStandalone: true, selector: "ngx-decaf-empty-state", inputs: { title: "title", titleColor: "titleColor", subtitle: "subtitle", subtitleColor: "subtitleColor", showIcon: "showIcon", icon: "icon", iconSize: "iconSize", iconColor: "iconColor", buttonLink: "buttonLink", buttonText: "buttonText", buttonFill: "buttonFill", buttonColor: "buttonColor", buttonSize: "buttonSize", searchValue: "searchValue" }, usesInheritance: true, ngImport: i0, template: " <ngx-decaf-card [className]=\"className\">\n
|
|
6804
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: EmptyStateComponent, isStandalone: true, selector: "ngx-decaf-empty-state", inputs: { title: "title", titleColor: "titleColor", subtitle: "subtitle", subtitleColor: "subtitleColor", showIcon: "showIcon", icon: "icon", iconSize: "iconSize", iconColor: "iconColor", buttonLink: "buttonLink", buttonText: "buttonText", buttonFill: "buttonFill", buttonColor: "buttonColor", buttonSize: "buttonSize", searchValue: "searchValue" }, usesInheritance: true, ngImport: i0, template: "<div class=\"decaf-empty-state-component\" #component>\n <ngx-decaf-card [className]=\"className\">\n @if (icon && showIcon) {\n <div class=\"dcf-icon-container\">\n <ngx-decaf-icon\n aria-hidden=\"true\"\n [name]=\"icon\"\n [size]=\"iconSize\"\n [color]=\"!this.isDarkMode ? iconColor : ''\"\n />\n </div>\n }\n @if (title) {\n <h4 class=\"dcf-ititle\" [class]=\"isDarkMode ? 'light' : titleColor\" [innerHTML]=\"title\"></h4>\n }\n @if (subtitle) {\n <p [class]=\"isDarkMode ? 'light' : subtitleColor\" [innerHTML]=\"searchValue ? searchSubtitle : subtitle\"></p>\n }\n @if (!enableCreationByModelRoute) {\n @if (buttonLink && buttonText) {\n <div>\n <ion-button\n [size]=\"buttonSize\"\n [fill]=\"buttonFill\"\n [color]=\"buttonColor\"\n (click)=\"handleClick()\">\n {{ buttonText }}\n </ion-button>\n </div>\n }\n } @else {\n\n <div>\n <ion-button\n class=\"dcf-margin-top\"\n [size]=\"buttonSize\"\n [fill]=\"buttonFill\"\n [color]=\"buttonColor\"\n (click)=\"changeOperation(OperationKeys.CREATE)\" fill=\"clear\">\n {{ buttonText?.length ? buttonText : locale + '.button_create' | translate }}\n </ion-button>\n </div>\n\n }\n </ngx-decaf-card>\n</div>\n", styles: [":host{text-align:center}:host ion-button{margin-top:.75rem}:host .dcf-icon-container{transform:scale(1.25);opacity:.75;margin-top:1.25rem!important;margin-bottom:.5rem!important}:host .dcf-ititle{font-weight:600!important}:host .dcf-subtitle{font-weight:500!important}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "ngx-decaf-icon", inputs: ["name", "color", "slot", "button", "buttonFill", "buttonShape", "width", "size", "inline"] }, { kind: "component", type: 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: CardComponent, selector: "ngx-decaf-card", inputs: ["type", "title", "body", "subtitle", "color", "separator", "borders", "inlineContent", "inlineContentPosition"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
6248
6805
|
};
|
|
6249
6806
|
EmptyStateComponent = __decorate([
|
|
6250
6807
|
Dynamic(),
|
|
@@ -6253,11 +6810,11 @@ EmptyStateComponent = __decorate([
|
|
|
6253
6810
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: EmptyStateComponent, decorators: [{
|
|
6254
6811
|
type: Component,
|
|
6255
6812
|
args: [{ selector: 'ngx-decaf-empty-state', standalone: true, imports: [
|
|
6256
|
-
|
|
6813
|
+
IconComponent,
|
|
6257
6814
|
TranslatePipe,
|
|
6258
6815
|
IonButton,
|
|
6259
6816
|
CardComponent
|
|
6260
|
-
], template: " <ngx-decaf-card [className]=\"className\">\n
|
|
6817
|
+
], template: "<div class=\"decaf-empty-state-component\" #component>\n <ngx-decaf-card [className]=\"className\">\n @if (icon && showIcon) {\n <div class=\"dcf-icon-container\">\n <ngx-decaf-icon\n aria-hidden=\"true\"\n [name]=\"icon\"\n [size]=\"iconSize\"\n [color]=\"!this.isDarkMode ? iconColor : ''\"\n />\n </div>\n }\n @if (title) {\n <h4 class=\"dcf-ititle\" [class]=\"isDarkMode ? 'light' : titleColor\" [innerHTML]=\"title\"></h4>\n }\n @if (subtitle) {\n <p [class]=\"isDarkMode ? 'light' : subtitleColor\" [innerHTML]=\"searchValue ? searchSubtitle : subtitle\"></p>\n }\n @if (!enableCreationByModelRoute) {\n @if (buttonLink && buttonText) {\n <div>\n <ion-button\n [size]=\"buttonSize\"\n [fill]=\"buttonFill\"\n [color]=\"buttonColor\"\n (click)=\"handleClick()\">\n {{ buttonText }}\n </ion-button>\n </div>\n }\n } @else {\n\n <div>\n <ion-button\n class=\"dcf-margin-top\"\n [size]=\"buttonSize\"\n [fill]=\"buttonFill\"\n [color]=\"buttonColor\"\n (click)=\"changeOperation(OperationKeys.CREATE)\" fill=\"clear\">\n {{ buttonText?.length ? buttonText : locale + '.button_create' | translate }}\n </ion-button>\n </div>\n\n }\n </ngx-decaf-card>\n</div>\n", styles: [":host{text-align:center}:host ion-button{margin-top:.75rem}:host .dcf-icon-container{transform:scale(1.25);opacity:.75;margin-top:1.25rem!important;margin-bottom:.5rem!important}:host .dcf-ititle{font-weight:600!important}:host .dcf-subtitle{font-weight:500!important}\n"] }]
|
|
6261
6818
|
}], ctorParameters: () => [], propDecorators: { title: [{
|
|
6262
6819
|
type: Input
|
|
6263
6820
|
}], titleColor: [{
|
|
@@ -6452,11 +7009,44 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
|
|
|
6452
7009
|
* @summary Numeric limit that controls how many items can be added when `multiple` is true.
|
|
6453
7010
|
* When set to Infinity there is no limit.
|
|
6454
7011
|
*
|
|
6455
|
-
* @type {number}
|
|
6456
|
-
* @default Infinity
|
|
7012
|
+
* @type {number}
|
|
7013
|
+
* @default Infinity
|
|
7014
|
+
* @memberOf FieldsetComponent
|
|
7015
|
+
*/
|
|
7016
|
+
this.max = undefined;
|
|
7017
|
+
/**
|
|
7018
|
+
* @description Maximum allowed items in the fieldset.
|
|
7019
|
+
* @summary Numeric limit that controls how many items can be added when `multiple` is true.
|
|
7020
|
+
* When set to Infinity there is no limit.
|
|
7021
|
+
*
|
|
7022
|
+
* @type {number}
|
|
7023
|
+
* @default Infinity
|
|
7024
|
+
* @memberOf FieldsetComponent
|
|
7025
|
+
*/
|
|
7026
|
+
this.required = false;
|
|
7027
|
+
/**
|
|
7028
|
+
* @description Determines if the fieldset items can be reordered.
|
|
7029
|
+
* @summary Boolean flag that enables or disables the drag-and-drop reordering functionality
|
|
7030
|
+
* for the items within the fieldset. When set to true, users can rearrange the order
|
|
7031
|
+
* of items using drag-and-drop gestures. This is particularly useful for managing
|
|
7032
|
+
* lists where the order of items is significant.
|
|
7033
|
+
*
|
|
7034
|
+
* @type {boolean}
|
|
7035
|
+
* @default true
|
|
7036
|
+
* @memberOf FieldsetComponent
|
|
7037
|
+
*/
|
|
7038
|
+
this.ordenable = true;
|
|
7039
|
+
/**
|
|
7040
|
+
* @description Determines if the fieldset items can be edited by the user.
|
|
7041
|
+
* @summary Boolean flag that enables or disables the editing functionality
|
|
7042
|
+
* for the items within the fieldset. When set to true, users can modify the items.
|
|
7043
|
+
*
|
|
7044
|
+
* @type {boolean}
|
|
7045
|
+
* @default true
|
|
6457
7046
|
* @memberOf FieldsetComponent
|
|
7047
|
+
* @default true
|
|
6458
7048
|
*/
|
|
6459
|
-
this.
|
|
7049
|
+
this.editable = true;
|
|
6460
7050
|
addIcons({ alertCircleOutline, addOutline, trashOutline, createOutline });
|
|
6461
7051
|
}
|
|
6462
7052
|
/**
|
|
@@ -6474,21 +7064,38 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
|
|
|
6474
7064
|
this.multiple = false;
|
|
6475
7065
|
this.buttonLabel = this.translateService.instant(this.locale + '.add');
|
|
6476
7066
|
this.buttonCancelLabel = this.translateService.instant(this.locale + '.cancel');
|
|
7067
|
+
if (!this.multiple)
|
|
7068
|
+
this.ordenable = false;
|
|
6477
7069
|
if ([OperationKeys.CREATE, OperationKeys.UPDATE].includes(this.operation)) {
|
|
6478
7070
|
if (!this.formGroup) {
|
|
6479
|
-
if (this.parentForm instanceof FormGroup)
|
|
6480
|
-
|
|
7071
|
+
if (this.parentForm instanceof FormGroup) {
|
|
7072
|
+
// iterate on childOf path to get correct formGroup
|
|
7073
|
+
const parts = this.childOf.split('.');
|
|
7074
|
+
let formGroup = this.parentForm;
|
|
7075
|
+
for (const part of parts)
|
|
7076
|
+
formGroup = formGroup.controls[part];
|
|
7077
|
+
this.formGroup = formGroup;
|
|
7078
|
+
if (this.formGroup instanceof FormGroup)
|
|
7079
|
+
this.formGroup = this.formGroup.parent;
|
|
7080
|
+
}
|
|
6481
7081
|
if (!this.formGroup && this.parentForm instanceof FormArray)
|
|
6482
7082
|
this.formGroup = this.parentForm;
|
|
6483
7083
|
if (!this.formGroup && this.children[0]?.['formGroup'] instanceof FormGroup)
|
|
6484
7084
|
this.formGroup = this.children[0]?.['formGroup'].parent;
|
|
7085
|
+
if (this.formGroup && !(this.formGroup instanceof FormArray))
|
|
7086
|
+
this.formGroup = this.formGroup?.parent;
|
|
6485
7087
|
}
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
7088
|
+
}
|
|
7089
|
+
if (this.multiple) {
|
|
7090
|
+
this.formGroup?.setErrors(null);
|
|
7091
|
+
this.formGroup?.disable();
|
|
7092
|
+
if (this.required) {
|
|
7093
|
+
this.collapsable = false;
|
|
7094
|
+
this.activePage = this.getActivePage();
|
|
7095
|
+
}
|
|
7096
|
+
}
|
|
7097
|
+
else {
|
|
7098
|
+
this.activePage = this.getActivePage();
|
|
6492
7099
|
}
|
|
6493
7100
|
this.initialized = true;
|
|
6494
7101
|
}
|
|
@@ -6523,26 +7130,25 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
|
|
|
6523
7130
|
*/
|
|
6524
7131
|
ngAfterViewInit() {
|
|
6525
7132
|
super.ngAfterViewInit();
|
|
6526
|
-
if (!this.collapsable)
|
|
6527
|
-
|
|
6528
|
-
if (this.operation === OperationKeys.READ || this.operation === OperationKeys.DELETE) {
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
}
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
}
|
|
7133
|
+
// if (!this.collapsable)
|
|
7134
|
+
// this.isOpen = true;
|
|
7135
|
+
// if (this.operation === OperationKeys.READ || this.operation === OperationKeys.DELETE) {
|
|
7136
|
+
// this.isOpen = true;
|
|
7137
|
+
// // hidden remove button
|
|
7138
|
+
// const accordionElement = this.component?.nativeElement.querySelector('ion-accordion-group');
|
|
7139
|
+
// if (accordionElement)
|
|
7140
|
+
// this.renderer.setAttribute(accordionElement, 'value', 'open');
|
|
7141
|
+
// } else {
|
|
7142
|
+
// const inputs = this.component?.nativeElement.querySelectorAll('.dcf-field-required');
|
|
7143
|
+
// this.isRequired = inputs?.length > 0;
|
|
7144
|
+
// if (this.isRequired) {
|
|
7145
|
+
// this.accordionComponent.value = 'open';
|
|
7146
|
+
// this.handleAccordionToggle();
|
|
7147
|
+
// }
|
|
7148
|
+
// }
|
|
6543
7149
|
// if (!(this.formGroup instanceof FormArray))
|
|
6544
7150
|
// this.formGroup = (this.formGroup as FormGroup)
|
|
6545
|
-
this.changeDetectorRef.detectChanges();
|
|
7151
|
+
// this.changeDetectorRef.detectChanges();
|
|
6546
7152
|
}
|
|
6547
7153
|
/**
|
|
6548
7154
|
* @description Handles removal of the fieldset with slide animation.
|
|
@@ -6555,15 +7161,23 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
|
|
|
6555
7161
|
* @returns {void}
|
|
6556
7162
|
* @memberOf FieldsetComponent
|
|
6557
7163
|
*/
|
|
6558
|
-
|
|
6559
|
-
event
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
|
|
7164
|
+
handleClear(event) {
|
|
7165
|
+
if (event)
|
|
7166
|
+
event.stopImmediatePropagation();
|
|
7167
|
+
this.formGroup?.disable();
|
|
7168
|
+
this.items = [];
|
|
7169
|
+
this.value = undefined;
|
|
7170
|
+
this.activePage = undefined;
|
|
7171
|
+
this.activeFormGroupIndex = 0;
|
|
7172
|
+
this.accordionComponent.value = '';
|
|
7173
|
+
this.changeDetectorRef.detectChanges();
|
|
7174
|
+
// this.component.nativeElement.classList.add('dcf-animation', 'dcf-animation-slide-top-medium', 'dcf-animation-reverse', 'dcf-animation-fast');
|
|
7175
|
+
// setTimeout(() => {
|
|
7176
|
+
// // Use Renderer2 to safely remove the element
|
|
7177
|
+
// const parent = this.renderer.parentNode(this.component.nativeElement);
|
|
7178
|
+
// if (parent)
|
|
7179
|
+
// this.renderer.removeChild(parent, this.component.nativeElement);
|
|
7180
|
+
// }, 150);
|
|
6567
7181
|
}
|
|
6568
7182
|
/**
|
|
6569
7183
|
* @description Handles creating new items or triggering group addition events.
|
|
@@ -6588,6 +7202,10 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
|
|
|
6588
7202
|
async handleCreateItem(event) {
|
|
6589
7203
|
if (event && event instanceof CustomEvent)
|
|
6590
7204
|
event.stopImmediatePropagation();
|
|
7205
|
+
if (!this.activePage) {
|
|
7206
|
+
this.activePage = this.getActivePage();
|
|
7207
|
+
return;
|
|
7208
|
+
}
|
|
6591
7209
|
const formGroup = this.activeFormGroup;
|
|
6592
7210
|
const value = formGroup.value;
|
|
6593
7211
|
const hasSomeValue = this.hasValue(value);
|
|
@@ -6603,7 +7221,7 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
|
|
|
6603
7221
|
this.setValue();
|
|
6604
7222
|
NgxFormService.addGroupToParent(formGroup.parent);
|
|
6605
7223
|
this.activeFormGroupIndex = formGroup.parent.length - 1;
|
|
6606
|
-
this.
|
|
7224
|
+
this.activePage = this.getActivePage();
|
|
6607
7225
|
}
|
|
6608
7226
|
else {
|
|
6609
7227
|
this.isUniqueError = typeof value === ReservedModels.OBJECT ?
|
|
@@ -6620,6 +7238,7 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
|
|
|
6620
7238
|
if (formGroup) {
|
|
6621
7239
|
this.updatingItem = Object.assign({}, formGroup.value || {}, { index });
|
|
6622
7240
|
this.activeFormGroupIndex = index;
|
|
7241
|
+
this.activePage = this.getActivePage();
|
|
6623
7242
|
}
|
|
6624
7243
|
}
|
|
6625
7244
|
/**
|
|
@@ -6660,8 +7279,13 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
|
|
|
6660
7279
|
formArray.removeAt(index);
|
|
6661
7280
|
}
|
|
6662
7281
|
this.setValue();
|
|
6663
|
-
if (this.
|
|
6664
|
-
|
|
7282
|
+
if (this.items.length > 0) {
|
|
7283
|
+
if (this.activeFormGroupIndex > 0)
|
|
7284
|
+
this.activeFormGroupIndex = this.activeFormGroupIndex - 1;
|
|
7285
|
+
}
|
|
7286
|
+
else {
|
|
7287
|
+
this.handleClear();
|
|
7288
|
+
}
|
|
6665
7289
|
}
|
|
6666
7290
|
/**
|
|
6667
7291
|
* @description Handles reordering of items within the fieldset list.
|
|
@@ -6740,7 +7364,7 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
|
|
|
6740
7364
|
handleAccordionToggle(event) {
|
|
6741
7365
|
if (event)
|
|
6742
7366
|
event.stopImmediatePropagation();
|
|
6743
|
-
if (!this.collapsable) {
|
|
7367
|
+
if (!this.collapsable || this.isRequired) {
|
|
6744
7368
|
this.isOpen = true;
|
|
6745
7369
|
}
|
|
6746
7370
|
else {
|
|
@@ -6758,15 +7382,32 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
|
|
|
6758
7382
|
* error state and accordion visibility accordingly.
|
|
6759
7383
|
*
|
|
6760
7384
|
* @param {CustomEvent} event - Custom event containing validation error details
|
|
6761
|
-
* @returns {
|
|
7385
|
+
* @returns {UIModelMetadata[] | undefined}
|
|
6762
7386
|
* @memberOf FieldsetComponent
|
|
6763
7387
|
*/
|
|
6764
|
-
handleValidationError(event) {
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
|
|
6768
|
-
|
|
6769
|
-
|
|
7388
|
+
// handleValidationError(event: CustomEvent): void {
|
|
7389
|
+
// event.stopImmediatePropagation();
|
|
7390
|
+
// const {hasErrors} = event.detail;
|
|
7391
|
+
// this.isOpen = this.hasValidationErrors = hasErrors;
|
|
7392
|
+
// if (hasErrors)
|
|
7393
|
+
// this.accordionComponent.value = 'open';
|
|
7394
|
+
// }
|
|
7395
|
+
getActivePage() {
|
|
7396
|
+
this.activePage = undefined;
|
|
7397
|
+
this.isOpen = true;
|
|
7398
|
+
this.accordionComponent.value = 'open';
|
|
7399
|
+
this.changeDetectorRef.detectChanges();
|
|
7400
|
+
this.timerSubscription = timer(10).subscribe(() => {
|
|
7401
|
+
this.children = this.children.map(child => {
|
|
7402
|
+
if (!child.props)
|
|
7403
|
+
child.props = {};
|
|
7404
|
+
child.props = Object.assign(child.props, { activeFormGroup: this.activeFormGroupIndex, multiple: this.multiple });
|
|
7405
|
+
return child;
|
|
7406
|
+
});
|
|
7407
|
+
});
|
|
7408
|
+
if (this.multiple)
|
|
7409
|
+
this.getFormArrayIndex(this.activeFormGroupIndex);
|
|
7410
|
+
return this.children;
|
|
6770
7411
|
}
|
|
6771
7412
|
/**
|
|
6772
7413
|
* @description Processes and stores a new or updated value in the fieldset.
|
|
@@ -6820,7 +7461,7 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
|
|
|
6820
7461
|
return this.mapper;
|
|
6821
7462
|
}
|
|
6822
7463
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FieldsetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6823
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: FieldsetComponent, isStandalone: true, selector: "ngx-decaf-fieldset", inputs: { formControl: "formControl", collapsable: "collapsable", customTypes: "customTypes", title: "title", description: "description", multiple: "multiple", value: "value", borders: "borders", max: "max" }, viewQueries: [{ propertyName: "accordionComponent", first: true, predicate: ["accordionComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "\n\n<fieldset\n (fieldsetAddGroupEvent)=\"handleCreateItem($event)\"\n [class]=\"'dcf-fieldset-component ' + operation\"\n [class.dcf-blank]=\"!borders\"\n [class.open]=\"isOpen\"\n [class.not-collapsable]=\"!collapsable\"\n #component>\n <div class=\"dcf-width-1-1\">\n @if (!collapsable) {\n <legend class=\"dcf-title\">{{ (title ? title : name) | translate }}</legend>\n }\n <ion-accordion-group class=\"dcf-width-1-1\" [class.open]=\"isOpen\" [class.hasValidationErrors]=\"hasValidationErrors\" [value]=\"(operation === 'read' || !collapsable) ? 'open' : ''\" #accordionComponent>\n <ion-accordion value=\"open\">\n @if (collapsable) {\n <ion-item [class.disable-collapse]=\"!collapsable\" slot=\"header\" [button]=\"collapsable\" (click)=\"handleAccordionToggle($event)\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-flex dcf-flex-middle dcf-width-1-1\">\n <div class=\"dcf-width-expand\">\n <legend>{{ (title ? title : name) | translate }}</legend>\n </div>\n @if (!isRequired && ['create', 'update'].includes(operation) && collapsable) {\n <div class=\"dcf-width-auto dcf-delete\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleRemoveComponent($event)\">\n <ion-icon name=\"trash-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n </div>\n </ion-item>\n }\n <div slot=\"content\" [attr.aria-hidden]=\"!isOpen\">\n @if (multiple && items.length) {\n <ion-list class=\"dcf-fields-list\">\n <ion-reorder-group [formGroup]=\"formGroup.parent\" [disabled]=\"updatingItem\" (ionItemReorder)=\"handleReorderItems($any($event))\" #accordionComponent>\n @for(item of items; track item.index) {\n <ion-item [class.not-unique]=\"item.title === isUniqueError\" [class.updating]=\"updatingItem?.[pk] === item.title\" lines=\"full\" [button]=\"false\">\n @if (items?.length > 1 && !updatingItem) {\n <ion-reorder slot=\"start\">\n <ion-icon name=\"swap-vertical-outline\"></ion-icon>\n </ion-reorder>\n } @else {\n <div slot=\"start\">\n <ion-icon class=\"dcf-reorder-disabled\" size=\"small\" name=\"swap-vertical-outline\" disabled></ion-icon>\n </div>\n }\n <ion-label [color]=\"(item.title === isUniqueError && !updatingItem?.[pk] === item.title) ? 'danger' : ''\">{{ item.index }}. {{ item.title }}\n @if (item.description?.length > 0) {\n <br />\n <ion-text class=\"dcf-subtitle\">{{item.description}}</ion-text>\n }\n </ion-label>\n @if (!updatingItem || updatingItem?.[pk] !== item.title) {\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleUpdateItem($index)\">\n <ion-icon name=\"create-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n }\n\n @if (!updatingItem) {\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleRemoveItem($index)\">\n <ion-icon name=\"trash-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n }\n </ion-item>\n }\n </ion-reorder-group>\n </ion-list>\n }\n\n @if (children?.length) {\n <ngx-decaf-layout\n [className]=\"'dcf-fieldset-grid dcf-grid-nested'\"\n [flexMode]=\"props.flexMode || false\"\n [match]=\"false\"\n [gap]=\"'small'\"\n [children]=\"children || []\"\n [parentForm]=\"formGroup || parentForm\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [hidden]=\"items.length === max && !updatingItem\"\n />\n }\n\n @if (multiple && ['create', 'update'].includes(operation)) {\n @if (isUniqueError) {\n <div class=\"dcf-not-unique-container dcf-animation dcf-animation-bottom-small dcf-animation-fast\">\n <div class=\" dcf-grid dcf-grid-collapse dcf-width-1-1 \">\n <div class=\"dcf-auto\" [attr.style]=\"'max-width: 50px'\">\n <ion-icon name=\"alert-circle-outline\"></ion-icon>\n </div>\n <div class=\"dcf-width-expand\">\n <ion-text color=\"danger\" class=\"dcf-text-small\">{{ locale + '.not_unique' | translate : { value: isUniqueError } }}</ion-text>\n </div>\n </div>\n </div>\n }\n @if(max) {\n <div class=\"dcf-width-1-1 dcf-max-message-container\">\n <ion-text class=\"dcf-text-small\"\n [color]=\"items.length !== max ? (!isDarkMode ? 'medium' : '') : 'primary'\"\n >\n {{ locale + (items.length !== max ? '.max_items' : '.max_items_reached') | translate : { '0': max } }}\n </ion-text>\n </div>\n }\n <div class=\"dcf-grid dcf-grid-small dcf-flex dcf-buttons-container\">\n @if (updatingItem) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" color=\"danger\" (click)=\"handleCancelUpdateItem()\">\n {{ buttonCancelLabel }}\n </ion-button>\n </div>\n <div>\n <ion-button size=\"small\" fill=\"clear\" (click)=\"handleCreateItem()\">\n <ion-icon name=\"refresh-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.update' | translate }}\n </ion-button>\n </div>\n } @else {\n @if (items.length < max || !max) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" class=\"dcf-button-add\" [color]=\"isDarkMode ? 'light' : 'dark'\" (click)=\"handleCreateItem()\">\n <ion-icon name=\"add-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.add' | translate }}\n </ion-button>\n </div>\n\n }\n }\n </div>\n }\n </div>\n </ion-accordion>\n </ion-accordion-group>\n </div>\n</fieldset>\n\n", styles: ["ion-accordion-group ion-item[slot=header] .dcf-delete{width:30px}ion-accordion-group ion-item[slot=header] .dcf-delete ion-button{transform:translateY(-2px)}ion-accordion-group ion-item[slot=header] .dcf-delete ion-icon{font-size:1.15rem}*{overflow-x:hidden!important}.dcf-fieldset-component{border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-3)}.dcf-fieldset-component ion-accordion{background:var(--dcf-card-background)!important}.dcf-fieldset-component.read,.dcf-fieldset-component.delete{margin:var(--dcf-margin-small) 0rem!important}.dcf-fieldset-component:not(.dcf-blank) ion-accordion [slot=header]{--border-color: transparent;--border-radius: 6px;--inner-border-width: 0;--padding-start: .25rem;margin:unset;margin-top:.125rem}.dcf-fieldset-component:not(.dcf-blank) ion-accordion [slot=content]{padding:var(--dcf-padding-small) .25rem}.dcf-fieldset-component.dcf-blank{border-color:transparent;padding:0rem!important;margin:0!important}.dcf-fieldset-component.dcf-blank [slot=content]{padding:var(--dcf-padding-small) .25rem;margin:0!important}.dcf-fieldset-component legend,.dcf-fieldset-component .dcf-title{font-size:.875rem;font-weight:600;margin:0}.dcf-fieldset-component.not-collapsable .dcf-title{margin:var(--dcf-padding-small)!important;display:inline-block}.dcf-fieldset-component .dcf-max-message-container{margin:var(--dcf-padding-small)}.dcf-not-unique-container{display:flex;justify-content:center;align-items:center;margin-bottom:var(--dcf-spacement);flex:1 1 auto}.dcf-not-unique-container>div{display:flex;justify-content:center;align-items:center}.dcf-not-unique-container ion-icon{transform:translatey(2px);margin-right:5px}.dcf-fields-list{padding:.25rem var(--dcf-margin-small);margin-bottom:var(--dcf-margin-small)!important}.dcf-fields-list ion-item{--min-height: 50px;--padding-top: .25rem;--padding-bottom: .25rem;--padding-start: .75rem;--padding-end: .75rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--border-color: var(--dcf-color-gray-2) !important}.dcf-fields-list ion-item ion-icon.dcf-reorder-disabled{width:var(--dcf-spacement);transform:translatey(2px);color:var(--dcf-color-gray-4)}.dcf-fields-list ion-item.updating{--background: rgba(var(--dcf-color-primary-rgb), .1) !important}.dcf-fields-list ion-item.not-unique{--background: rgba(var(--dcf-color-danger-rgb), .05) !important}.dcf-fields-list ion-item .dcf-subtitle{font-size:.925rem;color:var(--ion-color-gray-4)}.dcf-buttons-container{margin-bottom:0!important}@media (max-width: 480px){.dcf-buttons-container{flex-direction:column-reverse;gap:.5rem;align-items:stretch}.dcf-buttons-container ion-button{width:100%;justify-content:center;height:40px}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: IonAccordionGroup, selector: "ion-accordion-group", inputs: ["animated", "disabled", "expand", "mode", "multiple", "readonly", "value"] }, { kind: "component", type: IonAccordion, selector: "ion-accordion", inputs: ["disabled", "mode", "readonly", "toggleIcon", "toggleIconSlot", "value"] }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: IonReorder, selector: "ion-reorder" }, { kind: "component", type: IonReorderGroup, selector: "ion-reorder-group", inputs: ["disabled"] }, { kind: "component", type: 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: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: LayoutComponent, selector: "ngx-decaf-layout", inputs: ["gap", "breakpoint", "grid", "match", "flexMode", "rowCard", "maxColsLength"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
7464
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: FieldsetComponent, isStandalone: true, selector: "ngx-decaf-fieldset", inputs: { formControl: "formControl", collapsable: "collapsable", customTypes: "customTypes", title: "title", description: "description", multiple: "multiple", value: "value", borders: "borders", max: "max", required: "required", ordenable: "ordenable", editable: "editable" }, viewQueries: [{ propertyName: "accordionComponent", first: true, predicate: ["accordionComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "\n\n<fieldset\n (fieldsetAddGroupEvent)=\"handleCreateItem($event)\"\n [class]=\"'dcf-fieldset-component ' + operation\"\n [class.dcf-blank]=\"!borders\"\n [class.open]=\"isOpen\"\n [class.dcf-not-collapsable]=\"!collapsable\"\n #component>\n <div class=\"dcf-width-1-1\">\n @if (!collapsable || required) {\n <legend class=\"dcf-title\">{{ (title ? title : name) | translate }}</legend>\n }\n <ion-accordion-group class=\"dcf-width-1-1\" [class.open]=\"isOpen\" [class.hasValidationErrors]=\"hasValidationErrors\" [value]=\"(operation === 'read' || !collapsable) ? 'open' : ''\" #accordionComponent>\n <ion-accordion\n value=\"open\"\n [class.dcf-disabled]=\"!activePage\"\n [class.dcf-empty]=\"!items?.length\"\n >\n @if (collapsable && !required) {\n <ion-item slot=\"header\" [button]=\"collapsable\" (click)=\"handleAccordionToggle($event)\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-flex dcf-flex-middle dcf-width-1-1\">\n <div class=\"dcf-width-expand\">\n <legend>{{ (title ? title : name) | translate }}</legend>\n </div>\n @if (!isRequired && ['create', 'update'].includes(operation) && collapsable && multiple) {\n <div class=\"dcf-width-auto dcf-delete\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleClear($event)\">\n <ion-icon aria-hidden=\"true\" name=\"trash-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n </div>\n </ion-item>\n }\n <div slot=\"content\" [attr.aria-hidden]=\"!isOpen\">\n @if (activePage) {\n <div>\n <ngx-decaf-layout\n [className]=\"'dcf-fieldset-grid dcf-grid-nested'\"\n [flexMode]=\"props.flexMode ?? false\"\n [match]=\"false\"\n [gap]=\"'small'\"\n [children]=\"activePage || []\"\n [parentForm]=\"formGroup || parentForm\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [borders]=\"borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [hidden]=\"items.length === max && !updatingItem\"\n />\n </div>\n }\n </div>\n </ion-accordion>\n </ion-accordion-group>\n\n @if (multiple && items.length) {\n <ion-list class=\"dcf-fields-list\">\n <ion-reorder-group [formGroup]=\"formGroup.parent\" [disabled]=\"updatingItem\" (ionItemReorder)=\"handleReorderItems($any($event))\" #accordionComponent>\n @for(item of items; track item.index) {\n <ion-item [class.not-unique]=\"item.title === isUniqueError\" [class.updating]=\"updatingItem?.[pk] === item.title\" lines=\"full\" [button]=\"false\">\n @if(ordenable) {\n @if (items?.length > 1 && !updatingItem) {\n <ion-reorder slot=\"start\">\n <ion-icon aria-hidden=\"true\" name=\"swap-vertical-outline\"></ion-icon>\n </ion-reorder>\n } @else {\n <div slot=\"start\">\n <ion-icon aria-hidden=\"true\" class=\"dcf-reorder-disabled\" size=\"small\" name=\"swap-vertical-outline\" disabled></ion-icon>\n </div>\n }\n }\n\n <ion-label [color]=\"(item.title === isUniqueError && !updatingItem?.[pk] === item.title) ? 'danger' : ''\">{{ item.index }}. {{ item.title }}\n @if (item.description?.length > 0) {\n <br />\n <ion-text class=\"dcf-subtitle\">{{item.description}}</ion-text>\n }\n </ion-label>\n\n @if(editable) {\n @if (!updatingItem || updatingItem?.[pk] !== item.title) {\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleUpdateItem($index)\">\n <ion-icon aria-hidden=\"true\" name=\"create-outline\" color=\"dark\" ></ion-icon>\n </ion-button>\n }\n }\n\n\n @if (!updatingItem) {\n <ion-button fill=\"clear\" size=\"small\" color=\"danger\" (click)=\"handleRemoveItem($index)\">\n <ion-icon aria-hidden=\"true\" name=\"close-outline\" color=\"dark\"></ion-icon>\n </ion-button>\n }\n </ion-item>\n }\n </ion-reorder-group>\n </ion-list>\n }\n\n @if (multiple && ['create', 'update'].includes(operation)) {\n @if (isUniqueError) {\n <div class=\"dcf-not-unique-container dcf-animation dcf-animation-bottom-small dcf-animation-fast\">\n <div class=\" dcf-grid dcf-grid-collapse dcf-width-1-1 \">\n <div class=\"dcf-auto\" [attr.style]=\"'max-width: 50px'\">\n <ion-icon aria-hidden=\"true\" name=\"alert-circle-outline\"></ion-icon>\n </div>\n <div class=\"dcf-width-expand\">\n <ion-text color=\"danger\" class=\"dcf-text-small\">{{ locale + '.not_unique' | translate : { value: isUniqueError } }}</ion-text>\n </div>\n </div>\n </div>\n }\n @if(max) {\n <div class=\"dcf-width-1-1 dcf-max-message-container\">\n <ion-text class=\"dcf-text-small\"\n [color]=\"items.length !== max ? (!isDarkMode ? 'medium' : '') : 'primary'\"\n >\n {{ locale + (items.length !== max ? '.max_items' : '.max_items_reached') | translate : { '0': max } }}\n </ion-text>\n </div>\n }\n\n <div class=\"dcf-grid dcf-grid-small dcf-flex dcf-buttons-container\" [class.dcf-not-collapsable]=\"!collapsable\" [class.dcf-empty]=\"!activePage\" [class.dcf-blank]=\"!borders\">\n @if (updatingItem) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" color=\"danger\" (click)=\"handleCancelUpdateItem()\">\n {{ locale + '.cancel' | translate }}\n </ion-button>\n </div>\n <div>\n <ion-button size=\"small\" fill=\"clear\" (click)=\"handleCreateItem()\">\n <ion-icon aria-hidden=\"true\" name=\"refresh-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.update' | translate }}\n </ion-button>\n </div>\n } @else {\n\n @if (items.length < max || !max) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" class=\"dcf-button-add\" [color]=\"isDarkMode ? 'light' : 'dark'\" (click)=\"handleCreateItem()\">\n <ion-icon aria-hidden=\"true\" name=\"add-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.add' | translate }}\n </ion-button>\n </div>\n }\n }\n </div>\n }\n </div>\n</fieldset>\n\n", styles: ["ion-accordion ion-item[slot=header] .dcf-delete{width:30px}ion-accordion ion-item[slot=header] .dcf-delete ion-button{transform:translateY(-2px)}ion-accordion ion-item[slot=header] .dcf-delete ion-icon{font-size:1.15rem}ion-accordion.dcf-disabled [slot=content]{padding-bottom:0rem!important}ion-accordion.dcf-empty,ion-accordion.dcf-disabled{opacity:1!important}ion-accordion.dcf-empty ::ng-deep .ion-accordion-toggle-icon,ion-accordion.dcf-disabled ::ng-deep .ion-accordion-toggle-icon{display:none!important}ion-accordion.dcf-empty .dcf-delete,ion-accordion.dcf-disabled .dcf-delete{display:none!important}ion-accordion.dcf-empty ion-item[slot=header],ion-accordion.dcf-disabled ion-item[slot=header]{pointer-events:none;cursor:default!important}.dcf-fieldset-component{border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-3)}.dcf-fieldset-component.dcf-blank{border-color:transparent;padding:0rem!important;margin:0!important}.dcf-fieldset-component *{overflow-x:hidden!important}.dcf-fieldset-component ion-accordion:not(.dcf-empty){background:var(--dcf-card-background)!important}.dcf-fieldset-component ion-accordion ion-item{--background-hover: transparent !important}.dcf-fieldset-component.read,.dcf-fieldset-component.delete{margin:var(--dcf-margin-small) 0rem!important}.dcf-fieldset-component.read [slot=header],.dcf-fieldset-component.delete [slot=header]{margin-bottom:0rem!important}.dcf-fieldset-component [slot=header]{--border-color: transparent;--border-radius: 6px;--inner-border-width: 0;--padding-start: .65rem;--color: var(--ion-color-text) !important;margin:unset}.dcf-fieldset-component legend,.dcf-fieldset-component .dcf-title{font-weight:500;font-size:1rem;line-height:1.5rem;font-weight:600;margin:0;color:var(--ion-color-text)!important}.dcf-fieldset-component .dcf-title{padding:.8rem!important}.dcf-fieldset-component [slot=content]{padding:var(--dcf-padding-small) .25rem!important}.dcf-fieldset-component [slot=content]>div{padding-top:.25rem!important}.dcf-fieldset-component:not(.dcf-blank) ion-accordion [slot=header]{margin-top:.125rem}.dcf-fieldset-component .dcf-max-message-container{margin:var(--dcf-padding-small) .75rem}.dcf-not-unique-container{display:flex;justify-content:center;align-items:center;margin-bottom:var(--dcf-spacement);flex:1 1 auto}.dcf-not-unique-container>div{display:flex;justify-content:center;align-items:center}.dcf-not-unique-container ion-icon{transform:translatey(2px);margin-right:5px}.dcf-fields-list{padding:.25rem var(--dcf-margin-small);margin-bottom:var(--dcf-margin-small)!important}.dcf-fields-list ion-item{--min-height: 50px;--padding-top: .25rem;--padding-bottom: .25rem;--padding-start: .75rem;--padding-end: .75rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--border-color: var(--dcf-color-gray-2) !important}.dcf-fields-list ion-item ion-icon.dcf-reorder-disabled{width:var(--dcf-spacement);transform:translatey(2px);color:var(--dcf-color-gray-4)}.dcf-fields-list ion-item.updating{--background: rgba(var(--dcf-color-primary-rgb), .1) !important}.dcf-fields-list ion-item.not-unique{--background: rgba(var(--dcf-color-danger-rgb), .05) !important}.dcf-fields-list ion-item .dcf-subtitle{font-size:.925rem;color:var(--ion-color-gray-4)}.dcf-buttons-container{margin-bottom:0!important;margin-top:-.5rem;padding:0rem .125rem}.dcf-buttons-container:not(.dcf-blank){padding-bottom:var(--dcf-padding-small)!important}.dcf-buttons-container.dcf-not-collapsable.dcf-empty{position:relative;top:-1rem!important}@media (max-width: 480px){.dcf-buttons-container{flex-direction:column-reverse;gap:.5rem;align-items:stretch}.dcf-buttons-container ion-button{width:100%;justify-content:center;height:40px}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: IonAccordionGroup, selector: "ion-accordion-group", inputs: ["animated", "disabled", "expand", "mode", "multiple", "readonly", "value"] }, { kind: "component", type: IonAccordion, selector: "ion-accordion", inputs: ["disabled", "mode", "readonly", "toggleIcon", "toggleIconSlot", "value"] }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: IonReorder, selector: "ion-reorder" }, { kind: "component", type: IonReorderGroup, selector: "ion-reorder-group", inputs: ["disabled"] }, { kind: "component", type: 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: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: LayoutComponent, selector: "ngx-decaf-layout", inputs: ["gap", "grid", "flexMode", "rowCard", "maxColsLength"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
6824
7465
|
};
|
|
6825
7466
|
FieldsetComponent = __decorate([
|
|
6826
7467
|
Dynamic(),
|
|
@@ -6842,7 +7483,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
|
|
|
6842
7483
|
IonButton,
|
|
6843
7484
|
IonIcon,
|
|
6844
7485
|
LayoutComponent
|
|
6845
|
-
], template: "\n\n<fieldset\n (fieldsetAddGroupEvent)=\"handleCreateItem($event)\"\n [class]=\"'dcf-fieldset-component ' + operation\"\n [class.dcf-blank]=\"!borders\"\n [class.open]=\"isOpen\"\n [class.not-collapsable]=\"!collapsable\"\n #component>\n <div class=\"dcf-width-1-1\">\n @if (!collapsable) {\n <legend class=\"dcf-title\">{{ (title ? title : name) | translate }}</legend>\n }\n <ion-accordion-group class=\"dcf-width-1-1\" [class.open]=\"isOpen\" [class.hasValidationErrors]=\"hasValidationErrors\" [value]=\"(operation === 'read' || !collapsable) ? 'open' : ''\" #accordionComponent>\n <ion-accordion value=\"open\">\n @if (collapsable) {\n <ion-item [class.disable-collapse]=\"!collapsable\" slot=\"header\" [button]=\"collapsable\" (click)=\"handleAccordionToggle($event)\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-flex dcf-flex-middle dcf-width-1-1\">\n <div class=\"dcf-width-expand\">\n <legend>{{ (title ? title : name) | translate }}</legend>\n </div>\n @if (!isRequired && ['create', 'update'].includes(operation) && collapsable) {\n <div class=\"dcf-width-auto dcf-delete\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleRemoveComponent($event)\">\n <ion-icon name=\"trash-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n </div>\n </ion-item>\n }\n <div slot=\"content\" [attr.aria-hidden]=\"!isOpen\">\n @if (multiple && items.length) {\n <ion-list class=\"dcf-fields-list\">\n <ion-reorder-group [formGroup]=\"formGroup.parent\" [disabled]=\"updatingItem\" (ionItemReorder)=\"handleReorderItems($any($event))\" #accordionComponent>\n @for(item of items; track item.index) {\n <ion-item [class.not-unique]=\"item.title === isUniqueError\" [class.updating]=\"updatingItem?.[pk] === item.title\" lines=\"full\" [button]=\"false\">\n @if (items?.length > 1 && !updatingItem) {\n <ion-reorder slot=\"start\">\n <ion-icon name=\"swap-vertical-outline\"></ion-icon>\n </ion-reorder>\n } @else {\n <div slot=\"start\">\n <ion-icon class=\"dcf-reorder-disabled\" size=\"small\" name=\"swap-vertical-outline\" disabled></ion-icon>\n </div>\n }\n <ion-label [color]=\"(item.title === isUniqueError && !updatingItem?.[pk] === item.title) ? 'danger' : ''\">{{ item.index }}. {{ item.title }}\n @if (item.description?.length > 0) {\n <br />\n <ion-text class=\"dcf-subtitle\">{{item.description}}</ion-text>\n }\n </ion-label>\n @if (!updatingItem || updatingItem?.[pk] !== item.title) {\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleUpdateItem($index)\">\n <ion-icon name=\"create-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n }\n\n @if (!updatingItem) {\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleRemoveItem($index)\">\n <ion-icon name=\"trash-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n }\n </ion-item>\n }\n </ion-reorder-group>\n </ion-list>\n }\n\n @if (children?.length) {\n <ngx-decaf-layout\n [className]=\"'dcf-fieldset-grid dcf-grid-nested'\"\n [flexMode]=\"props.flexMode || false\"\n [match]=\"false\"\n [gap]=\"'small'\"\n [children]=\"children || []\"\n [parentForm]=\"formGroup || parentForm\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [hidden]=\"items.length === max && !updatingItem\"\n />\n }\n\n @if (multiple && ['create', 'update'].includes(operation)) {\n @if (isUniqueError) {\n <div class=\"dcf-not-unique-container dcf-animation dcf-animation-bottom-small dcf-animation-fast\">\n <div class=\" dcf-grid dcf-grid-collapse dcf-width-1-1 \">\n <div class=\"dcf-auto\" [attr.style]=\"'max-width: 50px'\">\n <ion-icon name=\"alert-circle-outline\"></ion-icon>\n </div>\n <div class=\"dcf-width-expand\">\n <ion-text color=\"danger\" class=\"dcf-text-small\">{{ locale + '.not_unique' | translate : { value: isUniqueError } }}</ion-text>\n </div>\n </div>\n </div>\n }\n @if(max) {\n <div class=\"dcf-width-1-1 dcf-max-message-container\">\n <ion-text class=\"dcf-text-small\"\n [color]=\"items.length !== max ? (!isDarkMode ? 'medium' : '') : 'primary'\"\n >\n {{ locale + (items.length !== max ? '.max_items' : '.max_items_reached') | translate : { '0': max } }}\n </ion-text>\n </div>\n }\n <div class=\"dcf-grid dcf-grid-small dcf-flex dcf-buttons-container\">\n @if (updatingItem) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" color=\"danger\" (click)=\"handleCancelUpdateItem()\">\n {{ buttonCancelLabel }}\n </ion-button>\n </div>\n <div>\n <ion-button size=\"small\" fill=\"clear\" (click)=\"handleCreateItem()\">\n <ion-icon name=\"refresh-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.update' | translate }}\n </ion-button>\n </div>\n } @else {\n @if (items.length < max || !max) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" class=\"dcf-button-add\" [color]=\"isDarkMode ? 'light' : 'dark'\" (click)=\"handleCreateItem()\">\n <ion-icon name=\"add-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.add' | translate }}\n </ion-button>\n </div>\n\n }\n }\n </div>\n }\n </div>\n </ion-accordion>\n </ion-accordion-group>\n </div>\n</fieldset>\n\n", styles: ["ion-accordion-group ion-item[slot=header] .dcf-delete{width:30px}ion-accordion-group ion-item[slot=header] .dcf-delete ion-button{transform:translateY(-2px)}ion-accordion-group ion-item[slot=header] .dcf-delete ion-icon{font-size:1.15rem}*{overflow-x:hidden!important}.dcf-fieldset-component{border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-3)}.dcf-fieldset-component ion-accordion{background:var(--dcf-card-background)!important}.dcf-fieldset-component.read,.dcf-fieldset-component.delete{margin:var(--dcf-margin-small) 0rem!important}.dcf-fieldset-component:not(.dcf-blank) ion-accordion [slot=header]{--border-color: transparent;--border-radius: 6px;--inner-border-width: 0;--padding-start: .25rem;margin:unset;margin-top:.125rem}.dcf-fieldset-component:not(.dcf-blank) ion-accordion [slot=content]{padding:var(--dcf-padding-small) .25rem}.dcf-fieldset-component.dcf-blank{border-color:transparent;padding:0rem!important;margin:0!important}.dcf-fieldset-component.dcf-blank [slot=content]{padding:var(--dcf-padding-small) .25rem;margin:0!important}.dcf-fieldset-component legend,.dcf-fieldset-component .dcf-title{font-size:.875rem;font-weight:600;margin:0}.dcf-fieldset-component.not-collapsable .dcf-title{margin:var(--dcf-padding-small)!important;display:inline-block}.dcf-fieldset-component .dcf-max-message-container{margin:var(--dcf-padding-small)}.dcf-not-unique-container{display:flex;justify-content:center;align-items:center;margin-bottom:var(--dcf-spacement);flex:1 1 auto}.dcf-not-unique-container>div{display:flex;justify-content:center;align-items:center}.dcf-not-unique-container ion-icon{transform:translatey(2px);margin-right:5px}.dcf-fields-list{padding:.25rem var(--dcf-margin-small);margin-bottom:var(--dcf-margin-small)!important}.dcf-fields-list ion-item{--min-height: 50px;--padding-top: .25rem;--padding-bottom: .25rem;--padding-start: .75rem;--padding-end: .75rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--border-color: var(--dcf-color-gray-2) !important}.dcf-fields-list ion-item ion-icon.dcf-reorder-disabled{width:var(--dcf-spacement);transform:translatey(2px);color:var(--dcf-color-gray-4)}.dcf-fields-list ion-item.updating{--background: rgba(var(--dcf-color-primary-rgb), .1) !important}.dcf-fields-list ion-item.not-unique{--background: rgba(var(--dcf-color-danger-rgb), .05) !important}.dcf-fields-list ion-item .dcf-subtitle{font-size:.925rem;color:var(--ion-color-gray-4)}.dcf-buttons-container{margin-bottom:0!important}@media (max-width: 480px){.dcf-buttons-container{flex-direction:column-reverse;gap:.5rem;align-items:stretch}.dcf-buttons-container ion-button{width:100%;justify-content:center;height:40px}}\n"] }]
|
|
7486
|
+
], template: "\n\n<fieldset\n (fieldsetAddGroupEvent)=\"handleCreateItem($event)\"\n [class]=\"'dcf-fieldset-component ' + operation\"\n [class.dcf-blank]=\"!borders\"\n [class.open]=\"isOpen\"\n [class.dcf-not-collapsable]=\"!collapsable\"\n #component>\n <div class=\"dcf-width-1-1\">\n @if (!collapsable || required) {\n <legend class=\"dcf-title\">{{ (title ? title : name) | translate }}</legend>\n }\n <ion-accordion-group class=\"dcf-width-1-1\" [class.open]=\"isOpen\" [class.hasValidationErrors]=\"hasValidationErrors\" [value]=\"(operation === 'read' || !collapsable) ? 'open' : ''\" #accordionComponent>\n <ion-accordion\n value=\"open\"\n [class.dcf-disabled]=\"!activePage\"\n [class.dcf-empty]=\"!items?.length\"\n >\n @if (collapsable && !required) {\n <ion-item slot=\"header\" [button]=\"collapsable\" (click)=\"handleAccordionToggle($event)\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-flex dcf-flex-middle dcf-width-1-1\">\n <div class=\"dcf-width-expand\">\n <legend>{{ (title ? title : name) | translate }}</legend>\n </div>\n @if (!isRequired && ['create', 'update'].includes(operation) && collapsable && multiple) {\n <div class=\"dcf-width-auto dcf-delete\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleClear($event)\">\n <ion-icon aria-hidden=\"true\" name=\"trash-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n </div>\n </ion-item>\n }\n <div slot=\"content\" [attr.aria-hidden]=\"!isOpen\">\n @if (activePage) {\n <div>\n <ngx-decaf-layout\n [className]=\"'dcf-fieldset-grid dcf-grid-nested'\"\n [flexMode]=\"props.flexMode ?? false\"\n [match]=\"false\"\n [gap]=\"'small'\"\n [children]=\"activePage || []\"\n [parentForm]=\"formGroup || parentForm\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [borders]=\"borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [hidden]=\"items.length === max && !updatingItem\"\n />\n </div>\n }\n </div>\n </ion-accordion>\n </ion-accordion-group>\n\n @if (multiple && items.length) {\n <ion-list class=\"dcf-fields-list\">\n <ion-reorder-group [formGroup]=\"formGroup.parent\" [disabled]=\"updatingItem\" (ionItemReorder)=\"handleReorderItems($any($event))\" #accordionComponent>\n @for(item of items; track item.index) {\n <ion-item [class.not-unique]=\"item.title === isUniqueError\" [class.updating]=\"updatingItem?.[pk] === item.title\" lines=\"full\" [button]=\"false\">\n @if(ordenable) {\n @if (items?.length > 1 && !updatingItem) {\n <ion-reorder slot=\"start\">\n <ion-icon aria-hidden=\"true\" name=\"swap-vertical-outline\"></ion-icon>\n </ion-reorder>\n } @else {\n <div slot=\"start\">\n <ion-icon aria-hidden=\"true\" class=\"dcf-reorder-disabled\" size=\"small\" name=\"swap-vertical-outline\" disabled></ion-icon>\n </div>\n }\n }\n\n <ion-label [color]=\"(item.title === isUniqueError && !updatingItem?.[pk] === item.title) ? 'danger' : ''\">{{ item.index }}. {{ item.title }}\n @if (item.description?.length > 0) {\n <br />\n <ion-text class=\"dcf-subtitle\">{{item.description}}</ion-text>\n }\n </ion-label>\n\n @if(editable) {\n @if (!updatingItem || updatingItem?.[pk] !== item.title) {\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleUpdateItem($index)\">\n <ion-icon aria-hidden=\"true\" name=\"create-outline\" color=\"dark\" ></ion-icon>\n </ion-button>\n }\n }\n\n\n @if (!updatingItem) {\n <ion-button fill=\"clear\" size=\"small\" color=\"danger\" (click)=\"handleRemoveItem($index)\">\n <ion-icon aria-hidden=\"true\" name=\"close-outline\" color=\"dark\"></ion-icon>\n </ion-button>\n }\n </ion-item>\n }\n </ion-reorder-group>\n </ion-list>\n }\n\n @if (multiple && ['create', 'update'].includes(operation)) {\n @if (isUniqueError) {\n <div class=\"dcf-not-unique-container dcf-animation dcf-animation-bottom-small dcf-animation-fast\">\n <div class=\" dcf-grid dcf-grid-collapse dcf-width-1-1 \">\n <div class=\"dcf-auto\" [attr.style]=\"'max-width: 50px'\">\n <ion-icon aria-hidden=\"true\" name=\"alert-circle-outline\"></ion-icon>\n </div>\n <div class=\"dcf-width-expand\">\n <ion-text color=\"danger\" class=\"dcf-text-small\">{{ locale + '.not_unique' | translate : { value: isUniqueError } }}</ion-text>\n </div>\n </div>\n </div>\n }\n @if(max) {\n <div class=\"dcf-width-1-1 dcf-max-message-container\">\n <ion-text class=\"dcf-text-small\"\n [color]=\"items.length !== max ? (!isDarkMode ? 'medium' : '') : 'primary'\"\n >\n {{ locale + (items.length !== max ? '.max_items' : '.max_items_reached') | translate : { '0': max } }}\n </ion-text>\n </div>\n }\n\n <div class=\"dcf-grid dcf-grid-small dcf-flex dcf-buttons-container\" [class.dcf-not-collapsable]=\"!collapsable\" [class.dcf-empty]=\"!activePage\" [class.dcf-blank]=\"!borders\">\n @if (updatingItem) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" color=\"danger\" (click)=\"handleCancelUpdateItem()\">\n {{ locale + '.cancel' | translate }}\n </ion-button>\n </div>\n <div>\n <ion-button size=\"small\" fill=\"clear\" (click)=\"handleCreateItem()\">\n <ion-icon aria-hidden=\"true\" name=\"refresh-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.update' | translate }}\n </ion-button>\n </div>\n } @else {\n\n @if (items.length < max || !max) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" class=\"dcf-button-add\" [color]=\"isDarkMode ? 'light' : 'dark'\" (click)=\"handleCreateItem()\">\n <ion-icon aria-hidden=\"true\" name=\"add-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.add' | translate }}\n </ion-button>\n </div>\n }\n }\n </div>\n }\n </div>\n</fieldset>\n\n", styles: ["ion-accordion ion-item[slot=header] .dcf-delete{width:30px}ion-accordion ion-item[slot=header] .dcf-delete ion-button{transform:translateY(-2px)}ion-accordion ion-item[slot=header] .dcf-delete ion-icon{font-size:1.15rem}ion-accordion.dcf-disabled [slot=content]{padding-bottom:0rem!important}ion-accordion.dcf-empty,ion-accordion.dcf-disabled{opacity:1!important}ion-accordion.dcf-empty ::ng-deep .ion-accordion-toggle-icon,ion-accordion.dcf-disabled ::ng-deep .ion-accordion-toggle-icon{display:none!important}ion-accordion.dcf-empty .dcf-delete,ion-accordion.dcf-disabled .dcf-delete{display:none!important}ion-accordion.dcf-empty ion-item[slot=header],ion-accordion.dcf-disabled ion-item[slot=header]{pointer-events:none;cursor:default!important}.dcf-fieldset-component{border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-3)}.dcf-fieldset-component.dcf-blank{border-color:transparent;padding:0rem!important;margin:0!important}.dcf-fieldset-component *{overflow-x:hidden!important}.dcf-fieldset-component ion-accordion:not(.dcf-empty){background:var(--dcf-card-background)!important}.dcf-fieldset-component ion-accordion ion-item{--background-hover: transparent !important}.dcf-fieldset-component.read,.dcf-fieldset-component.delete{margin:var(--dcf-margin-small) 0rem!important}.dcf-fieldset-component.read [slot=header],.dcf-fieldset-component.delete [slot=header]{margin-bottom:0rem!important}.dcf-fieldset-component [slot=header]{--border-color: transparent;--border-radius: 6px;--inner-border-width: 0;--padding-start: .65rem;--color: var(--ion-color-text) !important;margin:unset}.dcf-fieldset-component legend,.dcf-fieldset-component .dcf-title{font-weight:500;font-size:1rem;line-height:1.5rem;font-weight:600;margin:0;color:var(--ion-color-text)!important}.dcf-fieldset-component .dcf-title{padding:.8rem!important}.dcf-fieldset-component [slot=content]{padding:var(--dcf-padding-small) .25rem!important}.dcf-fieldset-component [slot=content]>div{padding-top:.25rem!important}.dcf-fieldset-component:not(.dcf-blank) ion-accordion [slot=header]{margin-top:.125rem}.dcf-fieldset-component .dcf-max-message-container{margin:var(--dcf-padding-small) .75rem}.dcf-not-unique-container{display:flex;justify-content:center;align-items:center;margin-bottom:var(--dcf-spacement);flex:1 1 auto}.dcf-not-unique-container>div{display:flex;justify-content:center;align-items:center}.dcf-not-unique-container ion-icon{transform:translatey(2px);margin-right:5px}.dcf-fields-list{padding:.25rem var(--dcf-margin-small);margin-bottom:var(--dcf-margin-small)!important}.dcf-fields-list ion-item{--min-height: 50px;--padding-top: .25rem;--padding-bottom: .25rem;--padding-start: .75rem;--padding-end: .75rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--border-color: var(--dcf-color-gray-2) !important}.dcf-fields-list ion-item ion-icon.dcf-reorder-disabled{width:var(--dcf-spacement);transform:translatey(2px);color:var(--dcf-color-gray-4)}.dcf-fields-list ion-item.updating{--background: rgba(var(--dcf-color-primary-rgb), .1) !important}.dcf-fields-list ion-item.not-unique{--background: rgba(var(--dcf-color-danger-rgb), .05) !important}.dcf-fields-list ion-item .dcf-subtitle{font-size:.925rem;color:var(--ion-color-gray-4)}.dcf-buttons-container{margin-bottom:0!important;margin-top:-.5rem;padding:0rem .125rem}.dcf-buttons-container:not(.dcf-blank){padding-bottom:var(--dcf-padding-small)!important}.dcf-buttons-container.dcf-not-collapsable.dcf-empty{position:relative;top:-1rem!important}@media (max-width: 480px){.dcf-buttons-container{flex-direction:column-reverse;gap:.5rem;align-items:stretch}.dcf-buttons-container ion-button{width:100%;justify-content:center;height:40px}}\n"] }]
|
|
6846
7487
|
}], ctorParameters: () => [], propDecorators: { accordionComponent: [{
|
|
6847
7488
|
type: ViewChild,
|
|
6848
7489
|
args: ['accordionComponent', { static: false }]
|
|
@@ -6864,6 +7505,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
|
|
|
6864
7505
|
type: Input
|
|
6865
7506
|
}], max: [{
|
|
6866
7507
|
type: Input
|
|
7508
|
+
}], required: [{
|
|
7509
|
+
type: Input
|
|
7510
|
+
}], ordenable: [{
|
|
7511
|
+
type: Input
|
|
7512
|
+
}], editable: [{
|
|
7513
|
+
type: Input
|
|
6867
7514
|
}] } });
|
|
6868
7515
|
|
|
6869
7516
|
/**
|
|
@@ -7999,7 +8646,7 @@ let FilterComponent = class FilterComponent extends NgxComponentDirective {
|
|
|
7999
8646
|
this.searchEvent.emit(value);
|
|
8000
8647
|
}
|
|
8001
8648
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8002
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: FilterComponent, isStandalone: true, selector: "ngx-decaf-filter", inputs: { indexes: "indexes", conditions: "conditions", sortBy: "sortBy", disableSort: "disableSort" }, outputs: { filterEvent: "filterEvent", searchEvent: "searchEvent" }, host: { properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "optionsFilterElement", first: true, predicate: ["optionsFilterElement"], descendants: true, read: ElementRef }], usesInheritance: true, ngImport: i0, template: "\n@if (!indexes.length) {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n}\n\n<div [id]=\"uid\" class=\"dcf-grid dcf-grid-small dcf-grid-match dcf-filter-component\" [class.dcf-hidden]=\"!indexes.length\" #component>\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-filter\">\n <div class=\"dcf-input\">\n @for(filter of filterValue; track trackItemFn($index, filter?.['index'])) {\n @if (filter?.['index']) {\n <ion-chip [outline]=\"true\">{{ filter?.['index'] }}</ion-chip>\n }\n @if (filter?.['condition']) {\n <ion-chip [outline]=\"true\">{{ filter?.['condition'] }}</ion-chip>\n }\n @if (filter?.['value']) {\n <ion-chip [outline]=\"true\" class=\"dcf-filter-value\">\n {{ filter?.['value'] }}\n <ion-icon name=\"close-outline\" (click)=\"removeFilter(filter?.['value'])\" size=\"small\"></ion-icon>\n </ion-chip>\n }\n }\n <div class=\"dcf-width-1-1\">\n <!-- [readonly]=\"step !== 3\" -->\n <input\n fill=\"none\"\n [(ngModel)]=\"value\"\n (keydown.enter)=\"addFilter(value, $event)\"\n (keydown.backspace)=\"clear(value)\"\n (input)=\"handleInput($event)\"\n (click)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n type=\"text\"\n id=\"dcf-filter-field\"\n placeholder=\"{{ locale + (step === 3 ? '.type' : '.select') | translate }}\"\n\n />\n @if (windowWidth >= 768) {\n <div [class]=\"'dcf-dropdown ' + (options.length > 0 ? ' dcf-active' : '')\" #optionsFilterElement>\n <div>\n @if (filteredOptions.length > 0) {\n @for(key of filteredOptions; track key) {\n <div\n class=\"dcf-item\"\n tabindex=\"0\"\n (keydown.enter)=\"selectOption(key)\"\n (click)=\"selectOption(key)\">\n {{ key }}\n </div>\n }\n } @else {\n <div class=\"dcf-empty\"\n (click)=\"filteredOptions = options; value = ''\"\n tabindex=\"0\"\n (keydown.enter)=\"filteredOptions = options; value = ''\"\n >\n {{ locale + '.no_suggestions' | translate }}\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n @if (filterValue.length > 0) {\n <div class=\"dcf-icon-clear\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"clear()\">\n <ion-icon name=\"trash-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n <div class=\"dcf-icon-search\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"submit()\">\n <ion-icon name=\"search-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n </div>\n @if (windowWidth < 768) {\n <div [class]=\"'dcf-dropdown ' + (options.length > 0 ? ' dcf-active' : '')\" #optionsFilterElement>\n <div>\n @if (filteredOptions.length > 0) {\n @for(key of filteredOptions; track key) {\n <div\n class=\"dcf-item\"\n tabindex=\"0\"\n (keydown.enter)=\"selectOption(key)\"\n (click)=\"selectOption(key)\">\n {{ key }}\n </div>\n }\n } @else {\n <div class=\"dcf-empty\"\n (click)=\"filteredOptions = options; value = ''\"\n tabindex=\"0\"\n (keydown.enter)=\"filteredOptions = options; value = ''\"\n >\n {{ locale + '.no_suggestions' | translate }}\n </div>\n }\n </div>\n </div>\n }\n </div>\n @if (!disableSort) {\n <div class=\"dcf-width-1-5@m dcf-width-1-1 dcf-sort-container\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-flex dcf-flex-middle dcf-grid-match\">\n <div class=\"dcf-width-expand\">\n <ion-select\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n class=\"dcf-sort-select\"\n (ionChange)=\"handleSortChange($event)\"\n interface=\"popover\"\n [value]=\"sortValue\"\n label-placement=\"floating\"\n fill=\"outline\"\n [label]=\"locale + '.sort' | translate\"\n >\n @for(sort of sortBy; track sort) {\n\n <ion-select-option [value]=\"sort\">{{ sort | translate }}</ion-select-option>\n }\n </ion-select>\n </div>\n <div class=\"dcf-width-auto\">\n <ion-button (click)=\"handleSortDirectionChange()\" fill=\"clear\">\n <ion-icon slot=\"icon-only\" [color]=\"!isDarkMode ? 'primary' : 'light'\" [name]=\"sortDirection === 'desc' ? 'arrow-down-outline' : 'arrow-up-outline'\"></ion-icon>\n </ion-button>\n </div>\n </div>\n </div>\n }\n</div>\n\n\n", styles: [".dcf-filter-component{padding:0 .5rem;margin-top:.75rem;margin-bottom:.75rem}.dcf-filter-component:not(.dcf-palette-dark) .dcf-filter{border:1px solid var(--dcf-color-gray-3);background-color:#fff}.dcf-filter-component:not(.dcf-palette-dark) .dcf-filter:focus-within{border-color:var(--dcf-color-primary);background-color:#fff}.dcf-filter-component:not(.dcf-palette-dark) ion-chip{border:1px solid var(--dcf-color-gray-3);color:var(--dcf-color-gray-7)}.dcf-filter-component:not(.dcf-palette-dark) ion-chip.dcf-filter-value{background:var(--dcf-color-gray-2);border-color:var(--dcf-color-gray-4)!important;color:var(--dcf-color-gray-8)!important}.dcf-filter-component:not(.dcf-palette-dark) .dcf-input input{color:var(--dcf-color-gray-7)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown{background-color:#fff}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-gray-2)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-8)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-3)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{pointer-events:none;touch-action:none;cursor:text!important;border-color:transparent!important}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-1)}.dcf-filter-component.dcf-palette-dark .dcf-filter{border:1px solid var(--dcf-color-step-500)}.dcf-filter-component.dcf-palette-dark .dcf-filter ::-webkit-input-placeholder,.dcf-filter-component.dcf-palette-dark .dcf-filter ::placeholder{color:var(--dcf-color-gray-4)!important}.dcf-filter-component.dcf-palette-dark .dcf-filter:hover{border-color:var(--dcf-color-gray-2)}.dcf-filter-component.dcf-palette-dark .dcf-filter:focus-within{border-color:var(--dcf-color-gray-2)}.dcf-filter-component.dcf-palette-dark ion-chip{border-color:var(--dcf-color-step-300);background:rgba(var(--dcf-color-medium-rgb),.1)}.dcf-filter-component.dcf-palette-dark ion-chip.dcf-filter-value{background:rgba(var(--dcf-color-medium-rgb),.3)!important;border-color:var(--dcf-color-step-500)}.dcf-filter-component.dcf-palette-dark .dcf-input input{color:var(--dcf-color-gray-1)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown{background-color:var(--dcf-item-background)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-step-600)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-1)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-5)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{cursor:text!important;pointer-events:none;touch-action:none;border-color:transparent!important}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-8)}ion-select{min-height:44px!important}.dcf-hidden{display:none!important}.dcf-filter{display:flex;width:100%;min-height:40px;box-shadow:0 1px 2px #0a0d120d;border-radius:var(--dcf-border-radius);box-sizing:border-box}.dcf-filter ion-chip{border-radius:6px;padding:0 8px!important;height:24px;min-height:24px;font-size:.75rem;font-style:normal;font-weight:500;flex-shrink:0;margin-right:2px;white-space:nowrap}.dcf-filter ion-chip.sc-ion-chip-md-h,.dcf-filter ion-chip.sc-ion-chip-ios-h{height:24px;min-height:24px}.dcf-filter ion-chip.sc-ion-chip-md-h .chip-native,.dcf-filter ion-chip.sc-ion-chip-ios-h .chip-native{padding:0 8px!important;height:24px;min-height:24px}.dcf-filter ion-chip ion-label{padding:0 4px;margin:0;font-size:.75rem;white-space:nowrap}.dcf-filter ion-chip ion-icon{margin:0 2px;font-size:.75rem}.dcf-filter .dcf-input{width:100%;display:flex;align-items:center;overflow-x:auto;overflow-y:hidden;white-space:nowrap;padding-left:.5rem}.dcf-filter .dcf-input input{min-height:40px;min-width:100px;width:100%;font-size:1rem;border:none;outline:none;background:transparent;border:0px!important;outline:none!important}.dcf-filter .dcf-input input:focus{border:0px!important;outline:none!important}.dcf-filter .dcf-icon-clear,.dcf-filter .dcf-icon-search{display:flex;justify-content:center;text-align:center;align-items:center;min-width:40px}.dcf-filter .dcf-icon-search ion-icon{font-size:1.25rem}.dcf-sort-container{min-width:200px!important;width:auto}@media (min-width: 990px){.dcf-sort-container{max-width:20%!important}}@media (max-width: 680px){.dcf-sort-container{min-width:100%!important;margin:.75rem 0rem}}.dcf-dropdown{position:absolute;max-height:200px;overflow-y:auto;border-radius:4px;z-index:1000!important;min-width:200px;max-width:300px;display:none}.dcf-dropdown.dcf-active{display:block;margin-top:-3px;box-shadow:0 12px 16px -4px #0a0d1214,0 4px 6px -2px #0a0d1208,0 2px 2px -1px #0a0d120a!important;border-radius:var(--dcf-border-radius);padding:.5rem .25rem}@media (max-width: 768px){.dcf-dropdown.dcf-active{margin-top:55px}}.dcf-dropdown.dcf-active>div>div{cursor:pointer;height:35px;padding:.5rem 1rem;border:1px solid transparent;font-size:1rem;display:flex;align-items:center;border-radius:6px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: IonChip, selector: "ion-chip", inputs: ["color", "disabled", "mode", "outline"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: 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: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "errorText", "expandedIcon", "fill", "helperText", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: SearchbarComponent, selector: "ngx-decaf-searchbar", inputs: ["autocomplete", "autocorrect", "animated", "buttonCancelText", "clearIcon", "color", "debounce", "disabled", "enterkeyhint", "inputmode", "placeholder", "searchIcon", "showCancelButton", "showClearButton", "spellcheck", "type", "value", "queryKeys", "isVisible", "wrapper", "wrapperColor", "emitEventToWindow"], outputs: ["searchEvent"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
8649
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: FilterComponent, isStandalone: true, selector: "ngx-decaf-filter", inputs: { indexes: "indexes", conditions: "conditions", sortBy: "sortBy", disableSort: "disableSort" }, outputs: { filterEvent: "filterEvent", searchEvent: "searchEvent" }, host: { properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "optionsFilterElement", first: true, predicate: ["optionsFilterElement"], descendants: true, read: ElementRef }], usesInheritance: true, ngImport: i0, template: "\n@if (!indexes.length) {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n}\n\n<div [id]=\"uid\" class=\"dcf-grid dcf-grid-small dcf-grid-match dcf-filter-component\" [class.dcf-hidden]=\"!indexes.length\" #component>\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-filter\">\n <div class=\"dcf-input\">\n @for(filter of filterValue; track trackItemFn($index, filter?.['index'])) {\n @if (filter?.['index']) {\n <ion-chip [outline]=\"true\">{{ filter?.['index'] }}</ion-chip>\n }\n @if (filter?.['condition']) {\n <ion-chip [outline]=\"true\">{{ filter?.['condition'] }}</ion-chip>\n }\n @if (filter?.['value']) {\n <ion-chip [outline]=\"true\" class=\"dcf-filter-value\">\n {{ filter?.['value'] }}\n <ion-icon tabindex=\"0\" name=\"close-outline\" (click)=\"removeFilter(filter?.['value'])\" size=\"small\"></ion-icon>\n </ion-chip>\n }\n }\n <div class=\"dcf-width-1-1\">\n <!-- [readonly]=\"step !== 3\" -->\n <input\n fill=\"none\"\n [(ngModel)]=\"value\"\n (keydown.enter)=\"addFilter(value, $event)\"\n (keydown.backspace)=\"clear(value)\"\n (input)=\"handleInput($event)\"\n (click)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n type=\"text\"\n id=\"dcf-filter-field\"\n placeholder=\"{{ locale + (step === 3 ? '.type' : '.select') | translate }}\"\n\n />\n @if (windowWidth >= 768) {\n <div [class]=\"'dcf-dropdown ' + (options.length > 0 ? ' dcf-active' : '')\" #optionsFilterElement>\n <div>\n @if (filteredOptions.length > 0) {\n @for(key of filteredOptions; track key) {\n <div\n class=\"dcf-item\"\n tabindex=\"0\"\n (keydown.enter)=\"selectOption(key)\"\n (click)=\"selectOption(key)\">\n {{ key }}\n </div>\n }\n } @else {\n <div class=\"dcf-empty\"\n (click)=\"filteredOptions = options; value = ''\"\n tabindex=\"0\"\n (keydown.enter)=\"filteredOptions = options; value = ''\"\n >\n {{ locale + '.no_suggestions' | translate }}\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n @if (filterValue.length > 0) {\n <div class=\"dcf-icon-clear\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"clear()\">\n <ion-icon aria-hidden=\"true\" name=\"trash-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n <div class=\"dcf-icon-search\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"submit()\">\n <ion-icon aria-hidden=\"true\" name=\"search-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n </div>\n @if (windowWidth < 768) {\n <div [class]=\"'dcf-dropdown ' + (options.length > 0 ? ' dcf-active' : '')\" #optionsFilterElement>\n <div>\n @if (filteredOptions.length > 0) {\n @for(key of filteredOptions; track key) {\n <div\n class=\"dcf-item\"\n tabindex=\"0\"\n (keydown.enter)=\"selectOption(key)\"\n (click)=\"selectOption(key)\">\n {{ key }}\n </div>\n }\n } @else {\n <div class=\"dcf-empty\"\n (click)=\"filteredOptions = options; value = ''\"\n tabindex=\"0\"\n (keydown.enter)=\"filteredOptions = options; value = ''\"\n >\n {{ locale + '.no_suggestions' | translate }}\n </div>\n }\n </div>\n </div>\n }\n </div>\n @if (!disableSort) {\n <div class=\"dcf-width-1-5@m dcf-width-1-1 dcf-sort-container\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-flex dcf-flex-middle dcf-grid-match\">\n <div class=\"dcf-width-expand\">\n <ion-select\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n class=\"dcf-sort-select\"\n (ionChange)=\"handleSortChange($event)\"\n interface=\"popover\"\n [value]=\"sortValue\"\n label-placement=\"floating\"\n fill=\"outline\"\n [label]=\"locale + '.sort' | translate\"\n >\n @for(sort of sortBy; track sort) {\n\n <ion-select-option [value]=\"sort\">{{ sort | translate }}</ion-select-option>\n }\n </ion-select>\n </div>\n <div class=\"dcf-width-auto\">\n <ion-button (click)=\"handleSortDirectionChange()\" fill=\"clear\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" [color]=\"!isDarkMode ? 'primary' : 'light'\" [name]=\"sortDirection === 'desc' ? 'arrow-down-outline' : 'arrow-up-outline'\"></ion-icon>\n </ion-button>\n </div>\n </div>\n </div>\n }\n</div>\n\n\n", styles: [".dcf-filter-component{padding:0 .5rem;margin-top:.75rem;margin-bottom:.75rem}.dcf-filter-component:not(.dcf-palette-dark) .dcf-filter{border:1px solid var(--dcf-color-gray-3);background-color:#fff}.dcf-filter-component:not(.dcf-palette-dark) .dcf-filter:focus-within{border-color:var(--dcf-color-primary);background-color:#fff}.dcf-filter-component:not(.dcf-palette-dark) ion-chip{border:1px solid var(--dcf-color-gray-3);color:var(--dcf-color-gray-7)}.dcf-filter-component:not(.dcf-palette-dark) ion-chip.dcf-filter-value{background:var(--dcf-color-gray-2);border-color:var(--dcf-color-gray-4)!important;color:var(--dcf-color-gray-8)!important}.dcf-filter-component:not(.dcf-palette-dark) .dcf-input input{color:var(--dcf-color-gray-7)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown{background-color:#fff}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-gray-2)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-8)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-3)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{pointer-events:none;touch-action:none;cursor:text!important;border-color:transparent!important}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-1)}.dcf-filter-component.dcf-palette-dark .dcf-filter{border:1px solid var(--dcf-color-step-500)}.dcf-filter-component.dcf-palette-dark .dcf-filter ::-webkit-input-placeholder,.dcf-filter-component.dcf-palette-dark .dcf-filter ::placeholder{color:var(--dcf-color-gray-4)!important}.dcf-filter-component.dcf-palette-dark .dcf-filter:hover{border-color:var(--dcf-color-gray-2)}.dcf-filter-component.dcf-palette-dark .dcf-filter:focus-within{border-color:var(--dcf-color-gray-2)}.dcf-filter-component.dcf-palette-dark ion-chip{border-color:var(--dcf-color-step-300);background:rgba(var(--dcf-color-medium-rgb),.1)}.dcf-filter-component.dcf-palette-dark ion-chip.dcf-filter-value{background:rgba(var(--dcf-color-medium-rgb),.3)!important;border-color:var(--dcf-color-step-500)}.dcf-filter-component.dcf-palette-dark .dcf-input input{color:var(--dcf-color-gray-1)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown{background-color:var(--dcf-item-background)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-step-600)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-1)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-5)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{cursor:text!important;pointer-events:none;touch-action:none;border-color:transparent!important}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-8)}ion-select{min-height:44px!important}.dcf-hidden{display:none!important}.dcf-filter{display:flex;width:100%;min-height:40px;box-shadow:0 1px 2px #0a0d120d;border-radius:var(--dcf-border-radius);box-sizing:border-box}.dcf-filter ion-chip{border-radius:6px;padding:0 8px!important;height:24px;min-height:24px;font-size:.75rem;font-style:normal;font-weight:500;flex-shrink:0;margin-right:2px;white-space:nowrap}.dcf-filter ion-chip.sc-ion-chip-md-h,.dcf-filter ion-chip.sc-ion-chip-ios-h{height:24px;min-height:24px}.dcf-filter ion-chip.sc-ion-chip-md-h .chip-native,.dcf-filter ion-chip.sc-ion-chip-ios-h .chip-native{padding:0 8px!important;height:24px;min-height:24px}.dcf-filter ion-chip ion-label{padding:0 4px;margin:0;font-size:.75rem;white-space:nowrap}.dcf-filter ion-chip ion-icon{margin:0 2px;font-size:.75rem}.dcf-filter .dcf-input{width:100%;display:flex;align-items:center;overflow-x:auto;overflow-y:hidden;white-space:nowrap;padding-left:.5rem}.dcf-filter .dcf-input input{min-height:40px;min-width:100px;width:100%;font-size:1rem;border:none;outline:none;background:transparent;border:0px!important;outline:none!important}.dcf-filter .dcf-input input:focus{border:0px!important;outline:none!important}.dcf-filter .dcf-icon-clear,.dcf-filter .dcf-icon-search{display:flex;justify-content:center;text-align:center;align-items:center;min-width:40px}.dcf-filter .dcf-icon-search ion-icon{font-size:1.25rem}.dcf-sort-container{min-width:200px!important;width:auto}@media (min-width: 990px){.dcf-sort-container{max-width:20%!important}}@media (max-width: 680px){.dcf-sort-container{min-width:100%!important;margin:.75rem 0rem}}.dcf-dropdown{position:absolute;max-height:200px;overflow-y:auto;border-radius:4px;z-index:1000!important;min-width:200px;max-width:300px;display:none}.dcf-dropdown.dcf-active{display:block;margin-top:-3px;box-shadow:0 12px 16px -4px #0a0d1214,0 4px 6px -2px #0a0d1208,0 2px 2px -1px #0a0d120a!important;border-radius:var(--dcf-border-radius);padding:.5rem .25rem}@media (max-width: 768px){.dcf-dropdown.dcf-active{margin-top:55px}}.dcf-dropdown.dcf-active>div>div{cursor:pointer;height:35px;padding:.5rem 1rem;border:1px solid transparent;font-size:1rem;display:flex;align-items:center;border-radius:6px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: IonChip, selector: "ion-chip", inputs: ["color", "disabled", "mode", "outline"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: 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: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "errorText", "expandedIcon", "fill", "helperText", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: SearchbarComponent, selector: "ngx-decaf-searchbar", inputs: ["autocomplete", "autocorrect", "animated", "buttonCancelText", "clearIcon", "color", "debounce", "disabled", "enterkeyhint", "inputmode", "placeholder", "searchIcon", "showCancelButton", "showClearButton", "spellcheck", "type", "value", "queryKeys", "isVisible", "wrapper", "wrapperColor", "emitEventToWindow"], outputs: ["searchEvent"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
8003
8650
|
};
|
|
8004
8651
|
FilterComponent = __decorate([
|
|
8005
8652
|
Dynamic(),
|
|
@@ -8017,7 +8664,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
|
|
|
8017
8664
|
IonSelectOption,
|
|
8018
8665
|
IonIcon,
|
|
8019
8666
|
SearchbarComponent
|
|
8020
|
-
], standalone: true, host: { '[attr.id]': 'uid' }, template: "\n@if (!indexes.length) {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n}\n\n<div [id]=\"uid\" class=\"dcf-grid dcf-grid-small dcf-grid-match dcf-filter-component\" [class.dcf-hidden]=\"!indexes.length\" #component>\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-filter\">\n <div class=\"dcf-input\">\n @for(filter of filterValue; track trackItemFn($index, filter?.['index'])) {\n @if (filter?.['index']) {\n <ion-chip [outline]=\"true\">{{ filter?.['index'] }}</ion-chip>\n }\n @if (filter?.['condition']) {\n <ion-chip [outline]=\"true\">{{ filter?.['condition'] }}</ion-chip>\n }\n @if (filter?.['value']) {\n <ion-chip [outline]=\"true\" class=\"dcf-filter-value\">\n {{ filter?.['value'] }}\n <ion-icon name=\"close-outline\" (click)=\"removeFilter(filter?.['value'])\" size=\"small\"></ion-icon>\n </ion-chip>\n }\n }\n <div class=\"dcf-width-1-1\">\n <!-- [readonly]=\"step !== 3\" -->\n <input\n fill=\"none\"\n [(ngModel)]=\"value\"\n (keydown.enter)=\"addFilter(value, $event)\"\n (keydown.backspace)=\"clear(value)\"\n (input)=\"handleInput($event)\"\n (click)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n type=\"text\"\n id=\"dcf-filter-field\"\n placeholder=\"{{ locale + (step === 3 ? '.type' : '.select') | translate }}\"\n\n />\n @if (windowWidth >= 768) {\n <div [class]=\"'dcf-dropdown ' + (options.length > 0 ? ' dcf-active' : '')\" #optionsFilterElement>\n <div>\n @if (filteredOptions.length > 0) {\n @for(key of filteredOptions; track key) {\n <div\n class=\"dcf-item\"\n tabindex=\"0\"\n (keydown.enter)=\"selectOption(key)\"\n (click)=\"selectOption(key)\">\n {{ key }}\n </div>\n }\n } @else {\n <div class=\"dcf-empty\"\n (click)=\"filteredOptions = options; value = ''\"\n tabindex=\"0\"\n (keydown.enter)=\"filteredOptions = options; value = ''\"\n >\n {{ locale + '.no_suggestions' | translate }}\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n @if (filterValue.length > 0) {\n <div class=\"dcf-icon-clear\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"clear()\">\n <ion-icon name=\"trash-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n <div class=\"dcf-icon-search\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"submit()\">\n <ion-icon name=\"search-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n </div>\n @if (windowWidth < 768) {\n <div [class]=\"'dcf-dropdown ' + (options.length > 0 ? ' dcf-active' : '')\" #optionsFilterElement>\n <div>\n @if (filteredOptions.length > 0) {\n @for(key of filteredOptions; track key) {\n <div\n class=\"dcf-item\"\n tabindex=\"0\"\n (keydown.enter)=\"selectOption(key)\"\n (click)=\"selectOption(key)\">\n {{ key }}\n </div>\n }\n } @else {\n <div class=\"dcf-empty\"\n (click)=\"filteredOptions = options; value = ''\"\n tabindex=\"0\"\n (keydown.enter)=\"filteredOptions = options; value = ''\"\n >\n {{ locale + '.no_suggestions' | translate }}\n </div>\n }\n </div>\n </div>\n }\n </div>\n @if (!disableSort) {\n <div class=\"dcf-width-1-5@m dcf-width-1-1 dcf-sort-container\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-flex dcf-flex-middle dcf-grid-match\">\n <div class=\"dcf-width-expand\">\n <ion-select\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n class=\"dcf-sort-select\"\n (ionChange)=\"handleSortChange($event)\"\n interface=\"popover\"\n [value]=\"sortValue\"\n label-placement=\"floating\"\n fill=\"outline\"\n [label]=\"locale + '.sort' | translate\"\n >\n @for(sort of sortBy; track sort) {\n\n <ion-select-option [value]=\"sort\">{{ sort | translate }}</ion-select-option>\n }\n </ion-select>\n </div>\n <div class=\"dcf-width-auto\">\n <ion-button (click)=\"handleSortDirectionChange()\" fill=\"clear\">\n <ion-icon slot=\"icon-only\" [color]=\"!isDarkMode ? 'primary' : 'light'\" [name]=\"sortDirection === 'desc' ? 'arrow-down-outline' : 'arrow-up-outline'\"></ion-icon>\n </ion-button>\n </div>\n </div>\n </div>\n }\n</div>\n\n\n", styles: [".dcf-filter-component{padding:0 .5rem;margin-top:.75rem;margin-bottom:.75rem}.dcf-filter-component:not(.dcf-palette-dark) .dcf-filter{border:1px solid var(--dcf-color-gray-3);background-color:#fff}.dcf-filter-component:not(.dcf-palette-dark) .dcf-filter:focus-within{border-color:var(--dcf-color-primary);background-color:#fff}.dcf-filter-component:not(.dcf-palette-dark) ion-chip{border:1px solid var(--dcf-color-gray-3);color:var(--dcf-color-gray-7)}.dcf-filter-component:not(.dcf-palette-dark) ion-chip.dcf-filter-value{background:var(--dcf-color-gray-2);border-color:var(--dcf-color-gray-4)!important;color:var(--dcf-color-gray-8)!important}.dcf-filter-component:not(.dcf-palette-dark) .dcf-input input{color:var(--dcf-color-gray-7)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown{background-color:#fff}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-gray-2)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-8)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-3)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{pointer-events:none;touch-action:none;cursor:text!important;border-color:transparent!important}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-1)}.dcf-filter-component.dcf-palette-dark .dcf-filter{border:1px solid var(--dcf-color-step-500)}.dcf-filter-component.dcf-palette-dark .dcf-filter ::-webkit-input-placeholder,.dcf-filter-component.dcf-palette-dark .dcf-filter ::placeholder{color:var(--dcf-color-gray-4)!important}.dcf-filter-component.dcf-palette-dark .dcf-filter:hover{border-color:var(--dcf-color-gray-2)}.dcf-filter-component.dcf-palette-dark .dcf-filter:focus-within{border-color:var(--dcf-color-gray-2)}.dcf-filter-component.dcf-palette-dark ion-chip{border-color:var(--dcf-color-step-300);background:rgba(var(--dcf-color-medium-rgb),.1)}.dcf-filter-component.dcf-palette-dark ion-chip.dcf-filter-value{background:rgba(var(--dcf-color-medium-rgb),.3)!important;border-color:var(--dcf-color-step-500)}.dcf-filter-component.dcf-palette-dark .dcf-input input{color:var(--dcf-color-gray-1)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown{background-color:var(--dcf-item-background)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-step-600)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-1)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-5)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{cursor:text!important;pointer-events:none;touch-action:none;border-color:transparent!important}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-8)}ion-select{min-height:44px!important}.dcf-hidden{display:none!important}.dcf-filter{display:flex;width:100%;min-height:40px;box-shadow:0 1px 2px #0a0d120d;border-radius:var(--dcf-border-radius);box-sizing:border-box}.dcf-filter ion-chip{border-radius:6px;padding:0 8px!important;height:24px;min-height:24px;font-size:.75rem;font-style:normal;font-weight:500;flex-shrink:0;margin-right:2px;white-space:nowrap}.dcf-filter ion-chip.sc-ion-chip-md-h,.dcf-filter ion-chip.sc-ion-chip-ios-h{height:24px;min-height:24px}.dcf-filter ion-chip.sc-ion-chip-md-h .chip-native,.dcf-filter ion-chip.sc-ion-chip-ios-h .chip-native{padding:0 8px!important;height:24px;min-height:24px}.dcf-filter ion-chip ion-label{padding:0 4px;margin:0;font-size:.75rem;white-space:nowrap}.dcf-filter ion-chip ion-icon{margin:0 2px;font-size:.75rem}.dcf-filter .dcf-input{width:100%;display:flex;align-items:center;overflow-x:auto;overflow-y:hidden;white-space:nowrap;padding-left:.5rem}.dcf-filter .dcf-input input{min-height:40px;min-width:100px;width:100%;font-size:1rem;border:none;outline:none;background:transparent;border:0px!important;outline:none!important}.dcf-filter .dcf-input input:focus{border:0px!important;outline:none!important}.dcf-filter .dcf-icon-clear,.dcf-filter .dcf-icon-search{display:flex;justify-content:center;text-align:center;align-items:center;min-width:40px}.dcf-filter .dcf-icon-search ion-icon{font-size:1.25rem}.dcf-sort-container{min-width:200px!important;width:auto}@media (min-width: 990px){.dcf-sort-container{max-width:20%!important}}@media (max-width: 680px){.dcf-sort-container{min-width:100%!important;margin:.75rem 0rem}}.dcf-dropdown{position:absolute;max-height:200px;overflow-y:auto;border-radius:4px;z-index:1000!important;min-width:200px;max-width:300px;display:none}.dcf-dropdown.dcf-active{display:block;margin-top:-3px;box-shadow:0 12px 16px -4px #0a0d1214,0 4px 6px -2px #0a0d1208,0 2px 2px -1px #0a0d120a!important;border-radius:var(--dcf-border-radius);padding:.5rem .25rem}@media (max-width: 768px){.dcf-dropdown.dcf-active{margin-top:55px}}.dcf-dropdown.dcf-active>div>div{cursor:pointer;height:35px;padding:.5rem 1rem;border:1px solid transparent;font-size:1rem;display:flex;align-items:center;border-radius:6px}\n"] }]
|
|
8667
|
+
], standalone: true, host: { '[attr.id]': 'uid' }, template: "\n@if (!indexes.length) {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n}\n\n<div [id]=\"uid\" class=\"dcf-grid dcf-grid-small dcf-grid-match dcf-filter-component\" [class.dcf-hidden]=\"!indexes.length\" #component>\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-filter\">\n <div class=\"dcf-input\">\n @for(filter of filterValue; track trackItemFn($index, filter?.['index'])) {\n @if (filter?.['index']) {\n <ion-chip [outline]=\"true\">{{ filter?.['index'] }}</ion-chip>\n }\n @if (filter?.['condition']) {\n <ion-chip [outline]=\"true\">{{ filter?.['condition'] }}</ion-chip>\n }\n @if (filter?.['value']) {\n <ion-chip [outline]=\"true\" class=\"dcf-filter-value\">\n {{ filter?.['value'] }}\n <ion-icon tabindex=\"0\" name=\"close-outline\" (click)=\"removeFilter(filter?.['value'])\" size=\"small\"></ion-icon>\n </ion-chip>\n }\n }\n <div class=\"dcf-width-1-1\">\n <!-- [readonly]=\"step !== 3\" -->\n <input\n fill=\"none\"\n [(ngModel)]=\"value\"\n (keydown.enter)=\"addFilter(value, $event)\"\n (keydown.backspace)=\"clear(value)\"\n (input)=\"handleInput($event)\"\n (click)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n type=\"text\"\n id=\"dcf-filter-field\"\n placeholder=\"{{ locale + (step === 3 ? '.type' : '.select') | translate }}\"\n\n />\n @if (windowWidth >= 768) {\n <div [class]=\"'dcf-dropdown ' + (options.length > 0 ? ' dcf-active' : '')\" #optionsFilterElement>\n <div>\n @if (filteredOptions.length > 0) {\n @for(key of filteredOptions; track key) {\n <div\n class=\"dcf-item\"\n tabindex=\"0\"\n (keydown.enter)=\"selectOption(key)\"\n (click)=\"selectOption(key)\">\n {{ key }}\n </div>\n }\n } @else {\n <div class=\"dcf-empty\"\n (click)=\"filteredOptions = options; value = ''\"\n tabindex=\"0\"\n (keydown.enter)=\"filteredOptions = options; value = ''\"\n >\n {{ locale + '.no_suggestions' | translate }}\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n @if (filterValue.length > 0) {\n <div class=\"dcf-icon-clear\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"clear()\">\n <ion-icon aria-hidden=\"true\" name=\"trash-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n <div class=\"dcf-icon-search\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"submit()\">\n <ion-icon aria-hidden=\"true\" name=\"search-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n </div>\n @if (windowWidth < 768) {\n <div [class]=\"'dcf-dropdown ' + (options.length > 0 ? ' dcf-active' : '')\" #optionsFilterElement>\n <div>\n @if (filteredOptions.length > 0) {\n @for(key of filteredOptions; track key) {\n <div\n class=\"dcf-item\"\n tabindex=\"0\"\n (keydown.enter)=\"selectOption(key)\"\n (click)=\"selectOption(key)\">\n {{ key }}\n </div>\n }\n } @else {\n <div class=\"dcf-empty\"\n (click)=\"filteredOptions = options; value = ''\"\n tabindex=\"0\"\n (keydown.enter)=\"filteredOptions = options; value = ''\"\n >\n {{ locale + '.no_suggestions' | translate }}\n </div>\n }\n </div>\n </div>\n }\n </div>\n @if (!disableSort) {\n <div class=\"dcf-width-1-5@m dcf-width-1-1 dcf-sort-container\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-flex dcf-flex-middle dcf-grid-match\">\n <div class=\"dcf-width-expand\">\n <ion-select\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n class=\"dcf-sort-select\"\n (ionChange)=\"handleSortChange($event)\"\n interface=\"popover\"\n [value]=\"sortValue\"\n label-placement=\"floating\"\n fill=\"outline\"\n [label]=\"locale + '.sort' | translate\"\n >\n @for(sort of sortBy; track sort) {\n\n <ion-select-option [value]=\"sort\">{{ sort | translate }}</ion-select-option>\n }\n </ion-select>\n </div>\n <div class=\"dcf-width-auto\">\n <ion-button (click)=\"handleSortDirectionChange()\" fill=\"clear\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" [color]=\"!isDarkMode ? 'primary' : 'light'\" [name]=\"sortDirection === 'desc' ? 'arrow-down-outline' : 'arrow-up-outline'\"></ion-icon>\n </ion-button>\n </div>\n </div>\n </div>\n }\n</div>\n\n\n", styles: [".dcf-filter-component{padding:0 .5rem;margin-top:.75rem;margin-bottom:.75rem}.dcf-filter-component:not(.dcf-palette-dark) .dcf-filter{border:1px solid var(--dcf-color-gray-3);background-color:#fff}.dcf-filter-component:not(.dcf-palette-dark) .dcf-filter:focus-within{border-color:var(--dcf-color-primary);background-color:#fff}.dcf-filter-component:not(.dcf-palette-dark) ion-chip{border:1px solid var(--dcf-color-gray-3);color:var(--dcf-color-gray-7)}.dcf-filter-component:not(.dcf-palette-dark) ion-chip.dcf-filter-value{background:var(--dcf-color-gray-2);border-color:var(--dcf-color-gray-4)!important;color:var(--dcf-color-gray-8)!important}.dcf-filter-component:not(.dcf-palette-dark) .dcf-input input{color:var(--dcf-color-gray-7)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown{background-color:#fff}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-gray-2)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-8)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-3)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{pointer-events:none;touch-action:none;cursor:text!important;border-color:transparent!important}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-1)}.dcf-filter-component.dcf-palette-dark .dcf-filter{border:1px solid var(--dcf-color-step-500)}.dcf-filter-component.dcf-palette-dark .dcf-filter ::-webkit-input-placeholder,.dcf-filter-component.dcf-palette-dark .dcf-filter ::placeholder{color:var(--dcf-color-gray-4)!important}.dcf-filter-component.dcf-palette-dark .dcf-filter:hover{border-color:var(--dcf-color-gray-2)}.dcf-filter-component.dcf-palette-dark .dcf-filter:focus-within{border-color:var(--dcf-color-gray-2)}.dcf-filter-component.dcf-palette-dark ion-chip{border-color:var(--dcf-color-step-300);background:rgba(var(--dcf-color-medium-rgb),.1)}.dcf-filter-component.dcf-palette-dark ion-chip.dcf-filter-value{background:rgba(var(--dcf-color-medium-rgb),.3)!important;border-color:var(--dcf-color-step-500)}.dcf-filter-component.dcf-palette-dark .dcf-input input{color:var(--dcf-color-gray-1)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown{background-color:var(--dcf-item-background)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-step-600)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-1)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-5)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{cursor:text!important;pointer-events:none;touch-action:none;border-color:transparent!important}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-8)}ion-select{min-height:44px!important}.dcf-hidden{display:none!important}.dcf-filter{display:flex;width:100%;min-height:40px;box-shadow:0 1px 2px #0a0d120d;border-radius:var(--dcf-border-radius);box-sizing:border-box}.dcf-filter ion-chip{border-radius:6px;padding:0 8px!important;height:24px;min-height:24px;font-size:.75rem;font-style:normal;font-weight:500;flex-shrink:0;margin-right:2px;white-space:nowrap}.dcf-filter ion-chip.sc-ion-chip-md-h,.dcf-filter ion-chip.sc-ion-chip-ios-h{height:24px;min-height:24px}.dcf-filter ion-chip.sc-ion-chip-md-h .chip-native,.dcf-filter ion-chip.sc-ion-chip-ios-h .chip-native{padding:0 8px!important;height:24px;min-height:24px}.dcf-filter ion-chip ion-label{padding:0 4px;margin:0;font-size:.75rem;white-space:nowrap}.dcf-filter ion-chip ion-icon{margin:0 2px;font-size:.75rem}.dcf-filter .dcf-input{width:100%;display:flex;align-items:center;overflow-x:auto;overflow-y:hidden;white-space:nowrap;padding-left:.5rem}.dcf-filter .dcf-input input{min-height:40px;min-width:100px;width:100%;font-size:1rem;border:none;outline:none;background:transparent;border:0px!important;outline:none!important}.dcf-filter .dcf-input input:focus{border:0px!important;outline:none!important}.dcf-filter .dcf-icon-clear,.dcf-filter .dcf-icon-search{display:flex;justify-content:center;text-align:center;align-items:center;min-width:40px}.dcf-filter .dcf-icon-search ion-icon{font-size:1.25rem}.dcf-sort-container{min-width:200px!important;width:auto}@media (min-width: 990px){.dcf-sort-container{max-width:20%!important}}@media (max-width: 680px){.dcf-sort-container{min-width:100%!important;margin:.75rem 0rem}}.dcf-dropdown{position:absolute;max-height:200px;overflow-y:auto;border-radius:4px;z-index:1000!important;min-width:200px;max-width:300px;display:none}.dcf-dropdown.dcf-active{display:block;margin-top:-3px;box-shadow:0 12px 16px -4px #0a0d1214,0 4px 6px -2px #0a0d1208,0 2px 2px -1px #0a0d120a!important;border-radius:var(--dcf-border-radius);padding:.5rem .25rem}@media (max-width: 768px){.dcf-dropdown.dcf-active{margin-top:55px}}.dcf-dropdown.dcf-active>div>div{cursor:pointer;height:35px;padding:.5rem 1rem;border:1px solid transparent;font-size:1rem;display:flex;align-items:center;border-radius:6px}\n"] }]
|
|
8021
8668
|
}], ctorParameters: () => [], propDecorators: { optionsFilterElement: [{
|
|
8022
8669
|
type: ViewChild,
|
|
8023
8670
|
args: ['optionsFilterElement', { read: ElementRef, static: false }]
|
|
@@ -8170,7 +8817,7 @@ class PaginationComponent extends NgxComponentDirective {
|
|
|
8170
8817
|
if (page)
|
|
8171
8818
|
this.current = page;
|
|
8172
8819
|
this.clickEvent.emit({
|
|
8173
|
-
name:
|
|
8820
|
+
name: ComponentEventNames.CLICK,
|
|
8174
8821
|
data: {
|
|
8175
8822
|
direction,
|
|
8176
8823
|
page: this.current
|
|
@@ -8745,11 +9392,11 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
|
|
|
8745
9392
|
this.item['tag'] = ComponentsTagNames.LIST_ITEM;
|
|
8746
9393
|
this.empty = Object.assign({}, DefaultListEmptyOptions, this.empty);
|
|
8747
9394
|
await this.refresh();
|
|
8748
|
-
// if (this.operations.includes(OperationKeys.CREATE) && this.route)
|
|
8749
|
-
// this.empty.link = `${this.route}/${OperationKeys.CREATE}`;
|
|
8750
9395
|
if (!this.initialized)
|
|
8751
|
-
|
|
9396
|
+
this.parseProps(this);
|
|
8752
9397
|
this.initialized = true;
|
|
9398
|
+
if (this.isModalChild)
|
|
9399
|
+
this.changeDetectorRef.detectChanges();
|
|
8753
9400
|
}
|
|
8754
9401
|
/**
|
|
8755
9402
|
* @description Cleans up resources when the component is destroyed.
|
|
@@ -8926,6 +9573,8 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
|
|
|
8926
9573
|
this.page = 1;
|
|
8927
9574
|
}
|
|
8928
9575
|
this.searchValue = value;
|
|
9576
|
+
if (this.isModalChild)
|
|
9577
|
+
this.changeDetectorRef.detectChanges();
|
|
8929
9578
|
await this.refresh(true);
|
|
8930
9579
|
}
|
|
8931
9580
|
else {
|
|
@@ -8959,6 +9608,8 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
|
|
|
8959
9608
|
*/
|
|
8960
9609
|
async clearSearch() {
|
|
8961
9610
|
await this.handleSearch(undefined);
|
|
9611
|
+
if (this.isModalChild)
|
|
9612
|
+
this.changeDetectorRef.detectChanges();
|
|
8962
9613
|
}
|
|
8963
9614
|
/**
|
|
8964
9615
|
* @description Emits a refresh event with the current data.
|
|
@@ -8975,7 +9626,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
|
|
|
8975
9626
|
data = this.items;
|
|
8976
9627
|
this.skeletonData = new Array(data?.length || 2);
|
|
8977
9628
|
this.refreshEvent.emit({
|
|
8978
|
-
name:
|
|
9629
|
+
name: ComponentEventNames.REFRESH,
|
|
8979
9630
|
data: data || [],
|
|
8980
9631
|
component: this.componentName
|
|
8981
9632
|
});
|
|
@@ -9046,7 +9697,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
|
|
|
9046
9697
|
* @memberOf ListComponent
|
|
9047
9698
|
*/
|
|
9048
9699
|
async refresh(event = false) {
|
|
9049
|
-
// if (typeof force !== 'boolean' && force.type ===
|
|
9700
|
+
// if (typeof force !== 'boolean' && force.type === ComponentEventNames.BACK_BUTTON_NAVIGATION) {
|
|
9050
9701
|
// const {refresh} = (force as CustomEvent).detail;
|
|
9051
9702
|
// if (!refresh)
|
|
9052
9703
|
// return false;
|
|
@@ -9057,7 +9708,6 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
|
|
|
9057
9708
|
this.data = !this.model ?
|
|
9058
9709
|
await this.getFromRequest(!!event, start, limit)
|
|
9059
9710
|
: await this.getFromModel(!!event);
|
|
9060
|
-
this.refreshEventEmit();
|
|
9061
9711
|
if (this.type === ListComponentsTypes.INFINITE) {
|
|
9062
9712
|
if (this.page === this.pages) {
|
|
9063
9713
|
if (event?.target)
|
|
@@ -9068,7 +9718,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
|
|
|
9068
9718
|
this.page += 1;
|
|
9069
9719
|
this.refreshing = false;
|
|
9070
9720
|
setTimeout(() => {
|
|
9071
|
-
if (event?.target && event?.type !==
|
|
9721
|
+
if (event?.target && event?.type !== ComponentEventNames.BACK_BUTTON_NAVIGATION)
|
|
9072
9722
|
event.target.complete();
|
|
9073
9723
|
}, 200);
|
|
9074
9724
|
}
|
|
@@ -9127,7 +9777,11 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
|
|
|
9127
9777
|
* @memberOf ListComponent
|
|
9128
9778
|
*/
|
|
9129
9779
|
parseSearchResults(results, search) {
|
|
9130
|
-
|
|
9780
|
+
const filtered = results.filter((item) => Object.values(item).some(v => {
|
|
9781
|
+
if (v.toString().toLowerCase().includes(search?.toLowerCase()))
|
|
9782
|
+
return v;
|
|
9783
|
+
}));
|
|
9784
|
+
return filtered;
|
|
9131
9785
|
}
|
|
9132
9786
|
/**
|
|
9133
9787
|
* @description Fetches data from a request source.
|
|
@@ -9143,7 +9797,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
|
|
|
9143
9797
|
* @memberOf ListComponent
|
|
9144
9798
|
*/
|
|
9145
9799
|
async getFromRequest(force = false, start, limit) {
|
|
9146
|
-
let
|
|
9800
|
+
let data = [...this.data || []];
|
|
9147
9801
|
if (!this.data?.length || force || this.searchValue?.length || !!this.searchValue) {
|
|
9148
9802
|
// (self.data as ListItem[]) = [];
|
|
9149
9803
|
if (!this.searchValue?.length && !this.searchValue) {
|
|
@@ -9151,20 +9805,31 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
|
|
|
9151
9805
|
this.logger.info('No data and source passed to infinite list');
|
|
9152
9806
|
return [];
|
|
9153
9807
|
}
|
|
9154
|
-
if (this.source instanceof Function)
|
|
9155
|
-
|
|
9156
|
-
|
|
9157
|
-
|
|
9158
|
-
|
|
9808
|
+
if (this.source instanceof Function) {
|
|
9809
|
+
data = await this.source();
|
|
9810
|
+
if (!Array.isArray(data))
|
|
9811
|
+
data = data?.['response']?.['data'] || data?.['results'] || [];
|
|
9812
|
+
}
|
|
9813
|
+
if (!data?.length && this.data?.length)
|
|
9814
|
+
data = this.data;
|
|
9815
|
+
this.data = [...await this.parseResult(data)];
|
|
9159
9816
|
if (this.data?.length)
|
|
9160
9817
|
this.items = this.type === ListComponentsTypes.INFINITE ?
|
|
9161
|
-
(this.items || []).concat([...this.data.slice(start, limit)]) : [...
|
|
9818
|
+
(this.items || []).concat([...this.data.slice(start, limit)]) : [...data.slice(start, limit)];
|
|
9162
9819
|
}
|
|
9163
9820
|
else {
|
|
9164
|
-
|
|
9165
|
-
this.items =
|
|
9821
|
+
const data = await this.parseResult(this.parseSearchResults(this.data, this.searchValue));
|
|
9822
|
+
this.items = [...data];
|
|
9823
|
+
if (this.isModalChild)
|
|
9824
|
+
this.changeDetectorRef.detectChanges();
|
|
9166
9825
|
}
|
|
9167
9826
|
}
|
|
9827
|
+
else {
|
|
9828
|
+
const data = [...await this.parseResult(this.data)];
|
|
9829
|
+
this.items = this.type === ListComponentsTypes.INFINITE ? [...(this.items || []), ...(data || [])] : [...(data || [])];
|
|
9830
|
+
if (this.isModalChild)
|
|
9831
|
+
this.changeDetectorRef.detectChanges();
|
|
9832
|
+
}
|
|
9168
9833
|
if (this.loadMoreData && this.type === ListComponentsTypes.PAGINATED)
|
|
9169
9834
|
this.getMoreData(this.data?.length || 0);
|
|
9170
9835
|
return this.data || [];
|
|
@@ -9457,7 +10122,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
|
|
|
9457
10122
|
return (searchValue?.query).map(item => `${item.index} ${item.condition} ${item.value}`).join(", ");
|
|
9458
10123
|
}
|
|
9459
10124
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9460
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: ListComponent, isStandalone: true, selector: "ngx-decaf-list", inputs: { type: "type", showSearchbar: "showSearchbar", data: "data", source: "source", start: "start", limit: "limit", loadMoreData: "loadMoreData", lines: "lines", inset: "inset", scrollThreshold: "scrollThreshold", scrollPosition: "scrollPosition", loadingText: "loadingText", showRefresher: "showRefresher", loadingSpinner: "loadingSpinner", enableFilter: "enableFilter", sortDirection: "sortDirection", sortBy: "sortBy", disableSort: "disableSort", empty: "empty" }, outputs: { refreshEvent: "refreshEvent", clickEvent: "clickEvent" }, host: { listeners: { "window:ListItemClickEvent": "handleClick($event)", "window:searchbarEvent": "handleSearch($event)", "window:BackButtonNavigationEndEvent": "refresh($event)" }, properties: { "attr.id": "uid" } }, usesInheritance: true, ngImport: i0, template: "\n@if (showRefresher) {\n <ion-refresher slot=\"fixed\" [pullFactor]=\"1\" [pullMin]=\"100\" [pullMax]=\"200\" (ionRefresh)=\"handleRefresh($event)\">\n <ion-refresher-content />\n </ion-refresher>\n}\n\n@if (showSearchbar) {\n @if (model && enableFilter) {\n @if (data?.length || searching) {\n <ngx-decaf-filter\n [model]=\"model\"\n [sortDirection]=\"sortDirection\"\n [disableSort]=\"disableSort\"\n (filterEvent)=\"handleFilter($event)\"\n (searchEvent)=\"handleSearch($event)\"\n />\n }\n } @else {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n }\n}\n\n@if (data?.length) {\n <ion-list [id]=\"uid\" [inset]=\"inset\" [lines]=\"lines\"
|
|
10125
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: ListComponent, isStandalone: true, selector: "ngx-decaf-list", inputs: { type: "type", showSearchbar: "showSearchbar", data: "data", source: "source", start: "start", limit: "limit", loadMoreData: "loadMoreData", lines: "lines", inset: "inset", scrollThreshold: "scrollThreshold", scrollPosition: "scrollPosition", loadingText: "loadingText", showRefresher: "showRefresher", loadingSpinner: "loadingSpinner", enableFilter: "enableFilter", sortDirection: "sortDirection", sortBy: "sortBy", disableSort: "disableSort", empty: "empty" }, outputs: { refreshEvent: "refreshEvent", clickEvent: "clickEvent" }, host: { listeners: { "window:ListItemClickEvent": "handleClick($event)", "window:searchbarEvent": "handleSearch($event)", "window:BackButtonNavigationEndEvent": "refresh($event)" }, properties: { "attr.id": "uid" } }, usesInheritance: true, ngImport: i0, template: "<div #component>\n\n</div>\n@if (showRefresher) {\n <ion-refresher slot=\"fixed\" [pullFactor]=\"1\" [pullMin]=\"100\" [pullMax]=\"200\" (ionRefresh)=\"handleRefresh($event)\">\n <ion-refresher-content />\n </ion-refresher>\n}\n\n@if (showSearchbar) {\n @if (model && enableFilter) {\n @if (data?.length || searching) {\n <ngx-decaf-filter\n [model]=\"model\"\n [sortDirection]=\"sortDirection\"\n [disableSort]=\"disableSort\"\n (filterEvent)=\"handleFilter($event)\"\n (searchEvent)=\"handleSearch($event)\"\n />\n }\n } @else {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n }\n}\n\n@if (initialized && data?.length) {\n <ion-list [id]=\"uid\" [inset]=\"inset\" [lines]=\"lines\">\n @if (item?.tag) {\n @for(child of items; track trackItemFn($index, child)) {\n <ngx-decaf-component-renderer\n [tag]=\"item.tag\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]='{\n item: child,\n mapper: mapper,\n route: route\n }'>\n </ngx-decaf-component-renderer>\n }\n } @else {\n <ng-content></ng-content>\n }\n </ion-list>\n\n @if (loadMoreData) {\n @if (pages > 0 && type === 'paginated' && !searchValue?.length) {\n <ngx-decaf-pagination\n [totalPages]=\"pages\"\n [current]=\"page\"\n (clickEvent)=\"handlePaginate($event)\"\n />\n\n } @else {\n <ion-infinite-scroll\n [class]=\"searchValue?.length ? 'dcf-hidden' : ''\"\n\n [position]=\"scrollPosition\"\n [threshold]=\"scrollThreshold\"\n (ionInfinite)=\"handleRefresh($event)\">\n <ion-infinite-scroll-content [loadingSpinner]=\"loadingSpinner\" [loadingText]=\"loadingText\" />\n </ion-infinite-scroll>\n }\n }\n} @else {\n @if (refreshing) {\n @for(skl of skeletonData; track $index) {\n <ion-item>\n <ion-thumbnail slot=\"start\">\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n </ion-thumbnail>\n <ion-label>\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%;\"><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text></ion-text>\n </ion-label>\n </ion-item>\n }\n\n } @else {\n @if (!searching) {\n <ngx-decaf-empty-state\n [title]=\"(locale + '.'+ empty.title) | translate\"\n [model]=\"model\"\n [icon]=\"empty.icon\"\n className=\"dcf-empty-data\"\n [subtitle]=\"(locale + '.'+ empty.subtitle) | translate\" />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n [model]=\"model\"\n className=\"empty-search\"\n [translatable]=\"true\"\n className=\"dcf-empty-data\"\n [title]=\"locale + '.search.title' | translate\"\n [subtitle]=\"locale + '.search.subtitle' | translate: {'0': parseSearchValue()}\"\n [searchValue]=\"searchValue\"\n />\n }\n }\n}\n\n", styles: ["ion-infinite-scroll{max-height:50px}ion-infinite-scroll:not(.infinite-scroll-loading) ::ng-deep{max-height:1.5rem}ion-infinite-scroll ::ng-deep ion-spinner{--color: var(--dcf-color-primary);padding-top:1rem}@media (max-width: 768px){#end,[slot=end]{display:none!important}}\n"], dependencies: [{ kind: "component", type: IonRefresher, selector: "ion-refresher", inputs: ["closeDuration", "disabled", "mode", "pullFactor", "pullMax", "pullMin", "snapbackDuration"] }, { kind: "component", type: PaginationComponent, selector: "ngx-decaf-pagination", inputs: ["totalPages", "current"], outputs: ["clickEvent"] }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonThumbnail, selector: "ion-thumbnail" }, { kind: "component", type: IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: IonRefresherContent, selector: "ion-refresher-content", inputs: ["pullingIcon", "pullingText", "refreshingSpinner", "refreshingText"] }, { kind: "component", type: IonInfiniteScroll, selector: "ion-infinite-scroll", inputs: ["disabled", "position", "threshold"] }, { kind: "component", type: IonInfiniteScrollContent, selector: "ion-infinite-scroll-content", inputs: ["loadingSpinner", "loadingText"] }, { kind: "component", type: SearchbarComponent, selector: "ngx-decaf-searchbar", inputs: ["autocomplete", "autocorrect", "animated", "buttonCancelText", "clearIcon", "color", "debounce", "disabled", "enterkeyhint", "inputmode", "placeholder", "searchIcon", "showCancelButton", "showClearButton", "spellcheck", "type", "value", "queryKeys", "isVisible", "wrapper", "wrapperColor", "emitEventToWindow"], outputs: ["searchEvent"] }, { kind: "component", type: EmptyStateComponent, selector: "ngx-decaf-empty-state", inputs: ["title", "titleColor", "subtitle", "subtitleColor", "showIcon", "icon", "iconSize", "iconColor", "buttonLink", "buttonText", "buttonFill", "buttonColor", "buttonSize", "searchValue"] }, { kind: "component", type: FilterComponent, selector: "ngx-decaf-filter", inputs: ["indexes", "conditions", "sortBy", "disableSort"], outputs: ["filterEvent", "searchEvent"] }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "children", "projectable", "parent"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
9461
10126
|
};
|
|
9462
10127
|
ListComponent = __decorate([
|
|
9463
10128
|
Dynamic(),
|
|
@@ -9484,7 +10149,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
|
|
|
9484
10149
|
EmptyStateComponent,
|
|
9485
10150
|
FilterComponent,
|
|
9486
10151
|
ComponentRendererComponent
|
|
9487
|
-
], host: { '[attr.id]': 'uid' }, template: "\n@if (showRefresher) {\n <ion-refresher slot=\"fixed\" [pullFactor]=\"1\" [pullMin]=\"100\" [pullMax]=\"200\" (ionRefresh)=\"handleRefresh($event)\">\n <ion-refresher-content />\n </ion-refresher>\n}\n\n@if (showSearchbar) {\n @if (model && enableFilter) {\n @if (data?.length || searching) {\n <ngx-decaf-filter\n [model]=\"model\"\n [sortDirection]=\"sortDirection\"\n [disableSort]=\"disableSort\"\n (filterEvent)=\"handleFilter($event)\"\n (searchEvent)=\"handleSearch($event)\"\n />\n }\n } @else {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n }\n}\n\n@if (data?.length) {\n <ion-list [id]=\"uid\" [inset]=\"inset\" [lines]=\"lines\"
|
|
10152
|
+
], host: { '[attr.id]': 'uid' }, template: "<div #component>\n\n</div>\n@if (showRefresher) {\n <ion-refresher slot=\"fixed\" [pullFactor]=\"1\" [pullMin]=\"100\" [pullMax]=\"200\" (ionRefresh)=\"handleRefresh($event)\">\n <ion-refresher-content />\n </ion-refresher>\n}\n\n@if (showSearchbar) {\n @if (model && enableFilter) {\n @if (data?.length || searching) {\n <ngx-decaf-filter\n [model]=\"model\"\n [sortDirection]=\"sortDirection\"\n [disableSort]=\"disableSort\"\n (filterEvent)=\"handleFilter($event)\"\n (searchEvent)=\"handleSearch($event)\"\n />\n }\n } @else {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n }\n}\n\n@if (initialized && data?.length) {\n <ion-list [id]=\"uid\" [inset]=\"inset\" [lines]=\"lines\">\n @if (item?.tag) {\n @for(child of items; track trackItemFn($index, child)) {\n <ngx-decaf-component-renderer\n [tag]=\"item.tag\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]='{\n item: child,\n mapper: mapper,\n route: route\n }'>\n </ngx-decaf-component-renderer>\n }\n } @else {\n <ng-content></ng-content>\n }\n </ion-list>\n\n @if (loadMoreData) {\n @if (pages > 0 && type === 'paginated' && !searchValue?.length) {\n <ngx-decaf-pagination\n [totalPages]=\"pages\"\n [current]=\"page\"\n (clickEvent)=\"handlePaginate($event)\"\n />\n\n } @else {\n <ion-infinite-scroll\n [class]=\"searchValue?.length ? 'dcf-hidden' : ''\"\n\n [position]=\"scrollPosition\"\n [threshold]=\"scrollThreshold\"\n (ionInfinite)=\"handleRefresh($event)\">\n <ion-infinite-scroll-content [loadingSpinner]=\"loadingSpinner\" [loadingText]=\"loadingText\" />\n </ion-infinite-scroll>\n }\n }\n} @else {\n @if (refreshing) {\n @for(skl of skeletonData; track $index) {\n <ion-item>\n <ion-thumbnail slot=\"start\">\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n </ion-thumbnail>\n <ion-label>\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%;\"><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text></ion-text>\n </ion-label>\n </ion-item>\n }\n\n } @else {\n @if (!searching) {\n <ngx-decaf-empty-state\n [title]=\"(locale + '.'+ empty.title) | translate\"\n [model]=\"model\"\n [icon]=\"empty.icon\"\n className=\"dcf-empty-data\"\n [subtitle]=\"(locale + '.'+ empty.subtitle) | translate\" />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n [model]=\"model\"\n className=\"empty-search\"\n [translatable]=\"true\"\n className=\"dcf-empty-data\"\n [title]=\"locale + '.search.title' | translate\"\n [subtitle]=\"locale + '.search.subtitle' | translate: {'0': parseSearchValue()}\"\n [searchValue]=\"searchValue\"\n />\n }\n }\n}\n\n", styles: ["ion-infinite-scroll{max-height:50px}ion-infinite-scroll:not(.infinite-scroll-loading) ::ng-deep{max-height:1.5rem}ion-infinite-scroll ::ng-deep ion-spinner{--color: var(--dcf-color-primary);padding-top:1rem}@media (max-width: 768px){#end,[slot=end]{display:none!important}}\n"] }]
|
|
9488
10153
|
}], ctorParameters: () => [], propDecorators: { type: [{
|
|
9489
10154
|
type: Input
|
|
9490
10155
|
}], showSearchbar: [{
|
|
@@ -9736,8 +10401,8 @@ let ListItemComponent = class ListItemComponent extends NgxComponentDirective {
|
|
|
9736
10401
|
// forcing trap focus
|
|
9737
10402
|
removeFocusTrap();
|
|
9738
10403
|
if (!this.route) {
|
|
9739
|
-
const event = { target: target, action, pk: this.pk, data: this.uid, name:
|
|
9740
|
-
windowEventEmitter(`ListItem${
|
|
10404
|
+
const event = { target: target, action, pk: this.pk, data: this.uid, name: ComponentEventNames.CLICK, component: this.componentName };
|
|
10405
|
+
windowEventEmitter(`ListItem${ComponentEventNames.CLICK}`, event);
|
|
9741
10406
|
return this.clickEvent.emit(event);
|
|
9742
10407
|
}
|
|
9743
10408
|
return await this.redirect(action, (typeof this.uid === 'number' ? `${this.uid}` : this.uid));
|
|
@@ -9872,7 +10537,7 @@ let ListItemComponent = class ListItemComponent extends NgxComponentDirective {
|
|
|
9872
10537
|
this.actionMenuOpen = true;
|
|
9873
10538
|
}
|
|
9874
10539
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9875
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: ListItemComponent, isStandalone: true, selector: "ngx-decaf-list-item", inputs: { lines: "lines", item: "item", icon: "icon", iconSlot: "iconSlot", button: "button", title: "title", description: "description", info: "info", subinfo: "subinfo" }, outputs: { clickEvent: "clickEvent" }, host: { listeners: { "window:resize": "enableSlideItems($event)" }, properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef }, { propertyName: "actionMenuComponent", first: true, predicate: ["actionMenuComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "\n@if (title || description) {\n <ion-item-sliding>\n <ion-item\n [id]=\"uid\"\n [lines]=\"lines\"\n [button]=\"button\"\n [class]=\"className\"\n (click)=\"operations?.includes('read') ? handleAction('read', $event, component) : ''\"\n #component\n >\n @if (icon && lines !== 'inset') {\n <div class=\"dcf-icon\" [slot]=\"iconSlot\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\"></ion-icon>\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-flex dcf-flex-middle dcf-grid-collapse\" dcf-grid>\n @if (icon && lines === 'inset') {\n <div class=\"dcf-icon dcf-grid-icon\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\"></ion-icon>\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand@s dcf-width-1-1 dcf-label\">\n @if (title) {\n <ion-label class=\"dcf-item-title\">\n {{ uid !== title ? (uid + ' - ' + title) : title }}\n </ion-label>\n }\n @if (description) {\n <div class=\"dcf-description\" [innerHTML]=\"description\"></div>\n }\n </div>\n @if (info || subinfo) {\n <div class=\"dcf-width-auto@s dcf-width-expand dcf-info dcf-flex dcf-flex-right@s\">\n <div>\n @if (info) {\n <span [innerHTML]=\"info\"></span>\n }\n @if (subinfo) {\n <div class=\"dcf-subinfo dcf-text-truncate\" [innerHTML]=\"subinfo\" ></div>\n }\n </div>\n </div>\n }\n\n <div class=\"dcf-width-auto dcf-flex dcf-flex-middle dcf-flex-right\">\n @if ((operations.includes('delete') || operations.includes('update')) && uid) {\n\n <div class=\"dcf-visible@s\" id=\"dcf-actions\">\n <ion-button class=\"\" shape=\"round\" fill=\"clear\" color=\"primary\" (click)=\"presentActionsMenu($event)\">\n <ion-icon slot=\"icon-only\" aria-hidden=\"true\" name=\"ellipsis-vertical-outline\"></ion-icon>\n </ion-button>\n <ion-popover\n #actionMenuComponent\n side=\"bottom\"\n alignment=\"left\"\n\n [isOpen]=\"actionMenuOpen\"\n (didDismiss)=\"actionMenuOpen = false\">\n <ng-template>\n <ion-content class=\"ion-padding\">\n <ion-list lines=\"none\">\n <ion-list-header>\n <h4 class=\"dcf-text-capitalize\" [innerHTML]=\"'actions' | translate\"></h4>\n </ion-list-header>\n @for (operation of ['update', 'delete']; track operation) {\n @if (operations.includes(operation)) {\n <ion-item [button]=\"true\" (click)=\"handleAction(operation, $event, component)\">\n <ion-avatar class=\"dcf-flex dcf-flex-middle\" aria-hidden=\"true\" slot=\"start\">\n @if (operation === 'update') {\n <ion-icon color=\"primary\" aria-hidden=\"true\" name=\"create-outline\"></ion-icon>\n } @else {\n <ion-icon color=\"danger\" aria-hidden=\"true\" name=\"trash\"></ion-icon>\n }\n </ion-avatar>\n <ion-label class=\"dcf-text-capitalize\">{{ operation | translate }}</ion-label>\n </ion-item>\n }\n }\n </ion-list>\n </ion-content>\n </ng-template>\n </ion-popover>\n </div>\n }\n <!-- @if (operations?.length && uid) {\n <div class=\"dcf-visible@m\" id=\"dcf-actions\">\n @if (operations?.includes('update')) {\n <ion-button fill=\"clear\" size=\"small\" color=\"primary\" (click)=\"handleAction('update', component)\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\"></ion-icon>\n </ion-button>\n }\n @if (operations?.includes('delete')) {\n <ion-button fill=\"clear\" size=\"small\" color=\"danger\" (click)=\"handleAction('delete', component)\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\"></ion-icon>\n </ion-button>\n }\n </div>\n } -->\n @if (windowWidth > 639) {\n <div id=\"end\">\n <ng-content select=\"[slot='end']\"></ng-content>\n </div>\n }\n </div>\n </div>\n </div>\n </ion-item>\n @if (showSlideItems && uid) {\n <ion-item-options side=\"end\" (ionSwipe)=\"operations.length === 1 ? handleAction(operations[0], $event, component) : ''\">\n @if (operations?.includes('update')) {\n <ion-item-option class=\"dcf-update\" (click)=\"handleAction('update', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\"></ion-icon>\n </ion-item-option>\n }\n @if (operations?.includes('delete')) {\n <ion-item-option class=\"dcf- delete\" (click)=\"handleAction('delete', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\"></ion-icon>\n </ion-item-option>\n }\n </ion-item-options>\n }\n </ion-item-sliding>\n}\n", styles: ["ion-item:not(.dcf-palette-dark){--background-hover-opacity: .1;--background-focused-opacity: .1;--border-color: var(--dcf-color-gray-2)}ion-item:not(.dcf-palette-dark) .dcf-info{color:var(--dcf-color-gray-6)}ion-item:not(.dcf-palette-dark) .dcf-item-title{color:var(--dcf-color-gray-8)}ion-item:not(.dcf-palette-dark) .dcf-description{color:var(--dcf-color-gray-6)}ion-item:not(.dcf-palette-dark) ion-button{color:var(--dcf-color-gray-7);--background: var(--dcf-color-gray-1) !important}ion-item:not(.dcf-palette-dark) ion-avatar{color:var(--dcf-color-gray-7);background:var(--dcf-color-gray-1)!important}ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete),ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),.25)!important}ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete) .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete) ion-icon,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update) .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-7)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete *,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update ion-icon{color:var(--dcf-color-primary)!important}ion-item.dcf-palette-dark{--background-hover-opacity: .25;--background-focused-opacity: .25;--border-color: var(--dcf-color-gray-6)}ion-item.dcf-palette-dark .dcf-description{color:var(--dcf-color-gray-4)}ion-item.dcf-palette-dark ion-button{color:var(--dcf-color-gray-1)!important;--background: var(--dcf-color-gray-7) !important}ion-item.dcf-palette-dark ion-avatar{color:var(--dcf-color-gray-1)!important;background:var(--dcf-background-color)!important}ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete),ion-item.dcf-palette-dark ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),1)!important}ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete) .dcf-ti,ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete) ion-icon,ion-item.dcf-palette-dark ion-item-option:not(.dcf-update) .dcf-ti,ion-item.dcf-palette-dark ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-2)!important}ion-item.dcf-palette-dark ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item.dcf-palette-dark ion-item-option.dcf-delete .dcf-ti,ion-item.dcf-palette-dark ion-item-option.dcf-delete *,ion-item.dcf-palette-dark ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item.dcf-palette-dark ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item.dcf-palette-dark ion-item-option.dcf-update .dcf-ti,ion-item.dcf-palette-dark ion-item-option.dcf-update ion-icon{color:var(--dcf-color-gray-2)!important}ion-item-sliding{box-sizing:border-box}ion-item-sliding[class*=active-slide]{border-color:var(--dcf-color-gray-3)}ion-item-sliding ion-item-option{color:var(--dcf-color-gray-5);box-shadow:inset 0 0 5px rgba(var(--dcf-color-dark-rgb),.15)!important;background:var(--dcf-color-gray-3)}ion-item{--min-height: 50px;--padding-top: .25rem;--padding-bottom: .25rem;--padding-start: .75rem;--padding-end: .75rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--background-hover: var(--dcf-color-gray-8);--background-focused: var(--dcf-color-gray-8)}ion-item.item-lines-full{--padding-top: .5rem;--padding-bottom: .5rem;--padding-start: .25rem;-padding-end:.25rem;padding:0 .65rem}ion-item.item-lines-inset{--padding-top: 0rem !important;--padding-bottom: 0rem !important;--inner-padding-top: .5rem !important;--inner-padding-bottom: .65rem !important}ion-item .dcf-info{min-width:10vw;background:transparent!important}ion-item .dcf-grid{padding:0!important;margin:0!important;min-width:100%!important}ion-item .dcf-item-title{font-style:normal;font-weight:700}ion-item .dcf-description{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-style:normal;font-weight:400;font-size:.925rem}ion-item::part(native){min-width:100%}ion-item [slot=start]{margin-right:.5rem!important}ion-item [slot=end]{margin-left:.5rem!important}ion-item .dcf-info{font-size:.9rem}ion-item .dcf-info .dcf-subinfo.dcf-line{margin-left:.5rem}@media (min-width: var(--dcf-width-sm)){ion-item .dcf-info .dcf-subinfo.dcf-line{display:block;margin-left:0}}ion-item #dcf-actions{padding:5px}@media (max-width: var(--dcf-width-m)){ion-item #dcf-actions{display:none;pointer-events:none!important;cursor:text!important}ion-item #dcf-actions *{display:none;pointer-events:none!important;cursor:text!important}}ion-item #dcf-actions ion-button{--padding-start: 1rem;--padding-end: .75rem;--padding-top: .85rem !important;--padding-bottom: .85rem !important;color:#ccc;margin-right:.5rem!important;--background: var(--dcf-color-gray-2) !important}ion-item #dcf-actions ion-button ion-icon{position:relative;left:-1px}@media (max-width: var(--dcf-width-m)){ion-item #dcf-end,ion-item [slot=end]{display:none!important}}ion-item #dcf-end{padding-top:5px;display:flex;align-items:flex-end}ion-item .dcf-icon{display:flex;justify-content:center;align-items:center;text-align:center;margin-right:.5rem!important}ion-item .dcf-icon.dcf-grid-icon{min-width:50px;text-align:left;display:flex;justify-content:flex-start}@media (max-width: var(--dcf-width-s)){ion-item .dcf-icon{align-items:flex-start!important}}ion-item .dcf-icon ion-button ion-icon{font-size:20px}ion-avatar{width:48px;height:48px;display:flex;justify-content:center;align-items:center;text-align:center}ion-avatar ion-icon{font-size:20px}ion-avatar .dcf-icon-large{transform:translateY(5px)}\n"], dependencies: [{ kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonListHeader, selector: "ion-list-header", inputs: ["color", "lines", "mode"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonItemSliding, selector: "ion-item-sliding", inputs: ["disabled"] }, { kind: "component", type: IonItemOptions, selector: "ion-item-options", inputs: ["side"] }, { kind: "component", type: IonItemOption, selector: "ion-item-option", inputs: ["color", "disabled", "download", "expandable", "href", "mode", "rel", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: 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: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonPopover, selector: "ion-popover" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
10540
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: ListItemComponent, isStandalone: true, selector: "ngx-decaf-list-item", inputs: { lines: "lines", item: "item", icon: "icon", iconSlot: "iconSlot", button: "button", title: "title", description: "description", info: "info", subinfo: "subinfo" }, outputs: { clickEvent: "clickEvent" }, host: { listeners: { "window:resize": "enableSlideItems($event)" }, properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef }, { propertyName: "actionMenuComponent", first: true, predicate: ["actionMenuComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "\n@if (title || description) {\n <ion-item-sliding>\n <ion-item\n [id]=\"uid\"\n [lines]=\"lines\"\n [button]=\"button\"\n [class]=\"className\"\n (click)=\"operations?.includes('read') ? handleAction('read', $event, component) : ''\"\n #component\n >\n @if (icon && lines !== 'inset') {\n <div class=\"dcf-icon\" [slot]=\"iconSlot\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\" />\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-flex dcf-flex-middle dcf-grid-collapse\" dcf-grid>\n @if (icon && lines === 'inset') {\n <div class=\"dcf-icon dcf-grid-icon\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\" />\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand@s dcf-width-1-1 dcf-label\">\n @if (title) {\n <ion-label class=\"dcf-item-title\">\n {{ uid !== title ? (uid + ' - ' + title) : title }}\n </ion-label>\n }\n @if (description) {\n <div class=\"dcf-description\" [innerHTML]=\"description\"></div>\n }\n </div>\n @if (info || subinfo) {\n <div class=\"dcf-width-auto@s dcf-width-expand dcf-info dcf-flex dcf-flex-right@s\">\n <div>\n @if (info) {\n <span [innerHTML]=\"info\"></span>\n }\n @if (subinfo) {\n <div class=\"dcf-subinfo dcf-text-truncate\" [innerHTML]=\"subinfo\" ></div>\n }\n </div>\n </div>\n }\n\n <div class=\"dcf-width-auto dcf-flex dcf-flex-middle dcf-flex-right\">\n @if ((operations.includes('delete') || operations.includes('update')) && uid) {\n\n <div class=\"dcf-visible@s\" id=\"dcf-actions\">\n <ion-button class=\"\" shape=\"round\" fill=\"clear\" color=\"primary\" (click)=\"presentActionsMenu($event)\">\n <ion-icon slot=\"icon-only\" aria-hidden=\"true\" name=\"ellipsis-vertical-outline\" />\n </ion-button>\n <ion-popover\n #actionMenuComponent\n side=\"bottom\"\n alignment=\"left\"\n\n [isOpen]=\"actionMenuOpen\"\n (didDismiss)=\"actionMenuOpen = false\">\n <ng-template>\n <ion-content class=\"ion-padding\">\n <ion-list lines=\"none\">\n <ion-list-header>\n <h4 class=\"dcf-text-capitalize\" [innerHTML]=\"'actions' | translate\"></h4>\n </ion-list-header>\n @for (operation of ['update', 'delete']; track operation) {\n @if (operations.includes(operation)) {\n <ion-item [button]=\"true\" (click)=\"handleAction(operation, $event, component)\">\n <ion-avatar class=\"dcf-flex dcf-flex-middle\" aria-hidden=\"true\" slot=\"start\">\n @if (operation === 'update') {\n <ion-icon color=\"primary\" aria-hidden=\"true\" name=\"create-outline\" />\n } @else {\n <ion-icon color=\"danger\" aria-hidden=\"true\" name=\"trash\" />\n }\n </ion-avatar>\n <ion-label class=\"dcf-text-capitalize\">{{ operation | translate }}</ion-label>\n </ion-item>\n }\n }\n </ion-list>\n </ion-content>\n </ng-template>\n </ion-popover>\n </div>\n }\n @if (windowWidth > 639) {\n <div id=\"end\">\n <ng-content select=\"[slot='end']\"></ng-content>\n </div>\n }\n </div>\n </div>\n </div>\n </ion-item>\n @if (showSlideItems && uid) {\n <ion-item-options side=\"end\" (ionSwipe)=\"operations.length === 1 ? handleAction(operations[0], $event, component) : ''\">\n @if (operations?.includes('update')) {\n <ion-item-option class=\"dcf-update\" (click)=\"handleAction('update', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\" />\n </ion-item-option>\n }\n @if (operations?.includes('delete')) {\n <ion-item-option class=\"dcf-delete\" (click)=\"handleAction('delete', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\" />\n </ion-item-option>\n }\n </ion-item-options>\n }\n </ion-item-sliding>\n}\n", styles: ["ion-item:not(.dcf-palette-dark){--background-hover-opacity: .1;--background-focused-opacity: .1;--border-color: var(--dcf-color-gray-2)}ion-item:not(.dcf-palette-dark) .dcf-info{color:var(--dcf-color-gray-6)}ion-item:not(.dcf-palette-dark) .dcf-item-title{color:var(--dcf-color-gray-8)}ion-item:not(.dcf-palette-dark) .dcf-description{color:var(--dcf-color-gray-6)}ion-item:not(.dcf-palette-dark) ion-button{color:var(--dcf-color-gray-7);--background: var(--dcf-color-gray-1) !important}ion-item:not(.dcf-palette-dark) ion-avatar{color:var(--dcf-color-gray-7);background:var(--dcf-color-gray-1)!important}ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete),ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),.25)!important}ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete) .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete) ion-icon,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update) .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-7)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete *,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update ion-icon{color:var(--dcf-color-primary)!important}ion-item.dcf-palette-dark{--background-hover-opacity: .25;--background-focused-opacity: .25;--border-color: var(--dcf-color-gray-6)}ion-item.dcf-palette-dark .dcf-description{color:var(--dcf-color-gray-4)}ion-item.dcf-palette-dark ion-button{color:var(--dcf-color-gray-1)!important;--background: var(--dcf-color-gray-7) !important}ion-item.dcf-palette-dark ion-avatar{color:var(--dcf-color-gray-1)!important;background:var(--dcf-background-color)!important}ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete),ion-item.dcf-palette-dark ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),1)!important}ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete) .dcf-ti,ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete) ion-icon,ion-item.dcf-palette-dark ion-item-option:not(.dcf-update) .dcf-ti,ion-item.dcf-palette-dark ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-2)!important}ion-item.dcf-palette-dark ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item.dcf-palette-dark ion-item-option.dcf-delete .dcf-ti,ion-item.dcf-palette-dark ion-item-option.dcf-delete *,ion-item.dcf-palette-dark ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item.dcf-palette-dark ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item.dcf-palette-dark ion-item-option.dcf-update .dcf-ti,ion-item.dcf-palette-dark ion-item-option.dcf-update ion-icon{color:var(--dcf-color-gray-2)!important}ion-item-sliding{box-sizing:border-box}ion-item-sliding[class*=active-slide]{border-color:var(--dcf-color-gray-3)}ion-item-sliding ion-item-option{color:var(--dcf-color-gray-5);box-shadow:inset 0 0 5px rgba(var(--dcf-color-dark-rgb),.15)!important;background:var(--dcf-color-gray-3)}ion-item{--min-height: 50px;--padding-top: .25rem;--padding-bottom: .25rem;--padding-start: .75rem;--padding-end: .75rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--background-hover: var(--dcf-color-gray-8);--background-focused: var(--dcf-color-gray-8)}ion-item.item-lines-full{--padding-top: .5rem;--padding-bottom: .5rem;--padding-start: .25rem;-padding-end:.25rem;padding:0 .65rem}ion-item.item-lines-inset{--padding-top: 0rem !important;--padding-bottom: 0rem !important;--inner-padding-top: .5rem !important;--inner-padding-bottom: .65rem !important}ion-item .dcf-info{min-width:10vw;background:transparent!important}ion-item .dcf-grid{padding:0!important;margin:0!important;min-width:100%!important}ion-item .dcf-item-title{font-style:normal;font-weight:700}ion-item .dcf-description{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-style:normal;font-weight:400;font-size:.925rem}ion-item::part(native){min-width:100%}ion-item [slot=start]{margin-right:.5rem!important}ion-item [slot=end]{margin-left:.5rem!important}ion-item .dcf-info{font-size:.9rem}ion-item .dcf-info .dcf-subinfo.dcf-line{margin-left:.5rem}@media (min-width: var(--dcf-width-sm)){ion-item .dcf-info .dcf-subinfo.dcf-line{display:block;margin-left:0}}ion-item #dcf-actions{padding:5px}@media (max-width: var(--dcf-width-m)){ion-item #dcf-actions{display:none;pointer-events:none!important;cursor:text!important}ion-item #dcf-actions *{display:none;pointer-events:none!important;cursor:text!important}}ion-item #dcf-actions ion-button{--padding-start: 1rem;--padding-end: .75rem;--padding-top: .85rem !important;--padding-bottom: .85rem !important;color:#ccc;margin-right:.5rem!important;--background: var(--dcf-color-gray-2) !important}ion-item #dcf-actions ion-button ion-icon{position:relative;left:-1px}@media (max-width: var(--dcf-width-m)){ion-item #dcf-end,ion-item [slot=end]{display:none!important}}ion-item #dcf-end{padding-top:5px;display:flex;align-items:flex-end}ion-item .dcf-icon{display:flex;justify-content:center;align-items:center;text-align:center;margin-right:.5rem!important}ion-item .dcf-icon.dcf-grid-icon{min-width:50px;text-align:left;display:flex;justify-content:flex-start}@media (max-width: var(--dcf-width-s)){ion-item .dcf-icon{align-items:flex-start!important}}ion-item .dcf-icon ion-button ion-icon{font-size:20px}ion-avatar{width:48px;height:48px;display:flex;justify-content:center;align-items:center;text-align:center}ion-avatar ion-icon{font-size:20px}ion-avatar .dcf-icon-large{transform:translateY(5px)}\n"], dependencies: [{ kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonListHeader, selector: "ion-list-header", inputs: ["color", "lines", "mode"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonItemSliding, selector: "ion-item-sliding", inputs: ["disabled"] }, { kind: "component", type: IonItemOptions, selector: "ion-item-options", inputs: ["side"] }, { kind: "component", type: IonItemOption, selector: "ion-item-option", inputs: ["color", "disabled", "download", "expandable", "href", "mode", "rel", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: 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: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonPopover, selector: "ion-popover" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
9876
10541
|
};
|
|
9877
10542
|
ListItemComponent = __decorate([
|
|
9878
10543
|
Dynamic(),
|
|
@@ -9893,7 +10558,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
|
|
|
9893
10558
|
IonButton,
|
|
9894
10559
|
IonContent,
|
|
9895
10560
|
IonPopover
|
|
9896
|
-
], host: { '[attr.id]': 'uid' }, template: "\n@if (title || description) {\n <ion-item-sliding>\n <ion-item\n [id]=\"uid\"\n [lines]=\"lines\"\n [button]=\"button\"\n [class]=\"className\"\n (click)=\"operations?.includes('read') ? handleAction('read', $event, component) : ''\"\n #component\n >\n @if (icon && lines !== 'inset') {\n <div class=\"dcf-icon\" [slot]=\"iconSlot\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\"></ion-icon>\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-flex dcf-flex-middle dcf-grid-collapse\" dcf-grid>\n @if (icon && lines === 'inset') {\n <div class=\"dcf-icon dcf-grid-icon\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\"></ion-icon>\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand@s dcf-width-1-1 dcf-label\">\n @if (title) {\n <ion-label class=\"dcf-item-title\">\n {{ uid !== title ? (uid + ' - ' + title) : title }}\n </ion-label>\n }\n @if (description) {\n <div class=\"dcf-description\" [innerHTML]=\"description\"></div>\n }\n </div>\n @if (info || subinfo) {\n <div class=\"dcf-width-auto@s dcf-width-expand dcf-info dcf-flex dcf-flex-right@s\">\n <div>\n @if (info) {\n <span [innerHTML]=\"info\"></span>\n }\n @if (subinfo) {\n <div class=\"dcf-subinfo dcf-text-truncate\" [innerHTML]=\"subinfo\" ></div>\n }\n </div>\n </div>\n }\n\n <div class=\"dcf-width-auto dcf-flex dcf-flex-middle dcf-flex-right\">\n @if ((operations.includes('delete') || operations.includes('update')) && uid) {\n\n <div class=\"dcf-visible@s\" id=\"dcf-actions\">\n <ion-button class=\"\" shape=\"round\" fill=\"clear\" color=\"primary\" (click)=\"presentActionsMenu($event)\">\n <ion-icon slot=\"icon-only\" aria-hidden=\"true\" name=\"ellipsis-vertical-outline\"></ion-icon>\n </ion-button>\n <ion-popover\n #actionMenuComponent\n side=\"bottom\"\n alignment=\"left\"\n\n [isOpen]=\"actionMenuOpen\"\n (didDismiss)=\"actionMenuOpen = false\">\n <ng-template>\n <ion-content class=\"ion-padding\">\n <ion-list lines=\"none\">\n <ion-list-header>\n <h4 class=\"dcf-text-capitalize\" [innerHTML]=\"'actions' | translate\"></h4>\n </ion-list-header>\n @for (operation of ['update', 'delete']; track operation) {\n @if (operations.includes(operation)) {\n <ion-item [button]=\"true\" (click)=\"handleAction(operation, $event, component)\">\n <ion-avatar class=\"dcf-flex dcf-flex-middle\" aria-hidden=\"true\" slot=\"start\">\n @if (operation === 'update') {\n <ion-icon color=\"primary\" aria-hidden=\"true\" name=\"create-outline\"></ion-icon>\n } @else {\n <ion-icon color=\"danger\" aria-hidden=\"true\" name=\"trash\"></ion-icon>\n }\n </ion-avatar>\n <ion-label class=\"dcf-text-capitalize\">{{ operation | translate }}</ion-label>\n </ion-item>\n }\n }\n </ion-list>\n </ion-content>\n </ng-template>\n </ion-popover>\n </div>\n }\n <!-- @if (operations?.length && uid) {\n <div class=\"dcf-visible@m\" id=\"dcf-actions\">\n @if (operations?.includes('update')) {\n <ion-button fill=\"clear\" size=\"small\" color=\"primary\" (click)=\"handleAction('update', component)\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\"></ion-icon>\n </ion-button>\n }\n @if (operations?.includes('delete')) {\n <ion-button fill=\"clear\" size=\"small\" color=\"danger\" (click)=\"handleAction('delete', component)\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\"></ion-icon>\n </ion-button>\n }\n </div>\n } -->\n @if (windowWidth > 639) {\n <div id=\"end\">\n <ng-content select=\"[slot='end']\"></ng-content>\n </div>\n }\n </div>\n </div>\n </div>\n </ion-item>\n @if (showSlideItems && uid) {\n <ion-item-options side=\"end\" (ionSwipe)=\"operations.length === 1 ? handleAction(operations[0], $event, component) : ''\">\n @if (operations?.includes('update')) {\n <ion-item-option class=\"dcf-update\" (click)=\"handleAction('update', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\"></ion-icon>\n </ion-item-option>\n }\n @if (operations?.includes('delete')) {\n <ion-item-option class=\"dcf- delete\" (click)=\"handleAction('delete', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\"></ion-icon>\n </ion-item-option>\n }\n </ion-item-options>\n }\n </ion-item-sliding>\n}\n", styles: ["ion-item:not(.dcf-palette-dark){--background-hover-opacity: .1;--background-focused-opacity: .1;--border-color: var(--dcf-color-gray-2)}ion-item:not(.dcf-palette-dark) .dcf-info{color:var(--dcf-color-gray-6)}ion-item:not(.dcf-palette-dark) .dcf-item-title{color:var(--dcf-color-gray-8)}ion-item:not(.dcf-palette-dark) .dcf-description{color:var(--dcf-color-gray-6)}ion-item:not(.dcf-palette-dark) ion-button{color:var(--dcf-color-gray-7);--background: var(--dcf-color-gray-1) !important}ion-item:not(.dcf-palette-dark) ion-avatar{color:var(--dcf-color-gray-7);background:var(--dcf-color-gray-1)!important}ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete),ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),.25)!important}ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete) .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete) ion-icon,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update) .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-7)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete *,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update ion-icon{color:var(--dcf-color-primary)!important}ion-item.dcf-palette-dark{--background-hover-opacity: .25;--background-focused-opacity: .25;--border-color: var(--dcf-color-gray-6)}ion-item.dcf-palette-dark .dcf-description{color:var(--dcf-color-gray-4)}ion-item.dcf-palette-dark ion-button{color:var(--dcf-color-gray-1)!important;--background: var(--dcf-color-gray-7) !important}ion-item.dcf-palette-dark ion-avatar{color:var(--dcf-color-gray-1)!important;background:var(--dcf-background-color)!important}ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete),ion-item.dcf-palette-dark ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),1)!important}ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete) .dcf-ti,ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete) ion-icon,ion-item.dcf-palette-dark ion-item-option:not(.dcf-update) .dcf-ti,ion-item.dcf-palette-dark ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-2)!important}ion-item.dcf-palette-dark ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item.dcf-palette-dark ion-item-option.dcf-delete .dcf-ti,ion-item.dcf-palette-dark ion-item-option.dcf-delete *,ion-item.dcf-palette-dark ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item.dcf-palette-dark ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item.dcf-palette-dark ion-item-option.dcf-update .dcf-ti,ion-item.dcf-palette-dark ion-item-option.dcf-update ion-icon{color:var(--dcf-color-gray-2)!important}ion-item-sliding{box-sizing:border-box}ion-item-sliding[class*=active-slide]{border-color:var(--dcf-color-gray-3)}ion-item-sliding ion-item-option{color:var(--dcf-color-gray-5);box-shadow:inset 0 0 5px rgba(var(--dcf-color-dark-rgb),.15)!important;background:var(--dcf-color-gray-3)}ion-item{--min-height: 50px;--padding-top: .25rem;--padding-bottom: .25rem;--padding-start: .75rem;--padding-end: .75rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--background-hover: var(--dcf-color-gray-8);--background-focused: var(--dcf-color-gray-8)}ion-item.item-lines-full{--padding-top: .5rem;--padding-bottom: .5rem;--padding-start: .25rem;-padding-end:.25rem;padding:0 .65rem}ion-item.item-lines-inset{--padding-top: 0rem !important;--padding-bottom: 0rem !important;--inner-padding-top: .5rem !important;--inner-padding-bottom: .65rem !important}ion-item .dcf-info{min-width:10vw;background:transparent!important}ion-item .dcf-grid{padding:0!important;margin:0!important;min-width:100%!important}ion-item .dcf-item-title{font-style:normal;font-weight:700}ion-item .dcf-description{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-style:normal;font-weight:400;font-size:.925rem}ion-item::part(native){min-width:100%}ion-item [slot=start]{margin-right:.5rem!important}ion-item [slot=end]{margin-left:.5rem!important}ion-item .dcf-info{font-size:.9rem}ion-item .dcf-info .dcf-subinfo.dcf-line{margin-left:.5rem}@media (min-width: var(--dcf-width-sm)){ion-item .dcf-info .dcf-subinfo.dcf-line{display:block;margin-left:0}}ion-item #dcf-actions{padding:5px}@media (max-width: var(--dcf-width-m)){ion-item #dcf-actions{display:none;pointer-events:none!important;cursor:text!important}ion-item #dcf-actions *{display:none;pointer-events:none!important;cursor:text!important}}ion-item #dcf-actions ion-button{--padding-start: 1rem;--padding-end: .75rem;--padding-top: .85rem !important;--padding-bottom: .85rem !important;color:#ccc;margin-right:.5rem!important;--background: var(--dcf-color-gray-2) !important}ion-item #dcf-actions ion-button ion-icon{position:relative;left:-1px}@media (max-width: var(--dcf-width-m)){ion-item #dcf-end,ion-item [slot=end]{display:none!important}}ion-item #dcf-end{padding-top:5px;display:flex;align-items:flex-end}ion-item .dcf-icon{display:flex;justify-content:center;align-items:center;text-align:center;margin-right:.5rem!important}ion-item .dcf-icon.dcf-grid-icon{min-width:50px;text-align:left;display:flex;justify-content:flex-start}@media (max-width: var(--dcf-width-s)){ion-item .dcf-icon{align-items:flex-start!important}}ion-item .dcf-icon ion-button ion-icon{font-size:20px}ion-avatar{width:48px;height:48px;display:flex;justify-content:center;align-items:center;text-align:center}ion-avatar ion-icon{font-size:20px}ion-avatar .dcf-icon-large{transform:translateY(5px)}\n"] }]
|
|
10561
|
+
], host: { '[attr.id]': 'uid' }, template: "\n@if (title || description) {\n <ion-item-sliding>\n <ion-item\n [id]=\"uid\"\n [lines]=\"lines\"\n [button]=\"button\"\n [class]=\"className\"\n (click)=\"operations?.includes('read') ? handleAction('read', $event, component) : ''\"\n #component\n >\n @if (icon && lines !== 'inset') {\n <div class=\"dcf-icon\" [slot]=\"iconSlot\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\" />\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-flex dcf-flex-middle dcf-grid-collapse\" dcf-grid>\n @if (icon && lines === 'inset') {\n <div class=\"dcf-icon dcf-grid-icon\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\" />\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand@s dcf-width-1-1 dcf-label\">\n @if (title) {\n <ion-label class=\"dcf-item-title\">\n {{ uid !== title ? (uid + ' - ' + title) : title }}\n </ion-label>\n }\n @if (description) {\n <div class=\"dcf-description\" [innerHTML]=\"description\"></div>\n }\n </div>\n @if (info || subinfo) {\n <div class=\"dcf-width-auto@s dcf-width-expand dcf-info dcf-flex dcf-flex-right@s\">\n <div>\n @if (info) {\n <span [innerHTML]=\"info\"></span>\n }\n @if (subinfo) {\n <div class=\"dcf-subinfo dcf-text-truncate\" [innerHTML]=\"subinfo\" ></div>\n }\n </div>\n </div>\n }\n\n <div class=\"dcf-width-auto dcf-flex dcf-flex-middle dcf-flex-right\">\n @if ((operations.includes('delete') || operations.includes('update')) && uid) {\n\n <div class=\"dcf-visible@s\" id=\"dcf-actions\">\n <ion-button class=\"\" shape=\"round\" fill=\"clear\" color=\"primary\" (click)=\"presentActionsMenu($event)\">\n <ion-icon slot=\"icon-only\" aria-hidden=\"true\" name=\"ellipsis-vertical-outline\" />\n </ion-button>\n <ion-popover\n #actionMenuComponent\n side=\"bottom\"\n alignment=\"left\"\n\n [isOpen]=\"actionMenuOpen\"\n (didDismiss)=\"actionMenuOpen = false\">\n <ng-template>\n <ion-content class=\"ion-padding\">\n <ion-list lines=\"none\">\n <ion-list-header>\n <h4 class=\"dcf-text-capitalize\" [innerHTML]=\"'actions' | translate\"></h4>\n </ion-list-header>\n @for (operation of ['update', 'delete']; track operation) {\n @if (operations.includes(operation)) {\n <ion-item [button]=\"true\" (click)=\"handleAction(operation, $event, component)\">\n <ion-avatar class=\"dcf-flex dcf-flex-middle\" aria-hidden=\"true\" slot=\"start\">\n @if (operation === 'update') {\n <ion-icon color=\"primary\" aria-hidden=\"true\" name=\"create-outline\" />\n } @else {\n <ion-icon color=\"danger\" aria-hidden=\"true\" name=\"trash\" />\n }\n </ion-avatar>\n <ion-label class=\"dcf-text-capitalize\">{{ operation | translate }}</ion-label>\n </ion-item>\n }\n }\n </ion-list>\n </ion-content>\n </ng-template>\n </ion-popover>\n </div>\n }\n @if (windowWidth > 639) {\n <div id=\"end\">\n <ng-content select=\"[slot='end']\"></ng-content>\n </div>\n }\n </div>\n </div>\n </div>\n </ion-item>\n @if (showSlideItems && uid) {\n <ion-item-options side=\"end\" (ionSwipe)=\"operations.length === 1 ? handleAction(operations[0], $event, component) : ''\">\n @if (operations?.includes('update')) {\n <ion-item-option class=\"dcf-update\" (click)=\"handleAction('update', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\" />\n </ion-item-option>\n }\n @if (operations?.includes('delete')) {\n <ion-item-option class=\"dcf-delete\" (click)=\"handleAction('delete', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\" />\n </ion-item-option>\n }\n </ion-item-options>\n }\n </ion-item-sliding>\n}\n", styles: ["ion-item:not(.dcf-palette-dark){--background-hover-opacity: .1;--background-focused-opacity: .1;--border-color: var(--dcf-color-gray-2)}ion-item:not(.dcf-palette-dark) .dcf-info{color:var(--dcf-color-gray-6)}ion-item:not(.dcf-palette-dark) .dcf-item-title{color:var(--dcf-color-gray-8)}ion-item:not(.dcf-palette-dark) .dcf-description{color:var(--dcf-color-gray-6)}ion-item:not(.dcf-palette-dark) ion-button{color:var(--dcf-color-gray-7);--background: var(--dcf-color-gray-1) !important}ion-item:not(.dcf-palette-dark) ion-avatar{color:var(--dcf-color-gray-7);background:var(--dcf-color-gray-1)!important}ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete),ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),.25)!important}ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete) .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete) ion-icon,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update) .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-7)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete *,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update ion-icon{color:var(--dcf-color-primary)!important}ion-item.dcf-palette-dark{--background-hover-opacity: .25;--background-focused-opacity: .25;--border-color: var(--dcf-color-gray-6)}ion-item.dcf-palette-dark .dcf-description{color:var(--dcf-color-gray-4)}ion-item.dcf-palette-dark ion-button{color:var(--dcf-color-gray-1)!important;--background: var(--dcf-color-gray-7) !important}ion-item.dcf-palette-dark ion-avatar{color:var(--dcf-color-gray-1)!important;background:var(--dcf-background-color)!important}ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete),ion-item.dcf-palette-dark ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),1)!important}ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete) .dcf-ti,ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete) ion-icon,ion-item.dcf-palette-dark ion-item-option:not(.dcf-update) .dcf-ti,ion-item.dcf-palette-dark ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-2)!important}ion-item.dcf-palette-dark ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item.dcf-palette-dark ion-item-option.dcf-delete .dcf-ti,ion-item.dcf-palette-dark ion-item-option.dcf-delete *,ion-item.dcf-palette-dark ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item.dcf-palette-dark ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item.dcf-palette-dark ion-item-option.dcf-update .dcf-ti,ion-item.dcf-palette-dark ion-item-option.dcf-update ion-icon{color:var(--dcf-color-gray-2)!important}ion-item-sliding{box-sizing:border-box}ion-item-sliding[class*=active-slide]{border-color:var(--dcf-color-gray-3)}ion-item-sliding ion-item-option{color:var(--dcf-color-gray-5);box-shadow:inset 0 0 5px rgba(var(--dcf-color-dark-rgb),.15)!important;background:var(--dcf-color-gray-3)}ion-item{--min-height: 50px;--padding-top: .25rem;--padding-bottom: .25rem;--padding-start: .75rem;--padding-end: .75rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--background-hover: var(--dcf-color-gray-8);--background-focused: var(--dcf-color-gray-8)}ion-item.item-lines-full{--padding-top: .5rem;--padding-bottom: .5rem;--padding-start: .25rem;-padding-end:.25rem;padding:0 .65rem}ion-item.item-lines-inset{--padding-top: 0rem !important;--padding-bottom: 0rem !important;--inner-padding-top: .5rem !important;--inner-padding-bottom: .65rem !important}ion-item .dcf-info{min-width:10vw;background:transparent!important}ion-item .dcf-grid{padding:0!important;margin:0!important;min-width:100%!important}ion-item .dcf-item-title{font-style:normal;font-weight:700}ion-item .dcf-description{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-style:normal;font-weight:400;font-size:.925rem}ion-item::part(native){min-width:100%}ion-item [slot=start]{margin-right:.5rem!important}ion-item [slot=end]{margin-left:.5rem!important}ion-item .dcf-info{font-size:.9rem}ion-item .dcf-info .dcf-subinfo.dcf-line{margin-left:.5rem}@media (min-width: var(--dcf-width-sm)){ion-item .dcf-info .dcf-subinfo.dcf-line{display:block;margin-left:0}}ion-item #dcf-actions{padding:5px}@media (max-width: var(--dcf-width-m)){ion-item #dcf-actions{display:none;pointer-events:none!important;cursor:text!important}ion-item #dcf-actions *{display:none;pointer-events:none!important;cursor:text!important}}ion-item #dcf-actions ion-button{--padding-start: 1rem;--padding-end: .75rem;--padding-top: .85rem !important;--padding-bottom: .85rem !important;color:#ccc;margin-right:.5rem!important;--background: var(--dcf-color-gray-2) !important}ion-item #dcf-actions ion-button ion-icon{position:relative;left:-1px}@media (max-width: var(--dcf-width-m)){ion-item #dcf-end,ion-item [slot=end]{display:none!important}}ion-item #dcf-end{padding-top:5px;display:flex;align-items:flex-end}ion-item .dcf-icon{display:flex;justify-content:center;align-items:center;text-align:center;margin-right:.5rem!important}ion-item .dcf-icon.dcf-grid-icon{min-width:50px;text-align:left;display:flex;justify-content:flex-start}@media (max-width: var(--dcf-width-s)){ion-item .dcf-icon{align-items:flex-start!important}}ion-item .dcf-icon ion-button ion-icon{font-size:20px}ion-avatar{width:48px;height:48px;display:flex;justify-content:center;align-items:center;text-align:center}ion-avatar ion-icon{font-size:20px}ion-avatar .dcf-icon-large{transform:translateY(5px)}\n"] }]
|
|
9897
10562
|
}], ctorParameters: () => [], propDecorators: { component: [{
|
|
9898
10563
|
type: ViewChild,
|
|
9899
10564
|
args: ['component', { read: ElementRef, static: false }]
|
|
@@ -10091,7 +10756,7 @@ let SteppedFormComponent = class SteppedFormComponent extends NgxFormDirective {
|
|
|
10091
10756
|
c.props['page'] = page > this.pages ? this.pages : page;
|
|
10092
10757
|
return c;
|
|
10093
10758
|
})];
|
|
10094
|
-
this.
|
|
10759
|
+
this.getActivePage(this.activeIndex);
|
|
10095
10760
|
}
|
|
10096
10761
|
else {
|
|
10097
10762
|
this.children = this.pageTitles.map((page, index) => {
|
|
@@ -10104,6 +10769,12 @@ let SteppedFormComponent = class SteppedFormComponent extends NgxFormDirective {
|
|
|
10104
10769
|
items
|
|
10105
10770
|
};
|
|
10106
10771
|
});
|
|
10772
|
+
// this.formGroup = new FormGroup(
|
|
10773
|
+
// (this.formGroup as FormArray).controls.reduce((acc, control, index) => {
|
|
10774
|
+
// acc[index] = control as FormGroup;
|
|
10775
|
+
// return acc;
|
|
10776
|
+
// }, {} as Record<string, FormGroup>)
|
|
10777
|
+
// );
|
|
10107
10778
|
}
|
|
10108
10779
|
this.initialized = true;
|
|
10109
10780
|
}
|
|
@@ -10147,286 +10818,631 @@ let SteppedFormComponent = class SteppedFormComponent extends NgxFormDirective {
|
|
|
10147
10818
|
* S->>P: submitEvent.emit({data, name: SUBMIT})
|
|
10148
10819
|
* end
|
|
10149
10820
|
*
|
|
10150
|
-
* @memberOf SteppedFormComponent
|
|
10821
|
+
* @memberOf SteppedFormComponent
|
|
10822
|
+
*/
|
|
10823
|
+
handleNext(lastPage = false) {
|
|
10824
|
+
const isValid = NgxFormService.validateFields(this.formGroup);
|
|
10825
|
+
// const isValid = this.paginated ?
|
|
10826
|
+
// NgxFormService.validateFields(this.formGroup as FormGroup) :
|
|
10827
|
+
// (this.formGroup as FormArray)?.controls.every(control => NgxFormService.validateFields(control as FormGroup));
|
|
10828
|
+
if (!lastPage) {
|
|
10829
|
+
if (isValid) {
|
|
10830
|
+
this.activeIndex = this.activeIndex + 1;
|
|
10831
|
+
this.getActivePage(this.activeIndex);
|
|
10832
|
+
}
|
|
10833
|
+
}
|
|
10834
|
+
else {
|
|
10835
|
+
if (isValid) {
|
|
10836
|
+
const rootForm = this.formGroup?.root || this.formGroup;
|
|
10837
|
+
const data = Object.assign({}, ...Object.values(NgxFormService.getFormData(rootForm)));
|
|
10838
|
+
this.submitEvent.emit({
|
|
10839
|
+
data,
|
|
10840
|
+
component: this.componentName,
|
|
10841
|
+
name: this.action || ComponentEventNames.SUBMIT,
|
|
10842
|
+
handlers: this.handlers,
|
|
10843
|
+
});
|
|
10844
|
+
}
|
|
10845
|
+
}
|
|
10846
|
+
}
|
|
10847
|
+
/**
|
|
10848
|
+
* @description Handles navigation to the previous page.
|
|
10849
|
+
* @summary Moves the user back to the previous page in the stepped form.
|
|
10850
|
+
* This method decrements the active page number and updates the form
|
|
10851
|
+
* group and children to display the previous page's content.
|
|
10852
|
+
*
|
|
10853
|
+
* @return {void}
|
|
10854
|
+
*
|
|
10855
|
+
* @mermaid
|
|
10856
|
+
* sequenceDiagram
|
|
10857
|
+
* participant U as User
|
|
10858
|
+
* participant S as SteppedFormComponent
|
|
10859
|
+
*
|
|
10860
|
+
* U->>S: Click Back
|
|
10861
|
+
* S->>S: activeIndex--
|
|
10862
|
+
* S->>S: getCurrentFormGroup(activeIndex)
|
|
10863
|
+
* Note over S: Update active form and children
|
|
10864
|
+
*
|
|
10865
|
+
* @memberOf SteppedFormComponent
|
|
10866
|
+
*/
|
|
10867
|
+
handleBack() {
|
|
10868
|
+
if (!this.paginated)
|
|
10869
|
+
return this.location.back();
|
|
10870
|
+
this.activeIndex = this.activeIndex - 1;
|
|
10871
|
+
this.getActivePage(this.activeIndex);
|
|
10872
|
+
}
|
|
10873
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: SteppedFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
10874
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: SteppedFormComponent, isStandalone: true, selector: "ngx-decaf-stepped-form", inputs: { children: "children", paginated: "paginated", pages: "pages", pageTitles: "pageTitles", operation: "operation", startPage: "startPage" }, host: { properties: { "attr.id": "uid" } }, usesInheritance: true, ngImport: i0, template: "<form\n class=\"dcf-steped-form\"\n [class.paginated]=\"paginated\"\n novalidate\n #component\n>\n @if (paginated) {\n <div class=\"dcf-page-steps\">\n <div class=\"dcf-grid dcf-grid-collapse skip\">\n @for (page of pageTitles; track $index) {\n <div class=\"dcf-flex dcf-flex-middle\">\n <div\n class=\"dcf-step\"\n [class.dcf-active]=\"activeIndex === $index + 1\"\n [class.dcf-passed]=\"$index + 1 < activeIndex\"\n >\n {{ $index + 1 }}\n </div>\n @if (page?.title || page?.description) {\n <div class=\"dcf-information dcf-visible@s\">\n @if (page?.title) {\n <div class=\"dcf-title\">{{ page?.title | translate }}</div>\n }\n @if (page?.description) {\n <div class=\"dcf-description\">\n {{ page?.description | translate }}\n </div>\n }\n <div class=\"dcf-separator\"></div>\n </div>\n }\n @if ($index < pageTitles.length - 1) {\n <div class=\"dcf-arrow-container\">\n <svg\n width=\"8\"\n height=\"12\"\n viewBox=\"0 0 8 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M1.5 1L6.5 6L1.5 11\" />\n </svg>\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n @if (\n pageTitles[activeIndex - 1]?.title ||\n pageTitles[activeIndex - 1]?.description\n ) {\n <div class=\"dcf-current-step\">\n <div>\n @if (pageTitles[activeIndex - 1]?.title) {\n <div class=\"dcf-title\">\n {{ pageTitles[activeIndex - 1]?.title | translate }}\n </div>\n }\n @if (pageTitles[activeIndex - 1]?.description) {\n <div class=\"dcf-description\">\n {{ pageTitles[activeIndex - 1]?.description | translate }}\n </div>\n }\n </div>\n </div>\n }\n\n @if (initialized && activePage?.length) {\n <ngx-decaf-layout\n [className]=\"'dcf-stepped-form-grid paginated dcf-grid-nested'\"\n [children]=\"activePage || []\"\n [parentForm]=\"formGroup || parentForm\"\n [gap]=\"'small'\"\n [flexMode]=\"props.flexMode || false\"\n [match]=\"false\"\n [cardBody]=\"cardBody\"\n [cardType]=\"cardType\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [match]=\"false\"\n />\n } @else {\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%\"\n ><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text\n ></ion-text>\n <br />\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%\"\n ><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text\n ></ion-text>\n }\n <div\n class=\"dcf-buttons-container dcf-grid dcf-grid-collapse dcf-flex dcf-flex-left\"\n >\n <div class=\"dcf-width-1-2@s\">\n <ion-button color=\"light\" (click)=\"handleBack()\" [disabled]=\"activeIndex <= 1\">{{ locale + \".previous\" | translate }}</ion-button>\n </div>\n\n <div class=\"dcf-width-1-2@s\">\n <ion-button fill=\"solid\" (click)=\"handleNext(activeIndex === pages ? true : false)\">\n @if (activeIndex === pages) {\n {{ locale + \".submit\" | translate }}\n } @else {\n {{ locale + \".next\" | translate }}\n }\n </ion-button>\n </div>\n </div>\n } @else {\n <div class=\"dcf-single-step\">\n @for (item of children; track $index) {\n <ngx-decaf-card\n [className]=\"className\"\n [body]=\"cardBody\"\n [type]=\"cardType\"\n >\n <div>\n @if (item.title || item.description) {\n <div class=\"dcf-information\">\n <div>\n @if (item.title) {\n <div class=\"dcf-title\">{{ item.title | translate }}</div>\n }\n @if (item.description) {\n <div class=\"dcf-description\">\n {{ item.description | translate }}\n </div>\n }\n </div>\n </div>\n }\n <div [class.dcf-margin-bottom]=\"cardType === 'blank'\">\n @if (initialized && item.items?.length) {\n <ngx-decaf-layout\n [className]=\"'dcf-stepped-form-grid dcf-grid-nested'\"\n [children]=\"item.items || []\"\n [parentForm]=\"formGroup || parentForm\"\n [flexMode]=\"props.flexMode || false\"\n [gap]=\"'small'\"\n [cardBody]=\"cardBody\"\n [cardType]=\"cardType\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [match]=\"false\"\n />\n }\n </div>\n </div>\n </ngx-decaf-card>\n }\n <div\n class=\"dcf-buttons-container dcf-grid dcf-grid-small dcf-flex dcf-flex-right\"\n >\n <div class=\"dcf-width-auto@s dcf-width-1-1\">\n <ion-button color=\"light\" (click)=\"handleBack()\">\n {{ locale + \".cancel\" | translate }}\n </ion-button>\n </div>\n\n <div class=\"dcf-width-auto@s dcf-width-1-1\">\n <ion-button fill=\"solid\" (click)=\"handleNext(true)\">\n {{ locale + \".submit\" | translate }}\n </ion-button>\n </div>\n </div>\n </div>\n }\n</form>\n", styles: [".dcf-buttons-container{margin-top:1.8rem;margin-bottom:0}@media (min-width: 639px){.dcf-buttons-container.dcf-flex div:nth-child(2){display:flex;justify-content:flex-end}}@media (max-width: 638px){.dcf-buttons-container.dcf-flex div{width:100%}.dcf-buttons-container.dcf-flex ion-button{width:100%;margin-bottom:1rem}}.dcf-steped-form.paginated{padding:2rem 1rem}.dcf-page-steps{display:flex;justify-content:center;align-items:center;margin-bottom:2rem;overflow-x:auto;flex-wrap:nowrap}.dcf-page-steps .dcf-grid{display:flex!important;flex-wrap:nowrap!important;align-items:center}.dcf-step{height:38px;min-width:38px;width:38px;background:var(--dcf-color-gray-2);margin:0;display:flex;color:var(--dcf-color-gray-7);justify-content:center;align-items:center;font-size:1rem;font-weight:600;border-radius:var(--dcf-border-radius)}.dcf-step.dcf-active{color:var(--dcf-color-light);background:var(--ion-color-primary);box-shadow:0 2px 6px #144c714d}.dcf-step.dcf-passed{color:var(--dcf-color-primary-shade);background:var(--dcf-color-gray-3)}.dcf-information{padding-left:.5rem}.dcf-title{font-size:.875rem;font-weight:600;margin:0}.dcf-description{font-size:.8rem;font-weight:500;margin:0;margin-top:.25rem;color:var(--dcf-color-gray-4)}.dcf-arrow-container{display:flex;align-items:center;justify-content:center;padding:0 .5rem;height:38px}.dcf-arrow-container{display:flex;align-items:center;justify-content:center;padding:0 1rem;height:40px}.dcf-arrow-container svg{width:1rem;height:1rem;stroke:var(--dcf-color-gray-8);stroke-opacity:.7;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}ion-button[color=light]{--background: var(--dcf-color-gray-7) !important}.dcf-current-step{margin-top:-.5rem!important;margin-bottom:1.75rem!important;display:flex;align-items:center;justify-content:center}@media (min-width: 639px){.dcf-current-step{display:none}}.dcf-single-step .dcf-information{margin-bottom:1rem}.dcf-single-step .dcf-step-container:not(.ngx-decaf-fieldset){padding-bottom:1.5rem;padding-top:.5rem}.dcf-single-step ion-card{margin-bottom:1.5rem}.dcf-single-step ion-card .dcf-information{margin-top:.75rem}.dcf-step-form-container{margin-bottom:1.75rem!important}.dcf-steped-form ::ng-deep ngx-decaf-component-renderer.ngx-decaf-fieldset,.dcf-steped-form ::ng-deep ngx-decaf-fieldset{padding-top:0!important;padding-bottom:0!important}.dcf-steped-form ::ng-deep ngx-decaf-component-renderer.ngx-decaf-fieldset ion-button,.dcf-steped-form ::ng-deep ngx-decaf-fieldset ion-button{margin-top:1rem!important}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: 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: LayoutComponent, selector: "ngx-decaf-layout", inputs: ["gap", "grid", "flexMode", "rowCard", "maxColsLength"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
10875
|
+
};
|
|
10876
|
+
SteppedFormComponent = __decorate([
|
|
10877
|
+
Dynamic(),
|
|
10878
|
+
__metadata("design:paramtypes", [])
|
|
10879
|
+
], SteppedFormComponent);
|
|
10880
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: SteppedFormComponent, decorators: [{
|
|
10881
|
+
type: Component,
|
|
10882
|
+
args: [{ selector: 'ngx-decaf-stepped-form', imports: [
|
|
10883
|
+
TranslatePipe,
|
|
10884
|
+
ReactiveFormsModule,
|
|
10885
|
+
IonSkeletonText,
|
|
10886
|
+
IonText,
|
|
10887
|
+
IonButton,
|
|
10888
|
+
LayoutComponent
|
|
10889
|
+
], standalone: true, host: { '[attr.id]': 'uid' }, template: "<form\n class=\"dcf-steped-form\"\n [class.paginated]=\"paginated\"\n novalidate\n #component\n>\n @if (paginated) {\n <div class=\"dcf-page-steps\">\n <div class=\"dcf-grid dcf-grid-collapse skip\">\n @for (page of pageTitles; track $index) {\n <div class=\"dcf-flex dcf-flex-middle\">\n <div\n class=\"dcf-step\"\n [class.dcf-active]=\"activeIndex === $index + 1\"\n [class.dcf-passed]=\"$index + 1 < activeIndex\"\n >\n {{ $index + 1 }}\n </div>\n @if (page?.title || page?.description) {\n <div class=\"dcf-information dcf-visible@s\">\n @if (page?.title) {\n <div class=\"dcf-title\">{{ page?.title | translate }}</div>\n }\n @if (page?.description) {\n <div class=\"dcf-description\">\n {{ page?.description | translate }}\n </div>\n }\n <div class=\"dcf-separator\"></div>\n </div>\n }\n @if ($index < pageTitles.length - 1) {\n <div class=\"dcf-arrow-container\">\n <svg\n width=\"8\"\n height=\"12\"\n viewBox=\"0 0 8 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M1.5 1L6.5 6L1.5 11\" />\n </svg>\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n @if (\n pageTitles[activeIndex - 1]?.title ||\n pageTitles[activeIndex - 1]?.description\n ) {\n <div class=\"dcf-current-step\">\n <div>\n @if (pageTitles[activeIndex - 1]?.title) {\n <div class=\"dcf-title\">\n {{ pageTitles[activeIndex - 1]?.title | translate }}\n </div>\n }\n @if (pageTitles[activeIndex - 1]?.description) {\n <div class=\"dcf-description\">\n {{ pageTitles[activeIndex - 1]?.description | translate }}\n </div>\n }\n </div>\n </div>\n }\n\n @if (initialized && activePage?.length) {\n <ngx-decaf-layout\n [className]=\"'dcf-stepped-form-grid paginated dcf-grid-nested'\"\n [children]=\"activePage || []\"\n [parentForm]=\"formGroup || parentForm\"\n [gap]=\"'small'\"\n [flexMode]=\"props.flexMode || false\"\n [match]=\"false\"\n [cardBody]=\"cardBody\"\n [cardType]=\"cardType\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [match]=\"false\"\n />\n } @else {\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%\"\n ><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text\n ></ion-text>\n <br />\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%\"\n ><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text\n ></ion-text>\n }\n <div\n class=\"dcf-buttons-container dcf-grid dcf-grid-collapse dcf-flex dcf-flex-left\"\n >\n <div class=\"dcf-width-1-2@s\">\n <ion-button color=\"light\" (click)=\"handleBack()\" [disabled]=\"activeIndex <= 1\">{{ locale + \".previous\" | translate }}</ion-button>\n </div>\n\n <div class=\"dcf-width-1-2@s\">\n <ion-button fill=\"solid\" (click)=\"handleNext(activeIndex === pages ? true : false)\">\n @if (activeIndex === pages) {\n {{ locale + \".submit\" | translate }}\n } @else {\n {{ locale + \".next\" | translate }}\n }\n </ion-button>\n </div>\n </div>\n } @else {\n <div class=\"dcf-single-step\">\n @for (item of children; track $index) {\n <ngx-decaf-card\n [className]=\"className\"\n [body]=\"cardBody\"\n [type]=\"cardType\"\n >\n <div>\n @if (item.title || item.description) {\n <div class=\"dcf-information\">\n <div>\n @if (item.title) {\n <div class=\"dcf-title\">{{ item.title | translate }}</div>\n }\n @if (item.description) {\n <div class=\"dcf-description\">\n {{ item.description | translate }}\n </div>\n }\n </div>\n </div>\n }\n <div [class.dcf-margin-bottom]=\"cardType === 'blank'\">\n @if (initialized && item.items?.length) {\n <ngx-decaf-layout\n [className]=\"'dcf-stepped-form-grid dcf-grid-nested'\"\n [children]=\"item.items || []\"\n [parentForm]=\"formGroup || parentForm\"\n [flexMode]=\"props.flexMode || false\"\n [gap]=\"'small'\"\n [cardBody]=\"cardBody\"\n [cardType]=\"cardType\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [match]=\"false\"\n />\n }\n </div>\n </div>\n </ngx-decaf-card>\n }\n <div\n class=\"dcf-buttons-container dcf-grid dcf-grid-small dcf-flex dcf-flex-right\"\n >\n <div class=\"dcf-width-auto@s dcf-width-1-1\">\n <ion-button color=\"light\" (click)=\"handleBack()\">\n {{ locale + \".cancel\" | translate }}\n </ion-button>\n </div>\n\n <div class=\"dcf-width-auto@s dcf-width-1-1\">\n <ion-button fill=\"solid\" (click)=\"handleNext(true)\">\n {{ locale + \".submit\" | translate }}\n </ion-button>\n </div>\n </div>\n </div>\n }\n</form>\n", styles: [".dcf-buttons-container{margin-top:1.8rem;margin-bottom:0}@media (min-width: 639px){.dcf-buttons-container.dcf-flex div:nth-child(2){display:flex;justify-content:flex-end}}@media (max-width: 638px){.dcf-buttons-container.dcf-flex div{width:100%}.dcf-buttons-container.dcf-flex ion-button{width:100%;margin-bottom:1rem}}.dcf-steped-form.paginated{padding:2rem 1rem}.dcf-page-steps{display:flex;justify-content:center;align-items:center;margin-bottom:2rem;overflow-x:auto;flex-wrap:nowrap}.dcf-page-steps .dcf-grid{display:flex!important;flex-wrap:nowrap!important;align-items:center}.dcf-step{height:38px;min-width:38px;width:38px;background:var(--dcf-color-gray-2);margin:0;display:flex;color:var(--dcf-color-gray-7);justify-content:center;align-items:center;font-size:1rem;font-weight:600;border-radius:var(--dcf-border-radius)}.dcf-step.dcf-active{color:var(--dcf-color-light);background:var(--ion-color-primary);box-shadow:0 2px 6px #144c714d}.dcf-step.dcf-passed{color:var(--dcf-color-primary-shade);background:var(--dcf-color-gray-3)}.dcf-information{padding-left:.5rem}.dcf-title{font-size:.875rem;font-weight:600;margin:0}.dcf-description{font-size:.8rem;font-weight:500;margin:0;margin-top:.25rem;color:var(--dcf-color-gray-4)}.dcf-arrow-container{display:flex;align-items:center;justify-content:center;padding:0 .5rem;height:38px}.dcf-arrow-container{display:flex;align-items:center;justify-content:center;padding:0 1rem;height:40px}.dcf-arrow-container svg{width:1rem;height:1rem;stroke:var(--dcf-color-gray-8);stroke-opacity:.7;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}ion-button[color=light]{--background: var(--dcf-color-gray-7) !important}.dcf-current-step{margin-top:-.5rem!important;margin-bottom:1.75rem!important;display:flex;align-items:center;justify-content:center}@media (min-width: 639px){.dcf-current-step{display:none}}.dcf-single-step .dcf-information{margin-bottom:1rem}.dcf-single-step .dcf-step-container:not(.ngx-decaf-fieldset){padding-bottom:1.5rem;padding-top:.5rem}.dcf-single-step ion-card{margin-bottom:1.5rem}.dcf-single-step ion-card .dcf-information{margin-top:.75rem}.dcf-step-form-container{margin-bottom:1.75rem!important}.dcf-steped-form ::ng-deep ngx-decaf-component-renderer.ngx-decaf-fieldset,.dcf-steped-form ::ng-deep ngx-decaf-fieldset{padding-top:0!important;padding-bottom:0!important}.dcf-steped-form ::ng-deep ngx-decaf-component-renderer.ngx-decaf-fieldset ion-button,.dcf-steped-form ::ng-deep ngx-decaf-fieldset ion-button{margin-top:1rem!important}\n"] }]
|
|
10890
|
+
}], ctorParameters: () => [], propDecorators: { children: [{
|
|
10891
|
+
type: Input
|
|
10892
|
+
}], paginated: [{
|
|
10893
|
+
type: Input
|
|
10894
|
+
}], pages: [{
|
|
10895
|
+
type: Input
|
|
10896
|
+
}], pageTitles: [{
|
|
10897
|
+
type: Input
|
|
10898
|
+
}], operation: [{
|
|
10899
|
+
type: Input
|
|
10900
|
+
}], startPage: [{
|
|
10901
|
+
type: Input
|
|
10902
|
+
}] } });
|
|
10903
|
+
|
|
10904
|
+
const FileErrors = {
|
|
10905
|
+
notAllowed: 'not_allowed',
|
|
10906
|
+
maxSize: 'max_size',
|
|
10907
|
+
};
|
|
10908
|
+
/**
|
|
10909
|
+
* @description File upload component for Angular applications.
|
|
10910
|
+
* @summary This component provides a user interface for uploading files with support for drag-and-drop,
|
|
10911
|
+
* file validation, and preview functionality. It integrates seamlessly with Angular reactive forms
|
|
10912
|
+
* and supports multiple file uploads, directory mode, and custom file size limits.
|
|
10913
|
+
*
|
|
10914
|
+
* @class FileUploadComponent
|
|
10915
|
+
* @example
|
|
10916
|
+
* ```typescript
|
|
10917
|
+
* <ngx-decaf-file-upload [formGroup]="formGroup" [name]="'fileInput'" [multiple]="true"></ngx-decaf-file-upload>
|
|
10918
|
+
* ```
|
|
10919
|
+
* @mermaid
|
|
10920
|
+
* sequenceDiagram
|
|
10921
|
+
* participant User
|
|
10922
|
+
* participant FileUploadComponent
|
|
10923
|
+
* User->>FileUploadComponent: Select or drag files
|
|
10924
|
+
* FileUploadComponent->>FileUploadComponent: Validate files
|
|
10925
|
+
* FileUploadComponent->>FileUploadComponent: Emit change event
|
|
10926
|
+
* User->>FileUploadComponent: Remove file
|
|
10927
|
+
* FileUploadComponent->>FileUploadComponent: Update file list
|
|
10928
|
+
*/
|
|
10929
|
+
let FileUploadComponent = class FileUploadComponent extends NgxFormFieldDirective {
|
|
10930
|
+
constructor() {
|
|
10931
|
+
super("FileUploadComponent");
|
|
10932
|
+
/**
|
|
10933
|
+
* @description Allows multiple file selection.
|
|
10934
|
+
* @summary When true, the user can select multiple files for upload.
|
|
10935
|
+
*
|
|
10936
|
+
* @type {boolean}
|
|
10937
|
+
* @default false
|
|
10938
|
+
*/
|
|
10939
|
+
this.multiple = false;
|
|
10940
|
+
/**
|
|
10941
|
+
* @description Specifies the input type for the file upload field.
|
|
10942
|
+
* @summary Defines the type of input element used for file uploads, such as file or directory.
|
|
10943
|
+
*
|
|
10944
|
+
* @type {PossibleInputTypes}
|
|
10945
|
+
* @default HTML5InputTypes.FILE
|
|
10946
|
+
*/
|
|
10947
|
+
this.type = HTML5InputTypes.FILE;
|
|
10948
|
+
/**
|
|
10949
|
+
* @description Size of the file upload component.
|
|
10950
|
+
* @summary Determines the visual size of the file upload component, such as large, small, or default.
|
|
10951
|
+
*
|
|
10952
|
+
* @type {Extract<ElementSize, 'large' | 'small' | 'default'>}
|
|
10953
|
+
* @default ElementSizes.large
|
|
10954
|
+
*/
|
|
10955
|
+
this.size = ElementSizes.large;
|
|
10956
|
+
/**
|
|
10957
|
+
* @description Flex positioning of the container's content.
|
|
10958
|
+
* @summary Controls how child elements are positioned within the container when flex layout
|
|
10959
|
+
* is enabled. Options include 'center', 'top', 'bottom', 'left', 'right', and combinations
|
|
10960
|
+
* like 'top-left'. This property is only applied when the flex property is true.
|
|
10961
|
+
*
|
|
10962
|
+
* @type {FlexPosition}
|
|
10963
|
+
* @default 'center'
|
|
10964
|
+
*/
|
|
10965
|
+
this.position = 'center';
|
|
10966
|
+
/**
|
|
10967
|
+
* @description Accepted file types for upload.
|
|
10968
|
+
* @summary Specifies the file types that are allowed for upload, such as images or documents.
|
|
10969
|
+
*
|
|
10970
|
+
* @type {string | string[]}
|
|
10971
|
+
* @default ['image/*']
|
|
10972
|
+
*/
|
|
10973
|
+
this.accept = ['image/*'];
|
|
10974
|
+
/**
|
|
10975
|
+
* @description Whether to show an icon in the file upload field.
|
|
10976
|
+
* @summary When true, an icon is displayed alongside the file upload input.
|
|
10977
|
+
*
|
|
10978
|
+
* @type {boolean}
|
|
10979
|
+
* @default true
|
|
10980
|
+
*/
|
|
10981
|
+
this.showIcon = true;
|
|
10982
|
+
/**
|
|
10983
|
+
* @description Enables directory mode for file uploads.
|
|
10984
|
+
* @summary When true, the user can upload entire directories instead of individual files.
|
|
10985
|
+
*
|
|
10986
|
+
* @type {boolean}
|
|
10987
|
+
* @default false
|
|
10988
|
+
*/
|
|
10989
|
+
this.enableDirectoryMode = false;
|
|
10990
|
+
/**
|
|
10991
|
+
* @description Maximum file size allowed for upload.
|
|
10992
|
+
* @summary Specifies the maximum size (in MB) for files that can be uploaded.
|
|
10993
|
+
*
|
|
10994
|
+
* @type {number}
|
|
10995
|
+
* @default 1
|
|
10996
|
+
*/
|
|
10997
|
+
this.maxFileSize = 1;
|
|
10998
|
+
/**
|
|
10999
|
+
* @description Event emitted when the file upload field changes.
|
|
11000
|
+
* @summary Emits an event containing details about the change in the file upload field.
|
|
11001
|
+
*
|
|
11002
|
+
* @type {EventEmitter<IBaseCustomEvent>}
|
|
11003
|
+
*/
|
|
11004
|
+
this.changeEvent = new EventEmitter();
|
|
11005
|
+
/**
|
|
11006
|
+
* @description Preview of the first file in the upload list.
|
|
11007
|
+
* @summary Stores the data URL of the first file in the upload list for preview purposes.
|
|
11008
|
+
* This is typically used to display a thumbnail or preview image.
|
|
11009
|
+
*
|
|
11010
|
+
* @type {string | undefined}
|
|
11011
|
+
*/
|
|
11012
|
+
this.preview = undefined;
|
|
11013
|
+
/**
|
|
11014
|
+
* @description List of files selected for upload.
|
|
11015
|
+
* @summary Contains the files selected by the user for upload. This array is updated
|
|
11016
|
+
* whenever files are added or removed from the upload list.
|
|
11017
|
+
*
|
|
11018
|
+
* @type {File[]}
|
|
11019
|
+
*/
|
|
11020
|
+
this.files = [];
|
|
11021
|
+
/**
|
|
11022
|
+
* @description List of errors encountered during file validation.
|
|
11023
|
+
* @summary Stores validation errors for files that do not meet the specified criteria,
|
|
11024
|
+
* such as file type or size restrictions. Each error includes the file name, size, and error message.
|
|
11025
|
+
*
|
|
11026
|
+
* @type {IFileUploadError[]}
|
|
11027
|
+
*/
|
|
11028
|
+
this.errors = [];
|
|
11029
|
+
/**
|
|
11030
|
+
* @description Indicates whether a drag operation is in progress.
|
|
11031
|
+
* @summary This flag is set to true when a file is being dragged over the upload area.
|
|
11032
|
+
* It is used to provide visual feedback to the user during drag-and-drop operations.
|
|
11033
|
+
*
|
|
11034
|
+
* @type {boolean}
|
|
11035
|
+
* @default false
|
|
11036
|
+
*/
|
|
11037
|
+
this.dragging = false;
|
|
11038
|
+
/**
|
|
11039
|
+
* @description Counter for drag events.
|
|
11040
|
+
* @summary Tracks the number of drag events to ensure proper handling of drag-and-drop
|
|
11041
|
+
* operations. The counter is incremented on drag enter and decremented on drag leave.
|
|
11042
|
+
*
|
|
11043
|
+
* @type {number}
|
|
11044
|
+
* @default 0
|
|
11045
|
+
*/
|
|
11046
|
+
this.dragCounter = 0;
|
|
11047
|
+
}
|
|
11048
|
+
/**
|
|
11049
|
+
* @description Lifecycle hook that is called after Angular has initialized all data-bound properties of a directive.
|
|
11050
|
+
* @summary Sets up the component by enabling directory mode if specified, formatting the accepted file types,
|
|
11051
|
+
* and converting the maximum file size from megabytes to bytes.
|
|
11052
|
+
*
|
|
11053
|
+
* @returns {void}
|
|
11054
|
+
*/
|
|
11055
|
+
ngOnInit() {
|
|
11056
|
+
if (this.enableDirectoryMode) {
|
|
11057
|
+
this.multiple = true;
|
|
11058
|
+
}
|
|
11059
|
+
if (Array.isArray(this.accept)) {
|
|
11060
|
+
this.accept = this.accept.join(',');
|
|
11061
|
+
}
|
|
11062
|
+
// Convert maxFileSize from MB to bytes
|
|
11063
|
+
this.maxFileSize = this.maxFileSize * 1024 * 1024;
|
|
11064
|
+
}
|
|
11065
|
+
/**
|
|
11066
|
+
* @description Lifecycle hook that is called when a directive, pipe, or service is destroyed.
|
|
11067
|
+
* @summary Cleans up the component by calling the parent ngOnDestroy method and clearing the file upload state.
|
|
11068
|
+
*
|
|
11069
|
+
* @returns {Promise<void> | void}
|
|
11070
|
+
*/
|
|
11071
|
+
ngOnDestroy() {
|
|
11072
|
+
super.ngOnDestroy();
|
|
11073
|
+
this.handleClear();
|
|
11074
|
+
}
|
|
11075
|
+
/**
|
|
11076
|
+
* @description Handles the click event to trigger file selection.
|
|
11077
|
+
* @summary Simulates a click on the hidden file input element to open the file selection dialog.
|
|
11078
|
+
* This method is used to allow users to select files programmatically.
|
|
11079
|
+
*
|
|
11080
|
+
* @returns {void}
|
|
11081
|
+
*/
|
|
11082
|
+
handleClickToSelect() {
|
|
11083
|
+
const element = this.component.nativeElement;
|
|
11084
|
+
if (element)
|
|
11085
|
+
element.querySelector('#dcf-file-input')?.click();
|
|
11086
|
+
}
|
|
11087
|
+
/**
|
|
11088
|
+
* @description Handles the file selection event.
|
|
11089
|
+
* @summary Processes the files selected by the user, validates them, and updates the file list.
|
|
11090
|
+
* This method is triggered when the user selects files using the file input element.
|
|
11091
|
+
*
|
|
11092
|
+
* @param {Event} event - The file selection event.
|
|
11093
|
+
* @returns {void}
|
|
11094
|
+
*/
|
|
11095
|
+
handleSelection(event) {
|
|
11096
|
+
this.clearErrors();
|
|
11097
|
+
const input = event.target;
|
|
11098
|
+
if (input.files) {
|
|
11099
|
+
const fileList = Array.from(input.files);
|
|
11100
|
+
this.handleSelectionConfirm(fileList);
|
|
11101
|
+
input.value = '';
|
|
11102
|
+
}
|
|
11103
|
+
}
|
|
11104
|
+
/**
|
|
11105
|
+
* @description Handles the drop event for drag-and-drop file uploads.
|
|
11106
|
+
* @summary Processes the files dropped by the user, validates them, and updates the file list.
|
|
11107
|
+
* This method is triggered when the user drops files onto the upload area.
|
|
11108
|
+
*
|
|
11109
|
+
* @param {DragEvent} event - The drag-and-drop event.
|
|
11110
|
+
* @returns {void}
|
|
11111
|
+
*/
|
|
11112
|
+
handleDrop(event) {
|
|
11113
|
+
event.preventDefault();
|
|
11114
|
+
event.stopPropagation();
|
|
11115
|
+
this.dragCounter = 0;
|
|
11116
|
+
this.dragging = false;
|
|
11117
|
+
this.clearErrors();
|
|
11118
|
+
if (!event.dataTransfer)
|
|
11119
|
+
return;
|
|
11120
|
+
const fileList = Array.from(event.dataTransfer.files);
|
|
11121
|
+
this.handleSelectionConfirm(fileList);
|
|
11122
|
+
}
|
|
11123
|
+
/**
|
|
11124
|
+
* @description Handles the drag over event for drag-and-drop file uploads.
|
|
11125
|
+
* @summary Sets the dragging flag to true to provide visual feedback during drag-and-drop operations.
|
|
11126
|
+
* This method is triggered when the user drags files over the upload area.
|
|
11127
|
+
*
|
|
11128
|
+
* @param {DragEvent} event - The drag over event.
|
|
11129
|
+
* @returns {void}
|
|
11130
|
+
*/
|
|
11131
|
+
handleDragOver(event) {
|
|
11132
|
+
event.preventDefault();
|
|
11133
|
+
event.stopPropagation();
|
|
11134
|
+
this.dragging = true;
|
|
11135
|
+
}
|
|
11136
|
+
/**
|
|
11137
|
+
* @description Handles the drag leave event for drag-and-drop file uploads.
|
|
11138
|
+
* @summary Decrements the drag counter and clears the dragging flag when the counter reaches zero.
|
|
11139
|
+
* This method is triggered when the user drags files out of the upload area.
|
|
11140
|
+
*
|
|
11141
|
+
* @param {DragEvent} event - The drag leave event.
|
|
11142
|
+
* @returns {void}
|
|
11143
|
+
*/
|
|
11144
|
+
handleDragLeave(event) {
|
|
11145
|
+
event.preventDefault();
|
|
11146
|
+
event.stopPropagation();
|
|
11147
|
+
this.dragCounter = Math.max(0, this.dragCounter - 1);
|
|
11148
|
+
if (this.dragCounter === 0) {
|
|
11149
|
+
this.dragging = false;
|
|
11150
|
+
}
|
|
11151
|
+
}
|
|
11152
|
+
/**
|
|
11153
|
+
* @description Clears the file list and validation errors.
|
|
11154
|
+
* @summary Resets the file upload component by clearing the selected files, preview, and errors.
|
|
11155
|
+
* This method is used to reset the component state.
|
|
11156
|
+
*
|
|
11157
|
+
* @returns {void}
|
|
10151
11158
|
*/
|
|
10152
|
-
|
|
10153
|
-
|
|
10154
|
-
|
|
10155
|
-
|
|
10156
|
-
|
|
10157
|
-
|
|
10158
|
-
|
|
10159
|
-
|
|
11159
|
+
handleClear() {
|
|
11160
|
+
this.clearErrors();
|
|
11161
|
+
this.preview = undefined;
|
|
11162
|
+
this.files = [];
|
|
11163
|
+
}
|
|
11164
|
+
/**
|
|
11165
|
+
* @description Confirms the file selection and updates the component state.
|
|
11166
|
+
* @summary Validates each file in the selection, updates the file list, and emits
|
|
11167
|
+
* the change event. If multiple or directory mode is enabled, adds files to the existing list.
|
|
11168
|
+
* Otherwise, replaces the existing files with the new selection.
|
|
11169
|
+
*
|
|
11170
|
+
* @param {File[]} files - The array of files selected by the user.
|
|
11171
|
+
* @returns {Promise<void>}
|
|
11172
|
+
*/
|
|
11173
|
+
async handleSelectionConfirm(files) {
|
|
11174
|
+
const validFiles = [];
|
|
11175
|
+
for (const file of files) {
|
|
11176
|
+
const isValid = this.validateFile(file);
|
|
11177
|
+
if (isValid === true) {
|
|
11178
|
+
validFiles.push(file);
|
|
10160
11179
|
}
|
|
10161
|
-
|
|
10162
|
-
|
|
10163
|
-
|
|
10164
|
-
|
|
10165
|
-
|
|
10166
|
-
this.submitEvent.emit({
|
|
10167
|
-
data,
|
|
10168
|
-
component: this.componentName,
|
|
10169
|
-
name: this.action || EventConstants.SUBMIT,
|
|
10170
|
-
handlers: this.handlers,
|
|
11180
|
+
else {
|
|
11181
|
+
this.errors.push({
|
|
11182
|
+
name: file.name,
|
|
11183
|
+
error: isValid,
|
|
11184
|
+
size: file.size
|
|
10171
11185
|
});
|
|
10172
11186
|
}
|
|
10173
11187
|
}
|
|
11188
|
+
if (this.multiple || this.enableDirectoryMode) {
|
|
11189
|
+
this.files = this.files.concat(validFiles);
|
|
11190
|
+
}
|
|
11191
|
+
else {
|
|
11192
|
+
this.files = [validFiles[0]];
|
|
11193
|
+
}
|
|
11194
|
+
if (this.files.length) {
|
|
11195
|
+
const dataValues = await this.getDataURLs(this.files);
|
|
11196
|
+
this.setValue(JSON.stringify(dataValues));
|
|
11197
|
+
}
|
|
11198
|
+
await this.getPreview();
|
|
11199
|
+
this.changeEventEmit();
|
|
11200
|
+
}
|
|
11201
|
+
/**
|
|
11202
|
+
* @description Validates a single file against the component's constraints.
|
|
11203
|
+
* @summary Checks the file type and size against the accepted values and limits.
|
|
11204
|
+
* Returns true if the file is valid, or an error code if it is not.
|
|
11205
|
+
*
|
|
11206
|
+
* @param {File} file - The file to be validated.
|
|
11207
|
+
* @returns {true | string} - Returns true if valid, error code otherwise.
|
|
11208
|
+
*/
|
|
11209
|
+
validateFile(file) {
|
|
11210
|
+
if (this.accept && this.accept !== '*') {
|
|
11211
|
+
const acceptedExtensions = Array.isArray(this.accept) ?
|
|
11212
|
+
this.accept : this.accept.split(',').map(ext => ext.trim());
|
|
11213
|
+
const accept = acceptedExtensions.some(ext => {
|
|
11214
|
+
if (ext === '*')
|
|
11215
|
+
return true;
|
|
11216
|
+
if (ext.endsWith('/*'))
|
|
11217
|
+
return file.type.startsWith(ext.replace(/\/\*$/, ''));
|
|
11218
|
+
const fileExtension = file.type.split('/').pop() || '';
|
|
11219
|
+
return file.type === ext || fileExtension === ext || file.name.toLowerCase().endsWith(ext.replace('.', ''));
|
|
11220
|
+
});
|
|
11221
|
+
if (!accept)
|
|
11222
|
+
return FileErrors.notAllowed;
|
|
11223
|
+
}
|
|
11224
|
+
if (this.maxFileSize && file.size > this.maxFileSize)
|
|
11225
|
+
return FileErrors.maxSize;
|
|
11226
|
+
return true;
|
|
10174
11227
|
}
|
|
10175
11228
|
/**
|
|
10176
|
-
* @description
|
|
10177
|
-
* @summary
|
|
10178
|
-
*
|
|
10179
|
-
* group and children to display the previous page's content.
|
|
10180
|
-
*
|
|
10181
|
-
* @return {void}
|
|
10182
|
-
*
|
|
10183
|
-
* @mermaid
|
|
10184
|
-
* sequenceDiagram
|
|
10185
|
-
* participant U as User
|
|
10186
|
-
* participant S as SteppedFormComponent
|
|
10187
|
-
*
|
|
10188
|
-
* U->>S: Click Back
|
|
10189
|
-
* S->>S: activeIndex--
|
|
10190
|
-
* S->>S: getCurrentFormGroup(activeIndex)
|
|
10191
|
-
* Note over S: Update active form and children
|
|
11229
|
+
* @description Displays a preview of the selected file in a lightbox.
|
|
11230
|
+
* @summary If the file is an image, its data URL is retrieved and displayed in a modal lightbox.
|
|
11231
|
+
* The lightbox shows the image at its natural size, constrained to the viewport dimensions.
|
|
10192
11232
|
*
|
|
10193
|
-
* @
|
|
11233
|
+
* @param {File | string} [file] - The file to be previewed. If not provided, the current preview file is used.
|
|
11234
|
+
* @returns {Promise<void>}
|
|
10194
11235
|
*/
|
|
10195
|
-
|
|
10196
|
-
|
|
10197
|
-
|
|
10198
|
-
this.
|
|
11236
|
+
async showFilePreview(file, fileExtension = 'image/') {
|
|
11237
|
+
let content;
|
|
11238
|
+
if (file instanceof File) {
|
|
11239
|
+
const dataUrl = await this.getDataURLs(file);
|
|
11240
|
+
if (dataUrl && dataUrl.length)
|
|
11241
|
+
file = dataUrl[0];
|
|
10199
11242
|
}
|
|
10200
|
-
|
|
11243
|
+
if (fileExtension.includes('image/'))
|
|
11244
|
+
content = '<img src="' + file + '" style="max-width: 100%; height: auto;" />';
|
|
11245
|
+
if (fileExtension.includes('xml')) {
|
|
11246
|
+
const parseXml = (xmlString) => {
|
|
11247
|
+
try {
|
|
11248
|
+
xmlString = xmlString.replace(/^data:[^;]+;base64,/, '').replace(/\s+/g, '');
|
|
11249
|
+
const decodedString = atob(xmlString);
|
|
11250
|
+
const parser = new DOMParser();
|
|
11251
|
+
const xmlDoc = parser.parseFromString(decodedString, "text/xml");
|
|
11252
|
+
// const encoder = new TextEncoder(); // gera bytes UTF-8
|
|
11253
|
+
// const utf8Bytes = encoder.encode(xmlDoc.documentElement.outerHTML);
|
|
11254
|
+
// return new TextDecoder("utf-8").decode(utf8Bytes);
|
|
11255
|
+
return xmlDoc.documentElement.innerHTML;
|
|
11256
|
+
}
|
|
11257
|
+
catch (error) {
|
|
11258
|
+
this.logger.error(error?.message);
|
|
11259
|
+
return undefined;
|
|
11260
|
+
}
|
|
11261
|
+
};
|
|
11262
|
+
content = parseXml(file);
|
|
11263
|
+
content = `<div class="dfc-padding">${content}</div>`;
|
|
11264
|
+
}
|
|
11265
|
+
await presentNgxLightBoxModal(content || "");
|
|
10201
11266
|
}
|
|
10202
11267
|
/**
|
|
10203
|
-
* @description
|
|
10204
|
-
* @summary
|
|
10205
|
-
*
|
|
10206
|
-
* proper Angular change detection when updating the activeContent.
|
|
10207
|
-
*
|
|
10208
|
-
* @param {number} page - The page number to activate
|
|
10209
|
-
* @return {void}
|
|
10210
|
-
*
|
|
10211
|
-
* @private
|
|
10212
|
-
* @mermaid
|
|
10213
|
-
* sequenceDiagram
|
|
10214
|
-
* participant S as SteppedFormComponent
|
|
10215
|
-
* participant F as FormArray
|
|
10216
|
-
* participant T as Timer
|
|
11268
|
+
* @description Checks if a file is an image based on its MIME type.
|
|
11269
|
+
* @summary Determines if the file can be accepted as an image by checking
|
|
11270
|
+
* if its type starts with 'image/'.
|
|
10217
11271
|
*
|
|
10218
|
-
*
|
|
10219
|
-
*
|
|
10220
|
-
* S->>S: Set activeContent = undefined
|
|
10221
|
-
* S->>T: timer(10).subscribe()
|
|
10222
|
-
* T-->>S: Filter children for active page
|
|
10223
|
-
* S->>S: Set activeContent
|
|
10224
|
-
*
|
|
10225
|
-
* @memberOf SteppedFormComponent
|
|
11272
|
+
* @param {File} file - The file to be checked.
|
|
11273
|
+
* @returns {boolean} - True if the file is an image, false otherwise.
|
|
10226
11274
|
*/
|
|
10227
|
-
|
|
10228
|
-
|
|
10229
|
-
this.formGroup = this.formGroup?.parent;
|
|
10230
|
-
this.formGroup = this.formGroup.at(page - 1);
|
|
10231
|
-
this.activeContent = undefined;
|
|
10232
|
-
this.timerSubscription = timer(10).subscribe(() => this.activeContent = this.children.filter(c => c.props?.['page'] === page));
|
|
10233
|
-
}
|
|
10234
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: SteppedFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
10235
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: SteppedFormComponent, isStandalone: true, selector: "ngx-decaf-stepped-form", inputs: { children: "children", paginated: "paginated", pages: "pages", pageTitles: "pageTitles", operation: "operation", startPage: "startPage" }, host: { properties: { "attr.id": "uid" } }, usesInheritance: true, ngImport: i0, template: "<form class=\"dcf-steped-form\" [class.paginated]=\"paginated\" novalidate #component>\n @if (paginated) {\n <div class=\"dcf-page-steps\">\n <div class=\"dcf-grid dcf-grid-collapse skip\">\n @for(page of pageTitles; track $index;) {\n <div class=\"dcf-flex dcf-flex-middle\">\n <div class=\"dcf-step\" [class.dcf-active]=\"activeIndex === $index + 1\" [class.dcf-passed]=\"($index + 1) < activeIndex\">{{ $index + 1 }}</div>\n @if ((page?.title || page?.description)) {\n <div class=\"dcf-information dcf-visible@s\">\n @if (page?.title) {\n <div class=\"dcf-title\">{{ page?.title | translate }}</div>\n }\n @if (page?.description) {\n <div class=\"dcf-description\">{{ page?.description | translate }}</div>\n }\n <div class=\"dcf-separator\"></div>\n </div>\n }\n @if ($index < pageTitles.length - 1) {\n <div class=\"dcf-arrow-container\">\n <svg width=\"8\" height=\"12\" viewBox=\"0 0 8 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M1.5 1L6.5 6L1.5 11\" />\n </svg>\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n @if (pageTitles[activeIndex - 1]?.title || pageTitles[activeIndex - 1]?.description) {\n <div class=\"dcf-current-step\">\n <div>\n @if (pageTitles[activeIndex - 1]?.title) {\n <div class=\"dcf-title\">{{ pageTitles[activeIndex - 1]?.title | translate }}</div>\n }\n @if (pageTitles[activeIndex - 1]?.description) {\n <div class=\"dcf-description\">{{ pageTitles[activeIndex - 1]?.description | translate }}</div>\n }\n </div>\n </div>\n }\n\n @if (initialized && activeContent?.length) {\n <ngx-decaf-layout\n [className]=\"'dcf-stepped-form-grid paginated dcf-grid-nested'\"\n [children]=\"activeContent || []\"\n [parentForm]=\"formGroup || parentForm\"\n [gap]=\"'small'\"\n [flexMode]=\"props.flexMode || false\"\n [match]=\"false\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [match]=\"false\"\n />\n } @else {\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%;\"><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text></ion-text>\n <br />\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%;\"><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text></ion-text>\n }\n <div class=\"dcf-buttons-container dcf-grid dcf-grid-collapse dcf-flex dcf-flex-left\">\n <div class=\"dcf-width-1-2@s\">\n <ion-button color=\"light\" (click)=\"handleBack()\" [disabled]=\"activeIndex <= 1\">\n <!-- <ion-icon aria-hidden=\"true\" name=\"arrow-back-outline\"></ion-icon> -->\n {{locale + '.previous' | translate}}\n </ion-button>\n </div>\n\n <div class=\"dcf-width-1-2@s\">\n <ion-button fill=\"solid\" (click)=\"handleNext(activeIndex === pages ? true : false)\">\n @if (activeIndex === pages) {\n {{locale + '.submit' | translate}}\n } @else {\n {{locale + '.next' | translate}}\n <!-- <ion-icon aria-hidden=\"true\" name=\"arrow-forward-outline\"></ion-icon> -->\n }\n </ion-button>\n </div>\n </div>\n } @else {\n <div class=\"dcf-single-step\">\n @for (item of children; track $index) {\n <ion-card>\n <ion-card-content>\n @if (item.title || item.description) {\n <div class=\"dcf-information\">\n <div>\n @if (item.title) {\n <div class=\"dcf-title\">{{ item.title | translate }}</div>\n }\n @if (item.description) {\n <div class=\"dcf-description\">{{ item.description | translate }}</div>\n }\n </div>\n </div>\n }\n <div>\n @if (initialized && item.items?.length) {\n <div>\n <ngx-decaf-layout\n [className]=\"'dcf-stepped-form-grid dcf-grid-nested'\"\n [children]=\"item.items || []\"\n [parentForm]=\"formGroup || parentForm\"\n [flexMode]=\"props.flexMode || false\"\n [gap]=\"'small'\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [match]=\"false\"\n\n />\n </div>\n\n }\n </div>\n </ion-card-content>\n </ion-card>\n }\n <div class=\"dcf-buttons-container dcf-grid dcf-grid-small dcf-flex dcf-flex-right\">\n <div class=\"dcf-width-auto@s dcf-width-1-1\">\n <ion-button color=\"light\" (click)=\"handleBack()\">\n {{locale + '.cancel' | translate}}\n </ion-button>\n </div>\n\n <div class=\"dcf-width-auto@s dcf-width-1-1\">\n <ion-button fill=\"solid\" (click)=\"handleNext(true)\">\n {{locale + '.submit' | translate}}\n </ion-button>\n </div>\n </div>\n </div>\n }\n</form>\n", styles: [".dcf-buttons-container{margin-top:1.8rem;margin-bottom:0}@media (min-width: 639px){.dcf-buttons-container.dcf-flex div:nth-child(2){display:flex;justify-content:flex-end}}@media (max-width: 638px){.dcf-buttons-container.dcf-flex div{width:100%}.dcf-buttons-container.dcf-flex ion-button{width:100%;margin-bottom:1rem}}.dcf-steped-form.paginated{padding:2rem 1rem}.dcf-page-steps{display:flex;justify-content:center;align-items:center;margin-bottom:2rem;overflow-x:auto;flex-wrap:nowrap}.dcf-page-steps .dcf-grid{display:flex!important;flex-wrap:nowrap!important;align-items:center}.dcf-step{height:38px;min-width:38px;width:38px;background:var(--dcf-color-gray-2);margin:0;display:flex;color:var(--dcf-color-gray-7);justify-content:center;align-items:center;font-size:1rem;font-weight:600;border-radius:var(--dcf-border-radius)}.dcf-step.dcf-active{color:var(--dcf-color-light);background:var(--ion-color-primary);box-shadow:0 2px 6px #144c714d}.dcf-step.dcf-passed{color:var(--dcf-color-primary-shade);background:var(--dcf-color-gray-3)}.dcf-information{padding-left:.5rem}.dcf-title{font-size:.875rem;font-weight:600;margin:0;color:var(--dcf-color-gray-7)}.dcf-description{font-size:.8rem;font-weight:500;margin:0;margin-top:.25rem;color:var(--dcf-color-gray-4)}.dcf-arrow-container{display:flex;align-items:center;justify-content:center;padding:0 .5rem;height:38px}.dcf-arrow-container{display:flex;align-items:center;justify-content:center;padding:0 1rem;height:40px}.dcf-arrow-container svg{width:1rem;height:1rem;stroke:var(--dcf-color-gray-8);stroke-opacity:.7;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}ion-button[color=light]{--background: var(--dcf-color-gray-7) !important}.dcf-current-step{margin-top:-.5rem!important;margin-bottom:1.75rem!important;display:flex;align-items:center;justify-content:center}@media (min-width: 639px){.dcf-current-step{display:none}}.dcf-single-step .dcf-information{margin-bottom:1rem}.dcf-single-step .dcf-step-container:not(.ngx-decaf-fieldset){padding-bottom:1.5rem;padding-top:.5rem}.dcf-single-step ion-card{margin-bottom:1.5rem}.dcf-single-step ion-card .dcf-information{margin-top:.75rem}.dcf-step-form-container{margin-bottom:1.75rem!important}.dcf-steped-form ::ng-deep ngx-decaf-component-renderer.ngx-decaf-fieldset,.dcf-steped-form ::ng-deep ngx-decaf-fieldset{padding-top:0!important;padding-bottom:0!important}.dcf-steped-form ::ng-deep ngx-decaf-component-renderer.ngx-decaf-fieldset ion-button,.dcf-steped-form ::ng-deep ngx-decaf-fieldset ion-button{margin-top:1rem!important}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: 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: LayoutComponent, selector: "ngx-decaf-layout", inputs: ["gap", "breakpoint", "grid", "match", "flexMode", "rowCard", "maxColsLength"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
10236
|
-
};
|
|
10237
|
-
SteppedFormComponent = __decorate([
|
|
10238
|
-
Dynamic(),
|
|
10239
|
-
__metadata("design:paramtypes", [])
|
|
10240
|
-
], SteppedFormComponent);
|
|
10241
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: SteppedFormComponent, decorators: [{
|
|
10242
|
-
type: Component,
|
|
10243
|
-
args: [{ selector: 'ngx-decaf-stepped-form', imports: [
|
|
10244
|
-
TranslatePipe,
|
|
10245
|
-
ReactiveFormsModule,
|
|
10246
|
-
IonSkeletonText,
|
|
10247
|
-
IonText,
|
|
10248
|
-
IonButton,
|
|
10249
|
-
LayoutComponent
|
|
10250
|
-
], standalone: true, host: { '[attr.id]': 'uid' }, template: "<form class=\"dcf-steped-form\" [class.paginated]=\"paginated\" novalidate #component>\n @if (paginated) {\n <div class=\"dcf-page-steps\">\n <div class=\"dcf-grid dcf-grid-collapse skip\">\n @for(page of pageTitles; track $index;) {\n <div class=\"dcf-flex dcf-flex-middle\">\n <div class=\"dcf-step\" [class.dcf-active]=\"activeIndex === $index + 1\" [class.dcf-passed]=\"($index + 1) < activeIndex\">{{ $index + 1 }}</div>\n @if ((page?.title || page?.description)) {\n <div class=\"dcf-information dcf-visible@s\">\n @if (page?.title) {\n <div class=\"dcf-title\">{{ page?.title | translate }}</div>\n }\n @if (page?.description) {\n <div class=\"dcf-description\">{{ page?.description | translate }}</div>\n }\n <div class=\"dcf-separator\"></div>\n </div>\n }\n @if ($index < pageTitles.length - 1) {\n <div class=\"dcf-arrow-container\">\n <svg width=\"8\" height=\"12\" viewBox=\"0 0 8 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M1.5 1L6.5 6L1.5 11\" />\n </svg>\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n @if (pageTitles[activeIndex - 1]?.title || pageTitles[activeIndex - 1]?.description) {\n <div class=\"dcf-current-step\">\n <div>\n @if (pageTitles[activeIndex - 1]?.title) {\n <div class=\"dcf-title\">{{ pageTitles[activeIndex - 1]?.title | translate }}</div>\n }\n @if (pageTitles[activeIndex - 1]?.description) {\n <div class=\"dcf-description\">{{ pageTitles[activeIndex - 1]?.description | translate }}</div>\n }\n </div>\n </div>\n }\n\n @if (initialized && activeContent?.length) {\n <ngx-decaf-layout\n [className]=\"'dcf-stepped-form-grid paginated dcf-grid-nested'\"\n [children]=\"activeContent || []\"\n [parentForm]=\"formGroup || parentForm\"\n [gap]=\"'small'\"\n [flexMode]=\"props.flexMode || false\"\n [match]=\"false\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [match]=\"false\"\n />\n } @else {\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%;\"><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text></ion-text>\n <br />\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%;\"><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text></ion-text>\n }\n <div class=\"dcf-buttons-container dcf-grid dcf-grid-collapse dcf-flex dcf-flex-left\">\n <div class=\"dcf-width-1-2@s\">\n <ion-button color=\"light\" (click)=\"handleBack()\" [disabled]=\"activeIndex <= 1\">\n <!-- <ion-icon aria-hidden=\"true\" name=\"arrow-back-outline\"></ion-icon> -->\n {{locale + '.previous' | translate}}\n </ion-button>\n </div>\n\n <div class=\"dcf-width-1-2@s\">\n <ion-button fill=\"solid\" (click)=\"handleNext(activeIndex === pages ? true : false)\">\n @if (activeIndex === pages) {\n {{locale + '.submit' | translate}}\n } @else {\n {{locale + '.next' | translate}}\n <!-- <ion-icon aria-hidden=\"true\" name=\"arrow-forward-outline\"></ion-icon> -->\n }\n </ion-button>\n </div>\n </div>\n } @else {\n <div class=\"dcf-single-step\">\n @for (item of children; track $index) {\n <ion-card>\n <ion-card-content>\n @if (item.title || item.description) {\n <div class=\"dcf-information\">\n <div>\n @if (item.title) {\n <div class=\"dcf-title\">{{ item.title | translate }}</div>\n }\n @if (item.description) {\n <div class=\"dcf-description\">{{ item.description | translate }}</div>\n }\n </div>\n </div>\n }\n <div>\n @if (initialized && item.items?.length) {\n <div>\n <ngx-decaf-layout\n [className]=\"'dcf-stepped-form-grid dcf-grid-nested'\"\n [children]=\"item.items || []\"\n [parentForm]=\"formGroup || parentForm\"\n [flexMode]=\"props.flexMode || false\"\n [gap]=\"'small'\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [match]=\"false\"\n\n />\n </div>\n\n }\n </div>\n </ion-card-content>\n </ion-card>\n }\n <div class=\"dcf-buttons-container dcf-grid dcf-grid-small dcf-flex dcf-flex-right\">\n <div class=\"dcf-width-auto@s dcf-width-1-1\">\n <ion-button color=\"light\" (click)=\"handleBack()\">\n {{locale + '.cancel' | translate}}\n </ion-button>\n </div>\n\n <div class=\"dcf-width-auto@s dcf-width-1-1\">\n <ion-button fill=\"solid\" (click)=\"handleNext(true)\">\n {{locale + '.submit' | translate}}\n </ion-button>\n </div>\n </div>\n </div>\n }\n</form>\n", styles: [".dcf-buttons-container{margin-top:1.8rem;margin-bottom:0}@media (min-width: 639px){.dcf-buttons-container.dcf-flex div:nth-child(2){display:flex;justify-content:flex-end}}@media (max-width: 638px){.dcf-buttons-container.dcf-flex div{width:100%}.dcf-buttons-container.dcf-flex ion-button{width:100%;margin-bottom:1rem}}.dcf-steped-form.paginated{padding:2rem 1rem}.dcf-page-steps{display:flex;justify-content:center;align-items:center;margin-bottom:2rem;overflow-x:auto;flex-wrap:nowrap}.dcf-page-steps .dcf-grid{display:flex!important;flex-wrap:nowrap!important;align-items:center}.dcf-step{height:38px;min-width:38px;width:38px;background:var(--dcf-color-gray-2);margin:0;display:flex;color:var(--dcf-color-gray-7);justify-content:center;align-items:center;font-size:1rem;font-weight:600;border-radius:var(--dcf-border-radius)}.dcf-step.dcf-active{color:var(--dcf-color-light);background:var(--ion-color-primary);box-shadow:0 2px 6px #144c714d}.dcf-step.dcf-passed{color:var(--dcf-color-primary-shade);background:var(--dcf-color-gray-3)}.dcf-information{padding-left:.5rem}.dcf-title{font-size:.875rem;font-weight:600;margin:0;color:var(--dcf-color-gray-7)}.dcf-description{font-size:.8rem;font-weight:500;margin:0;margin-top:.25rem;color:var(--dcf-color-gray-4)}.dcf-arrow-container{display:flex;align-items:center;justify-content:center;padding:0 .5rem;height:38px}.dcf-arrow-container{display:flex;align-items:center;justify-content:center;padding:0 1rem;height:40px}.dcf-arrow-container svg{width:1rem;height:1rem;stroke:var(--dcf-color-gray-8);stroke-opacity:.7;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}ion-button[color=light]{--background: var(--dcf-color-gray-7) !important}.dcf-current-step{margin-top:-.5rem!important;margin-bottom:1.75rem!important;display:flex;align-items:center;justify-content:center}@media (min-width: 639px){.dcf-current-step{display:none}}.dcf-single-step .dcf-information{margin-bottom:1rem}.dcf-single-step .dcf-step-container:not(.ngx-decaf-fieldset){padding-bottom:1.5rem;padding-top:.5rem}.dcf-single-step ion-card{margin-bottom:1.5rem}.dcf-single-step ion-card .dcf-information{margin-top:.75rem}.dcf-step-form-container{margin-bottom:1.75rem!important}.dcf-steped-form ::ng-deep ngx-decaf-component-renderer.ngx-decaf-fieldset,.dcf-steped-form ::ng-deep ngx-decaf-fieldset{padding-top:0!important;padding-bottom:0!important}.dcf-steped-form ::ng-deep ngx-decaf-component-renderer.ngx-decaf-fieldset ion-button,.dcf-steped-form ::ng-deep ngx-decaf-fieldset ion-button{margin-top:1rem!important}\n"] }]
|
|
10251
|
-
}], ctorParameters: () => [], propDecorators: { children: [{
|
|
10252
|
-
type: Input
|
|
10253
|
-
}], paginated: [{
|
|
10254
|
-
type: Input
|
|
10255
|
-
}], pages: [{
|
|
10256
|
-
type: Input
|
|
10257
|
-
}], pageTitles: [{
|
|
10258
|
-
type: Input
|
|
10259
|
-
}], operation: [{
|
|
10260
|
-
type: Input
|
|
10261
|
-
}], startPage: [{
|
|
10262
|
-
type: Input
|
|
10263
|
-
}] } });
|
|
10264
|
-
|
|
10265
|
-
let ModalComponent = class ModalComponent extends NgxParentComponentDirective {
|
|
10266
|
-
constructor() {
|
|
10267
|
-
super("ModalComponent");
|
|
10268
|
-
this.isOpen = false;
|
|
10269
|
-
this.InlineContentPosition = 'bottom';
|
|
10270
|
-
this.fullscreen = false;
|
|
10271
|
-
this.modalController = inject(ModalController);
|
|
10272
|
-
addIcons(allIcons);
|
|
10273
|
-
}
|
|
10274
|
-
async ngOnInit() {
|
|
10275
|
-
if (!this.modalController)
|
|
10276
|
-
this.modalController = modalController;
|
|
10277
|
-
}
|
|
10278
|
-
async initialize(options = {}) {
|
|
10279
|
-
if (!this.modalController)
|
|
10280
|
-
this.modalController = modalController;
|
|
10281
|
-
this.options = Object.assign({}, DefaultModalOptions, this.options, options);
|
|
10282
|
-
this.initialized = true;
|
|
11275
|
+
isImageFile(file) {
|
|
11276
|
+
return file && file.type.startsWith('image/');
|
|
10283
11277
|
}
|
|
10284
|
-
|
|
10285
|
-
|
|
10286
|
-
|
|
10287
|
-
|
|
11278
|
+
/**
|
|
11279
|
+
* @description Removes a file from the selection.
|
|
11280
|
+
* @summary Updates the file list to exclude the file at the specified index.
|
|
11281
|
+
* Emits the change event and updates the preview if necessary.
|
|
11282
|
+
*
|
|
11283
|
+
* @param {number} index - The index of the file to be removed.
|
|
11284
|
+
* @returns {Promise<void>}
|
|
11285
|
+
*/
|
|
11286
|
+
async removeFile(index) {
|
|
11287
|
+
if (index <= this.files.length)
|
|
11288
|
+
this.files = [...this.files.filter((_, i) => i !== index)];
|
|
11289
|
+
await this.getPreview();
|
|
11290
|
+
this.changeEventEmit();
|
|
10288
11291
|
}
|
|
10289
|
-
|
|
10290
|
-
|
|
10291
|
-
|
|
11292
|
+
/**
|
|
11293
|
+
* @description Retrieves the preview image for the selected files.
|
|
11294
|
+
* @summary If the first selected file is an image, its data URL is retrieved and set as the preview.
|
|
11295
|
+
* If the file is not an image, the preview is cleared.
|
|
11296
|
+
*
|
|
11297
|
+
* @returns {Promise<void>}
|
|
11298
|
+
*/
|
|
11299
|
+
async getPreview() {
|
|
11300
|
+
this.preview = undefined;
|
|
11301
|
+
const file = this.files && this.files.length ? this.files[0] : null;
|
|
11302
|
+
if (file) {
|
|
11303
|
+
const dataUrl = await this.getDataURLs(file);
|
|
11304
|
+
if (dataUrl && dataUrl.length)
|
|
11305
|
+
this.preview = dataUrl[0];
|
|
11306
|
+
}
|
|
10292
11307
|
}
|
|
10293
|
-
|
|
10294
|
-
|
|
10295
|
-
|
|
10296
|
-
|
|
10297
|
-
|
|
10298
|
-
|
|
10299
|
-
|
|
10300
|
-
|
|
10301
|
-
|
|
10302
|
-
|
|
10303
|
-
|
|
11308
|
+
/**
|
|
11309
|
+
* @description Emits the change event for the file upload field.
|
|
11310
|
+
* @summary Triggers the change event, notifying any listeners that the value has changed.
|
|
11311
|
+
* The event contains the updated value, component name, and event type.
|
|
11312
|
+
*
|
|
11313
|
+
* @returns {void}
|
|
11314
|
+
*/
|
|
11315
|
+
changeEventEmit() {
|
|
11316
|
+
this.changeEvent.emit({
|
|
11317
|
+
data: this.value,
|
|
11318
|
+
component: this.componentName,
|
|
11319
|
+
name: ComponentEventNames.CHANGE,
|
|
10304
11320
|
});
|
|
10305
11321
|
}
|
|
10306
|
-
|
|
10307
|
-
|
|
10308
|
-
|
|
10309
|
-
|
|
10310
|
-
|
|
10311
|
-
|
|
10312
|
-
|
|
10313
|
-
|
|
10314
|
-
|
|
10315
|
-
|
|
10316
|
-
|
|
10317
|
-
|
|
10318
|
-
|
|
10319
|
-
|
|
10320
|
-
]
|
|
10321
|
-
|
|
10322
|
-
|
|
10323
|
-
|
|
10324
|
-
|
|
10325
|
-
|
|
10326
|
-
|
|
10327
|
-
|
|
10328
|
-
|
|
10329
|
-
|
|
10330
|
-
|
|
10331
|
-
|
|
10332
|
-
|
|
10333
|
-
type: Input
|
|
10334
|
-
}], InlineContentPosition: [{
|
|
10335
|
-
type: Input
|
|
10336
|
-
}], fullscreen: [{
|
|
10337
|
-
type: Input
|
|
10338
|
-
}] } });
|
|
10339
|
-
async function getNgxModalComponent(props = {}, modalProps = {}, injector) {
|
|
10340
|
-
const { globals } = { ...props };
|
|
10341
|
-
if (!globals || !globals?.['operation'])
|
|
10342
|
-
props.globals = { ...(globals || {}), operation: OperationKeys.CREATE };
|
|
10343
|
-
const component = NgxRenderingEngine.createComponent(ModalComponent, props, injector || undefined);
|
|
10344
|
-
return component.create(modalProps);
|
|
10345
|
-
}
|
|
10346
|
-
|
|
10347
|
-
class NgxSvgDirective {
|
|
10348
|
-
constructor() {
|
|
10349
|
-
this.mediaService = inject(NgxMediaService);
|
|
10350
|
-
this.element = inject(ElementRef);
|
|
10351
|
-
this.http = inject(HttpClient);
|
|
10352
|
-
}
|
|
10353
|
-
ngOnInit() {
|
|
10354
|
-
this.path = this.path?.trim() || this.element?.nativeElement?.getAttribute('src')?.trim() || '';
|
|
10355
|
-
if (this.path)
|
|
10356
|
-
this.mediaService.loadSvgObserver(this.http, this.path, this.element.nativeElement);
|
|
10357
|
-
}
|
|
10358
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgxSvgDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
10359
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.9", type: NgxSvgDirective, isStandalone: true, selector: "[ngx-decaf-svg]", inputs: { path: ["ngx-decaf-svg", "path"] }, ngImport: i0 }); }
|
|
10360
|
-
}
|
|
10361
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgxSvgDirective, decorators: [{
|
|
10362
|
-
type: Directive,
|
|
10363
|
-
args: [{
|
|
10364
|
-
selector: '[ngx-decaf-svg]',
|
|
10365
|
-
standalone: true
|
|
10366
|
-
}]
|
|
10367
|
-
}], propDecorators: { path: [{
|
|
10368
|
-
type: Input,
|
|
10369
|
-
args: ['ngx-decaf-svg']
|
|
10370
|
-
}] } });
|
|
10371
|
-
|
|
10372
|
-
let IconComponent = class IconComponent {
|
|
10373
|
-
constructor() {
|
|
10374
|
-
this.color = "";
|
|
10375
|
-
this.slot = 'icon-only';
|
|
10376
|
-
this.button = false;
|
|
10377
|
-
this.buttonFill = 'clear';
|
|
10378
|
-
this.buttonShape = 'round';
|
|
10379
|
-
this.size = 'default';
|
|
10380
|
-
this.type = 'ionic';
|
|
10381
|
-
this.isSvg = false;
|
|
10382
|
-
this.initialized = false;
|
|
10383
|
-
this.inline = false;
|
|
10384
|
-
this.mediaService = new NgxMediaService$1();
|
|
10385
|
-
addIcons(allIcons);
|
|
11322
|
+
/**
|
|
11323
|
+
* @description Retrieves the data URLs for the selected files.
|
|
11324
|
+
* @summary Converts the selected image files to data URLs using FileReader.
|
|
11325
|
+
* The resulting data URLs can be used for previewing images in the browser.
|
|
11326
|
+
*
|
|
11327
|
+
* @param {File[] | File} [files] - The files for which to generate data URLs.
|
|
11328
|
+
* If not provided, the currently selected files are used.
|
|
11329
|
+
*
|
|
11330
|
+
* @returns {Promise<string[] | undefined>} - A promise that resolves to an array of data URLs, or undefined if an error occurs.
|
|
11331
|
+
*/
|
|
11332
|
+
async getDataURLs(files) {
|
|
11333
|
+
if (!files)
|
|
11334
|
+
files = this.files;
|
|
11335
|
+
if (!Array.isArray(files))
|
|
11336
|
+
files = [files];
|
|
11337
|
+
// files = files.filter(f => f.type && f.type.startsWith('image/'));
|
|
11338
|
+
return this.readFile(files).then(urls => {
|
|
11339
|
+
// validate generated DataURLs
|
|
11340
|
+
const invalid = urls.some(u => !this.isValidDataURL(u));
|
|
11341
|
+
if (invalid)
|
|
11342
|
+
return undefined;
|
|
11343
|
+
if (this.multiple || this.enableDirectoryMode)
|
|
11344
|
+
return urls;
|
|
11345
|
+
return urls.length ? [urls[0]] : undefined;
|
|
11346
|
+
}).catch(() => {
|
|
11347
|
+
return undefined;
|
|
11348
|
+
});
|
|
10386
11349
|
}
|
|
10387
|
-
|
|
10388
|
-
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
|
|
10392
|
-
|
|
11350
|
+
/**
|
|
11351
|
+
* @description Validates the format of a data URL.
|
|
11352
|
+
* @summary Checks if the data URL is a non-empty string and matches the expected pattern
|
|
11353
|
+
* for base64-encoded image data URLs. Uses a regular expression to validate the format.
|
|
11354
|
+
*
|
|
11355
|
+
* @param {string | undefined} dataURL - The data URL to be validated.
|
|
11356
|
+
* @returns {boolean} - True if the data URL is valid, false otherwise.
|
|
11357
|
+
*/
|
|
11358
|
+
isValidDataURL(dataURL) {
|
|
11359
|
+
if (!dataURL || typeof dataURL !== 'string') {
|
|
11360
|
+
return false;
|
|
11361
|
+
}
|
|
11362
|
+
// Regex para qualquer MIME type seguido de ;base64
|
|
11363
|
+
const match = dataURL.match(/^data:([a-zA-Z0-9.+-\\/]+);base64,([A-Za-z0-9+/=\s]+)$/);
|
|
11364
|
+
if (!match)
|
|
11365
|
+
return false;
|
|
11366
|
+
const payload = match[2];
|
|
11367
|
+
try {
|
|
11368
|
+
if (typeof atob === 'function') {
|
|
11369
|
+
// remove espaços e tenta decodificar
|
|
11370
|
+
atob(payload.replace(/\s+/g, ''));
|
|
11371
|
+
}
|
|
11372
|
+
return true;
|
|
11373
|
+
}
|
|
11374
|
+
catch {
|
|
11375
|
+
return false;
|
|
10393
11376
|
}
|
|
10394
|
-
this.initialized = true;
|
|
10395
11377
|
}
|
|
10396
|
-
|
|
10397
|
-
|
|
11378
|
+
/**
|
|
11379
|
+
* @description Clears all error messages from the component.
|
|
11380
|
+
* @summary Resets the error state, removing all error messages from the display.
|
|
11381
|
+
*
|
|
11382
|
+
* @returns {void}
|
|
11383
|
+
*/
|
|
11384
|
+
clearErrors() {
|
|
11385
|
+
this.errors = [];
|
|
10398
11386
|
}
|
|
10399
|
-
|
|
10400
|
-
|
|
11387
|
+
/**
|
|
11388
|
+
* @description Reads the selected files as data URLs.
|
|
11389
|
+
* @summary Uses the FileReader API to read each file as a data URL.
|
|
11390
|
+
* Returns a promise that resolves to an array of data URLs.
|
|
11391
|
+
*
|
|
11392
|
+
* @param {File[]} files - The files to be read.
|
|
11393
|
+
* @returns {Promise<string[]>} - A promise that resolves to an array of data URLs.
|
|
11394
|
+
*/
|
|
11395
|
+
readFile(files) {
|
|
11396
|
+
return Promise.all(files.map(file => new Promise((resolve, reject) => {
|
|
11397
|
+
const reader = new FileReader();
|
|
11398
|
+
reader.onerror = () => reject(reader.error);
|
|
11399
|
+
reader.onload = () => resolve(String(reader.result || ''));
|
|
11400
|
+
reader.readAsDataURL(file);
|
|
11401
|
+
})));
|
|
11402
|
+
}
|
|
11403
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FileUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
11404
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: FileUploadComponent, isStandalone: true, selector: "ngx-decaf-file-upload", inputs: { formGroup: "formGroup", name: "name", formControl: "formControl", required: "required", multiple: "multiple", type: "type", label: "label", buttonLabel: "buttonLabel", size: "size", position: "position", accept: "accept", showIcon: "showIcon", enableDirectoryMode: "enableDirectoryMode", maxFileSize: "maxFileSize" }, outputs: { changeEvent: "changeEvent" }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"decaf-file-component\" #component>\n <input\n id=\"dcf-file-input\"\n type=\"file\"\n placeholder=\"Select files\"\n [attr.accept]=\"accept\"\n [attr.multiple]=\"multiple ? true : null\"\n (change)=\"handleSelection($event)\"\n [multiple]=\"multiple\"\n hidden\n [attr.webkitdirectory]=\"enableDirectoryMode ? true : null\"\n />\n\n <ngx-decaf-card [className]=\"className\" [body]=\"'blank'\">\n <div>\n <div\n [class]=\"\n 'dcf-drop-area '\n + ' dcf-' + size\n + ' dcf-flex dcf-flex-' + position\n + ' dcf-text-' + position\n \"\n\n [class.dcf-dragging]=\"dragging\"\n [class.dcf-has-files]=\"files.length\"\n (drop)=\"!files?.length ? handleDrop($event) : dragging = false\"\n (dragover)=\"!files?.length ? handleDragOver($event) : dragging = false\"\n (dragleave)=\"!files?.length ? handleDragLeave($event) : dragging = false\"\n >\n <div>\n @if (!preview) {\n @if(showIcon) {\n <ngx-decaf-icon name=\"cloud-upload-outline\" size=\"large\" />\n }\n <p class=\"dcf-drag-description\">{{ label ? (label | translate) : (locale + \".drag_file\" | translate) }}</p>\n <ion-button class=\"dcf-button-select\" (click)=\"handleClickToSelect()\" size=\"small\">\n {{ buttonLabel ? (buttonLabel | translate) : (locale + \".buttons.select\" | translate) }}\n </ion-button>\n <div #container>\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n } @else {\n @if ((!directoryMode && !multiple) ) {\n <div class=\"dcf-preview dcf-grid dcf-grid-match dcf-grid-collapse\">\n <div class=\"dcf-width-1-4@m dcf-width-1-3@s dcf-flex dcf-flex-center dcf-flex-middle\">\n <div class=\"dcf-preview-image\">\n <ion-img\n [src]=\"preview\"\n [title]=\"locale + '.preview' | translate\"\n [alt]=\"locale + '.preview' | translate\"\n />\n <div class=\"dcf-overlay\">\n <ion-button (click)=\"showFilePreview(preview)\" fill=\"clear\" color=\"light\" size=\"small\">\n {{ locale + \".buttons.preview\" | translate }}\n </ion-button>\n </div>\n </div>\n </div>\n <div class=\"description dcf-flex dcf-flex-middle dcf-width-expand@s\">\n <div>\n <p class=\"dcf-title\">{{ locale + \".preview\" | translate }}</p>\n <p class=\"subtitle\">{{ files[0].name }}</p>\n <ion-button (click)=\"handleClear()\" fill=\"clear\" color=\"danger\" size=\"small\">{{ locale + \".buttons.clear\" | translate }} </ion-button>\n </div>\n </div>\n </div>\n } @else {\n <div class=\"dcf-margin-bottom\">\n {{ locale + \".selection\" | translate: { \"0\": files.length > 10 ? files.length : `0${files.length}` } }}\n @if(errors.length > 0) {\n <br /><span class=\"dcf-error-message\">{{ locale + \".selection_error\" | translate: { \"0\": errors.length > 10 ? errors.length : `0${errors.length}` } }}</span>\n }\n </div>\n <div class=\"dcf-preview-list-container\">\n <ion-list class=\"dcf-preview-list\">\n @for (file of errors; track $index) {\n <ion-item lines=\"full\" class=\"dcf-error-item\">\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n <div class=\"dcf-error-message\" slot=\"end\">\n {{ locale + \".errors.\" + file.error | translate: { \"0\": file.error === 'max_size' ? maxFileSize / 1024 / 1024 : file.name.split(\".\") } }}\n </div>\n <ion-note slot=\"end\">{{ file.size / 1024 / 1024 | number: \"1.1-1\" }} MB</ion-note>\n </ion-item>\n }\n\n @for (file of files; track $index) {\n <ion-item lines=\"full\">\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n <ion-note slot=\"end\">{{ file.size / 1024 / 1024 | number: \"1.1-1\" }} MB</ion-note>\n <div class=\"dcf-flex dcf-flex-middle\" slot=\"end\">\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n (click)=\"showFilePreview(file, file.type)\"\n [name]=\"'image-outline'\"\n />\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n [name]=\"'trash-outline'\"\n (click)=\"removeFile($index)\"\n [color]=\"'danger'\"\n [size]=\"'small'\"\n />\n </div>\n </ion-item>\n }\n </ion-list>\n </div>\n }\n }\n </div>\n\n\n </div>\n </div>\n </ngx-decaf-card>\n</div>\n\n<!-- <ion-card-header>\n <ion-card-title>Upload de Imagem</ion-card-title>\n </ion-card-header>\n\n <ion-card-content>\n <div\n class=\"dcf-drop-area\"\n [class.dragging]=\"dragging\"\n (drop)=\"onDrop($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n >\n <div class=\"dcf-drop-content\">\n <ion-icon name=\"cloud-upload-outline\" size=\"large\"></ion-icon>\n <p>Arraste e solte aqui ou</p>\n <ion-button size=\"small\" fill=\"outline\" (click)=\"triggerFileSelect()\">Selecionar arquivo</ion-button>\n </div>\n </div>\n\n <input\n #fileInput\n type=\"file\"\n [attr.accept]=\"accept\"\n [attr.multiple]=\"multiple ? true : null\"\n (change)=\"onFileSelected($event)\"\n hidden\n />\n\n <div *ngIf=\"previewUrl\" class=\"dcf-preview\">\n <ion-item>\n <div slot=\"start\">\n <ion-img [src]=\"previewUrl\"></ion-img>\n </div>\n <ion-label>\n <h3>Pr\u00E9-visualiza\u00E7\u00E3o</h3>\n <p *ngIf=\"files.length\">{{ files[0].name }}</p>\n </ion-label>\n </ion-item>\n </div>\n\n <ion-list *ngIf=\"files.length\">\n <ion-list-header>\n <ion-label>Arquivos selecionados</ion-label>\n </ion-list-header>\n <ion-item *ngFor=\"let f of files; let i = index\">\n <ion-label>{{ f.name }}</ion-label>\n <ion-note slot=\"end\">{{ (f.size / 1024 / 1024) | number:'1.1-1' }} MB</ion-note>\n <ion-button fill=\"clear\" slot=\"end\" (click)=\"removeFile(i)\">\n <ion-icon slot=\"icon-only\" name=\"close-circle\"></ion-icon>\n </ion-button>\n </ion-item>\n </ion-list>\n\n <div *ngIf=\"errors.length\">\n <ion-list>\n <ion-item *ngFor=\"let err of errors\">\n <ion-icon name=\"alert-circle\" slot=\"start\" color=\"danger\"></ion-icon>\n <ion-label color=\"danger\">{{ err }}</ion-label>\n </ion-item>\n </ion-list>\n </div>\n\n <ion-row class=\"dcf-actions\">\n <ion-col>\n <ion-button expand=\"block\" (click)=\"triggerFileSelect()\">Selecionar</ion-button>\n </ion-col>\n <ion-col>\n <ion-button expand=\"block\" color=\"danger\" fill=\"outline\" (click)=\"clear()\">Limpar</ion-button>\n </ion-col>\n </ion-row>\n </ion-card-content> -->\n", styles: [".decaf-file-component.dcf-palette-dark .dcf-button-select{--background: rgb(var(--dcf-color-light-rgb), .1) !important;--background-hover: rgb(var(--dcf-color-light-rgb), .75) !important;--background-activated: rgb(var(--dcf-color-light-rgb), .4) !important;--background-focused: rgb(var(--dcf-color-light-rgb), .4) !important;--color: var(--dcf-color-light) !important}.decaf-file-component.dcf-palette-dark .dcf-has-files{border-style:solid;border-color:var(--dcf-color-gray-6)!important}.decaf-file-component .dcf-upload-icon{--box-shadow: none !important}.decaf-file-component .dcf-upload-icon ion-icon{width:1.5rem!important}.decaf-file-component ion-button.dcf-button-select{--background: rgb(var(--dcf-color-primary-rgb), .1);--background-hover: rgb(var(--dcf-color-primary-rgb), .75);--background-activated: rgb(var(--dcf-color-primary-rgb), .4);--background-focused: rgb(var(--dcf-color-primary-rgb), .4);--color: var(--dcf-color-primary-shade);--border-radius: var(--dcf-border-radius-small);--box-shadow: none;--padding-top: var(--dcf-padding-xsmall);--padding-bottom: var(--dcf-padding-xsmall);--padding-start: var(--dcf-padding-small);--padding-end: var(--dcf-padding-small);font-weight:500;text-transform:none;margin-top:var(--dcf-margin-small)!important}.decaf-file-component .dcf-error{color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:500!important;line-height:1.1rem;z-index:9999;animation-duration:.05s;animation-timing-function:ease-in;animation-fill-mode:both;animation-name:fadeBottomSmallAnimation}.decaf-file-component .dcf-error .ti,.decaf-file-component .dcf-error ion-icon{position:relative;top:2px!important;min-width:20px;font-size:1rem!important;text-align:left}.decaf-file-component ion-card-content{width:100%}.decaf-file-component .dcf-error-message{color:var(--dcf-color-danger);font-size:.875rem}.decaf-file-component .dcf-drag-description{font-size:1rem;line-height:1.5rem;font-weight:500;margin-bottom:var(--dcf-margin-small)}.decaf-file-component .dcf-drop-area{display:flex;align-items:center;border:1.5px dashed var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-small)!important;transition:border-style .15s ease,border-color .15s ease;background:transparent}.decaf-file-component .dcf-drop-area.dcf-large{min-height:180px}.decaf-file-component .dcf-drop-area>div{width:100%}.decaf-file-component .dcf-drop-area.dcf-has-files{border-style:solid;border-color:var(--dcf-color-primary-shade);transition:border-style .15s ease,border-color .15s ease;padding:var(--dcf-spacement) var(--dcf-spacement-small)!important}.decaf-file-component .dcf-drop-area:not(.dcf-has-files){border-style:dashed;padding:var(--dcf-spacement) var(--dcf-spacement-medium)}.decaf-file-component .dcf-drop-area.dcf-dragging{background:#00000008;border-color:var(--ion-color-primary);box-shadow:0 2px 8px #0000000f}.decaf-file-component .dcf-preview .dcf-preview-image{border:1px solid var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-xsmall);max-width:320px;padding:.5rem;box-sizing:border-box;height:160px;position:relative;cursor:pointer;overflow:hidden}.decaf-file-component .dcf-preview .dcf-preview-image ion-img{height:140px!important;display:block;width:100%}.decaf-file-component .dcf-preview .dcf-preview-image:hover .dcf-overlay{opacity:1}.decaf-file-component .dcf-preview .dcf-preview-image .dcf-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:#0009;display:flex;justify-content:center;align-items:center;opacity:0;transition:opacity .3s ease}.decaf-file-component .dcf-preview .description{text-align:left;padding:1rem;font-size:.75rem}.decaf-file-component .dcf-preview .description .dcf-title{font-size:1rem;font-weight:500}.decaf-file-component .dcf-preview .description ion-button{margin-top:var(--dcf-margin-small)!important}.decaf-file-component .dcf-preview-list-container{max-height:150px;overflow-y:auto}.decaf-file-component .dcf-preview-list-container ion-list{padding:0!important;margin:0!important}@media (max-width: 767px){.decaf-file-component .dcf-preview-list-container ion-list{width:100%;min-width:576px;overflow-x:auto}}.decaf-file-component .dcf-preview-list-container:not(:hover){scrollbar-color:rgba(var(--dcf-color-medium-rgb),.125) transparent!important}.decaf-file-component .dcf-preview-list-container ion-item{font-size:.875rem!important}.decaf-file-component .dcf-preview-list-container ion-item.dcf-error-item{--background: rgba(var(--dcf-color-danger-rgb), .02) !important;--border-color: rgba(var(--dcf-color-danger-rgb), .2) !important}.decaf-file-component .dcf-preview-list-container ion-item ion-item{--padding-top: .25rem;--padding-bottom: 0rem;--inner-padding-start: 0rem;--padding-start: var(--dcf-padding-xsmall) !important;--padding-end: 0rem;--inner-padding-end: var(--dcf-padding-xsmall) !important;--background-hover: var(--dcf-color-gray-8);--background-focused: var(--dcf-color-gray-8);--background-hover-opacity: .1;--background-focused-opacity: .1;--border-color: var(--dcf-color-gray-2)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: CardComponent, selector: "ngx-decaf-card", inputs: ["type", "title", "body", "subtitle", "color", "separator", "borders", "inlineContent", "inlineContentPosition"] }, { kind: "component", type: IconComponent, selector: "ngx-decaf-icon", inputs: ["name", "color", "slot", "button", "buttonFill", "buttonShape", "width", "size", "inline"] }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "pipe", type: i1$1.DecimalPipe, name: "number" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
10401
11405
|
};
|
|
10402
|
-
|
|
11406
|
+
FileUploadComponent = __decorate([
|
|
10403
11407
|
Dynamic(),
|
|
10404
11408
|
__metadata("design:paramtypes", [])
|
|
10405
|
-
],
|
|
10406
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type:
|
|
11409
|
+
], FileUploadComponent);
|
|
11410
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FileUploadComponent, decorators: [{
|
|
10407
11411
|
type: Component,
|
|
10408
|
-
args: [{ selector: 'ngx-decaf-icon', imports: [NgxSvgDirective, IonIcon, IonButton], standalone: true, host: { '[attr.id]': 'uid' }, template: "<div class=\"dcf-icon\" #component>\n @if(initialized) {\n @if(button) {\n <ion-button\n [fill]=\"buttonFill\"\n [shape]=\"buttonShape\"\n [color]=\"color\">\n @if(type === 'image') {\n @if(isSvg) {\n <span\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [class]=\"color ? 'dcf-color-' + color : ''\"\n [style.width]=\"width\"\n [ngx-decaf-svg]=\"name\">\n ></span>\n } @else {\n <img\n aria-hidden=\"true\" [alt]=\"name\" [title]=\"name\" [slot]=\"slot\" [src]=\"name\" [style.width]=\"width\" title=\"icon\" />\n }\n\n } @else {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [ios]=\"name\"\n [md]=\"name\"\n [size]=\"size\"\n [color]=\"color\"\n [name]=\"name\" />\n }\n </ion-button>\n } @else {\n @if(type === 'image') {\n @if(isSvg) {\n <span\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [class]=\"color ? 'dcf-color-' + color : ''\"\n [style.width]=\"width\"\n [ngx-decaf-svg]=\"name\"\n\n >\n </span>\n } @else {\n <img aria-hidden=\"true\" [alt]=\"name\" [title]=\"name\" [slot]=\"slot\" [src]=\"name\" [style.width]=\"width\" title=\"icon\" />\n }\n }\n @if(type === 'ionic') {\n\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [ios]=\"name\"\n [md]=\"name\"\n [size]=\"size\"\n [color]=\"color\"\n [name]=\"name\" />\n\n }\n }\n }\n</div>\n", styles: ["::ng-deep .dcf-icon.dcf-palette-dark ion-icon{color:var(--dcf-text-color)!important}::ng-deep .dcf-icon.dcf-palette-dark svg{fill:var(--dcf-text-color);fill-opacity:.25!important;stroke:var(--dcf-text-color)!important}::ng-deep .dcf-icon.dcf-palette-dark svg *{fill:var(--dcf-color-primary)!important;stroke:var(--dcf-color-gray-1)!important}.dcf-icon ion-icon:not([size]){font-size:1.35rem!important}\n"] }]
|
|
11412
|
+
args: [{ selector: 'ngx-decaf-file-upload', standalone: true, imports: [CommonModule, ReactiveFormsModule, CardComponent, IconComponent, IonList, IonLabel, IonItem, IonText, TranslatePipe, IonIcon, IonButton], template: "<div class=\"decaf-file-component\" #component>\n <input\n id=\"dcf-file-input\"\n type=\"file\"\n placeholder=\"Select files\"\n [attr.accept]=\"accept\"\n [attr.multiple]=\"multiple ? true : null\"\n (change)=\"handleSelection($event)\"\n [multiple]=\"multiple\"\n hidden\n [attr.webkitdirectory]=\"enableDirectoryMode ? true : null\"\n />\n\n <ngx-decaf-card [className]=\"className\" [body]=\"'blank'\">\n <div>\n <div\n [class]=\"\n 'dcf-drop-area '\n + ' dcf-' + size\n + ' dcf-flex dcf-flex-' + position\n + ' dcf-text-' + position\n \"\n\n [class.dcf-dragging]=\"dragging\"\n [class.dcf-has-files]=\"files.length\"\n (drop)=\"!files?.length ? handleDrop($event) : dragging = false\"\n (dragover)=\"!files?.length ? handleDragOver($event) : dragging = false\"\n (dragleave)=\"!files?.length ? handleDragLeave($event) : dragging = false\"\n >\n <div>\n @if (!preview) {\n @if(showIcon) {\n <ngx-decaf-icon name=\"cloud-upload-outline\" size=\"large\" />\n }\n <p class=\"dcf-drag-description\">{{ label ? (label | translate) : (locale + \".drag_file\" | translate) }}</p>\n <ion-button class=\"dcf-button-select\" (click)=\"handleClickToSelect()\" size=\"small\">\n {{ buttonLabel ? (buttonLabel | translate) : (locale + \".buttons.select\" | translate) }}\n </ion-button>\n <div #container>\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n } @else {\n @if ((!directoryMode && !multiple) ) {\n <div class=\"dcf-preview dcf-grid dcf-grid-match dcf-grid-collapse\">\n <div class=\"dcf-width-1-4@m dcf-width-1-3@s dcf-flex dcf-flex-center dcf-flex-middle\">\n <div class=\"dcf-preview-image\">\n <ion-img\n [src]=\"preview\"\n [title]=\"locale + '.preview' | translate\"\n [alt]=\"locale + '.preview' | translate\"\n />\n <div class=\"dcf-overlay\">\n <ion-button (click)=\"showFilePreview(preview)\" fill=\"clear\" color=\"light\" size=\"small\">\n {{ locale + \".buttons.preview\" | translate }}\n </ion-button>\n </div>\n </div>\n </div>\n <div class=\"description dcf-flex dcf-flex-middle dcf-width-expand@s\">\n <div>\n <p class=\"dcf-title\">{{ locale + \".preview\" | translate }}</p>\n <p class=\"subtitle\">{{ files[0].name }}</p>\n <ion-button (click)=\"handleClear()\" fill=\"clear\" color=\"danger\" size=\"small\">{{ locale + \".buttons.clear\" | translate }} </ion-button>\n </div>\n </div>\n </div>\n } @else {\n <div class=\"dcf-margin-bottom\">\n {{ locale + \".selection\" | translate: { \"0\": files.length > 10 ? files.length : `0${files.length}` } }}\n @if(errors.length > 0) {\n <br /><span class=\"dcf-error-message\">{{ locale + \".selection_error\" | translate: { \"0\": errors.length > 10 ? errors.length : `0${errors.length}` } }}</span>\n }\n </div>\n <div class=\"dcf-preview-list-container\">\n <ion-list class=\"dcf-preview-list\">\n @for (file of errors; track $index) {\n <ion-item lines=\"full\" class=\"dcf-error-item\">\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n <div class=\"dcf-error-message\" slot=\"end\">\n {{ locale + \".errors.\" + file.error | translate: { \"0\": file.error === 'max_size' ? maxFileSize / 1024 / 1024 : file.name.split(\".\") } }}\n </div>\n <ion-note slot=\"end\">{{ file.size / 1024 / 1024 | number: \"1.1-1\" }} MB</ion-note>\n </ion-item>\n }\n\n @for (file of files; track $index) {\n <ion-item lines=\"full\">\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n <ion-note slot=\"end\">{{ file.size / 1024 / 1024 | number: \"1.1-1\" }} MB</ion-note>\n <div class=\"dcf-flex dcf-flex-middle\" slot=\"end\">\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n (click)=\"showFilePreview(file, file.type)\"\n [name]=\"'image-outline'\"\n />\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n [name]=\"'trash-outline'\"\n (click)=\"removeFile($index)\"\n [color]=\"'danger'\"\n [size]=\"'small'\"\n />\n </div>\n </ion-item>\n }\n </ion-list>\n </div>\n }\n }\n </div>\n\n\n </div>\n </div>\n </ngx-decaf-card>\n</div>\n\n<!-- <ion-card-header>\n <ion-card-title>Upload de Imagem</ion-card-title>\n </ion-card-header>\n\n <ion-card-content>\n <div\n class=\"dcf-drop-area\"\n [class.dragging]=\"dragging\"\n (drop)=\"onDrop($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n >\n <div class=\"dcf-drop-content\">\n <ion-icon name=\"cloud-upload-outline\" size=\"large\"></ion-icon>\n <p>Arraste e solte aqui ou</p>\n <ion-button size=\"small\" fill=\"outline\" (click)=\"triggerFileSelect()\">Selecionar arquivo</ion-button>\n </div>\n </div>\n\n <input\n #fileInput\n type=\"file\"\n [attr.accept]=\"accept\"\n [attr.multiple]=\"multiple ? true : null\"\n (change)=\"onFileSelected($event)\"\n hidden\n />\n\n <div *ngIf=\"previewUrl\" class=\"dcf-preview\">\n <ion-item>\n <div slot=\"start\">\n <ion-img [src]=\"previewUrl\"></ion-img>\n </div>\n <ion-label>\n <h3>Pr\u00E9-visualiza\u00E7\u00E3o</h3>\n <p *ngIf=\"files.length\">{{ files[0].name }}</p>\n </ion-label>\n </ion-item>\n </div>\n\n <ion-list *ngIf=\"files.length\">\n <ion-list-header>\n <ion-label>Arquivos selecionados</ion-label>\n </ion-list-header>\n <ion-item *ngFor=\"let f of files; let i = index\">\n <ion-label>{{ f.name }}</ion-label>\n <ion-note slot=\"end\">{{ (f.size / 1024 / 1024) | number:'1.1-1' }} MB</ion-note>\n <ion-button fill=\"clear\" slot=\"end\" (click)=\"removeFile(i)\">\n <ion-icon slot=\"icon-only\" name=\"close-circle\"></ion-icon>\n </ion-button>\n </ion-item>\n </ion-list>\n\n <div *ngIf=\"errors.length\">\n <ion-list>\n <ion-item *ngFor=\"let err of errors\">\n <ion-icon name=\"alert-circle\" slot=\"start\" color=\"danger\"></ion-icon>\n <ion-label color=\"danger\">{{ err }}</ion-label>\n </ion-item>\n </ion-list>\n </div>\n\n <ion-row class=\"dcf-actions\">\n <ion-col>\n <ion-button expand=\"block\" (click)=\"triggerFileSelect()\">Selecionar</ion-button>\n </ion-col>\n <ion-col>\n <ion-button expand=\"block\" color=\"danger\" fill=\"outline\" (click)=\"clear()\">Limpar</ion-button>\n </ion-col>\n </ion-row>\n </ion-card-content> -->\n", styles: [".decaf-file-component.dcf-palette-dark .dcf-button-select{--background: rgb(var(--dcf-color-light-rgb), .1) !important;--background-hover: rgb(var(--dcf-color-light-rgb), .75) !important;--background-activated: rgb(var(--dcf-color-light-rgb), .4) !important;--background-focused: rgb(var(--dcf-color-light-rgb), .4) !important;--color: var(--dcf-color-light) !important}.decaf-file-component.dcf-palette-dark .dcf-has-files{border-style:solid;border-color:var(--dcf-color-gray-6)!important}.decaf-file-component .dcf-upload-icon{--box-shadow: none !important}.decaf-file-component .dcf-upload-icon ion-icon{width:1.5rem!important}.decaf-file-component ion-button.dcf-button-select{--background: rgb(var(--dcf-color-primary-rgb), .1);--background-hover: rgb(var(--dcf-color-primary-rgb), .75);--background-activated: rgb(var(--dcf-color-primary-rgb), .4);--background-focused: rgb(var(--dcf-color-primary-rgb), .4);--color: var(--dcf-color-primary-shade);--border-radius: var(--dcf-border-radius-small);--box-shadow: none;--padding-top: var(--dcf-padding-xsmall);--padding-bottom: var(--dcf-padding-xsmall);--padding-start: var(--dcf-padding-small);--padding-end: var(--dcf-padding-small);font-weight:500;text-transform:none;margin-top:var(--dcf-margin-small)!important}.decaf-file-component .dcf-error{color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:500!important;line-height:1.1rem;z-index:9999;animation-duration:.05s;animation-timing-function:ease-in;animation-fill-mode:both;animation-name:fadeBottomSmallAnimation}.decaf-file-component .dcf-error .ti,.decaf-file-component .dcf-error ion-icon{position:relative;top:2px!important;min-width:20px;font-size:1rem!important;text-align:left}.decaf-file-component ion-card-content{width:100%}.decaf-file-component .dcf-error-message{color:var(--dcf-color-danger);font-size:.875rem}.decaf-file-component .dcf-drag-description{font-size:1rem;line-height:1.5rem;font-weight:500;margin-bottom:var(--dcf-margin-small)}.decaf-file-component .dcf-drop-area{display:flex;align-items:center;border:1.5px dashed var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-small)!important;transition:border-style .15s ease,border-color .15s ease;background:transparent}.decaf-file-component .dcf-drop-area.dcf-large{min-height:180px}.decaf-file-component .dcf-drop-area>div{width:100%}.decaf-file-component .dcf-drop-area.dcf-has-files{border-style:solid;border-color:var(--dcf-color-primary-shade);transition:border-style .15s ease,border-color .15s ease;padding:var(--dcf-spacement) var(--dcf-spacement-small)!important}.decaf-file-component .dcf-drop-area:not(.dcf-has-files){border-style:dashed;padding:var(--dcf-spacement) var(--dcf-spacement-medium)}.decaf-file-component .dcf-drop-area.dcf-dragging{background:#00000008;border-color:var(--ion-color-primary);box-shadow:0 2px 8px #0000000f}.decaf-file-component .dcf-preview .dcf-preview-image{border:1px solid var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-xsmall);max-width:320px;padding:.5rem;box-sizing:border-box;height:160px;position:relative;cursor:pointer;overflow:hidden}.decaf-file-component .dcf-preview .dcf-preview-image ion-img{height:140px!important;display:block;width:100%}.decaf-file-component .dcf-preview .dcf-preview-image:hover .dcf-overlay{opacity:1}.decaf-file-component .dcf-preview .dcf-preview-image .dcf-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:#0009;display:flex;justify-content:center;align-items:center;opacity:0;transition:opacity .3s ease}.decaf-file-component .dcf-preview .description{text-align:left;padding:1rem;font-size:.75rem}.decaf-file-component .dcf-preview .description .dcf-title{font-size:1rem;font-weight:500}.decaf-file-component .dcf-preview .description ion-button{margin-top:var(--dcf-margin-small)!important}.decaf-file-component .dcf-preview-list-container{max-height:150px;overflow-y:auto}.decaf-file-component .dcf-preview-list-container ion-list{padding:0!important;margin:0!important}@media (max-width: 767px){.decaf-file-component .dcf-preview-list-container ion-list{width:100%;min-width:576px;overflow-x:auto}}.decaf-file-component .dcf-preview-list-container:not(:hover){scrollbar-color:rgba(var(--dcf-color-medium-rgb),.125) transparent!important}.decaf-file-component .dcf-preview-list-container ion-item{font-size:.875rem!important}.decaf-file-component .dcf-preview-list-container ion-item.dcf-error-item{--background: rgba(var(--dcf-color-danger-rgb), .02) !important;--border-color: rgba(var(--dcf-color-danger-rgb), .2) !important}.decaf-file-component .dcf-preview-list-container ion-item ion-item{--padding-top: .25rem;--padding-bottom: 0rem;--inner-padding-start: 0rem;--padding-start: var(--dcf-padding-xsmall) !important;--padding-end: 0rem;--inner-padding-end: var(--dcf-padding-xsmall) !important;--background-hover: var(--dcf-color-gray-8);--background-focused: var(--dcf-color-gray-8);--background-hover-opacity: .1;--background-focused-opacity: .1;--border-color: var(--dcf-color-gray-2)}\n"] }]
|
|
10409
11413
|
}], ctorParameters: () => [], propDecorators: { component: [{
|
|
10410
11414
|
type: ViewChild,
|
|
10411
|
-
args: ['component', {
|
|
11415
|
+
args: ['component', { static: true }]
|
|
11416
|
+
}], formGroup: [{
|
|
11417
|
+
type: Input
|
|
10412
11418
|
}], name: [{
|
|
10413
11419
|
type: Input
|
|
10414
|
-
}],
|
|
11420
|
+
}], formControl: [{
|
|
10415
11421
|
type: Input
|
|
10416
|
-
}],
|
|
11422
|
+
}], required: [{
|
|
10417
11423
|
type: Input
|
|
10418
|
-
}],
|
|
11424
|
+
}], multiple: [{
|
|
10419
11425
|
type: Input
|
|
10420
|
-
}],
|
|
11426
|
+
}], type: [{
|
|
10421
11427
|
type: Input
|
|
10422
|
-
}],
|
|
11428
|
+
}], label: [{
|
|
10423
11429
|
type: Input
|
|
10424
|
-
}],
|
|
11430
|
+
}], buttonLabel: [{
|
|
10425
11431
|
type: Input
|
|
10426
11432
|
}], size: [{
|
|
10427
11433
|
type: Input
|
|
10428
|
-
}],
|
|
11434
|
+
}], position: [{
|
|
11435
|
+
type: Input
|
|
11436
|
+
}], accept: [{
|
|
11437
|
+
type: Input
|
|
11438
|
+
}], showIcon: [{
|
|
11439
|
+
type: Input
|
|
11440
|
+
}], enableDirectoryMode: [{
|
|
10429
11441
|
type: Input
|
|
11442
|
+
}], maxFileSize: [{
|
|
11443
|
+
type: Input
|
|
11444
|
+
}], changeEvent: [{
|
|
11445
|
+
type: Output
|
|
10430
11446
|
}] } });
|
|
10431
11447
|
|
|
10432
11448
|
/**
|
|
@@ -10455,7 +11471,8 @@ const Components = [
|
|
|
10455
11471
|
FilterComponent,
|
|
10456
11472
|
SteppedFormComponent,
|
|
10457
11473
|
IconComponent,
|
|
10458
|
-
CardComponent
|
|
11474
|
+
CardComponent,
|
|
11475
|
+
FileUploadComponent
|
|
10459
11476
|
];
|
|
10460
11477
|
class ForAngularComponentsModule {
|
|
10461
11478
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ForAngularComponentsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
@@ -10474,7 +11491,8 @@ class ForAngularComponentsModule {
|
|
|
10474
11491
|
FilterComponent,
|
|
10475
11492
|
SteppedFormComponent,
|
|
10476
11493
|
IconComponent,
|
|
10477
|
-
CardComponent
|
|
11494
|
+
CardComponent,
|
|
11495
|
+
FileUploadComponent], exports: [ModelRendererComponent,
|
|
10478
11496
|
ComponentRendererComponent,
|
|
10479
11497
|
CrudFieldComponent,
|
|
10480
11498
|
CrudFormComponent,
|
|
@@ -10489,7 +11507,8 @@ class ForAngularComponentsModule {
|
|
|
10489
11507
|
FilterComponent,
|
|
10490
11508
|
SteppedFormComponent,
|
|
10491
11509
|
IconComponent,
|
|
10492
|
-
CardComponent
|
|
11510
|
+
CardComponent,
|
|
11511
|
+
FileUploadComponent] }); }
|
|
10493
11512
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ForAngularComponentsModule, imports: [CrudFieldComponent,
|
|
10494
11513
|
CrudFormComponent,
|
|
10495
11514
|
EmptyStateComponent,
|
|
@@ -10503,7 +11522,8 @@ class ForAngularComponentsModule {
|
|
|
10503
11522
|
FilterComponent,
|
|
10504
11523
|
SteppedFormComponent,
|
|
10505
11524
|
IconComponent,
|
|
10506
|
-
CardComponent
|
|
11525
|
+
CardComponent,
|
|
11526
|
+
FileUploadComponent] }); }
|
|
10507
11527
|
}
|
|
10508
11528
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ForAngularComponentsModule, decorators: [{
|
|
10509
11529
|
type: NgModule,
|
|
@@ -10701,7 +11721,7 @@ class NgxPageDirective extends NgxComponentDirective {
|
|
|
10701
11721
|
* @return {void}
|
|
10702
11722
|
* @memberOf module:lib/engine/NgxPageDirective
|
|
10703
11723
|
*/
|
|
10704
|
-
setPageTitle(route, menu) {
|
|
11724
|
+
async setPageTitle(route, menu) {
|
|
10705
11725
|
if (!route)
|
|
10706
11726
|
route = this.router.url.replace('/', '');
|
|
10707
11727
|
if (!menu)
|
|
@@ -10709,7 +11729,7 @@ class NgxPageDirective extends NgxComponentDirective {
|
|
|
10709
11729
|
const activeMenu = menu.find(item => item?.url?.includes(route));
|
|
10710
11730
|
if (activeMenu) {
|
|
10711
11731
|
const title = activeMenu?.title || activeMenu?.label;
|
|
10712
|
-
this.titleService.setTitle(`${title}`);
|
|
11732
|
+
this.titleService.setTitle(`${await this.translate(title)} ${this.appName ? `- ${this.appName}` : ''}`);
|
|
10713
11733
|
if (!this.title)
|
|
10714
11734
|
this.title = title;
|
|
10715
11735
|
}
|
|
@@ -10780,10 +11800,13 @@ class NgxModelPageDirective extends NgxPageDirective {
|
|
|
10780
11800
|
// super("NgxModelPageDirective");
|
|
10781
11801
|
// }
|
|
10782
11802
|
get pageTitle() {
|
|
11803
|
+
if (!this.modelName && this.model instanceof Model)
|
|
11804
|
+
this.modelName = this.model?.constructor?.name || "";
|
|
10783
11805
|
if (!this.operation)
|
|
10784
|
-
return `Listing ${this.modelName}`;
|
|
11806
|
+
return this.title ? this.title : `Listing ${this.modelName}`;
|
|
10785
11807
|
const operation = this.operation.charAt(0).toUpperCase() + this.operation.slice(1).toLowerCase();
|
|
10786
|
-
return
|
|
11808
|
+
return this.modelName ?
|
|
11809
|
+
`${operation} ${this.modelName}` : this.title;
|
|
10787
11810
|
}
|
|
10788
11811
|
/**
|
|
10789
11812
|
* @description Lazy-initialized repository getter with model resolution.
|
|
@@ -10863,7 +11886,7 @@ class NgxModelPageDirective extends NgxPageDirective {
|
|
|
10863
11886
|
async handleEvent(event) {
|
|
10864
11887
|
const { name } = event;
|
|
10865
11888
|
switch (name) {
|
|
10866
|
-
case
|
|
11889
|
+
case ComponentEventNames.SUBMIT:
|
|
10867
11890
|
await this.handleSubmit(event);
|
|
10868
11891
|
break;
|
|
10869
11892
|
}
|
|
@@ -10879,7 +11902,7 @@ class NgxModelPageDirective extends NgxPageDirective {
|
|
|
10879
11902
|
* @param {IBaseCustomEvent} event - The submit event containing form data
|
|
10880
11903
|
* @return {Promise<IModelPageCustomEvent|void>} Promise that resolves on success or throws on error
|
|
10881
11904
|
*/
|
|
10882
|
-
async handleSubmit(event) {
|
|
11905
|
+
async handleSubmit(event, redirect = false) {
|
|
10883
11906
|
try {
|
|
10884
11907
|
const repo = this._repository;
|
|
10885
11908
|
const operation = this.operation === OperationKeys.READ ? 'delete' : this.operation.toLowerCase();
|
|
@@ -10893,7 +11916,8 @@ class NgxModelPageDirective extends NgxPageDirective {
|
|
|
10893
11916
|
});
|
|
10894
11917
|
if (result) {
|
|
10895
11918
|
repo.refresh(this.modelName, this.operation, this.modelId);
|
|
10896
|
-
|
|
11919
|
+
if (redirect)
|
|
11920
|
+
this.location.back();
|
|
10897
11921
|
}
|
|
10898
11922
|
return {
|
|
10899
11923
|
...event,
|
|
@@ -10996,5 +12020,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
|
|
|
10996
12020
|
* Generated bundle index. Do not edit.
|
|
10997
12021
|
*/
|
|
10998
12022
|
|
|
10999
|
-
export { ActionRoles, AngularEngineKeys, BaseComponentProps, CPTKN, CardComponent, ComponentRendererComponent, ComponentsTagNames, CrudFieldComponent, CrudFormComponent, CssClasses, DB_ADAPTER_PROVIDER, DB_ADAPTER_PROVIDER_TOKEN, DecafFakerRepository, DefaultFormReactiveOptions, DefaultListEmptyOptions, DefaultModalOptions, Dynamic, DynamicModule, ElementSizes, EmptyStateComponent,
|
|
12023
|
+
export { ActionRoles, AngularEngineKeys, BaseComponentProps, CPTKN, CardComponent, ComponentEventNames, ComponentRendererComponent, ComponentsTagNames, CrudFieldComponent, CrudFormComponent, CssClasses, DB_ADAPTER_PROVIDER, DB_ADAPTER_PROVIDER_TOKEN, DecafFakerRepository, DefaultFormReactiveOptions, DefaultListEmptyOptions, DefaultModalOptions, Dynamic, DynamicModule, ElementPositions, ElementSizes, EmptyStateComponent, FieldsetComponent, FileUploadComponent, FilterComponent, ForAngularCommonModule, ForAngularComponentsModule, FormConstants, I18N_CONFIG_TOKEN, I18nLoader, I18nLoaderFactory, I18nParser, IconComponent, LOCALE_ROOT_TOKEN, LayoutComponent, LayoutGridGaps, ListComponent, ListComponentsTypes, ListItemComponent, ListItemPositions, LoggerLevels, ModalComponent, ModelRendererComponent, NgxComponentDirective, NgxEventHandler, NgxFormDirective, NgxFormFieldDirective, NgxFormService, NgxMediaService, NgxModelPageDirective, NgxPageDirective, NgxParentComponentDirective, NgxRenderingEngine, NgxSvgDirective, PaginationComponent, RouteDirections, SearchbarComponent, SteppedFormComponent, WindowColorSchemes, cleanSpaces, dataMapper, filterString, formatDate, generateRandomValue, getFakerData, getInjectablesRegistry, getLocaleContext, getLocaleContextByKey, getLocaleFromClassName, getLocaleLanguage, getLogger, getModelRepository, getNgxModalComponent, getNgxSelectOptionsModal, getOnWindow, getOnWindowDocument, getWindow, getWindowDocument, getWindowWidth, isDarkMode, isDevelopmentMode, isNotUndefined, isValidDate, itemMapper, parseToValidDate, presentNgxLightBoxModal, provideDbAdapter, provideDynamicComponents, provideI18n, provideI18nLoader, removeFocusTrap, setOnWindow, stringToBoolean, windowEventEmitter };
|
|
11000
12024
|
//# sourceMappingURL=decaf-ts-for-angular.mjs.map
|