@decaf-ts/for-angular 0.0.67 → 0.0.68

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.
@@ -5,10 +5,12 @@
5
5
  }
6
6
  },
7
7
  "menu": {
8
+ "dashboard": "Dashboard",
8
9
  "product": "Products",
9
10
  "batch": "Batches",
10
11
  "logout": "Logout",
11
12
  "account": "Account",
13
+ "leaflets": "Leaflets",
12
14
  "user": "Users",
13
15
  "category": "Categories",
14
16
  "employee": "Employees",
@@ -19,7 +19,7 @@
19
19
  }
20
20
  },
21
21
  "product": {
22
- "title":"Products Details",
22
+ "title":"Products",
23
23
  "menu": "Products",
24
24
  "section": {
25
25
  "details": {
@@ -2938,18 +2938,22 @@ var errors = {
2938
2938
  };
2939
2939
  var operations = {
2940
2940
  read: {
2941
+ title: "Read",
2941
2942
  success: "Successfully read item with {0} {1}.",
2942
2943
  error: "Error reading item with {0} {1}."
2943
2944
  },
2944
2945
  create: {
2946
+ title: "Create",
2945
2947
  success: "Successfully created item.",
2946
2948
  error: "Error creating item."
2947
2949
  },
2948
2950
  update: {
2951
+ title: "Update",
2949
2952
  success: "Successfully updated item with {0} {1}.",
2950
2953
  error: "Error updating item with {0} {1}."
2951
2954
  },
2952
2955
  "delete": {
2956
+ title: "Delete",
2953
2957
  success: "Successfully deleted item with {0} {1}.",
2954
2958
  error: "Error deleting item with {0} {1}."
2955
2959
  },
@@ -3228,7 +3232,7 @@ class I18nParser extends TranslateParser {
3228
3232
  if (typeof params === Primitives.STRING) {
3229
3233
  params = { '0': params };
3230
3234
  }
3231
- return sf(value, ...Object.values(params));
3235
+ return sf(value, ...Object.values(params)).replace(/undefined/g, "");
3232
3236
  }
3233
3237
  }
3234
3238
  /**
@@ -12613,53 +12617,59 @@ let TableComponent = class TableComponent extends ListComponent {
12613
12617
  }
12614
12618
  };
12615
12619
  }
12620
+ if (this.filterModel)
12621
+ await this.getFilterOptions();
12616
12622
  await this.refresh();
12617
12623
  }
12618
- itemMapper(item, mapper, props = {}) {
12619
- const mapped = Object.keys(item).reduce((acc, curr) => {
12620
- if (this.cols.includes(curr)) {
12621
- let value = item[curr];
12622
- const parserFn = mapper?.[curr]?.valueParserFn || undefined;
12623
- if (typeof parserFn === Function.name.toLowerCase()) {
12624
- value = parserFn(value, this);
12625
- }
12626
- else {
12627
- if (isValidDate(new Date(value)))
12628
- value = `${formatDate(value)}`;
12629
- }
12630
- acc[curr] = value;
12624
+ async getFilterOptions() {
12625
+ const repo = getModelAndRepository(this.filterModel);
12626
+ if (repo) {
12627
+ const { repository, pk } = repo;
12628
+ if (!this.filterBy)
12629
+ this.filterBy = pk;
12630
+ if (!this.filterOptionsMapper) {
12631
+ this.filterOptionsMapper = this.filterOptionsMapper || ((item) => ({
12632
+ text: `${item[pk]}`,
12633
+ value: `${item[pk]}`,
12634
+ }));
12631
12635
  }
12632
- return acc;
12633
- }, { ...(props ?? {}) });
12634
- return mapped;
12636
+ const query = await repository.select().execute();
12637
+ if (query?.length)
12638
+ this.filterOptions = query.map((item) => this.filterOptionsMapper(item));
12639
+ }
12640
+ }
12641
+ itemMapper(item, mapper, props = {}) {
12642
+ item = super.itemMapper(item, this.cols.filter(c => c !== 'actions'), props);
12643
+ return Object.keys(item).reduce((accum, curr, index) => {
12644
+ const parserFn = mapper[this.cols[index]]?.valueParserFn || undefined;
12645
+ return { ...accum, [curr]: parserFn ? parserFn(item[curr], this) : item[curr] };
12646
+ }, { ...props });
12635
12647
  }
12636
12648
  mapResults(data) {
12637
12649
  if (!data || !data.length)
12638
12650
  return [];
12639
- return data.reduce((accum, curr) => {
12640
- accum.push({
12641
- ...this.itemMapper(curr, this.mapper, { uid: curr[this.pk] })
12642
- });
12643
- return accum;
12644
- }, []);
12651
+ return data.reduce((accum, curr) => [
12652
+ ...accum,
12653
+ this.itemMapper(curr, this.mapper, { uid: curr[this.pk] })
12654
+ ], []);
12645
12655
  }
12646
12656
  async handleAction(event, action, uid) {
12647
12657
  event.stopImmediatePropagation();
12648
12658
  await this.router.navigate([`/${this.route}/${action}/${uid}`]);
12649
12659
  }
12650
12660
  async openFilterSelectOptions(event) {
12651
- const type = (this.filter.length > 10 ? SelectFieldInterfaces.MODAL : SelectFieldInterfaces.POPOVER);
12661
+ const type = (this.filterOptions.length > 10 ? SelectFieldInterfaces.MODAL : SelectFieldInterfaces.POPOVER);
12652
12662
  if (type === SelectFieldInterfaces.MODAL) {
12653
12663
  event.preventDefault();
12654
12664
  event.stopImmediatePropagation();
12655
12665
  const title = await this.translate(`${this.locale}.filter_by`);
12656
- const modal = await getNgxSelectOptionsModal(title, this.filter, this.injector);
12666
+ const modal = await getNgxSelectOptionsModal(title, this.filterOptions, this.injector);
12657
12667
  this.changeDetectorRef.detectChanges();
12658
12668
  const { data, role } = await modal.onWillDismiss();
12659
12669
  if (role === ActionRoles.confirm && data !== this.filterValue) {
12660
12670
  this.filterValue = data;
12661
12671
  await this.handleSearch({ query: [
12662
- { index: 'productCode', value: this.filterValue, condition: 'Contains' }
12672
+ { index: this.filterBy, value: this.filterValue, condition: 'Contains' }
12663
12673
  ] });
12664
12674
  }
12665
12675
  }
@@ -12673,7 +12683,7 @@ let TableComponent = class TableComponent extends ListComponent {
12673
12683
  }
12674
12684
  }
12675
12685
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
12676
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: TableComponent, isStandalone: true, selector: "ngx-decaf-table", inputs: { filter: "filter", filterIndex: "filterIndex", filterLabel: "filterLabel" }, usesInheritance: true, ngImport: i0, template: "\n@if (showSearchbar && (data?.length || searching)) {\n <div class=\"dcf-grid-actions\">\n <div class=\"dcf-grid dcf-grid-small\">\n <div class=\"dcf-width-expand@s\">\n <ngx-decaf-searchbar\n [emitEventToWindow]=\"false\"\n [debounce]=\"500\"\n (searchEvent)=\"handleSearch($event)\"\n />\n </div>\n @if(filter?.length && filterIndex) {\n <div class=\"dcf-width-auto@s dcf-select-filter-container dcf-flex dcf-flex-middle\">\n <ion-select\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [mode]=\"'md'\"\n fill=\"outline\"\n [value]=\"filterValue ?? '' \"\n [labelPlacement]=\"'floating'\"\n [label]=\" locale + '.filter.label' | translate\"\n (click)=\"openFilterSelectOptions($event)\"\n [placeholder]=\" locale + '.filter.label' | translate\"\n interface=\"popover\"\n >\n <ion-select-option value=\"\">{{ locale + '.filter.all' | translate }}</ion-select-option>\n @for(filterOption of filter; track $index) {\n <ion-select-option value=\"{{ filterOption.value }}\">{{ filterOption.text }}</ion-select-option>\n }\n <ion-button fill=\"clear\" (click)=\"handleFilterSelectClear($event)\" slot=\"end\" size=\"small\" [disabled]=\"!filterValue\">\n <ngx-decaf-icon fill=\"clear\" slot=\"icon-only\" [name]=\"'ti-input-x'\" />\n </ion-button>\n </ion-select>\n </div>\n }\n </div>\n </div>\n}\n\n<div class=\"dcf-table-container\">\n @if(initialized && data?.length) {\n <table class=\"dcf-table\">\n <thead>\n <tr>\n @for(col of cols; track $index) {\n <th>{{ locale + '.' + col + '.label' | translate}}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for(item of items; track trackItemFn($index, item)) {\n <tr (click)=\"handleAction($event, OperationKeys.READ, item.uid)\">\n @for(col of item | keyvalue; track $index) {\n @if(!['actions', 'uid'].includes(col.key)) {\n <td>{{ col.value }}</td>\n } @else {\n @if(allowOperations) {\n <td class=\"dcf-col-actions\">\n <div class=\"dcf-flex dcf-flex-center\">\n <ngx-decaf-icon\n [button]=\"true\"\n (click)=\"handleAction($event, OperationKeys.UPDATE, item.uid)\"\n fill=\"clear\"\n slot=\"icon-only\"\n color=\"primary\"\n name=\"ti-pencil\"\n />\n <ngx-decaf-icon\n [button]=\"true\"\n (click)=\"handleAction($event,OperationKeys.DELETE, item.uid)\"\n fill=\"clear\"\n slot=\"icon-only\"\n color=\"danger\"\n name=\"ti-trash\"\n />\n </div>\n </td>\n }\n }\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n @if (!searching) {\n <ngx-decaf-empty-state\n [title]=\"'component.list.empty.title' | translate\"\n [subtitle]=\"'component.list.empty.subtitle' | translate\"\n [model]=\"model\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [buttonLink]=\"empty?.link ?? undefined\"\n [borders]=\"borders\"\n [icon]=\"(item?.icon ?? 'folder-open-outline') || empty.icon\"\n className=\"dcf-empty-data\"\n />\n } @else {\n\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n [model]=\"model\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [borders]=\"borders\"\n [operations]=\"operations\"\n [body]=\"'small'\"\n [translatable]=\"true\"\n [title]=\"'component.list.search.title' | translate\"\n [subtitle]=\"'component.list.search.subtitle' | translate: {'0': parseSearchValue()}\"\n [searchValue]=\"searchValue\"\n />\n }\n }\n</div>\n @if (loadMoreData) {\n <div class=\"dcf-table-pagination\">\n @if (pages > 0 && !searchValue?.length) {\n <ngx-decaf-pagination\n [totalPages]=\"pages\"\n [current]=\"page\"\n (clickEvent)=\"handlePaginate($event)\"\n />\n\n }\n </div>\n}\n\n", styles: [".dcf-table-container{display:block;overflow-x:auto!important;box-sizing:border-box;overflow-y:hidden;scrollbar-width:thin;box-shadow:var(--dcf-box-shadow-small);border:1px solid var(--dcf-color-gray-2);border-radius:var(--dcf-border-radius-small)}.dcf-table-container::-webkit-scrollbar{width:5px}.dcf-table-container table{min-width:680px}.dcf-table{width:100%;border-collapse:collapse;border-radius:var(--dcf-border-radius-xsmall);overflow:hidden;background:var(--dcf-card-background);color:var(--dcf-text-color);font-size:.8rem}.dcf-table thead{background:rgba(var(--dcf-color-primary-rgb),.075);text-transform:uppercase;color:var(--dcf-color-dark);letter-spacing:.06em;font-size:.825rem;white-space:nowrap;width:auto}.dcf-table thead th{text-align:left;padding:.875rem 1rem;font-weight:600;max-width:max-content}.dcf-table tbody tr{transition:background .12s ease,box-shadow .12s ease}.dcf-table tbody tr:hover{background:rgba(var(--dcf-color-primary-rgb),.05);cursor:pointer}.dcf-table tbody tr:not(:last-child){border-bottom:1px solid var(--dcf-color-gray-2)}.dcf-table tbody td{padding:1rem 1.125rem;font-size:.875rem}.dcf-table tbody td:first-child{font-weight:600}.dcf-table tbody td.dcf-col-actions{padding-top:0!important;padding-bottom:0!important}.dcf-table tfoot{font-size:.85rem}.dcf-table tfoot td{padding:.875rem 1.125rem;border-top:1px solid 1px solid var(--dcf-color-gray-2)}.dcf-select-filter-container{min-width:200px}.dcf-buttons-grid{margin-top:var(--dcf-margin-medium);margin-bottom:var(--dcf-margin)}@media (max-width: 480px){.dcf-buttons-grid{flex-direction:row-reverse!important}.dcf-buttons-grid>div{width:100%}.dcf-buttons-grid>div+div{margin-top:1rem}.dcf-buttons-grid ion-button{width:100%}}ion-select{margin-top:.5rem;max-height:40px!important}ion-select ion-button{transform:scale(.75)!important;margin:0!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: "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: IconComponent, selector: "ngx-decaf-icon", inputs: ["name", "color", "slot", "button", "buttonFill", "buttonShape", "width", "size", "inline"] }, { kind: "component", type: PaginationComponent, selector: "ngx-decaf-pagination", inputs: ["totalPages", "current"], outputs: ["clickEvent"] }, { kind: "pipe", type: i1$1.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
12686
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: TableComponent, isStandalone: true, selector: "ngx-decaf-table", inputs: { filterModel: "filterModel", filterOptions: "filterOptions", filterBy: "filterBy", filterLabel: "filterLabel", filterOptionsMapper: "filterOptionsMapper" }, usesInheritance: true, ngImport: i0, template: "\n@if (showSearchbar && (data?.length || searching)) {\n <div class=\"dcf-grid-actions\">\n <div class=\"dcf-grid dcf-grid-small\">\n <div class=\"dcf-width-expand@s\">\n <ngx-decaf-searchbar\n [emitEventToWindow]=\"false\"\n [debounce]=\"500\"\n (searchEvent)=\"handleSearch($event)\"\n />\n </div>\n @if(filterOptions?.length) {\n <div class=\"dcf-width-1-3@s dcf-width-1-4@m dcf-select-filter-container dcf-flex dcf-flex-middle\">\n <ion-select\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [mode]=\"'md'\"\n fill=\"outline\"\n [value]=\"filterValue ?? '' \"\n [labelPlacement]=\"'floating'\"\n [label]=\" locale + '.filter.label' | translate\"\n (click)=\"openFilterSelectOptions($event)\"\n [placeholder]=\" locale + '.filter.label' | translate\"\n interface=\"popover\"\n >\n <ion-select-option value=\"\">{{ locale + '.filter.all' | translate }}</ion-select-option>\n @for(option of filterOptions; track $index) {\n <ion-select-option value=\"{{ option.value }}\">{{ option.text }}</ion-select-option>\n }\n <ion-button fill=\"clear\" (click)=\"handleFilterSelectClear($event)\" slot=\"end\" size=\"small\" [disabled]=\"!filterValue\">\n <ngx-decaf-icon fill=\"clear\" slot=\"icon-only\" [name]=\"'ti-input-x'\" />\n </ion-button>\n </ion-select>\n </div>\n }\n </div>\n </div>\n}\n\n<div class=\"dcf-table-container\">\n @if(initialized && data?.length) {\n <table class=\"dcf-table\">\n <thead>\n <tr>\n @for(col of cols; track $index) {\n <th>{{ locale + '.' + col + '.label' | translate}}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for(item of items; track trackItemFn($index, item)) {\n <tr (click)=\"handleAction($event, OperationKeys.READ, item.uid)\">\n @for(col of item | keyvalue; track $index) {\n @if(!['actions', 'uid'].includes(col.key)) {\n <td>{{ col.value }}</td>\n } @else {\n @if(allowOperations) {\n <td class=\"dcf-col-actions\">\n <div class=\"dcf-flex dcf-flex-center\">\n <ngx-decaf-icon\n [button]=\"true\"\n (click)=\"handleAction($event, OperationKeys.UPDATE, item.uid)\"\n fill=\"clear\"\n slot=\"icon-only\"\n color=\"primary\"\n name=\"ti-pencil\"\n />\n <ngx-decaf-icon\n [button]=\"true\"\n (click)=\"handleAction($event,OperationKeys.DELETE, item.uid)\"\n fill=\"clear\"\n slot=\"icon-only\"\n color=\"danger\"\n name=\"ti-trash\"\n />\n </div>\n </td>\n }\n }\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n @if (!searching) {\n <ngx-decaf-empty-state\n [title]=\"'component.list.empty.title' | translate\"\n [subtitle]=\"'component.list.empty.subtitle' | translate\"\n [model]=\"model\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [buttonLink]=\"empty?.link ?? undefined\"\n [borders]=\"borders\"\n [icon]=\"(item?.icon ?? 'folder-open-outline') || empty.icon\"\n className=\"dcf-empty-data\"\n />\n } @else {\n\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n [model]=\"model\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [borders]=\"borders\"\n [operations]=\"operations\"\n [body]=\"'small'\"\n [translatable]=\"true\"\n [title]=\"'component.list.search.title' | translate\"\n [subtitle]=\"'component.list.search.subtitle' | translate: {'0': parseSearchValue()}\"\n [searchValue]=\"searchValue\"\n />\n }\n }\n</div>\n @if (loadMoreData) {\n <div class=\"dcf-table-pagination\">\n @if (pages > 0 && !searchValue?.length) {\n <ngx-decaf-pagination\n [totalPages]=\"pages\"\n [current]=\"page\"\n (clickEvent)=\"handlePaginate($event)\"\n />\n\n }\n </div>\n}\n\n", styles: [".dcf-table-container{display:block;overflow-x:auto!important;box-sizing:border-box;overflow-y:hidden;scrollbar-width:thin;box-shadow:var(--dcf-box-shadow-small);border:1px solid var(--dcf-color-gray-2);border-radius:var(--dcf-border-radius-small)}.dcf-table-container::-webkit-scrollbar{width:5px}.dcf-table-container table{min-width:680px}.dcf-table{width:100%;border-collapse:collapse;border-radius:var(--dcf-border-radius-xsmall);overflow:hidden;background:var(--dcf-card-background);color:var(--dcf-text-color);font-size:.8rem}.dcf-table thead{background:rgba(var(--dcf-color-primary-rgb),.075);text-transform:uppercase;color:var(--dcf-color-dark);letter-spacing:.06em;font-size:.825rem;white-space:nowrap;width:auto}.dcf-table thead th{text-align:left;padding:.875rem 1rem;font-weight:600;max-width:max-content}.dcf-table tbody tr{transition:background .12s ease,box-shadow .12s ease}.dcf-table tbody tr:hover{background:rgba(var(--dcf-color-primary-rgb),.05);cursor:pointer}.dcf-table tbody tr:not(:last-child){border-bottom:1px solid var(--dcf-color-gray-2)}.dcf-table tbody td{padding:1rem 1.125rem;font-size:.875rem}.dcf-table tbody td:first-child{font-weight:600}.dcf-table tbody td.dcf-col-actions{padding-top:0!important;padding-bottom:0!important}.dcf-table tfoot{font-size:.85rem}.dcf-table tfoot td{padding:.875rem 1.125rem;border-top:1px solid 1px solid var(--dcf-color-gray-2)}.dcf-select-filter-container{min-width:200px}.dcf-buttons-grid{margin-top:var(--dcf-margin-medium);margin-bottom:var(--dcf-margin)}@media (max-width: 480px){.dcf-buttons-grid{flex-direction:row-reverse!important}.dcf-buttons-grid>div{width:100%}.dcf-buttons-grid>div+div{margin-top:1rem}.dcf-buttons-grid ion-button{width:100%}}ion-select{margin-top:.5rem;max-height:40px!important}ion-select ion-button{transform:scale(.75)!important;margin:0!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: "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: IconComponent, selector: "ngx-decaf-icon", inputs: ["name", "color", "slot", "button", "buttonFill", "buttonShape", "width", "size", "inline"] }, { kind: "component", type: PaginationComponent, selector: "ngx-decaf-pagination", inputs: ["totalPages", "current"], outputs: ["clickEvent"] }, { kind: "pipe", type: i1$1.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
12677
12687
  };
12678
12688
  TableComponent = __decorate([
12679
12689
  Dynamic()
@@ -12689,13 +12699,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
12689
12699
  EmptyStateComponent,
12690
12700
  IconComponent,
12691
12701
  PaginationComponent
12692
- ], template: "\n@if (showSearchbar && (data?.length || searching)) {\n <div class=\"dcf-grid-actions\">\n <div class=\"dcf-grid dcf-grid-small\">\n <div class=\"dcf-width-expand@s\">\n <ngx-decaf-searchbar\n [emitEventToWindow]=\"false\"\n [debounce]=\"500\"\n (searchEvent)=\"handleSearch($event)\"\n />\n </div>\n @if(filter?.length && filterIndex) {\n <div class=\"dcf-width-auto@s dcf-select-filter-container dcf-flex dcf-flex-middle\">\n <ion-select\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [mode]=\"'md'\"\n fill=\"outline\"\n [value]=\"filterValue ?? '' \"\n [labelPlacement]=\"'floating'\"\n [label]=\" locale + '.filter.label' | translate\"\n (click)=\"openFilterSelectOptions($event)\"\n [placeholder]=\" locale + '.filter.label' | translate\"\n interface=\"popover\"\n >\n <ion-select-option value=\"\">{{ locale + '.filter.all' | translate }}</ion-select-option>\n @for(filterOption of filter; track $index) {\n <ion-select-option value=\"{{ filterOption.value }}\">{{ filterOption.text }}</ion-select-option>\n }\n <ion-button fill=\"clear\" (click)=\"handleFilterSelectClear($event)\" slot=\"end\" size=\"small\" [disabled]=\"!filterValue\">\n <ngx-decaf-icon fill=\"clear\" slot=\"icon-only\" [name]=\"'ti-input-x'\" />\n </ion-button>\n </ion-select>\n </div>\n }\n </div>\n </div>\n}\n\n<div class=\"dcf-table-container\">\n @if(initialized && data?.length) {\n <table class=\"dcf-table\">\n <thead>\n <tr>\n @for(col of cols; track $index) {\n <th>{{ locale + '.' + col + '.label' | translate}}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for(item of items; track trackItemFn($index, item)) {\n <tr (click)=\"handleAction($event, OperationKeys.READ, item.uid)\">\n @for(col of item | keyvalue; track $index) {\n @if(!['actions', 'uid'].includes(col.key)) {\n <td>{{ col.value }}</td>\n } @else {\n @if(allowOperations) {\n <td class=\"dcf-col-actions\">\n <div class=\"dcf-flex dcf-flex-center\">\n <ngx-decaf-icon\n [button]=\"true\"\n (click)=\"handleAction($event, OperationKeys.UPDATE, item.uid)\"\n fill=\"clear\"\n slot=\"icon-only\"\n color=\"primary\"\n name=\"ti-pencil\"\n />\n <ngx-decaf-icon\n [button]=\"true\"\n (click)=\"handleAction($event,OperationKeys.DELETE, item.uid)\"\n fill=\"clear\"\n slot=\"icon-only\"\n color=\"danger\"\n name=\"ti-trash\"\n />\n </div>\n </td>\n }\n }\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n @if (!searching) {\n <ngx-decaf-empty-state\n [title]=\"'component.list.empty.title' | translate\"\n [subtitle]=\"'component.list.empty.subtitle' | translate\"\n [model]=\"model\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [buttonLink]=\"empty?.link ?? undefined\"\n [borders]=\"borders\"\n [icon]=\"(item?.icon ?? 'folder-open-outline') || empty.icon\"\n className=\"dcf-empty-data\"\n />\n } @else {\n\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n [model]=\"model\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [borders]=\"borders\"\n [operations]=\"operations\"\n [body]=\"'small'\"\n [translatable]=\"true\"\n [title]=\"'component.list.search.title' | translate\"\n [subtitle]=\"'component.list.search.subtitle' | translate: {'0': parseSearchValue()}\"\n [searchValue]=\"searchValue\"\n />\n }\n }\n</div>\n @if (loadMoreData) {\n <div class=\"dcf-table-pagination\">\n @if (pages > 0 && !searchValue?.length) {\n <ngx-decaf-pagination\n [totalPages]=\"pages\"\n [current]=\"page\"\n (clickEvent)=\"handlePaginate($event)\"\n />\n\n }\n </div>\n}\n\n", styles: [".dcf-table-container{display:block;overflow-x:auto!important;box-sizing:border-box;overflow-y:hidden;scrollbar-width:thin;box-shadow:var(--dcf-box-shadow-small);border:1px solid var(--dcf-color-gray-2);border-radius:var(--dcf-border-radius-small)}.dcf-table-container::-webkit-scrollbar{width:5px}.dcf-table-container table{min-width:680px}.dcf-table{width:100%;border-collapse:collapse;border-radius:var(--dcf-border-radius-xsmall);overflow:hidden;background:var(--dcf-card-background);color:var(--dcf-text-color);font-size:.8rem}.dcf-table thead{background:rgba(var(--dcf-color-primary-rgb),.075);text-transform:uppercase;color:var(--dcf-color-dark);letter-spacing:.06em;font-size:.825rem;white-space:nowrap;width:auto}.dcf-table thead th{text-align:left;padding:.875rem 1rem;font-weight:600;max-width:max-content}.dcf-table tbody tr{transition:background .12s ease,box-shadow .12s ease}.dcf-table tbody tr:hover{background:rgba(var(--dcf-color-primary-rgb),.05);cursor:pointer}.dcf-table tbody tr:not(:last-child){border-bottom:1px solid var(--dcf-color-gray-2)}.dcf-table tbody td{padding:1rem 1.125rem;font-size:.875rem}.dcf-table tbody td:first-child{font-weight:600}.dcf-table tbody td.dcf-col-actions{padding-top:0!important;padding-bottom:0!important}.dcf-table tfoot{font-size:.85rem}.dcf-table tfoot td{padding:.875rem 1.125rem;border-top:1px solid 1px solid var(--dcf-color-gray-2)}.dcf-select-filter-container{min-width:200px}.dcf-buttons-grid{margin-top:var(--dcf-margin-medium);margin-bottom:var(--dcf-margin)}@media (max-width: 480px){.dcf-buttons-grid{flex-direction:row-reverse!important}.dcf-buttons-grid>div{width:100%}.dcf-buttons-grid>div+div{margin-top:1rem}.dcf-buttons-grid ion-button{width:100%}}ion-select{margin-top:.5rem;max-height:40px!important}ion-select ion-button{transform:scale(.75)!important;margin:0!important}\n"] }]
12693
- }], propDecorators: { filter: [{
12702
+ ], template: "\n@if (showSearchbar && (data?.length || searching)) {\n <div class=\"dcf-grid-actions\">\n <div class=\"dcf-grid dcf-grid-small\">\n <div class=\"dcf-width-expand@s\">\n <ngx-decaf-searchbar\n [emitEventToWindow]=\"false\"\n [debounce]=\"500\"\n (searchEvent)=\"handleSearch($event)\"\n />\n </div>\n @if(filterOptions?.length) {\n <div class=\"dcf-width-1-3@s dcf-width-1-4@m dcf-select-filter-container dcf-flex dcf-flex-middle\">\n <ion-select\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [mode]=\"'md'\"\n fill=\"outline\"\n [value]=\"filterValue ?? '' \"\n [labelPlacement]=\"'floating'\"\n [label]=\" locale + '.filter.label' | translate\"\n (click)=\"openFilterSelectOptions($event)\"\n [placeholder]=\" locale + '.filter.label' | translate\"\n interface=\"popover\"\n >\n <ion-select-option value=\"\">{{ locale + '.filter.all' | translate }}</ion-select-option>\n @for(option of filterOptions; track $index) {\n <ion-select-option value=\"{{ option.value }}\">{{ option.text }}</ion-select-option>\n }\n <ion-button fill=\"clear\" (click)=\"handleFilterSelectClear($event)\" slot=\"end\" size=\"small\" [disabled]=\"!filterValue\">\n <ngx-decaf-icon fill=\"clear\" slot=\"icon-only\" [name]=\"'ti-input-x'\" />\n </ion-button>\n </ion-select>\n </div>\n }\n </div>\n </div>\n}\n\n<div class=\"dcf-table-container\">\n @if(initialized && data?.length) {\n <table class=\"dcf-table\">\n <thead>\n <tr>\n @for(col of cols; track $index) {\n <th>{{ locale + '.' + col + '.label' | translate}}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for(item of items; track trackItemFn($index, item)) {\n <tr (click)=\"handleAction($event, OperationKeys.READ, item.uid)\">\n @for(col of item | keyvalue; track $index) {\n @if(!['actions', 'uid'].includes(col.key)) {\n <td>{{ col.value }}</td>\n } @else {\n @if(allowOperations) {\n <td class=\"dcf-col-actions\">\n <div class=\"dcf-flex dcf-flex-center\">\n <ngx-decaf-icon\n [button]=\"true\"\n (click)=\"handleAction($event, OperationKeys.UPDATE, item.uid)\"\n fill=\"clear\"\n slot=\"icon-only\"\n color=\"primary\"\n name=\"ti-pencil\"\n />\n <ngx-decaf-icon\n [button]=\"true\"\n (click)=\"handleAction($event,OperationKeys.DELETE, item.uid)\"\n fill=\"clear\"\n slot=\"icon-only\"\n color=\"danger\"\n name=\"ti-trash\"\n />\n </div>\n </td>\n }\n }\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n @if (!searching) {\n <ngx-decaf-empty-state\n [title]=\"'component.list.empty.title' | translate\"\n [subtitle]=\"'component.list.empty.subtitle' | translate\"\n [model]=\"model\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [buttonLink]=\"empty?.link ?? undefined\"\n [borders]=\"borders\"\n [icon]=\"(item?.icon ?? 'folder-open-outline') || empty.icon\"\n className=\"dcf-empty-data\"\n />\n } @else {\n\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n [model]=\"model\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [borders]=\"borders\"\n [operations]=\"operations\"\n [body]=\"'small'\"\n [translatable]=\"true\"\n [title]=\"'component.list.search.title' | translate\"\n [subtitle]=\"'component.list.search.subtitle' | translate: {'0': parseSearchValue()}\"\n [searchValue]=\"searchValue\"\n />\n }\n }\n</div>\n @if (loadMoreData) {\n <div class=\"dcf-table-pagination\">\n @if (pages > 0 && !searchValue?.length) {\n <ngx-decaf-pagination\n [totalPages]=\"pages\"\n [current]=\"page\"\n (clickEvent)=\"handlePaginate($event)\"\n />\n\n }\n </div>\n}\n\n", styles: [".dcf-table-container{display:block;overflow-x:auto!important;box-sizing:border-box;overflow-y:hidden;scrollbar-width:thin;box-shadow:var(--dcf-box-shadow-small);border:1px solid var(--dcf-color-gray-2);border-radius:var(--dcf-border-radius-small)}.dcf-table-container::-webkit-scrollbar{width:5px}.dcf-table-container table{min-width:680px}.dcf-table{width:100%;border-collapse:collapse;border-radius:var(--dcf-border-radius-xsmall);overflow:hidden;background:var(--dcf-card-background);color:var(--dcf-text-color);font-size:.8rem}.dcf-table thead{background:rgba(var(--dcf-color-primary-rgb),.075);text-transform:uppercase;color:var(--dcf-color-dark);letter-spacing:.06em;font-size:.825rem;white-space:nowrap;width:auto}.dcf-table thead th{text-align:left;padding:.875rem 1rem;font-weight:600;max-width:max-content}.dcf-table tbody tr{transition:background .12s ease,box-shadow .12s ease}.dcf-table tbody tr:hover{background:rgba(var(--dcf-color-primary-rgb),.05);cursor:pointer}.dcf-table tbody tr:not(:last-child){border-bottom:1px solid var(--dcf-color-gray-2)}.dcf-table tbody td{padding:1rem 1.125rem;font-size:.875rem}.dcf-table tbody td:first-child{font-weight:600}.dcf-table tbody td.dcf-col-actions{padding-top:0!important;padding-bottom:0!important}.dcf-table tfoot{font-size:.85rem}.dcf-table tfoot td{padding:.875rem 1.125rem;border-top:1px solid 1px solid var(--dcf-color-gray-2)}.dcf-select-filter-container{min-width:200px}.dcf-buttons-grid{margin-top:var(--dcf-margin-medium);margin-bottom:var(--dcf-margin)}@media (max-width: 480px){.dcf-buttons-grid{flex-direction:row-reverse!important}.dcf-buttons-grid>div{width:100%}.dcf-buttons-grid>div+div{margin-top:1rem}.dcf-buttons-grid ion-button{width:100%}}ion-select{margin-top:.5rem;max-height:40px!important}ion-select ion-button{transform:scale(.75)!important;margin:0!important}\n"] }]
12703
+ }], propDecorators: { filterModel: [{
12694
12704
  type: Input
12695
- }], filterIndex: [{
12705
+ }], filterOptions: [{
12706
+ type: Input
12707
+ }], filterBy: [{
12696
12708
  type: Input
12697
12709
  }], filterLabel: [{
12698
12710
  type: Input
12711
+ }], filterOptionsMapper: [{
12712
+ type: Input
12699
12713
  }] } });
12700
12714
 
12701
12715
  /**
@@ -12941,8 +12955,8 @@ class NgxPageDirective extends NgxComponentDirective {
12941
12955
  if (this.locale)
12942
12956
  return `${this.locale}.title`;
12943
12957
  if (this.currentRoute)
12944
- return this.currentRoute?.charAt(0).toUpperCase() + this.currentRoute?.slice(1) || 'Decaf For Angular';
12945
- return "";
12958
+ return `${this.currentRoute}.title`;
12959
+ return `${this.model.constructor.name}.title`;
12946
12960
  }
12947
12961
  async ngOnInit() {
12948
12962
  // connect component to media service for color scheme toggling
@@ -12966,8 +12980,8 @@ class NgxPageDirective extends NgxComponentDirective {
12966
12980
  this.currentRoute = url;
12967
12981
  if (this.hasMenu)
12968
12982
  this.hasMenu = url !== "login" && url !== "";
12969
- this.setPageTitle(this.currentRoute);
12970
12983
  this.title = this.pageTitle;
12984
+ await this.setPageTitle(url);
12971
12985
  }
12972
12986
  if (event instanceof NavigationStart) {
12973
12987
  const url = (event?.url || "").replace('/', '');
@@ -12998,8 +13012,9 @@ class NgxPageDirective extends NgxComponentDirective {
12998
13012
  menu = this.menu;
12999
13013
  const activeMenu = menu.find(item => item?.url?.includes(route));
13000
13014
  if (activeMenu) {
13001
- const title = activeMenu?.title || activeMenu?.label;
13002
- this.titleService.setTitle(`${await this.translate(title)} ${this.appName ? `- ${this.appName}` : ''}`);
13015
+ const label = `${(activeMenu?.title || activeMenu?.label || "").toLowerCase()}`;
13016
+ const title = `${await this.translate(label ? "menu." + label : label)} ${this.appName ? `- ${this.appName}` : ''}`;
13017
+ this.titleService.setTitle(title);
13003
13018
  if (!this.title)
13004
13019
  this.title = title;
13005
13020
  }
@@ -13072,15 +13087,6 @@ class NgxModelPageDirective extends NgxPageDirective {
13072
13087
  // constructor(@Inject(CPTKN) hm: boolean = true, @Inject(CPTKN) protected toastController?: ToastController) {
13073
13088
  // super("NgxModelPageDirective");
13074
13089
  // }
13075
- get pageTitle() {
13076
- if (!this.modelName && this.model instanceof Model)
13077
- this.modelName = this.model?.constructor?.name || '';
13078
- if (!this.operation)
13079
- return this.title ? this.title : `Listing ${this.modelName}`;
13080
- const operation = this.operation.charAt(0).toUpperCase() +
13081
- this.operation.slice(1).toLowerCase();
13082
- return this.modelName ? `${operation} ${this.modelName}` : this.title;
13083
- }
13084
13090
  /**
13085
13091
  * @description Lazy-initialized repository getter with model resolution.
13086
13092
  * @summary Creates and returns a repository instance for the specified model name.
@@ -13457,5 +13463,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
13457
13463
  * Generated bundle index. Do not edit.
13458
13464
  */
13459
13465
 
13460
- export { ActionRoles, AngularEngineKeys, BaseComponentProps, CPTKN, CardComponent, ComponentEventNames, ComponentRendererComponent, ComponentsTagNames, CrudFieldComponent, CrudFormComponent, CssClasses, DB_ADAPTER_FLAVOUR_TOKEN, DB_ADAPTER_PROVIDER_TOKEN, DecafFakerRepository, DefaultFormReactiveOptions, DefaultListEmptyOptions, DefaultModalOptions, Dynamic, DynamicModule, ElementPositions, ElementSizes, EmptyStateComponent, FieldsetComponent, FileUploadComponent, FilterComponent, ForAngularCommonModule, ForAngularComponentsModule, FormConstants, I18N_CONFIG_TOKEN, I18nLoader, I18nLoaderFactory, I18nParser, IconComponent, LOCALE_ROOT_TOKEN, LayoutComponent, LayoutGridGaps, ListComponent, ListComponentsTypes, ListItemComponent, ListItemPositions, LoggerLevels, ModalComponent, ModelRendererComponent, NgxComponentDirective, NgxEventHandler, NgxFormDirective, NgxFormFieldDirective, NgxFormService, NgxMediaService, NgxModelPageDirective, NgxPageDirective, NgxParentComponentDirective, NgxRenderingEngine, NgxSvgDirective, PaginationComponent, RouteDirections, SearchbarComponent, SelectFieldInterfaces, SteppedFormComponent, TableComponent, WindowColorSchemes, cleanSpaces, dataMapper, decafPageTransition, filterString, formatDate, generateRandomValue, getDbAdapterFlavour, getFakerData, getInjectablesRegistry, getLocaleContext, getLocaleContextByKey, getLocaleFromClassName, getLocaleLanguage, getLogger, getMenuIcon, getModelAndRepository, getNgxInlineModal, getNgxModalComponent, getNgxModalCrudComponent, getNgxSelectOptionsModal, getOnWindow, getOnWindowDocument, getWindow, getWindowDocument, getWindowWidth, isDarkMode, isDevelopmentMode, isNotUndefined, isValidDate, itemMapper, parseToValidDate, presentNgxInlineModal, presentNgxLightBoxModal, provideDecafDarkMode, provideDecafDbAdapter, provideDecafDynamicComponents, provideDecafI18nConfig, provideDecafI18nLoader, provideDecafPageTransition, removeFocusTrap, setOnWindow, stringToBoolean, windowEventEmitter };
13466
+ export { ActionRoles, AngularEngineKeys, BaseComponentProps, CPTKN, CardComponent, ComponentEventNames, ComponentRendererComponent, ComponentsTagNames, CrudFieldComponent, CrudFormComponent, CssClasses, DB_ADAPTER_FLAVOUR_TOKEN, DB_ADAPTER_PROVIDER_TOKEN, DecafFakerRepository, DefaultFormReactiveOptions, DefaultListEmptyOptions, DefaultModalOptions, Dynamic, DynamicModule, ElementPositions, ElementSizes, EmptyStateComponent, FieldsetComponent, FileUploadComponent, FilterComponent, ForAngularCommonModule, ForAngularComponentsModule, FormConstants, I18N_CONFIG_TOKEN, I18nLoader, I18nLoaderFactory, I18nParser, IconComponent, LOCALE_ROOT_TOKEN, LayoutComponent, LayoutGridGaps, ListComponent, ListComponentsTypes, ListItemComponent, ListItemPositions, LoggerLevels, ModalComponent, ModelRendererComponent, NgxComponentDirective, NgxEventHandler, NgxFormDirective, NgxFormFieldDirective, NgxFormService, NgxMediaService, NgxModelPageDirective, NgxPageDirective, NgxParentComponentDirective, NgxRenderingEngine, NgxRouterService, NgxSvgDirective, PaginationComponent, RouteDirections, SearchbarComponent, SelectFieldInterfaces, SteppedFormComponent, TableComponent, WindowColorSchemes, cleanSpaces, dataMapper, decafPageTransition, filterString, formatDate, generateRandomValue, getDbAdapterFlavour, getFakerData, getInjectablesRegistry, getLocaleContext, getLocaleContextByKey, getLocaleFromClassName, getLocaleLanguage, getLogger, getMenuIcon, getModelAndRepository, getNgxInlineModal, getNgxModalComponent, getNgxModalCrudComponent, getNgxSelectOptionsModal, getOnWindow, getOnWindowDocument, getWindow, getWindowDocument, getWindowWidth, isDarkMode, isDevelopmentMode, isNotUndefined, isValidDate, itemMapper, parseToValidDate, presentNgxInlineModal, presentNgxLightBoxModal, provideDecafDarkMode, provideDecafDbAdapter, provideDecafDynamicComponents, provideDecafI18nConfig, provideDecafI18nLoader, provideDecafPageTransition, removeFocusTrap, setOnWindow, stringToBoolean, windowEventEmitter };
13461
13467
  //# sourceMappingURL=decaf-ts-for-angular.mjs.map