@sd-angular/core 19.0.0-beta.4 → 19.0.0-beta.6

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.
Files changed (39) hide show
  1. package/components/document-builder/src/document-builder.component.d.ts +7 -6
  2. package/components/document-builder/src/document-builder.model.d.ts +1 -0
  3. package/components/document-builder/src/plugins/heading/heading.plugin.d.ts +4 -0
  4. package/components/document-builder/src/plugins/{image-upload.plugin.d.ts → image-upload/image-upload.plugin.d.ts} +0 -4
  5. package/components/document-builder/src/plugins/index.d.ts +6 -5
  6. package/components/table/src/models/table-item.model.d.ts +2 -1
  7. package/components/table/src/models/table-option.model.d.ts +2 -1
  8. package/fesm2022/sd-angular-core-components-document-builder.mjs +240 -333
  9. package/fesm2022/sd-angular-core-components-document-builder.mjs.map +1 -1
  10. package/fesm2022/sd-angular-core-components-table.mjs +361 -73
  11. package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
  12. package/fesm2022/sd-angular-core-components-workflow.mjs +3 -3
  13. package/fesm2022/sd-angular-core-components-workflow.mjs.map +1 -1
  14. package/fesm2022/sd-angular-core-forms-autocomplete.mjs +4 -2
  15. package/fesm2022/sd-angular-core-forms-autocomplete.mjs.map +1 -1
  16. package/fesm2022/sd-angular-core-forms-date.mjs +4 -2
  17. package/fesm2022/sd-angular-core-forms-date.mjs.map +1 -1
  18. package/fesm2022/sd-angular-core-forms-datetime.mjs +17 -3
  19. package/fesm2022/sd-angular-core-forms-datetime.mjs.map +1 -1
  20. package/fesm2022/sd-angular-core-forms-input-number.mjs +4 -3
  21. package/fesm2022/sd-angular-core-forms-input-number.mjs.map +1 -1
  22. package/fesm2022/sd-angular-core-forms-input.mjs +4 -2
  23. package/fesm2022/sd-angular-core-forms-input.mjs.map +1 -1
  24. package/fesm2022/sd-angular-core-forms-radio.mjs +4 -2
  25. package/fesm2022/sd-angular-core-forms-radio.mjs.map +1 -1
  26. package/fesm2022/sd-angular-core-forms-select.mjs +4 -2
  27. package/fesm2022/sd-angular-core-forms-select.mjs.map +1 -1
  28. package/fesm2022/sd-angular-core-forms-textarea.mjs +14 -2
  29. package/fesm2022/sd-angular-core-forms-textarea.mjs.map +1 -1
  30. package/fesm2022/sd-angular-core-pipes.mjs +21 -1
  31. package/fesm2022/sd-angular-core-pipes.mjs.map +1 -1
  32. package/forms/datetime/src/datetime.component.d.ts +4 -1
  33. package/package.json +69 -69
  34. package/pipes/index.d.ts +1 -0
  35. package/pipes/src/empty.pipe.d.ts +7 -0
  36. /package/components/document-builder/src/plugins/{comment.plugin.d.ts → comment/comment.plugin.d.ts} +0 -0
  37. /package/components/document-builder/src/plugins/{page-orientation.plugin.d.ts → page-orientation/page-orientation.plugin.d.ts} +0 -0
  38. /package/components/document-builder/src/plugins/{table-fit.plugin.d.ts → table-fit/table-fit.plugin.d.ts} +0 -0
  39. /package/components/document-builder/src/plugins/{variable.plugin.d.ts → variable/variable.plugin.d.ts} +0 -0
@@ -422,7 +422,7 @@ class ExternalFilterComponent {
422
422
  });
423
423
  };
