@decaf-ts/for-angular 0.0.25 → 0.0.26
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/fesm2022/decaf-ts-for-angular.mjs +1465 -1488
- package/fesm2022/decaf-ts-for-angular.mjs.map +1 -1
- package/index.d.ts +7470 -3
- package/package.json +14 -17
- package/components/component-renderer/component-renderer.component.d.ts +0 -278
- package/components/crud-field/crud-field.component.d.ts +0 -611
- package/components/crud-form/constants.d.ts +0 -5
- package/components/crud-form/crud-form.component.d.ts +0 -288
- package/components/crud-form/types.d.ts +0 -17
- package/components/empty-state/empty-state.component.d.ts +0 -300
- package/components/fieldset/fieldset.component.d.ts +0 -555
- package/components/filter/filter.component.d.ts +0 -514
- package/components/for-angular-components.module.d.ts +0 -20
- package/components/index.d.ts +0 -16
- package/components/layout/layout.component.d.ts +0 -110
- package/components/list/list.component.d.ts +0 -848
- package/components/list-item/list-item.component.d.ts +0 -390
- package/components/model-renderer/model-renderer.component.d.ts +0 -97
- package/components/pagination/constants.d.ts +0 -7
- package/components/pagination/pagination.component.d.ts +0 -264
- package/components/searchbar/searchbar.component.d.ts +0 -407
- package/components/stepped-form/stepped-form.component.d.ts +0 -255
- package/directives/collapsable.directive.d.ts +0 -9
- package/directives/index.d.ts +0 -1
- package/engine/DynamicModule.d.ts +0 -17
- package/engine/NgxBaseComponent.d.ts +0 -541
- package/engine/NgxCrudFormField.d.ts +0 -123
- package/engine/NgxFormService.d.ts +0 -601
- package/engine/NgxRenderingEngine.d.ts +0 -282
- package/engine/ValidatorFactory.d.ts +0 -15
- package/engine/constants.d.ts +0 -168
- package/engine/decorators.d.ts +0 -25
- package/engine/index.d.ts +0 -18
- package/engine/interfaces.d.ts +0 -271
- package/engine/types.d.ts +0 -200
- package/esm2022/components/component-renderer/component-renderer.component.mjs +0 -321
- package/esm2022/components/crud-field/crud-field.component.mjs +0 -518
- package/esm2022/components/crud-form/constants.mjs +0 -14
- package/esm2022/components/crud-form/crud-form.component.mjs +0 -259
- package/esm2022/components/crud-form/types.mjs +0 -2
- package/esm2022/components/empty-state/empty-state.component.mjs +0 -345
- package/esm2022/components/fieldset/fieldset.component.mjs +0 -677
- package/esm2022/components/filter/filter.component.mjs +0 -700
- package/esm2022/components/for-angular-components.module.mjs +0 -84
- package/esm2022/components/index.mjs +0 -20
- package/esm2022/components/layout/layout.component.mjs +0 -150
- package/esm2022/components/list/list.component.mjs +0 -1238
- package/esm2022/components/list-item/list-item.component.mjs +0 -405
- package/esm2022/components/model-renderer/model-renderer.component.mjs +0 -144
- package/esm2022/components/pagination/constants.mjs +0 -2
- package/esm2022/components/pagination/pagination.component.mjs +0 -321
- package/esm2022/components/searchbar/searchbar.component.mjs +0 -491
- package/esm2022/components/stepped-form/stepped-form.component.mjs +0 -306
- package/esm2022/decaf-ts-for-angular.mjs +0 -5
- package/esm2022/directives/collapsable.directive.mjs +0 -29
- package/esm2022/directives/index.mjs +0 -2
- package/esm2022/engine/DynamicModule.mjs +0 -18
- package/esm2022/engine/NgxBaseComponent.mjs +0 -541
- package/esm2022/engine/NgxCrudFormField.mjs +0 -137
- package/esm2022/engine/NgxFormService.mjs +0 -917
- package/esm2022/engine/NgxRenderingEngine.mjs +0 -376
- package/esm2022/engine/ValidatorFactory.mjs +0 -106
- package/esm2022/engine/constants.mjs +0 -170
- package/esm2022/engine/decorators.mjs +0 -38
- package/esm2022/engine/index.mjs +0 -19
- package/esm2022/engine/interfaces.mjs +0 -4
- package/esm2022/engine/types.mjs +0 -2
- package/esm2022/for-angular-common.module.mjs +0 -84
- package/esm2022/helpers/index.mjs +0 -13
- package/esm2022/helpers/utils.mjs +0 -436
- package/esm2022/i18n/Loader.mjs +0 -86
- package/esm2022/i18n/data/en.json +0 -85
- package/esm2022/public-apis.mjs +0 -15
- package/for-angular-common.module.d.ts +0 -50
- package/helpers/index.d.ts +0 -12
- package/helpers/utils.d.ts +0 -279
- package/i18n/Loader.d.ts +0 -43
- package/public-apis.d.ts +0 -14
|
@@ -11,11 +11,10 @@ import { TranslateModule, TranslatePipe, TranslateService } from '@ngx-translate
|
|
|
11
11
|
import { Logging } from '@decaf-ts/logging';
|
|
12
12
|
import { __decorate, __metadata } from 'tslib';
|
|
13
13
|
import { apply, metadata } from '@decaf-ts/reflection';
|
|
14
|
-
import { IonInput, IonItem, IonCheckbox, IonRadioGroup, IonRadio, IonSelect, IonSelectOption, IonLabel, IonText, IonTextarea,
|
|
14
|
+
import { IonInput, IonItem, IonCheckbox, IonRadioGroup, IonRadio, IonSelect, IonSelectOption, IonLabel, IonText, IonTextarea, IonButton, IonIcon, IonCard, IonCardContent, IonAccordionGroup, IonAccordion, IonList, IonReorder, IonReorderGroup, IonSearchbar, IonChip, IonRefresher, IonThumbnail, IonSkeletonText, IonRefresherContent, IonInfiniteScroll, IonInfiniteScrollContent, IonListHeader, IonItemSliding, IonItemOptions, IonItemOption, IonContent, IonPopover } from '@ionic/angular/standalone';
|
|
15
15
|
import { addIcons } from 'ionicons';
|
|
16
16
|
import * as allIcons from 'ionicons/icons';
|
|
17
17
|
import { chevronUpOutline, chevronDownOutline, createOutline, alertCircleOutline, chevronForwardOutline, chevronBackOutline, arrowBackOutline, arrowForwardOutline } from 'ionicons/icons';
|
|
18
|
-
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
|
19
18
|
import { forkJoin, fromEvent, debounceTime, Subject, timer } from 'rxjs';
|
|
20
19
|
import { map } from 'rxjs/operators';
|
|
21
20
|
import { Repository, OrderDirection, Condition } from '@decaf-ts/core';
|
|
@@ -292,8 +291,19 @@ class ValidatorFactory {
|
|
|
292
291
|
}
|
|
293
292
|
}
|
|
294
293
|
|
|
294
|
+
/** */
|
|
295
295
|
const DB_ADAPTER_PROVIDER_TOKEN = new InjectionToken('DB_ADAPTER_PROVIDER');
|
|
296
296
|
const I18N_CONFIG_TOKEN = new InjectionToken('I18N_CONFIG_TOKEN');
|
|
297
|
+
function provideDbAdapter(adapterClass, options = {}) {
|
|
298
|
+
const adapter = new adapterClass(options);
|
|
299
|
+
// Log and expose adapter flavour globally
|
|
300
|
+
getLogger(provideDbAdapter).info(`Using ${adapter.flavour} as Db Provider`);
|
|
301
|
+
// getWindow()['dbAdapterFlavour'] = adapter.flavour;
|
|
302
|
+
return {
|
|
303
|
+
provide: DB_ADAPTER_PROVIDER_TOKEN,
|
|
304
|
+
useValue: adapter,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
297
307
|
const ComponentsAndModules = [
|
|
298
308
|
CommonModule,
|
|
299
309
|
FormsModule,
|
|
@@ -341,8 +351,8 @@ class ForAngularCommonModule {
|
|
|
341
351
|
ngModule: ForAngularCommonModule,
|
|
342
352
|
};
|
|
343
353
|
}
|
|
344
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
345
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
354
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: ForAngularCommonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
355
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.2", ngImport: i0, type: ForAngularCommonModule, imports: [CommonModule,
|
|
346
356
|
FormsModule,
|
|
347
357
|
ReactiveFormsModule,
|
|
348
358
|
TranslateModule,
|
|
@@ -351,7 +361,7 @@ class ForAngularCommonModule {
|
|
|
351
361
|
ReactiveFormsModule,
|
|
352
362
|
TranslateModule,
|
|
353
363
|
TranslatePipe] }); }
|
|
354
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
364
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: ForAngularCommonModule, imports: [CommonModule,
|
|
355
365
|
FormsModule,
|
|
356
366
|
ReactiveFormsModule,
|
|
357
367
|
TranslateModule,
|
|
@@ -360,7 +370,7 @@ class ForAngularCommonModule {
|
|
|
360
370
|
ReactiveFormsModule,
|
|
361
371
|
TranslateModule] }); }
|
|
362
372
|
}
|
|
363
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
373
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: ForAngularCommonModule, decorators: [{
|
|
364
374
|
type: NgModule,
|
|
365
375
|
args: [{
|
|
366
376
|
imports: ComponentsAndModules,
|
|
@@ -2382,10 +2392,10 @@ class ComponentRendererComponent {
|
|
|
2382
2392
|
}
|
|
2383
2393
|
}
|
|
2384
2394
|
}
|
|
2385
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2386
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2395
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: ComponentRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2396
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.2", type: ComponentRendererComponent, isStandalone: true, selector: "ngx-decaf-component-renderer", inputs: { tag: "tag", globals: "globals", children: "children", model: "model", parent: "parent" }, outputs: { listenEvent: "listenEvent" }, host: { properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "vcr", first: true, predicate: ["componentViewContainer"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "inner", first: true, predicate: ["inner"], descendants: true, read: TemplateRef, static: true }], ngImport: i0, template: "<!-- Keep to avoid id conflicts -->\n<div [id]=\"uid\"></div>\n\n<ng-template #componentViewContainer></ng-template>\n<ng-template #inner>\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(children?.length) {\n @for(child of children; track child) {\n @if(child.children?.length) {\n <ngx-decaf-component-renderer [parent]=\"child\"> </ngx-decaf-component-renderer>\n } @else {\n <ngx-decaf-component-renderer\n [tag]=\"child?.tag\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]=\"{props: child.props}\" />\n }\n }\n }\n</ng-template>\n\n\n", styles: [""], dependencies: [{ kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "globals", "children", "model", "parent"], outputs: ["listenEvent"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }] }); }
|
|
2387
2397
|
}
|
|
2388
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2398
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: ComponentRendererComponent, decorators: [{
|
|
2389
2399
|
type: Component,
|
|
2390
2400
|
args: [{ selector: 'ngx-decaf-component-renderer', imports: [NgComponentOutlet], standalone: true, host: { '[attr.id]': 'uid' }, template: "<!-- Keep to avoid id conflicts -->\n<div [id]=\"uid\"></div>\n\n<ng-template #componentViewContainer></ng-template>\n<ng-template #inner>\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(children?.length) {\n @for(child of children; track child) {\n @if(child.children?.length) {\n <ngx-decaf-component-renderer [parent]=\"child\"> </ngx-decaf-component-renderer>\n } @else {\n <ngx-decaf-component-renderer\n [tag]=\"child?.tag\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]=\"{props: child.props}\" />\n }\n }\n }\n</ng-template>\n\n\n" }]
|
|
2391
2401
|
}], ctorParameters: () => [], propDecorators: { vcr: [{
|
|
@@ -2660,20 +2670,6 @@ var en = {
|
|
|
2660
2670
|
component: component
|
|
2661
2671
|
};
|
|
2662
2672
|
|
|
2663
|
-
class I18nLoader {
|
|
2664
|
-
static loadFromHttp(http) {
|
|
2665
|
-
function getSuffix() {
|
|
2666
|
-
const today = new Date();
|
|
2667
|
-
return `.json?version=${today.getFullYear()}${today.getMonth()}${today.getDay()}`;
|
|
2668
|
-
}
|
|
2669
|
-
return new (class extends TranslateHttpLoader {
|
|
2670
|
-
getTranslation(lang) {
|
|
2671
|
-
const res = super.getTranslation(lang);
|
|
2672
|
-
return res;
|
|
2673
|
-
}
|
|
2674
|
-
})(http, './assets/i18n/', getSuffix());
|
|
2675
|
-
}
|
|
2676
|
-
}
|
|
2677
2673
|
function getLocaleContext(clazz, suffix) {
|
|
2678
2674
|
return getLocaleFromClassName(clazz, suffix);
|
|
2679
2675
|
}
|
|
@@ -2700,22 +2696,21 @@ function getLocaleContextByKey(locale, phrase) {
|
|
|
2700
2696
|
return `${locale}.${cleanSpaces(parts.join('.'), true)}`;
|
|
2701
2697
|
}
|
|
2702
2698
|
function I18nLoaderFactory(http) {
|
|
2703
|
-
const { resources, versionedSuffix } = inject(I18N_CONFIG_TOKEN, { optional: true }) ??
|
|
2704
|
-
return new
|
|
2699
|
+
const { resources, versionedSuffix } = inject(I18N_CONFIG_TOKEN, { optional: true }) ?? provideI18nLoader().useValue;
|
|
2700
|
+
return new I18nLoader(http, resources?.length ? resources : [{ prefix: './app/assets/i18n/', suffix: '.json' }], versionedSuffix);
|
|
2705
2701
|
}
|
|
2706
|
-
function
|
|
2702
|
+
function provideI18nLoader(resources = [], versionedSuffix = false) {
|
|
2707
2703
|
if (!Array.isArray(resources))
|
|
2708
2704
|
resources = [resources];
|
|
2709
2705
|
return {
|
|
2710
2706
|
provide: I18N_CONFIG_TOKEN,
|
|
2711
2707
|
useValue: { resources: [
|
|
2712
|
-
// { prefix: './assets/i18n/', suffix: '.json' },
|
|
2713
2708
|
...resources
|
|
2714
2709
|
], versionedSuffix }
|
|
2715
2710
|
};
|
|
2716
2711
|
}
|
|
2717
2712
|
const libLanguage = { en };
|
|
2718
|
-
class
|
|
2713
|
+
class I18nLoader {
|
|
2719
2714
|
constructor(http, resources = [], versionedSuffix = false) {
|
|
2720
2715
|
this.http = http;
|
|
2721
2716
|
this.resources = resources;
|
|
@@ -3101,13 +3096,13 @@ let CrudFieldComponent = class CrudFieldComponent extends NgxCrudFormField {
|
|
|
3101
3096
|
});
|
|
3102
3097
|
component.dispatchEvent(event);
|
|
3103
3098
|
}
|
|
3104
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3105
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: CrudFieldComponent, isStandalone: true, selector: "ngx-decaf-crud-field", inputs: { operation: "operation", name: "name", 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", cols: "cols", rows: "rows", 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", activeFormGroup: "activeFormGroup", pk: "pk" }, host: { listeners: { "window:fieldsetAddGroupEvent": "handleFieldsetCreateGroupEvent($event)", "window:fieldsetUpdateGroupEvent": "handleFieldsetUpdateGroupEvent($event)", "window:fieldsetRemoveGroupEvent": "handleFieldsetRemoveGroupEvent($event)" }, properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef }], usesInheritance: true, ngImport: i0, template: "@if(operation === 'read' || operation === 'delete') {\n <ng-container #component>\n <div [class]=\"'dcf-input-item ' + operation\">\n <ion-item>\n <ion-label>\n {{ label | translate }}<br />\n @if(value) {\n <ion-text [innerHTML]=\"type === 'password' ? '********' : value\"></ion-text>\n } @else {\n <br />\n }\n </ion-label>\n </ion-item>\n </div>\n </ng-container>\n} @else {\n <ng-container [formGroup]=\"getActiveFormGroup\">\n <div #container [class]=\"'dcf-input-item ' + (operation || 'create')\" (createGroupEvent)=\"multiple ? handleFieldsetCreateGroupEvent($event) : ''\">\n @if(type === 'textarea') {\n <ion-textarea\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [autoGrow]=\"true\"\n [required]=\"required !== undefined ? required : null\"\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 <ion-item>\n <ion-checkbox\n #checkboxElement\n [mode]=\"mode\"\n [errorText]=\"getErrors(container)\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [value]=\"value\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\"\n #component>\n <span [innerHTML]=\"label | translate\"></span>\n </ion-checkbox>\n </ion-item>\n }\n @else if(type === 'radio') {\n <ion-radio-group [formControlName]=\"name\" [value]=\"value\" #component>\n <label class=\"dcf-radio-group-label\" [for]=\"path\">{{label | translate}}</label>\n @for(option of options; track option) {\n <ion-item>\n <ion-radio\n [errorText]=\"getErrors(container)\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [readonly]=\"readonly\"\n [value]=\"option.value\"\n >{{ translatable ? (option?.text | translate) : option?.text }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if(type === 'select') {\n <ion-select\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [label]=\"translatable ? (label | translate) : label\"\n [value]=\"value\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [interface]=\"interface\" #component>\n @for(option of options; track option.value) {\n <ion-select-option [value]=\"option.value\">\n {{ option.text | translate }}\n </ion-select-option>\n }\n </ion-select>\n }\n @else {\n <ion-input\n [type]=\"type\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [labelPlacement]=\"labelPlacement\"\n [required]=\"required !== undefined ? required : false\"\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}\n\n", styles: [".dcf-input-item.create,.dcf-input-item.update{margin-bottom:1.8rem;margin-top:0!important}.dcf-input-item.create.checkbox+.checkbox,.dcf-input-item.update.checkbox+.checkbox{margin-top:-.25rem!important}.dcf-input-item.create ion-item,.dcf-input-item.update ion-item{--border-color: transparent}.dcf-input-item.create ion-item.dcf-text-wrap ion-label>*,.dcf-input-item.update ion-item.dcf-text-wrap ion-label>*{white-space:wrap!important;word-break:break-all!important}.dcf-input-item.read ion-label,.dcf-input-item.delete ion-label{font-weight:600}@media (prefers-color-scheme: light){.dcf-input-item.read ion-label,.dcf-input-item.delete ion-label{color:var(--dcf-color-gray-7)}}.dcf-input-item.read ion-text,.dcf-input-item.delete ion-text{display:block;margin-top:.5rem!important}.dcf-input-item ion-item{--padding-end: 0rem;--padding-start: 0px !important;--padding-top: 0px !important;--background: transparent;--background-hover-opacity: .1;--background-activated-opacity: .15;--background-focused-opacity: .15}@media (prefers-color-scheme: dark){.dcf-input-item ion-item{--border-color: var(--dcf-color-gray-6)}}@media (prefers-color-scheme: light){.dcf-input-item ion-item{--background-hover: var(--dcf-color-primary);--background-focused: var(--dcf-color-primary);--border-color: var(--dcf-color-gray-2)}}.dcf-input-item ion-item span,.dcf-input-item ion-item ion-text{font-weight:400!important;font-size:.925rem;min-height:.5rem!important}.dcf-input-item ion-item span:not(.dcf-display-block),.dcf-input-item ion-item ion-text:not(.dcf-display-block){display:inline-block}.dcf-input-item ion-item span.dcf-display-block,.dcf-input-item ion-item ion-text.dcf-display-block{display:block!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{--size: 1.5rem;--checkbox-background-checked: var(--dcf-color-primary);--checkmark-width: 2px}ion-item{--inner-padding-start: .75rem}ion-checkbox::part(container){border-radius:50%;padding:3px}@media (prefers-color-scheme: light){ion-checkbox::part(container){border:2px solid var(--dcf-color-primary)}}ion-item .dcf-radio-group-label,ion-radio-group .dcf-radio-group-label{font-weight:600}ion-item .dcf-radio-group-label~ion-item,ion-radio-group .dcf-radio-group-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}ion-item+.dcf-helper,ion-radio-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-error{position:absolute;color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:600!important;line-height:1.1rem;box-sizing:border-box;z-index:9999;margin-top:0;animation-duration:.1s;animation-timing-function:ease-out;animation-fill-mode:both;animation-name:fadeTopSmallAnimation;display:flex;align-items:flex-start;gap:.25rem}.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;color:var(--dcf-color-gray-7)!important;text-decoration:underline}.dcf-error+.dcf-helper{padding-top:1rem}@keyframes fadeTopSmallAnimation{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeBottomSmallAnimation{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeTopMediumAnimation{0%{opacity:0;transform:translateY(-50px)}to{opacity:1;transform:translateY(0)}}::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.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { 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: "pipe", type: TranslatePipe, name: "translate" }, { 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"] }] }); }
|
|
3099
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: CrudFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
3100
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.2", type: CrudFieldComponent, isStandalone: true, selector: "ngx-decaf-crud-field", inputs: { operation: "operation", name: "name", 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", cols: "cols", rows: "rows", 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", activeFormGroup: "activeFormGroup", pk: "pk" }, host: { listeners: { "window:fieldsetAddGroupEvent": "handleFieldsetCreateGroupEvent($event)", "window:fieldsetUpdateGroupEvent": "handleFieldsetUpdateGroupEvent($event)", "window:fieldsetRemoveGroupEvent": "handleFieldsetRemoveGroupEvent($event)" }, properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef }], usesInheritance: true, ngImport: i0, template: "@if(operation === 'read' || operation === 'delete') {\n <ng-container #component>\n <div [class]=\"'dcf-input-item ' + operation\">\n <ion-item>\n <ion-label>\n {{ label | translate }}<br />\n @if(value) {\n <ion-text [innerHTML]=\"type === 'password' ? '********' : value\"></ion-text>\n } @else {\n <br />\n }\n </ion-label>\n </ion-item>\n </div>\n </ng-container>\n} @else {\n <ng-container [formGroup]=\"getActiveFormGroup\">\n <div #container [class]=\"'dcf-input-item ' + (operation || 'create')\" (createGroupEvent)=\"multiple ? handleFieldsetCreateGroupEvent($event) : ''\">\n @if(type === 'textarea') {\n <ion-textarea\n [id]=\"name\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [autoGrow]=\"true\"\n [required]=\"required !== undefined ? required : null\"\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 <ion-item>\n <ion-checkbox\n [id]=\"name\"\n [mode]=\"mode\"\n [errorText]=\"getErrors(container)\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [value]=\"value\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\"\n #component>\n <span [innerHTML]=\"label | translate\"></span>\n </ion-checkbox>\n </ion-item>\n }\n @else if(type === 'radio') {\n <ion-radio-group [formControlName]=\"name\" [value]=\"value\" #component>\n <label class=\"dcf-radio-group-label\" [for]=\"path\">{{label | translate}}</label>\n @for(option of options; track option) {\n <ion-item>\n <ion-radio\n [id]=\"name\"\n [errorText]=\"getErrors(container)\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [readonly]=\"readonly\"\n [value]=\"option.value\"\n >{{ translatable ? (option?.text | translate) : option?.text }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if(type === 'select') {\n <ion-select\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [label]=\"translatable ? (label | translate) : label\"\n [value]=\"value\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [interface]=\"interface\" #component>\n @for(option of options; track option.value) {\n <ion-select-option [value]=\"option.value\">\n {{ option.text | translate }}\n </ion-select-option>\n }\n </ion-select>\n }\n @else {\n <ion-input\n [id]=\"name\"\n [type]=\"type\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [labelPlacement]=\"labelPlacement\"\n [required]=\"required !== undefined ? required : false\"\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}\n\n", styles: ["@media (prefers-color-scheme: light){.dcf-input-item.read ion-label,.dcf-input-item.delete ion-label{color:var(--dcf-color-gray-7)}.dcf-input-item ion-item{--background-hover: var(--dcf-color-primary);--background-focused: var(--dcf-color-primary);--border-color: var(--dcf-color-gray-2)}ion-checkbox::part(container){border:2px solid var(--dcf-color-primary)}}@media (prefers-color-scheme: dark){.dcf-input-item ion-item{--border-color: var(--dcf-color-gray-6)}}.dcf-input-item.create,.dcf-input-item.update{margin-bottom:1.8rem;margin-top:0!important}.dcf-input-item.create.checkbox+.checkbox,.dcf-input-item.update.checkbox+.checkbox{margin-top:-.25rem!important}.dcf-input-item.create ion-item,.dcf-input-item.update ion-item{--border-color: transparent}.dcf-input-item.create ion-item.dcf-text-wrap ion-label>*,.dcf-input-item.update ion-item.dcf-text-wrap ion-label>*{white-space:wrap!important;word-break:break-all!important}.dcf-input-item.read ion-label,.dcf-input-item.delete ion-label{font-weight:600}.dcf-input-item.read ion-text,.dcf-input-item.delete ion-text{display:block;margin-top:.5rem!important}.dcf-input-item ion-item{--padding-end: 0rem;--padding-start: 0px !important;--padding-top: 0px !important;--background: transparent;--background-hover-opacity: .1;--background-activated-opacity: .15;--background-focused-opacity: .15}.dcf-input-item ion-item span,.dcf-input-item ion-item ion-text{font-weight:400!important;font-size:.925rem;min-height:.5rem!important}.dcf-input-item ion-item span:not(.dcf-display-block),.dcf-input-item ion-item ion-text:not(.dcf-display-block){display:inline-block}.dcf-input-item ion-item span.dcf-display-block,.dcf-input-item ion-item ion-text.dcf-display-block{display:block!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{--size: 1.5rem;--checkbox-background-checked: var(--dcf-color-primary);--checkmark-width: 2px}ion-item{--inner-padding-start: .75rem}ion-checkbox::part(container){border-radius:50%;padding:3px}ion-item .dcf-radio-group-label,ion-radio-group .dcf-radio-group-label{font-weight:600}ion-item .dcf-radio-group-label~ion-item,ion-radio-group .dcf-radio-group-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}ion-item+.dcf-helper,ion-radio-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-error{position:absolute;color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:600!important;line-height:1.1rem;box-sizing:border-box;z-index:9999;margin-top:0;animation-duration:.1s;animation-timing-function:ease-out;animation-fill-mode:both;animation-name:fadeTopSmallAnimation;display:flex;align-items:flex-start;gap:.25rem}.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;color:var(--dcf-color-gray-7)!important;text-decoration:underline}.dcf-error+.dcf-helper{padding-top:1rem}@keyframes fadeTopSmallAnimation{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeBottomSmallAnimation{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeTopMediumAnimation{0%{opacity:0;transform:translateY(-50px)}to{opacity:1;transform:translateY(0)}}::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.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { 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" }] }); }
|
|
3106
3101
|
};
|
|
3107
3102
|
CrudFieldComponent = __decorate([
|
|
3108
3103
|
Dynamic()
|
|
3109
3104
|
], CrudFieldComponent);
|
|
3110
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3105
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: CrudFieldComponent, decorators: [{
|
|
3111
3106
|
type: Component,
|
|
3112
3107
|
args: [{ standalone: true, imports: [
|
|
3113
3108
|
ReactiveFormsModule,
|
|
@@ -3121,9 +3116,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
3121
3116
|
IonSelectOption,
|
|
3122
3117
|
IonLabel,
|
|
3123
3118
|
IonText,
|
|
3124
|
-
IonTextarea
|
|
3125
|
-
|
|
3126
|
-
], selector: 'ngx-decaf-crud-field', schemas: [CUSTOM_ELEMENTS_SCHEMA], host: { '[attr.id]': 'uid' }, template: "@if(operation === 'read' || operation === 'delete') {\n <ng-container #component>\n <div [class]=\"'dcf-input-item ' + operation\">\n <ion-item>\n <ion-label>\n {{ label | translate }}<br />\n @if(value) {\n <ion-text [innerHTML]=\"type === 'password' ? '********' : value\"></ion-text>\n } @else {\n <br />\n }\n </ion-label>\n </ion-item>\n </div>\n </ng-container>\n} @else {\n <ng-container [formGroup]=\"getActiveFormGroup\">\n <div #container [class]=\"'dcf-input-item ' + (operation || 'create')\" (createGroupEvent)=\"multiple ? handleFieldsetCreateGroupEvent($event) : ''\">\n @if(type === 'textarea') {\n <ion-textarea\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [autoGrow]=\"true\"\n [required]=\"required !== undefined ? required : null\"\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 <ion-item>\n <ion-checkbox\n #checkboxElement\n [mode]=\"mode\"\n [errorText]=\"getErrors(container)\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [value]=\"value\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\"\n #component>\n <span [innerHTML]=\"label | translate\"></span>\n </ion-checkbox>\n </ion-item>\n }\n @else if(type === 'radio') {\n <ion-radio-group [formControlName]=\"name\" [value]=\"value\" #component>\n <label class=\"dcf-radio-group-label\" [for]=\"path\">{{label | translate}}</label>\n @for(option of options; track option) {\n <ion-item>\n <ion-radio\n [errorText]=\"getErrors(container)\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [readonly]=\"readonly\"\n [value]=\"option.value\"\n >{{ translatable ? (option?.text | translate) : option?.text }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if(type === 'select') {\n <ion-select\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [label]=\"translatable ? (label | translate) : label\"\n [value]=\"value\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [interface]=\"interface\" #component>\n @for(option of options; track option.value) {\n <ion-select-option [value]=\"option.value\">\n {{ option.text | translate }}\n </ion-select-option>\n }\n </ion-select>\n }\n @else {\n <ion-input\n [type]=\"type\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [labelPlacement]=\"labelPlacement\"\n [required]=\"required !== undefined ? required : false\"\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}\n\n", styles: [".dcf-input-item.create,.dcf-input-item.update{margin-bottom:1.8rem;margin-top:0!important}.dcf-input-item.create.checkbox+.checkbox,.dcf-input-item.update.checkbox+.checkbox{margin-top:-.25rem!important}.dcf-input-item.create ion-item,.dcf-input-item.update ion-item{--border-color: transparent}.dcf-input-item.create ion-item.dcf-text-wrap ion-label>*,.dcf-input-item.update ion-item.dcf-text-wrap ion-label>*{white-space:wrap!important;word-break:break-all!important}.dcf-input-item.read ion-label,.dcf-input-item.delete ion-label{font-weight:600}@media (prefers-color-scheme: light){.dcf-input-item.read ion-label,.dcf-input-item.delete ion-label{color:var(--dcf-color-gray-7)}}.dcf-input-item.read ion-text,.dcf-input-item.delete ion-text{display:block;margin-top:.5rem!important}.dcf-input-item ion-item{--padding-end: 0rem;--padding-start: 0px !important;--padding-top: 0px !important;--background: transparent;--background-hover-opacity: .1;--background-activated-opacity: .15;--background-focused-opacity: .15}@media (prefers-color-scheme: dark){.dcf-input-item ion-item{--border-color: var(--dcf-color-gray-6)}}@media (prefers-color-scheme: light){.dcf-input-item ion-item{--background-hover: var(--dcf-color-primary);--background-focused: var(--dcf-color-primary);--border-color: var(--dcf-color-gray-2)}}.dcf-input-item ion-item span,.dcf-input-item ion-item ion-text{font-weight:400!important;font-size:.925rem;min-height:.5rem!important}.dcf-input-item ion-item span:not(.dcf-display-block),.dcf-input-item ion-item ion-text:not(.dcf-display-block){display:inline-block}.dcf-input-item ion-item span.dcf-display-block,.dcf-input-item ion-item ion-text.dcf-display-block{display:block!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{--size: 1.5rem;--checkbox-background-checked: var(--dcf-color-primary);--checkmark-width: 2px}ion-item{--inner-padding-start: .75rem}ion-checkbox::part(container){border-radius:50%;padding:3px}@media (prefers-color-scheme: light){ion-checkbox::part(container){border:2px solid var(--dcf-color-primary)}}ion-item .dcf-radio-group-label,ion-radio-group .dcf-radio-group-label{font-weight:600}ion-item .dcf-radio-group-label~ion-item,ion-radio-group .dcf-radio-group-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}ion-item+.dcf-helper,ion-radio-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-error{position:absolute;color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:600!important;line-height:1.1rem;box-sizing:border-box;z-index:9999;margin-top:0;animation-duration:.1s;animation-timing-function:ease-out;animation-fill-mode:both;animation-name:fadeTopSmallAnimation;display:flex;align-items:flex-start;gap:.25rem}.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;color:var(--dcf-color-gray-7)!important;text-decoration:underline}.dcf-error+.dcf-helper{padding-top:1rem}@keyframes fadeTopSmallAnimation{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeBottomSmallAnimation{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeTopMediumAnimation{0%{opacity:0;transform:translateY(-50px)}to{opacity:1;transform:translateY(0)}}::ng-deep ion-textarea{min-height:80px!important;scrollbar-color:#888 #f0f0f0;scrollbar-width:thin}\n"] }]
|
|
3119
|
+
IonTextarea
|
|
3120
|
+
], selector: 'ngx-decaf-crud-field', schemas: [CUSTOM_ELEMENTS_SCHEMA], host: { '[attr.id]': 'uid' }, template: "@if(operation === 'read' || operation === 'delete') {\n <ng-container #component>\n <div [class]=\"'dcf-input-item ' + operation\">\n <ion-item>\n <ion-label>\n {{ label | translate }}<br />\n @if(value) {\n <ion-text [innerHTML]=\"type === 'password' ? '********' : value\"></ion-text>\n } @else {\n <br />\n }\n </ion-label>\n </ion-item>\n </div>\n </ng-container>\n} @else {\n <ng-container [formGroup]=\"getActiveFormGroup\">\n <div #container [class]=\"'dcf-input-item ' + (operation || 'create')\" (createGroupEvent)=\"multiple ? handleFieldsetCreateGroupEvent($event) : ''\">\n @if(type === 'textarea') {\n <ion-textarea\n [id]=\"name\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [autoGrow]=\"true\"\n [required]=\"required !== undefined ? required : null\"\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 <ion-item>\n <ion-checkbox\n [id]=\"name\"\n [mode]=\"mode\"\n [errorText]=\"getErrors(container)\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [value]=\"value\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\"\n #component>\n <span [innerHTML]=\"label | translate\"></span>\n </ion-checkbox>\n </ion-item>\n }\n @else if(type === 'radio') {\n <ion-radio-group [formControlName]=\"name\" [value]=\"value\" #component>\n <label class=\"dcf-radio-group-label\" [for]=\"path\">{{label | translate}}</label>\n @for(option of options; track option) {\n <ion-item>\n <ion-radio\n [id]=\"name\"\n [errorText]=\"getErrors(container)\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [readonly]=\"readonly\"\n [value]=\"option.value\"\n >{{ translatable ? (option?.text | translate) : option?.text }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if(type === 'select') {\n <ion-select\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [label]=\"translatable ? (label | translate) : label\"\n [value]=\"value\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [interface]=\"interface\" #component>\n @for(option of options; track option.value) {\n <ion-select-option [value]=\"option.value\">\n {{ option.text | translate }}\n </ion-select-option>\n }\n </ion-select>\n }\n @else {\n <ion-input\n [id]=\"name\"\n [type]=\"type\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [labelPlacement]=\"labelPlacement\"\n [required]=\"required !== undefined ? required : false\"\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}\n\n", styles: ["@media (prefers-color-scheme: light){.dcf-input-item.read ion-label,.dcf-input-item.delete ion-label{color:var(--dcf-color-gray-7)}.dcf-input-item ion-item{--background-hover: var(--dcf-color-primary);--background-focused: var(--dcf-color-primary);--border-color: var(--dcf-color-gray-2)}ion-checkbox::part(container){border:2px solid var(--dcf-color-primary)}}@media (prefers-color-scheme: dark){.dcf-input-item ion-item{--border-color: var(--dcf-color-gray-6)}}.dcf-input-item.create,.dcf-input-item.update{margin-bottom:1.8rem;margin-top:0!important}.dcf-input-item.create.checkbox+.checkbox,.dcf-input-item.update.checkbox+.checkbox{margin-top:-.25rem!important}.dcf-input-item.create ion-item,.dcf-input-item.update ion-item{--border-color: transparent}.dcf-input-item.create ion-item.dcf-text-wrap ion-label>*,.dcf-input-item.update ion-item.dcf-text-wrap ion-label>*{white-space:wrap!important;word-break:break-all!important}.dcf-input-item.read ion-label,.dcf-input-item.delete ion-label{font-weight:600}.dcf-input-item.read ion-text,.dcf-input-item.delete ion-text{display:block;margin-top:.5rem!important}.dcf-input-item ion-item{--padding-end: 0rem;--padding-start: 0px !important;--padding-top: 0px !important;--background: transparent;--background-hover-opacity: .1;--background-activated-opacity: .15;--background-focused-opacity: .15}.dcf-input-item ion-item span,.dcf-input-item ion-item ion-text{font-weight:400!important;font-size:.925rem;min-height:.5rem!important}.dcf-input-item ion-item span:not(.dcf-display-block),.dcf-input-item ion-item ion-text:not(.dcf-display-block){display:inline-block}.dcf-input-item ion-item span.dcf-display-block,.dcf-input-item ion-item ion-text.dcf-display-block{display:block!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{--size: 1.5rem;--checkbox-background-checked: var(--dcf-color-primary);--checkmark-width: 2px}ion-item{--inner-padding-start: .75rem}ion-checkbox::part(container){border-radius:50%;padding:3px}ion-item .dcf-radio-group-label,ion-radio-group .dcf-radio-group-label{font-weight:600}ion-item .dcf-radio-group-label~ion-item,ion-radio-group .dcf-radio-group-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}ion-item+.dcf-helper,ion-radio-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-error{position:absolute;color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:600!important;line-height:1.1rem;box-sizing:border-box;z-index:9999;margin-top:0;animation-duration:.1s;animation-timing-function:ease-out;animation-fill-mode:both;animation-name:fadeTopSmallAnimation;display:flex;align-items:flex-start;gap:.25rem}.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;color:var(--dcf-color-gray-7)!important;text-decoration:underline}.dcf-error+.dcf-helper{padding-top:1rem}@keyframes fadeTopSmallAnimation{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeBottomSmallAnimation{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeTopMediumAnimation{0%{opacity:0;transform:translateY(-50px)}to{opacity:1;transform:translateY(0)}}::ng-deep ion-textarea{min-height:80px!important;scrollbar-color:#888 #f0f0f0;scrollbar-width:thin}\n"] }]
|
|
3127
3121
|
}], propDecorators: { operation: [{
|
|
3128
3122
|
type: Input,
|
|
3129
3123
|
args: [{ required: true }]
|
|
@@ -3743,10 +3737,10 @@ class NgxBaseComponent {
|
|
|
3743
3737
|
if (!this.initialized)
|
|
3744
3738
|
this.initialized = true;
|
|
3745
3739
|
}
|
|
3746
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3747
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
3740
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxBaseComponent, deps: [{ token: 'instanceToken' }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3741
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.2", type: NgxBaseComponent, isStandalone: true, selector: "ng-component", inputs: { rendererId: "rendererId", model: "model", props: "props", item: "item", pk: "pk", route: "route", operations: "operations", uid: "uid", mapper: "mapper", locale: "locale", translatable: "translatable", className: "className", mode: "mode", renderChild: "renderChild" }, outputs: { listenEvent: "listenEvent" }, host: { properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef, static: true }], usesOnChanges: true, ngImport: i0, template: '<div></div>', isInline: true }); }
|
|
3748
3742
|
}
|
|
3749
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3743
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxBaseComponent, decorators: [{
|
|
3750
3744
|
type: Component,
|
|
3751
3745
|
args: [{
|
|
3752
3746
|
standalone: true,
|
|
@@ -4015,13 +4009,13 @@ let CrudFormComponent = class CrudFormComponent {
|
|
|
4015
4009
|
name: EventConstants.SUBMIT,
|
|
4016
4010
|
});
|
|
4017
4011
|
}
|
|
4018
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
4019
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
4012
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: CrudFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4013
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.2", type: CrudFormComponent, isStandalone: true, selector: "ngx-decaf-crud-form", inputs: { model: "model", modelId: "modelId", updateOn: "updateOn", target: "target", method: "method", options: "options", action: "action", operation: "operation", handlers: "handlers", formGroup: "formGroup", childOf: "childOf", rendererId: "rendererId", uid: "uid", allowClear: "allowClear" }, outputs: { submitEvent: "submitEvent" }, host: { properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "component", first: true, predicate: ["reactiveForm"], descendants: true, read: ElementRef }], ngImport: i0, template: "@if(operation !== 'read' && operation !== 'delete') {\n <form #reactiveForm [id]=\"rendererId\" [formGroup]=\"formGroup\" (submit)=\"submit($event)\" novalidate [target]=\"target\">\n <ng-content #formContent></ng-content>\n <div class=\"dcf-buttons-container dcf-grid dcf-grid-collapse 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 </form>\n} @else {\n <div [class]=\"'dcf-buttons-container dcf-grid dcf-grid-collapse dcf-flex dcf-flex-left ' + operation\" [id]=\"uid\">\n @if(operation === OperationKeys.READ && 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 </div>\n}\n\n", styles: [".dcf-buttons-container{margin-top:1.8rem;margin-bottom:0}@media (min-width: 768px){.dcf-buttons-container.dcf-flex{flex-direction:row-reverse}}@media (max-width: 767px){.dcf-buttons-container.dcf-flex div{width:100%}.dcf-buttons-container.dcf-flex ion-button{width:100%;margin-bottom:1rem}}form{padding:2rem 1rem}\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: 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"] }] }); }
|
|
4020
4014
|
};
|
|
4021
4015
|
CrudFormComponent = __decorate([
|
|
4022
4016
|
Dynamic()
|
|
4023
4017
|
], CrudFormComponent);
|
|
4024
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
4018
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: CrudFormComponent, decorators: [{
|
|
4025
4019
|
type: Component,
|
|
4026
4020
|
args: [{ standalone: true, selector: 'ngx-decaf-crud-form', imports: [ReactiveFormsModule, IonButton, IonIcon], host: { '[attr.id]': 'uid' }, template: "@if(operation !== 'read' && operation !== 'delete') {\n <form #reactiveForm [id]=\"rendererId\" [formGroup]=\"formGroup\" (submit)=\"submit($event)\" novalidate [target]=\"target\">\n <ng-content #formContent></ng-content>\n <div class=\"dcf-buttons-container dcf-grid dcf-grid-collapse 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 </form>\n} @else {\n <div [class]=\"'dcf-buttons-container dcf-grid dcf-grid-collapse dcf-flex dcf-flex-left ' + operation\" [id]=\"uid\">\n @if(operation === OperationKeys.READ && 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 </div>\n}\n\n", styles: [".dcf-buttons-container{margin-top:1.8rem;margin-bottom:0}@media (min-width: 768px){.dcf-buttons-container.dcf-flex{flex-direction:row-reverse}}@media (max-width: 767px){.dcf-buttons-container.dcf-flex div{width:100%}.dcf-buttons-container.dcf-flex ion-button{width:100%;margin-bottom:1rem}}form{padding:2rem 1rem}\n"] }]
|
|
4027
4021
|
}], propDecorators: { model: [{
|
|
@@ -4347,17 +4341,16 @@ let EmptyStateComponent = class EmptyStateComponent extends NgxBaseComponent {
|
|
|
4347
4341
|
const result = await this.translate.instant(content, { 'value0': this.searchValue });
|
|
4348
4342
|
return this.sanitizer.bypassSecurityTrustHtml(result);
|
|
4349
4343
|
}
|
|
4350
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
4351
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
4344
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: EmptyStateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4345
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.2", 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: "\n<ion-card [id]=\"uid\" [class]=\"className\">\n <ion-card-content>\n @if(icon && showIcon) {\n <div class=\"dcf-icon-container\">\n <ion-icon\n name=\"alert-circle-outline\"\n size=\"large\"\n color=\"danger\"\n />\n </div>\n }\n @if(title) {\n <h5 [class]=\"titleColor\" [innerHTML]=\"title\"></h5>\n }\n @if(subtitle) {\n @if(!searchValue) {\n <p [class]=\"subtitleColor\" [innerHTML]=\"subtitle\"></p>\n } @else {\n <p [class]=\"subtitleColor\" [innerHTML]=\"searchSubtitle\"></p>\n }\n }\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 </ion-card-content>\n</ion-card>\n", styles: ["ion-card{text-align:center}ion-card ion-button{margin-top:.75rem}ion-card ion-icon{font-size:2.5rem}ion-card .dcf-icon-container{transform:scale(1.25);opacity:.75;margin-top:1.25rem!important;margin-bottom:.5rem!important}ion-card .dcf-ititle{font-weight:600!important;color:var(--dcf-color-gray-6)!important}ion-card .dcf-isubtitle{font-weight:500!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: IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }] }); }
|
|
4352
4346
|
};
|
|
4353
4347
|
EmptyStateComponent = __decorate([
|
|
4354
4348
|
Dynamic(),
|
|
4355
4349
|
__metadata("design:paramtypes", [])
|
|
4356
4350
|
], EmptyStateComponent);
|
|
4357
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
4351
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: EmptyStateComponent, decorators: [{
|
|
4358
4352
|
type: Component,
|
|
4359
4353
|
args: [{ selector: 'ngx-decaf-empty-state', standalone: true, imports: [
|
|
4360
|
-
TranslatePipe,
|
|
4361
4354
|
IonCard,
|
|
4362
4355
|
IonCardContent,
|
|
4363
4356
|
IonIcon
|
|
@@ -5001,14 +4994,14 @@ let FieldsetComponent = class FieldsetComponent extends NgxBaseComponent {
|
|
|
5001
4994
|
}
|
|
5002
4995
|
return this.mapper;
|
|
5003
4996
|
}
|
|
5004
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
5005
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: FieldsetComponent, isStandalone: true, selector: "ngx-decaf-fieldset", inputs: { name: "name", childOf: "childOf", page: "page", uid: "uid", customTypes: "customTypes", operation: "operation", formGroup: "formGroup", title: "title", description: "description", target: "target", multiple: "multiple", value: "value", handlers: "handlers" }, host: { properties: { "attr.id": "overriode " } }, viewQueries: [{ propertyName: "accordionComponent", first: true, predicate: ["accordionComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "\n\n<fieldset\n (fieldsetAddGroupEvent)=\"handleCreateItem($event)\"\n (fieldsetRemoveGroupEvent)=\"handleRemoveItem(undefined, $event)\"\n [class]=\"'dcf-fieldset ' + operation\"\n #component>\n <ion-accordion-group [class.open]=\"isOpen\" [class.hasValidationErrors]=\"hasValidationErrors\" (validationErrorEvent)=\"handleValidationError($event)\" #accordionComponent>\n <ion-accordion value=\"open\">\n <ion-item slot=\"header\" (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>{{ name | translate }}</legend>\n </div>\n @if(!isRequired && ['create', 'update'].includes(operation)) {\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 <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(item.title, $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(item.title)\">\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 <ng-content select=\"[slot=content]\"></ng-content>\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 <div class=\"dcf-margin-bottom dcf-grid dcf-grid-collapse dcf-flex\">\n @if(updatingItem) {\n <ion-button size=\"small\" fill=\"clear\" color=\"danger\" (click)=\"handleCancelUpdateItem()\">\n {{ buttonCancelLabel }}\n </ion-button>\n }\n <ion-button size=\"small\" fill=\"clear\" class=\"dcf-button-add\" (click)=\"handleCreateItem()\">\n <ion-icon name=\"add-outline\" slot=\"start\"></ion-icon>\n {{buttonLabel}}\n </ion-button>\n\n </div>\n }\n\n </div>\n </ion-accordion>\n </ion-accordion-group>\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}::ng-deep ion-accordion ngx-decaf-crud-field:last-child ion-item{--inner-border-width: 0px !important;--border-width: 0px !important}.dcf-fieldset{margin-bottom:1.8rem;margin-top:1rem;padding-bottom:0;padding-top:1rem;background:var(--dcf-card-background);border-radius:6px;height:100%}@media (prefers-color-scheme: light){.dcf-fieldset{border:1px solid var(--dcf-color-gray-3)}.dcf-fieldset .dcf-button-add{color:var(--ion-color-dark)!important}}@media (prefers-color-scheme: dark){.dcf-fieldset{border:1px solid var(--dcf-color-step-400)}.dcf-fieldset .dcf-button-add{color:var(--ion-color-gray-2)}}.dcf-fieldset.read,.dcf-fieldset.delete{margin-top:1.25rem;padding-bottom:1rem}.dcf-fieldset.read [slot=content],.dcf-fieldset.delete [slot=content]{padding-top:0!important}.dcf-fieldset.read ion-accordion,.dcf-fieldset.delete ion-accordion{margin-bottom:0rem!important}@media (prefers-color-scheme: dark){.dcf-fieldset.read,.dcf-fieldset.delete{border:1px solid var(--dcf-color-gray-6)}}.dcf-fieldset ion-accordion{background:var(--dcf-card-background);margin-bottom:1rem}.dcf-fieldset ion-accordion.accordion-collapsing,.dcf-fieldset ion-accordion.accordion-collapsed{margin-bottom:1rem}.dcf-fieldset ion-accordion ion-item[slot=header]{--border-color: transparent;--border-radius: 6px;--inner-border-width: 0;--padding-start: 12px}.dcf-fieldset ion-accordion ion-item[slot=header] legend{font-weight:600;font-size:1rem;margin:0}@media (prefers-color-scheme: light){.dcf-fieldset ion-accordion ion-item[slot=header] legend{color:var(--dcf-color-gray-7)}}.dcf-fieldset ion-accordion [slot=content]{padding-top:2rem!important;padding-inline:.75rem}.dcf-not-unique-container{display:flex;justify-content:center;align-items:center;margin-bottom:1rem;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{margin-top:-1rem;margin-bottom:1rem;padding:0!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;border:1px solid transparent;box-sizing:border-box}.dcf-fields-list ion-item ion-icon.dcf-reorder-disabled{width:1rem;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:.8rem;color:var(--dcf-color-gray-7)}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }, { 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"] }] }); }
|
|
4997
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: FieldsetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4998
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.2", type: FieldsetComponent, isStandalone: true, selector: "ngx-decaf-fieldset", inputs: { name: "name", childOf: "childOf", page: "page", uid: "uid", customTypes: "customTypes", operation: "operation", formGroup: "formGroup", title: "title", description: "description", target: "target", multiple: "multiple", value: "value", handlers: "handlers" }, host: { properties: { "attr.id": "overriode " } }, viewQueries: [{ propertyName: "accordionComponent", first: true, predicate: ["accordionComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "\n\n<fieldset\n (fieldsetAddGroupEvent)=\"handleCreateItem($event)\"\n (fieldsetRemoveGroupEvent)=\"handleRemoveItem(undefined, $event)\"\n [class]=\"'dcf-fieldset ' + operation\"\n #component>\n <ion-accordion-group [class.open]=\"isOpen\" [class.hasValidationErrors]=\"hasValidationErrors\" (validationErrorEvent)=\"handleValidationError($event)\" #accordionComponent>\n <ion-accordion value=\"open\">\n <ion-item slot=\"header\" (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>{{ name | translate }}</legend>\n </div>\n @if(!isRequired && ['create', 'update'].includes(operation)) {\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 <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(item.title, $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(item.title)\">\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 <ng-content select=\"[slot=content]\"></ng-content>\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 <div class=\"dcf-margin-bottom dcf-grid dcf-grid-collapse dcf-flex\">\n @if(updatingItem) {\n <ion-button size=\"small\" fill=\"clear\" color=\"danger\" (click)=\"handleCancelUpdateItem()\">\n {{ buttonCancelLabel }}\n </ion-button>\n }\n <ion-button size=\"small\" fill=\"clear\" class=\"dcf-button-add\" (click)=\"handleCreateItem()\">\n <ion-icon name=\"add-outline\" slot=\"start\"></ion-icon>\n {{buttonLabel}}\n </ion-button>\n\n </div>\n }\n\n </div>\n </ion-accordion>\n </ion-accordion-group>\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}::ng-deep ion-accordion ngx-decaf-crud-field:last-child ion-item{--inner-border-width: 0px !important;--border-width: 0px !important}@media (prefers-color-scheme: light){.dcf-fieldset{border:1px solid var(--dcf-color-gray-3)}.dcf-fieldset .dcf-button-add{color:var(--ion-color-dark)!important}ion-accordion ion-item[slot=header] legend{color:var(--dcf-color-gray-7)}}@media (prefers-color-scheme: dark){.dcf-fieldset{border:1px solid var(--dcf-color-step-400)}.dcf-fieldset .dcf-button-add{color:var(--ion-color-gray-2)}.dcf-fieldset.read,.dcf-fieldset.delete{border:1px solid var(--dcf-color-gray-6)}}.dcf-fieldset{margin-bottom:1.8rem;margin-top:1rem;padding-bottom:0;padding-top:1rem;background:var(--dcf-card-background);border-radius:6px;height:100%}.dcf-fieldset.read,.dcf-fieldset.delete{margin-top:1.25rem;padding-bottom:1rem}.dcf-fieldset.read [slot=content],.dcf-fieldset.delete [slot=content]{padding-top:0!important}.dcf-fieldset.read ion-accordion,.dcf-fieldset.delete ion-accordion{margin-bottom:0rem!important}.dcf-fieldset ion-accordion{background:var(--dcf-card-background);margin-bottom:1rem}.dcf-fieldset ion-accordion.accordion-collapsing,.dcf-fieldset ion-accordion.accordion-collapsed{margin-bottom:1rem}.dcf-fieldset ion-accordion ion-item[slot=header]{--border-color: transparent;--border-radius: 6px;--inner-border-width: 0;--padding-start: 12px}.dcf-fieldset ion-accordion ion-item[slot=header] legend{font-weight:600;font-size:1rem;margin:0}.dcf-fieldset ion-accordion [slot=content]{padding-top:2rem!important;padding-inline:.75rem}.dcf-not-unique-container{display:flex;justify-content:center;align-items:center;margin-bottom:1rem;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{margin-top:-1rem;margin-bottom:1rem;padding:0!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;border:1px solid transparent;box-sizing:border-box}.dcf-fields-list ion-item ion-icon.dcf-reorder-disabled{width:1rem;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:.8rem;color:var(--dcf-color-gray-7)}\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: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
5006
4999
|
};
|
|
5007
5000
|
FieldsetComponent = __decorate([
|
|
5008
5001
|
Dynamic(),
|
|
5009
5002
|
__metadata("design:paramtypes", [])
|
|
5010
5003
|
], FieldsetComponent);
|
|
5011
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
5004
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: FieldsetComponent, decorators: [{
|
|
5012
5005
|
type: Component,
|
|
5013
5006
|
args: [{ standalone: true, selector: 'ngx-decaf-fieldset', schemas: [], imports: [
|
|
5014
5007
|
TranslatePipe,
|
|
@@ -5023,7 +5016,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
5023
5016
|
IonReorderGroup,
|
|
5024
5017
|
IonButton,
|
|
5025
5018
|
IonIcon,
|
|
5026
|
-
], host: { '[attr.id]': 'overriode ' }, template: "\n\n<fieldset\n (fieldsetAddGroupEvent)=\"handleCreateItem($event)\"\n (fieldsetRemoveGroupEvent)=\"handleRemoveItem(undefined, $event)\"\n [class]=\"'dcf-fieldset ' + operation\"\n #component>\n <ion-accordion-group [class.open]=\"isOpen\" [class.hasValidationErrors]=\"hasValidationErrors\" (validationErrorEvent)=\"handleValidationError($event)\" #accordionComponent>\n <ion-accordion value=\"open\">\n <ion-item slot=\"header\" (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>{{ name | translate }}</legend>\n </div>\n @if(!isRequired && ['create', 'update'].includes(operation)) {\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 <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(item.title, $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(item.title)\">\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 <ng-content select=\"[slot=content]\"></ng-content>\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 <div class=\"dcf-margin-bottom dcf-grid dcf-grid-collapse dcf-flex\">\n @if(updatingItem) {\n <ion-button size=\"small\" fill=\"clear\" color=\"danger\" (click)=\"handleCancelUpdateItem()\">\n {{ buttonCancelLabel }}\n </ion-button>\n }\n <ion-button size=\"small\" fill=\"clear\" class=\"dcf-button-add\" (click)=\"handleCreateItem()\">\n <ion-icon name=\"add-outline\" slot=\"start\"></ion-icon>\n {{buttonLabel}}\n </ion-button>\n\n </div>\n }\n\n </div>\n </ion-accordion>\n </ion-accordion-group>\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}::ng-deep ion-accordion ngx-decaf-crud-field:last-child ion-item{--inner-border-width: 0px !important;--border-width: 0px !important}
|
|
5019
|
+
], host: { '[attr.id]': 'overriode ' }, template: "\n\n<fieldset\n (fieldsetAddGroupEvent)=\"handleCreateItem($event)\"\n (fieldsetRemoveGroupEvent)=\"handleRemoveItem(undefined, $event)\"\n [class]=\"'dcf-fieldset ' + operation\"\n #component>\n <ion-accordion-group [class.open]=\"isOpen\" [class.hasValidationErrors]=\"hasValidationErrors\" (validationErrorEvent)=\"handleValidationError($event)\" #accordionComponent>\n <ion-accordion value=\"open\">\n <ion-item slot=\"header\" (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>{{ name | translate }}</legend>\n </div>\n @if(!isRequired && ['create', 'update'].includes(operation)) {\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 <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(item.title, $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(item.title)\">\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 <ng-content select=\"[slot=content]\"></ng-content>\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 <div class=\"dcf-margin-bottom dcf-grid dcf-grid-collapse dcf-flex\">\n @if(updatingItem) {\n <ion-button size=\"small\" fill=\"clear\" color=\"danger\" (click)=\"handleCancelUpdateItem()\">\n {{ buttonCancelLabel }}\n </ion-button>\n }\n <ion-button size=\"small\" fill=\"clear\" class=\"dcf-button-add\" (click)=\"handleCreateItem()\">\n <ion-icon name=\"add-outline\" slot=\"start\"></ion-icon>\n {{buttonLabel}}\n </ion-button>\n\n </div>\n }\n\n </div>\n </ion-accordion>\n </ion-accordion-group>\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}::ng-deep ion-accordion ngx-decaf-crud-field:last-child ion-item{--inner-border-width: 0px !important;--border-width: 0px !important}@media (prefers-color-scheme: light){.dcf-fieldset{border:1px solid var(--dcf-color-gray-3)}.dcf-fieldset .dcf-button-add{color:var(--ion-color-dark)!important}ion-accordion ion-item[slot=header] legend{color:var(--dcf-color-gray-7)}}@media (prefers-color-scheme: dark){.dcf-fieldset{border:1px solid var(--dcf-color-step-400)}.dcf-fieldset .dcf-button-add{color:var(--ion-color-gray-2)}.dcf-fieldset.read,.dcf-fieldset.delete{border:1px solid var(--dcf-color-gray-6)}}.dcf-fieldset{margin-bottom:1.8rem;margin-top:1rem;padding-bottom:0;padding-top:1rem;background:var(--dcf-card-background);border-radius:6px;height:100%}.dcf-fieldset.read,.dcf-fieldset.delete{margin-top:1.25rem;padding-bottom:1rem}.dcf-fieldset.read [slot=content],.dcf-fieldset.delete [slot=content]{padding-top:0!important}.dcf-fieldset.read ion-accordion,.dcf-fieldset.delete ion-accordion{margin-bottom:0rem!important}.dcf-fieldset ion-accordion{background:var(--dcf-card-background);margin-bottom:1rem}.dcf-fieldset ion-accordion.accordion-collapsing,.dcf-fieldset ion-accordion.accordion-collapsed{margin-bottom:1rem}.dcf-fieldset ion-accordion ion-item[slot=header]{--border-color: transparent;--border-radius: 6px;--inner-border-width: 0;--padding-start: 12px}.dcf-fieldset ion-accordion ion-item[slot=header] legend{font-weight:600;font-size:1rem;margin:0}.dcf-fieldset ion-accordion [slot=content]{padding-top:2rem!important;padding-inline:.75rem}.dcf-not-unique-container{display:flex;justify-content:center;align-items:center;margin-bottom:1rem;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{margin-top:-1rem;margin-bottom:1rem;padding:0!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;border:1px solid transparent;box-sizing:border-box}.dcf-fields-list ion-item ion-icon.dcf-reorder-disabled{width:1rem;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:.8rem;color:var(--dcf-color-gray-7)}\n"] }]
|
|
5027
5020
|
}], ctorParameters: () => [], propDecorators: { accordionComponent: [{
|
|
5028
5021
|
type: ViewChild,
|
|
5029
5022
|
args: ['accordionComponent', { static: false }]
|
|
@@ -5481,10 +5474,10 @@ class SearchbarComponent extends NgxBaseComponent {
|
|
|
5481
5474
|
preventChange(event) {
|
|
5482
5475
|
event.preventDefault();
|
|
5483
5476
|
}
|
|
5484
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
5485
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
5477
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: SearchbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5478
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.2", type: SearchbarComponent, isStandalone: true, selector: "ngx-decaf-searchbar", inputs: { autocomplete: "autocomplete", autocorrect: "autocorrect", animated: "animated", buttonCancelText: "buttonCancelText", clearIcon: "clearIcon", color: "color", debounce: "debounce", disabled: "disabled", enterkeyhint: "enterkeyhint", inputmode: "inputmode", placeholder: "placeholder", searchIcon: "searchIcon", showCancelButton: "showCancelButton", showClearButton: "showClearButton", spellcheck: "spellcheck", type: "type", value: "value", queryKeys: "queryKeys", isVisible: "isVisible", wrapper: "wrapper", wrapperColor: "wrapperColor", emitEventToWindow: "emitEventToWindow" }, outputs: { searchEvent: "searchEvent" }, host: { listeners: { "window:toggleSearchbarVisibility": "handleToggleVisibility($event)" } }, usesInheritance: true, ngImport: i0, template: "<ion-searchbar\n [id]=\"uid\"\n ngClass=\"dcf-searchbar\"\n name=\"search\"\n mode=\"ios\"\n (keyup.enter)=\"preventChange($event)\"\n (ionChange)=\"handleChange($event)\"\n (ionInput)=\"handleInput($event)\"\n (ionClear)=\"handleClear()\"\n [autocomplete]=\"autocomplete\"\n [showCancelButton]=\"showCancelButton\"\n [cancelButtonText]=\"buttonCancelText\"\n [clearIcon]=\"clearIcon\"\n [color]=\"color\"\n [debounce]=\"debounce\"\n [disabled]=\"disabled\"\n [enterkeyhint]=\"enterkeyhint\"\n [inputmode]=\"inputmode\"\n [placeholder]=\"placeholder\"\n [searchIcon]=\"searchIcon\"\n [showClearButton]=\"showClearButton\"\n [spellcheck]=\"spellcheck\"\n [type]=\"type\"\n #component\n />\n", styles: [""], dependencies: [{ kind: "component", type: IonSearchbar, selector: "ion-searchbar", inputs: ["animated", "autocomplete", "autocorrect", "cancelButtonIcon", "cancelButtonText", "clearIcon", "color", "debounce", "disabled", "enterkeyhint", "inputmode", "mode", "name", "placeholder", "searchIcon", "showCancelButton", "showClearButton", "spellcheck", "type", "value"] }] }); }
|
|
5486
5479
|
}
|
|
5487
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
5480
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: SearchbarComponent, decorators: [{
|
|
5488
5481
|
type: Component,
|
|
5489
5482
|
args: [{ selector: 'ngx-decaf-searchbar', standalone: true, imports: [IonSearchbar], template: "<ion-searchbar\n [id]=\"uid\"\n ngClass=\"dcf-searchbar\"\n name=\"search\"\n mode=\"ios\"\n (keyup.enter)=\"preventChange($event)\"\n (ionChange)=\"handleChange($event)\"\n (ionInput)=\"handleInput($event)\"\n (ionClear)=\"handleClear()\"\n [autocomplete]=\"autocomplete\"\n [showCancelButton]=\"showCancelButton\"\n [cancelButtonText]=\"buttonCancelText\"\n [clearIcon]=\"clearIcon\"\n [color]=\"color\"\n [debounce]=\"debounce\"\n [disabled]=\"disabled\"\n [enterkeyhint]=\"enterkeyhint\"\n [inputmode]=\"inputmode\"\n [placeholder]=\"placeholder\"\n [searchIcon]=\"searchIcon\"\n [showClearButton]=\"showClearButton\"\n [spellcheck]=\"spellcheck\"\n [type]=\"type\"\n #component\n />\n" }]
|
|
5490
5483
|
}], ctorParameters: () => [], propDecorators: { autocomplete: [{
|
|
@@ -6183,20 +6176,18 @@ let FilterComponent = class FilterComponent extends NgxBaseComponent {
|
|
|
6183
6176
|
handleSearch(value) {
|
|
6184
6177
|
this.searchEvent.emit(value);
|
|
6185
6178
|
}
|
|
6186
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
6187
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: FilterComponent, isStandalone: true, selector: "ngx-decaf-filter", inputs: { indexes: "indexes", conditions: "conditions", sortBy: "sortBy", disableSort: "disableSort" }, outputs: { filterEvent: "filterEvent", searchEvent: "searchEvent" }, 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-grid\" [class.dcf-hidden]=\"!indexes.length\">\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\" (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\n placeholder=\"{{ locale + (step === 3 ? '.type' : '.select') | translate }}\"\n #component\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' : 'medium'\" 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' : 'medium'\" 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' : 'medium'\" [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-grid{padding:0 .5rem;margin-top:.75rem;margin-bottom:.75rem}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}@media (prefers-color-scheme: light){.dcf-filter{border:1px solid var(--dcf-color-gray-3);background-color:#fff}.dcf-filter:focus-within{border-color:var(--dcf-color-primary);background-color:#fff}}@media (prefers-color-scheme: dark){.dcf-filter{border:1px solid var(--dcf-color-step-500)}.dcf-filter ::-webkit-input-placeholder,.dcf-filter ::placeholder{color:var(--dcf-color-gray-4)!important}.dcf-filter:hover{border-color:var(--dcf-color-gray-2)}.dcf-filter:focus-within{border-color:var(--dcf-color-gray-2)}}.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}@media (prefers-color-scheme: light){.dcf-filter ion-chip{border:1px solid var(--dcf-color-gray-3);color:var(--dcf-color-gray-7)}.dcf-filter 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}}@media (prefers-color-scheme: dark){.dcf-filter ion-chip{border-color:var(--dcf-color-step-300);background:rgba(var(--dcf-color-medium-rgb),.1)}.dcf-filter ion-chip.dcf-filter-value{background:rgba(var(--dcf-color-medium-rgb),.3)!important;border-color:var(--dcf-color-step-500)}}.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}@media (prefers-color-scheme: light){.dcf-filter .dcf-input input{color:var(--dcf-color-gray-7)}}@media (prefers-color-scheme: dark){.dcf-filter .dcf-input input{color:var(--dcf-color-gray-1)}}.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}@media (prefers-color-scheme: light){.dcf-dropdown{background-color:#fff}.dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-gray-2)}}@media (prefers-color-scheme: dark){.dcf-dropdown{background-color:var(--dcf-item-background)}.dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-step-600)}}.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}@media (prefers-color-scheme: light){.dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-8)}.dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-3)}.dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{pointer-events:none;touch-action:none;cursor:text!important;border-color:transparent!important}.dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-1)}}@media (prefers-color-scheme: dark){.dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-1)}.dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-5)}.dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{cursor:text!important;pointer-events:none;touch-action:none;border-color:transparent!important}.dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-8)}}\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: "pipe", type: TranslatePipe, name: "translate" }, { 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"] }] }); }
|
|
6179
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: FilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6180
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.2", type: FilterComponent, isStandalone: true, selector: "ngx-decaf-filter", inputs: { indexes: "indexes", conditions: "conditions", sortBy: "sortBy", disableSort: "disableSort" }, outputs: { filterEvent: "filterEvent", searchEvent: "searchEvent" }, 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-grid\" [class.dcf-hidden]=\"!indexes.length\">\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\" (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\n placeholder=\"{{ locale + (step === 3 ? '.type' : '.select') | translate }}\"\n #component\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' : 'medium'\" 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' : 'medium'\" 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' : 'medium'\" [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: ["@media (prefers-color-scheme: light){.dcf-filter{border:1px solid var(--dcf-color-gray-3);background-color:#fff}.dcf-filter:focus-within{border-color:var(--dcf-color-primary);background-color:#fff}ion-chip{border:1px solid var(--dcf-color-gray-3);color:var(--dcf-color-gray-7)}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-input input{color:var(--dcf-color-gray-7)}.dcf-dropdown{background-color:#fff}.dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-gray-2)}.dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-8)}.dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-3)}.dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{pointer-events:none;touch-action:none;cursor:text!important;border-color:transparent!important}.dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-1)}}@media (prefers-color-scheme: dark){.dcf-filter{border:1px solid var(--dcf-color-step-500)}.dcf-filter ::-webkit-input-placeholder,.dcf-filter ::placeholder{color:var(--dcf-color-gray-4)!important}.dcf-filter:hover{border-color:var(--dcf-color-gray-2)}.dcf-filter:focus-within{border-color:var(--dcf-color-gray-2)}ion-chip{border-color:var(--dcf-color-step-300);background:rgba(var(--dcf-color-medium-rgb),.1)}ion-chip.dcf-filter-value{background:rgba(var(--dcf-color-medium-rgb),.3)!important;border-color:var(--dcf-color-step-500)}.dcf-input input{color:var(--dcf-color-gray-1)}.dcf-dropdown{background-color:var(--dcf-item-background)}.dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-step-600)}.dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-1)}.dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-5)}.dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{cursor:text!important;pointer-events:none;touch-action:none;border-color:transparent!important}.dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-8)}}.dcf-filter-grid{padding:0 .5rem;margin-top:.75rem;margin-bottom:.75rem}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" }] }); }
|
|
6188
6181
|
};
|
|
6189
6182
|
FilterComponent = __decorate([
|
|
6190
6183
|
Dynamic(),
|
|
6191
6184
|
__metadata("design:paramtypes", [])
|
|
6192
6185
|
], FilterComponent);
|
|
6193
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
6186
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: FilterComponent, decorators: [{
|
|
6194
6187
|
type: Component,
|
|
6195
6188
|
args: [{ selector: 'ngx-decaf-filter', imports: [
|
|
6196
6189
|
FormsModule,
|
|
6197
6190
|
TranslatePipe,
|
|
6198
|
-
IonLabel,
|
|
6199
|
-
IonItem,
|
|
6200
6191
|
IonChip,
|
|
6201
6192
|
IonIcon,
|
|
6202
6193
|
IonButton,
|
|
@@ -6204,7 +6195,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
6204
6195
|
IonSelectOption,
|
|
6205
6196
|
IonIcon,
|
|
6206
6197
|
SearchbarComponent
|
|
6207
|
-
], standalone: true, 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-grid\" [class.dcf-hidden]=\"!indexes.length\">\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\" (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\n placeholder=\"{{ locale + (step === 3 ? '.type' : '.select') | translate }}\"\n #component\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' : 'medium'\" 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' : 'medium'\" 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' : 'medium'\" [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-grid{padding:0 .5rem;margin-top:.75rem;margin-bottom:.75rem}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}@media (prefers-color-scheme: light){.dcf-filter{border:1px solid var(--dcf-color-gray-3);background-color:#fff}.dcf-filter:focus-within{border-color:var(--dcf-color-primary);background-color:#fff}}@media (prefers-color-scheme: dark){.dcf-filter{border:1px solid var(--dcf-color-step-500)}.dcf-filter ::-webkit-input-placeholder,.dcf-filter ::placeholder{color:var(--dcf-color-gray-4)!important}.dcf-filter:hover{border-color:var(--dcf-color-gray-2)}.dcf-filter:focus-within{border-color:var(--dcf-color-gray-2)}}.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}@media (prefers-color-scheme: light){.dcf-filter ion-chip{border:1px solid var(--dcf-color-gray-3);color:var(--dcf-color-gray-7)}.dcf-filter 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}}@media (prefers-color-scheme: dark){.dcf-filter ion-chip{border-color:var(--dcf-color-step-300);background:rgba(var(--dcf-color-medium-rgb),.1)}.dcf-filter ion-chip.dcf-filter-value{background:rgba(var(--dcf-color-medium-rgb),.3)!important;border-color:var(--dcf-color-step-500)}}.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}@media (prefers-color-scheme: light){.dcf-filter .dcf-input input{color:var(--dcf-color-gray-7)}}@media (prefers-color-scheme: dark){.dcf-filter .dcf-input input{color:var(--dcf-color-gray-1)}}.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}@media (prefers-color-scheme: light){.dcf-dropdown{background-color:#fff}.dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-gray-2)}}@media (prefers-color-scheme: dark){.dcf-dropdown{background-color:var(--dcf-item-background)}.dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-step-600)}}.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}@media (prefers-color-scheme: light){.dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-8)}.dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-3)}.dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{pointer-events:none;touch-action:none;cursor:text!important;border-color:transparent!important}.dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-1)}}@media (prefers-color-scheme: dark){.dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-1)}.dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-5)}.dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{cursor:text!important;pointer-events:none;touch-action:none;border-color:transparent!important}.dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-8)}}\n"] }]
|
|
6198
|
+
], standalone: true, 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-grid\" [class.dcf-hidden]=\"!indexes.length\">\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\" (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\n placeholder=\"{{ locale + (step === 3 ? '.type' : '.select') | translate }}\"\n #component\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' : 'medium'\" 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' : 'medium'\" 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' : 'medium'\" [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: ["@media (prefers-color-scheme: light){.dcf-filter{border:1px solid var(--dcf-color-gray-3);background-color:#fff}.dcf-filter:focus-within{border-color:var(--dcf-color-primary);background-color:#fff}ion-chip{border:1px solid var(--dcf-color-gray-3);color:var(--dcf-color-gray-7)}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-input input{color:var(--dcf-color-gray-7)}.dcf-dropdown{background-color:#fff}.dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-gray-2)}.dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-8)}.dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-3)}.dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{pointer-events:none;touch-action:none;cursor:text!important;border-color:transparent!important}.dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-1)}}@media (prefers-color-scheme: dark){.dcf-filter{border:1px solid var(--dcf-color-step-500)}.dcf-filter ::-webkit-input-placeholder,.dcf-filter ::placeholder{color:var(--dcf-color-gray-4)!important}.dcf-filter:hover{border-color:var(--dcf-color-gray-2)}.dcf-filter:focus-within{border-color:var(--dcf-color-gray-2)}ion-chip{border-color:var(--dcf-color-step-300);background:rgba(var(--dcf-color-medium-rgb),.1)}ion-chip.dcf-filter-value{background:rgba(var(--dcf-color-medium-rgb),.3)!important;border-color:var(--dcf-color-step-500)}.dcf-input input{color:var(--dcf-color-gray-1)}.dcf-dropdown{background-color:var(--dcf-item-background)}.dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-step-600)}.dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-1)}.dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-5)}.dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{cursor:text!important;pointer-events:none;touch-action:none;border-color:transparent!important}.dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-8)}}.dcf-filter-grid{padding:0 .5rem;margin-top:.75rem;margin-bottom:.75rem}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"] }]
|
|
6208
6199
|
}], ctorParameters: () => [], propDecorators: { optionsFilterElement: [{
|
|
6209
6200
|
type: ViewChild,
|
|
6210
6201
|
args: ['optionsFilterElement', { read: ElementRef, static: false }]
|
|
@@ -6335,10 +6326,10 @@ class ModelRendererComponent {
|
|
|
6335
6326
|
}
|
|
6336
6327
|
}
|
|
6337
6328
|
}
|
|
6338
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
6339
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
6329
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: ModelRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6330
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.2", type: ModelRendererComponent, isStandalone: true, selector: "ngx-decaf-model-renderer", inputs: { model: "model", globals: "globals", projectable: "projectable", rendererId: "rendererId" }, outputs: { listenEvent: "listenEvent" }, host: { properties: { "attr.id": "rendererId" } }, viewQueries: [{ propertyName: "inner", first: true, predicate: ["inner"], descendants: true, read: TemplateRef, static: true }, { propertyName: "vcr", first: true, predicate: ["componentOuter"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: " <!-- Keep to avoid id conflicts -->\n <div [id]=\"rendererId\"></div>\n\n <ng-template #componentOuter></ng-template>\n <ng-template #inner>\n <div [id]=\"rendererId || null\">\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: [""], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "globals", "children", "model", "parent"], outputs: ["listenEvent"] }] }); }
|
|
6340
6331
|
}
|
|
6341
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
6332
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: ModelRendererComponent, decorators: [{
|
|
6342
6333
|
type: Component,
|
|
6343
6334
|
args: [{ standalone: true, imports: [NgComponentOutlet, ComponentRendererComponent], selector: 'ngx-decaf-model-renderer', host: { '[attr.id]': 'rendererId' }, template: " <!-- Keep to avoid id conflicts -->\n <div [id]=\"rendererId\"></div>\n\n <ng-template #componentOuter></ng-template>\n <ng-template #inner>\n <div [id]=\"rendererId || null\">\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" }]
|
|
6344
6335
|
}], propDecorators: { model: [{
|
|
@@ -6488,10 +6479,10 @@ class LayoutComponent extends NgxBaseComponent {
|
|
|
6488
6479
|
this.rows = this._rows;
|
|
6489
6480
|
this.initialized = true;
|
|
6490
6481
|
}
|
|
6491
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
6492
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
6482
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: LayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6483
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.2", type: LayoutComponent, isStandalone: true, selector: "ngx-decaf-layout", inputs: { cols: "cols", rows: "rows", breakpoint: "breakpoint", children: "children" }, usesInheritance: true, ngImport: i0, template: "\n@if(initialized) {\n @for (row of rows; track trackItemFn($index, row); let rowIndex = $index) {\n <div [id]=\"uid\" class=\"dcf-grid dcf-grid-collapse dcf-grid-match\">\n @if(row) {\n <div class=\"dcf-width-1-1 dcf-grid-title\">\n <ion-card class=\"dcf-grid-title\">\n {{row.title | translate}}\n </ion-card>\n </div>\n }\n @for (child of row.cols; track trackItemFn($index, child.col); let colIndex = $index) {\n <div [class]=\"(child.col === cols.length ? 'dcf-width-1-1' : 'dcf-width-'+child.col+'-'+cols.length+'@'+breakpoint)\">\n <div [class]=\"'dcf-grid-child '+child.col \">\n @if(child.tag === 'ngx-decaf-crud-form') {\n <ion-card [class]=\"'dcf-height-1-1 ' + className\">\n <ion-card-content>\n <ngx-decaf-model-renderer\n [model]=\"child.props.name\"\n (listenEvent)=\"handleEvent($event)\"\n />\n </ion-card-content>\n </ion-card>\n } @else {\n <ngx-decaf-component-renderer\n [tag]=\"child.tag\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]=\"{props: child.props}\"\n />\n }\n </div>\n </div>\n }\n </div>\n }\n}\n", styles: [".dcf-grid>div:not(.dcf-grid-title) ::ng-deep ngx-decaf-component-renderer>*>*{height:100%;display:flex;justify-content:center!important;align-items:center!important}.dcf-grid ion-card.dcf-height-1-1>ion-card-content{margin-top:2rem}.dcf-grid.dcf-grid-small .dcf-grid-child{margin-bottom:2rem}.dcf-grid.dcf-grid-collapse .dcf-grid-child{margin-bottom:1.25rem}.dcf-grid.dcf-grid-collapse .dcf-grid-child ion-card{margin-bottom:1.25rem}.dcf-grid-title{font-size:1.05rem!important;background:none;box-shadow:none;margin-bottom:0;padding-bottom:0;font-weight:600;color:var(--dcf-color-dark);display:flex;align-items:center;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}\n"], dependencies: [{ kind: "component", type: ModelRendererComponent, selector: "ngx-decaf-model-renderer", inputs: ["model", "globals", "projectable", "rendererId"], outputs: ["listenEvent"] }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "globals", "children", "model", "parent"], outputs: ["listenEvent"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
6493
6484
|
}
|
|
6494
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
6485
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: LayoutComponent, decorators: [{
|
|
6495
6486
|
type: Component,
|
|
6496
6487
|
args: [{ selector: 'ngx-decaf-layout', imports: [TranslatePipe, ModelRendererComponent, ComponentRendererComponent], standalone: true, template: "\n@if(initialized) {\n @for (row of rows; track trackItemFn($index, row); let rowIndex = $index) {\n <div [id]=\"uid\" class=\"dcf-grid dcf-grid-collapse dcf-grid-match\">\n @if(row) {\n <div class=\"dcf-width-1-1 dcf-grid-title\">\n <ion-card class=\"dcf-grid-title\">\n {{row.title | translate}}\n </ion-card>\n </div>\n }\n @for (child of row.cols; track trackItemFn($index, child.col); let colIndex = $index) {\n <div [class]=\"(child.col === cols.length ? 'dcf-width-1-1' : 'dcf-width-'+child.col+'-'+cols.length+'@'+breakpoint)\">\n <div [class]=\"'dcf-grid-child '+child.col \">\n @if(child.tag === 'ngx-decaf-crud-form') {\n <ion-card [class]=\"'dcf-height-1-1 ' + className\">\n <ion-card-content>\n <ngx-decaf-model-renderer\n [model]=\"child.props.name\"\n (listenEvent)=\"handleEvent($event)\"\n />\n </ion-card-content>\n </ion-card>\n } @else {\n <ngx-decaf-component-renderer\n [tag]=\"child.tag\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]=\"{props: child.props}\"\n />\n }\n </div>\n </div>\n }\n </div>\n }\n}\n", styles: [".dcf-grid>div:not(.dcf-grid-title) ::ng-deep ngx-decaf-component-renderer>*>*{height:100%;display:flex;justify-content:center!important;align-items:center!important}.dcf-grid ion-card.dcf-height-1-1>ion-card-content{margin-top:2rem}.dcf-grid.dcf-grid-small .dcf-grid-child{margin-bottom:2rem}.dcf-grid.dcf-grid-collapse .dcf-grid-child{margin-bottom:1.25rem}.dcf-grid.dcf-grid-collapse .dcf-grid-child ion-card{margin-bottom:1.25rem}.dcf-grid-title{font-size:1.05rem!important;background:none;box-shadow:none;margin-bottom:0;padding-bottom:0;font-weight:600;color:var(--dcf-color-dark);display:flex;align-items:center;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}\n"] }]
|
|
6497
6488
|
}], ctorParameters: () => [], propDecorators: { cols: [{
|
|
@@ -6505,857 +6496,466 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
6505
6496
|
}] } });
|
|
6506
6497
|
|
|
6507
6498
|
/**
|
|
6508
|
-
* @description A component for
|
|
6509
|
-
* @summary
|
|
6510
|
-
*
|
|
6511
|
-
*
|
|
6512
|
-
* @extends NgxBaseComponent
|
|
6513
|
-
*
|
|
6514
|
-
* @param {string} [lines='none'] - Determines the line style of the item. Can be 'inset', 'inseet', or 'none'.
|
|
6515
|
-
* @param {Record<string, any>} item - The data item to be displayed in the list item.
|
|
6516
|
-
* @param {string} icon - The name of the icon to be displayed.
|
|
6517
|
-
* @param {'start' | 'end'} [iconSlot='start'] - The position of the icon within the item.
|
|
6518
|
-
* @param {StringOrBoolean} [button=true] - Determines if the item should behave as a button.
|
|
6519
|
-
* @param {string} [title] - The main title of the list item.
|
|
6520
|
-
* @param {string} [description] - A description for the list item.
|
|
6521
|
-
* @param {string} [info] - Additional information for the list item.
|
|
6522
|
-
* @param {string} [subinfo] - Sub-information for the list item.
|
|
6499
|
+
* @description A pagination component for navigating through multiple pages of content.
|
|
6500
|
+
* @summary This component provides a user interface for paginated content navigation,
|
|
6501
|
+
* displaying page numbers and navigation controls. It supports customizable page counts,
|
|
6502
|
+
* current page tracking, and emits events when users navigate between pages.
|
|
6523
6503
|
*
|
|
6524
|
-
*
|
|
6525
|
-
*
|
|
6526
|
-
*
|
|
6527
|
-
* icon="star"
|
|
6528
|
-
* title="Item Title"
|
|
6529
|
-
* description="Item Description"
|
|
6530
|
-
* (clickEvent)="handleItemClick($event)">
|
|
6531
|
-
* </ngx-decaf-list-item>
|
|
6504
|
+
* The component intelligently handles large numbers of pages by showing a subset of page
|
|
6505
|
+
* numbers with ellipses to indicate skipped pages, ensuring the UI remains clean and usable
|
|
6506
|
+
* even with many pages.
|
|
6532
6507
|
*
|
|
6533
6508
|
* @mermaid
|
|
6534
6509
|
* sequenceDiagram
|
|
6535
|
-
* participant C as Component
|
|
6536
|
-
* participant V as View
|
|
6537
6510
|
* participant U as User
|
|
6538
|
-
*
|
|
6539
|
-
*
|
|
6540
|
-
*
|
|
6541
|
-
*
|
|
6542
|
-
*
|
|
6543
|
-
*
|
|
6511
|
+
* participant P as PaginationComponent
|
|
6512
|
+
* participant E as External Component
|
|
6513
|
+
*
|
|
6514
|
+
* U->>P: Click page number
|
|
6515
|
+
* P->>P: navigate(page)
|
|
6516
|
+
* P->>P: handleClick(direction, page)
|
|
6517
|
+
* P->>E: Emit clickEvent with PaginationCustomEvent
|
|
6518
|
+
*
|
|
6519
|
+
* U->>P: Click next button
|
|
6520
|
+
* P->>P: next()
|
|
6521
|
+
* P->>P: handleClick('next')
|
|
6522
|
+
* P->>E: Emit clickEvent with PaginationCustomEvent
|
|
6523
|
+
*
|
|
6524
|
+
* U->>P: Click previous button
|
|
6525
|
+
* P->>P: previous()
|
|
6526
|
+
* P->>P: handleClick('previous')
|
|
6527
|
+
* P->>E: Emit clickEvent with PaginationCustomEvent
|
|
6528
|
+
*
|
|
6529
|
+
* @example
|
|
6530
|
+
* <ngx-decaf-pagination
|
|
6531
|
+
* [pages]="10"
|
|
6532
|
+
* [current]="3"
|
|
6533
|
+
* (clickEvent)="handlePageChange($event)">
|
|
6534
|
+
* </ngx-decaf-pagination>
|
|
6535
|
+
*
|
|
6536
|
+
* @extends {NgxBaseComponent}
|
|
6537
|
+
* @implements {OnInit}
|
|
6544
6538
|
*/
|
|
6545
|
-
|
|
6539
|
+
class PaginationComponent extends NgxBaseComponent {
|
|
6546
6540
|
/**
|
|
6547
|
-
* @
|
|
6548
|
-
* @
|
|
6549
|
-
* with the component name for
|
|
6550
|
-
* all available Ionic icons to ensure they can be displayed in the component.
|
|
6551
|
-
*
|
|
6552
|
-
* @memberOf ListItemComponent
|
|
6541
|
+
* @constructor
|
|
6542
|
+
* @description Initializes a new instance of the PaginationComponent.
|
|
6543
|
+
* Calls the parent constructor with the component name for generate base locale string.
|
|
6553
6544
|
*/
|
|
6554
6545
|
constructor() {
|
|
6555
|
-
super("
|
|
6556
|
-
/**
|
|
6557
|
-
* @description Controls the display of lines around the list item.
|
|
6558
|
-
* @summary Determines how lines are displayed around the list item borders.
|
|
6559
|
-
* 'inset' shows lines with padding, 'full' shows full-width lines, and 'none'
|
|
6560
|
-
* removes all lines. This affects the visual separation between list items.
|
|
6561
|
-
*
|
|
6562
|
-
* @type {'inset' | 'full' | 'none'}
|
|
6563
|
-
* @default 'inset'
|
|
6564
|
-
* @memberOf ListItemComponent
|
|
6565
|
-
*/
|
|
6566
|
-
this.lines = 'full';
|
|
6567
|
-
/**
|
|
6568
|
-
* @description Position of the icon within the list item.
|
|
6569
|
-
* @summary Determines whether the icon appears at the start (left in LTR languages)
|
|
6570
|
-
* or end (right in LTR languages) of the list item. This affects the overall
|
|
6571
|
-
* layout and visual hierarchy of the item content.
|
|
6572
|
-
*
|
|
6573
|
-
* @type {'start' | 'end'}
|
|
6574
|
-
* @default 'start'
|
|
6575
|
-
* @memberOf ListItemComponent
|
|
6576
|
-
*/
|
|
6577
|
-
this.iconSlot = 'start';
|
|
6546
|
+
super("PaginationComponent");
|
|
6578
6547
|
/**
|
|
6579
|
-
* @description Controls whether the
|
|
6580
|
-
* @summary When set to true, the
|
|
6581
|
-
*
|
|
6582
|
-
* When false, the item is displayed as static content without interactive behavior.
|
|
6548
|
+
* @description Controls whether the component uses translation services.
|
|
6549
|
+
* @summary When set to true, the component will attempt to use translation services
|
|
6550
|
+
* for any text content. This allows for internationalization of the pagination component.
|
|
6583
6551
|
*
|
|
6584
6552
|
* @type {StringOrBoolean}
|
|
6585
6553
|
* @default true
|
|
6586
|
-
* @memberOf
|
|
6587
|
-
*/
|
|
6588
|
-
this.button = true;
|
|
6589
|
-
/**
|
|
6590
|
-
* @description Event emitter for list item click interactions.
|
|
6591
|
-
* @summary Emits custom events when the list item is clicked or when actions
|
|
6592
|
-
* are performed on it. The emitted event contains information about the action,
|
|
6593
|
-
* the item data, and other relevant context for parent components to handle.
|
|
6594
|
-
*
|
|
6595
|
-
* @type {EventEmitter<ListItemCustomEvent>}
|
|
6596
|
-
* @memberOf ListItemComponent
|
|
6597
|
-
*/
|
|
6598
|
-
this.clickEvent = new EventEmitter();
|
|
6599
|
-
/**
|
|
6600
|
-
* @description Flag indicating whether slide items are currently enabled.
|
|
6601
|
-
* @summary Controls the visibility of slide actions based on screen size and
|
|
6602
|
-
* available operations. When true, users can swipe on the item to reveal
|
|
6603
|
-
* action buttons for operations like edit and delete.
|
|
6604
|
-
*
|
|
6605
|
-
* @type {boolean}
|
|
6606
|
-
* @default false
|
|
6607
|
-
* @memberOf ListItemComponent
|
|
6554
|
+
* @memberOf PaginationComponent
|
|
6608
6555
|
*/
|
|
6609
|
-
this.
|
|
6556
|
+
this.translatable = true;
|
|
6610
6557
|
/**
|
|
6611
|
-
* @description
|
|
6612
|
-
* @summary
|
|
6613
|
-
*
|
|
6614
|
-
* are performed. Used for managing the popover lifecycle.
|
|
6558
|
+
* @description The currently active page number.
|
|
6559
|
+
* @summary Specifies which page is currently active or selected. This value is used
|
|
6560
|
+
* to highlight the current page in the UI and as a reference point for navigation.
|
|
6615
6561
|
*
|
|
6616
|
-
* @type {
|
|
6617
|
-
* @default
|
|
6618
|
-
* @memberOf
|
|
6562
|
+
* @type {number}
|
|
6563
|
+
* @default 1
|
|
6564
|
+
* @memberOf PaginationComponent
|
|
6619
6565
|
*/
|
|
6620
|
-
this.
|
|
6566
|
+
this.current = 1;
|
|
6621
6567
|
/**
|
|
6622
|
-
* @description
|
|
6623
|
-
* @summary
|
|
6624
|
-
*
|
|
6625
|
-
*
|
|
6568
|
+
* @description Event emitter for pagination navigation events.
|
|
6569
|
+
* @summary Emits a custom event when users navigate between pages, either by clicking
|
|
6570
|
+
* on page numbers or using the next/previous buttons. The event contains information
|
|
6571
|
+
* about the navigation direction and the target page number.
|
|
6626
6572
|
*
|
|
6627
|
-
* @
|
|
6628
|
-
* @
|
|
6629
|
-
* @memberOf ListItemComponent
|
|
6573
|
+
* @type {EventEmitter<PaginationCustomEvent>}
|
|
6574
|
+
* @memberOf PaginationComponent
|
|
6630
6575
|
*/
|
|
6631
|
-
this.
|
|
6632
|
-
addIcons(
|
|
6576
|
+
this.clickEvent = new EventEmitter();
|
|
6577
|
+
addIcons({ chevronBackOutline, chevronForwardOutline });
|
|
6633
6578
|
}
|
|
6634
6579
|
/**
|
|
6635
|
-
* @description Initializes the component after Angular
|
|
6636
|
-
* @summary Sets up the component by
|
|
6637
|
-
*
|
|
6638
|
-
*
|
|
6639
|
-
* properly initialized and responsive behavior is configured.
|
|
6580
|
+
* @description Initializes the component after Angular sets the input properties.
|
|
6581
|
+
* @summary Sets up the component by initializing the locale settings based on the
|
|
6582
|
+
* translatable property, generating the page numbers based on the total pages and
|
|
6583
|
+
* current page, and storing the last page number for boundary checking.
|
|
6640
6584
|
*
|
|
6641
6585
|
* @mermaid
|
|
6642
6586
|
* sequenceDiagram
|
|
6643
6587
|
* participant A as Angular Lifecycle
|
|
6644
|
-
* participant
|
|
6645
|
-
* participant W as Window
|
|
6588
|
+
* participant P as PaginationComponent
|
|
6646
6589
|
*
|
|
6647
|
-
* A->>
|
|
6648
|
-
*
|
|
6649
|
-
*
|
|
6650
|
-
*
|
|
6651
|
-
*
|
|
6652
|
-
*
|
|
6653
|
-
* end
|
|
6654
|
-
* L->>W: getWindowWidth()
|
|
6655
|
-
* W-->>L: Return current width
|
|
6656
|
-
* L->>L: Store windowWidth
|
|
6590
|
+
* A->>P: ngOnInit()
|
|
6591
|
+
* P->>P: getLocale(translatable)
|
|
6592
|
+
* P->>P: Set locale
|
|
6593
|
+
* P->>P: getPages(data, current)
|
|
6594
|
+
* P->>P: Set pages array
|
|
6595
|
+
* P->>P: Set last page number
|
|
6657
6596
|
*
|
|
6658
|
-
* @
|
|
6659
|
-
* @memberOf
|
|
6597
|
+
* @returns {void}
|
|
6598
|
+
* @memberOf PaginationComponent
|
|
6660
6599
|
*/
|
|
6661
|
-
|
|
6662
|
-
this.
|
|
6663
|
-
this.
|
|
6664
|
-
this.
|
|
6665
|
-
if (this.operations?.length)
|
|
6666
|
-
this.className += ` action`;
|
|
6667
|
-
this.windowWidth = getWindowWidth();
|
|
6600
|
+
ngOnInit() {
|
|
6601
|
+
this.locale = this.getLocale(this.translatable);
|
|
6602
|
+
this.pages = this.getPages(this.totalPages, this.current);
|
|
6603
|
+
this.last = this.totalPages;
|
|
6668
6604
|
}
|
|
6669
6605
|
/**
|
|
6670
|
-
* @description Handles
|
|
6671
|
-
* @summary
|
|
6672
|
-
*
|
|
6673
|
-
*
|
|
6674
|
-
* route configuration. This method supports both event-driven and navigation-driven architectures.
|
|
6606
|
+
* @description Handles click events on pagination controls.
|
|
6607
|
+
* @summary Processes user interactions with the pagination component, updating the
|
|
6608
|
+
* current page if specified and emitting an event with navigation details. This method
|
|
6609
|
+
* is called when users click on page numbers or navigation buttons.
|
|
6675
6610
|
*
|
|
6676
|
-
* @param {
|
|
6677
|
-
* @param {
|
|
6678
|
-
* @
|
|
6679
|
-
* @return {Promise<boolean|void>} A promise that resolves to navigation success or void for events
|
|
6611
|
+
* @param {('next' | 'previous')} direction - The direction of navigation
|
|
6612
|
+
* @param {number} [page] - Optional page number to navigate to directly
|
|
6613
|
+
* @returns {void}
|
|
6680
6614
|
*
|
|
6681
6615
|
* @mermaid
|
|
6682
6616
|
* sequenceDiagram
|
|
6683
6617
|
* participant U as User
|
|
6684
|
-
* participant
|
|
6685
|
-
* participant
|
|
6686
|
-
* participant N as NavController
|
|
6687
|
-
* participant E as Event System
|
|
6618
|
+
* participant P as PaginationComponent
|
|
6619
|
+
* participant E as External Component
|
|
6688
6620
|
*
|
|
6689
|
-
* U->>
|
|
6690
|
-
*
|
|
6691
|
-
* alt
|
|
6692
|
-
*
|
|
6693
|
-
* end
|
|
6694
|
-
* L->>L: removeFocusTrap()
|
|
6695
|
-
* alt No route configured
|
|
6696
|
-
* L->>E: windowEventEmitter()
|
|
6697
|
-
* L->>P: clickEvent.emit()
|
|
6698
|
-
* else Route configured
|
|
6699
|
-
* L->>N: redirect(action, uid)
|
|
6700
|
-
* N-->>L: Return navigation result
|
|
6621
|
+
* U->>P: Click pagination control
|
|
6622
|
+
* P->>P: handleClick(direction, page?)
|
|
6623
|
+
* alt page is provided
|
|
6624
|
+
* P->>P: Update current page
|
|
6701
6625
|
* end
|
|
6626
|
+
* P->>E: Emit clickEvent with direction and page
|
|
6702
6627
|
*
|
|
6703
|
-
* @memberOf
|
|
6628
|
+
* @memberOf PaginationComponent
|
|
6704
6629
|
*/
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
}
|
|
6716
|
-
return await this.redirect(action, (typeof this.uid === 'number' ? `${this.uid}` : this.uid));
|
|
6630
|
+
handleClick(direction, page) {
|
|
6631
|
+
if (page)
|
|
6632
|
+
this.current = page;
|
|
6633
|
+
this.clickEvent.emit({
|
|
6634
|
+
name: EventConstants.CLICK,
|
|
6635
|
+
data: {
|
|
6636
|
+
direction,
|
|
6637
|
+
page: this.current
|
|
6638
|
+
},
|
|
6639
|
+
component: this.componentName
|
|
6640
|
+
});
|
|
6717
6641
|
}
|
|
6718
6642
|
/**
|
|
6719
|
-
* @description
|
|
6720
|
-
* @summary
|
|
6721
|
-
*
|
|
6722
|
-
*
|
|
6723
|
-
*
|
|
6643
|
+
* @description Generates the array of page objects for display.
|
|
6644
|
+
* @summary Creates an array of page objects based on the total number of pages and
|
|
6645
|
+
* the current page. For small page counts (≤5), all pages are shown. For larger page
|
|
6646
|
+
* counts, a subset is shown with ellipses to indicate skipped pages. This ensures
|
|
6647
|
+
* the pagination UI remains clean and usable even with many pages.
|
|
6724
6648
|
*
|
|
6725
|
-
* @
|
|
6649
|
+
* @param {number} total - The total number of pages
|
|
6650
|
+
* @param {number} [current] - The current active page (defaults to this.current)
|
|
6651
|
+
* @returns {KeyValue[]} Array of page objects with index and text properties
|
|
6726
6652
|
*
|
|
6727
6653
|
* @mermaid
|
|
6728
|
-
*
|
|
6729
|
-
*
|
|
6730
|
-
*
|
|
6731
|
-
*
|
|
6654
|
+
* flowchart TD
|
|
6655
|
+
* A[Start] --> B{total <= 5?}
|
|
6656
|
+
* B -->|Yes| C[Show all pages]
|
|
6657
|
+
* B -->|No| D[Show first page]
|
|
6658
|
+
* D --> E[Show last pages]
|
|
6659
|
+
* E --> F[Add ellipses for skipped pages]
|
|
6660
|
+
* C --> G[Return pages array]
|
|
6661
|
+
* F --> G
|
|
6732
6662
|
*
|
|
6733
|
-
*
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6663
|
+
* @memberOf PaginationComponent
|
|
6664
|
+
*/
|
|
6665
|
+
getPages(total, current) {
|
|
6666
|
+
if (!current)
|
|
6667
|
+
current = this.current;
|
|
6668
|
+
const pages = [];
|
|
6669
|
+
function getPage(index, text = '', clazz = 'button') {
|
|
6670
|
+
if (pages.some(item => item['index'] === index))
|
|
6671
|
+
return;
|
|
6672
|
+
pages.push({ index, text: index != null ? index.toString().padStart(2, '0') : text, class: clazz });
|
|
6673
|
+
}
|
|
6674
|
+
if (total <= 5) {
|
|
6675
|
+
for (let i = 1; i <= total; i++)
|
|
6676
|
+
getPage(i);
|
|
6677
|
+
}
|
|
6678
|
+
else {
|
|
6679
|
+
// Adiciona os dois primeiros
|
|
6680
|
+
getPage(1);
|
|
6681
|
+
getPage(2);
|
|
6682
|
+
// Adiciona "..." entre os blocos
|
|
6683
|
+
if (current && current > 3)
|
|
6684
|
+
getPage(null, '...');
|
|
6685
|
+
// Adiciona a página atual (se estiver no meio)
|
|
6686
|
+
if (current && current > 2 && current < total - 1)
|
|
6687
|
+
getPage(current);
|
|
6688
|
+
// Adiciona "..." entre os blocos
|
|
6689
|
+
if (current && current < total - 2)
|
|
6690
|
+
getPage(null, '...', 'separator');
|
|
6691
|
+
// Adiciona os dois últimos
|
|
6692
|
+
getPage(total - 1);
|
|
6693
|
+
getPage(total);
|
|
6694
|
+
}
|
|
6695
|
+
return pages;
|
|
6696
|
+
}
|
|
6697
|
+
/**
|
|
6698
|
+
* @description Gets the current active page number.
|
|
6699
|
+
* @summary Returns the current page number that is active in the pagination component.
|
|
6700
|
+
* This method provides a way to access the current page state from outside the component.
|
|
6743
6701
|
*
|
|
6744
|
-
* @
|
|
6702
|
+
* @returns {number} The current page number
|
|
6703
|
+
* @memberOf PaginationComponent
|
|
6745
6704
|
*/
|
|
6746
|
-
|
|
6747
|
-
this.
|
|
6748
|
-
if (!this.operations?.length || this.windowWidth > 639)
|
|
6749
|
-
return this.showSlideItems = false;
|
|
6750
|
-
this.showSlideItems = this.operations.includes(OperationKeys.UPDATE) || this.operations.includes(OperationKeys.DELETE);
|
|
6751
|
-
return this.showSlideItems;
|
|
6705
|
+
getCurrent() {
|
|
6706
|
+
return this.current;
|
|
6752
6707
|
}
|
|
6753
6708
|
/**
|
|
6754
|
-
* @description
|
|
6755
|
-
* @summary
|
|
6756
|
-
*
|
|
6757
|
-
*
|
|
6758
|
-
* is coordinated with the CSS animation duration to ensure the element is removed
|
|
6759
|
-
* after the animation completes.
|
|
6709
|
+
* @description Navigates to the next page.
|
|
6710
|
+
* @summary Increments the current page number if not at the last page and triggers
|
|
6711
|
+
* the click event handler with 'next' direction. This method is typically called
|
|
6712
|
+
* when the user clicks on the "next" button in the pagination UI.
|
|
6760
6713
|
*
|
|
6761
|
-
* @
|
|
6762
|
-
* @return {void}
|
|
6714
|
+
* @returns {void}
|
|
6763
6715
|
*
|
|
6764
6716
|
* @mermaid
|
|
6765
6717
|
* sequenceDiagram
|
|
6766
|
-
* participant
|
|
6767
|
-
* participant
|
|
6768
|
-
* participant D as DOM
|
|
6718
|
+
* participant U as User
|
|
6719
|
+
* participant P as PaginationComponent
|
|
6769
6720
|
*
|
|
6770
|
-
*
|
|
6771
|
-
*
|
|
6772
|
-
*
|
|
6773
|
-
*
|
|
6774
|
-
*
|
|
6775
|
-
*
|
|
6776
|
-
* D->>D: Remove element from DOM
|
|
6721
|
+
* U->>P: Click next button
|
|
6722
|
+
* P->>P: next()
|
|
6723
|
+
* alt page <= max pages
|
|
6724
|
+
* P->>P: Increment current page
|
|
6725
|
+
* P->>P: handleClick('next')
|
|
6726
|
+
* end
|
|
6777
6727
|
*
|
|
6778
|
-
* @memberOf
|
|
6728
|
+
* @memberOf PaginationComponent
|
|
6779
6729
|
*/
|
|
6780
|
-
|
|
6781
|
-
|
|
6782
|
-
|
|
6730
|
+
next() {
|
|
6731
|
+
const page = this.current + 1;
|
|
6732
|
+
if (page <= Object.keys(this.pages)?.length || 0) {
|
|
6733
|
+
this.current = page;
|
|
6734
|
+
this.handleClick('next');
|
|
6735
|
+
}
|
|
6783
6736
|
}
|
|
6784
6737
|
/**
|
|
6785
|
-
* @description Navigates to
|
|
6786
|
-
* @summary
|
|
6787
|
-
* the
|
|
6788
|
-
*
|
|
6789
|
-
* CRUD operations where each action (create, read, update, delete) has its own route.
|
|
6738
|
+
* @description Navigates to the previous page.
|
|
6739
|
+
* @summary Decrements the current page number if not at the first page and triggers
|
|
6740
|
+
* the click event handler with 'previous' direction. This method is typically called
|
|
6741
|
+
* when the user clicks on the "previous" button in the pagination UI.
|
|
6790
6742
|
*
|
|
6791
|
-
* @
|
|
6792
|
-
* @param {string} [id] - The unique identifier of the item to be acted upon
|
|
6793
|
-
* @return {Promise<boolean>} A promise that resolves to true if navigation was successful
|
|
6743
|
+
* @returns {void}
|
|
6794
6744
|
*
|
|
6795
6745
|
* @mermaid
|
|
6796
6746
|
* sequenceDiagram
|
|
6797
|
-
* participant
|
|
6798
|
-
* participant
|
|
6799
|
-
* participant R as Router
|
|
6747
|
+
* participant U as User
|
|
6748
|
+
* participant P as PaginationComponent
|
|
6800
6749
|
*
|
|
6801
|
-
*
|
|
6802
|
-
*
|
|
6803
|
-
*
|
|
6804
|
-
*
|
|
6805
|
-
*
|
|
6806
|
-
*
|
|
6750
|
+
* U->>P: Click previous button
|
|
6751
|
+
* P->>P: previous()
|
|
6752
|
+
* alt page > 0
|
|
6753
|
+
* P->>P: Decrement current page
|
|
6754
|
+
* P->>P: handleClick('previous')
|
|
6755
|
+
* end
|
|
6807
6756
|
*
|
|
6808
|
-
* @memberOf
|
|
6757
|
+
* @memberOf PaginationComponent
|
|
6809
6758
|
*/
|
|
6810
|
-
|
|
6811
|
-
|
|
6759
|
+
previous() {
|
|
6760
|
+
const page = this.current - 1;
|
|
6761
|
+
if (page > 0) {
|
|
6762
|
+
this.current = page;
|
|
6763
|
+
this.handleClick('previous');
|
|
6764
|
+
}
|
|
6812
6765
|
}
|
|
6813
6766
|
/**
|
|
6814
|
-
* @description
|
|
6815
|
-
* @summary
|
|
6816
|
-
*
|
|
6817
|
-
*
|
|
6818
|
-
* popover with the triggering event, and opens the action menu. The menu typically contains
|
|
6819
|
-
* available CRUD operations for the item.
|
|
6767
|
+
* @description Navigates to a specific page number.
|
|
6768
|
+
* @summary Updates the current page to the specified page number and triggers
|
|
6769
|
+
* the click event handler with the appropriate direction. This method is typically
|
|
6770
|
+
* called when the user clicks directly on a page number in the pagination UI.
|
|
6820
6771
|
*
|
|
6821
|
-
* @param {
|
|
6822
|
-
* @
|
|
6772
|
+
* @param {number | null} page - The page number to navigate to
|
|
6773
|
+
* @returns {void}
|
|
6823
6774
|
*
|
|
6824
6775
|
* @mermaid
|
|
6825
6776
|
* sequenceDiagram
|
|
6826
6777
|
* participant U as User
|
|
6827
|
-
* participant
|
|
6828
|
-
* participant P as Popover
|
|
6829
|
-
* participant A as Accessibility
|
|
6778
|
+
* participant P as PaginationComponent
|
|
6830
6779
|
*
|
|
6831
|
-
* U->>
|
|
6832
|
-
*
|
|
6833
|
-
*
|
|
6834
|
-
*
|
|
6835
|
-
*
|
|
6836
|
-
*
|
|
6780
|
+
* U->>P: Click page number
|
|
6781
|
+
* P->>P: navigate(page)
|
|
6782
|
+
* alt page is not null and different from current
|
|
6783
|
+
* P->>P: Determine direction (next/previous)
|
|
6784
|
+
* P->>P: handleClick(direction, page)
|
|
6785
|
+
* end
|
|
6837
6786
|
*
|
|
6838
|
-
* @memberOf
|
|
6787
|
+
* @memberOf PaginationComponent
|
|
6839
6788
|
*/
|
|
6840
|
-
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
removeFocusTrap();
|
|
6844
|
-
this.actionMenuComponent.event = event;
|
|
6845
|
-
this.actionMenuOpen = true;
|
|
6789
|
+
navigate(page) {
|
|
6790
|
+
if (page !== null && this.current !== page)
|
|
6791
|
+
this.handleClick(page > this.current ? 'next' : 'previous', page);
|
|
6846
6792
|
}
|
|
6847
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
6848
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", 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)" } }, viewQueries: [{ propertyName: "actionMenuComponent", first: true, predicate: ["actionMenuComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "\n@if(title || description) {\n <ion-item-sliding #component>\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 \">\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 <ion-label class=\"dcf-item-title\" [innerHTML]=\"uid + ' - ' + title\" ></ion-label>\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 <div class=\"dcf-visible@m\" id=\"dcf-actions\">\n <ion-button class=\"dcf-hidden@m\" 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{--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)}@media (prefers-color-scheme: dark){ion-item{--background-hover-opacity: .25;--background-focused-opacity: .25}}@media (prefers-color-scheme: light){ion-item{--background-hover-opacity: .1;--background-focused-opacity: .1}}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}@media (prefers-color-scheme: light){ion-item{--border-color: var(--dcf-color-gray-2)}ion-item .dcf-info{color:var(--dcf-color-gray-6)}ion-item .dcf-item-title{color:var(--dcf-color-gray-8)}ion-item .dcf-description{color:var(--dcf-color-gray-6)}}@media (prefers-color-scheme: dark){ion-item{--border-color: var(--dcf-color-gray-6)}ion-item .dcf-description{color:var(--dcf-color-gray-4)}}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}}@media (prefers-color-scheme: light){ion-item .dcf-icon ion-button{color:var(--dcf-color-gray-7);--background: var(--dcf-color-gray-1) !important}}@media (prefers-color-scheme: dark){ion-item .dcf-icon ion-button{color:var(--dcf-color-gray-1)!important;--background: var(--dcf-color-gray-7) !important}}ion-item .dcf-icon ion-button ion-icon{font-size:20px}ion-item .dcf-icon ion-avatar{width:48px;height:48px;display:flex;justify-content:center;align-items:center;text-align:center}@media (prefers-color-scheme: light){ion-item .dcf-icon ion-avatar{color:var(--dcf-color-gray-7);background:var(--dcf-color-gray-1)!important}}@media (prefers-color-scheme: dark){ion-item .dcf-icon ion-avatar{color:var(--dcf-color-gray-1)!important;background:var(--dcf-background-color)!important}}ion-item .dcf-icon ion-avatar ion-icon{font-size:20px}ion-item .dcf-icon ion-avatar .dcf-icon-large{transform:translateY(5px)}ion-item-sliding{box-sizing:border-box}@media (prefers-color-scheme: light){ion-item-sliding ion-item-option:not(.dcf-delete),ion-item-sliding ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),.25)!important}ion-item-sliding ion-item-option:not(.dcf-delete) .dcf-ti,ion-item-sliding ion-item-option:not(.dcf-delete) ion-icon,ion-item-sliding ion-item-option:not(.dcf-update) .dcf-ti,ion-item-sliding ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-7)!important}ion-item-sliding ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item-sliding ion-item-option.dcf-delete .dcf-ti,ion-item-sliding ion-item-option.dcf-delete *,ion-item-sliding ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item-sliding ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item-sliding ion-item-option.dcf-update .dcf-ti,ion-item-sliding ion-item-option.dcf-update ion-icon{color:var(--dcf-color-primary)!important}}@media (prefers-color-scheme: dark){ion-item-sliding ion-item-option:not(.dcf-delete),ion-item-sliding ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),1)!important}ion-item-sliding ion-item-option:not(.dcf-delete) .dcf-ti,ion-item-sliding ion-item-option:not(.dcf-delete) ion-icon,ion-item-sliding ion-item-option:not(.dcf-update) .dcf-ti,ion-item-sliding ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-2)!important}ion-item-sliding ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item-sliding ion-item-option.dcf-delete .dcf-ti,ion-item-sliding ion-item-option.dcf-delete *,ion-item-sliding ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item-sliding ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item-sliding ion-item-option.dcf-update .dcf-ti,ion-item-sliding ion-item-option.dcf-update ion-icon{color:var(--dcf-color-gray-2)!important}}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)}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }, { 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" }] }); }
|
|
6849
|
-
}
|
|
6850
|
-
|
|
6851
|
-
Dynamic(),
|
|
6852
|
-
__metadata("design:paramtypes", [])
|
|
6853
|
-
], ListItemComponent);
|
|
6854
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ListItemComponent, decorators: [{
|
|
6793
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: PaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6794
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.2", type: PaginationComponent, isStandalone: true, selector: "ngx-decaf-pagination", inputs: { totalPages: "totalPages", current: "current" }, outputs: { clickEvent: "clickEvent" }, usesInheritance: true, ngImport: i0, template: " <div [id]=\"uid\" class=\"dcf-paginator-container dcf-flex dcf-flex-center\">\n <div class=\"dcf-width-1-1\">\n <div class=\"dcf-pagination-resume\" [innerHTML]=\"locale + '.resume' | translate: {value0: current, value1: last}\"></div>\n <div #paginationComponent class=\"dcf-pagination dcf-flex-center\">\n <div\n aria-label=\"previous\"\n tabindex=\"0\"\n (click)=\"previous()\"\n (keydown.enter)=\"previous()\" [class.dcf-disabled]=\"current === 1\">\n <ion-icon name=\"chevron-back-outline\" aria-hidden=\"true\"></ion-icon>\n </div>\n @for(page of pages; track page) {\n <div tabindex=\"0\" [class]=\"page['class']\" (click)=\"navigate(page['index'])\"\n (keydown.enter)=\"navigate(page['index'])\"\n [class.dcf-active]=\"current === page['index']\">\n <span class=\"page-item\">{{ page['text'] }}</span>\n </div>\n }\n <div\n tabindex=\"0\" (click)=\"next()\"\n (keydown.enter)=\"next()\"\n [class.dcf-disabled]=\"current === last\">\n <ion-icon name=\"chevron-forward-outline\" aria-hidden=\"true\"></ion-icon>\n </div>\n </div>\n </div>\n</div>\n", styles: [".dcf-paginator-container{margin-bottom:1rem}.dcf-pagination{display:flex;flex-wrap:wrap;align-items:center;margin-left:0;padding:0;list-style:none}.dcf-pagination .page-item{display:flex;justify-content:center;align-items:center;text-align:center;font-weight:600;width:34px;line-height:34px;padding:0!important;border-radius:50%;box-sizing:border-box}@media (prefers-color-scheme: dark){.dcf-pagination .page-item{color:var(--dcf-color-gray-3)!important}}@media (prefers-color-scheme: light){.dcf-pagination .page-item{color:var(--dcf-color-gray-7)!important}}.dcf-pagination>*{flex:none;padding-left:0;position:relative;margin:0px .15rem;cursor:pointer}.dcf-pagination>*.dcf-disabled{pointer-events:none;touch-action:none;cursor:text}.dcf-pagination>*.dcf-active{pointer-events:none;touch-action:none}@media (prefers-color-scheme: light){.dcf-pagination>*.dcf-active .page-item{background:rgba(var(--dcf-color-primary-rgb),.15)}.dcf-pagination>*:hover:not(.dcf-active) *{color:var(--dcf-color-primary)!important}}@media (prefers-color-scheme: dark){.dcf-pagination>*.dcf-active .page-item{background:var(--dcf-color-gray-7)}.dcf-pagination>*:hover:not(.dcf-active) *{color:var(--dcf-color-primary)!important}}.dcf-pagination-resume{margin:1rem 0px;text-align:center}@media (prefers-color-scheme: light){.dcf-pagination-resume{color:var(--dcf-color-gray-8)}}\n"], dependencies: [{ kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
6795
|
+
}
|
|
6796
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: PaginationComponent, decorators: [{
|
|
6855
6797
|
type: Component,
|
|
6856
|
-
args: [{ selector: 'ngx-decaf-
|
|
6798
|
+
args: [{ selector: 'ngx-decaf-pagination', imports: [
|
|
6857
6799
|
TranslatePipe,
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
IonIcon,
|
|
6865
|
-
IonLabel,
|
|
6866
|
-
IonButton,
|
|
6867
|
-
IonContent,
|
|
6868
|
-
IonPopover
|
|
6869
|
-
], template: "\n@if(title || description) {\n <ion-item-sliding #component>\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 \">\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 <ion-label class=\"dcf-item-title\" [innerHTML]=\"uid + ' - ' + title\" ></ion-label>\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 <div class=\"dcf-visible@m\" id=\"dcf-actions\">\n <ion-button class=\"dcf-hidden@m\" 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{--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)}@media (prefers-color-scheme: dark){ion-item{--background-hover-opacity: .25;--background-focused-opacity: .25}}@media (prefers-color-scheme: light){ion-item{--background-hover-opacity: .1;--background-focused-opacity: .1}}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}@media (prefers-color-scheme: light){ion-item{--border-color: var(--dcf-color-gray-2)}ion-item .dcf-info{color:var(--dcf-color-gray-6)}ion-item .dcf-item-title{color:var(--dcf-color-gray-8)}ion-item .dcf-description{color:var(--dcf-color-gray-6)}}@media (prefers-color-scheme: dark){ion-item{--border-color: var(--dcf-color-gray-6)}ion-item .dcf-description{color:var(--dcf-color-gray-4)}}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}}@media (prefers-color-scheme: light){ion-item .dcf-icon ion-button{color:var(--dcf-color-gray-7);--background: var(--dcf-color-gray-1) !important}}@media (prefers-color-scheme: dark){ion-item .dcf-icon ion-button{color:var(--dcf-color-gray-1)!important;--background: var(--dcf-color-gray-7) !important}}ion-item .dcf-icon ion-button ion-icon{font-size:20px}ion-item .dcf-icon ion-avatar{width:48px;height:48px;display:flex;justify-content:center;align-items:center;text-align:center}@media (prefers-color-scheme: light){ion-item .dcf-icon ion-avatar{color:var(--dcf-color-gray-7);background:var(--dcf-color-gray-1)!important}}@media (prefers-color-scheme: dark){ion-item .dcf-icon ion-avatar{color:var(--dcf-color-gray-1)!important;background:var(--dcf-background-color)!important}}ion-item .dcf-icon ion-avatar ion-icon{font-size:20px}ion-item .dcf-icon ion-avatar .dcf-icon-large{transform:translateY(5px)}ion-item-sliding{box-sizing:border-box}@media (prefers-color-scheme: light){ion-item-sliding ion-item-option:not(.dcf-delete),ion-item-sliding ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),.25)!important}ion-item-sliding ion-item-option:not(.dcf-delete) .dcf-ti,ion-item-sliding ion-item-option:not(.dcf-delete) ion-icon,ion-item-sliding ion-item-option:not(.dcf-update) .dcf-ti,ion-item-sliding ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-7)!important}ion-item-sliding ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item-sliding ion-item-option.dcf-delete .dcf-ti,ion-item-sliding ion-item-option.dcf-delete *,ion-item-sliding ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item-sliding ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item-sliding ion-item-option.dcf-update .dcf-ti,ion-item-sliding ion-item-option.dcf-update ion-icon{color:var(--dcf-color-primary)!important}}@media (prefers-color-scheme: dark){ion-item-sliding ion-item-option:not(.dcf-delete),ion-item-sliding ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),1)!important}ion-item-sliding ion-item-option:not(.dcf-delete) .dcf-ti,ion-item-sliding ion-item-option:not(.dcf-delete) ion-icon,ion-item-sliding ion-item-option:not(.dcf-update) .dcf-ti,ion-item-sliding ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-2)!important}ion-item-sliding ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item-sliding ion-item-option.dcf-delete .dcf-ti,ion-item-sliding ion-item-option.dcf-delete *,ion-item-sliding ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item-sliding ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item-sliding ion-item-option.dcf-update .dcf-ti,ion-item-sliding ion-item-option.dcf-update ion-icon{color:var(--dcf-color-gray-2)!important}}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)}\n"] }]
|
|
6870
|
-
}], ctorParameters: () => [], propDecorators: { actionMenuComponent: [{
|
|
6871
|
-
type: ViewChild,
|
|
6872
|
-
args: ['actionMenuComponent']
|
|
6873
|
-
}], lines: [{
|
|
6874
|
-
type: Input
|
|
6875
|
-
}], item: [{
|
|
6876
|
-
type: Input
|
|
6877
|
-
}], icon: [{
|
|
6878
|
-
type: Input
|
|
6879
|
-
}], iconSlot: [{
|
|
6880
|
-
type: Input
|
|
6881
|
-
}], button: [{
|
|
6882
|
-
type: Input
|
|
6883
|
-
}], title: [{
|
|
6884
|
-
type: Input
|
|
6885
|
-
}], description: [{
|
|
6886
|
-
type: Input
|
|
6887
|
-
}], info: [{
|
|
6888
|
-
type: Input
|
|
6889
|
-
}], subinfo: [{
|
|
6800
|
+
IonIcon
|
|
6801
|
+
], standalone: true, template: " <div [id]=\"uid\" class=\"dcf-paginator-container dcf-flex dcf-flex-center\">\n <div class=\"dcf-width-1-1\">\n <div class=\"dcf-pagination-resume\" [innerHTML]=\"locale + '.resume' | translate: {value0: current, value1: last}\"></div>\n <div #paginationComponent class=\"dcf-pagination dcf-flex-center\">\n <div\n aria-label=\"previous\"\n tabindex=\"0\"\n (click)=\"previous()\"\n (keydown.enter)=\"previous()\" [class.dcf-disabled]=\"current === 1\">\n <ion-icon name=\"chevron-back-outline\" aria-hidden=\"true\"></ion-icon>\n </div>\n @for(page of pages; track page) {\n <div tabindex=\"0\" [class]=\"page['class']\" (click)=\"navigate(page['index'])\"\n (keydown.enter)=\"navigate(page['index'])\"\n [class.dcf-active]=\"current === page['index']\">\n <span class=\"page-item\">{{ page['text'] }}</span>\n </div>\n }\n <div\n tabindex=\"0\" (click)=\"next()\"\n (keydown.enter)=\"next()\"\n [class.dcf-disabled]=\"current === last\">\n <ion-icon name=\"chevron-forward-outline\" aria-hidden=\"true\"></ion-icon>\n </div>\n </div>\n </div>\n</div>\n", styles: [".dcf-paginator-container{margin-bottom:1rem}.dcf-pagination{display:flex;flex-wrap:wrap;align-items:center;margin-left:0;padding:0;list-style:none}.dcf-pagination .page-item{display:flex;justify-content:center;align-items:center;text-align:center;font-weight:600;width:34px;line-height:34px;padding:0!important;border-radius:50%;box-sizing:border-box}@media (prefers-color-scheme: dark){.dcf-pagination .page-item{color:var(--dcf-color-gray-3)!important}}@media (prefers-color-scheme: light){.dcf-pagination .page-item{color:var(--dcf-color-gray-7)!important}}.dcf-pagination>*{flex:none;padding-left:0;position:relative;margin:0px .15rem;cursor:pointer}.dcf-pagination>*.dcf-disabled{pointer-events:none;touch-action:none;cursor:text}.dcf-pagination>*.dcf-active{pointer-events:none;touch-action:none}@media (prefers-color-scheme: light){.dcf-pagination>*.dcf-active .page-item{background:rgba(var(--dcf-color-primary-rgb),.15)}.dcf-pagination>*:hover:not(.dcf-active) *{color:var(--dcf-color-primary)!important}}@media (prefers-color-scheme: dark){.dcf-pagination>*.dcf-active .page-item{background:var(--dcf-color-gray-7)}.dcf-pagination>*:hover:not(.dcf-active) *{color:var(--dcf-color-primary)!important}}.dcf-pagination-resume{margin:1rem 0px;text-align:center}@media (prefers-color-scheme: light){.dcf-pagination-resume{color:var(--dcf-color-gray-8)}}\n"] }]
|
|
6802
|
+
}], ctorParameters: () => [], propDecorators: { totalPages: [{
|
|
6803
|
+
type: Input,
|
|
6804
|
+
args: [{ required: true }]
|
|
6805
|
+
}], current: [{
|
|
6890
6806
|
type: Input
|
|
6891
6807
|
}], clickEvent: [{
|
|
6892
6808
|
type: Output
|
|
6893
|
-
}], enableSlideItems: [{
|
|
6894
|
-
type: HostListener,
|
|
6895
|
-
args: ['window:resize', ['$event']]
|
|
6896
6809
|
}] } });
|
|
6897
6810
|
|
|
6898
6811
|
/**
|
|
6899
|
-
* @description A
|
|
6900
|
-
* @summary This component provides a
|
|
6901
|
-
*
|
|
6902
|
-
*
|
|
6812
|
+
* @description A versatile list component that supports various data display modes.
|
|
6813
|
+
* @summary This component provides a flexible way to display lists of data with support
|
|
6814
|
+
* for infinite scrolling, pagination, searching, and custom item rendering. It can fetch
|
|
6815
|
+
* data from various sources including models, functions, or direct data input.
|
|
6903
6816
|
*
|
|
6904
|
-
* The component
|
|
6905
|
-
*
|
|
6906
|
-
*
|
|
6817
|
+
* The component supports two main display types:
|
|
6818
|
+
* 1. Infinite scrolling - Loads more data as the user scrolls
|
|
6819
|
+
* 2. Pagination - Displays data in pages with navigation controls
|
|
6820
|
+
*
|
|
6821
|
+
* Additional features include:
|
|
6822
|
+
* - Pull-to-refresh functionality
|
|
6823
|
+
* - Search filtering
|
|
6824
|
+
* - Empty state customization
|
|
6825
|
+
* - Custom item rendering
|
|
6826
|
+
* - Event emission for interactions
|
|
6907
6827
|
*
|
|
6908
6828
|
* @mermaid
|
|
6909
6829
|
* sequenceDiagram
|
|
6910
6830
|
* participant U as User
|
|
6911
|
-
* participant
|
|
6912
|
-
* participant
|
|
6831
|
+
* participant L as ListComponent
|
|
6832
|
+
* participant D as Data Source
|
|
6833
|
+
* participant E as External Components
|
|
6913
6834
|
*
|
|
6914
|
-
* U->>
|
|
6915
|
-
*
|
|
6916
|
-
*
|
|
6917
|
-
*
|
|
6835
|
+
* U->>L: Initialize component
|
|
6836
|
+
* L->>L: ngOnInit()
|
|
6837
|
+
* L->>D: Request initial data
|
|
6838
|
+
* D-->>L: Return data
|
|
6839
|
+
* L->>L: Process and display data
|
|
6918
6840
|
*
|
|
6919
|
-
*
|
|
6920
|
-
*
|
|
6921
|
-
*
|
|
6922
|
-
*
|
|
6841
|
+
* alt User scrolls (Infinite mode)
|
|
6842
|
+
* U->>L: Scroll to bottom
|
|
6843
|
+
* L->>D: Request more data
|
|
6844
|
+
* D-->>L: Return additional data
|
|
6845
|
+
* L->>L: Append to existing data
|
|
6846
|
+
* else User changes page (Paginated mode)
|
|
6847
|
+
* U->>L: Click page number
|
|
6848
|
+
* L->>L: handlePaginate()
|
|
6849
|
+
* L->>D: Request data for page
|
|
6850
|
+
* D-->>L: Return page data
|
|
6851
|
+
* L->>L: Replace displayed data
|
|
6852
|
+
* end
|
|
6923
6853
|
*
|
|
6924
|
-
*
|
|
6925
|
-
*
|
|
6926
|
-
*
|
|
6927
|
-
*
|
|
6854
|
+
* alt User searches
|
|
6855
|
+
* U->>L: Enter search term
|
|
6856
|
+
* L->>L: handleSearch()
|
|
6857
|
+
* L->>D: Filter data by search term
|
|
6858
|
+
* D-->>L: Return filtered data
|
|
6859
|
+
* L->>L: Update displayed data
|
|
6860
|
+
* end
|
|
6861
|
+
*
|
|
6862
|
+
* alt User clicks item
|
|
6863
|
+
* U->>L: Click list item
|
|
6864
|
+
* L->>L: handleClick()
|
|
6865
|
+
* L->>E: Emit clickEvent
|
|
6866
|
+
* end
|
|
6928
6867
|
*
|
|
6929
6868
|
* @example
|
|
6930
|
-
* <ngx-decaf-
|
|
6931
|
-
* [
|
|
6932
|
-
* [
|
|
6933
|
-
*
|
|
6934
|
-
*
|
|
6869
|
+
* <ngx-decaf-list
|
|
6870
|
+
* [source]="dataSource"
|
|
6871
|
+
* [limit]="10"
|
|
6872
|
+
* [type]="'infinite'"
|
|
6873
|
+
* [showSearchbar]="true"
|
|
6874
|
+
* (clickEvent)="handleItemClick($event)"
|
|
6875
|
+
* (refreshEvent)="handleRefresh($event)">
|
|
6876
|
+
* </ngx-decaf-list>
|
|
6935
6877
|
*
|
|
6936
6878
|
* @extends {NgxBaseComponent}
|
|
6937
6879
|
* @implements {OnInit}
|
|
6938
6880
|
*/
|
|
6939
|
-
class
|
|
6881
|
+
let ListComponent = class ListComponent extends NgxBaseComponent {
|
|
6940
6882
|
/**
|
|
6941
|
-
* @
|
|
6942
|
-
* @
|
|
6943
|
-
*
|
|
6883
|
+
* @description Initializes a new instance of the ListComponent.
|
|
6884
|
+
* @summary Creates a new ListComponent and sets up the base component with the appropriate
|
|
6885
|
+
* component name. This constructor is called when Angular instantiates the component and
|
|
6886
|
+
* before any input properties are set. It passes the component name to the parent class
|
|
6887
|
+
* constructor to enable proper localization and component identification.
|
|
6888
|
+
*
|
|
6889
|
+
* The constructor is intentionally minimal, with most initialization logic deferred to
|
|
6890
|
+
* the ngOnInit lifecycle hook. This follows Angular best practices by keeping the constructor
|
|
6891
|
+
* focused on dependency injection and basic setup, while complex initialization that depends
|
|
6892
|
+
* on input properties is handled in ngOnInit.
|
|
6893
|
+
*
|
|
6894
|
+
* @memberOf ListComponent
|
|
6944
6895
|
*/
|
|
6945
6896
|
constructor() {
|
|
6946
|
-
super("
|
|
6897
|
+
super("ListComponent");
|
|
6898
|
+
/**
|
|
6899
|
+
* @description The display mode for the list component.
|
|
6900
|
+
* @summary Determines how the list data is loaded and displayed. Options include:
|
|
6901
|
+
* - INFINITE: Loads more data as the user scrolls (infinite scrolling)
|
|
6902
|
+
* - PAGINATED: Displays data in pages with navigation controls
|
|
6903
|
+
*
|
|
6904
|
+
* @type {ListComponentsTypes}
|
|
6905
|
+
* @default ListComponentsTypes.INFINITE
|
|
6906
|
+
* @memberOf ListComponent
|
|
6907
|
+
*/
|
|
6908
|
+
this.type = ListComponentsTypes.INFINITE;
|
|
6947
6909
|
/**
|
|
6948
6910
|
* @description Controls whether the component uses translation services.
|
|
6949
6911
|
* @summary When set to true, the component will attempt to use translation services
|
|
6950
|
-
* for any text content. This allows for internationalization of the
|
|
6912
|
+
* for any text content. This allows for internationalization of the list component.
|
|
6951
6913
|
*
|
|
6952
6914
|
* @type {StringOrBoolean}
|
|
6953
6915
|
* @default true
|
|
6954
|
-
* @memberOf
|
|
6916
|
+
* @memberOf ListComponent
|
|
6955
6917
|
*/
|
|
6956
6918
|
this.translatable = true;
|
|
6957
6919
|
/**
|
|
6958
|
-
* @description
|
|
6959
|
-
* @summary
|
|
6960
|
-
* to
|
|
6920
|
+
* @description Controls the visibility of the search bar.
|
|
6921
|
+
* @summary When set to true, displays a search bar at the top of the list that allows
|
|
6922
|
+
* users to filter the list items. The search functionality works by filtering the
|
|
6923
|
+
* existing data or by triggering a new data fetch with search parameters.
|
|
6924
|
+
*
|
|
6925
|
+
* @type {StringOrBoolean}
|
|
6926
|
+
* @default true
|
|
6927
|
+
* @memberOf ListComponent
|
|
6928
|
+
*/
|
|
6929
|
+
this.showSearchbar = true;
|
|
6930
|
+
/**
|
|
6931
|
+
* @description Direct data input for the list component.
|
|
6932
|
+
* @summary Provides a way to directly pass data to the list component instead of
|
|
6933
|
+
* fetching it from a source. When both data and source are provided, the component
|
|
6934
|
+
* will use the source to fetch data only if the data array is empty.
|
|
6935
|
+
*
|
|
6936
|
+
* @type {KeyValue[] | undefined}
|
|
6937
|
+
* @default undefined
|
|
6938
|
+
* @memberOf ListComponent
|
|
6939
|
+
*/
|
|
6940
|
+
this.data = undefined;
|
|
6941
|
+
/**
|
|
6942
|
+
* @description The starting index for data fetching.
|
|
6943
|
+
* @summary Specifies the index from which to start fetching data. This is used
|
|
6944
|
+
* for pagination and infinite scrolling to determine which subset of data to load.
|
|
6961
6945
|
*
|
|
6962
6946
|
* @type {number}
|
|
6963
|
-
* @default
|
|
6964
|
-
* @memberOf
|
|
6947
|
+
* @default 0
|
|
6948
|
+
* @memberOf ListComponent
|
|
6965
6949
|
*/
|
|
6966
|
-
this.
|
|
6950
|
+
this.start = 0;
|
|
6967
6951
|
/**
|
|
6968
|
-
* @description
|
|
6969
|
-
* @summary
|
|
6970
|
-
*
|
|
6971
|
-
* about the navigation direction and the target page number.
|
|
6952
|
+
* @description The number of items to fetch per page or load operation.
|
|
6953
|
+
* @summary Determines how many items are loaded at once during pagination or
|
|
6954
|
+
* infinite scrolling. This affects the size of data chunks requested from the source.
|
|
6972
6955
|
*
|
|
6973
|
-
* @type {
|
|
6974
|
-
* @
|
|
6975
|
-
|
|
6976
|
-
this.clickEvent = new EventEmitter();
|
|
6977
|
-
addIcons({ chevronBackOutline, chevronForwardOutline });
|
|
6978
|
-
}
|
|
6979
|
-
/**
|
|
6980
|
-
* @description Initializes the component after Angular sets the input properties.
|
|
6981
|
-
* @summary Sets up the component by initializing the locale settings based on the
|
|
6982
|
-
* translatable property, generating the page numbers based on the total pages and
|
|
6983
|
-
* current page, and storing the last page number for boundary checking.
|
|
6984
|
-
*
|
|
6985
|
-
* @mermaid
|
|
6986
|
-
* sequenceDiagram
|
|
6987
|
-
* participant A as Angular Lifecycle
|
|
6988
|
-
* participant P as PaginationComponent
|
|
6989
|
-
*
|
|
6990
|
-
* A->>P: ngOnInit()
|
|
6991
|
-
* P->>P: getLocale(translatable)
|
|
6992
|
-
* P->>P: Set locale
|
|
6993
|
-
* P->>P: getPages(data, current)
|
|
6994
|
-
* P->>P: Set pages array
|
|
6995
|
-
* P->>P: Set last page number
|
|
6996
|
-
*
|
|
6997
|
-
* @returns {void}
|
|
6998
|
-
* @memberOf PaginationComponent
|
|
6999
|
-
*/
|
|
7000
|
-
ngOnInit() {
|
|
7001
|
-
this.locale = this.getLocale(this.translatable);
|
|
7002
|
-
this.pages = this.getPages(this.totalPages, this.current);
|
|
7003
|
-
this.last = this.totalPages;
|
|
7004
|
-
}
|
|
7005
|
-
/**
|
|
7006
|
-
* @description Handles click events on pagination controls.
|
|
7007
|
-
* @summary Processes user interactions with the pagination component, updating the
|
|
7008
|
-
* current page if specified and emitting an event with navigation details. This method
|
|
7009
|
-
* is called when users click on page numbers or navigation buttons.
|
|
7010
|
-
*
|
|
7011
|
-
* @param {('next' | 'previous')} direction - The direction of navigation
|
|
7012
|
-
* @param {number} [page] - Optional page number to navigate to directly
|
|
7013
|
-
* @returns {void}
|
|
7014
|
-
*
|
|
7015
|
-
* @mermaid
|
|
7016
|
-
* sequenceDiagram
|
|
7017
|
-
* participant U as User
|
|
7018
|
-
* participant P as PaginationComponent
|
|
7019
|
-
* participant E as External Component
|
|
7020
|
-
*
|
|
7021
|
-
* U->>P: Click pagination control
|
|
7022
|
-
* P->>P: handleClick(direction, page?)
|
|
7023
|
-
* alt page is provided
|
|
7024
|
-
* P->>P: Update current page
|
|
7025
|
-
* end
|
|
7026
|
-
* P->>E: Emit clickEvent with direction and page
|
|
7027
|
-
*
|
|
7028
|
-
* @memberOf PaginationComponent
|
|
7029
|
-
*/
|
|
7030
|
-
handleClick(direction, page) {
|
|
7031
|
-
if (page)
|
|
7032
|
-
this.current = page;
|
|
7033
|
-
this.clickEvent.emit({
|
|
7034
|
-
name: EventConstants.CLICK,
|
|
7035
|
-
data: {
|
|
7036
|
-
direction,
|
|
7037
|
-
page: this.current
|
|
7038
|
-
},
|
|
7039
|
-
component: this.componentName
|
|
7040
|
-
});
|
|
7041
|
-
}
|
|
7042
|
-
/**
|
|
7043
|
-
* @description Generates the array of page objects for display.
|
|
7044
|
-
* @summary Creates an array of page objects based on the total number of pages and
|
|
7045
|
-
* the current page. For small page counts (≤5), all pages are shown. For larger page
|
|
7046
|
-
* counts, a subset is shown with ellipses to indicate skipped pages. This ensures
|
|
7047
|
-
* the pagination UI remains clean and usable even with many pages.
|
|
7048
|
-
*
|
|
7049
|
-
* @param {number} total - The total number of pages
|
|
7050
|
-
* @param {number} [current] - The current active page (defaults to this.current)
|
|
7051
|
-
* @returns {KeyValue[]} Array of page objects with index and text properties
|
|
7052
|
-
*
|
|
7053
|
-
* @mermaid
|
|
7054
|
-
* flowchart TD
|
|
7055
|
-
* A[Start] --> B{total <= 5?}
|
|
7056
|
-
* B -->|Yes| C[Show all pages]
|
|
7057
|
-
* B -->|No| D[Show first page]
|
|
7058
|
-
* D --> E[Show last pages]
|
|
7059
|
-
* E --> F[Add ellipses for skipped pages]
|
|
7060
|
-
* C --> G[Return pages array]
|
|
7061
|
-
* F --> G
|
|
7062
|
-
*
|
|
7063
|
-
* @memberOf PaginationComponent
|
|
7064
|
-
*/
|
|
7065
|
-
getPages(total, current) {
|
|
7066
|
-
if (!current)
|
|
7067
|
-
current = this.current;
|
|
7068
|
-
const pages = [];
|
|
7069
|
-
function getPage(index, text = '', clazz = 'button') {
|
|
7070
|
-
if (pages.some(item => item['index'] === index))
|
|
7071
|
-
return;
|
|
7072
|
-
pages.push({ index, text: index != null ? index.toString().padStart(2, '0') : text, class: clazz });
|
|
7073
|
-
}
|
|
7074
|
-
if (total <= 5) {
|
|
7075
|
-
for (let i = 1; i <= total; i++)
|
|
7076
|
-
getPage(i);
|
|
7077
|
-
}
|
|
7078
|
-
else {
|
|
7079
|
-
// Adiciona os dois primeiros
|
|
7080
|
-
getPage(1);
|
|
7081
|
-
getPage(2);
|
|
7082
|
-
// Adiciona "..." entre os blocos
|
|
7083
|
-
if (current && current > 3)
|
|
7084
|
-
getPage(null, '...');
|
|
7085
|
-
// Adiciona a página atual (se estiver no meio)
|
|
7086
|
-
if (current && current > 2 && current < total - 1)
|
|
7087
|
-
getPage(current);
|
|
7088
|
-
// Adiciona "..." entre os blocos
|
|
7089
|
-
if (current && current < total - 2)
|
|
7090
|
-
getPage(null, '...', 'separator');
|
|
7091
|
-
// Adiciona os dois últimos
|
|
7092
|
-
getPage(total - 1);
|
|
7093
|
-
getPage(total);
|
|
7094
|
-
}
|
|
7095
|
-
return pages;
|
|
7096
|
-
}
|
|
7097
|
-
/**
|
|
7098
|
-
* @description Gets the current active page number.
|
|
7099
|
-
* @summary Returns the current page number that is active in the pagination component.
|
|
7100
|
-
* This method provides a way to access the current page state from outside the component.
|
|
7101
|
-
*
|
|
7102
|
-
* @returns {number} The current page number
|
|
7103
|
-
* @memberOf PaginationComponent
|
|
7104
|
-
*/
|
|
7105
|
-
getCurrent() {
|
|
7106
|
-
return this.current;
|
|
7107
|
-
}
|
|
7108
|
-
/**
|
|
7109
|
-
* @description Navigates to the next page.
|
|
7110
|
-
* @summary Increments the current page number if not at the last page and triggers
|
|
7111
|
-
* the click event handler with 'next' direction. This method is typically called
|
|
7112
|
-
* when the user clicks on the "next" button in the pagination UI.
|
|
7113
|
-
*
|
|
7114
|
-
* @returns {void}
|
|
7115
|
-
*
|
|
7116
|
-
* @mermaid
|
|
7117
|
-
* sequenceDiagram
|
|
7118
|
-
* participant U as User
|
|
7119
|
-
* participant P as PaginationComponent
|
|
7120
|
-
*
|
|
7121
|
-
* U->>P: Click next button
|
|
7122
|
-
* P->>P: next()
|
|
7123
|
-
* alt page <= max pages
|
|
7124
|
-
* P->>P: Increment current page
|
|
7125
|
-
* P->>P: handleClick('next')
|
|
7126
|
-
* end
|
|
7127
|
-
*
|
|
7128
|
-
* @memberOf PaginationComponent
|
|
7129
|
-
*/
|
|
7130
|
-
next() {
|
|
7131
|
-
const page = this.current + 1;
|
|
7132
|
-
if (page <= Object.keys(this.pages)?.length || 0) {
|
|
7133
|
-
this.current = page;
|
|
7134
|
-
this.handleClick('next');
|
|
7135
|
-
}
|
|
7136
|
-
}
|
|
7137
|
-
/**
|
|
7138
|
-
* @description Navigates to the previous page.
|
|
7139
|
-
* @summary Decrements the current page number if not at the first page and triggers
|
|
7140
|
-
* the click event handler with 'previous' direction. This method is typically called
|
|
7141
|
-
* when the user clicks on the "previous" button in the pagination UI.
|
|
7142
|
-
*
|
|
7143
|
-
* @returns {void}
|
|
7144
|
-
*
|
|
7145
|
-
* @mermaid
|
|
7146
|
-
* sequenceDiagram
|
|
7147
|
-
* participant U as User
|
|
7148
|
-
* participant P as PaginationComponent
|
|
7149
|
-
*
|
|
7150
|
-
* U->>P: Click previous button
|
|
7151
|
-
* P->>P: previous()
|
|
7152
|
-
* alt page > 0
|
|
7153
|
-
* P->>P: Decrement current page
|
|
7154
|
-
* P->>P: handleClick('previous')
|
|
7155
|
-
* end
|
|
7156
|
-
*
|
|
7157
|
-
* @memberOf PaginationComponent
|
|
7158
|
-
*/
|
|
7159
|
-
previous() {
|
|
7160
|
-
const page = this.current - 1;
|
|
7161
|
-
if (page > 0) {
|
|
7162
|
-
this.current = page;
|
|
7163
|
-
this.handleClick('previous');
|
|
7164
|
-
}
|
|
7165
|
-
}
|
|
7166
|
-
/**
|
|
7167
|
-
* @description Navigates to a specific page number.
|
|
7168
|
-
* @summary Updates the current page to the specified page number and triggers
|
|
7169
|
-
* the click event handler with the appropriate direction. This method is typically
|
|
7170
|
-
* called when the user clicks directly on a page number in the pagination UI.
|
|
7171
|
-
*
|
|
7172
|
-
* @param {number | null} page - The page number to navigate to
|
|
7173
|
-
* @returns {void}
|
|
7174
|
-
*
|
|
7175
|
-
* @mermaid
|
|
7176
|
-
* sequenceDiagram
|
|
7177
|
-
* participant U as User
|
|
7178
|
-
* participant P as PaginationComponent
|
|
7179
|
-
*
|
|
7180
|
-
* U->>P: Click page number
|
|
7181
|
-
* P->>P: navigate(page)
|
|
7182
|
-
* alt page is not null and different from current
|
|
7183
|
-
* P->>P: Determine direction (next/previous)
|
|
7184
|
-
* P->>P: handleClick(direction, page)
|
|
7185
|
-
* end
|
|
7186
|
-
*
|
|
7187
|
-
* @memberOf PaginationComponent
|
|
7188
|
-
*/
|
|
7189
|
-
navigate(page) {
|
|
7190
|
-
if (page !== null && this.current !== page)
|
|
7191
|
-
this.handleClick(page > this.current ? 'next' : 'previous', page);
|
|
7192
|
-
}
|
|
7193
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7194
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: PaginationComponent, isStandalone: true, selector: "ngx-decaf-pagination", inputs: { totalPages: "totalPages", current: "current" }, outputs: { clickEvent: "clickEvent" }, usesInheritance: true, ngImport: i0, template: " <div [id]=\"uid\" class=\"dcf-paginator-container dcf-flex dcf-flex-center\">\n <div class=\"dcf-width-1-1\">\n <div class=\"dcf-pagination-resume\" [innerHTML]=\"locale + '.resume' | translate: {value0: current, value1: last}\"></div>\n <div #paginationComponent class=\"dcf-pagination dcf-flex-center\">\n <div\n aria-label=\"previous\"\n tabindex=\"0\"\n (click)=\"previous()\"\n (keydown.enter)=\"previous()\" [class.dcf-disabled]=\"current === 1\">\n <ion-icon name=\"chevron-back-outline\" aria-hidden=\"true\"></ion-icon>\n </div>\n @for(page of pages; track page) {\n <div tabindex=\"0\" [class]=\"page['class']\" (click)=\"navigate(page['index'])\"\n (keydown.enter)=\"navigate(page['index'])\"\n [class.dcf-active]=\"current === page['index']\">\n <span class=\"page-item\">{{ page['text'] }}</span>\n </div>\n }\n <div\n tabindex=\"0\" (click)=\"next()\"\n (keydown.enter)=\"next()\"\n [class.dcf-disabled]=\"current === last\">\n <ion-icon name=\"chevron-forward-outline\" aria-hidden=\"true\"></ion-icon>\n </div>\n </div>\n </div>\n</div>\n", styles: [".dcf-paginator-container{margin-bottom:1rem}.dcf-pagination{display:flex;flex-wrap:wrap;align-items:center;margin-left:0;padding:0;list-style:none}.dcf-pagination .page-item{display:flex;justify-content:center;align-items:center;text-align:center;font-weight:600;width:34px;line-height:34px;padding:0!important;border-radius:50%;box-sizing:border-box}@media (prefers-color-scheme: dark){.dcf-pagination .page-item{color:var(--dcf-color-gray-3)!important}}@media (prefers-color-scheme: light){.dcf-pagination .page-item{color:var(--dcf-color-gray-7)!important}}.dcf-pagination>*{flex:none;padding-left:0;position:relative;margin:0px .15rem;cursor:pointer}.dcf-pagination>*.dcf-disabled{pointer-events:none;touch-action:none;cursor:text}.dcf-pagination>*.dcf-active{pointer-events:none;touch-action:none}@media (prefers-color-scheme: light){.dcf-pagination>*.dcf-active .page-item{background:rgba(var(--dcf-color-primary-rgb),.15)}.dcf-pagination>*:hover:not(.dcf-active) *{color:var(--dcf-color-primary)!important}}@media (prefers-color-scheme: dark){.dcf-pagination>*.dcf-active .page-item{background:var(--dcf-color-gray-7)}.dcf-pagination>*:hover:not(.dcf-active) *{color:var(--dcf-color-primary)!important}}.dcf-pagination-resume{margin:1rem 0px;text-align:center}@media (prefers-color-scheme: light){.dcf-pagination-resume{color:var(--dcf-color-gray-8)}}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }] }); }
|
|
7195
|
-
}
|
|
7196
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PaginationComponent, decorators: [{
|
|
7197
|
-
type: Component,
|
|
7198
|
-
args: [{ selector: 'ngx-decaf-pagination', imports: [
|
|
7199
|
-
TranslatePipe,
|
|
7200
|
-
IonIcon
|
|
7201
|
-
], standalone: true, template: " <div [id]=\"uid\" class=\"dcf-paginator-container dcf-flex dcf-flex-center\">\n <div class=\"dcf-width-1-1\">\n <div class=\"dcf-pagination-resume\" [innerHTML]=\"locale + '.resume' | translate: {value0: current, value1: last}\"></div>\n <div #paginationComponent class=\"dcf-pagination dcf-flex-center\">\n <div\n aria-label=\"previous\"\n tabindex=\"0\"\n (click)=\"previous()\"\n (keydown.enter)=\"previous()\" [class.dcf-disabled]=\"current === 1\">\n <ion-icon name=\"chevron-back-outline\" aria-hidden=\"true\"></ion-icon>\n </div>\n @for(page of pages; track page) {\n <div tabindex=\"0\" [class]=\"page['class']\" (click)=\"navigate(page['index'])\"\n (keydown.enter)=\"navigate(page['index'])\"\n [class.dcf-active]=\"current === page['index']\">\n <span class=\"page-item\">{{ page['text'] }}</span>\n </div>\n }\n <div\n tabindex=\"0\" (click)=\"next()\"\n (keydown.enter)=\"next()\"\n [class.dcf-disabled]=\"current === last\">\n <ion-icon name=\"chevron-forward-outline\" aria-hidden=\"true\"></ion-icon>\n </div>\n </div>\n </div>\n</div>\n", styles: [".dcf-paginator-container{margin-bottom:1rem}.dcf-pagination{display:flex;flex-wrap:wrap;align-items:center;margin-left:0;padding:0;list-style:none}.dcf-pagination .page-item{display:flex;justify-content:center;align-items:center;text-align:center;font-weight:600;width:34px;line-height:34px;padding:0!important;border-radius:50%;box-sizing:border-box}@media (prefers-color-scheme: dark){.dcf-pagination .page-item{color:var(--dcf-color-gray-3)!important}}@media (prefers-color-scheme: light){.dcf-pagination .page-item{color:var(--dcf-color-gray-7)!important}}.dcf-pagination>*{flex:none;padding-left:0;position:relative;margin:0px .15rem;cursor:pointer}.dcf-pagination>*.dcf-disabled{pointer-events:none;touch-action:none;cursor:text}.dcf-pagination>*.dcf-active{pointer-events:none;touch-action:none}@media (prefers-color-scheme: light){.dcf-pagination>*.dcf-active .page-item{background:rgba(var(--dcf-color-primary-rgb),.15)}.dcf-pagination>*:hover:not(.dcf-active) *{color:var(--dcf-color-primary)!important}}@media (prefers-color-scheme: dark){.dcf-pagination>*.dcf-active .page-item{background:var(--dcf-color-gray-7)}.dcf-pagination>*:hover:not(.dcf-active) *{color:var(--dcf-color-primary)!important}}.dcf-pagination-resume{margin:1rem 0px;text-align:center}@media (prefers-color-scheme: light){.dcf-pagination-resume{color:var(--dcf-color-gray-8)}}\n"] }]
|
|
7202
|
-
}], ctorParameters: () => [], propDecorators: { totalPages: [{
|
|
7203
|
-
type: Input,
|
|
7204
|
-
args: [{ required: true }]
|
|
7205
|
-
}], current: [{
|
|
7206
|
-
type: Input
|
|
7207
|
-
}], clickEvent: [{
|
|
7208
|
-
type: Output
|
|
7209
|
-
}] } });
|
|
7210
|
-
|
|
7211
|
-
/**
|
|
7212
|
-
* @description A versatile list component that supports various data display modes.
|
|
7213
|
-
* @summary This component provides a flexible way to display lists of data with support
|
|
7214
|
-
* for infinite scrolling, pagination, searching, and custom item rendering. It can fetch
|
|
7215
|
-
* data from various sources including models, functions, or direct data input.
|
|
7216
|
-
*
|
|
7217
|
-
* The component supports two main display types:
|
|
7218
|
-
* 1. Infinite scrolling - Loads more data as the user scrolls
|
|
7219
|
-
* 2. Pagination - Displays data in pages with navigation controls
|
|
7220
|
-
*
|
|
7221
|
-
* Additional features include:
|
|
7222
|
-
* - Pull-to-refresh functionality
|
|
7223
|
-
* - Search filtering
|
|
7224
|
-
* - Empty state customization
|
|
7225
|
-
* - Custom item rendering
|
|
7226
|
-
* - Event emission for interactions
|
|
7227
|
-
*
|
|
7228
|
-
* @mermaid
|
|
7229
|
-
* sequenceDiagram
|
|
7230
|
-
* participant U as User
|
|
7231
|
-
* participant L as ListComponent
|
|
7232
|
-
* participant D as Data Source
|
|
7233
|
-
* participant E as External Components
|
|
7234
|
-
*
|
|
7235
|
-
* U->>L: Initialize component
|
|
7236
|
-
* L->>L: ngOnInit()
|
|
7237
|
-
* L->>D: Request initial data
|
|
7238
|
-
* D-->>L: Return data
|
|
7239
|
-
* L->>L: Process and display data
|
|
7240
|
-
*
|
|
7241
|
-
* alt User scrolls (Infinite mode)
|
|
7242
|
-
* U->>L: Scroll to bottom
|
|
7243
|
-
* L->>D: Request more data
|
|
7244
|
-
* D-->>L: Return additional data
|
|
7245
|
-
* L->>L: Append to existing data
|
|
7246
|
-
* else User changes page (Paginated mode)
|
|
7247
|
-
* U->>L: Click page number
|
|
7248
|
-
* L->>L: handlePaginate()
|
|
7249
|
-
* L->>D: Request data for page
|
|
7250
|
-
* D-->>L: Return page data
|
|
7251
|
-
* L->>L: Replace displayed data
|
|
7252
|
-
* end
|
|
7253
|
-
*
|
|
7254
|
-
* alt User searches
|
|
7255
|
-
* U->>L: Enter search term
|
|
7256
|
-
* L->>L: handleSearch()
|
|
7257
|
-
* L->>D: Filter data by search term
|
|
7258
|
-
* D-->>L: Return filtered data
|
|
7259
|
-
* L->>L: Update displayed data
|
|
7260
|
-
* end
|
|
7261
|
-
*
|
|
7262
|
-
* alt User clicks item
|
|
7263
|
-
* U->>L: Click list item
|
|
7264
|
-
* L->>L: handleClick()
|
|
7265
|
-
* L->>E: Emit clickEvent
|
|
7266
|
-
* end
|
|
7267
|
-
*
|
|
7268
|
-
* @example
|
|
7269
|
-
* <ngx-decaf-list
|
|
7270
|
-
* [source]="dataSource"
|
|
7271
|
-
* [limit]="10"
|
|
7272
|
-
* [type]="'infinite'"
|
|
7273
|
-
* [showSearchbar]="true"
|
|
7274
|
-
* (clickEvent)="handleItemClick($event)"
|
|
7275
|
-
* (refreshEvent)="handleRefresh($event)">
|
|
7276
|
-
* </ngx-decaf-list>
|
|
7277
|
-
*
|
|
7278
|
-
* @extends {NgxBaseComponent}
|
|
7279
|
-
* @implements {OnInit}
|
|
7280
|
-
*/
|
|
7281
|
-
let ListComponent = class ListComponent extends NgxBaseComponent {
|
|
7282
|
-
/**
|
|
7283
|
-
* @description Initializes a new instance of the ListComponent.
|
|
7284
|
-
* @summary Creates a new ListComponent and sets up the base component with the appropriate
|
|
7285
|
-
* component name. This constructor is called when Angular instantiates the component and
|
|
7286
|
-
* before any input properties are set. It passes the component name to the parent class
|
|
7287
|
-
* constructor to enable proper localization and component identification.
|
|
7288
|
-
*
|
|
7289
|
-
* The constructor is intentionally minimal, with most initialization logic deferred to
|
|
7290
|
-
* the ngOnInit lifecycle hook. This follows Angular best practices by keeping the constructor
|
|
7291
|
-
* focused on dependency injection and basic setup, while complex initialization that depends
|
|
7292
|
-
* on input properties is handled in ngOnInit.
|
|
7293
|
-
*
|
|
7294
|
-
* @memberOf ListComponent
|
|
7295
|
-
*/
|
|
7296
|
-
constructor() {
|
|
7297
|
-
super("ListComponent");
|
|
7298
|
-
/**
|
|
7299
|
-
* @description The display mode for the list component.
|
|
7300
|
-
* @summary Determines how the list data is loaded and displayed. Options include:
|
|
7301
|
-
* - INFINITE: Loads more data as the user scrolls (infinite scrolling)
|
|
7302
|
-
* - PAGINATED: Displays data in pages with navigation controls
|
|
7303
|
-
*
|
|
7304
|
-
* @type {ListComponentsTypes}
|
|
7305
|
-
* @default ListComponentsTypes.INFINITE
|
|
7306
|
-
* @memberOf ListComponent
|
|
7307
|
-
*/
|
|
7308
|
-
this.type = ListComponentsTypes.INFINITE;
|
|
7309
|
-
/**
|
|
7310
|
-
* @description Controls whether the component uses translation services.
|
|
7311
|
-
* @summary When set to true, the component will attempt to use translation services
|
|
7312
|
-
* for any text content. This allows for internationalization of the list component.
|
|
7313
|
-
*
|
|
7314
|
-
* @type {StringOrBoolean}
|
|
7315
|
-
* @default true
|
|
7316
|
-
* @memberOf ListComponent
|
|
7317
|
-
*/
|
|
7318
|
-
this.translatable = true;
|
|
7319
|
-
/**
|
|
7320
|
-
* @description Controls the visibility of the search bar.
|
|
7321
|
-
* @summary When set to true, displays a search bar at the top of the list that allows
|
|
7322
|
-
* users to filter the list items. The search functionality works by filtering the
|
|
7323
|
-
* existing data or by triggering a new data fetch with search parameters.
|
|
7324
|
-
*
|
|
7325
|
-
* @type {StringOrBoolean}
|
|
7326
|
-
* @default true
|
|
7327
|
-
* @memberOf ListComponent
|
|
7328
|
-
*/
|
|
7329
|
-
this.showSearchbar = true;
|
|
7330
|
-
/**
|
|
7331
|
-
* @description Direct data input for the list component.
|
|
7332
|
-
* @summary Provides a way to directly pass data to the list component instead of
|
|
7333
|
-
* fetching it from a source. When both data and source are provided, the component
|
|
7334
|
-
* will use the source to fetch data only if the data array is empty.
|
|
7335
|
-
*
|
|
7336
|
-
* @type {KeyValue[] | undefined}
|
|
7337
|
-
* @default undefined
|
|
7338
|
-
* @memberOf ListComponent
|
|
7339
|
-
*/
|
|
7340
|
-
this.data = undefined;
|
|
7341
|
-
/**
|
|
7342
|
-
* @description The starting index for data fetching.
|
|
7343
|
-
* @summary Specifies the index from which to start fetching data. This is used
|
|
7344
|
-
* for pagination and infinite scrolling to determine which subset of data to load.
|
|
7345
|
-
*
|
|
7346
|
-
* @type {number}
|
|
7347
|
-
* @default 0
|
|
7348
|
-
* @memberOf ListComponent
|
|
7349
|
-
*/
|
|
7350
|
-
this.start = 0;
|
|
7351
|
-
/**
|
|
7352
|
-
* @description The number of items to fetch per page or load operation.
|
|
7353
|
-
* @summary Determines how many items are loaded at once during pagination or
|
|
7354
|
-
* infinite scrolling. This affects the size of data chunks requested from the source.
|
|
7355
|
-
*
|
|
7356
|
-
* @type {number}
|
|
7357
|
-
* @default 10
|
|
7358
|
-
* @memberOf ListComponent
|
|
6956
|
+
* @type {number}
|
|
6957
|
+
* @default 10
|
|
6958
|
+
* @memberOf ListComponent
|
|
7359
6959
|
*/
|
|
7360
6960
|
this.limit = 10;
|
|
7361
6961
|
/**
|
|
@@ -7588,842 +7188,1221 @@ let ListComponent = class ListComponent extends NgxBaseComponent {
|
|
|
7588
7188
|
*/
|
|
7589
7189
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7590
7190
|
this.observerSubjet = new Subject();
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7191
|
+
}
|
|
7192
|
+
/**
|
|
7193
|
+
* @description Initializes the component after Angular sets the input properties.
|
|
7194
|
+
* @summary Sets up the component by initializing event subscriptions, processing boolean
|
|
7195
|
+
* inputs, and loading the initial data. This method prepares the component for user
|
|
7196
|
+
* interaction by ensuring all properties are properly initialized and data is loaded.
|
|
7197
|
+
*
|
|
7198
|
+
* @returns {Promise<void>}
|
|
7199
|
+
*
|
|
7200
|
+
* @mermaid
|
|
7201
|
+
* sequenceDiagram
|
|
7202
|
+
* participant A as Angular Lifecycle
|
|
7203
|
+
* participant L as ListComponent
|
|
7204
|
+
* participant D as Data Source
|
|
7205
|
+
*
|
|
7206
|
+
* A->>L: ngOnInit()
|
|
7207
|
+
* L->>L: Set up click event debouncing
|
|
7208
|
+
* L->>L: Process boolean inputs
|
|
7209
|
+
* L->>L: Configure component based on inputs
|
|
7210
|
+
* L->>L: refresh()
|
|
7211
|
+
* L->>D: Request initial data
|
|
7212
|
+
* D-->>L: Return data
|
|
7213
|
+
* L->>L: Process and display data
|
|
7214
|
+
* L->>L: Configure empty state if needed
|
|
7215
|
+
* L->>L: initialize()
|
|
7216
|
+
*
|
|
7217
|
+
* @memberOf ListComponent
|
|
7218
|
+
*/
|
|
7219
|
+
async ngOnInit() {
|
|
7601
7220
|
this.observer = { refresh: async (...args) => this.observeRepository(...args) };
|
|
7221
|
+
this.clickItemSubject.pipe(debounceTime(100)).subscribe(event => this.clickEventEmit(event));
|
|
7222
|
+
this.observerSubjet.pipe(debounceTime(100)).subscribe(args => this.handleObserveEvent(args[0], args[1], args[2]));
|
|
7223
|
+
this.enableFilter = stringToBoolean(this.enableFilter);
|
|
7224
|
+
this.limit = Number(this.limit);
|
|
7225
|
+
this.start = Number(this.start);
|
|
7226
|
+
this.inset = stringToBoolean(this.inset);
|
|
7227
|
+
this.showRefresher = stringToBoolean(this.showRefresher);
|
|
7228
|
+
this.loadMoreData = stringToBoolean(this.loadMoreData);
|
|
7229
|
+
this.showSearchbar = stringToBoolean(this.showSearchbar);
|
|
7230
|
+
this.disableSort = stringToBoolean(this.disableSort);
|
|
7231
|
+
if (typeof this.item?.['tag'] === 'boolean' && this.item?.['tag'] === true)
|
|
7232
|
+
this.item['tag'] = ComponentsTagNames.LIST_ITEM;
|
|
7233
|
+
await this.refresh();
|
|
7234
|
+
if (this.operations.includes(OperationKeys.CREATE) && this.route)
|
|
7235
|
+
this.empty.link = `${this.route}/${OperationKeys.CREATE}`;
|
|
7236
|
+
await this.initialize();
|
|
7237
|
+
if (this.model instanceof Model && this._repository)
|
|
7238
|
+
this._repository.observe(this.observer);
|
|
7239
|
+
}
|
|
7240
|
+
/**
|
|
7241
|
+
* @description Cleans up resources when the component is destroyed.
|
|
7242
|
+
* @summary Performs cleanup operations when the component is being removed from the DOM.
|
|
7243
|
+
* This includes clearing references to models and data to prevent memory leaks.
|
|
7244
|
+
*
|
|
7245
|
+
* @returns {void}
|
|
7246
|
+
* @memberOf ListComponent
|
|
7247
|
+
*/
|
|
7248
|
+
ngOnDestroy() {
|
|
7249
|
+
if (this._repository)
|
|
7250
|
+
this._repository.unObserve(this.observer);
|
|
7251
|
+
this.data = this.model = this._repository = this.paginator = undefined;
|
|
7252
|
+
}
|
|
7253
|
+
/**
|
|
7254
|
+
* @description Handles repository observation events with debouncing.
|
|
7255
|
+
* @summary Processes repository change notifications and routes them appropriately.
|
|
7256
|
+
* For CREATE events with a UID, handles them immediately. For other events,
|
|
7257
|
+
* passes them to the debounced observer subject to prevent excessive updates.
|
|
7258
|
+
*
|
|
7259
|
+
* @param {...unknown[]} args - The repository event arguments including table, event type, and UID
|
|
7260
|
+
* @returns {Promise<void>}
|
|
7261
|
+
* @memberOf ListComponent
|
|
7262
|
+
*/
|
|
7263
|
+
async observeRepository(...args) {
|
|
7264
|
+
const [table, event, uid] = args;
|
|
7265
|
+
if (event === OperationKeys.CREATE && !!uid)
|
|
7266
|
+
return this.handleObserveEvent(table, event, uid);
|
|
7267
|
+
return this.observerSubjet.next(args);
|
|
7268
|
+
}
|
|
7269
|
+
/**
|
|
7270
|
+
* @description Handles specific repository events and updates the list accordingly.
|
|
7271
|
+
* @summary Processes repository change events (CREATE, UPDATE, DELETE) and performs
|
|
7272
|
+
* the appropriate list operations. This includes adding new items, updating existing
|
|
7273
|
+
* ones, or removing deleted items from the list display.
|
|
7274
|
+
*
|
|
7275
|
+
* @param {string} table - The table/model name that changed
|
|
7276
|
+
* @param {OperationKeys} event - The type of operation (CREATE, UPDATE, DELETE)
|
|
7277
|
+
* @param {string | number} uid - The unique identifier of the affected item
|
|
7278
|
+
* @returns {Promise<void>}
|
|
7279
|
+
* @memberOf ListComponent
|
|
7280
|
+
*/
|
|
7281
|
+
async handleObserveEvent(table, event, uid) {
|
|
7282
|
+
if (event === OperationKeys.CREATE) {
|
|
7283
|
+
if (uid) {
|
|
7284
|
+
await this.handleCreate(uid);
|
|
7285
|
+
}
|
|
7286
|
+
else {
|
|
7287
|
+
await this.refresh(true);
|
|
7288
|
+
}
|
|
7289
|
+
}
|
|
7290
|
+
else {
|
|
7291
|
+
if (event === OperationKeys.UPDATE)
|
|
7292
|
+
await this.handleUpdate(uid);
|
|
7293
|
+
if (event === OperationKeys.DELETE)
|
|
7294
|
+
this.handleDelete(uid);
|
|
7295
|
+
this.refreshEventEmit();
|
|
7296
|
+
}
|
|
7297
|
+
}
|
|
7298
|
+
/**
|
|
7299
|
+
* @description Function for tracking items in the list.
|
|
7300
|
+
* @summary Provides a tracking function for the `*ngFor` directive in the component template.
|
|
7301
|
+
* This function is used to identify and control the rendering of items in the list,
|
|
7302
|
+
* preventing duplicate or unnecessary rendering.
|
|
7303
|
+
*
|
|
7304
|
+
* The `trackItemFn` function takes two parameters: `index` (the index of the item in the list)
|
|
7305
|
+
* and `item` (the actual item from the list). It returns the tracking key, which in this case
|
|
7306
|
+
* is the union of the `uid` of the item with the model name.
|
|
7307
|
+
*
|
|
7308
|
+
* @param {number} index - The index of the item in the list.
|
|
7309
|
+
|
|
7310
|
+
* @param {KeyValue | string | number} item - The actual item from the list.
|
|
7311
|
+
* @returns {string | number} The tracking key for the item.
|
|
7312
|
+
* @memberOf ListComponent
|
|
7313
|
+
*/
|
|
7314
|
+
trackItemFn(index, item) {
|
|
7315
|
+
return `${item?.['uid'] || item?.[this.pk]}-${index}`;
|
|
7316
|
+
}
|
|
7317
|
+
/**
|
|
7318
|
+
* Handles the create event from the repository.
|
|
7319
|
+
*
|
|
7320
|
+
* @param {string | number} uid - The ID of the item to create.
|
|
7321
|
+
* @returns {Promise<void>} A promise that resolves when the item is created and added to the list.
|
|
7322
|
+
*/
|
|
7323
|
+
async handleCreate(uid) {
|
|
7324
|
+
const result = await this._repository?.read(uid);
|
|
7325
|
+
const item = this.mapResults([result])[0];
|
|
7326
|
+
this.items = this.data = [item, ...this.items || []];
|
|
7327
|
+
}
|
|
7328
|
+
/**
|
|
7329
|
+
* @description Handles the update event from the repository.
|
|
7330
|
+
* @summary Updates the list item with the specified ID based on the new data.
|
|
7331
|
+
*
|
|
7332
|
+
* @param {string | number} uid - The ID of the item to update
|
|
7333
|
+
* @returns {Promise<void>}
|
|
7334
|
+
* @private
|
|
7335
|
+
* @memberOf ListComponent
|
|
7336
|
+
*/
|
|
7337
|
+
async handleUpdate(uid) {
|
|
7338
|
+
const item = this.itemMapper(await this._repository?.read(uid) || {}, this.mapper);
|
|
7339
|
+
this.data = [];
|
|
7340
|
+
for (const key in this.items) {
|
|
7341
|
+
const child = this.items[key];
|
|
7342
|
+
if (child['uid'] === item['uid']) {
|
|
7343
|
+
this.items[key] = Object.assign({}, child, item);
|
|
7344
|
+
break;
|
|
7345
|
+
}
|
|
7346
|
+
}
|
|
7347
|
+
setTimeout(() => {
|
|
7348
|
+
this.data = [...this.items];
|
|
7349
|
+
}, 0);
|
|
7350
|
+
}
|
|
7351
|
+
/**
|
|
7352
|
+
* @description Removes an item from the list by ID.
|
|
7353
|
+
* @summary Filters out an item with the specified ID from the data array and
|
|
7354
|
+
* refreshes the list display. This is typically used after a delete operation.
|
|
7355
|
+
*
|
|
7356
|
+
* @param {string} uid - The ID of the item to delete
|
|
7357
|
+
* @param {string} pk - The primary key field name
|
|
7358
|
+
* @returns {Promise<void>}
|
|
7359
|
+
*
|
|
7360
|
+
* @memberOf ListComponent
|
|
7361
|
+
*/
|
|
7362
|
+
handleDelete(uid, pk) {
|
|
7363
|
+
if (!pk)
|
|
7364
|
+
pk = this.pk;
|
|
7365
|
+
this.items = this.data?.filter((item) => item['uid'] !== uid) || [];
|
|
7366
|
+
}
|
|
7367
|
+
/**
|
|
7368
|
+
* @description Handles click events from list items.
|
|
7369
|
+
* @summary Listens for global ListItemClickEvent events and passes them to the
|
|
7370
|
+
* debounced click subject. This allows the component to respond to clicks on
|
|
7371
|
+
* list items regardless of where they originate from.
|
|
7372
|
+
*
|
|
7373
|
+
* @param {ListItemCustomEvent | RendererCustomEvent} event - The click event
|
|
7374
|
+
* @returns {void}
|
|
7375
|
+
*
|
|
7376
|
+
* @memberOf ListComponent
|
|
7377
|
+
*/
|
|
7378
|
+
handleClick(event) {
|
|
7379
|
+
this.clickItemSubject.next(event);
|
|
7602
7380
|
}
|
|
7603
7381
|
/**
|
|
7604
|
-
* @description
|
|
7605
|
-
* @summary
|
|
7606
|
-
*
|
|
7607
|
-
*
|
|
7382
|
+
* @description Handles search events from the search bar.
|
|
7383
|
+
* @summary Processes search queries from the search bar component, updating the
|
|
7384
|
+
* displayed data based on the search term. The behavior differs between infinite
|
|
7385
|
+
* and paginated modes to provide the best user experience for each mode.
|
|
7608
7386
|
*
|
|
7387
|
+
* @param {string | undefined} value - The search term or undefined to clear search
|
|
7609
7388
|
* @returns {Promise<void>}
|
|
7610
7389
|
*
|
|
7611
7390
|
* @mermaid
|
|
7612
|
-
*
|
|
7613
|
-
*
|
|
7614
|
-
*
|
|
7615
|
-
*
|
|
7391
|
+
* flowchart TD
|
|
7392
|
+
* A[Search Event] --> B{Type is Infinite?}
|
|
7393
|
+
* B -->|Yes| C[Disable loadMoreData]
|
|
7394
|
+
* B -->|No| D[Enable loadMoreData]
|
|
7395
|
+
* C --> E{Search value undefined?}
|
|
7396
|
+
* E -->|Yes| F[Enable loadMoreData]
|
|
7397
|
+
* E -->|No| G[Store search value]
|
|
7398
|
+
* D --> G
|
|
7399
|
+
* F --> H[Reset page to 1]
|
|
7400
|
+
* G --> I[Refresh data]
|
|
7401
|
+
* H --> I
|
|
7616
7402
|
*
|
|
7617
|
-
*
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7403
|
+
* @memberOf ListComponent
|
|
7404
|
+
*/
|
|
7405
|
+
async handleSearch(value) {
|
|
7406
|
+
if (this.type === ListComponentsTypes.INFINITE) {
|
|
7407
|
+
this.loadMoreData = false;
|
|
7408
|
+
if (value === undefined) {
|
|
7409
|
+
this.loadMoreData = true;
|
|
7410
|
+
this.page = 1;
|
|
7411
|
+
}
|
|
7412
|
+
this.searchValue = value;
|
|
7413
|
+
await this.refresh(true);
|
|
7414
|
+
}
|
|
7415
|
+
else {
|
|
7416
|
+
this.loadMoreData = true;
|
|
7417
|
+
this.searchValue = value;
|
|
7418
|
+
if (value === undefined)
|
|
7419
|
+
this.page = this.lastPage;
|
|
7420
|
+
await this.refresh(true);
|
|
7421
|
+
}
|
|
7422
|
+
}
|
|
7423
|
+
/**
|
|
7424
|
+
* @description Handles filter events from the filter component.
|
|
7425
|
+
* @summary Processes filter queries from the filter component and applies them
|
|
7426
|
+
* to the list data. This method acts as a bridge between the filter component
|
|
7427
|
+
* and the search functionality, converting filter queries into search operations.
|
|
7627
7428
|
*
|
|
7429
|
+
* @param {IFilterQuery | undefined} value - The filter query object or undefined to clear filters
|
|
7430
|
+
* @returns {Promise<void>}
|
|
7628
7431
|
* @memberOf ListComponent
|
|
7629
7432
|
*/
|
|
7630
|
-
async
|
|
7631
|
-
|
|
7632
|
-
this.observerSubjet.pipe(debounceTime(100)).subscribe(args => this.handleObserveEvent(args[0], args[1], args[2]));
|
|
7633
|
-
this.enableFilter = stringToBoolean(this.enableFilter);
|
|
7634
|
-
this.limit = Number(this.limit);
|
|
7635
|
-
this.start = Number(this.start);
|
|
7636
|
-
this.inset = stringToBoolean(this.inset);
|
|
7637
|
-
this.showRefresher = stringToBoolean(this.showRefresher);
|
|
7638
|
-
this.loadMoreData = stringToBoolean(this.loadMoreData);
|
|
7639
|
-
this.showSearchbar = stringToBoolean(this.showSearchbar);
|
|
7640
|
-
this.disableSort = stringToBoolean(this.disableSort);
|
|
7641
|
-
if (typeof this.item?.['tag'] === 'boolean' && this.item?.['tag'] === true)
|
|
7642
|
-
this.item['tag'] = ComponentsTagNames.LIST_ITEM;
|
|
7643
|
-
await this.refresh();
|
|
7644
|
-
if (this.operations.includes(OperationKeys.CREATE) && this.route)
|
|
7645
|
-
this.empty.link = `${this.route}/${OperationKeys.CREATE}`;
|
|
7646
|
-
await this.initialize();
|
|
7647
|
-
if (this.model instanceof Model && this._repository)
|
|
7648
|
-
this._repository.observe(this.observer);
|
|
7433
|
+
async handleFilter(value) {
|
|
7434
|
+
await this.handleSearch(value);
|
|
7649
7435
|
}
|
|
7650
7436
|
/**
|
|
7651
|
-
* @description
|
|
7652
|
-
* @summary
|
|
7653
|
-
* This
|
|
7437
|
+
* @description Clears the current search and resets the list.
|
|
7438
|
+
* @summary Convenience method that clears the search by calling handleSearch
|
|
7439
|
+
* with undefined. This resets the list to show all data without filtering.
|
|
7440
|
+
*
|
|
7441
|
+
* @returns {Promise<void>}
|
|
7442
|
+
* @memberOf ListComponent
|
|
7443
|
+
*/
|
|
7444
|
+
async clearSearch() {
|
|
7445
|
+
await this.handleSearch(undefined);
|
|
7446
|
+
}
|
|
7447
|
+
/**
|
|
7448
|
+
* @description Emits a refresh event with the current data.
|
|
7449
|
+
* @summary Creates and emits a refresh event containing the current list data.
|
|
7450
|
+
* This notifies parent components that the list data has been refreshed.
|
|
7654
7451
|
*
|
|
7452
|
+
* @param {KeyValue[]} [data] - Optional data to include in the event
|
|
7655
7453
|
* @returns {void}
|
|
7454
|
+
*
|
|
7656
7455
|
* @memberOf ListComponent
|
|
7657
7456
|
*/
|
|
7658
|
-
|
|
7659
|
-
if (
|
|
7660
|
-
this.
|
|
7661
|
-
this.
|
|
7457
|
+
refreshEventEmit(data) {
|
|
7458
|
+
if (!data)
|
|
7459
|
+
data = this.items;
|
|
7460
|
+
this.skeletonData = new Array(data?.length || 2);
|
|
7461
|
+
this.refreshEvent.emit({
|
|
7462
|
+
name: EventConstants.REFRESH,
|
|
7463
|
+
data: data || [],
|
|
7464
|
+
component: this.componentName
|
|
7465
|
+
});
|
|
7662
7466
|
}
|
|
7663
7467
|
/**
|
|
7664
|
-
* @description
|
|
7665
|
-
* @summary Processes
|
|
7666
|
-
*
|
|
7667
|
-
*
|
|
7468
|
+
* @description Emits a click event for a list item.
|
|
7469
|
+
* @summary Processes and emits a click event when a list item is clicked.
|
|
7470
|
+
* This extracts the relevant data from the event and passes it to parent components.
|
|
7471
|
+
*
|
|
7472
|
+
* @private
|
|
7473
|
+
* @param {ListItemCustomEvent | RendererCustomEvent} event - The click event
|
|
7474
|
+
* @returns {void}
|
|
7668
7475
|
*
|
|
7669
|
-
* @param {...unknown[]} args - The repository event arguments including table, event type, and UID
|
|
7670
|
-
* @returns {Promise<void>}
|
|
7671
7476
|
* @memberOf ListComponent
|
|
7672
7477
|
*/
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
if (event === OperationKeys.CREATE && !!uid)
|
|
7676
|
-
return this.handleObserveEvent(table, event, uid);
|
|
7677
|
-
return this.observerSubjet.next(args);
|
|
7478
|
+
clickEventEmit(event) {
|
|
7479
|
+
this.clickEvent.emit(event);
|
|
7678
7480
|
}
|
|
7679
7481
|
/**
|
|
7680
|
-
* @description
|
|
7681
|
-
* @summary
|
|
7682
|
-
*
|
|
7683
|
-
*
|
|
7482
|
+
* @description Refreshes the list data from the configured source.
|
|
7483
|
+
* @summary This method handles both initial data loading and subsequent refresh operations,
|
|
7484
|
+
* including pull-to-refresh and infinite scrolling. It manages the data fetching process,
|
|
7485
|
+
* updates the component's state, and handles pagination or infinite scrolling logic based
|
|
7486
|
+
* on the component's configuration.
|
|
7487
|
+
*
|
|
7488
|
+
* The method performs the following steps:
|
|
7489
|
+
* 1. Sets the refreshing flag to indicate a data fetch is in progress
|
|
7490
|
+
* 2. Calculates the appropriate start and limit values based on pagination settings
|
|
7491
|
+
* 3. Fetches data from the appropriate source (model or request)
|
|
7492
|
+
* 4. Updates the component's data and emits a refresh event
|
|
7493
|
+
* 5. Handles pagination or infinite scrolling state updates
|
|
7494
|
+
* 6. Completes any provided event (like InfiniteScrollCustomEvent)
|
|
7495
|
+
*
|
|
7496
|
+
* @param {InfiniteScrollCustomEvent | RefresherCustomEvent | boolean} event - The event that triggered the refresh,
|
|
7497
|
+
* or a boolean flag indicating if this is a forced refresh
|
|
7498
|
+
* @returns {Promise<void>} A promise that resolves when the refresh operation is complete
|
|
7499
|
+
*
|
|
7500
|
+
* @mermaid
|
|
7501
|
+
* sequenceDiagram
|
|
7502
|
+
* participant L as ListComponent
|
|
7503
|
+
* participant D as Data Source
|
|
7504
|
+
* participant E as Event System
|
|
7505
|
+
*
|
|
7506
|
+
* L->>L: refresh(event)
|
|
7507
|
+
* L->>L: Set refreshing flag
|
|
7508
|
+
* L->>L: Calculate start and limit
|
|
7509
|
+
* alt Using model
|
|
7510
|
+
* L->>D: getFromModel(force, start, limit)
|
|
7511
|
+
* D-->>L: Return data
|
|
7512
|
+
* else Using request
|
|
7513
|
+
* L->>D: getFromRequest(force, start, limit)
|
|
7514
|
+
* D-->>L: Return data
|
|
7515
|
+
* end
|
|
7516
|
+
* L->>E: refreshEventEmit()
|
|
7517
|
+
* alt Infinite scrolling mode
|
|
7518
|
+
* L->>L: Check if reached last page
|
|
7519
|
+
* alt Last page reached
|
|
7520
|
+
* L->>L: Complete scroll event
|
|
7521
|
+
* L->>L: Disable loadMoreData
|
|
7522
|
+
* else More pages available
|
|
7523
|
+
* L->>L: Increment page number
|
|
7524
|
+
* L->>L: Complete scroll event after delay
|
|
7525
|
+
* end
|
|
7526
|
+
* else Paginated mode
|
|
7527
|
+
* L->>L: Clear refreshing flag after delay
|
|
7528
|
+
* end
|
|
7684
7529
|
*
|
|
7685
|
-
* @param {string} table - The table/model name that changed
|
|
7686
|
-
* @param {OperationKeys} event - The type of operation (CREATE, UPDATE, DELETE)
|
|
7687
|
-
* @param {string | number} uid - The unique identifier of the affected item
|
|
7688
|
-
* @returns {Promise<void>}
|
|
7689
7530
|
* @memberOf ListComponent
|
|
7690
7531
|
*/
|
|
7691
|
-
async
|
|
7692
|
-
if
|
|
7693
|
-
|
|
7694
|
-
|
|
7532
|
+
async refresh(event = false) {
|
|
7533
|
+
// if(typeof force !== 'boolean' && force.type === EventConstants.BACK_BUTTON_NAVIGATION) {
|
|
7534
|
+
// const {refresh} = (force as CustomEvent).detail;
|
|
7535
|
+
// if(!refresh)
|
|
7536
|
+
// return false;
|
|
7537
|
+
// }
|
|
7538
|
+
this.refreshing = true;
|
|
7539
|
+
const start = this.page > 1 ? (this.page - 1) * this.limit : this.start;
|
|
7540
|
+
const limit = (this.page * (this.limit > 12 ? 12 : this.limit));
|
|
7541
|
+
this.data = !this.model ?
|
|
7542
|
+
await this.getFromRequest(!!event, start, limit)
|
|
7543
|
+
: await this.getFromModel(!!event);
|
|
7544
|
+
this.refreshEventEmit();
|
|
7545
|
+
if (this.type === ListComponentsTypes.INFINITE) {
|
|
7546
|
+
if (this.page === this.pages) {
|
|
7547
|
+
if (event?.target)
|
|
7548
|
+
event.target.complete();
|
|
7549
|
+
this.loadMoreData = false;
|
|
7695
7550
|
}
|
|
7696
7551
|
else {
|
|
7697
|
-
|
|
7552
|
+
this.page += 1;
|
|
7553
|
+
this.refreshing = false;
|
|
7554
|
+
setTimeout(() => {
|
|
7555
|
+
if (event?.target && event?.type !== EventConstants.BACK_BUTTON_NAVIGATION)
|
|
7556
|
+
event.target.complete();
|
|
7557
|
+
}, 200);
|
|
7698
7558
|
}
|
|
7699
7559
|
}
|
|
7700
7560
|
else {
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
this.handleDelete(uid);
|
|
7705
|
-
this.refreshEventEmit();
|
|
7561
|
+
setTimeout(() => {
|
|
7562
|
+
this.refreshing = false;
|
|
7563
|
+
}, 200);
|
|
7706
7564
|
}
|
|
7707
7565
|
}
|
|
7708
7566
|
/**
|
|
7709
|
-
|
|
7710
|
-
|
|
7711
|
-
|
|
7712
|
-
|
|
7567
|
+
* @description Handles pagination events from the pagination component.
|
|
7568
|
+
* @summary Processes pagination events by updating the current page number and
|
|
7569
|
+
* refreshing the list data to display the selected page. This method is called
|
|
7570
|
+
* when a user interacts with the pagination controls to navigate between pages.
|
|
7571
|
+
*
|
|
7572
|
+
* @param {PaginationCustomEvent} event - The pagination event containing page information
|
|
7573
|
+
* @returns {void}
|
|
7574
|
+
*
|
|
7575
|
+
* @memberOf ListComponent
|
|
7576
|
+
*/
|
|
7577
|
+
handlePaginate(event) {
|
|
7578
|
+
const { page } = event.data;
|
|
7579
|
+
this.page = page;
|
|
7580
|
+
this.refresh(true);
|
|
7581
|
+
}
|
|
7582
|
+
/**
|
|
7583
|
+
* @description Handles pull-to-refresh events from the refresher component.
|
|
7584
|
+
* @summary Processes refresh events triggered by the user pulling down on the list
|
|
7585
|
+
* or by programmatic refresh requests. This method refreshes the list data and
|
|
7586
|
+
* completes the refresher animation when the data is loaded.
|
|
7713
7587
|
*
|
|
7714
|
-
*
|
|
7715
|
-
*
|
|
7716
|
-
* is the union of the `uid` of the item with the model name.
|
|
7588
|
+
* @param {InfiniteScrollCustomEvent | CustomEvent} [event] - The refresh event
|
|
7589
|
+
* @returns {Promise<void>} A promise that resolves when the refresh operation is complete
|
|
7717
7590
|
*
|
|
7718
|
-
* @param {number} index - The index of the item in the list.
|
|
7719
|
-
|
|
7720
|
-
* @param {KeyValue | string | number} item - The actual item from the list.
|
|
7721
|
-
* @returns {string | number} The tracking key for the item.
|
|
7722
7591
|
* @memberOf ListComponent
|
|
7723
7592
|
*/
|
|
7724
|
-
|
|
7725
|
-
|
|
7593
|
+
async handleRefresh(event) {
|
|
7594
|
+
await this.refresh(event || true);
|
|
7595
|
+
if (event instanceof CustomEvent)
|
|
7596
|
+
setTimeout(() => {
|
|
7597
|
+
// Any calls to load data go here
|
|
7598
|
+
event.target.complete();
|
|
7599
|
+
}, 400);
|
|
7726
7600
|
}
|
|
7727
7601
|
/**
|
|
7728
|
-
*
|
|
7602
|
+
* @description Filters data based on a search string.
|
|
7603
|
+
* @summary Processes the current data array to find items that match the provided
|
|
7604
|
+
* search string. This uses the arrayQueryByString utility to perform the filtering
|
|
7605
|
+
* across all properties of the items.
|
|
7729
7606
|
*
|
|
7730
|
-
* @param {
|
|
7731
|
-
* @
|
|
7732
|
-
|
|
7733
|
-
async handleCreate(uid) {
|
|
7734
|
-
const result = await this._repository?.read(uid);
|
|
7735
|
-
const item = this.mapResults([result])[0];
|
|
7736
|
-
this.items = this.data = [item, ...this.items || []];
|
|
7737
|
-
}
|
|
7738
|
-
/**
|
|
7739
|
-
* @description Handles the update event from the repository.
|
|
7740
|
-
* @summary Updates the list item with the specified ID based on the new data.
|
|
7607
|
+
* @param {KeyValue[]} results - The array of items to search through
|
|
7608
|
+
* @param {string} search - The search string to filter by
|
|
7609
|
+
* @returns {KeyValue[]} A promise that resolves to the filtered array of items
|
|
7741
7610
|
*
|
|
7742
|
-
* @param {string | number} uid - The ID of the item to update
|
|
7743
|
-
* @returns {Promise<void>}
|
|
7744
|
-
* @private
|
|
7745
7611
|
* @memberOf ListComponent
|
|
7746
7612
|
*/
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
this.data = [];
|
|
7750
|
-
for (const key in this.items) {
|
|
7751
|
-
const child = this.items[key];
|
|
7752
|
-
if (child['uid'] === item['uid']) {
|
|
7753
|
-
this.items[key] = Object.assign({}, child, item);
|
|
7754
|
-
break;
|
|
7755
|
-
}
|
|
7756
|
-
}
|
|
7757
|
-
setTimeout(() => {
|
|
7758
|
-
this.data = [...this.items];
|
|
7759
|
-
}, 0);
|
|
7613
|
+
parseSearchResults(results, search) {
|
|
7614
|
+
return results.filter((item) => Object.values(item).some(value => value.toString().toLowerCase().includes(search?.toLowerCase())));
|
|
7760
7615
|
}
|
|
7761
7616
|
/**
|
|
7762
|
-
* @description
|
|
7763
|
-
* @summary
|
|
7764
|
-
*
|
|
7617
|
+
* @description Fetches data from a request source.
|
|
7618
|
+
* @summary Retrieves data from the configured source function or URL, processes it,
|
|
7619
|
+
* and updates the component's data state. This method handles both initial data loading
|
|
7620
|
+
* and subsequent refresh operations when using an external data source rather than a model.
|
|
7765
7621
|
*
|
|
7766
|
-
* @param {
|
|
7767
|
-
* @param {
|
|
7768
|
-
* @
|
|
7622
|
+
* @param {boolean} force - Whether to force a refresh even if data already exists
|
|
7623
|
+
* @param {number} start - The starting index for pagination
|
|
7624
|
+
* @param {number} limit - The maximum number of items to retrieve
|
|
7625
|
+
* @returns {Promise<KeyValue[]>} A promise that resolves to the fetched data
|
|
7769
7626
|
*
|
|
7770
7627
|
* @memberOf ListComponent
|
|
7771
7628
|
*/
|
|
7772
|
-
|
|
7773
|
-
|
|
7774
|
-
|
|
7775
|
-
|
|
7629
|
+
async getFromRequest(force = false, start, limit) {
|
|
7630
|
+
let request = [];
|
|
7631
|
+
if (!this.data?.length || force || this.searchValue?.length || !!this.searchValue) {
|
|
7632
|
+
// (self.data as ListItem[]) = [];
|
|
7633
|
+
if (!this.searchValue?.length && !this.searchValue) {
|
|
7634
|
+
if (!this.source && !this.data?.length) {
|
|
7635
|
+
this.logger.info('No data and source passed to infinite list');
|
|
7636
|
+
return [];
|
|
7637
|
+
}
|
|
7638
|
+
if (this.source instanceof Function)
|
|
7639
|
+
request = await this.source();
|
|
7640
|
+
if (!Array.isArray(request))
|
|
7641
|
+
request = request?.['response']?.['data'] || request?.['results'] || [];
|
|
7642
|
+
this.data = [...await this.parseResult(request)];
|
|
7643
|
+
if (this.data?.length)
|
|
7644
|
+
this.items = this.type === ListComponentsTypes.INFINITE ?
|
|
7645
|
+
(this.items || []).concat([...this.data.slice(start, limit)]) : [...request.slice(start, limit)];
|
|
7646
|
+
}
|
|
7647
|
+
else {
|
|
7648
|
+
this.data = this.parseSearchResults(this.data, this.searchValue);
|
|
7649
|
+
this.items = this.data;
|
|
7650
|
+
}
|
|
7651
|
+
}
|
|
7652
|
+
if (this.loadMoreData && this.type === ListComponentsTypes.PAGINATED)
|
|
7653
|
+
this.getMoreData(this.data?.length || 0);
|
|
7654
|
+
return this.data || [];
|
|
7776
7655
|
}
|
|
7777
7656
|
/**
|
|
7778
|
-
* @description
|
|
7779
|
-
* @summary
|
|
7780
|
-
*
|
|
7781
|
-
*
|
|
7657
|
+
* @description Fetches data from a model source.
|
|
7658
|
+
* @summary Retrieves data from the configured model using its pagination or find methods,
|
|
7659
|
+
* processes it, and updates the component's data state. This method handles both initial
|
|
7660
|
+
* data loading and subsequent refresh operations when using a model as the data source.
|
|
7782
7661
|
*
|
|
7783
|
-
* @param {
|
|
7784
|
-
* @
|
|
7662
|
+
* @param {boolean} force - Whether to force a refresh even if data already exists
|
|
7663
|
+
* @param {number} start - The starting index for pagination
|
|
7664
|
+
* @param {number} limit - The maximum number of items to retrieve
|
|
7665
|
+
* @returns {Promise<KeyValue[]>} A promise that resolves to the fetched data
|
|
7785
7666
|
*
|
|
7786
7667
|
* @memberOf ListComponent
|
|
7787
7668
|
*/
|
|
7788
|
-
|
|
7789
|
-
this.
|
|
7669
|
+
async getFromModel(force = false) {
|
|
7670
|
+
let data = [...this.data || []];
|
|
7671
|
+
let request = [];
|
|
7672
|
+
// getting model repository
|
|
7673
|
+
if (!this._repository)
|
|
7674
|
+
this._repository = this.repository;
|
|
7675
|
+
const repo = this._repository;
|
|
7676
|
+
if (!this.data?.length || force || this.searchValue?.length || !!this.searchValue) {
|
|
7677
|
+
try {
|
|
7678
|
+
if (!this.searchValue?.length && !this.searchValue) {
|
|
7679
|
+
this.data = [];
|
|
7680
|
+
// const rawQuery = this.parseQuery(self.model as Repository<Model>, start, limit);
|
|
7681
|
+
// request = this.parseResult(await (this.model as any)?.paginate(start, limit));
|
|
7682
|
+
if (!this.paginator) {
|
|
7683
|
+
this.paginator = await repo
|
|
7684
|
+
.select()
|
|
7685
|
+
.orderBy([this.pk, this.sortDirection])
|
|
7686
|
+
.paginate(this.limit);
|
|
7687
|
+
}
|
|
7688
|
+
request = await this.parseResult(this.paginator);
|
|
7689
|
+
}
|
|
7690
|
+
else {
|
|
7691
|
+
if (!this.indexes)
|
|
7692
|
+
this.indexes = (Object.values(this.mapper) || [this.pk]);
|
|
7693
|
+
const condition = this.parseConditions(this.searchValue);
|
|
7694
|
+
request = await this.parseResult(await repo.query(condition, (this.sortBy || this.pk), this.sortDirection));
|
|
7695
|
+
data = [];
|
|
7696
|
+
}
|
|
7697
|
+
data = this.type === ListComponentsTypes.INFINITE ? [...(data).concat(request)] : [...request];
|
|
7698
|
+
}
|
|
7699
|
+
catch (error) {
|
|
7700
|
+
this.logger.error(error?.message || `Unable to find ${this.model} on registry. Return empty array from component`);
|
|
7701
|
+
}
|
|
7702
|
+
}
|
|
7703
|
+
if (data?.length) {
|
|
7704
|
+
if (this.searchValue) {
|
|
7705
|
+
this.items = [...data];
|
|
7706
|
+
if (this.items?.length <= this.limit)
|
|
7707
|
+
this.loadMoreData = false;
|
|
7708
|
+
}
|
|
7709
|
+
else {
|
|
7710
|
+
this.items = [...data];
|
|
7711
|
+
}
|
|
7712
|
+
}
|
|
7713
|
+
if (this.type === ListComponentsTypes.PAGINATED && this.paginator)
|
|
7714
|
+
this.getMoreData(this.paginator.total);
|
|
7715
|
+
return data || [];
|
|
7790
7716
|
}
|
|
7791
7717
|
/**
|
|
7792
|
-
* @description
|
|
7793
|
-
* @summary
|
|
7794
|
-
*
|
|
7795
|
-
*
|
|
7718
|
+
* @description Converts search values or filter queries into database conditions.
|
|
7719
|
+
* @summary Transforms search input or complex filter queries into Condition objects
|
|
7720
|
+
* that can be used for database querying. Handles both simple string/number searches
|
|
7721
|
+
* across indexed fields and complex filter queries with multiple criteria.
|
|
7796
7722
|
*
|
|
7797
|
-
*
|
|
7798
|
-
*
|
|
7723
|
+
* For simple searches (string/number):
|
|
7724
|
+
* - Creates conditions that search across all indexed fields
|
|
7725
|
+
* - Uses equality for numeric values and regex for string values
|
|
7726
|
+
* - Combines conditions with OR logic to search multiple fields
|
|
7799
7727
|
*
|
|
7800
|
-
*
|
|
7801
|
-
*
|
|
7802
|
-
*
|
|
7803
|
-
*
|
|
7804
|
-
*
|
|
7805
|
-
* C --> E{Search value undefined?}
|
|
7806
|
-
* E -->|Yes| F[Enable loadMoreData]
|
|
7807
|
-
* E -->|No| G[Store search value]
|
|
7808
|
-
* D --> G
|
|
7809
|
-
* F --> H[Reset page to 1]
|
|
7810
|
-
* G --> I[Refresh data]
|
|
7811
|
-
* H --> I
|
|
7728
|
+
* For complex filter queries:
|
|
7729
|
+
* - Processes each filter item with its specific condition type
|
|
7730
|
+
* - Supports Equal, Not Equal, Contains, Not Contains, Greater Than, Less Than
|
|
7731
|
+
* - Updates sort configuration based on the filter query
|
|
7732
|
+
* - Combines multiple filter conditions with OR logic
|
|
7812
7733
|
*
|
|
7734
|
+
* @param {string | number | IFilterQuery} value - The search value or filter query object
|
|
7735
|
+
* @returns {Condition<Model>} A Condition object for database querying
|
|
7813
7736
|
* @memberOf ListComponent
|
|
7814
7737
|
*/
|
|
7815
|
-
|
|
7816
|
-
|
|
7817
|
-
|
|
7818
|
-
|
|
7819
|
-
|
|
7820
|
-
this.
|
|
7738
|
+
parseConditions(value) {
|
|
7739
|
+
let _condition;
|
|
7740
|
+
if (typeof value === Primitives.STRING || typeof value === Primitives.NUMBER) {
|
|
7741
|
+
_condition = Condition.attribute(this.pk).eq(!isNaN(value) ? Number(value) : value);
|
|
7742
|
+
for (const index of this.indexes) {
|
|
7743
|
+
if (index === this.pk)
|
|
7744
|
+
continue;
|
|
7745
|
+
let orCondition;
|
|
7746
|
+
if (!isNaN(value)) {
|
|
7747
|
+
orCondition = Condition.attribute(index).eq(Number(value));
|
|
7748
|
+
}
|
|
7749
|
+
else {
|
|
7750
|
+
orCondition = Condition.attribute(index).regexp(value);
|
|
7751
|
+
}
|
|
7752
|
+
_condition = _condition.or(orCondition);
|
|
7821
7753
|
}
|
|
7822
|
-
this.searchValue = value;
|
|
7823
|
-
await this.refresh(true);
|
|
7824
7754
|
}
|
|
7825
7755
|
else {
|
|
7826
|
-
|
|
7827
|
-
|
|
7828
|
-
if (
|
|
7829
|
-
|
|
7830
|
-
|
|
7756
|
+
const { query, sort } = value;
|
|
7757
|
+
_condition = Condition.attribute(this.pk).dif('null');
|
|
7758
|
+
if (query?.length)
|
|
7759
|
+
_condition = undefined;
|
|
7760
|
+
(query || []).forEach((item) => {
|
|
7761
|
+
const { value, condition, index } = item;
|
|
7762
|
+
let val = value;
|
|
7763
|
+
if (index === this.pk || !isNaN(val))
|
|
7764
|
+
val = Number(val);
|
|
7765
|
+
let orCondition;
|
|
7766
|
+
switch (condition) {
|
|
7767
|
+
case "Equal":
|
|
7768
|
+
orCondition = Condition.attribute(index).eq(val);
|
|
7769
|
+
break;
|
|
7770
|
+
case "Not Equal":
|
|
7771
|
+
orCondition = Condition.attribute(index).dif(val);
|
|
7772
|
+
break;
|
|
7773
|
+
case "Not Contains":
|
|
7774
|
+
orCondition = !Condition.attribute(index).regexp(new RegExp(`^(?!.*${val}).*$`));
|
|
7775
|
+
break;
|
|
7776
|
+
case "Contains":
|
|
7777
|
+
orCondition = Condition.attribute(index).regexp(val);
|
|
7778
|
+
break;
|
|
7779
|
+
case "Greater Than":
|
|
7780
|
+
orCondition = Condition.attribute(index).gte(val);
|
|
7781
|
+
break;
|
|
7782
|
+
case "Less Than":
|
|
7783
|
+
orCondition = Condition.attribute(index).lte(val);
|
|
7784
|
+
break;
|
|
7785
|
+
}
|
|
7786
|
+
_condition = (!_condition ?
|
|
7787
|
+
orCondition : _condition.and(orCondition));
|
|
7788
|
+
});
|
|
7789
|
+
this.sortBy = sort?.value || this.pk;
|
|
7790
|
+
this.sortDirection = sort?.direction || this.sortDirection;
|
|
7831
7791
|
}
|
|
7792
|
+
return _condition;
|
|
7832
7793
|
}
|
|
7833
7794
|
/**
|
|
7834
|
-
* @description
|
|
7835
|
-
* @summary
|
|
7836
|
-
*
|
|
7837
|
-
*
|
|
7838
|
-
*
|
|
7839
|
-
* @param {IFilterQuery | undefined} value - The filter query object or undefined to clear filters
|
|
7840
|
-
* @returns {Promise<void>}
|
|
7841
|
-
* @memberOf ListComponent
|
|
7842
|
-
*/
|
|
7843
|
-
async handleFilter(value) {
|
|
7844
|
-
await this.handleSearch(value);
|
|
7845
|
-
}
|
|
7846
|
-
/**
|
|
7847
|
-
* @description Clears the current search and resets the list.
|
|
7848
|
-
* @summary Convenience method that clears the search by calling handleSearch
|
|
7849
|
-
* with undefined. This resets the list to show all data without filtering.
|
|
7850
|
-
*
|
|
7851
|
-
* @returns {Promise<void>}
|
|
7852
|
-
* @memberOf ListComponent
|
|
7853
|
-
*/
|
|
7854
|
-
async clearSearch() {
|
|
7855
|
-
await this.handleSearch(undefined);
|
|
7856
|
-
}
|
|
7857
|
-
/**
|
|
7858
|
-
* @description Emits a refresh event with the current data.
|
|
7859
|
-
* @summary Creates and emits a refresh event containing the current list data.
|
|
7860
|
-
* This notifies parent components that the list data has been refreshed.
|
|
7795
|
+
* @description Processes query results into a standardized format.
|
|
7796
|
+
* @summary Handles different result formats from various data sources, extracting
|
|
7797
|
+
* pagination information when available and applying any configured data mapping.
|
|
7798
|
+
* This ensures consistent data structure regardless of the source.
|
|
7861
7799
|
*
|
|
7862
|
-
* @
|
|
7863
|
-
* @
|
|
7800
|
+
* @protected
|
|
7801
|
+
* @param {KeyValue[] | Paginator} result - The raw query result
|
|
7802
|
+
* @returns {KeyValue[]} The processed array of items
|
|
7864
7803
|
*
|
|
7865
7804
|
* @memberOf ListComponent
|
|
7866
7805
|
*/
|
|
7867
|
-
|
|
7868
|
-
if (!
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7806
|
+
async parseResult(result) {
|
|
7807
|
+
if (!Array.isArray(result) && ('page' in result && 'total' in result)) {
|
|
7808
|
+
const paginator = result;
|
|
7809
|
+
try {
|
|
7810
|
+
result = await paginator.page(this.page);
|
|
7811
|
+
// TODO: Chage for result.total;
|
|
7812
|
+
this.getMoreData(paginator.total);
|
|
7813
|
+
}
|
|
7814
|
+
catch (error) {
|
|
7815
|
+
this.logger.info(error?.message || 'Unable to get page from paginator. Return empty array from component');
|
|
7816
|
+
result = [];
|
|
7817
|
+
}
|
|
7818
|
+
}
|
|
7819
|
+
else {
|
|
7820
|
+
this.getMoreData(result?.length || 0);
|
|
7821
|
+
}
|
|
7822
|
+
return (Object.keys(this.mapper || {}).length) ?
|
|
7823
|
+
this.mapResults(result) : result;
|
|
7876
7824
|
}
|
|
7877
7825
|
/**
|
|
7878
|
-
* @description
|
|
7879
|
-
* @summary
|
|
7880
|
-
*
|
|
7826
|
+
* @description Updates pagination state based on data length.
|
|
7827
|
+
* @summary Calculates whether more data is available and how many pages exist
|
|
7828
|
+
* based on the total number of items and the configured limit per page.
|
|
7829
|
+
* This information is used to control pagination UI and infinite scrolling behavior.
|
|
7881
7830
|
*
|
|
7882
|
-
* @
|
|
7883
|
-
* @param {ListItemCustomEvent | RendererCustomEvent} event - The click event
|
|
7831
|
+
* @param {number} length - The total number of items available
|
|
7884
7832
|
* @returns {void}
|
|
7885
7833
|
*
|
|
7886
7834
|
* @memberOf ListComponent
|
|
7887
7835
|
*/
|
|
7888
|
-
|
|
7889
|
-
this.clickEvent.emit(event);
|
|
7890
|
-
}
|
|
7891
|
-
/**
|
|
7892
|
-
* @description Refreshes the list data from the configured source.
|
|
7893
|
-
* @summary This method handles both initial data loading and subsequent refresh operations,
|
|
7894
|
-
* including pull-to-refresh and infinite scrolling. It manages the data fetching process,
|
|
7895
|
-
* updates the component's state, and handles pagination or infinite scrolling logic based
|
|
7896
|
-
* on the component's configuration.
|
|
7897
|
-
*
|
|
7898
|
-
* The method performs the following steps:
|
|
7899
|
-
* 1. Sets the refreshing flag to indicate a data fetch is in progress
|
|
7900
|
-
* 2. Calculates the appropriate start and limit values based on pagination settings
|
|
7901
|
-
* 3. Fetches data from the appropriate source (model or request)
|
|
7902
|
-
* 4. Updates the component's data and emits a refresh event
|
|
7903
|
-
* 5. Handles pagination or infinite scrolling state updates
|
|
7904
|
-
* 6. Completes any provided event (like InfiniteScrollCustomEvent)
|
|
7905
|
-
*
|
|
7906
|
-
* @param {InfiniteScrollCustomEvent | RefresherCustomEvent | boolean} event - The event that triggered the refresh,
|
|
7907
|
-
* or a boolean flag indicating if this is a forced refresh
|
|
7908
|
-
* @returns {Promise<void>} A promise that resolves when the refresh operation is complete
|
|
7909
|
-
*
|
|
7910
|
-
* @mermaid
|
|
7911
|
-
* sequenceDiagram
|
|
7912
|
-
* participant L as ListComponent
|
|
7913
|
-
* participant D as Data Source
|
|
7914
|
-
* participant E as Event System
|
|
7915
|
-
*
|
|
7916
|
-
* L->>L: refresh(event)
|
|
7917
|
-
* L->>L: Set refreshing flag
|
|
7918
|
-
* L->>L: Calculate start and limit
|
|
7919
|
-
* alt Using model
|
|
7920
|
-
* L->>D: getFromModel(force, start, limit)
|
|
7921
|
-
* D-->>L: Return data
|
|
7922
|
-
* else Using request
|
|
7923
|
-
* L->>D: getFromRequest(force, start, limit)
|
|
7924
|
-
* D-->>L: Return data
|
|
7925
|
-
* end
|
|
7926
|
-
* L->>E: refreshEventEmit()
|
|
7927
|
-
* alt Infinite scrolling mode
|
|
7928
|
-
* L->>L: Check if reached last page
|
|
7929
|
-
* alt Last page reached
|
|
7930
|
-
* L->>L: Complete scroll event
|
|
7931
|
-
* L->>L: Disable loadMoreData
|
|
7932
|
-
* else More pages available
|
|
7933
|
-
* L->>L: Increment page number
|
|
7934
|
-
* L->>L: Complete scroll event after delay
|
|
7935
|
-
* end
|
|
7936
|
-
* else Paginated mode
|
|
7937
|
-
* L->>L: Clear refreshing flag after delay
|
|
7938
|
-
* end
|
|
7939
|
-
*
|
|
7940
|
-
* @memberOf ListComponent
|
|
7941
|
-
*/
|
|
7942
|
-
async refresh(event = false) {
|
|
7943
|
-
// if(typeof force !== 'boolean' && force.type === EventConstants.BACK_BUTTON_NAVIGATION) {
|
|
7944
|
-
// const {refresh} = (force as CustomEvent).detail;
|
|
7945
|
-
// if(!refresh)
|
|
7946
|
-
// return false;
|
|
7947
|
-
// }
|
|
7948
|
-
this.refreshing = true;
|
|
7949
|
-
const start = this.page > 1 ? (this.page - 1) * this.limit : this.start;
|
|
7950
|
-
const limit = (this.page * (this.limit > 12 ? 12 : this.limit));
|
|
7951
|
-
this.data = !this.model ?
|
|
7952
|
-
await this.getFromRequest(!!event, start, limit)
|
|
7953
|
-
: await this.getFromModel(!!event);
|
|
7954
|
-
this.refreshEventEmit();
|
|
7836
|
+
getMoreData(length) {
|
|
7955
7837
|
if (this.type === ListComponentsTypes.INFINITE) {
|
|
7956
|
-
if (this.
|
|
7957
|
-
|
|
7958
|
-
|
|
7838
|
+
if (this.paginator)
|
|
7839
|
+
length = length * this.limit;
|
|
7840
|
+
if (length <= this.limit) {
|
|
7959
7841
|
this.loadMoreData = false;
|
|
7960
7842
|
}
|
|
7961
7843
|
else {
|
|
7962
|
-
this.
|
|
7963
|
-
this.
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
}, 200);
|
|
7844
|
+
this.pages = Math.floor(length / this.limit);
|
|
7845
|
+
if ((this.pages * this.limit) < length)
|
|
7846
|
+
this.pages += 1;
|
|
7847
|
+
if (this.pages === 1)
|
|
7848
|
+
this.loadMoreData = false;
|
|
7968
7849
|
}
|
|
7969
7850
|
}
|
|
7970
7851
|
else {
|
|
7971
|
-
|
|
7972
|
-
|
|
7973
|
-
|
|
7852
|
+
this.pages = length;
|
|
7853
|
+
if (this.pages === 1)
|
|
7854
|
+
this.loadMoreData = false;
|
|
7974
7855
|
}
|
|
7975
7856
|
}
|
|
7976
7857
|
/**
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
7980
|
-
|
|
7981
|
-
*
|
|
7982
|
-
* @param {PaginationCustomEvent} event - The pagination event containing page information
|
|
7983
|
-
* @returns {void}
|
|
7984
|
-
*
|
|
7985
|
-
* @memberOf ListComponent
|
|
7986
|
-
*/
|
|
7987
|
-
handlePaginate(event) {
|
|
7988
|
-
const { page } = event.data;
|
|
7989
|
-
this.page = page;
|
|
7990
|
-
this.refresh(true);
|
|
7991
|
-
}
|
|
7992
|
-
/**
|
|
7993
|
-
* @description Handles pull-to-refresh events from the refresher component.
|
|
7994
|
-
* @summary Processes refresh events triggered by the user pulling down on the list
|
|
7995
|
-
* or by programmatic refresh requests. This method refreshes the list data and
|
|
7996
|
-
* completes the refresher animation when the data is loaded.
|
|
7858
|
+
* @description Maps a single item using the configured mapper.
|
|
7859
|
+
* @summary Transforms a data item according to the mapping configuration,
|
|
7860
|
+
* extracting nested properties and formatting values as needed. This allows
|
|
7861
|
+
* the component to display data in a format different from how it's stored.
|
|
7997
7862
|
*
|
|
7998
|
-
* @
|
|
7999
|
-
* @
|
|
7863
|
+
* @protected
|
|
7864
|
+
* @param {KeyValue} item - The item to map
|
|
7865
|
+
* @param {KeyValue} mapper - The mapping configuration
|
|
7866
|
+
* @param {KeyValue} [props] - Additional properties to include
|
|
7867
|
+
* @returns {KeyValue} The mapped item
|
|
8000
7868
|
*
|
|
8001
7869
|
* @memberOf ListComponent
|
|
8002
7870
|
*/
|
|
8003
|
-
|
|
8004
|
-
|
|
8005
|
-
|
|
8006
|
-
|
|
8007
|
-
|
|
8008
|
-
|
|
8009
|
-
|
|
7871
|
+
itemMapper(item, mapper, props) {
|
|
7872
|
+
return Object.entries(mapper).reduce((accum, [key, value]) => {
|
|
7873
|
+
const arrayValue = value.split('.');
|
|
7874
|
+
if (!value) {
|
|
7875
|
+
accum[key] = value;
|
|
7876
|
+
}
|
|
7877
|
+
else {
|
|
7878
|
+
if (arrayValue.length === 1) {
|
|
7879
|
+
value = item?.[value] ? item[value] : value !== key ? value : "";
|
|
7880
|
+
if (isValidDate(value))
|
|
7881
|
+
value = `${formatDate(value)}`;
|
|
7882
|
+
accum[key] = value;
|
|
7883
|
+
}
|
|
7884
|
+
else {
|
|
7885
|
+
let val;
|
|
7886
|
+
for (const _value of arrayValue)
|
|
7887
|
+
val = !val
|
|
7888
|
+
? item[_value]
|
|
7889
|
+
: (typeof val === 'string' ? JSON.parse(val) : val)[_value];
|
|
7890
|
+
if (isValidDate(new Date(val)))
|
|
7891
|
+
val = `${formatDate(val)}`;
|
|
7892
|
+
accum[key] = val === null || val === undefined ? value : val;
|
|
7893
|
+
}
|
|
7894
|
+
}
|
|
7895
|
+
return Object.assign({}, props || {}, accum);
|
|
7896
|
+
}, {});
|
|
8010
7897
|
}
|
|
8011
7898
|
/**
|
|
8012
|
-
* @description
|
|
8013
|
-
* @summary
|
|
8014
|
-
*
|
|
8015
|
-
*
|
|
7899
|
+
* @description Maps all result items using the configured mapper.
|
|
7900
|
+
* @summary Applies the itemMapper to each item in the result set, adding
|
|
7901
|
+
* common properties like operations and route information. This transforms
|
|
7902
|
+
* the raw data into the format expected by the list item components.
|
|
8016
7903
|
*
|
|
8017
|
-
* @param {KeyValue[]}
|
|
8018
|
-
* @
|
|
8019
|
-
* @returns {KeyValue[]} A promise that resolves to the filtered array of items
|
|
7904
|
+
* @param {KeyValue[]} data - The array of items to map
|
|
7905
|
+
* @returns {KeyValue[]} The array of mapped items
|
|
8020
7906
|
*
|
|
8021
7907
|
* @memberOf ListComponent
|
|
8022
7908
|
*/
|
|
8023
|
-
|
|
8024
|
-
|
|
7909
|
+
mapResults(data) {
|
|
7910
|
+
if (!data || !data.length)
|
|
7911
|
+
return [];
|
|
7912
|
+
// passing uid as prop to mapper
|
|
7913
|
+
this.mapper = { ...this.mapper, ...{ uid: this.pk } };
|
|
7914
|
+
const props = Object.assign({
|
|
7915
|
+
operations: this.operations,
|
|
7916
|
+
route: this.route,
|
|
7917
|
+
...Object.keys(this.item).reduce((acc, key) => {
|
|
7918
|
+
acc[key] = this.item[key];
|
|
7919
|
+
return acc;
|
|
7920
|
+
}, {}),
|
|
7921
|
+
// ... (!this.item.render ? {} : Object.keys(this.item).reduce((acc: KeyValue, key: string) => {
|
|
7922
|
+
// acc[key] = this.item[key as keyof IListItemProp];
|
|
7923
|
+
// return acc;
|
|
7924
|
+
// }, {}))
|
|
7925
|
+
});
|
|
7926
|
+
return data.reduce((accum, curr) => {
|
|
7927
|
+
accum.push({ ...this.itemMapper(curr, this.mapper, props), ...{ pk: this.pk } });
|
|
7928
|
+
return accum;
|
|
7929
|
+
}, []);
|
|
8025
7930
|
}
|
|
7931
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: ListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7932
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.2", type: ListComponent, isStandalone: true, selector: "ngx-decaf-list", inputs: { type: "type", translatable: "translatable", 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", emptyIcon: "emptyIcon", empty: "empty" }, outputs: { refreshEvent: "refreshEvent", clickEvent: "clickEvent" }, host: { listeners: { "window:ListItemClickEvent": "handleClick($event)", "window:searchbarEvent": "handleSearch($event)", "window:BackButtonNavigationEndEvent": "refresh($event)" } }, 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 && data?.length) {\n @if(model && enableFilter) {\n <ngx-decaf-filter\n [model]=\"model\"\n [sortDirection]=\"sortDirection\"\n [disableSort]=\"disableSort\"\n (filterEvent)=\"handleFilter($event)\"\n (searchEvent)=\"handleSearch($event)\"\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\" #component>\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(!searchValue?.length) {\n <ngx-decaf-empty-state\n [title]=\"(locale + '.'+ empty.title) | translate\"\n [subtitle]=\"(locale + '.'+ empty.subtitle) | translate\"\n [buttonText]=\"empty.showButton ? (locale + '.'+ empty.button | translate) : ''\"\n [buttonLink]=\"empty.showButton ? empty.route : ''\"\n />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n ngClass=\"empty-search\"\n [translatable]=\"true\"\n title=\"search.title\"\n subtitle=\"search.subtitle\"\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", "globals", "children", "model", "parent"], outputs: ["listenEvent"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
7933
|
+
};
|
|
7934
|
+
ListComponent = __decorate([
|
|
7935
|
+
Dynamic(),
|
|
7936
|
+
__metadata("design:paramtypes", [])
|
|
7937
|
+
], ListComponent);
|
|
7938
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: ListComponent, decorators: [{
|
|
7939
|
+
type: Component,
|
|
7940
|
+
args: [{ selector: 'ngx-decaf-list', standalone: true, imports: [
|
|
7941
|
+
TranslatePipe,
|
|
7942
|
+
IonRefresher,
|
|
7943
|
+
PaginationComponent,
|
|
7944
|
+
IonList,
|
|
7945
|
+
IonItem,
|
|
7946
|
+
IonThumbnail,
|
|
7947
|
+
IonSkeletonText,
|
|
7948
|
+
IonLabel,
|
|
7949
|
+
IonText,
|
|
7950
|
+
IonRefresherContent,
|
|
7951
|
+
IonInfiniteScroll,
|
|
7952
|
+
IonInfiniteScrollContent,
|
|
7953
|
+
IonThumbnail,
|
|
7954
|
+
IonSkeletonText,
|
|
7955
|
+
SearchbarComponent,
|
|
7956
|
+
EmptyStateComponent,
|
|
7957
|
+
FilterComponent,
|
|
7958
|
+
ComponentRendererComponent
|
|
7959
|
+
], 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 && data?.length) {\n @if(model && enableFilter) {\n <ngx-decaf-filter\n [model]=\"model\"\n [sortDirection]=\"sortDirection\"\n [disableSort]=\"disableSort\"\n (filterEvent)=\"handleFilter($event)\"\n (searchEvent)=\"handleSearch($event)\"\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\" #component>\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(!searchValue?.length) {\n <ngx-decaf-empty-state\n [title]=\"(locale + '.'+ empty.title) | translate\"\n [subtitle]=\"(locale + '.'+ empty.subtitle) | translate\"\n [buttonText]=\"empty.showButton ? (locale + '.'+ empty.button | translate) : ''\"\n [buttonLink]=\"empty.showButton ? empty.route : ''\"\n />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n ngClass=\"empty-search\"\n [translatable]=\"true\"\n title=\"search.title\"\n subtitle=\"search.subtitle\"\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"] }]
|
|
7960
|
+
}], ctorParameters: () => [], propDecorators: { type: [{
|
|
7961
|
+
type: Input
|
|
7962
|
+
}], translatable: [{
|
|
7963
|
+
type: Input
|
|
7964
|
+
}], showSearchbar: [{
|
|
7965
|
+
type: Input
|
|
7966
|
+
}], data: [{
|
|
7967
|
+
type: Input
|
|
7968
|
+
}], source: [{
|
|
7969
|
+
type: Input
|
|
7970
|
+
}], start: [{
|
|
7971
|
+
type: Input
|
|
7972
|
+
}], limit: [{
|
|
7973
|
+
type: Input
|
|
7974
|
+
}], loadMoreData: [{
|
|
7975
|
+
type: Input
|
|
7976
|
+
}], lines: [{
|
|
7977
|
+
type: Input
|
|
7978
|
+
}], inset: [{
|
|
7979
|
+
type: Input
|
|
7980
|
+
}], scrollThreshold: [{
|
|
7981
|
+
type: Input
|
|
7982
|
+
}], scrollPosition: [{
|
|
7983
|
+
type: Input
|
|
7984
|
+
}], loadingText: [{
|
|
7985
|
+
type: Input
|
|
7986
|
+
}], showRefresher: [{
|
|
7987
|
+
type: Input
|
|
7988
|
+
}], loadingSpinner: [{
|
|
7989
|
+
type: Input
|
|
7990
|
+
}], enableFilter: [{
|
|
7991
|
+
type: Input
|
|
7992
|
+
}], sortDirection: [{
|
|
7993
|
+
type: Input
|
|
7994
|
+
}], sortBy: [{
|
|
7995
|
+
type: Input
|
|
7996
|
+
}], disableSort: [{
|
|
7997
|
+
type: Input
|
|
7998
|
+
}], emptyIcon: [{
|
|
7999
|
+
type: Input
|
|
8000
|
+
}], empty: [{
|
|
8001
|
+
type: Input
|
|
8002
|
+
}], refreshEvent: [{
|
|
8003
|
+
type: Output
|
|
8004
|
+
}], clickEvent: [{
|
|
8005
|
+
type: Output
|
|
8006
|
+
}], handleClick: [{
|
|
8007
|
+
type: HostListener,
|
|
8008
|
+
args: ['window:ListItemClickEvent', ['$event']]
|
|
8009
|
+
}], handleSearch: [{
|
|
8010
|
+
type: HostListener,
|
|
8011
|
+
args: ['window:searchbarEvent', ['$event']]
|
|
8012
|
+
}], refresh: [{
|
|
8013
|
+
type: HostListener,
|
|
8014
|
+
args: ['window:BackButtonNavigationEndEvent', ['$event']]
|
|
8015
|
+
}] } });
|
|
8016
|
+
|
|
8017
|
+
/**
|
|
8018
|
+
* @description A component for displaying a list item with various customization options.
|
|
8019
|
+
* @summary The ListItemComponent is an Angular component that extends NgxBaseComponent. It provides a flexible and customizable list item interface with support for icons, buttons, and various text elements. The component also handles actions and navigation based on user interactions.
|
|
8020
|
+
*
|
|
8021
|
+
* @class
|
|
8022
|
+
* @extends NgxBaseComponent
|
|
8023
|
+
*
|
|
8024
|
+
* @param {string} [lines='none'] - Determines the line style of the item. Can be 'inset', 'inseet', or 'none'.
|
|
8025
|
+
* @param {Record<string, any>} item - The data item to be displayed in the list item.
|
|
8026
|
+
* @param {string} icon - The name of the icon to be displayed.
|
|
8027
|
+
* @param {'start' | 'end'} [iconSlot='start'] - The position of the icon within the item.
|
|
8028
|
+
* @param {StringOrBoolean} [button=true] - Determines if the item should behave as a button.
|
|
8029
|
+
* @param {string} [title] - The main title of the list item.
|
|
8030
|
+
* @param {string} [description] - A description for the list item.
|
|
8031
|
+
* @param {string} [info] - Additional information for the list item.
|
|
8032
|
+
* @param {string} [subinfo] - Sub-information for the list item.
|
|
8033
|
+
*
|
|
8034
|
+
* @example
|
|
8035
|
+
* <ngx-decaf-list-item
|
|
8036
|
+
* [item]="dataItem"
|
|
8037
|
+
* icon="star"
|
|
8038
|
+
* title="Item Title"
|
|
8039
|
+
* description="Item Description"
|
|
8040
|
+
* (clickEvent)="handleItemClick($event)">
|
|
8041
|
+
* </ngx-decaf-list-item>
|
|
8042
|
+
*
|
|
8043
|
+
* @mermaid
|
|
8044
|
+
* sequenceDiagram
|
|
8045
|
+
* participant C as Component
|
|
8046
|
+
* participant V as View
|
|
8047
|
+
* participant U as User
|
|
8048
|
+
* C->>V: Initialize component
|
|
8049
|
+
* V->>U: Display list item
|
|
8050
|
+
* U->>V: Click on item or action
|
|
8051
|
+
* V->>C: Trigger handleAction()
|
|
8052
|
+
* C->>C: Process action
|
|
8053
|
+
* C->>V: Update view or navigate
|
|
8054
|
+
*/
|
|
8055
|
+
let ListItemComponent = class ListItemComponent extends NgxBaseComponent {
|
|
8026
8056
|
/**
|
|
8027
|
-
* @description
|
|
8028
|
-
* @summary
|
|
8029
|
-
*
|
|
8030
|
-
*
|
|
8031
|
-
*
|
|
8032
|
-
* @param {boolean} force - Whether to force a refresh even if data already exists
|
|
8033
|
-
* @param {number} start - The starting index for pagination
|
|
8034
|
-
* @param {number} limit - The maximum number of items to retrieve
|
|
8035
|
-
* @returns {Promise<KeyValue[]>} A promise that resolves to the fetched data
|
|
8057
|
+
* @description Creates an instance of ListItemComponent.
|
|
8058
|
+
* @summary Initializes a new ListItemComponent by calling the parent class constructor
|
|
8059
|
+
* with the component name for logging and identification purposes. Also registers
|
|
8060
|
+
* all available Ionic icons to ensure they can be displayed in the component.
|
|
8036
8061
|
*
|
|
8037
|
-
* @memberOf
|
|
8062
|
+
* @memberOf ListItemComponent
|
|
8038
8063
|
*/
|
|
8039
|
-
|
|
8040
|
-
|
|
8041
|
-
|
|
8042
|
-
|
|
8043
|
-
|
|
8044
|
-
|
|
8045
|
-
|
|
8046
|
-
|
|
8047
|
-
|
|
8048
|
-
|
|
8049
|
-
|
|
8050
|
-
|
|
8051
|
-
|
|
8052
|
-
|
|
8053
|
-
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
|
|
8060
|
-
|
|
8061
|
-
|
|
8062
|
-
|
|
8063
|
-
|
|
8064
|
-
|
|
8064
|
+
constructor() {
|
|
8065
|
+
super("ListItemComponent");
|
|
8066
|
+
/**
|
|
8067
|
+
* @description Controls the display of lines around the list item.
|
|
8068
|
+
* @summary Determines how lines are displayed around the list item borders.
|
|
8069
|
+
* 'inset' shows lines with padding, 'full' shows full-width lines, and 'none'
|
|
8070
|
+
* removes all lines. This affects the visual separation between list items.
|
|
8071
|
+
*
|
|
8072
|
+
* @type {'inset' | 'full' | 'none'}
|
|
8073
|
+
* @default 'inset'
|
|
8074
|
+
* @memberOf ListItemComponent
|
|
8075
|
+
*/
|
|
8076
|
+
this.lines = 'full';
|
|
8077
|
+
/**
|
|
8078
|
+
* @description Position of the icon within the list item.
|
|
8079
|
+
* @summary Determines whether the icon appears at the start (left in LTR languages)
|
|
8080
|
+
* or end (right in LTR languages) of the list item. This affects the overall
|
|
8081
|
+
* layout and visual hierarchy of the item content.
|
|
8082
|
+
*
|
|
8083
|
+
* @type {'start' | 'end'}
|
|
8084
|
+
* @default 'start'
|
|
8085
|
+
* @memberOf ListItemComponent
|
|
8086
|
+
*/
|
|
8087
|
+
this.iconSlot = 'start';
|
|
8088
|
+
/**
|
|
8089
|
+
* @description Controls whether the list item behaves as a clickable button.
|
|
8090
|
+
* @summary When set to true, the list item will have button-like behavior including
|
|
8091
|
+
* hover effects, click handling, and appropriate accessibility attributes.
|
|
8092
|
+
* When false, the item is displayed as static content without interactive behavior.
|
|
8093
|
+
*
|
|
8094
|
+
* @type {StringOrBoolean}
|
|
8095
|
+
* @default true
|
|
8096
|
+
* @memberOf ListItemComponent
|
|
8097
|
+
*/
|
|
8098
|
+
this.button = true;
|
|
8099
|
+
/**
|
|
8100
|
+
* @description Event emitter for list item click interactions.
|
|
8101
|
+
* @summary Emits custom events when the list item is clicked or when actions
|
|
8102
|
+
* are performed on it. The emitted event contains information about the action,
|
|
8103
|
+
* the item data, and other relevant context for parent components to handle.
|
|
8104
|
+
*
|
|
8105
|
+
* @type {EventEmitter<ListItemCustomEvent>}
|
|
8106
|
+
* @memberOf ListItemComponent
|
|
8107
|
+
*/
|
|
8108
|
+
this.clickEvent = new EventEmitter();
|
|
8109
|
+
/**
|
|
8110
|
+
* @description Flag indicating whether slide items are currently enabled.
|
|
8111
|
+
* @summary Controls the visibility of slide actions based on screen size and
|
|
8112
|
+
* available operations. When true, users can swipe on the item to reveal
|
|
8113
|
+
* action buttons for operations like edit and delete.
|
|
8114
|
+
*
|
|
8115
|
+
* @type {boolean}
|
|
8116
|
+
* @default false
|
|
8117
|
+
* @memberOf ListItemComponent
|
|
8118
|
+
*/
|
|
8119
|
+
this.showSlideItems = false;
|
|
8120
|
+
/**
|
|
8121
|
+
* @description Flag indicating whether the action menu popover is currently open.
|
|
8122
|
+
* @summary Tracks the state of the action menu to prevent multiple instances
|
|
8123
|
+
* from being opened simultaneously and to ensure proper cleanup when actions
|
|
8124
|
+
* are performed. Used for managing the popover lifecycle.
|
|
8125
|
+
*
|
|
8126
|
+
* @type {boolean}
|
|
8127
|
+
* @default false
|
|
8128
|
+
* @memberOf ListItemComponent
|
|
8129
|
+
*/
|
|
8130
|
+
this.actionMenuOpen = false;
|
|
8131
|
+
/**
|
|
8132
|
+
* @description Angular NavController service for handling navigation.
|
|
8133
|
+
* @summary Injected service that provides methods for programmatic navigation
|
|
8134
|
+
* within the Ionic application. Used for navigating to different routes when
|
|
8135
|
+
* list item actions are performed or when the item itself is clicked.
|
|
8136
|
+
*
|
|
8137
|
+
* @private
|
|
8138
|
+
* @type {NavController}
|
|
8139
|
+
* @memberOf ListItemComponent
|
|
8140
|
+
*/
|
|
8141
|
+
this.navController = inject(NavController);
|
|
8142
|
+
addIcons(allIcons);
|
|
8065
8143
|
}
|
|
8066
8144
|
/**
|
|
8067
|
-
* @description
|
|
8068
|
-
* @summary
|
|
8069
|
-
*
|
|
8070
|
-
*
|
|
8145
|
+
* @description Initializes the component after Angular first displays the data-bound properties.
|
|
8146
|
+
* @summary Sets up the component by determining slide item visibility, processing boolean inputs,
|
|
8147
|
+
* building CSS class names based on properties, and capturing the current window width.
|
|
8148
|
+
* This method prepares the component for user interaction by ensuring all properties are
|
|
8149
|
+
* properly initialized and responsive behavior is configured.
|
|
8071
8150
|
*
|
|
8072
|
-
* @
|
|
8073
|
-
*
|
|
8074
|
-
*
|
|
8075
|
-
*
|
|
8151
|
+
* @mermaid
|
|
8152
|
+
* sequenceDiagram
|
|
8153
|
+
* participant A as Angular Lifecycle
|
|
8154
|
+
* participant L as ListItemComponent
|
|
8155
|
+
* participant W as Window
|
|
8076
8156
|
*
|
|
8077
|
-
*
|
|
8157
|
+
* A->>L: ngOnInit()
|
|
8158
|
+
* L->>L: enableSlideItems()
|
|
8159
|
+
* L->>L: Process button boolean
|
|
8160
|
+
* L->>L: Build className with flex classes
|
|
8161
|
+
* alt operations exist
|
|
8162
|
+
* L->>L: Add 'action' class
|
|
8163
|
+
* end
|
|
8164
|
+
* L->>W: getWindowWidth()
|
|
8165
|
+
* W-->>L: Return current width
|
|
8166
|
+
* L->>L: Store windowWidth
|
|
8167
|
+
*
|
|
8168
|
+
* @return {Promise<void>}
|
|
8169
|
+
* @memberOf ListItemComponent
|
|
8078
8170
|
*/
|
|
8079
|
-
async
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
if (
|
|
8084
|
-
this.
|
|
8085
|
-
|
|
8086
|
-
if (!this.data?.length || force || this.searchValue?.length || !!this.searchValue) {
|
|
8087
|
-
try {
|
|
8088
|
-
if (!this.searchValue?.length && !this.searchValue) {
|
|
8089
|
-
this.data = [];
|
|
8090
|
-
// const rawQuery = this.parseQuery(self.model as Repository<Model>, start, limit);
|
|
8091
|
-
// request = this.parseResult(await (this.model as any)?.paginate(start, limit));
|
|
8092
|
-
if (!this.paginator) {
|
|
8093
|
-
this.paginator = await repo
|
|
8094
|
-
.select()
|
|
8095
|
-
.orderBy([this.pk, this.sortDirection])
|
|
8096
|
-
.paginate(this.limit);
|
|
8097
|
-
}
|
|
8098
|
-
request = await this.parseResult(this.paginator);
|
|
8099
|
-
}
|
|
8100
|
-
else {
|
|
8101
|
-
if (!this.indexes)
|
|
8102
|
-
this.indexes = (Object.values(this.mapper) || [this.pk]);
|
|
8103
|
-
const condition = this.parseConditions(this.searchValue);
|
|
8104
|
-
request = await this.parseResult(await repo.query(condition, (this.sortBy || this.pk), this.sortDirection));
|
|
8105
|
-
data = [];
|
|
8106
|
-
}
|
|
8107
|
-
data = this.type === ListComponentsTypes.INFINITE ? [...(data).concat(request)] : [...request];
|
|
8108
|
-
}
|
|
8109
|
-
catch (error) {
|
|
8110
|
-
this.logger.error(error?.message || `Unable to find ${this.model} on registry. Return empty array from component`);
|
|
8111
|
-
}
|
|
8112
|
-
}
|
|
8113
|
-
if (data?.length) {
|
|
8114
|
-
if (this.searchValue) {
|
|
8115
|
-
this.items = [...data];
|
|
8116
|
-
if (this.items?.length <= this.limit)
|
|
8117
|
-
this.loadMoreData = false;
|
|
8118
|
-
}
|
|
8119
|
-
else {
|
|
8120
|
-
this.items = [...data];
|
|
8121
|
-
}
|
|
8122
|
-
}
|
|
8123
|
-
if (this.type === ListComponentsTypes.PAGINATED && this.paginator)
|
|
8124
|
-
this.getMoreData(this.paginator.total);
|
|
8125
|
-
return data || [];
|
|
8171
|
+
async ngOnInit() {
|
|
8172
|
+
this.showSlideItems = this.enableSlideItems();
|
|
8173
|
+
this.button = stringToBoolean(this.button);
|
|
8174
|
+
this.className = `${this.className} dcf-flex dcf-flex-middle grid-item`;
|
|
8175
|
+
if (this.operations?.length)
|
|
8176
|
+
this.className += ` action`;
|
|
8177
|
+
this.windowWidth = getWindowWidth();
|
|
8126
8178
|
}
|
|
8127
8179
|
/**
|
|
8128
|
-
* @description
|
|
8129
|
-
* @summary
|
|
8130
|
-
*
|
|
8131
|
-
*
|
|
8180
|
+
* @description Handles user interactions and actions performed on the list item.
|
|
8181
|
+
* @summary This method is the central action handler for list item interactions. It manages
|
|
8182
|
+
* event propagation, dismisses open action menus, removes focus traps, and either emits
|
|
8183
|
+
* events for parent components to handle or performs navigation based on the component's
|
|
8184
|
+
* route configuration. This method supports both event-driven and navigation-driven architectures.
|
|
8132
8185
|
*
|
|
8133
|
-
*
|
|
8134
|
-
* -
|
|
8135
|
-
*
|
|
8136
|
-
*
|
|
8186
|
+
* @param {CrudOperations} action - The type of CRUD operation being performed
|
|
8187
|
+
* @param {Event} event - The browser event that triggered the action
|
|
8188
|
+
* @param {HTMLElement} [target] - Optional target element for the event
|
|
8189
|
+
* @return {Promise<boolean|void>} A promise that resolves to navigation success or void for events
|
|
8137
8190
|
*
|
|
8138
|
-
*
|
|
8139
|
-
*
|
|
8140
|
-
*
|
|
8141
|
-
*
|
|
8142
|
-
*
|
|
8191
|
+
* @mermaid
|
|
8192
|
+
* sequenceDiagram
|
|
8193
|
+
* participant U as User
|
|
8194
|
+
* participant L as ListItemComponent
|
|
8195
|
+
* participant P as Parent Component
|
|
8196
|
+
* participant N as NavController
|
|
8197
|
+
* participant E as Event System
|
|
8143
8198
|
*
|
|
8144
|
-
*
|
|
8145
|
-
*
|
|
8146
|
-
*
|
|
8199
|
+
* U->>L: Perform action (click/swipe)
|
|
8200
|
+
* L->>L: stopImmediatePropagation()
|
|
8201
|
+
* alt actionMenuOpen
|
|
8202
|
+
* L->>L: Dismiss action menu
|
|
8203
|
+
* end
|
|
8204
|
+
* L->>L: removeFocusTrap()
|
|
8205
|
+
* alt No route configured
|
|
8206
|
+
* L->>E: windowEventEmitter()
|
|
8207
|
+
* L->>P: clickEvent.emit()
|
|
8208
|
+
* else Route configured
|
|
8209
|
+
* L->>N: redirect(action, uid)
|
|
8210
|
+
* N-->>L: Return navigation result
|
|
8211
|
+
* end
|
|
8212
|
+
*
|
|
8213
|
+
* @memberOf ListItemComponent
|
|
8147
8214
|
*/
|
|
8148
|
-
|
|
8149
|
-
|
|
8150
|
-
if (
|
|
8151
|
-
|
|
8152
|
-
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
|
|
8157
|
-
|
|
8158
|
-
}
|
|
8159
|
-
else {
|
|
8160
|
-
orCondition = Condition.attribute(index).regexp(value);
|
|
8161
|
-
}
|
|
8162
|
-
_condition = _condition.or(orCondition);
|
|
8163
|
-
}
|
|
8164
|
-
}
|
|
8165
|
-
else {
|
|
8166
|
-
const { query, sort } = value;
|
|
8167
|
-
_condition = Condition.attribute(this.pk).dif('null');
|
|
8168
|
-
if (query?.length)
|
|
8169
|
-
_condition = undefined;
|
|
8170
|
-
(query || []).forEach((item) => {
|
|
8171
|
-
const { value, condition, index } = item;
|
|
8172
|
-
let val = value;
|
|
8173
|
-
if (index === this.pk || !isNaN(val))
|
|
8174
|
-
val = Number(val);
|
|
8175
|
-
let orCondition;
|
|
8176
|
-
switch (condition) {
|
|
8177
|
-
case "Equal":
|
|
8178
|
-
orCondition = Condition.attribute(index).eq(val);
|
|
8179
|
-
break;
|
|
8180
|
-
case "Not Equal":
|
|
8181
|
-
orCondition = Condition.attribute(index).dif(val);
|
|
8182
|
-
break;
|
|
8183
|
-
case "Not Contains":
|
|
8184
|
-
orCondition = !Condition.attribute(index).regexp(new RegExp(`^(?!.*${val}).*$`));
|
|
8185
|
-
break;
|
|
8186
|
-
case "Contains":
|
|
8187
|
-
orCondition = Condition.attribute(index).regexp(val);
|
|
8188
|
-
break;
|
|
8189
|
-
case "Greater Than":
|
|
8190
|
-
orCondition = Condition.attribute(index).gte(val);
|
|
8191
|
-
break;
|
|
8192
|
-
case "Less Than":
|
|
8193
|
-
orCondition = Condition.attribute(index).lte(val);
|
|
8194
|
-
break;
|
|
8195
|
-
}
|
|
8196
|
-
_condition = (!_condition ?
|
|
8197
|
-
orCondition : _condition.and(orCondition));
|
|
8198
|
-
});
|
|
8199
|
-
this.sortBy = sort?.value || this.pk;
|
|
8200
|
-
this.sortDirection = sort?.direction || this.sortDirection;
|
|
8215
|
+
async handleAction(action, event, target) {
|
|
8216
|
+
event.stopImmediatePropagation();
|
|
8217
|
+
if (this.actionMenuOpen)
|
|
8218
|
+
await this.actionMenuComponent.dismiss();
|
|
8219
|
+
// forcing trap focus
|
|
8220
|
+
removeFocusTrap();
|
|
8221
|
+
if (!this.route) {
|
|
8222
|
+
const event = { target: target, action, pk: this.pk, data: this.uid, name: EventConstants.CLICK, component: this.componentName };
|
|
8223
|
+
windowEventEmitter(`ListItem${EventConstants.CLICK}`, event);
|
|
8224
|
+
return this.clickEvent.emit(event);
|
|
8201
8225
|
}
|
|
8202
|
-
return
|
|
8226
|
+
return await this.redirect(action, (typeof this.uid === 'number' ? `${this.uid}` : this.uid));
|
|
8203
8227
|
}
|
|
8204
8228
|
/**
|
|
8205
|
-
* @description
|
|
8206
|
-
* @summary
|
|
8207
|
-
*
|
|
8208
|
-
*
|
|
8229
|
+
* @description Responsive handler that enables or disables slide items based on screen size and operations.
|
|
8230
|
+
* @summary This method is automatically called when the window is resized and also during component
|
|
8231
|
+
* initialization. It determines whether slide actions should be available based on the current
|
|
8232
|
+
* window width and the presence of UPDATE or DELETE operations. Slide items are typically hidden
|
|
8233
|
+
* on larger screens where there's space for dedicated action buttons.
|
|
8209
8234
|
*
|
|
8210
|
-
* @
|
|
8211
|
-
* @param {KeyValue[] | Paginator} result - The raw query result
|
|
8212
|
-
* @returns {KeyValue[]} The processed array of items
|
|
8235
|
+
* @return {boolean} True if slide items should be shown, false otherwise
|
|
8213
8236
|
*
|
|
8214
|
-
* @
|
|
8237
|
+
* @mermaid
|
|
8238
|
+
* sequenceDiagram
|
|
8239
|
+
* participant W as Window
|
|
8240
|
+
* participant L as ListItemComponent
|
|
8241
|
+
* participant U as UI
|
|
8242
|
+
*
|
|
8243
|
+
* W->>L: resize event
|
|
8244
|
+
* L->>W: getWindowWidth()
|
|
8245
|
+
* W-->>L: Return current width
|
|
8246
|
+
* L->>L: Store windowWidth
|
|
8247
|
+
* alt No operations OR width > 639px
|
|
8248
|
+
* L->>U: showSlideItems = false
|
|
8249
|
+
* else Operations include UPDATE/DELETE
|
|
8250
|
+
* L->>U: showSlideItems = true
|
|
8251
|
+
* end
|
|
8252
|
+
* L-->>U: Return showSlideItems value
|
|
8253
|
+
*
|
|
8254
|
+
* @memberOf ListItemComponent
|
|
8215
8255
|
*/
|
|
8216
|
-
|
|
8217
|
-
|
|
8218
|
-
|
|
8219
|
-
|
|
8220
|
-
|
|
8221
|
-
|
|
8222
|
-
this.getMoreData(paginator.total);
|
|
8223
|
-
}
|
|
8224
|
-
catch (error) {
|
|
8225
|
-
this.logger.info(error?.message || 'Unable to get page from paginator. Return empty array from component');
|
|
8226
|
-
result = [];
|
|
8227
|
-
}
|
|
8228
|
-
}
|
|
8229
|
-
else {
|
|
8230
|
-
this.getMoreData(result?.length || 0);
|
|
8231
|
-
}
|
|
8232
|
-
return (Object.keys(this.mapper || {}).length) ?
|
|
8233
|
-
this.mapResults(result) : result;
|
|
8256
|
+
enableSlideItems() {
|
|
8257
|
+
this.windowWidth = getWindowWidth();
|
|
8258
|
+
if (!this.operations?.length || this.windowWidth > 639)
|
|
8259
|
+
return this.showSlideItems = false;
|
|
8260
|
+
this.showSlideItems = this.operations.includes(OperationKeys.UPDATE) || this.operations.includes(OperationKeys.DELETE);
|
|
8261
|
+
return this.showSlideItems;
|
|
8234
8262
|
}
|
|
8235
8263
|
/**
|
|
8236
|
-
* @description
|
|
8237
|
-
* @summary
|
|
8238
|
-
*
|
|
8239
|
-
*
|
|
8264
|
+
* @description Animates and removes an element from the DOM.
|
|
8265
|
+
* @summary This method applies CSS animation classes to create a smooth fade-out effect
|
|
8266
|
+
* before removing the element from the DOM. The animation enhances user experience by
|
|
8267
|
+
* providing visual feedback when items are deleted or removed from lists. The timing
|
|
8268
|
+
* is coordinated with the CSS animation duration to ensure the element is removed
|
|
8269
|
+
* after the animation completes.
|
|
8240
8270
|
*
|
|
8241
|
-
* @param {
|
|
8242
|
-
* @
|
|
8271
|
+
* @param {HTMLElement} element - The DOM element to animate and remove
|
|
8272
|
+
* @return {void}
|
|
8243
8273
|
*
|
|
8244
|
-
* @
|
|
8274
|
+
* @mermaid
|
|
8275
|
+
* sequenceDiagram
|
|
8276
|
+
* participant L as ListItemComponent
|
|
8277
|
+
* participant E as HTMLElement
|
|
8278
|
+
* participant D as DOM
|
|
8279
|
+
*
|
|
8280
|
+
* L->>E: Add animation classes
|
|
8281
|
+
* Note over E: uk-animation-fade, uk-animation-medium, uk-animation-reverse
|
|
8282
|
+
* E->>E: Start fade animation
|
|
8283
|
+
* L->>L: setTimeout(600ms)
|
|
8284
|
+
* Note over L: Wait for animation to complete
|
|
8285
|
+
* L->>D: element.remove()
|
|
8286
|
+
* D->>D: Remove element from DOM
|
|
8287
|
+
*
|
|
8288
|
+
* @memberOf ListItemComponent
|
|
8245
8289
|
*/
|
|
8246
|
-
|
|
8247
|
-
|
|
8248
|
-
|
|
8249
|
-
length = length * this.limit;
|
|
8250
|
-
if (length <= this.limit) {
|
|
8251
|
-
this.loadMoreData = false;
|
|
8252
|
-
}
|
|
8253
|
-
else {
|
|
8254
|
-
this.pages = Math.floor(length / this.limit);
|
|
8255
|
-
if ((this.pages * this.limit) < length)
|
|
8256
|
-
this.pages += 1;
|
|
8257
|
-
if (this.pages === 1)
|
|
8258
|
-
this.loadMoreData = false;
|
|
8259
|
-
}
|
|
8260
|
-
}
|
|
8261
|
-
else {
|
|
8262
|
-
this.pages = length;
|
|
8263
|
-
if (this.pages === 1)
|
|
8264
|
-
this.loadMoreData = false;
|
|
8265
|
-
}
|
|
8290
|
+
removeElement(element) {
|
|
8291
|
+
element.classList.add('uk-animation-fade', 'uk-animation-medium', 'uk-animation-reverse');
|
|
8292
|
+
setTimeout(() => { element.remove(); }, 600);
|
|
8266
8293
|
}
|
|
8267
8294
|
/**
|
|
8268
|
-
* @description
|
|
8269
|
-
* @summary
|
|
8270
|
-
*
|
|
8271
|
-
*
|
|
8295
|
+
* @description Navigates to a new route based on the specified action and item ID.
|
|
8296
|
+
* @summary This method constructs a navigation URL using the component's route configuration,
|
|
8297
|
+
* the specified action, and an item identifier. It uses Ionic's NavController to perform
|
|
8298
|
+
* forward navigation with appropriate animations. This method is typically used for
|
|
8299
|
+
* CRUD operations where each action (create, read, update, delete) has its own route.
|
|
8272
8300
|
*
|
|
8273
|
-
* @
|
|
8274
|
-
* @param {
|
|
8275
|
-
* @
|
|
8276
|
-
* @param {KeyValue} [props] - Additional properties to include
|
|
8277
|
-
* @returns {KeyValue} The mapped item
|
|
8301
|
+
* @param {string} action - The action to be performed (e.g., 'edit', 'view', 'delete')
|
|
8302
|
+
* @param {string} [id] - The unique identifier of the item to be acted upon
|
|
8303
|
+
* @return {Promise<boolean>} A promise that resolves to true if navigation was successful
|
|
8278
8304
|
*
|
|
8279
|
-
* @
|
|
8305
|
+
* @mermaid
|
|
8306
|
+
* sequenceDiagram
|
|
8307
|
+
* participant L as ListItemComponent
|
|
8308
|
+
* participant N as NavController
|
|
8309
|
+
* participant R as Router
|
|
8310
|
+
*
|
|
8311
|
+
* L->>L: redirect(action, id)
|
|
8312
|
+
* L->>L: Construct URL: /{route}/{action}/{id}
|
|
8313
|
+
* L->>N: navigateForward(url)
|
|
8314
|
+
* N->>R: Navigate to constructed URL
|
|
8315
|
+
* R-->>N: Return navigation result
|
|
8316
|
+
* N-->>L: Return boolean success
|
|
8317
|
+
*
|
|
8318
|
+
* @memberOf ListItemComponent
|
|
8280
8319
|
*/
|
|
8281
|
-
|
|
8282
|
-
return
|
|
8283
|
-
const arrayValue = value.split('.');
|
|
8284
|
-
if (!value) {
|
|
8285
|
-
accum[key] = value;
|
|
8286
|
-
}
|
|
8287
|
-
else {
|
|
8288
|
-
if (arrayValue.length === 1) {
|
|
8289
|
-
value = item?.[value] ? item[value] : value !== key ? value : "";
|
|
8290
|
-
if (isValidDate(value))
|
|
8291
|
-
value = `${formatDate(value)}`;
|
|
8292
|
-
accum[key] = value;
|
|
8293
|
-
}
|
|
8294
|
-
else {
|
|
8295
|
-
let val;
|
|
8296
|
-
for (const _value of arrayValue)
|
|
8297
|
-
val = !val
|
|
8298
|
-
? item[_value]
|
|
8299
|
-
: (typeof val === 'string' ? JSON.parse(val) : val)[_value];
|
|
8300
|
-
if (isValidDate(new Date(val)))
|
|
8301
|
-
val = `${formatDate(val)}`;
|
|
8302
|
-
accum[key] = val === null || val === undefined ? value : val;
|
|
8303
|
-
}
|
|
8304
|
-
}
|
|
8305
|
-
return Object.assign({}, props || {}, accum);
|
|
8306
|
-
}, {});
|
|
8320
|
+
async redirect(action, id) {
|
|
8321
|
+
return await this.navController.navigateForward(`/${this.route}/${action}/${id || this.uid}`);
|
|
8307
8322
|
}
|
|
8308
8323
|
/**
|
|
8309
|
-
* @description
|
|
8310
|
-
* @summary
|
|
8311
|
-
*
|
|
8312
|
-
*
|
|
8324
|
+
* @description Presents the actions menu popover for the list item.
|
|
8325
|
+
* @summary This method handles the display of a contextual action menu when triggered by user
|
|
8326
|
+
* interaction (typically a long press or right-click). It stops event propagation to prevent
|
|
8327
|
+
* unwanted side effects, removes any existing focus traps for accessibility, configures the
|
|
8328
|
+
* popover with the triggering event, and opens the action menu. The menu typically contains
|
|
8329
|
+
* available CRUD operations for the item.
|
|
8313
8330
|
*
|
|
8314
|
-
* @param {
|
|
8315
|
-
* @
|
|
8331
|
+
* @param {Event} event - The event that triggered the action menu request
|
|
8332
|
+
* @return {void}
|
|
8316
8333
|
*
|
|
8317
|
-
* @
|
|
8334
|
+
* @mermaid
|
|
8335
|
+
* sequenceDiagram
|
|
8336
|
+
* participant U as User
|
|
8337
|
+
* participant L as ListItemComponent
|
|
8338
|
+
* participant P as Popover
|
|
8339
|
+
* participant A as Accessibility
|
|
8340
|
+
*
|
|
8341
|
+
* U->>L: Trigger action menu (long press/right-click)
|
|
8342
|
+
* L->>L: stopImmediatePropagation()
|
|
8343
|
+
* L->>A: removeFocusTrap()
|
|
8344
|
+
* L->>P: Set event reference
|
|
8345
|
+
* L->>L: actionMenuOpen = true
|
|
8346
|
+
* L->>P: Display popover with actions
|
|
8347
|
+
*
|
|
8348
|
+
* @memberOf ListItemComponent
|
|
8318
8349
|
*/
|
|
8319
|
-
|
|
8320
|
-
|
|
8321
|
-
|
|
8322
|
-
|
|
8323
|
-
this.
|
|
8324
|
-
|
|
8325
|
-
operations: this.operations,
|
|
8326
|
-
route: this.route,
|
|
8327
|
-
...Object.keys(this.item).reduce((acc, key) => {
|
|
8328
|
-
acc[key] = this.item[key];
|
|
8329
|
-
return acc;
|
|
8330
|
-
}, {}),
|
|
8331
|
-
// ... (!this.item.render ? {} : Object.keys(this.item).reduce((acc: KeyValue, key: string) => {
|
|
8332
|
-
// acc[key] = this.item[key as keyof IListItemProp];
|
|
8333
|
-
// return acc;
|
|
8334
|
-
// }, {}))
|
|
8335
|
-
});
|
|
8336
|
-
return data.reduce((accum, curr) => {
|
|
8337
|
-
accum.push({ ...this.itemMapper(curr, this.mapper, props), ...{ pk: this.pk } });
|
|
8338
|
-
return accum;
|
|
8339
|
-
}, []);
|
|
8350
|
+
presentActionsMenu(event) {
|
|
8351
|
+
event.stopImmediatePropagation();
|
|
8352
|
+
// forcing trap focus
|
|
8353
|
+
removeFocusTrap();
|
|
8354
|
+
this.actionMenuComponent.event = event;
|
|
8355
|
+
this.actionMenuOpen = true;
|
|
8340
8356
|
}
|
|
8341
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
8342
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ListComponent, isStandalone: true, selector: "ngx-decaf-list", inputs: { type: "type", translatable: "translatable", 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", emptyIcon: "emptyIcon", empty: "empty" }, outputs: { refreshEvent: "refreshEvent", clickEvent: "clickEvent" }, host: { listeners: { "window:ListItemClickEvent": "handleClick($event)", "window:searchbarEvent": "handleSearch($event)", "window:BackButtonNavigationEndEvent": "refresh($event)" } }, 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 && data?.length) {\n @if(model && enableFilter) {\n <ngx-decaf-filter\n [model]=\"model\"\n [sortDirection]=\"sortDirection\"\n [disableSort]=\"disableSort\"\n (filterEvent)=\"handleFilter($event)\"\n (searchEvent)=\"handleSearch($event)\"\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\" #component>\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(!searchValue?.length) {\n <ngx-decaf-empty-state\n [title]=\"(locale + '.'+ empty.title) | translate\"\n [subtitle]=\"(locale + '.'+ empty.subtitle) | translate\"\n [buttonText]=\"empty.showButton ? (locale + '.'+ empty.button | translate) : ''\"\n [buttonLink]=\"empty.showButton ? empty.route : ''\"\n />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n ngClass=\"empty-search\"\n [translatable]=\"true\"\n title=\"search.title\"\n subtitle=\"search.subtitle\"\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: "pipe", type: TranslatePipe, name: "translate" }, { 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", "globals", "children", "model", "parent"], outputs: ["listenEvent"] }] }); }
|
|
8357
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: ListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8358
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.2", 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)" } }, viewQueries: [{ propertyName: "actionMenuComponent", first: true, predicate: ["actionMenuComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "\n@if(title || description) {\n <ion-item-sliding #component>\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 \">\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 <ion-label class=\"dcf-item-title\" [innerHTML]=\"uid + ' - ' + title\" ></ion-label>\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 <div class=\"dcf-visible@m\" id=\"dcf-actions\">\n <ion-button class=\"dcf-hidden@m\" 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: ["@media (prefers-color-scheme: light){ion-item{--background-hover-opacity: .1;--background-focused-opacity: .1;--border-color: var(--dcf-color-gray-2)}ion-item .dcf-info{color:var(--dcf-color-gray-6)}ion-item .dcf-item-title{color:var(--dcf-color-gray-8)}ion-item .dcf-description{color:var(--dcf-color-gray-6)}ion-button{color:var(--dcf-color-gray-7);--background: var(--dcf-color-gray-1) !important}ion-avatar{color:var(--dcf-color-gray-7);background:var(--dcf-color-gray-1)!important}ion-item-option:not(.dcf-delete),ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),.25)!important}ion-item-option:not(.dcf-delete) .dcf-ti,ion-item-option:not(.dcf-delete) ion-icon,ion-item-option:not(.dcf-update) .dcf-ti,ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-7)!important}ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item-option.dcf-delete .dcf-ti,ion-item-option.dcf-delete *,ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item-option.dcf-update .dcf-ti,ion-item-option.dcf-update ion-icon{color:var(--dcf-color-primary)!important}}@media (prefers-color-scheme: dark){ion-item{--background-hover-opacity: .25;--background-focused-opacity: .25;--border-color: var(--dcf-color-gray-6)}ion-item .dcf-description{color:var(--dcf-color-gray-4)}ion-button{color:var(--dcf-color-gray-1)!important;--background: var(--dcf-color-gray-7) !important}ion-avatar{color:var(--dcf-color-gray-1)!important;background:var(--dcf-background-color)!important}ion-item-option:not(.dcf-delete),ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),1)!important}ion-item-option:not(.dcf-delete) .dcf-ti,ion-item-option:not(.dcf-delete) ion-icon,ion-item-option:not(.dcf-update) .dcf-ti,ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-2)!important}ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item-option.dcf-delete .dcf-ti,ion-item-option.dcf-delete *,ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item-option.dcf-update .dcf-ti,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-item .dcf-icon ion-avatar{width:48px;height:48px;display:flex;justify-content:center;align-items:center;text-align:center}ion-item .dcf-icon ion-avatar ion-icon{font-size:20px}ion-item .dcf-icon 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" }] }); }
|
|
8343
8359
|
};
|
|
8344
|
-
|
|
8360
|
+
ListItemComponent = __decorate([
|
|
8345
8361
|
Dynamic(),
|
|
8346
8362
|
__metadata("design:paramtypes", [])
|
|
8347
|
-
],
|
|
8348
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
8363
|
+
], ListItemComponent);
|
|
8364
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: ListItemComponent, decorators: [{
|
|
8349
8365
|
type: Component,
|
|
8350
|
-
args: [{ selector: 'ngx-decaf-list', standalone: true, imports: [
|
|
8366
|
+
args: [{ selector: 'ngx-decaf-list-item', standalone: true, imports: [
|
|
8351
8367
|
TranslatePipe,
|
|
8352
|
-
IonRefresher,
|
|
8353
|
-
IonLoading,
|
|
8354
|
-
PaginationComponent,
|
|
8355
8368
|
IonList,
|
|
8369
|
+
IonListHeader,
|
|
8356
8370
|
IonItem,
|
|
8357
|
-
|
|
8358
|
-
|
|
8371
|
+
IonItemSliding,
|
|
8372
|
+
IonItemOptions,
|
|
8373
|
+
IonItemOption,
|
|
8374
|
+
IonIcon,
|
|
8359
8375
|
IonLabel,
|
|
8360
|
-
|
|
8361
|
-
|
|
8362
|
-
|
|
8363
|
-
IonInfiniteScrollContent,
|
|
8364
|
-
|
|
8365
|
-
|
|
8366
|
-
|
|
8367
|
-
EmptyStateComponent,
|
|
8368
|
-
ListItemComponent,
|
|
8369
|
-
FilterComponent,
|
|
8370
|
-
ComponentRendererComponent
|
|
8371
|
-
], 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 && data?.length) {\n @if(model && enableFilter) {\n <ngx-decaf-filter\n [model]=\"model\"\n [sortDirection]=\"sortDirection\"\n [disableSort]=\"disableSort\"\n (filterEvent)=\"handleFilter($event)\"\n (searchEvent)=\"handleSearch($event)\"\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\" #component>\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(!searchValue?.length) {\n <ngx-decaf-empty-state\n [title]=\"(locale + '.'+ empty.title) | translate\"\n [subtitle]=\"(locale + '.'+ empty.subtitle) | translate\"\n [buttonText]=\"empty.showButton ? (locale + '.'+ empty.button | translate) : ''\"\n [buttonLink]=\"empty.showButton ? empty.route : ''\"\n />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n ngClass=\"empty-search\"\n [translatable]=\"true\"\n title=\"search.title\"\n subtitle=\"search.subtitle\"\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"] }]
|
|
8372
|
-
}], ctorParameters: () => [], propDecorators: { type: [{
|
|
8373
|
-
type: Input
|
|
8374
|
-
}], translatable: [{
|
|
8375
|
-
type: Input
|
|
8376
|
-
}], showSearchbar: [{
|
|
8377
|
-
type: Input
|
|
8378
|
-
}], data: [{
|
|
8379
|
-
type: Input
|
|
8380
|
-
}], source: [{
|
|
8381
|
-
type: Input
|
|
8382
|
-
}], start: [{
|
|
8383
|
-
type: Input
|
|
8384
|
-
}], limit: [{
|
|
8385
|
-
type: Input
|
|
8386
|
-
}], loadMoreData: [{
|
|
8387
|
-
type: Input
|
|
8376
|
+
IonButton,
|
|
8377
|
+
IonContent,
|
|
8378
|
+
IonPopover
|
|
8379
|
+
], template: "\n@if(title || description) {\n <ion-item-sliding #component>\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 \">\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 <ion-label class=\"dcf-item-title\" [innerHTML]=\"uid + ' - ' + title\" ></ion-label>\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 <div class=\"dcf-visible@m\" id=\"dcf-actions\">\n <ion-button class=\"dcf-hidden@m\" 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: ["@media (prefers-color-scheme: light){ion-item{--background-hover-opacity: .1;--background-focused-opacity: .1;--border-color: var(--dcf-color-gray-2)}ion-item .dcf-info{color:var(--dcf-color-gray-6)}ion-item .dcf-item-title{color:var(--dcf-color-gray-8)}ion-item .dcf-description{color:var(--dcf-color-gray-6)}ion-button{color:var(--dcf-color-gray-7);--background: var(--dcf-color-gray-1) !important}ion-avatar{color:var(--dcf-color-gray-7);background:var(--dcf-color-gray-1)!important}ion-item-option:not(.dcf-delete),ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),.25)!important}ion-item-option:not(.dcf-delete) .dcf-ti,ion-item-option:not(.dcf-delete) ion-icon,ion-item-option:not(.dcf-update) .dcf-ti,ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-7)!important}ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item-option.dcf-delete .dcf-ti,ion-item-option.dcf-delete *,ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item-option.dcf-update .dcf-ti,ion-item-option.dcf-update ion-icon{color:var(--dcf-color-primary)!important}}@media (prefers-color-scheme: dark){ion-item{--background-hover-opacity: .25;--background-focused-opacity: .25;--border-color: var(--dcf-color-gray-6)}ion-item .dcf-description{color:var(--dcf-color-gray-4)}ion-button{color:var(--dcf-color-gray-1)!important;--background: var(--dcf-color-gray-7) !important}ion-avatar{color:var(--dcf-color-gray-1)!important;background:var(--dcf-background-color)!important}ion-item-option:not(.dcf-delete),ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),1)!important}ion-item-option:not(.dcf-delete) .dcf-ti,ion-item-option:not(.dcf-delete) ion-icon,ion-item-option:not(.dcf-update) .dcf-ti,ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-2)!important}ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item-option.dcf-delete .dcf-ti,ion-item-option.dcf-delete *,ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item-option.dcf-update .dcf-ti,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-item .dcf-icon ion-avatar{width:48px;height:48px;display:flex;justify-content:center;align-items:center;text-align:center}ion-item .dcf-icon ion-avatar ion-icon{font-size:20px}ion-item .dcf-icon ion-avatar .dcf-icon-large{transform:translateY(5px)}\n"] }]
|
|
8380
|
+
}], ctorParameters: () => [], propDecorators: { actionMenuComponent: [{
|
|
8381
|
+
type: ViewChild,
|
|
8382
|
+
args: ['actionMenuComponent']
|
|
8388
8383
|
}], lines: [{
|
|
8389
8384
|
type: Input
|
|
8390
|
-
}],
|
|
8391
|
-
type: Input
|
|
8392
|
-
}], scrollThreshold: [{
|
|
8393
|
-
type: Input
|
|
8394
|
-
}], scrollPosition: [{
|
|
8395
|
-
type: Input
|
|
8396
|
-
}], loadingText: [{
|
|
8397
|
-
type: Input
|
|
8398
|
-
}], showRefresher: [{
|
|
8385
|
+
}], item: [{
|
|
8399
8386
|
type: Input
|
|
8400
|
-
}],
|
|
8387
|
+
}], icon: [{
|
|
8401
8388
|
type: Input
|
|
8402
|
-
}],
|
|
8389
|
+
}], iconSlot: [{
|
|
8403
8390
|
type: Input
|
|
8404
|
-
}],
|
|
8391
|
+
}], button: [{
|
|
8405
8392
|
type: Input
|
|
8406
|
-
}],
|
|
8393
|
+
}], title: [{
|
|
8407
8394
|
type: Input
|
|
8408
|
-
}],
|
|
8395
|
+
}], description: [{
|
|
8409
8396
|
type: Input
|
|
8410
|
-
}],
|
|
8397
|
+
}], info: [{
|
|
8411
8398
|
type: Input
|
|
8412
|
-
}],
|
|
8399
|
+
}], subinfo: [{
|
|
8413
8400
|
type: Input
|
|
8414
|
-
}], refreshEvent: [{
|
|
8415
|
-
type: Output
|
|
8416
8401
|
}], clickEvent: [{
|
|
8417
8402
|
type: Output
|
|
8418
|
-
}],
|
|
8419
|
-
type: HostListener,
|
|
8420
|
-
args: ['window:ListItemClickEvent', ['$event']]
|
|
8421
|
-
}], handleSearch: [{
|
|
8422
|
-
type: HostListener,
|
|
8423
|
-
args: ['window:searchbarEvent', ['$event']]
|
|
8424
|
-
}], refresh: [{
|
|
8403
|
+
}], enableSlideItems: [{
|
|
8425
8404
|
type: HostListener,
|
|
8426
|
-
args: ['window:
|
|
8405
|
+
args: ['window:resize', ['$event']]
|
|
8427
8406
|
}] } });
|
|
8428
8407
|
|
|
8429
8408
|
let SteppedFormComponent = class SteppedFormComponent {
|
|
@@ -8678,17 +8657,16 @@ let SteppedFormComponent = class SteppedFormComponent {
|
|
|
8678
8657
|
this.activeChildren = undefined;
|
|
8679
8658
|
this.timerSubscription = timer(10).subscribe(() => {
|
|
8680
8659
|
this.activeChildren = this.children.filter(c => c.props?.['page'] === page);
|
|
8681
|
-
console.log(this.activeChildren);
|
|
8682
8660
|
});
|
|
8683
8661
|
}
|
|
8684
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
8685
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
8662
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: SteppedFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8663
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.2", type: SteppedFormComponent, isStandalone: true, selector: "ngx-decaf-stepped-form", inputs: { locale: "locale", pages: "pages", operation: "operation", startPage: "startPage", children: "children", formGroup: "formGroup" }, outputs: { submitEvent: "submitEvent" }, ngImport: i0, template: "<form class=\"dcf-steped-form\" novalidate>\n <div class=\"dcf-page-steps\">\n <div>\n @for(page of pagesArray; track $index;) {\n <div [class.dcf-active]=\"activePage === $index + 1\" [class.dcf-passed]=\"($index + 1) < activePage\">{{ $index + 1 }}</div>\n }\n </div>\n </div>\n @if(formGroup) {\n @for(child of activeChildren; track $index) {\n <ngx-decaf-component-renderer\n [tag]=\"child?.tag\"\n (listenEvent)=\"handleEvent($event)\"\n [children]=\"child?.children || []\"\n [globals]=\"{props: child.props}\"\n />\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\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 fill=\"clear\" (click)=\"handleBack()\" [disabled]=\"activePage <= 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]=\"activePage === pages ? 'solid' : 'outline'\" (click)=\"handleNext(activePage === pages ? true : false)\">\n @if(activePage === 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</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{padding:2rem 1rem}.dcf-page-steps{display:flex;justify-content:center;margin-bottom:2rem}.dcf-page-steps>div{justify-content:center;min-width:200px;max-width:200px;column-gap:.25em;display:flex}.dcf-page-steps>div>div{width:30px;text-align:center;border-bottom:solid var(--dcf-color-gray-3);box-sizing:border-box;border-width:3px;font-size:0px;font-weight:600}.dcf-page-steps>div>div.dcf-active{border-width:5px;font-size:1rem;color:var(--ion-color-gray-7);border-color:var(--ion-color-primary);line-height:1rem}.dcf-page-steps>div>div.dcf-passed{border-width:4px;font-size:.5rem;line-height:1.2rem;border-color:var(--dcf-color-gray-5);color:var(--ion-color-primary)}\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: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "globals", "children", "model", "parent"], outputs: ["listenEvent"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
8686
8664
|
};
|
|
8687
8665
|
SteppedFormComponent = __decorate([
|
|
8688
8666
|
Dynamic(),
|
|
8689
8667
|
__metadata("design:paramtypes", [])
|
|
8690
8668
|
], SteppedFormComponent);
|
|
8691
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
8669
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: SteppedFormComponent, decorators: [{
|
|
8692
8670
|
type: Component,
|
|
8693
8671
|
args: [{ selector: 'ngx-decaf-stepped-form', imports: [
|
|
8694
8672
|
TranslatePipe,
|
|
@@ -8697,7 +8675,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
8697
8675
|
IonText,
|
|
8698
8676
|
IonButton,
|
|
8699
8677
|
IonIcon,
|
|
8700
|
-
ModelRendererComponent,
|
|
8701
8678
|
ComponentRendererComponent
|
|
8702
8679
|
], standalone: true, template: "<form class=\"dcf-steped-form\" novalidate>\n <div class=\"dcf-page-steps\">\n <div>\n @for(page of pagesArray; track $index;) {\n <div [class.dcf-active]=\"activePage === $index + 1\" [class.dcf-passed]=\"($index + 1) < activePage\">{{ $index + 1 }}</div>\n }\n </div>\n </div>\n @if(formGroup) {\n @for(child of activeChildren; track $index) {\n <ngx-decaf-component-renderer\n [tag]=\"child?.tag\"\n (listenEvent)=\"handleEvent($event)\"\n [children]=\"child?.children || []\"\n [globals]=\"{props: child.props}\"\n />\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\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 fill=\"clear\" (click)=\"handleBack()\" [disabled]=\"activePage <= 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]=\"activePage === pages ? 'solid' : 'outline'\" (click)=\"handleNext(activePage === pages ? true : false)\">\n @if(activePage === 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</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{padding:2rem 1rem}.dcf-page-steps{display:flex;justify-content:center;margin-bottom:2rem}.dcf-page-steps>div{justify-content:center;min-width:200px;max-width:200px;column-gap:.25em;display:flex}.dcf-page-steps>div>div{width:30px;text-align:center;border-bottom:solid var(--dcf-color-gray-3);box-sizing:border-box;border-width:3px;font-size:0px;font-weight:600}.dcf-page-steps>div>div.dcf-active{border-width:5px;font-size:1rem;color:var(--ion-color-gray-7);border-color:var(--ion-color-primary);line-height:1rem}.dcf-page-steps>div>div.dcf-passed{border-width:4px;font-size:.5rem;line-height:1.2rem;border-color:var(--dcf-color-gray-5);color:var(--ion-color-primary)}\n"] }]
|
|
8703
8680
|
}], ctorParameters: () => [], propDecorators: { locale: [{
|
|
@@ -8732,10 +8709,10 @@ class CollapsableDirective {
|
|
|
8732
8709
|
}
|
|
8733
8710
|
}
|
|
8734
8711
|
}
|
|
8735
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
8736
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
8712
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: CollapsableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
8713
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.2", type: CollapsableDirective, isStandalone: true, selector: "[decafCollapsable]", ngImport: i0 }); }
|
|
8737
8714
|
}
|
|
8738
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
8715
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: CollapsableDirective, decorators: [{
|
|
8739
8716
|
type: Directive,
|
|
8740
8717
|
args: [{
|
|
8741
8718
|
selector: '[decafCollapsable]',
|
|
@@ -8761,8 +8738,8 @@ const Components = [
|
|
|
8761
8738
|
SteppedFormComponent
|
|
8762
8739
|
];
|
|
8763
8740
|
class ForAngularComponentsModule {
|
|
8764
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
8765
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
8741
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: ForAngularComponentsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
8742
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.2", ngImport: i0, type: ForAngularComponentsModule, imports: [ModelRendererComponent,
|
|
8766
8743
|
ComponentRendererComponent,
|
|
8767
8744
|
CrudFieldComponent,
|
|
8768
8745
|
CrudFormComponent,
|
|
@@ -8789,7 +8766,7 @@ class ForAngularComponentsModule {
|
|
|
8789
8766
|
LayoutComponent,
|
|
8790
8767
|
FilterComponent,
|
|
8791
8768
|
SteppedFormComponent, CollapsableDirective] }); }
|
|
8792
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
8769
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: ForAngularComponentsModule, imports: [CrudFieldComponent,
|
|
8793
8770
|
CrudFormComponent,
|
|
8794
8771
|
EmptyStateComponent,
|
|
8795
8772
|
ListComponent,
|
|
@@ -8801,7 +8778,7 @@ class ForAngularComponentsModule {
|
|
|
8801
8778
|
FilterComponent,
|
|
8802
8779
|
SteppedFormComponent] }); }
|
|
8803
8780
|
}
|
|
8804
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
8781
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: ForAngularComponentsModule, decorators: [{
|
|
8805
8782
|
type: NgModule,
|
|
8806
8783
|
args: [{
|
|
8807
8784
|
imports: [...Components, ...Directives],
|
|
@@ -8825,5 +8802,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
8825
8802
|
* Generated bundle index. Do not edit.
|
|
8826
8803
|
*/
|
|
8827
8804
|
|
|
8828
|
-
export { AngularEngineKeys, BaseComponentProps, CollapsableDirective, ComponentRendererComponent, ComponentsTagNames, CrudFieldComponent, CrudFormComponent, CssClasses, DB_ADAPTER_PROVIDER_TOKEN, DefaultFormReactiveOptions, Dynamic, DynamicModule, EmptyStateComponent, EventConstants, FieldsetComponent, FilterComponent, ForAngularCommonModule, ForAngularComponentsModule, FormConstants, I18N_CONFIG_TOKEN, I18nLoader, I18nLoaderFactory, LayoutComponent, ListComponent, ListComponentsTypes, ListItemComponent, LoggerLevels, ModelRendererComponent,
|
|
8805
|
+
export { AngularEngineKeys, BaseComponentProps, CollapsableDirective, ComponentRendererComponent, ComponentsTagNames, CrudFieldComponent, CrudFormComponent, CssClasses, DB_ADAPTER_PROVIDER_TOKEN, DefaultFormReactiveOptions, Dynamic, DynamicModule, EmptyStateComponent, EventConstants, FieldsetComponent, FilterComponent, ForAngularCommonModule, ForAngularComponentsModule, FormConstants, I18N_CONFIG_TOKEN, I18nLoader, I18nLoaderFactory, LayoutComponent, ListComponent, ListComponentsTypes, ListItemComponent, LoggerLevels, ModelRendererComponent, NgxBaseComponent, NgxCrudFormField, NgxFormService, NgxRenderingEngine, PaginationComponent, RouteDirections, SearchbarComponent, SteppedFormComponent, cleanSpaces, dataMapper, formatDate, generateRandomValue, getInjectablesRegistry, getLocaleContext, getLocaleContextByKey, getLocaleFromClassName, getLocaleLanguage, getLogger, getOnWindow, getOnWindowDocument, getWindow, getWindowDocument, getWindowWidth, isDarkMode, isDevelopmentMode, isNotUndefined, isValidDate, itemMapper, parseToValidDate, provideDbAdapter, provideI18nLoader, removeFocusTrap, setOnWindow, stringToBoolean, windowEventEmitter };
|
|
8829
8806
|
//# sourceMappingURL=decaf-ts-for-angular.mjs.map
|