424
424
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ExternalFilterComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
425
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: ExternalFilterComponent, isStandalone: true, selector: "external-filter", inputs: { _autoId: ["autoId", "_autoId"], _filter: ["filter", "_filter"], _externalFilters: ["externalFilters", "_externalFilters"], _filterRegister: ["filterRegister", "_filterRegister"] }, ngImport: i0, template: "@if (!filter?.disabled) {\r\n @if (!isMobileOrTablet && externalFilters.length) {\r\n <sd-section [hideHeader]=\"filter?.hideExternalFilterToolbar\" icon=\"filter_alt\" iconColor=\"secondary\" title=\"B\u1ED9 l\u1ECDc\" collapsable>\r\n <div class=\"d-flex mr-4\" sdHeaderRight>\r\n <sd-button\r\n [autoId]=\"autoId + 'clearFilter'\"\r\n [disabled]=\"!filtered\"\r\n type=\"link\"\r\n prefixIcon=\"cleaning_services\"\r\n tooltip=\"X\u00F3a l\u1EF1a ch\u1ECDn\"\r\n (click)=\"$event.stopPropagation(); clearFilter($event)\"></sd-button>\r\n <sd-button\r\n [autoId]=\"autoId + 'setting'\"\r\n type=\"link\"\r\n prefixIcon=\"settings\"\r\n tooltip=\"T\u00F9y ch\u1EC9nh\"\r\n [matMenuTriggerFor]=\"menu\"\r\n (click)=\"$event.stopPropagation()\"></sd-button>\r\n <mat-menu #menu=\"matMenu\" class=\"sd-custom-panel-filter-configuration\">\r\n @for (externalFilter of externalFilters; track externalFilter.field) {\r\n <button mat-menu-item (click)=\"onCheckboxChange($event, externalFilter)\" [disabled]=\"externalFilter.required\">\r\n <sd-checkbox\r\n [label]=\"externalFilter.title\"\r\n [model]=\"inlineExternal[externalFilter.field]\"\r\n [disabled]=\"externalFilter.required\" />\r\n </button>\r\n }\r\n </mat-menu>\r\n </div>\r\n <div class=\"row mx-0\" style=\"row-gap: 16px\">\r\n @for (item of externalFilters; track item.field) {\r\n @if (inlineExternal[item.field]) {\r\n <div class=\"col-md-3 col-sm-6 px-8\" [class.col-lg-2]=\"col === 2\" [class.col-lg-3]=\"col === 3\">\r\n @if (item.type === 'string') {\r\n <sd-input\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n type=\"text\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (keyupEnter)=\"onKeyupEnter()\"\r\n appearance=\"outline\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-input>\r\n } @else if (item.type === 'number') {\r\n <sd-input-number\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (keyupEnter)=\"onKeyupEnter()\"\r\n appearance=\"outline\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-input-number>\r\n } @else if (item.type === 'boolean') {\r\n <sd-select\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [items]=\"[\r\n { value: true, display: item.option?.displayOnTrue || 'True' },\r\n { value: false, display: item.option?.displayOnFalse || 'False' }\r\n ]\"\r\n valueField=\"value\"\r\n displayField=\"display\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-select>\r\n } @else if (item.type === 'date') {\r\n <sd-date\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n [min]=\"item.minDate\"\r\n [max]=\"item.maxDate\"\r\n hideInlineError>\r\n </sd-date>\r\n } @else if (item.type === 'datetime') {\r\n <sd-datetime\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n [min]=\"item.minDate\"\r\n [max]=\"item.maxDate\"\r\n hideInlineError>\r\n </sd-datetime>\r\n } @else if (item.type === 'daterange') {\r\n <sd-date-range\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n [min]=\"item.minDate\"\r\n [max]=\"item.maxDate\"\r\n appearance=\"outline\"\r\n hideInlineError>\r\n </sd-date-range>\r\n } @else if (item.type === 'values') {\r\n @if (item.option.selection === 'MULTIPLE') {\r\n <sd-select\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [items]=\"item.option.items | filterValues | async\"\r\n [valueField]=\"item.option.valueField\"\r\n [displayField]=\"item.option.displayField\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n multiple\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-select>\r\n } @else if (item.option.selection === 'AUTOCOMPLETE') {\r\n <sd-select\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [items]=\"item.option.items | filterValues | async\"\r\n [valueField]=\"item.option.valueField\"\r\n [displayField]=\"item.option.displayField\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-select>\r\n } @else if (item.option.selection === 'MULTIPLEAUTOCOMPLETE') {\r\n <sd-select\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [items]=\"item.option.items | filterValues | async\"\r\n [valueField]=\"item.option.valueField\"\r\n [displayField]=\"item.option.displayField\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n multiple\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-select>\r\n } @else {\r\n <sd-select\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [items]=\"item.option.items | filterValues | async\"\r\n [valueField]=\"item.option.valueField\"\r\n [displayField]=\"item.option.displayField\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-select>\r\n }\r\n } @else if (item.type === 'lazy-values') {\r\n @if (item.option.selection === 'MULTIPLE') {\r\n <sd-select\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [items]=\"item.option.items\"\r\n [valueField]=\"item.option.valueField\"\r\n [displayField]=\"item.option.displayField\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n multiple\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-select>\r\n } @else {\r\n <sd-select\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [items]=\"item.option.items\"\r\n [valueField]=\"item.option.valueField\"\r\n [displayField]=\"item.option.displayField\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-select>\r\n }\r\n } @else if (item.type === 'custom' && item.filterDef) {\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n item.filterDef;\r\n context: { form: form, externalFilter: externalFilter, autoId: autoId + item.field }\r\n \"></ng-container>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n @if (filter?.manualFilter) {\r\n <div class=\"d-flex justify-content-end mt-16 px-8\">\r\n <sd-button\r\n [autoId]=\"autoId + 'onSubmit'\"\r\n [disabled]=\"form.invalid\"\r\n type=\"fill\"\r\n color=\"primary\"\r\n title=\"T\u00ECm ki\u1EBFm\"\r\n prefixIcon=\"filter_alt\"\r\n (click)=\"onSubmit()\">\r\n </sd-button>\r\n </div>\r\n }\r\n </sd-section>\r\n }\r\n <!-- <sd-popup-filter [filterRegister]=\"filterRegister!\" [columns]=\"columns\" [externalFilters]=\"externalFilters\">\r\n </sd-popup-filter> -->\r\n}\r\n", styles: [":host{display:block;padding-left:0;padding-right:0}::ng-deep .sd-custom-panel-filter-configuration{width:240px;max-height:550px;overflow-y:auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: SdSection, selector: "sd-section", inputs: ["title", "subTitle", "icon", "iconColor", "collapsed", "collapsable", "hideHeader"] }, { kind: "component", type: SdInput, selector: "sd-input", inputs: ["autoId", "name", "appearance", "size", "form", "label", "helperText", "placeholder", "type", "hideInlineError", "blurOnEnter", "model", "required", "readonly", "minlength", "maxlength", "pattern", "patternErrorMessage", "validator", "inlineError", "disabled", "viewed", "hyperlink", "tooltip"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "sdFocusForceBlur", "keyupEnter"] }, { kind: "component", type: SdInputNumber, selector: "sd-input-number", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "blurOnEnter", "model", "required", "type", "precision", "readonly", "min", "max", "validator", "inlineError", "disabled", "viewed", "hyperlink", "appearance"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "sdFocusForceBlur", "keyupEnter"] }, { kind: "component", type: SdSelect, selector: "sd-select", inputs: ["autoId", "name", "appearance", "hideInlineError", "size", "form", "label", "helperText", "placeholder", "model", "items", "valueField", "displayField", "disabledField", "cacheChecksum", "required", "validator", "inlineError", "disabled", "viewed", "hyperlink", "multiple", "limit"], outputs: ["modelChange", "sdChange", "sdSelection"] }, { kind: "component", type: SdDate, selector: "sd-date", inputs: ["autoId", "name", "appearance", "hideInlineError", "min", "max", "size", "form", "disabled", "viewed", "hyperlink", "required", "inlineError", "label", "helperText", "placeholder", "minDate", "maxDate", "model"], outputs: ["sdChange", "sdFocus", "modelChange"] }, { kind: "component", type: SdDatetime, selector: "sd-datetime", inputs: ["autoId", "name", "appearance", "hideInlineError", "min", "max", "size", "form", "disabled", "required", "inlineError", "label", "helperText", "placeholder", "minDate", "maxDate", "model"], outputs: ["sdChange", "sdFocus", "modelChange"] }, { kind: "component", type: SdDateRange$1, selector: "sd-date-range", inputs: ["autoId", "name", "appearance", "size", "form", "disabled", "required", "label", "helperText", "hideInlineError", "min", "max", "model"], outputs: ["modelChange", "sdChange"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "title", "width", "size", "tooltip", "prefixIcon", "suffixIcon", "fontSet", "disabled", "loading"], outputs: ["click"] }, { kind: "pipe", type: FilterValuesPipe, name: "filterValues" }, { kind: "component", type: SdCheckbox, selector: "sd-checkbox", inputs: ["autoId", "name", "form", "label", "color", "disabled", "model", "inlineError"], outputs: ["modelChange", "sdChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
425
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: ExternalFilterComponent, isStandalone: true, selector: "external-filter", inputs: { _autoId: ["autoId", "_autoId"], _filter: ["filter", "_filter"], _externalFilters: ["externalFilters", "_externalFilters"], _filterRegister: ["filterRegister", "_filterRegister"] }, ngImport: i0, template: "@if (!filter?.disabled) {\r\n @if (!isMobileOrTablet && externalFilters.length) {\r\n <sd-section [hideHeader]=\"filter?.hideExternalFilterToolbar\" icon=\"filter_alt\" iconColor=\"secondary\" title=\"B\u1ED9 l\u1ECDc\" collapsable>\r\n <div class=\"d-flex mr-4\" sdHeaderRight>\r\n <sd-button\r\n [autoId]=\"autoId + 'clearFilter'\"\r\n [disabled]=\"!filtered\"\r\n type=\"link\"\r\n prefixIcon=\"cleaning_services\"\r\n tooltip=\"X\u00F3a l\u1EF1a ch\u1ECDn\"\r\n (click)=\"$event.stopPropagation(); clearFilter($event)\"></sd-button>\r\n <sd-button\r\n [autoId]=\"autoId + 'setting'\"\r\n type=\"link\"\r\n prefixIcon=\"settings\"\r\n tooltip=\"T\u00F9y ch\u1EC9nh\"\r\n [matMenuTriggerFor]=\"menu\"\r\n (click)=\"$event.stopPropagation()\"></sd-button>\r\n <mat-menu #menu=\"matMenu\" class=\"sd-custom-panel-filter-configuration\">\r\n @for (externalFilter of externalFilters; track externalFilter.field) {\r\n <button mat-menu-item (click)=\"onCheckboxChange($event, externalFilter)\" [disabled]=\"externalFilter.required\">\r\n <sd-checkbox\r\n [label]=\"externalFilter.title\"\r\n [model]=\"inlineExternal[externalFilter.field]\"\r\n [disabled]=\"externalFilter.required\" />\r\n </button>\r\n }\r\n </mat-menu>\r\n </div>\r\n <div class=\"row mx-0\" style=\"row-gap: 16px\">\r\n @for (item of externalFilters; track item.field) {\r\n @if (inlineExternal[item.field]) {\r\n <div class=\"col-md-3 col-sm-6 px-8\" [class.col-lg-2]=\"col === 2\" [class.col-lg-3]=\"col === 3\">\r\n @if (item.type === 'string') {\r\n <sd-input\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n type=\"text\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (keyupEnter)=\"onKeyupEnter()\"\r\n appearance=\"outline\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-input>\r\n } @else if (item.type === 'number') {\r\n <sd-input-number\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (keyupEnter)=\"onKeyupEnter()\"\r\n appearance=\"outline\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-input-number>\r\n } @else if (item.type === 'boolean') {\r\n <sd-select\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [items]=\"[\r\n { value: true, display: item.option?.displayOnTrue || 'True' },\r\n { value: false, display: item.option?.displayOnFalse || 'False' }\r\n ]\"\r\n valueField=\"value\"\r\n displayField=\"display\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-select>\r\n } @else if (item.type === 'date') {\r\n <sd-date\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n [min]=\"item.minDate\"\r\n [max]=\"item.maxDate\"\r\n hideInlineError>\r\n </sd-date>\r\n } @else if (item.type === 'datetime') {\r\n <sd-datetime\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n [min]=\"item.minDate\"\r\n [max]=\"item.maxDate\"\r\n hideInlineError>\r\n </sd-datetime>\r\n } @else if (item.type === 'daterange') {\r\n <sd-date-range\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n [min]=\"item.minDate\"\r\n [max]=\"item.maxDate\"\r\n appearance=\"outline\"\r\n hideInlineError>\r\n </sd-date-range>\r\n } @else if (item.type === 'values') {\r\n @if (item.option.selection === 'MULTIPLE') {\r\n <sd-select\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [items]=\"item.option.items | filterValues | async\"\r\n [valueField]=\"item.option.valueField\"\r\n [displayField]=\"item.option.displayField\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n multiple\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-select>\r\n } @else if (item.option.selection === 'AUTOCOMPLETE') {\r\n <sd-select\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [items]=\"item.option.items | filterValues | async\"\r\n [valueField]=\"item.option.valueField\"\r\n [displayField]=\"item.option.displayField\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-select>\r\n } @else if (item.option.selection === 'MULTIPLEAUTOCOMPLETE') {\r\n <sd-select\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [items]=\"item.option.items | filterValues | async\"\r\n [valueField]=\"item.option.valueField\"\r\n [displayField]=\"item.option.displayField\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n multiple\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-select>\r\n } @else {\r\n <sd-select\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [items]=\"item.option.items | filterValues | async\"\r\n [valueField]=\"item.option.valueField\"\r\n [displayField]=\"item.option.displayField\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-select>\r\n }\r\n } @else if (item.type === 'lazy-values') {\r\n @if (item.option.selection === 'MULTIPLE') {\r\n <sd-select\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [items]=\"item.option.items\"\r\n [valueField]=\"item.option.valueField\"\r\n [displayField]=\"item.option.displayField\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n multiple\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-select>\r\n } @else {\r\n <sd-select\r\n [autoId]=\"autoId + item.field\"\r\n [label]=\"item.title\"\r\n [items]=\"item.option.items\"\r\n [valueField]=\"item.option.valueField\"\r\n [displayField]=\"item.option.displayField\"\r\n [(model)]=\"externalFilter![item.field]\"\r\n (sdChange)=\"onFilter()\"\r\n appearance=\"outline\"\r\n [form]=\"form\"\r\n [required]=\"item.required\"\r\n hideInlineError>\r\n </sd-select>\r\n }\r\n } @else if (item.type === 'custom' && item.filterDef) {\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n item.filterDef;\r\n context: { form: form, externalFilter: externalFilter, autoId: autoId + item.field }\r\n \"></ng-container>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n @if (filter?.manualFilter) {\r\n <div class=\"d-flex justify-content-end mt-16 px-8\">\r\n <sd-button\r\n [autoId]=\"autoId + 'onSubmit'\"\r\n [disabled]=\"form.invalid\"\r\n type=\"fill\"\r\n color=\"primary\"\r\n title=\"T\u00ECm ki\u1EBFm\"\r\n prefixIcon=\"filter_alt\"\r\n (click)=\"onSubmit()\">\r\n </sd-button>\r\n </div>\r\n }\r\n </sd-section>\r\n }\r\n <!-- <sd-popup-filter [filterRegister]=\"filterRegister!\" [columns]=\"columns\" [externalFilters]=\"externalFilters\">\r\n </sd-popup-filter> -->\r\n}\r\n", styles: [":host{display:block;padding-left:0;padding-right:0}::ng-deep .sd-custom-panel-filter-configuration{width:240px;max-height:550px;overflow-y:auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: SdSection, selector: "sd-section", inputs: ["title", "subTitle", "icon", "iconColor", "collapsed", "collapsable", "hideHeader"] }, { kind: "component", type: SdInput, selector: "sd-input", inputs: ["autoId", "name", "appearance", "size", "form", "label", "helperText", "placeholder", "type", "hideInlineError", "blurOnEnter", "model", "required", "readonly", "minlength", "maxlength", "pattern", "patternErrorMessage", "validator", "inlineError", "disabled", "viewed", "hyperlink", "tooltip"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "sdFocusForceBlur", "keyupEnter"] }, { kind: "component", type: SdInputNumber, selector: "sd-input-number", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "blurOnEnter", "model", "required", "type", "precision", "readonly", "min", "max", "validator", "inlineError", "disabled", "viewed", "hyperlink", "appearance"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "sdFocusForceBlur", "keyupEnter"] }, { kind: "component", type: SdSelect, selector: "sd-select", inputs: ["autoId", "name", "appearance", "hideInlineError", "size", "form", "label", "helperText", "placeholder", "model", "items", "valueField", "displayField", "disabledField", "cacheChecksum", "required", "validator", "inlineError", "disabled", "viewed", "hyperlink", "multiple", "limit"], outputs: ["modelChange", "sdChange", "sdSelection"] }, { kind: "component", type: SdDate, selector: "sd-date", inputs: ["autoId", "name", "appearance", "hideInlineError", "min", "max", "size", "form", "disabled", "viewed", "hyperlink", "required", "inlineError", "label", "helperText", "placeholder", "minDate", "maxDate", "model"], outputs: ["sdChange", "sdFocus", "modelChange"] }, { kind: "component", type: SdDatetime, selector: "sd-datetime", inputs: ["autoId", "name", "appearance", "hideInlineError", "min", "max", "size", "form", "disabled", "viewed", "hyperlink", "required", "inlineError", "label", "helperText", "placeholder", "minDate", "maxDate", "model"], outputs: ["sdChange", "sdFocus", "modelChange"] }, { kind: "component", type: SdDateRange$1, selector: "sd-date-range", inputs: ["autoId", "name", "appearance", "size", "form", "disabled", "required", "label", "helperText", "hideInlineError", "min", "max", "model"], outputs: ["modelChange", "sdChange"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "title", "width", "size", "tooltip", "prefixIcon", "suffixIcon", "fontSet", "disabled", "loading"], outputs: ["click"] }, { kind: "pipe", type: FilterValuesPipe, name: "filterValues" }, { kind: "component", type: SdCheckbox, selector: "sd-checkbox", inputs: ["autoId", "name", "form", "label", "color", "disabled", "model", "inlineError"], outputs: ["modelChange", "sdChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
426
426
  }
427
427
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ExternalFilterComponent, decorators: [{
428
428
  type: Component,
@@ -2096,7 +2096,8 @@ class SdTable extends SdBaseSecureComponent {
2096
2096
  option.filter.hideInlineFilter = option?.filter?.hideInlineFilter ?? this.tableConfiguration?.filter?.hideInlineFilter;
2097
2097
  option.filter.externalFilterPerRow = option?.filter?.externalFilterPerRow ?? this.tableConfiguration?.filter?.externalFilterPerRow;
2098
2098
  option.filter.manualFilter = option?.filter?.manualFilter ?? this.tableConfiguration?.filter?.manualFilter;
2099
- option.filter.hideExternalFilterToolbar = option?.filter?.hideExternalFilterToolbar ?? this.tableConfiguration?.filter?.hideExternalFilterToolbar;
2099
+ option.filter.hideExternalFilterToolbar =
2100
+ option?.filter?.hideExternalFilterToolbar ?? this.tableConfiguration?.filter?.hideExternalFilterToolbar;
2100
2101
  for (const column of option.columns || []) {
2101
2102
  if (column.filter?.operator?.enable) {
2102
2103
  if (!column.filter?.operator?.list?.length) {
@@ -2431,9 +2432,10 @@ class SdTable extends SdBaseSecureComponent {
2431
2432
  return await result;
2432
2433
  }
2433
2434
  else {
2434
- const filterInfo = this.#filterExportInfo(pageNumber, pageSize);
2435
+ const filterReq = this.#filterExportInfo(pageNumber, pageSize);
2435
2436
  if (this.tableOption.type === 'server') {
2436
- const result = this.tableOption.items(filterInfo);
2437
+ const pagingReq = this.#convertPagingReq(filterReq);
2438
+ const result = this.tableOption.items(filterReq, pagingReq);
2437
2439
  return await result;
2438
2440
  }
2439
2441
  else {
@@ -2450,7 +2452,7 @@ class SdTable extends SdBaseSecureComponent {
2450
2452
  else {
2451
2453
  exportedItems = this.tableOption.items;
2452
2454
  }
2453
- return this.#filterLocal(exportedItems, filterInfo);
2455
+ return this.#filterLocal(exportedItems, filterReq);
2454
2456
  }
2455
2457
  }
2456
2458
  };
@@ -2882,22 +2884,124 @@ class SdTable extends SdBaseSecureComponent {
2882
2884
  }
2883
2885
  }
2884
2886
  };
2887
+ #getNestedValue = (obj, path) => {
2888
+ if (!path || !obj)
2889
+ return undefined;
2890
+ const keys = path.split('.');
2891
+ let result = obj;
2892
+ for (const key of keys) {
2893
+ if (result === null || result === undefined) {
2894
+ return undefined;
2895
+ }
2896
+ result = result[key];
2897
+ }
2898
+ return result;
2899
+ };
2885
2900
  #format = async (rawItems, columns) => {
2886
2901
  const items = rawItems.map(MapToSdTableItem);
2902
+ // Cache for parsed field paths
2903
+ const fieldPathCache = new Map();
2904
+ /**
2905
+ * Get nested property value from object using dot notation
2906
+ */
2907
+ const getNestedValue = (obj, path) => {
2908
+ if (!path || obj == null)
2909
+ return undefined;
2910
+ let keys = fieldPathCache.get(path);
2911
+ if (!keys) {
2912
+ keys = path.split('.');
2913
+ fieldPathCache.set(path, keys);
2914
+ }
2915
+ if (keys.length === 1)
2916
+ return obj[keys[0]];
2917
+ let result = obj;
2918
+ for (const key of keys) {
2919
+ if (result == null)
2920
+ return undefined;
2921
+ result = result[key];
2922
+ }
2923
+ return result;
2924
+ };
2925
+ /**
2926
+ * Format date display based on column type
2927
+ */
2928
+ const formatDateDisplay = (value, type) => {
2929
+ const date = DateUtilities.toFormat(value, 'dd/MM/yyyy');
2930
+ const time = DateUtilities.toFormat(value, 'HH:mm:ss');
2931
+ if (type === 'datetime') {
2932
+ return time && date ? `<div class="T14R">${date}<span class="T14R text-black400 ml-4">${time}</span></div>` : '';
2933
+ }
2934
+ if (type === 'date')
2935
+ return date || '';
2936
+ if (type === 'time')
2937
+ return time || '';
2938
+ return '';
2939
+ };
2940
+ /**
2941
+ * Process values display (supports arrays)
2942
+ */
2943
+ const processValuesDisplay = (value, rowData, column, field) => {
2944
+ if (column.type === 'lazy-values' && typeof column.option.mapValue === 'function') {
2945
+ const val = column.option.mapValue(value, rowData);
2946
+ const vals = (Array.isArray(val) ? val : [val]).filter(e => e?.toString());
2947
+ return vals.map(val => this.#cacheObjValues[field]?.[val]?.[column.option.displayField] || val).join(', ');
2948
+ }
2949
+ const vals = (Array.isArray(value) ? value : [value]).filter(e => e?.toString());
2950
+ return vals.map(val => this.#cacheObjValues[field]?.[val]?.[column.option.displayField] || val).join(', ');
2951
+ };
2952
+ /**
2953
+ * Create badge configuration
2954
+ */
2955
+ const createBadge = (column, value, rowData) => {
2956
+ if (column.useBadge) {
2957
+ const badge = column.useBadge(value, rowData);
2958
+ if (badge) {
2959
+ return {
2960
+ badge: {
2961
+ type: badge.type ?? 'round',
2962
+ color: badge.color,
2963
+ icon: badge.icon,
2964
+ },
2965
+ title: badge.title,
2966
+ };
2967
+ }
2968
+ return undefined;
2969
+ }
2970
+ if ((column.type === 'string' || column.type === 'number' || column.type === 'values') && column.badge) {
2971
+ return {
2972
+ badge: {
2973
+ type: column.badgeType || 'icon',
2974
+ color: column.badge(value, rowData),
2975
+ icon: column.badgeIcon?.(value, rowData),
2976
+ },
2977
+ title: null,
2978
+ };
2979
+ }
2980
+ if (column.type === 'boolean') {
2981
+ return {
2982
+ badge: {
2983
+ type: 'round',
2984
+ color: value ? 'success' : 'error',
2985
+ },
2986
+ };
2987
+ }
2988
+ return undefined;
2989
+ };
2887
2990
  const execute = async (column) => {
2888
- // Clickable
2889
2991
  const { field, click, tooltip, htmlTemplate, transform } = column;
2992
+ // Load lazy-values
2890
2993
  if (!transform && !htmlTemplate && column.type === 'lazy-values' && typeof column.option.views === 'function') {
2891
- const { option: { views, mapValue }, } = column;
2994
+ const { option: { views, mapValue, valueField, displayField }, } = column;
2892
2995
  this.#cacheObjValues[field] = this.#cacheObjValues[field] || {};
2893
2996
  const values = ArrayUtilities.distinct(items
2894
2997
  .map(item => {
2998
+ const value = getNestedValue(item.data, field);
2895
2999
  if (typeof mapValue === 'function') {
2896
- return mapValue(item.data?.[field], item.data);
3000
+ return mapValue(value, item.data);
2897
3001
  }
2898
- return item.data?.[field];
3002
+ return value;
2899
3003
  })
2900
- .filter(val => !!val?.toString())
3004
+ .filter(val => val?.toString())
2901
3005
  .reduce((current, next) => [...current, ...(Array.isArray(next) ? next : [next])], [])
2902
3006
  .filter(val => !Object.keys(this.#cacheObjValues[field]).includes(val)));
2903
3007
  if (values.length) {
@@ -2905,17 +3009,19 @@ class SdTable extends SdBaseSecureComponent {
2905
3009
  console.error(err);
2906
3010
  return [];
2907
3011
  }))
2908
- .filter((item) => values.includes(item?.[column.option.valueField]))
3012
+ .filter((item) => values.includes(item?.[valueField]))
2909
3013
  .map((e) => ({
2910
- [column.option.valueField]: e?.[column.option.valueField],
2911
- [column.option.displayField]: e?.[column.option.displayField],
3014
+ [valueField]: e?.[valueField],
3015
+ [displayField]: e?.[displayField],
2912
3016
  }));
2913
- Object.assign(this.#cacheObjValues[field], ArrayUtilities.toObject(column.option.valueField, lazyItems) || {});
3017
+ Object.assign(this.#cacheObjValues[field], ArrayUtilities.toObject(valueField, lazyItems) || {});
2914
3018
  }
2915
3019
  }
3020
+ // Process each item
2916
3021
  for (const item of items) {
2917
3022
  const rowData = item.data;
2918
- const value = rowData?.[field];
3023
+ const value = getNestedValue(rowData, field);
3024
+ // Initialize display
2919
3025
  item.meta.display[field] = {
2920
3026
  badge: undefined,
2921
3027
  cellStyle: column.align === 'right' ? { 'text-align': 'right!important' } : undefined,
@@ -2925,57 +3031,34 @@ class SdTable extends SdBaseSecureComponent {
2925
3031
  click: typeof click === 'function' ? () => click(value, rowData) : undefined,
2926
3032
  };
2927
3033
  const display = item.meta.display[field];
2928
- // Display
3034
+ // Process display data
2929
3035
  if (typeof htmlTemplate === 'function') {
2930
3036
  display.isHtml = true;
2931
3037
  display.data = htmlTemplate(value, rowData);
2932
3038
  }
2933
3039
  else if (typeof transform === 'function') {
2934
3040
  const newValue = transform(value, rowData);
2935
- if (newValue instanceof Promise) {
2936
- display.data = await newValue;
2937
- }
2938
- else {
2939
- display.data = newValue;
2940
- }
3041
+ display.data = newValue instanceof Promise ? await newValue : newValue;
2941
3042
  }
2942
3043
  else {
3044
+ // Date/Time
2943
3045
  if (column.type === 'date' || column.type === 'datetime' || column.type === 'time') {
2944
- const date = DateUtilities.toFormat(value, 'dd/MM/yyyy');
2945
- let time = DateUtilities.toFormat(value, 'HH:mm:ss');
2946
- // if (time?.endsWith('00')) {
2947
- // time = DateUtilities.toFormat(value, 'HH:mm');
2948
- // }
2949
- if (column.type === 'date' || column.type === 'datetime') {
2950
- if (column.type === 'datetime') {
2951
- display.isHtml = true;
2952
- display.data = time && date ? `<div class="T14R">${date}<span class="T14R text-black400 ml-4">${time}</span></div>` : '';
2953
- }
2954
- else {
2955
- display.data = date;
2956
- }
2957
- }
2958
- if (column.type === 'time') {
2959
- display.data = time;
2960
- }
3046
+ const formatted = formatDateDisplay(value, column.type);
3047
+ display.data = formatted;
3048
+ display.isHtml = column.type === 'datetime';
2961
3049
  }
3050
+ // Values/Lazy-values
2962
3051
  if (column.type === 'values' || column.type === 'lazy-values') {
2963
- if (column.type === 'lazy-values' && typeof column.option.mapValue === 'function') {
2964
- const val = column.option.mapValue(value, rowData);
2965
- const vals = (Array.isArray(val) ? val : [val]).filter(e => !!e?.toString());
2966
- display.data = vals.map(val => this.#cacheObjValues[field]?.[val]?.[column.option.displayField] || val)?.join(', ');
2967
- }
2968
- else {
2969
- const vals = (Array.isArray(value) ? value : [value]).filter(e => !!e?.toString());
2970
- display.data = vals.map(val => this.#cacheObjValues[field]?.[val]?.[column.option.displayField] || val)?.join(', ');
2971
- }
3052
+ display.data = processValuesDisplay(value, rowData, column, field);
2972
3053
  }
3054
+ // Number
2973
3055
  if (column.type === 'number' && NumberUtilities.isNumber(value)) {
2974
3056
  display.data = this.formatNumberPipe.transform(value);
2975
3057
  }
3058
+ // Boolean
2976
3059
  if (column.type === 'boolean') {
2977
3060
  const { option } = column;
2978
- if (value !== undefined && value !== null && value !== '') {
3061
+ if (value != null && value !== '') {
2979
3062
  display.data = value === true ? option?.displayOnTrue || 'True' : option?.displayOnFalse || 'False';
2980
3063
  }
2981
3064
  else {
@@ -2983,31 +3066,14 @@ class SdTable extends SdBaseSecureComponent {
2983
3066
  }
2984
3067
  }
2985
3068
  // Badge
2986
- if (column.useBadge) {
2987
- const badge = column.useBadge(value, rowData);
2988
- if (badge) {
2989
- display.badge = {
2990
- type: badge.type ?? 'round',
2991
- color: badge.color,
2992
- icon: badge.icon,
2993
- };
2994
- display.data = badge.title ?? display.data;
3069
+ const badgeResult = createBadge(column, value, rowData);
3070
+ if (badgeResult) {
3071
+ display.badge = badgeResult.badge;
3072
+ if (badgeResult.title) {
3073
+ display.data = badgeResult.title;
2995
3074
  }
2996
3075
  }
2997
- else if ((column.type === 'string' || column.type === 'number' || column.type === 'values') && column.badge) {
2998
- display.badge = {
2999
- type: !column?.badgeType ? 'icon' : column.badgeType,
3000
- color: column.badge(value, rowData),
3001
- icon: column.badgeIcon?.(value, rowData),
3002
- };
3003
- }
3004
- else if (column.type === 'boolean') {
3005
- display.badge = {
3006
- type: 'round',
3007
- color: value ? 'success' : 'error',
3008
- icon: null,
3009
- };
3010
- }
3076
+ // Handle empty values
3011
3077
  if (display.data === null || display.data === undefined || display.data === '') {
3012
3078
  display.data = SD_EMPTY_STR;
3013
3079
  display.badge = undefined;
@@ -3015,6 +3081,7 @@ class SdTable extends SdBaseSecureComponent {
3015
3081
  }
3016
3082
  }
3017
3083
  };
3084
+ // Execute for all columns
3018
3085
  for (const column of columns.filter(e => !e.hidden)) {
3019
3086
  if (column.type === 'children') {
3020
3087
  for (const childColumn of column.children?.filter(e => !e.hidden) || []) {
@@ -3033,6 +3100,228 @@ class SdTable extends SdBaseSecureComponent {
3033
3100
  trackBy = (index, item) => {
3034
3101
  return item.meta.id;
3035
3102
  };
3103
+ #convertPagingReq = (filterReq) => {
3104
+ const { columns, filter } = this.tableOption;
3105
+ const externalFilters = filter?.externalFilters || [];
3106
+ const req = {
3107
+ filters: [],
3108
+ orders: [],
3109
+ pageNumber: filterReq.pageNumber,
3110
+ pageSize: filterReq.pageSize,
3111
+ };
3112
+ const { filters, orders } = req;
3113
+ const { rawColumnFilter, columnOperator, rawExternalFilter, orderBy, orderDirection } = filterReq;
3114
+ // Xử lý external filter
3115
+ for (const externalFilter of externalFilters || []) {
3116
+ const { field } = externalFilter;
3117
+ const value = rawExternalFilter?.[field];
3118
+ // Nếu có giá trị thì mới xử lý filter
3119
+ if (value !== undefined && value !== null && value !== '') {
3120
+ if (externalFilter.type === 'string') {
3121
+ // Nếu filter là equal và có dấu , ngăn cách thì hiểu là tìm nhiều ngăn cách bởi dấu phẩy
3122
+ if (externalFilter.defaultOperator === 'EQUAL' && value?.includes(',')) {
3123
+ filters.push({
3124
+ field,
3125
+ operator: 'IN',
3126
+ data: value.split(',').map(val => val.trim()),
3127
+ });
3128
+ }
3129
+ else {
3130
+ filters.push({
3131
+ field,
3132
+ operator: externalFilter.defaultOperator || 'CONTAIN',
3133
+ data: value,
3134
+ });
3135
+ }
3136
+ }
3137
+ else if (externalFilter.type === 'boolean') {
3138
+ filters.push({
3139
+ field,
3140
+ operator: 'EQUAL',
3141
+ data: value === true || value === 1 || value === 'true' || value === '1',
3142
+ });
3143
+ }
3144
+ else if (externalFilter.type === 'daterange') {
3145
+ if (typeof value === 'object' && 'from' in value && 'to' in value) {
3146
+ if (value?.from) {
3147
+ filters.push({
3148
+ field,
3149
+ operator: 'GREATER_OR_EQUAL',
3150
+ data: DateUtilities.begin(value?.from).toISOString(),
3151
+ });
3152
+ }
3153
+ if (value?.to) {
3154
+ filters.push({
3155
+ field,
3156
+ operator: 'LESS_THAN',
3157
+ data: DateUtilities.begin(DateUtilities.addDays(value?.to, 1)).toISOString(),
3158
+ });
3159
+ }
3160
+ }
3161
+ }
3162
+ else if (externalFilter.type === 'date' || externalFilter.type === 'datetime') {
3163
+ if (DateUtilities.isDate(value)) {
3164
+ if (externalFilter.type === 'date') {
3165
+ if (externalFilter.defaultOperator === 'GREATER_OR_EQUAL') {
3166
+ filters.push({
3167
+ field,
3168
+ operator: 'GREATER_OR_EQUAL',
3169
+ data: DateUtilities.begin(value).toISOString(),
3170
+ });
3171
+ }
3172
+ if (externalFilter.defaultOperator === 'LESS_OR_EQUAL') {
3173
+ filters.push({
3174
+ field,
3175
+ operator: 'LESS_THAN',
3176
+ data: DateUtilities.begin(DateUtilities.addDays(value, 1)).toISOString(),
3177
+ });
3178
+ }
3179
+ }
3180
+ else {
3181
+ if (externalFilter.defaultOperator === 'GREATER_OR_EQUAL') {
3182
+ filters.push({
3183
+ field,
3184
+ operator: 'GREATER_OR_EQUAL',
3185
+ data: new Date(value).toISOString(),
3186
+ });
3187
+ }
3188
+ if (externalFilter.defaultOperator === 'LESS_OR_EQUAL') {
3189
+ filters.push({
3190
+ field,
3191
+ operator: 'LESS_OR_EQUAL',
3192
+ data: new Date(value).toISOString(),
3193
+ });
3194
+ }
3195
+ }
3196
+ }
3197
+ }
3198
+ else {
3199
+ if (Array.isArray(value)) {
3200
+ if (value.length) {
3201
+ filters.push({
3202
+ field,
3203
+ operator: 'IN',
3204
+ data: value,
3205
+ });
3206
+ }
3207
+ }
3208
+ else if (typeof value === 'object' && 'from' in value && 'to' in value) {
3209
+ if (value?.from) {
3210
+ filters.push({
3211
+ field,
3212
+ operator: 'GREATER_OR_EQUAL',
3213
+ data: DateUtilities.begin(value?.from).toISOString(),
3214
+ });
3215
+ }
3216
+ if (value?.to) {
3217
+ filters.push({
3218
+ field,
3219
+ operator: 'LESS_THAN',
3220
+ data: DateUtilities.begin(DateUtilities.addDays(value?.to, 1)).toISOString(),
3221
+ });
3222
+ }
3223
+ }
3224
+ else {
3225
+ filters.push({
3226
+ field,
3227
+ operator: externalFilter.defaultOperator || 'EQUAL',
3228
+ data: value,
3229
+ });
3230
+ }
3231
+ }
3232
+ }
3233
+ }
3234
+ // Xử lý column filter
3235
+ // Xử lý column filter
3236
+ for (const column of columns || []) {
3237
+ const { field } = column;
3238
+ const value = rawColumnFilter?.[field];
3239
+ const operator = columnOperator?.[field] || column.filter?.operator?.default;
3240
+ // Nếu có giá trị thì mới xử lý filter
3241
+ if (value !== undefined && value !== null && value !== '') {
3242
+ if (column.type === 'string') {
3243
+ filters.push({
3244
+ field,
3245
+ operator: operator || 'CONTAIN',
3246
+ data: value,
3247
+ });
3248
+ }
3249
+ else if (column.type === 'boolean') {
3250
+ filters.push({
3251
+ field,
3252
+ operator: 'EQUAL',
3253
+ data: value === true || value === 1 || value === 'true' || value === '1',
3254
+ });
3255
+ }
3256
+ else if (column.type === 'date' || column.type === 'datetime') {
3257
+ if (value && typeof value === 'object' && 'from' in value && 'to' in value) {
3258
+ if (value?.from && value?.to) {
3259
+ filters.push({
3260
+ field,
3261
+ operator: 'BETWEEN',
3262
+ data: {
3263
+ from: DateUtilities.begin(value?.from).toISOString(),
3264
+ to: DateUtilities.end(value?.to).toISOString(),
3265
+ },
3266
+ });
3267
+ }
3268
+ else if (value?.from) {
3269
+ filters.push({
3270
+ field,
3271
+ operator: 'GREATER_OR_EQUAL',
3272
+ data: DateUtilities.begin(value?.from).toISOString(),
3273
+ });
3274
+ }
3275
+ else if (value?.to) {
3276
+ filters.push({
3277
+ field,
3278
+ operator: 'LESS_THAN',
3279
+ data: DateUtilities.begin(DateUtilities.addDays(value?.to, 1)).toISOString(),
3280
+ });
3281
+ }
3282
+ }
3283
+ else {
3284
+ if (DateUtilities.isDate(value)) {
3285
+ filters.push({
3286
+ field,
3287
+ operator: 'BETWEEN',
3288
+ data: {
3289
+ from: DateUtilities.begin(value).toISOString(),
3290
+ to: DateUtilities.end(value).toISOString(),
3291
+ },
3292
+ });
3293
+ }
3294
+ }
3295
+ }
3296
+ else {
3297
+ if (Array.isArray(value)) {
3298
+ if (value.length) {
3299
+ filters.push({
3300
+ field,
3301
+ operator: 'IN',
3302
+ data: value,
3303
+ });
3304
+ }
3305
+ }
3306
+ else {
3307
+ filters.push({
3308
+ field,
3309
+ operator: operator || 'EQUAL',
3310
+ data: value,
3311
+ });
3312
+ }
3313
+ }
3314
+ }
3315
+ }
3316
+ // Xử lý orders
3317
+ if (orderBy && orderDirection) {
3318
+ orders.push({
3319
+ field: orderBy,
3320
+ direction: orderDirection,
3321
+ });
3322
+ }
3323
+ return req;
3324
+ };
3036
3325
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdTable, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$4.SdFormatNumberPipe }, { token: SD_TABLE_CONFIGURATION, optional: true }, { token: ConfigService }, { token: i1$1.SdExcelService }, { token: i1$1.SdNotifyService }, { token: SdTableFilterService }], target: i0.ɵɵFactoryTarget.Component });
3037
3326
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: SdTable, isStandalone: true, selector: "sd-table", inputs: { _autoId: ["autoId", "_autoId"], option: "option" }, providers: [
3038
3327
  DatePipe,
@@ -3255,7 +3544,6 @@ const SdConvertToPagingReq = (filterRequest, args) => {
3255
3544
  });
3256
3545
  }
3257
3546
  else if (column.type === 'date' || column.type === 'datetime') {
3258
- console.log(value);
3259
3547
  if (typeof value === 'object' && 'from' in value && 'to' in value) {
3260
3548
  if (value?.from && value?.to) {
3261
3549
  filters.push({