@sdcorejs/angular 20.0.0 → 20.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -19
- package/assets/scss/core/_inline-edit.scss +105 -0
- package/assets/scss/core/form.scss +15 -0
- package/components/autoid-inspector/index.d.ts +53 -4
- package/components/form-generic/index.d.ts +12 -13
- package/components/index.d.ts +1 -0
- package/components/modal-resizable/index.d.ts +32 -0
- package/components/table/index.d.ts +99 -10
- package/components/view/index.d.ts +33 -0
- package/fesm2022/sdcorejs-angular-components-anchor.mjs +9 -9
- package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs +111 -24
- package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-avatar.mjs +4 -4
- package/fesm2022/sdcorejs-angular-components-avatar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-badge.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-base.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-button.mjs +4 -4
- package/fesm2022/sdcorejs-angular-components-button.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-chart.mjs +12 -12
- package/fesm2022/sdcorejs-angular-components-ckeditor-styles.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-code-editor.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-document-builder.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-editor.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs +288 -375
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-history.mjs +7 -7
- package/fesm2022/sdcorejs-angular-components-import-excel.mjs +10 -10
- package/fesm2022/sdcorejs-angular-components-inform.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-mini-editor.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs +158 -0
- package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-components-modal.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-operator.mjs +6 -4
- package/fesm2022/sdcorejs-angular-components-operator.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-preview.mjs +8 -8
- package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs +60 -106
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-quick-action.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-section.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +4 -4
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-splitter.mjs +12 -12
- package/fesm2022/sdcorejs-angular-components-stepper.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-tab-router.mjs +18 -18
- package/fesm2022/sdcorejs-angular-components-tab.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-table.mjs +335 -208
- package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs +16 -16
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-view.mjs +45 -13
- package/fesm2022/sdcorejs-angular-components-view.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components.mjs +1 -0
- package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-directives.mjs +21 -21
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +28 -8
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs +11 -6
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +15 -10
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip.mjs +15 -10
- package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs +21 -12
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date.mjs +29 -17
- package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs +34 -22
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-directives.mjs +12 -12
- package/fesm2022/sdcorejs-angular-forms-inline-text.mjs +167 -0
- package/fesm2022/sdcorejs-angular-forms-inline-text.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs +7 -5
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs +37 -10
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input.mjs +38 -12
- package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-label.mjs +3 -3
- package/fesm2022/sdcorejs-angular-forms-models.mjs +32 -2
- package/fesm2022/sdcorejs-angular-forms-models.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-radio.mjs +11 -6
- package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-select.mjs +36 -12
- package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-switch.mjs +11 -6
- package/fesm2022/sdcorejs-angular-forms-switch.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs +17 -7
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms.mjs +4 -4
- package/fesm2022/sdcorejs-angular-handlers.mjs +3 -3
- package/fesm2022/sdcorejs-angular-i18n.mjs +26 -6
- package/fesm2022/sdcorejs-angular-i18n.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-interceptors.mjs +6 -6
- package/fesm2022/sdcorejs-angular-modules-auth.mjs +9 -9
- package/fesm2022/sdcorejs-angular-modules-authom.mjs +7 -7
- package/fesm2022/sdcorejs-angular-modules-keycloak.mjs +7 -7
- package/fesm2022/sdcorejs-angular-modules-layout.mjs +73 -73
- package/fesm2022/sdcorejs-angular-modules-permission.mjs +9 -9
- package/fesm2022/sdcorejs-angular-pipes.mjs +14 -14
- package/fesm2022/sdcorejs-angular-services-api.mjs +10 -10
- package/fesm2022/sdcorejs-angular-services-cache.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-confirm.mjs +6 -6
- package/fesm2022/sdcorejs-angular-services-confirm.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-docx.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-excel.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-license.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-loading.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-notify.mjs +23 -10
- package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-storage.mjs +3 -3
- package/forms/autocomplete/index.d.ts +16 -3
- package/forms/checkbox/index.d.ts +5 -1
- package/forms/chip/index.d.ts +5 -2
- package/forms/chip-calendar/index.d.ts +5 -2
- package/forms/date/index.d.ts +14 -5
- package/forms/date-range/index.d.ts +12 -5
- package/forms/datetime/index.d.ts +14 -5
- package/forms/inline-text/index.d.ts +80 -0
- package/forms/input/index.d.ts +14 -2
- package/forms/input-color/index.d.ts +3 -1
- package/forms/input-number/index.d.ts +14 -2
- package/forms/models/index.d.ts +40 -2
- package/forms/radio/index.d.ts +5 -2
- package/forms/select/index.d.ts +23 -5
- package/forms/switch/index.d.ts +5 -2
- package/forms/textarea/index.d.ts +9 -2
- package/i18n/index.d.ts +4 -0
- package/package.json +10 -1
|
@@ -62,10 +62,10 @@ class SdTableCellDefDirective {
|
|
|
62
62
|
}
|
|
63
63
|
sdTableCellDef = input.required(...(ngDevMode ? [{ debugName: "sdTableCellDef" }] : []));
|
|
64
64
|
templateRef = inject(TemplateRef);
|
|
65
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
66
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.
|
|
65
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTableCellDefDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
66
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.24", type: SdTableCellDefDirective, isStandalone: true, selector: "[sdTableCellDef]", inputs: { sdTableCellDef: { classPropertyName: "sdTableCellDef", publicName: "sdTableCellDef", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
|
|
67
67
|
}
|
|
68
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
68
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTableCellDefDirective, decorators: [{
|
|
69
69
|
type: Directive,
|
|
70
70
|
args: [{
|
|
71
71
|
selector: '[sdTableCellDef]',
|
|
@@ -77,10 +77,10 @@ class SdTableExpandDefDirective {
|
|
|
77
77
|
return true;
|
|
78
78
|
}
|
|
79
79
|
templateRef = inject(TemplateRef);
|
|
80
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
81
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.
|
|
80
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTableExpandDefDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
81
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.24", type: SdTableExpandDefDirective, isStandalone: true, selector: "[sdTableExpandDef]", ngImport: i0 });
|
|
82
82
|
}
|
|
83
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
83
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTableExpandDefDirective, decorators: [{
|
|
84
84
|
type: Directive,
|
|
85
85
|
args: [{
|
|
86
86
|
selector: '[sdTableExpandDef]',
|
|
@@ -94,10 +94,10 @@ class SdTableFilterDefDirective {
|
|
|
94
94
|
sdTableFilterDef = input.required(...(ngDevMode ? [{ debugName: "sdTableFilterDef" }] : []));
|
|
95
95
|
defaultShowing = input(false, ...(ngDevMode ? [{ debugName: "defaultShowing", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
96
96
|
templateRef = inject(TemplateRef, { optional: true });
|
|
97
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
98
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.
|
|
97
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTableFilterDefDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
98
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.24", type: SdTableFilterDefDirective, isStandalone: true, selector: "[sdTableFilterDef]", inputs: { sdTableFilterDef: { classPropertyName: "sdTableFilterDef", publicName: "sdTableFilterDef", isSignal: true, isRequired: true, transformFunction: null }, defaultShowing: { classPropertyName: "defaultShowing", publicName: "defaultShowing", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
|
|
99
99
|
}
|
|
100
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
100
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTableFilterDefDirective, decorators: [{
|
|
101
101
|
type: Directive,
|
|
102
102
|
args: [{
|
|
103
103
|
selector: '[sdTableFilterDef]',
|
|
@@ -110,10 +110,10 @@ class SdMaterialFooterDefDirective {
|
|
|
110
110
|
}
|
|
111
111
|
sdTableFooterDef = input.required(...(ngDevMode ? [{ debugName: "sdTableFooterDef" }] : []));
|
|
112
112
|
templateRef = inject(TemplateRef);
|
|
113
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
114
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.
|
|
113
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdMaterialFooterDefDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
114
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.24", type: SdMaterialFooterDefDirective, isStandalone: true, selector: "[sdTableFooterDef]", inputs: { sdTableFooterDef: { classPropertyName: "sdTableFooterDef", publicName: "sdTableFooterDef", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
|
|
115
115
|
}
|
|
116
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
116
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdMaterialFooterDefDirective, decorators: [{
|
|
117
117
|
type: Directive,
|
|
118
118
|
args: [{
|
|
119
119
|
selector: '[sdTableFooterDef]',
|
|
@@ -140,10 +140,10 @@ class SdTableGroupDefDirective {
|
|
|
140
140
|
return true;
|
|
141
141
|
}
|
|
142
142
|
templateRef = inject(TemplateRef);
|
|
143
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
144
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.
|
|
143
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTableGroupDefDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
144
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.24", type: SdTableGroupDefDirective, isStandalone: true, selector: "[sdTableGroupDef]", ngImport: i0 });
|
|
145
145
|
}
|
|
146
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
146
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTableGroupDefDirective, decorators: [{
|
|
147
147
|
type: Directive,
|
|
148
148
|
args: [{ selector: '[sdTableGroupDef]' }]
|
|
149
149
|
}] });
|
|
@@ -154,10 +154,10 @@ class SdTableTitleDefDirective {
|
|
|
154
154
|
}
|
|
155
155
|
sdTableTitleDef = input.required(...(ngDevMode ? [{ debugName: "sdTableTitleDef" }] : []));
|
|
156
156
|
templateRef = inject(TemplateRef);
|
|
157
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
158
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.
|
|
157
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTableTitleDefDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
158
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.24", type: SdTableTitleDefDirective, isStandalone: true, selector: "[sdTableTitleDef]", inputs: { sdTableTitleDef: { classPropertyName: "sdTableTitleDef", publicName: "sdTableTitleDef", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
|
|
159
159
|
}
|
|
160
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
160
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTableTitleDefDirective, decorators: [{
|
|
161
161
|
type: Directive,
|
|
162
162
|
args: [{
|
|
163
163
|
selector: '[sdTableTitleDef]',
|
|
@@ -175,10 +175,10 @@ class ColumnTitleComponent {
|
|
|
175
175
|
}
|
|
176
176
|
return this.titleDef()?.templateRef;
|
|
177
177
|
}, ...(ngDevMode ? [{ debugName: "templateRef" }] : []));
|
|
178
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
179
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
178
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ColumnTitleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
179
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: ColumnTitleComponent, isStandalone: true, selector: "column-title", inputs: { column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, titleDef: { classPropertyName: "titleDef", publicName: "titleDef", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@let _column = column();\n@let _templateRef = templateRef();\n\n@if (_templateRef) {\n <ng-container *ngTemplateOutlet=\"_templateRef\"></ng-container>\n} @else {\n {{ _column.title }}\n}\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
180
180
|
}
|
|
181
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
181
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ColumnTitleComponent, decorators: [{
|
|
182
182
|
type: Component,
|
|
183
183
|
args: [{ selector: 'column-title', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [NgTemplateOutlet], template: "@let _column = column();\n@let _templateRef = templateRef();\n\n@if (_templateRef) {\n <ng-container *ngTemplateOutlet=\"_templateRef\"></ng-container>\n} @else {\n {{ _column.title }}\n}\n" }]
|
|
184
184
|
}], propDecorators: { column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }], titleDef: [{ type: i0.Input, args: [{ isSignal: true, alias: "titleDef", required: false }] }] } });
|
|
@@ -279,10 +279,10 @@ class ColumnFilterComponent {
|
|
|
279
279
|
onFilterChange = () => this.filterChange.emit();
|
|
280
280
|
// Blur input: commit giá trị KHÔNG trigger reload.
|
|
281
281
|
onFilterCommit = () => this.filterCommit.emit();
|
|
282
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
283
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.23", type: ColumnFilterComponent, isStandalone: true, selector: "column-filter", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, columnFilter: { classPropertyName: "columnFilter", publicName: "columnFilter", isSignal: true, isRequired: false, transformFunction: null }, cacheValues: { classPropertyName: "cacheValues", publicName: "cacheValues", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, operator: { classPropertyName: "operator", publicName: "operator", isSignal: true, isRequired: false, transformFunction: null }, isMobile: { classPropertyName: "isMobile", publicName: "isMobile", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { operator: "operatorChange", filterChange: "filterChange", filterCommit: "filterCommit" }, ngImport: i0, template: "@let _column = column();\n@let _columnFilter = columnFilter();\n@let _autoId = autoId();\n@let _templateRef = templateRef();\n@let _operators = operators();\n@let _items = items();\n@let _label = label();\n@let _context = { columnFilter: _columnFilter, autoId: _autoId };\n\n<div class=\"d-flex c-inline-column align-items-end\" style=\"width: 100%; max-width: 100%\">\n @if (\n _column.type === 'string' ||\n _column.type === 'number' ||\n _column.type === 'boolean' ||\n _column.type === 'values' ||\n _column.type === 'lazy-values' ||\n _column.type === 'date' ||\n _column.type === 'datetime' ||\n _column.type === 'time'\n ) {\n <!-- Operator filter -->\n @if (_operators.length) {\n <div class=\"d-flex align-items-center\" [ngClass]=\"operatorWrapperClass()\">\n <sd-operator [(model)]=\"operator\" [operators]=\"operatorValues()\" />\n </div>\n }\n\n <!-- N\u1EBFu filter nh\u1EADn v\u00E0o template -->\n @if (_templateRef) {\n <ng-container *ngTemplateOutlet=\"_templateRef; context: _context\"></ng-container>\n }\n <!-- M\u1EB7c \u0111\u1ECBnh theo type v\u00E0 gi\u00E1 tr\u1ECB values defined c\u1EE7a column -->\n @else {\n @if (_column.type === 'string') {\n <sd-input\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n type=\"text\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[_column.field]\"\n (keyupEnter)=\"onFilterChange()\"\n (sdBlur)=\"onFilterCommit()\"\n (cleared)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n </sd-input>\n } @else if (_column.type === 'number') {\n @if (!_column.filter?.type) {\n <sd-input-number\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[_column.field]\"\n (keyupEnter)=\"onFilterChange()\"\n (sdBlur)=\"onFilterCommit()\"\n (cleared)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n </sd-input-number>\n } @else if (_column.filter?.type === 'split-number') {\n <ng-container\n *ngTemplateOutlet=\"splitNumberTpl; context: { field: _column.field, disabled: _column.filter?.disabled }\">\n </ng-container>\n }\n } @else if (_column.type === 'boolean') {\n <sd-select\n minWidthPanel=\"200px\"\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n [style.width]=\"'100%'\"\n size=\"sm\"\n [label]=\"_label\"\n [items]=\"[\n { value: '1', display: _column.option?.displayOnTrue || 'True' },\n { value: '0', display: _column.option?.displayOnFalse || 'False' },\n ]\"\n valueField=\"value\"\n displayField=\"display\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n <ng-template sdItemDef let-item=\"item\">\n @if (item.value === '1') {\n <sd-badge color=\"success\" [title]=\"_column.option?.displayOnTrue || 'True'\"> </sd-badge>\n } @else {\n <sd-badge color=\"error\" [title]=\"_column.option?.displayOnFalse || 'False'\"> </sd-badge>\n }\n </ng-template>\n </sd-select>\n } @else if (_column.type === 'values') {\n <sd-select\n minWidthPanel=\"200px\"\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n [style.width]=\"'100%'\"\n size=\"sm\"\n [label]=\"_label\"\n [items]=\"_items\"\n [valueField]=\"_column.option.valueField\"\n [displayField]=\"_column.option.displayField\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n [multiple]=\"_column.option.selection === 'MULTIPLE'\"\n hideInlineError>\n </sd-select>\n } @else if (_column.type === 'lazy-values') {\n <sd-select\n minWidthPanel=\"200px\"\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n [style.width]=\"'100%'\"\n size=\"sm\"\n [label]=\"_label\"\n [items]=\"_items\"\n [valueField]=\"_column.option.valueField\"\n [displayField]=\"_column.option.displayField\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n [multiple]=\"_column.option.selection === 'MULTIPLE'\"\n hideInlineError>\n </sd-select>\n } @else if (_column.type === 'date' || _column.type === 'datetime' || _column.type === 'time') {\n @if (!_column.filter?.type || _column.filter?.type === 'daterange') {\n <sd-date-range\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n </sd-date-range>\n } @else if (_column.filter?.type === 'date') {\n <sd-date\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n type=\"date\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n </sd-date>\n } @else if (_column.filter?.type === 'split-date') {\n <ng-container\n *ngTemplateOutlet=\"splitDateTpl; context: { field: _column.field, disabled: _column.filter?.disabled }\">\n </ng-container>\n }\n }\n }\n } @else {\n <sd-input [autoId]=\"_autoId\" style=\"flex: 1 1 0%; min-width: 0\" type=\"text\" size=\"sm\" disabled></sd-input>\n }\n</div>\n\n<!-- ================================================ -->\n<!-- Split from/to templates (\u0111\u01B0a xu\u1ED1ng cu\u1ED1i file) -->\n<!-- ================================================ -->\n<ng-template #splitNumberTpl let-field=\"field\" let-disabled=\"disabled\">\n <div class=\"d-flex align-items-center\" style=\"flex: 1 1 0%; min-width: 0\">\n <sd-input-number\n [autoId]=\"_autoId + '-from'\"\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[field].from\"\n (sdChange)=\"onFilterChange()\"\n (sdBlur)=\"onFilterCommit()\"\n (cleared)=\"onFilterChange()\"\n [disabled]=\"disabled\"\n hideInlineError>\n </sd-input-number>\n <div class=\"mx-4\">-</div>\n <sd-input-number\n [autoId]=\"_autoId + '-to'\"\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n [(model)]=\"_columnFilter[field].to\"\n (sdChange)=\"onFilterChange()\"\n (sdBlur)=\"onFilterCommit()\"\n (cleared)=\"onFilterChange()\"\n [disabled]=\"disabled\"\n hideInlineError>\n </sd-input-number>\n </div>\n</ng-template>\n\n<ng-template #splitDateTpl let-field=\"field\" let-disabled=\"disabled\">\n <div class=\"d-flex align-items-center\" style=\"flex: 1 1 0%; min-width: 0\">\n <sd-date\n [autoId]=\"_autoId + '-from'\"\n style=\"flex: 1 1 0%; min-width: 0\"\n type=\"date\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[field].from\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"disabled\"\n hideInlineError>\n </sd-date>\n <div class=\"mx-4\">-</div>\n <sd-date\n [autoId]=\"_autoId + '-to'\"\n style=\"flex: 1 1 0%; min-width: 0\"\n type=\"date\"\n size=\"sm\"\n [(model)]=\"_columnFilter[field].to\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"disabled\"\n hideInlineError>\n </sd-date>\n </div>\n</ng-template>\n", styles: [":host ::ng-deep .c-inline-column .mat-mdc-text-field-wrapper{background-color:#fff}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: SdOperator, selector: "sd-operator", inputs: ["model", "operators", "disabled", "autoId"], outputs: ["modelChange"] }, { kind: "component", type: SdInput, selector: "sd-input", inputs: ["autoId", "name", "appearance", "floatLabel", "size", "form", "label", "helperText", "placeholder", "type", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "minlength", "maxlength", "pattern", "patternErrorMessage", "validator", "inlineError", "hyperlink", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "cleared", "sdFocusForceBlur"] }, { kind: "component", type: SdInputNumber, selector: "sd-input-number", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "type", "precision", "format", "min", "max", "validator", "inlineError", "hyperlink", "appearance", "floatLabel", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "cleared", "sdFocusForceBlur"] }, { kind: "component", type: SdSelect, selector: "sd-select", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "valueField", "displayField", "disabledField", "cacheChecksum", "limit", "hyperlink", "minWidthPanel", "hideInlineError", "required", "disabled", "viewed", "multiple", "bare", "validator", "inlineError", "appearance", "floatLabel", "items", "model"], outputs: ["modelChange", "sdChange", "sdSelection"] }, { kind: "component", type: SdDate, selector: "sd-date", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "bare", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdDateRange, selector: "sd-date-range", inputs: ["autoId", "name", "size", "form", "label", "helperText", "hideInlineError", "required", "disabled", "bare", "viewed", "appearance", "floatLabel", "min", "max", "model"], outputs: ["modelChange", "sdChange"] }, { kind: "component", type: SdBadge, selector: "sd-badge", inputs: ["type", "color", "primary", "secondary", "success", "info", "warning", "error", "fontSet", "title", "description", "tooltip", "icon", "size"], outputs: ["click"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
282
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ColumnFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
283
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: ColumnFilterComponent, isStandalone: true, selector: "column-filter", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, columnFilter: { classPropertyName: "columnFilter", publicName: "columnFilter", isSignal: true, isRequired: false, transformFunction: null }, cacheValues: { classPropertyName: "cacheValues", publicName: "cacheValues", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, operator: { classPropertyName: "operator", publicName: "operator", isSignal: true, isRequired: false, transformFunction: null }, isMobile: { classPropertyName: "isMobile", publicName: "isMobile", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { operator: "operatorChange", filterChange: "filterChange", filterCommit: "filterCommit" }, ngImport: i0, template: "@let _column = column();\n@let _columnFilter = columnFilter();\n@let _autoId = autoId();\n@let _templateRef = templateRef();\n@let _operators = operators();\n@let _items = items();\n@let _label = label();\n@let _context = { columnFilter: _columnFilter, autoId: _autoId };\n\n<div class=\"d-flex c-inline-column align-items-end\" style=\"width: 100%; max-width: 100%\">\n @if (\n _column.type === 'string' ||\n _column.type === 'number' ||\n _column.type === 'boolean' ||\n _column.type === 'values' ||\n _column.type === 'lazy-values' ||\n _column.type === 'date' ||\n _column.type === 'datetime' ||\n _column.type === 'time'\n ) {\n <!-- Operator filter -->\n @if (_operators.length) {\n <div class=\"d-flex align-items-center\" [ngClass]=\"operatorWrapperClass()\">\n <sd-operator [(model)]=\"operator\" [operators]=\"operatorValues()\" />\n </div>\n }\n\n <!-- N\u1EBFu filter nh\u1EADn v\u00E0o template -->\n @if (_templateRef) {\n <ng-container *ngTemplateOutlet=\"_templateRef; context: _context\"></ng-container>\n }\n <!-- M\u1EB7c \u0111\u1ECBnh theo type v\u00E0 gi\u00E1 tr\u1ECB values defined c\u1EE7a column -->\n @else {\n @if (_column.type === 'string') {\n <sd-input\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n type=\"text\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[_column.field]\"\n (keyupEnter)=\"onFilterChange()\"\n (sdBlur)=\"onFilterCommit()\"\n (cleared)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n </sd-input>\n } @else if (_column.type === 'number') {\n @if (!_column.filter?.type) {\n <sd-input-number\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[_column.field]\"\n (keyupEnter)=\"onFilterChange()\"\n (sdBlur)=\"onFilterCommit()\"\n (cleared)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n </sd-input-number>\n } @else if (_column.filter?.type === 'split-number') {\n <ng-container\n *ngTemplateOutlet=\"splitNumberTpl; context: { field: _column.field, disabled: _column.filter?.disabled }\">\n </ng-container>\n }\n } @else if (_column.type === 'boolean') {\n <sd-select\n minWidthPanel=\"200px\"\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n [style.width]=\"'100%'\"\n size=\"sm\"\n [label]=\"_label\"\n [items]=\"[\n { value: '1', display: _column.option?.displayOnTrue || 'True' },\n { value: '0', display: _column.option?.displayOnFalse || 'False' },\n ]\"\n valueField=\"value\"\n displayField=\"display\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n <ng-template sdItemDef let-item=\"item\">\n @if (item.value === '1') {\n <sd-badge color=\"success\" [title]=\"_column.option?.displayOnTrue || 'True'\"> </sd-badge>\n } @else {\n <sd-badge color=\"error\" [title]=\"_column.option?.displayOnFalse || 'False'\"> </sd-badge>\n }\n </ng-template>\n </sd-select>\n } @else if (_column.type === 'values') {\n <sd-select\n minWidthPanel=\"200px\"\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n [style.width]=\"'100%'\"\n size=\"sm\"\n [label]=\"_label\"\n [items]=\"_items\"\n [valueField]=\"_column.option.valueField\"\n [displayField]=\"_column.option.displayField\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n [multiple]=\"_column.option.selection === 'MULTIPLE'\"\n hideInlineError>\n </sd-select>\n } @else if (_column.type === 'lazy-values') {\n <sd-select\n minWidthPanel=\"200px\"\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n [style.width]=\"'100%'\"\n size=\"sm\"\n [label]=\"_label\"\n [items]=\"_items\"\n [valueField]=\"_column.option.valueField\"\n [displayField]=\"_column.option.displayField\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n [multiple]=\"_column.option.selection === 'MULTIPLE'\"\n hideInlineError>\n </sd-select>\n } @else if (_column.type === 'date' || _column.type === 'datetime' || _column.type === 'time') {\n @if (!_column.filter?.type || _column.filter?.type === 'daterange') {\n <sd-date-range\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n </sd-date-range>\n } @else if (_column.filter?.type === 'date') {\n <sd-date\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n type=\"date\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n </sd-date>\n } @else if (_column.filter?.type === 'split-date') {\n <ng-container\n *ngTemplateOutlet=\"splitDateTpl; context: { field: _column.field, disabled: _column.filter?.disabled }\">\n </ng-container>\n }\n }\n }\n } @else {\n <sd-input [autoId]=\"_autoId\" style=\"flex: 1 1 0%; min-width: 0\" type=\"text\" size=\"sm\" disabled></sd-input>\n }\n</div>\n\n<!-- ================================================ -->\n<!-- Split from/to templates (\u0111\u01B0a xu\u1ED1ng cu\u1ED1i file) -->\n<!-- ================================================ -->\n<ng-template #splitNumberTpl let-field=\"field\" let-disabled=\"disabled\">\n <div class=\"d-flex align-items-center\" style=\"flex: 1 1 0%; min-width: 0\">\n <sd-input-number\n [autoId]=\"_autoId + '-from'\"\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[field].from\"\n (sdChange)=\"onFilterChange()\"\n (sdBlur)=\"onFilterCommit()\"\n (cleared)=\"onFilterChange()\"\n [disabled]=\"disabled\"\n hideInlineError>\n </sd-input-number>\n <div class=\"mx-4\">-</div>\n <sd-input-number\n [autoId]=\"_autoId + '-to'\"\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n [(model)]=\"_columnFilter[field].to\"\n (sdChange)=\"onFilterChange()\"\n (sdBlur)=\"onFilterCommit()\"\n (cleared)=\"onFilterChange()\"\n [disabled]=\"disabled\"\n hideInlineError>\n </sd-input-number>\n </div>\n</ng-template>\n\n<ng-template #splitDateTpl let-field=\"field\" let-disabled=\"disabled\">\n <div class=\"d-flex align-items-center\" style=\"flex: 1 1 0%; min-width: 0\">\n <sd-date\n [autoId]=\"_autoId + '-from'\"\n style=\"flex: 1 1 0%; min-width: 0\"\n type=\"date\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[field].from\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"disabled\"\n hideInlineError>\n </sd-date>\n <div class=\"mx-4\">-</div>\n <sd-date\n [autoId]=\"_autoId + '-to'\"\n style=\"flex: 1 1 0%; min-width: 0\"\n type=\"date\"\n size=\"sm\"\n [(model)]=\"_columnFilter[field].to\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"disabled\"\n hideInlineError>\n </sd-date>\n </div>\n</ng-template>\n", styles: [":host ::ng-deep .c-inline-column .mat-mdc-text-field-wrapper{background-color:#fff}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: SdOperator, selector: "sd-operator", inputs: ["model", "operators", "disabled", "autoId"], outputs: ["modelChange"] }, { kind: "component", type: SdInput, selector: "sd-input", inputs: ["autoId", "name", "appearance", "floatLabel", "size", "form", "label", "helperText", "placeholder", "type", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "minlength", "maxlength", "pattern", "patternErrorMessage", "validator", "inlineError", "hyperlink", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "cleared", "sdFocusForceBlur"] }, { kind: "component", type: SdInputNumber, selector: "sd-input-number", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "type", "precision", "format", "min", "max", "validator", "inlineError", "hyperlink", "appearance", "floatLabel", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "cleared", "sdFocusForceBlur"] }, { kind: "component", type: SdSelect, selector: "sd-select", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "valueField", "displayField", "disabledField", "cacheChecksum", "limit", "hyperlink", "minWidthPanel", "hideInlineError", "required", "disabled", "viewed", "multiple", "clearable", "validator", "inlineError", "appearance", "floatLabel", "items", "model"], outputs: ["modelChange", "sdChange", "sdSelection"] }, { kind: "component", type: SdDate, selector: "sd-date", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "clearable", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdDateRange, selector: "sd-date-range", inputs: ["autoId", "name", "size", "form", "label", "helperText", "hideInlineError", "required", "disabled", "viewed", "clearable", "appearance", "floatLabel", "min", "max", "model"], outputs: ["modelChange", "sdChange"] }, { kind: "component", type: SdBadge, selector: "sd-badge", inputs: ["type", "color", "primary", "secondary", "success", "info", "warning", "error", "fontSet", "title", "description", "tooltip", "icon", "size"], outputs: ["click"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
284
284
|
}
|
|
285
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
285
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ColumnFilterComponent, decorators: [{
|
|
286
286
|
type: Component,
|
|
287
287
|
args: [{ selector: 'column-filter', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, SdOperator, SdInput, SdInputNumber, SdSelect, SdDate, SdDateRange, SdBadge], template: "@let _column = column();\n@let _columnFilter = columnFilter();\n@let _autoId = autoId();\n@let _templateRef = templateRef();\n@let _operators = operators();\n@let _items = items();\n@let _label = label();\n@let _context = { columnFilter: _columnFilter, autoId: _autoId };\n\n<div class=\"d-flex c-inline-column align-items-end\" style=\"width: 100%; max-width: 100%\">\n @if (\n _column.type === 'string' ||\n _column.type === 'number' ||\n _column.type === 'boolean' ||\n _column.type === 'values' ||\n _column.type === 'lazy-values' ||\n _column.type === 'date' ||\n _column.type === 'datetime' ||\n _column.type === 'time'\n ) {\n <!-- Operator filter -->\n @if (_operators.length) {\n <div class=\"d-flex align-items-center\" [ngClass]=\"operatorWrapperClass()\">\n <sd-operator [(model)]=\"operator\" [operators]=\"operatorValues()\" />\n </div>\n }\n\n <!-- N\u1EBFu filter nh\u1EADn v\u00E0o template -->\n @if (_templateRef) {\n <ng-container *ngTemplateOutlet=\"_templateRef; context: _context\"></ng-container>\n }\n <!-- M\u1EB7c \u0111\u1ECBnh theo type v\u00E0 gi\u00E1 tr\u1ECB values defined c\u1EE7a column -->\n @else {\n @if (_column.type === 'string') {\n <sd-input\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n type=\"text\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[_column.field]\"\n (keyupEnter)=\"onFilterChange()\"\n (sdBlur)=\"onFilterCommit()\"\n (cleared)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n </sd-input>\n } @else if (_column.type === 'number') {\n @if (!_column.filter?.type) {\n <sd-input-number\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[_column.field]\"\n (keyupEnter)=\"onFilterChange()\"\n (sdBlur)=\"onFilterCommit()\"\n (cleared)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n </sd-input-number>\n } @else if (_column.filter?.type === 'split-number') {\n <ng-container\n *ngTemplateOutlet=\"splitNumberTpl; context: { field: _column.field, disabled: _column.filter?.disabled }\">\n </ng-container>\n }\n } @else if (_column.type === 'boolean') {\n <sd-select\n minWidthPanel=\"200px\"\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n [style.width]=\"'100%'\"\n size=\"sm\"\n [label]=\"_label\"\n [items]=\"[\n { value: '1', display: _column.option?.displayOnTrue || 'True' },\n { value: '0', display: _column.option?.displayOnFalse || 'False' },\n ]\"\n valueField=\"value\"\n displayField=\"display\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n <ng-template sdItemDef let-item=\"item\">\n @if (item.value === '1') {\n <sd-badge color=\"success\" [title]=\"_column.option?.displayOnTrue || 'True'\"> </sd-badge>\n } @else {\n <sd-badge color=\"error\" [title]=\"_column.option?.displayOnFalse || 'False'\"> </sd-badge>\n }\n </ng-template>\n </sd-select>\n } @else if (_column.type === 'values') {\n <sd-select\n minWidthPanel=\"200px\"\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n [style.width]=\"'100%'\"\n size=\"sm\"\n [label]=\"_label\"\n [items]=\"_items\"\n [valueField]=\"_column.option.valueField\"\n [displayField]=\"_column.option.displayField\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n [multiple]=\"_column.option.selection === 'MULTIPLE'\"\n hideInlineError>\n </sd-select>\n } @else if (_column.type === 'lazy-values') {\n <sd-select\n minWidthPanel=\"200px\"\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n [style.width]=\"'100%'\"\n size=\"sm\"\n [label]=\"_label\"\n [items]=\"_items\"\n [valueField]=\"_column.option.valueField\"\n [displayField]=\"_column.option.displayField\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n [multiple]=\"_column.option.selection === 'MULTIPLE'\"\n hideInlineError>\n </sd-select>\n } @else if (_column.type === 'date' || _column.type === 'datetime' || _column.type === 'time') {\n @if (!_column.filter?.type || _column.filter?.type === 'daterange') {\n <sd-date-range\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n </sd-date-range>\n } @else if (_column.filter?.type === 'date') {\n <sd-date\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n type=\"date\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n </sd-date>\n } @else if (_column.filter?.type === 'split-date') {\n <ng-container\n *ngTemplateOutlet=\"splitDateTpl; context: { field: _column.field, disabled: _column.filter?.disabled }\">\n </ng-container>\n }\n }\n }\n } @else {\n <sd-input [autoId]=\"_autoId\" style=\"flex: 1 1 0%; min-width: 0\" type=\"text\" size=\"sm\" disabled></sd-input>\n }\n</div>\n\n<!-- ================================================ -->\n<!-- Split from/to templates (\u0111\u01B0a xu\u1ED1ng cu\u1ED1i file) -->\n<!-- ================================================ -->\n<ng-template #splitNumberTpl let-field=\"field\" let-disabled=\"disabled\">\n <div class=\"d-flex align-items-center\" style=\"flex: 1 1 0%; min-width: 0\">\n <sd-input-number\n [autoId]=\"_autoId + '-from'\"\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[field].from\"\n (sdChange)=\"onFilterChange()\"\n (sdBlur)=\"onFilterCommit()\"\n (cleared)=\"onFilterChange()\"\n [disabled]=\"disabled\"\n hideInlineError>\n </sd-input-number>\n <div class=\"mx-4\">-</div>\n <sd-input-number\n [autoId]=\"_autoId + '-to'\"\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n [(model)]=\"_columnFilter[field].to\"\n (sdChange)=\"onFilterChange()\"\n (sdBlur)=\"onFilterCommit()\"\n (cleared)=\"onFilterChange()\"\n [disabled]=\"disabled\"\n hideInlineError>\n </sd-input-number>\n </div>\n</ng-template>\n\n<ng-template #splitDateTpl let-field=\"field\" let-disabled=\"disabled\">\n <div class=\"d-flex align-items-center\" style=\"flex: 1 1 0%; min-width: 0\">\n <sd-date\n [autoId]=\"_autoId + '-from'\"\n style=\"flex: 1 1 0%; min-width: 0\"\n type=\"date\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[field].from\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"disabled\"\n hideInlineError>\n </sd-date>\n <div class=\"mx-4\">-</div>\n <sd-date\n [autoId]=\"_autoId + '-to'\"\n style=\"flex: 1 1 0%; min-width: 0\"\n type=\"date\"\n size=\"sm\"\n [(model)]=\"_columnFilter[field].to\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"disabled\"\n hideInlineError>\n </sd-date>\n </div>\n</ng-template>\n", styles: [":host ::ng-deep .c-inline-column .mat-mdc-text-field-wrapper{background-color:#fff}\n"] }]
|
|
288
288
|
}], ctorParameters: () => [], propDecorators: { autoIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }], columnFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnFilter", required: false }] }], cacheValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "cacheValues", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], operator: [{ type: i0.Input, args: [{ isSignal: true, alias: "operator", required: false }] }, { type: i0.Output, args: ["operatorChange"] }], isMobile: [{ type: i0.Input, args: [{ isSignal: true, alias: "isMobile", required: false }] }], filterChange: [{ type: i0.Output, args: ["filterChange"] }], filterCommit: [{ type: i0.Output, args: ["filterCommit"] }] } });
|
|
@@ -302,24 +302,42 @@ class FilterValuesPipe {
|
|
|
302
302
|
}
|
|
303
303
|
return [];
|
|
304
304
|
}
|
|
305
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
306
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.
|
|
305
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: FilterValuesPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
306
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.24", ngImport: i0, type: FilterValuesPipe, isStandalone: true, name: "filterValues" });
|
|
307
307
|
}
|
|
308
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
308
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: FilterValuesPipe, decorators: [{
|
|
309
309
|
type: Pipe,
|
|
310
310
|
args: [{
|
|
311
311
|
name: 'filterValues',
|
|
312
312
|
}]
|
|
313
313
|
}], ctorParameters: () => [] });
|
|
314
314
|
|
|
315
|
-
|
|
315
|
+
/**
|
|
316
|
+
* Type-guard: tree có nạp children lười (lazy) hay không.
|
|
317
|
+
* Dùng để narrow discriminated union `SdTableOptionTree` một cách an toàn —
|
|
318
|
+
* thay vì truy cập `option.onExpandChildren` trực tiếp trên union (chỉ tồn tại
|
|
319
|
+
* ở nhánh lazy).
|
|
320
|
+
*/
|
|
321
|
+
const isLazyTree = (option) => option?.loadType === 'lazy';
|
|
322
|
+
/**
|
|
323
|
+
* Key chứa mảng children trên object row.
|
|
324
|
+
* - `static`: lấy `childrenKey` đã cấu hình, mặc định `'children'`.
|
|
325
|
+
* - `lazy`: không có `childrenKey` riêng → luôn dùng `'children'` làm nơi lưu
|
|
326
|
+
* kết quả nạp lười.
|
|
327
|
+
*/
|
|
328
|
+
const getChildrenKey = (option) => (option?.loadType === 'static' ? option.childrenKey : undefined) ?? 'children';
|
|
316
329
|
const getChildrenFromData = (data, option) => {
|
|
317
330
|
const key = getChildrenKey(option);
|
|
318
331
|
const raw = data?.[key];
|
|
319
332
|
return Array.isArray(raw) ? raw : [];
|
|
320
333
|
};
|
|
334
|
+
/**
|
|
335
|
+
* Trạng thái bung mặc định cho một cấp.
|
|
336
|
+
* Chỉ `static` mới có `defaultExpanded`; lazy luôn trả `false` (không thể bung
|
|
337
|
+
* mặc định nhánh chưa nạp).
|
|
338
|
+
*/
|
|
321
339
|
const resolveDefaultExpanded = (level, option) => {
|
|
322
|
-
const def = option?.defaultExpanded ?? false;
|
|
340
|
+
const def = option?.loadType === 'static' ? option.defaultExpanded ?? false : false;
|
|
323
341
|
if (def === true)
|
|
324
342
|
return true;
|
|
325
343
|
if (def === false)
|
|
@@ -328,17 +346,53 @@ const resolveDefaultExpanded = (level, option) => {
|
|
|
328
346
|
return level < def;
|
|
329
347
|
return false;
|
|
330
348
|
};
|
|
349
|
+
/**
|
|
350
|
+
* Row có khả năng có children hay không (để hiện nút bung).
|
|
351
|
+
* - Có children embedded → true.
|
|
352
|
+
* - Lazy tree: dùng `hasChildren(row.data)` nếu được cấu hình; không thì luôn
|
|
353
|
+
* true (chưa biết cho tới khi nạp).
|
|
354
|
+
*/
|
|
331
355
|
const resolveHasChildren = (row, option) => {
|
|
332
356
|
const embedded = getChildrenFromData(row.data, option);
|
|
333
357
|
if (embedded.length > 0)
|
|
334
358
|
return true;
|
|
335
|
-
|
|
359
|
+
if (isLazyTree(option))
|
|
360
|
+
return option.hasChildren ? option.hasChildren(row.data) : true;
|
|
361
|
+
return false;
|
|
336
362
|
};
|
|
363
|
+
/** Row cần nạp lười (lazy) khi bung: là lazy tree và chưa có children embedded. */
|
|
337
364
|
const hasLazyChildren = (row, option) => {
|
|
338
|
-
if (!option
|
|
365
|
+
if (!isLazyTree(option))
|
|
339
366
|
return false;
|
|
340
367
|
return getChildrenFromData(row.data, option).length === 0;
|
|
341
368
|
};
|
|
369
|
+
/**
|
|
370
|
+
* True nếu `data` HOẶC bất kỳ hậu duệ nào (theo `childrenKey`) thoả `predicate`.
|
|
371
|
+
*
|
|
372
|
+
* Dùng cho search ở cấp con (static tree, table `type: 'local'`): một nhánh
|
|
373
|
+
* gốc được giữ lại trong kết quả lọc nếu subtree của nó có ít nhất một node
|
|
374
|
+
* khớp từ khoá. `visited` chống đệ quy vô hạn khi data có circular reference.
|
|
375
|
+
*/
|
|
376
|
+
const subtreeMatches = (data, predicate, option, visited = new Set()) => {
|
|
377
|
+
if (data == null || visited.has(data))
|
|
378
|
+
return false;
|
|
379
|
+
visited.add(data);
|
|
380
|
+
if (predicate(data))
|
|
381
|
+
return true;
|
|
382
|
+
for (const child of getChildrenFromData(data, option)) {
|
|
383
|
+
if (subtreeMatches(child, predicate, option, visited))
|
|
384
|
+
return true;
|
|
385
|
+
}
|
|
386
|
+
return false;
|
|
387
|
+
};
|
|
388
|
+
/**
|
|
389
|
+
* Lọc mảng children: chỉ giữ child có subtree khớp `predicate`.
|
|
390
|
+
*
|
|
391
|
+
* Trả về MẢNG MỚI nhưng GIỮ NGUYÊN object reference của từng child (không clone)
|
|
392
|
+
* — nhờ vậy `meta.id` (hash từ data) ổn định, selection / trạng thái bung không
|
|
393
|
+
* bị mất khi từ khoá search đổi. Đây là bước "prune" của tính năng search-con.
|
|
394
|
+
*/
|
|
395
|
+
const filterMatchingChildren = (children, predicate, option) => children.filter(child => subtreeMatches(child, predicate, option));
|
|
342
396
|
const flattenTree = (roots, option, visited = new Set()) => {
|
|
343
397
|
if (!option)
|
|
344
398
|
return roots;
|
|
@@ -430,10 +484,10 @@ class SdTreePipe {
|
|
|
430
484
|
return items;
|
|
431
485
|
return flattenTree(items, treeOption);
|
|
432
486
|
}
|
|
433
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
434
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.
|
|
487
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTreePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
488
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.24", ngImport: i0, type: SdTreePipe, isStandalone: true, name: "sdTree" });
|
|
435
489
|
}
|
|
436
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
490
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTreePipe, decorators: [{
|
|
437
491
|
type: Pipe,
|
|
438
492
|
args: [{ name: 'sdTree' }]
|
|
439
493
|
}] });
|
|
@@ -564,10 +618,10 @@ class ExternalFilterComponent {
|
|
|
564
618
|
return val !== undefined && val !== null && val !== '';
|
|
565
619
|
});
|
|
566
620
|
};
|
|
567
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
568
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.23", type: ExternalFilterComponent, isStandalone: true, selector: "external-filter", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, externalFilters: { classPropertyName: "externalFilters", publicName: "externalFilters", isSignal: true, isRequired: false, transformFunction: null }, filterRegister: { classPropertyName: "filterRegister", publicName: "filterRegister", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@let _filter = filter();\n@let _autoId = autoId();\n@let _items = filterItems();\n@let _externalFilter = externalFilter();\n@let _inlineExternal = inlineExternal();\n@let _filtered = filtered();\n@let _col = col();\n\n@if (!_filter?.disabled) {\n @if (!isMobileOrTablet && _items.length) {\n <sd-section\n [hideHeader]=\"_filter?.hideExternalFilterToolbar\"\n icon=\"filter_alt\"\n iconColor=\"secondary\"\n [title]=\"'core.component.table.filter' | translate\"\n collapsable>\n <div class=\"d-flex mr-4\" sdHeaderRight>\n <sd-button\n [autoId]=\"_autoId + 'clear'\"\n [disabled]=\"!_filtered\"\n type=\"link\"\n prefixIcon=\"cleaning_services\"\n [tooltip]=\"'core.component.table.clear-selection' | translate\"\n (click)=\"$event.stopPropagation(); clearFilter($event)\"></sd-button>\n <sd-button\n [autoId]=\"_autoId + 'setting'\"\n type=\"link\"\n prefixIcon=\"settings\"\n [tooltip]=\"'core.component.table.customize' | translate\"\n [matMenuTriggerFor]=\"menu\"\n (click)=\"$event.stopPropagation()\"></sd-button>\n <mat-menu #menu=\"matMenu\" class=\"sd-custom-panel-filter-configuration\" [attr.data-autoid]=\"_autoId + 'setting-menu'\">\n @for (externalFilter of _items; track externalFilter.field) {\n <button\n [attr.data-autoid]=\"_autoId + 'setting-' + externalFilter.field\"\n mat-menu-item\n (click)=\"onCheckboxChange($event, externalFilter)\"\n [disabled]=\"externalFilter.required\">\n <sd-checkbox\n [autoId]=\"_autoId + 'setting-' + externalFilter.field + '-checkbox'\"\n [label]=\"externalFilter.title\"\n [model]=\"_inlineExternal[externalFilter.field]\"\n [disabled]=\"externalFilter.required\" />\n </button>\n }\n </mat-menu>\n </div>\n <div class=\"row mx-0\" style=\"row-gap: 16px\">\n @for (item of _items; track item.field) {\n @if (_inlineExternal[item.field]) {\n <div class=\"col-md-3 col-sm-6 px-8\" [class.col-lg-2]=\"_col === 2\" [class.col-lg-3]=\"_col === 3\">\n @if (item.type === 'string') {\n <sd-input\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n type=\"text\"\n [(model)]=\"_externalFilter[item.field]\"\n (keyupEnter)=\"onKeyupEnter()\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-input>\n } @else if (item.type === 'number') {\n <sd-input-number\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [(model)]=\"_externalFilter[item.field]\"\n (keyupEnter)=\"onKeyupEnter()\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-input-number>\n } @else if (item.type === 'boolean') {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"[\n { value: true, display: item.option?.displayOnTrue || 'True' },\n { value: false, display: item.option?.displayOnFalse || 'False' },\n ]\"\n valueField=\"value\"\n displayField=\"display\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else if (item.type === 'date') {\n <sd-date\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n [min]=\"item.minDate\"\n [max]=\"item.maxDate\"\n hideInlineError>\n </sd-date>\n } @else if (item.type === 'datetime') {\n <sd-datetime\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n [min]=\"item.minDate\"\n [max]=\"item.maxDate\"\n hideInlineError>\n </sd-datetime>\n } @else if (item.type === 'daterange') {\n <sd-date-range\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n [form]=\"form\"\n [required]=\"item.required\"\n [min]=\"item.minDate\"\n [max]=\"item.maxDate\"\n appearance=\"outline\"\n hideInlineError>\n </sd-date-range>\n } @else if (item.type === 'values') {\n @if (item.option.selection === 'MULTIPLE') {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items | filterValues | async\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n multiple\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else if (item.option.selection === 'AUTOCOMPLETE') {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items | filterValues | async\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else if (item.option.selection === 'MULTIPLEAUTOCOMPLETE') {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items | filterValues | async\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n multiple\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items | filterValues | async\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n }\n } @else if (item.type === 'lazy-values') {\n @if (item.option.selection === 'MULTIPLE') {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n multiple\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n }\n } @else if (item.type === 'custom' && item.filterDef) {\n <ng-container\n *ngTemplateOutlet=\"\n item.filterDef;\n context: { form: form, externalFilter: _externalFilter, autoId: _autoId + item.field }\n \">\n </ng-container>\n }\n </div>\n }\n }\n </div>\n @if (_filter?.manualFilter) {\n <div class=\"d-flex justify-content-end mt-16 px-8\">\n <sd-button\n [autoId]=\"_autoId + 'submit'\"\n [disabled]=\"form.invalid\"\n type=\"fill\"\n color=\"primary\"\n [title]=\"'core.component.table.search' | translate\"\n prefixIcon=\"filter_alt\"\n (click)=\"onSubmit()\">\n </sd-button>\n </div>\n }\n </sd-section>\n }\n}\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: "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", "noPaddingBody"], outputs: ["collapsedChange"] }, { kind: "component", type: SdInput, selector: "sd-input", inputs: ["autoId", "name", "appearance", "floatLabel", "size", "form", "label", "helperText", "placeholder", "type", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "minlength", "maxlength", "pattern", "patternErrorMessage", "validator", "inlineError", "hyperlink", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "cleared", "sdFocusForceBlur"] }, { kind: "component", type: SdInputNumber, selector: "sd-input-number", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "type", "precision", "format", "min", "max", "validator", "inlineError", "hyperlink", "appearance", "floatLabel", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "cleared", "sdFocusForceBlur"] }, { kind: "component", type: SdSelect, selector: "sd-select", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "valueField", "displayField", "disabledField", "cacheChecksum", "limit", "hyperlink", "minWidthPanel", "hideInlineError", "required", "disabled", "viewed", "multiple", "bare", "validator", "inlineError", "appearance", "floatLabel", "items", "model"], outputs: ["modelChange", "sdChange", "sdSelection"] }, { kind: "component", type: SdDate, selector: "sd-date", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "bare", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdDatetime, selector: "sd-datetime", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "showSeconds", "bare", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdDateRange$1, selector: "sd-date-range", inputs: ["autoId", "name", "size", "form", "label", "helperText", "hideInlineError", "required", "disabled", "bare", "viewed", "appearance", "floatLabel", "min", "max", "model"], outputs: ["modelChange", "sdChange"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "component", type: SdCheckbox, selector: "sd-checkbox", inputs: ["autoId", "name", "form", "label", "color", "disabled", "viewed", "inlineError", "model"], outputs: ["modelChange", "sdChange"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: FilterValuesPipe, name: "filterValues" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
621
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ExternalFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
622
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: ExternalFilterComponent, isStandalone: true, selector: "external-filter", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, externalFilters: { classPropertyName: "externalFilters", publicName: "externalFilters", isSignal: true, isRequired: false, transformFunction: null }, filterRegister: { classPropertyName: "filterRegister", publicName: "filterRegister", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@let _filter = filter();\n@let _autoId = autoId();\n@let _items = filterItems();\n@let _externalFilter = externalFilter();\n@let _inlineExternal = inlineExternal();\n@let _filtered = filtered();\n@let _col = col();\n\n@if (!_filter?.disabled) {\n @if (!isMobileOrTablet && _items.length) {\n <sd-section\n [hideHeader]=\"_filter?.hideExternalFilterToolbar\"\n icon=\"filter_alt\"\n iconColor=\"secondary\"\n [title]=\"'core.component.table.filter' | translate\"\n collapsable>\n <div class=\"d-flex mr-4\" sdHeaderRight>\n <sd-button\n [autoId]=\"_autoId + 'clear'\"\n [disabled]=\"!_filtered\"\n type=\"link\"\n prefixIcon=\"cleaning_services\"\n [tooltip]=\"'core.component.table.clear-selection' | translate\"\n (click)=\"$event.stopPropagation(); clearFilter($event)\"></sd-button>\n <sd-button\n [autoId]=\"_autoId + 'setting'\"\n type=\"link\"\n prefixIcon=\"settings\"\n [tooltip]=\"'core.component.table.customize' | translate\"\n [matMenuTriggerFor]=\"menu\"\n (click)=\"$event.stopPropagation()\"></sd-button>\n <mat-menu #menu=\"matMenu\" class=\"sd-custom-panel-filter-configuration\" [attr.data-autoid]=\"_autoId + 'setting-menu'\">\n @for (externalFilter of _items; track externalFilter.field) {\n <button\n [attr.data-autoid]=\"_autoId + 'setting-' + externalFilter.field\"\n mat-menu-item\n (click)=\"onCheckboxChange($event, externalFilter)\"\n [disabled]=\"externalFilter.required\">\n <sd-checkbox\n [autoId]=\"_autoId + 'setting-' + externalFilter.field + '-checkbox'\"\n [label]=\"externalFilter.title\"\n [model]=\"_inlineExternal[externalFilter.field]\"\n [disabled]=\"externalFilter.required\" />\n </button>\n }\n </mat-menu>\n </div>\n <div class=\"row mx-0\" style=\"row-gap: 16px\">\n @for (item of _items; track item.field) {\n @if (_inlineExternal[item.field]) {\n <div class=\"col-md-3 col-sm-6 px-8\" [class.col-lg-2]=\"_col === 2\" [class.col-lg-3]=\"_col === 3\">\n @if (item.type === 'string') {\n <sd-input\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n type=\"text\"\n [(model)]=\"_externalFilter[item.field]\"\n (keyupEnter)=\"onKeyupEnter()\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-input>\n } @else if (item.type === 'number') {\n <sd-input-number\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [(model)]=\"_externalFilter[item.field]\"\n (keyupEnter)=\"onKeyupEnter()\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-input-number>\n } @else if (item.type === 'boolean') {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"[\n { value: true, display: item.option?.displayOnTrue || 'True' },\n { value: false, display: item.option?.displayOnFalse || 'False' },\n ]\"\n valueField=\"value\"\n displayField=\"display\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else if (item.type === 'date') {\n <sd-date\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n [min]=\"item.minDate\"\n [max]=\"item.maxDate\"\n hideInlineError>\n </sd-date>\n } @else if (item.type === 'datetime') {\n <sd-datetime\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n [min]=\"item.minDate\"\n [max]=\"item.maxDate\"\n hideInlineError>\n </sd-datetime>\n } @else if (item.type === 'daterange') {\n <sd-date-range\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n [form]=\"form\"\n [required]=\"item.required\"\n [min]=\"item.minDate\"\n [max]=\"item.maxDate\"\n appearance=\"outline\"\n hideInlineError>\n </sd-date-range>\n } @else if (item.type === 'values') {\n @if (item.option.selection === 'MULTIPLE') {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items | filterValues | async\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n multiple\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else if (item.option.selection === 'AUTOCOMPLETE') {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items | filterValues | async\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else if (item.option.selection === 'MULTIPLEAUTOCOMPLETE') {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items | filterValues | async\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n multiple\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items | filterValues | async\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n }\n } @else if (item.type === 'lazy-values') {\n @if (item.option.selection === 'MULTIPLE') {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n multiple\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n }\n } @else if (item.type === 'custom' && item.filterDef) {\n <ng-container\n *ngTemplateOutlet=\"\n item.filterDef;\n context: { form: form, externalFilter: _externalFilter, autoId: _autoId + item.field }\n \">\n </ng-container>\n }\n </div>\n }\n }\n </div>\n @if (_filter?.manualFilter) {\n <div class=\"d-flex justify-content-end mt-16 px-8\">\n <sd-button\n [autoId]=\"_autoId + 'submit'\"\n [disabled]=\"form.invalid\"\n type=\"fill\"\n color=\"primary\"\n [title]=\"'core.component.table.search' | translate\"\n prefixIcon=\"filter_alt\"\n (click)=\"onSubmit()\">\n </sd-button>\n </div>\n }\n </sd-section>\n }\n}\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: "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", "noPaddingBody"], outputs: ["collapsedChange"] }, { kind: "component", type: SdInput, selector: "sd-input", inputs: ["autoId", "name", "appearance", "floatLabel", "size", "form", "label", "helperText", "placeholder", "type", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "minlength", "maxlength", "pattern", "patternErrorMessage", "validator", "inlineError", "hyperlink", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "cleared", "sdFocusForceBlur"] }, { kind: "component", type: SdInputNumber, selector: "sd-input-number", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "type", "precision", "format", "min", "max", "validator", "inlineError", "hyperlink", "appearance", "floatLabel", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "cleared", "sdFocusForceBlur"] }, { kind: "component", type: SdSelect, selector: "sd-select", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "valueField", "displayField", "disabledField", "cacheChecksum", "limit", "hyperlink", "minWidthPanel", "hideInlineError", "required", "disabled", "viewed", "multiple", "clearable", "validator", "inlineError", "appearance", "floatLabel", "items", "model"], outputs: ["modelChange", "sdChange", "sdSelection"] }, { kind: "component", type: SdDate, selector: "sd-date", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "clearable", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdDatetime, selector: "sd-datetime", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "showSeconds", "clearable", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdDateRange$1, selector: "sd-date-range", inputs: ["autoId", "name", "size", "form", "label", "helperText", "hideInlineError", "required", "disabled", "viewed", "clearable", "appearance", "floatLabel", "min", "max", "model"], outputs: ["modelChange", "sdChange"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "component", type: SdCheckbox, selector: "sd-checkbox", inputs: ["autoId", "name", "form", "label", "color", "disabled", "viewed", "inlineError", "model"], outputs: ["modelChange", "sdChange"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: FilterValuesPipe, name: "filterValues" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
569
623
|
}
|
|
570
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
624
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ExternalFilterComponent, decorators: [{
|
|
571
625
|
type: Component,
|
|
572
626
|
args: [{ selector: 'external-filter', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
573
627
|
CommonModule,
|
|
@@ -660,10 +714,10 @@ class MobileFilterComponent {
|
|
|
660
714
|
// Local working state — không ghi gì khi cancel, chỉ đóng drawer.
|
|
661
715
|
this.drawer().close();
|
|
662
716
|
};
|
|
663
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
664
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.23", type: MobileFilterComponent, isStandalone: true, selector: "mobile-filter", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, externalFilters: { classPropertyName: "externalFilters", publicName: "externalFilters", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, filterDefs: { classPropertyName: "filterDefs", publicName: "filterDefs", isSignal: true, isRequired: false, transformFunction: null }, filterRegister: { classPropertyName: "filterRegister", publicName: "filterRegister", isSignal: true, isRequired: false, transformFunction: null }, cacheValues: { classPropertyName: "cacheValues", publicName: "cacheValues", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "drawer", first: true, predicate: SdSideDrawer, descendants: true, isSignal: true }], ngImport: i0, template: "@let _autoId = autoId();\n@let _externalFilters = externalFilterItems();\n@let _columns = columnItems();\n@let _filterDefs = filterDefItems();\n@let _workingColumnFilter = workingColumnFilter();\n@let _workingColumnOperator = workingColumnOperator();\n@let _workingExternalFilter = workingExternalFilter();\n@let _cacheValues = cacheValues();\n\n<sd-side-drawer\n #drawer\n [title]=\"'core.component.table.filter' | translate\"\n width=\"90vw\">\n <div class=\"mobile-filter-body\">\n <!-- ============================ -->\n <!-- 1. External filters (inline) -->\n <!-- ============================ -->\n @if (_externalFilters.length) {\n <section class=\"mobile-filter-section\">\n @for (item of _externalFilters; track item.field) {\n <div class=\"mobile-filter-row\">\n @if (item.type === 'string') {\n <sd-input\n [autoId]=\"_autoId + 'ext-' + item.field\"\n size=\"sm\"\n [label]=\"item.title\"\n type=\"text\"\n [(model)]=\"_workingExternalFilter[item.field]\"\n appearance=\"outline\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-input>\n } @else if (item.type === 'number') {\n <sd-input-number\n [autoId]=\"_autoId + 'ext-' + item.field\"\n size=\"sm\"\n [label]=\"item.title\"\n [(model)]=\"_workingExternalFilter[item.field]\"\n appearance=\"outline\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-input-number>\n } @else if (item.type === 'boolean') {\n <sd-select\n [autoId]=\"_autoId + 'ext-' + item.field\"\n size=\"sm\"\n [label]=\"item.title\"\n [items]=\"[\n { value: true, display: item.option?.displayOnTrue || 'True' },\n { value: false, display: item.option?.displayOnFalse || 'False' },\n ]\"\n valueField=\"value\"\n displayField=\"display\"\n [(model)]=\"_workingExternalFilter[item.field]\"\n appearance=\"outline\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else if (item.type === 'date') {\n <sd-date\n [autoId]=\"_autoId + 'ext-' + item.field\"\n size=\"sm\"\n [label]=\"item.title\"\n [(model)]=\"_workingExternalFilter[item.field]\"\n appearance=\"outline\"\n [required]=\"item.required\"\n [min]=\"item.minDate\"\n [max]=\"item.maxDate\"\n hideInlineError>\n </sd-date>\n } @else if (item.type === 'datetime') {\n <sd-datetime\n [autoId]=\"_autoId + 'ext-' + item.field\"\n size=\"sm\"\n [label]=\"item.title\"\n [(model)]=\"_workingExternalFilter[item.field]\"\n appearance=\"outline\"\n [required]=\"item.required\"\n [min]=\"item.minDate\"\n [max]=\"item.maxDate\"\n hideInlineError>\n </sd-datetime>\n } @else if (item.type === 'daterange') {\n <sd-date-range\n [autoId]=\"_autoId + 'ext-' + item.field\"\n size=\"sm\"\n [label]=\"item.title\"\n [(model)]=\"_workingExternalFilter[item.field]\"\n [required]=\"item.required\"\n [min]=\"item.minDate\"\n [max]=\"item.maxDate\"\n appearance=\"outline\"\n hideInlineError>\n </sd-date-range>\n } @else if (item.type === 'values') {\n <sd-select\n [autoId]=\"_autoId + 'ext-' + item.field\"\n size=\"sm\"\n [label]=\"item.title\"\n [items]=\"item.option.items | filterValues | async\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_workingExternalFilter[item.field]\"\n appearance=\"outline\"\n [multiple]=\"item.option.selection === 'MULTIPLE' || item.option.selection === 'MULTIPLEAUTOCOMPLETE'\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else if (item.type === 'lazy-values') {\n <sd-select\n [autoId]=\"_autoId + 'ext-' + item.field\"\n size=\"sm\"\n [label]=\"item.title\"\n [items]=\"item.option.items\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_workingExternalFilter[item.field]\"\n appearance=\"outline\"\n [multiple]=\"item.option.selection === 'MULTIPLE'\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else if (item.type === 'custom' && item.filterDef) {\n <ng-container\n *ngTemplateOutlet=\"\n item.filterDef;\n context: { externalFilter: _workingExternalFilter, autoId: _autoId + 'ext-' + item.field }\n \">\n </ng-container>\n }\n </div>\n }\n </section>\n }\n\n <!-- ============================ -->\n <!-- 2. Custom filterDef templates -->\n <!-- ============================ -->\n @if (_filterDefs.length) {\n <section class=\"mobile-filter-section\">\n @for (def of _filterDefs; track def.sdTableFilterDef()) {\n <div class=\"mobile-filter-row\" [attr.data-autoid]=\"_autoId + 'def-' + def.sdTableFilterDef()\">\n <ng-container\n *ngTemplateOutlet=\"def.templateRef!; context: { externalFilter: _workingExternalFilter }\">\n </ng-container>\n </div>\n }\n </section>\n }\n\n <!-- ============================ -->\n <!-- 3. Column filters -->\n <!-- ============================ -->\n @if (_columns.length) {\n <section class=\"mobile-filter-section\">\n @for (column of _columns; track column.field) {\n <div class=\"mobile-filter-row\" [attr.data-autoid]=\"_autoId + 'col-' + column.field\">\n <column-filter\n [autoId]=\"_autoId + 'col'\"\n [column]=\"column\"\n [columnFilter]=\"_workingColumnFilter\"\n [operator]=\"$any(_workingColumnOperator[column.field])\"\n (operatorChange)=\"_workingColumnOperator[column.field] = $event!\"\n [cacheValues]=\"_cacheValues\"\n isMobile>\n </column-filter>\n </div>\n }\n </section>\n }\n </div>\n\n <ng-container sdFooter>\n <div class=\"mobile-filter-footer\">\n <sd-button\n [autoId]=\"_autoId + 'cancel'\"\n class=\"mobile-filter-action\"\n (click)=\"onCancel()\"\n [title]=\"'core.confirm.no' | translate\"\n type=\"link\"\n color=\"secondary\">\n </sd-button>\n <sd-button\n [autoId]=\"_autoId + 'apply'\"\n class=\"mobile-filter-action\"\n (click)=\"onApply()\"\n [title]=\"'core.confirm.yes' | translate\"\n type=\"fill\"\n color=\"primary\">\n </sd-button>\n </div>\n </ng-container>\n</sd-side-drawer>\n", styles: [".mobile-filter-body{display:flex;flex-direction:column;gap:16px;padding:8px 0}.mobile-filter-section{display:flex;flex-direction:column;gap:12px}.mobile-filter-row{display:flex;flex-direction:column}.mobile-filter-footer{display:flex;gap:8px;width:100%}.mobile-filter-action{flex:1 1 50%}.mobile-filter-action ::ng-deep button{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: SdSideDrawer, selector: "sd-side-drawer", inputs: ["title", "width", "hideClose", "disableBackdropClose", "drawerClass", "autoId"], outputs: ["sdClosed"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "component", type: ColumnFilterComponent, selector: "column-filter", inputs: ["autoId", "column", "columnFilter", "cacheValues", "value", "operator", "isMobile"], outputs: ["operatorChange", "filterChange", "filterCommit"] }, { kind: "component", type: SdInput, selector: "sd-input", inputs: ["autoId", "name", "appearance", "floatLabel", "size", "form", "label", "helperText", "placeholder", "type", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "minlength", "maxlength", "pattern", "patternErrorMessage", "validator", "inlineError", "hyperlink", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "cleared", "sdFocusForceBlur"] }, { kind: "component", type: SdInputNumber, selector: "sd-input-number", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "type", "precision", "format", "min", "max", "validator", "inlineError", "hyperlink", "appearance", "floatLabel", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "cleared", "sdFocusForceBlur"] }, { kind: "component", type: SdSelect, selector: "sd-select", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "valueField", "displayField", "disabledField", "cacheChecksum", "limit", "hyperlink", "minWidthPanel", "hideInlineError", "required", "disabled", "viewed", "multiple", "bare", "validator", "inlineError", "appearance", "floatLabel", "items", "model"], outputs: ["modelChange", "sdChange", "sdSelection"] }, { kind: "component", type: SdDate, selector: "sd-date", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "bare", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdDatetime, selector: "sd-datetime", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "showSeconds", "bare", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdDateRange$1, selector: "sd-date-range", inputs: ["autoId", "name", "size", "form", "label", "helperText", "hideInlineError", "required", "disabled", "bare", "viewed", "appearance", "floatLabel", "min", "max", "model"], outputs: ["modelChange", "sdChange"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: FilterValuesPipe, name: "filterValues" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
717
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: MobileFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
718
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: MobileFilterComponent, isStandalone: true, selector: "mobile-filter", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, externalFilters: { classPropertyName: "externalFilters", publicName: "externalFilters", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, filterDefs: { classPropertyName: "filterDefs", publicName: "filterDefs", isSignal: true, isRequired: false, transformFunction: null }, filterRegister: { classPropertyName: "filterRegister", publicName: "filterRegister", isSignal: true, isRequired: false, transformFunction: null }, cacheValues: { classPropertyName: "cacheValues", publicName: "cacheValues", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "drawer", first: true, predicate: SdSideDrawer, descendants: true, isSignal: true }], ngImport: i0, template: "@let _autoId = autoId();\n@let _externalFilters = externalFilterItems();\n@let _columns = columnItems();\n@let _filterDefs = filterDefItems();\n@let _workingColumnFilter = workingColumnFilter();\n@let _workingColumnOperator = workingColumnOperator();\n@let _workingExternalFilter = workingExternalFilter();\n@let _cacheValues = cacheValues();\n\n<sd-side-drawer\n #drawer\n [title]=\"'core.component.table.filter' | translate\"\n width=\"90vw\">\n <div class=\"mobile-filter-body\">\n <!-- ============================ -->\n <!-- 1. External filters (inline) -->\n <!-- ============================ -->\n @if (_externalFilters.length) {\n <section class=\"mobile-filter-section\">\n @for (item of _externalFilters; track item.field) {\n <div class=\"mobile-filter-row\">\n @if (item.type === 'string') {\n <sd-input\n [autoId]=\"_autoId + 'ext-' + item.field\"\n size=\"sm\"\n [label]=\"item.title\"\n type=\"text\"\n [(model)]=\"_workingExternalFilter[item.field]\"\n appearance=\"outline\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-input>\n } @else if (item.type === 'number') {\n <sd-input-number\n [autoId]=\"_autoId + 'ext-' + item.field\"\n size=\"sm\"\n [label]=\"item.title\"\n [(model)]=\"_workingExternalFilter[item.field]\"\n appearance=\"outline\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-input-number>\n } @else if (item.type === 'boolean') {\n <sd-select\n [autoId]=\"_autoId + 'ext-' + item.field\"\n size=\"sm\"\n [label]=\"item.title\"\n [items]=\"[\n { value: true, display: item.option?.displayOnTrue || 'True' },\n { value: false, display: item.option?.displayOnFalse || 'False' },\n ]\"\n valueField=\"value\"\n displayField=\"display\"\n [(model)]=\"_workingExternalFilter[item.field]\"\n appearance=\"outline\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else if (item.type === 'date') {\n <sd-date\n [autoId]=\"_autoId + 'ext-' + item.field\"\n size=\"sm\"\n [label]=\"item.title\"\n [(model)]=\"_workingExternalFilter[item.field]\"\n appearance=\"outline\"\n [required]=\"item.required\"\n [min]=\"item.minDate\"\n [max]=\"item.maxDate\"\n hideInlineError>\n </sd-date>\n } @else if (item.type === 'datetime') {\n <sd-datetime\n [autoId]=\"_autoId + 'ext-' + item.field\"\n size=\"sm\"\n [label]=\"item.title\"\n [(model)]=\"_workingExternalFilter[item.field]\"\n appearance=\"outline\"\n [required]=\"item.required\"\n [min]=\"item.minDate\"\n [max]=\"item.maxDate\"\n hideInlineError>\n </sd-datetime>\n } @else if (item.type === 'daterange') {\n <sd-date-range\n [autoId]=\"_autoId + 'ext-' + item.field\"\n size=\"sm\"\n [label]=\"item.title\"\n [(model)]=\"_workingExternalFilter[item.field]\"\n [required]=\"item.required\"\n [min]=\"item.minDate\"\n [max]=\"item.maxDate\"\n appearance=\"outline\"\n hideInlineError>\n </sd-date-range>\n } @else if (item.type === 'values') {\n <sd-select\n [autoId]=\"_autoId + 'ext-' + item.field\"\n size=\"sm\"\n [label]=\"item.title\"\n [items]=\"item.option.items | filterValues | async\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_workingExternalFilter[item.field]\"\n appearance=\"outline\"\n [multiple]=\"item.option.selection === 'MULTIPLE' || item.option.selection === 'MULTIPLEAUTOCOMPLETE'\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else if (item.type === 'lazy-values') {\n <sd-select\n [autoId]=\"_autoId + 'ext-' + item.field\"\n size=\"sm\"\n [label]=\"item.title\"\n [items]=\"item.option.items\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_workingExternalFilter[item.field]\"\n appearance=\"outline\"\n [multiple]=\"item.option.selection === 'MULTIPLE'\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else if (item.type === 'custom' && item.filterDef) {\n <ng-container\n *ngTemplateOutlet=\"\n item.filterDef;\n context: { externalFilter: _workingExternalFilter, autoId: _autoId + 'ext-' + item.field }\n \">\n </ng-container>\n }\n </div>\n }\n </section>\n }\n\n <!-- ============================ -->\n <!-- 2. Custom filterDef templates -->\n <!-- ============================ -->\n @if (_filterDefs.length) {\n <section class=\"mobile-filter-section\">\n @for (def of _filterDefs; track def.sdTableFilterDef()) {\n <div class=\"mobile-filter-row\" [attr.data-autoid]=\"_autoId + 'def-' + def.sdTableFilterDef()\">\n <ng-container\n *ngTemplateOutlet=\"def.templateRef!; context: { externalFilter: _workingExternalFilter }\">\n </ng-container>\n </div>\n }\n </section>\n }\n\n <!-- ============================ -->\n <!-- 3. Column filters -->\n <!-- ============================ -->\n @if (_columns.length) {\n <section class=\"mobile-filter-section\">\n @for (column of _columns; track column.field) {\n <div class=\"mobile-filter-row\" [attr.data-autoid]=\"_autoId + 'col-' + column.field\">\n <column-filter\n [autoId]=\"_autoId + 'col'\"\n [column]=\"column\"\n [columnFilter]=\"_workingColumnFilter\"\n [operator]=\"$any(_workingColumnOperator[column.field])\"\n (operatorChange)=\"_workingColumnOperator[column.field] = $event!\"\n [cacheValues]=\"_cacheValues\"\n isMobile>\n </column-filter>\n </div>\n }\n </section>\n }\n </div>\n\n <ng-container sdFooter>\n <div class=\"mobile-filter-footer\">\n <sd-button\n [autoId]=\"_autoId + 'cancel'\"\n class=\"mobile-filter-action\"\n (click)=\"onCancel()\"\n [title]=\"'core.confirm.no' | translate\"\n type=\"link\"\n color=\"secondary\">\n </sd-button>\n <sd-button\n [autoId]=\"_autoId + 'apply'\"\n class=\"mobile-filter-action\"\n (click)=\"onApply()\"\n [title]=\"'core.confirm.yes' | translate\"\n type=\"fill\"\n color=\"primary\">\n </sd-button>\n </div>\n </ng-container>\n</sd-side-drawer>\n", styles: [".mobile-filter-body{display:flex;flex-direction:column;gap:16px;padding:8px 0}.mobile-filter-section{display:flex;flex-direction:column;gap:12px}.mobile-filter-row{display:flex;flex-direction:column}.mobile-filter-footer{display:flex;gap:8px;width:100%}.mobile-filter-action{flex:1 1 50%}.mobile-filter-action ::ng-deep button{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: SdSideDrawer, selector: "sd-side-drawer", inputs: ["title", "width", "hideClose", "disableBackdropClose", "drawerClass", "autoId"], outputs: ["sdClosed"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "component", type: ColumnFilterComponent, selector: "column-filter", inputs: ["autoId", "column", "columnFilter", "cacheValues", "value", "operator", "isMobile"], outputs: ["operatorChange", "filterChange", "filterCommit"] }, { kind: "component", type: SdInput, selector: "sd-input", inputs: ["autoId", "name", "appearance", "floatLabel", "size", "form", "label", "helperText", "placeholder", "type", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "minlength", "maxlength", "pattern", "patternErrorMessage", "validator", "inlineError", "hyperlink", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "cleared", "sdFocusForceBlur"] }, { kind: "component", type: SdInputNumber, selector: "sd-input-number", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "type", "precision", "format", "min", "max", "validator", "inlineError", "hyperlink", "appearance", "floatLabel", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "cleared", "sdFocusForceBlur"] }, { kind: "component", type: SdSelect, selector: "sd-select", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "valueField", "displayField", "disabledField", "cacheChecksum", "limit", "hyperlink", "minWidthPanel", "hideInlineError", "required", "disabled", "viewed", "multiple", "clearable", "validator", "inlineError", "appearance", "floatLabel", "items", "model"], outputs: ["modelChange", "sdChange", "sdSelection"] }, { kind: "component", type: SdDate, selector: "sd-date", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "clearable", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdDatetime, selector: "sd-datetime", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "showSeconds", "clearable", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdDateRange$1, selector: "sd-date-range", inputs: ["autoId", "name", "size", "form", "label", "helperText", "hideInlineError", "required", "disabled", "viewed", "clearable", "appearance", "floatLabel", "min", "max", "model"], outputs: ["modelChange", "sdChange"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: FilterValuesPipe, name: "filterValues" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
665
719
|
}
|
|
666
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
720
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: MobileFilterComponent, decorators: [{
|
|
667
721
|
type: Component,
|
|
668
722
|
args: [{ selector: 'mobile-filter', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
669
723
|
CommonModule,
|
|
@@ -742,10 +796,10 @@ class ActionFilterPipe {
|
|
|
742
796
|
}
|
|
743
797
|
return results.map(result => this.#convert(result));
|
|
744
798
|
};
|
|
745
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
746
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.
|
|
799
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ActionFilterPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
800
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.24", ngImport: i0, type: ActionFilterPipe, isStandalone: true, name: "actionFilter" });
|
|
747
801
|
}
|
|
748
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
802
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ActionFilterPipe, decorators: [{
|
|
749
803
|
type: Pipe,
|
|
750
804
|
args: [{
|
|
751
805
|
name: 'actionFilter',
|
|
@@ -756,9 +810,12 @@ class SelectorActionComponent {
|
|
|
756
810
|
// ==========================================
|
|
757
811
|
// 1. SIGNAL INPUTS / OUTPUTS
|
|
758
812
|
// ==========================================
|
|
813
|
+
autoIdInput = input(undefined, ...(ngDevMode ? [{ debugName: "autoIdInput", alias: 'autoId' }] : [{ alias: 'autoId' }]));
|
|
759
814
|
tableOption = input(undefined, ...(ngDevMode ? [{ debugName: "tableOption" }] : []));
|
|
760
815
|
selectedTableItems = input(undefined, ...(ngDevMode ? [{ debugName: "selectedTableItems" }] : []));
|
|
761
816
|
clear = output();
|
|
817
|
+
// Base autoId (đã là `components-table-<scope>` từ parent), '' khi parent không set.
|
|
818
|
+
autoId = computed(() => this.autoIdInput() || '', ...(ngDevMode ? [{ debugName: "autoId" }] : []));
|
|
762
819
|
// ==========================================
|
|
763
820
|
// 2. INJECT
|
|
764
821
|
// ==========================================
|
|
@@ -785,13 +842,13 @@ class SelectorActionComponent {
|
|
|
785
842
|
action.click(this.selectedTableItems()?.map(e => e.data));
|
|
786
843
|
}
|
|
787
844
|
};
|
|
788
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
789
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
845
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SelectorActionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
846
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: SelectorActionComponent, isStandalone: true, selector: "selector-action", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, tableOption: { classPropertyName: "tableOption", publicName: "tableOption", isSignal: true, isRequired: false, transformFunction: null }, selectedTableItems: { classPropertyName: "selectedTableItems", publicName: "selectedTableItems", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clear: "clear" }, ngImport: i0, template: "@let _actions = selectedTableItems() | actionFilter: tableOption()?.selector?.actions;\n@let _selected = selectedTableItems();\n@let _autoId = autoId();\n\n<sd-quick-action [opened]=\"opened()\">\n <div class=\"d-flex align-items-center\" sdMessage>\n <div class=\"c-bg-length\">\n <span class=\"c-length\">{{ _selected?.length }}</span>\n </div>\n <div class=\"c-message\">\n {{ message() }}\n </div>\n </div>\n\n <div class=\"d-flex align-items-center mr-8\" sdAction>\n @for (action of _actions; track $index) {\n @if (action.variant === 'normal') {\n <sd-button\n [autoId]=\"_autoId ? _autoId + '-action-' + $index : null\"\n class=\"ml-4\"\n [tooltip]=\"action.tooltip\"\n [prefixIcon]=\"action.icon\"\n [color]=\"action.color\"\n [type]=\"action.type || 'light'\"\n [fontSet]=\"action.fontSet\"\n [title]=\"action.title\"\n (click)=\"onClickAction(action)\"></sd-button>\n } @else if (action.variant === 'children') {\n @let _actionIndex = $index;\n <sd-button\n [autoId]=\"_autoId ? _autoId + '-action-' + _actionIndex : null\"\n class=\"ml-4\"\n [tooltip]=\"action.tooltip\"\n [prefixIcon]=\"action.icon || 'more_vert'\"\n [color]=\"action.color || 'secondary'\"\n [type]=\"action.type || 'light'\"\n [fontSet]=\"action.fontSet || 'material-icons-outlined'\"\n [title]=\"action.title\"\n [matMenuTriggerFor]=\"menu\">\n </sd-button>\n <mat-menu #menu=\"matMenu\">\n <span>\n @for (child of action.children; track $index) {\n <button\n mat-menu-item\n [attr.data-autoid]=\"_autoId ? _autoId + '-action-' + _actionIndex + '-' + $index : null\"\n (click)=\"onClickAction(child)\">\n @if (child.icon) {\n <mat-icon [fontSet]=\"child.fontSet || 'material-icons-outlined'\" class=\"c-icon\">{{ child.icon }}</mat-icon>\n }\n <span> {{ child.title }}</span>\n </button>\n }\n </span>\n </mat-menu>\n }\n }\n <!-- N\u00FAt close lu\u00F4n hi\u1EC7n k\u1EC3 c\u1EA3 kh\u00F4ng c\u00F3 action \u2014 \u0111\u1EA3m b\u1EA3o user c\u00F3 l\u1ED1i tho\u00E1t clear selection -->\n <sd-button [autoId]=\"_autoId ? _autoId + '-clear-selection' : null\" class=\"ml-4\" prefixIcon=\"close\" color=\"secondary\" type=\"outline\" (click)=\"onClear()\" width=\"35px\"></sd-button>\n </div>\n</sd-quick-action>\n", styles: [".c-bg-length{display:flex;flex-direction:column;align-items:flex-start;padding:12px 8px;position:static;width:auto;min-width:48px;height:48px;left:0;top:0;background:var(--sd-primary);border-radius:4px 0 0 4px}.c-bg-length .c-length{position:static;width:auto;min-width:32px;height:24px;left:8px;top:12px;font-family:Roboto;font-style:normal;font-weight:500;font-size:16px;line-height:24px;text-align:center;color:#fff}.c-message{position:static;min-width:200px;height:20px;left:0;top:6px;font-family:Roboto;font-style:normal;font-weight:400;font-size:14px;line-height:20px;color:#000;margin:0 0 0 8px}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { 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: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "component", type: SdQuickAction, selector: "sd-quick-action", inputs: ["opened"] }, { kind: "pipe", type: ActionFilterPipe, name: "actionFilter" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
790
847
|
}
|
|
791
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
848
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SelectorActionComponent, decorators: [{
|
|
792
849
|
type: Component,
|
|
793
|
-
args: [{ selector: 'selector-action', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIconModule, MatMenuModule, SdButton, SdQuickAction, ActionFilterPipe], template: "@let _actions = selectedTableItems() | actionFilter: tableOption()?.selector?.actions;\n@let _selected = selectedTableItems();\n\n<sd-quick-action [opened]=\"opened()\">\n <div class=\"d-flex align-items-center\" sdMessage>\n <div class=\"c-bg-length\">\n <span class=\"c-length\">{{ _selected?.length }}</span>\n </div>\n <div class=\"c-message\">\n {{ message() }}\n </div>\n </div>\n\n <div class=\"d-flex align-items-center mr-8\" sdAction>\n @for (action of _actions; track $index) {\n @if (action.variant === 'normal') {\n <sd-button\n class=\"ml-4\"\n [tooltip]=\"action.tooltip\"\n [prefixIcon]=\"action.icon\"\n [color]=\"action.color\"\n [type]=\"action.type || 'light'\"\n [fontSet]=\"action.fontSet\"\n [title]=\"action.title\"\n (click)=\"onClickAction(action)\"></sd-button>\n } @else if (action.variant === 'children') {\n <sd-button\n class=\"ml-4\"\n [tooltip]=\"action.tooltip\"\n [prefixIcon]=\"action.icon || 'more_vert'\"\n [color]=\"action.color || 'secondary'\"\n [type]=\"action.type || 'light'\"\n [fontSet]=\"action.fontSet || 'material-icons-outlined'\"\n [title]=\"action.title\"\n [matMenuTriggerFor]=\"menu\">\n </sd-button>\n <mat-menu #menu=\"matMenu\">\n <span>\n @for (child of action.children; track $index) {\n <button
|
|
794
|
-
}], propDecorators: { tableOption: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableOption", required: false }] }], selectedTableItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedTableItems", required: false }] }], clear: [{ type: i0.Output, args: ["clear"] }] } });
|
|
850
|
+
args: [{ selector: 'selector-action', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIconModule, MatMenuModule, SdButton, SdQuickAction, ActionFilterPipe], template: "@let _actions = selectedTableItems() | actionFilter: tableOption()?.selector?.actions;\n@let _selected = selectedTableItems();\n@let _autoId = autoId();\n\n<sd-quick-action [opened]=\"opened()\">\n <div class=\"d-flex align-items-center\" sdMessage>\n <div class=\"c-bg-length\">\n <span class=\"c-length\">{{ _selected?.length }}</span>\n </div>\n <div class=\"c-message\">\n {{ message() }}\n </div>\n </div>\n\n <div class=\"d-flex align-items-center mr-8\" sdAction>\n @for (action of _actions; track $index) {\n @if (action.variant === 'normal') {\n <sd-button\n [autoId]=\"_autoId ? _autoId + '-action-' + $index : null\"\n class=\"ml-4\"\n [tooltip]=\"action.tooltip\"\n [prefixIcon]=\"action.icon\"\n [color]=\"action.color\"\n [type]=\"action.type || 'light'\"\n [fontSet]=\"action.fontSet\"\n [title]=\"action.title\"\n (click)=\"onClickAction(action)\"></sd-button>\n } @else if (action.variant === 'children') {\n @let _actionIndex = $index;\n <sd-button\n [autoId]=\"_autoId ? _autoId + '-action-' + _actionIndex : null\"\n class=\"ml-4\"\n [tooltip]=\"action.tooltip\"\n [prefixIcon]=\"action.icon || 'more_vert'\"\n [color]=\"action.color || 'secondary'\"\n [type]=\"action.type || 'light'\"\n [fontSet]=\"action.fontSet || 'material-icons-outlined'\"\n [title]=\"action.title\"\n [matMenuTriggerFor]=\"menu\">\n </sd-button>\n <mat-menu #menu=\"matMenu\">\n <span>\n @for (child of action.children; track $index) {\n <button\n mat-menu-item\n [attr.data-autoid]=\"_autoId ? _autoId + '-action-' + _actionIndex + '-' + $index : null\"\n (click)=\"onClickAction(child)\">\n @if (child.icon) {\n <mat-icon [fontSet]=\"child.fontSet || 'material-icons-outlined'\" class=\"c-icon\">{{ child.icon }}</mat-icon>\n }\n <span> {{ child.title }}</span>\n </button>\n }\n </span>\n </mat-menu>\n }\n }\n <!-- N\u00FAt close lu\u00F4n hi\u1EC7n k\u1EC3 c\u1EA3 kh\u00F4ng c\u00F3 action \u2014 \u0111\u1EA3m b\u1EA3o user c\u00F3 l\u1ED1i tho\u00E1t clear selection -->\n <sd-button [autoId]=\"_autoId ? _autoId + '-clear-selection' : null\" class=\"ml-4\" prefixIcon=\"close\" color=\"secondary\" type=\"outline\" (click)=\"onClear()\" width=\"35px\"></sd-button>\n </div>\n</sd-quick-action>\n", styles: [".c-bg-length{display:flex;flex-direction:column;align-items:flex-start;padding:12px 8px;position:static;width:auto;min-width:48px;height:48px;left:0;top:0;background:var(--sd-primary);border-radius:4px 0 0 4px}.c-bg-length .c-length{position:static;width:auto;min-width:32px;height:24px;left:8px;top:12px;font-family:Roboto;font-style:normal;font-weight:500;font-size:16px;line-height:24px;text-align:center;color:#fff}.c-message{position:static;min-width:200px;height:20px;left:0;top:6px;font-family:Roboto;font-style:normal;font-weight:400;font-size:14px;line-height:20px;color:#000;margin:0 0 0 8px}\n"] }]
|
|
851
|
+
}], propDecorators: { autoIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], tableOption: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableOption", required: false }] }], selectedTableItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedTableItems", required: false }] }], clear: [{ type: i0.Output, args: ["clear"] }] } });
|
|
795
852
|
|
|
796
853
|
const DEFAULT_TABLE_CONFIG = {
|
|
797
854
|
paginate: {
|
|
@@ -811,7 +868,6 @@ class ConfigService {
|
|
|
811
868
|
GROUP: 'sdGroup',
|
|
812
869
|
REORDER: 'sdReorder',
|
|
813
870
|
INDEX: 'sdIndex',
|
|
814
|
-
TREE_TOGGLE: 'sdTreeToggle',
|
|
815
871
|
FILLER: 'sdFiller',
|
|
816
872
|
};
|
|
817
873
|
#prefix = 'TABLE_CONFIG';
|
|
@@ -863,10 +919,8 @@ class ConfigService {
|
|
|
863
919
|
result.firstHeaders.push(this.#COLUMNS.SELECTION);
|
|
864
920
|
result.displayedColumns.push(this.#COLUMNS.SELECTION);
|
|
865
921
|
}
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
result.displayedColumns.push(this.#COLUMNS.TREE_TOGGLE);
|
|
869
|
-
}
|
|
922
|
+
// why: tree toggle KHÔNG còn là cột riêng — icon expand được nhúng vào cột
|
|
923
|
+
// đầu tiên (cột Index nếu có, ngược lại là cột data đầu). Xem table.component.html.
|
|
870
924
|
// 👇 Chỉ push vào đầu nếu là left (mặc định)
|
|
871
925
|
if (commands?.length && !isCommandRight) {
|
|
872
926
|
result.firstHeaders.push(this.#COLUMNS.COMMAND);
|
|
@@ -959,7 +1013,7 @@ class ConfigService {
|
|
|
959
1013
|
}
|
|
960
1014
|
result.multipleHeader = result.secondHeaders.length > 0;
|
|
961
1015
|
// Sub infomation không thể có footer; filler cũng không cần footer cell.
|
|
962
|
-
result.displayedFooters = result.displayedColumns.filter(val => val !== this.#COLUMNS.SUBINFORMATION && val !== this.#COLUMNS.
|
|
1016
|
+
result.displayedFooters = result.displayedColumns.filter(val => val !== this.#COLUMNS.SUBINFORMATION && val !== this.#COLUMNS.FILLER);
|
|
963
1017
|
if (option.filler?.enabled) {
|
|
964
1018
|
// Footer cũng cần filler cuối để giữ width đồng bộ với data row
|
|
965
1019
|
result.displayedFooters.push(this.#COLUMNS.FILLER);
|
|
@@ -1012,10 +1066,10 @@ class ConfigService {
|
|
|
1012
1066
|
columns,
|
|
1013
1067
|
};
|
|
1014
1068
|
};
|
|
1015
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1016
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
1069
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ConfigService, deps: [{ token: i1$1.SdStorageService }, { token: SD_TABLE_CONFIGURATION, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1070
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ConfigService });
|
|
1017
1071
|
}
|
|
1018
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1072
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ConfigService, decorators: [{
|
|
1019
1073
|
type: Injectable
|
|
1020
1074
|
}], ctorParameters: () => [{ type: i1$1.SdStorageService }, { type: undefined, decorators: [{
|
|
1021
1075
|
type: Inject,
|
|
@@ -1030,8 +1084,11 @@ class ConfigComponent {
|
|
|
1030
1084
|
// ==========================================
|
|
1031
1085
|
// 1. SIGNAL INPUTS / OUTPUTS
|
|
1032
1086
|
// ==========================================
|
|
1087
|
+
autoIdInput = input(undefined, ...(ngDevMode ? [{ debugName: "autoIdInput", alias: 'autoId' }] : [{ alias: 'autoId' }]));
|
|
1033
1088
|
tableOption = input(undefined, ...(ngDevMode ? [{ debugName: "tableOption" }] : []));
|
|
1034
1089
|
changes = output();
|
|
1090
|
+
// Base autoId (đã là `components-table-<scope>` từ parent), '' khi parent không set.
|
|
1091
|
+
autoId = computed(() => this.autoIdInput() || '', ...(ngDevMode ? [{ debugName: "autoId" }] : []));
|
|
1035
1092
|
// ==========================================
|
|
1036
1093
|
// 2. SIGNAL QUERIES
|
|
1037
1094
|
// ==========================================
|
|
@@ -1102,10 +1159,10 @@ class ConfigComponent {
|
|
|
1102
1159
|
handleMouseUp() {
|
|
1103
1160
|
this.dragDisabled = true;
|
|
1104
1161
|
}
|
|
1105
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1106
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
1162
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ConfigComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1163
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: ConfigComponent, isStandalone: true, selector: "config", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, tableOption: { classPropertyName: "tableOption", publicName: "tableOption", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { changes: "changes" }, providers: [ConfigService], viewQueries: [{ propertyName: "modal", first: true, predicate: SdModal, descendants: true, isSignal: true }, { propertyName: "table", first: true, predicate: MatTable, descendants: true, isSignal: true }], ngImport: i0, template: "@let _configuration = configuration();\n@let _autoId = autoId();\n\n<sd-modal width=\"sm\" [title]=\"'core.component.table.setup' | translate\" #modal>\n @if (_configuration) {\n <div class=\"c-container\">\n <div class=\"c-table\" style=\"max-height: 70vh\">\n <table\n mat-table\n [dataSource]=\"_configuration.columns!\"\n cdkDropList\n [cdkDropListData]=\"_configuration.columns\"\n (cdkDropListDropped)=\"dropTable($event)\">\n <ng-container matColumnDef=\"invisible\">\n <th mat-header-cell class=\"c-th text-center px-4\" *matHeaderCellDef style=\"width: 96px\">\n {{ 'core.component.form-builder.display' | translate }}\n </th>\n <td class=\"text-center px-4\" mat-cell *matCellDef=\"let item\">\n <div class=\"d-flex\" style=\"gap: 8px\">\n <div class=\"c-handle\" (mousedown)=\"handleMouseDown()\" (mouseup)=\"handleMouseUp()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\" fill=\"#5f6368\">\n <path d=\"M0 0h24v24H0V0z\" fill=\"none\" />\n <path\n d=\"M11 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm-2-8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" />\n </svg>\n </div>\n <sd-switch [model]=\"!item.invisible\" (modelChange)=\"item.invisible = !item.invisible\" />\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"title\">\n <th mat-header-cell class=\"c-th px-4\" *matHeaderCellDef>\n {{ 'core.component.table.column-header' | translate }}\n </th>\n <td class=\"px-4\" mat-cell *matCellDef=\"let item\">\n <sd-input class=\"pb-4\" [placeholder]=\"item?.origin?.title\" [(model)]=\"item.title\" hideInlineError></sd-input>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"width\">\n <th mat-header-cell class=\"c-th px-4\" *matHeaderCellDef style=\"width: 80px\">\n {{ 'core.component.table.width' | translate }}\n </th>\n <td class=\"px-4\" mat-cell *matCellDef=\"let item\">\n <sd-input class=\"pb-4\" [placeholder]=\"item?.origin?.width\" [(model)]=\"item.width\" hideInlineError></sd-input>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"fixed\">\n <th mat-header-cell class=\"c-th text-center px-4\" *matHeaderCellDef style=\"width: 80px\">\n {{ 'core.component.table.fixed' | translate }}\n </th>\n <td class=\"text-center px-4\" mat-cell *matCellDef=\"let item\">\n <sd-switch [(model)]=\"item.fixed\" />\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"truncate\">\n <th mat-header-cell class=\"c-th text-center px-4\" *matHeaderCellDef style=\"width: 100px\">\n {{ 'core.component.table.char-limit' | translate }}\n </th>\n <td class=\"text-center px-4\" mat-cell *matCellDef=\"let item\">\n <sd-switch [(model)]=\"item.truncate\" />\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"['invisible', 'title', 'width', 'fixed', 'truncate']; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: ['invisible', 'title', 'width', 'fixed', 'truncate']\"\n cdkDrag\n [cdkDragData]=\"row\"\n cdkDragLockAxis=\"y\"\n [cdkDragDisabled]=\"dragDisabled\">\n </tr>\n </table>\n </div>\n </div>\n }\n <ng-container sdFooter>\n <sd-button [autoId]=\"_autoId ? _autoId + '-config-skip' : null\" class=\"mr-8\" (click)=\"close()\" [title]=\"'core.component.table.skip' | translate\" color=\"secondary\"> </sd-button>\n <sd-button [autoId]=\"_autoId ? _autoId + '-config-reset' : null\" class=\"mr-8\" (click)=\"onReset()\" [title]=\"'core.component.form-builder.default' | translate\" color=\"primary\"> </sd-button>\n <sd-button [autoId]=\"_autoId ? _autoId + '-config-apply' : null\" (click)=\"onSave()\" [title]=\"'core.component.table.apply' | translate\" type=\"fill\" color=\"primary\"> </sd-button>\n </ng-container>\n</sd-modal>\n", styles: [".c-table{position:relative;overflow:auto}.c-table table{width:100%}.c-table .c-th{font-weight:500;font-size:14px;line-height:20px;color:#000}.c-container{position:relative;min-height:200px}.c-handle{color:#ccc;cursor:move}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "ngmodule", type: CdkTableModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i11.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i11.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "component", type: SdInput, selector: "sd-input", inputs: ["autoId", "name", "appearance", "floatLabel", "size", "form", "label", "helperText", "placeholder", "type", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "minlength", "maxlength", "pattern", "patternErrorMessage", "validator", "inlineError", "hyperlink", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "cleared", "sdFocusForceBlur"] }, { kind: "component", type: SdModal, selector: "sd-modal", inputs: ["autoId", "title", "color", "width", "height", "view", "modalClass", "lazyLoadContent", "hideClose", "disableBackdropClose"], outputs: ["sdClosed"] }, { kind: "component", type: SdSwitch, selector: "sd-switch", inputs: ["autoId", "name", "form", "label", "color", "disabled", "viewed", "hideInlineError", "required", "model"], outputs: ["modelChange", "sdChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
1107
1164
|
}
|
|
1108
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1165
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ConfigComponent, decorators: [{
|
|
1109
1166
|
type: Component,
|
|
1110
1167
|
args: [{ selector: 'config', standalone: true, imports: [
|
|
1111
1168
|
CommonModule,
|
|
@@ -1119,17 +1176,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImpo
|
|
|
1119
1176
|
SdModal,
|
|
1120
1177
|
SdSwitch,
|
|
1121
1178
|
TranslatePipe,
|
|
1122
|
-
], providers: [ConfigService], template: "@let _configuration = configuration();\n\n<sd-modal width=\"sm\" [title]=\"'core.component.table.setup' | translate\" #modal>\n @if (_configuration) {\n <div class=\"c-container\">\n <div class=\"c-table\" style=\"max-height: 70vh\">\n <table\n mat-table\n [dataSource]=\"_configuration.columns!\"\n cdkDropList\n [cdkDropListData]=\"_configuration.columns\"\n (cdkDropListDropped)=\"dropTable($event)\">\n <ng-container matColumnDef=\"invisible\">\n <th mat-header-cell class=\"c-th text-center px-4\" *matHeaderCellDef style=\"width: 96px\">\n {{ 'core.component.form-builder.display' | translate }}\n </th>\n <td class=\"text-center px-4\" mat-cell *matCellDef=\"let item\">\n <div class=\"d-flex\" style=\"gap: 8px\">\n <div class=\"c-handle\" (mousedown)=\"handleMouseDown()\" (mouseup)=\"handleMouseUp()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\" fill=\"#5f6368\">\n <path d=\"M0 0h24v24H0V0z\" fill=\"none\" />\n <path\n d=\"M11 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm-2-8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" />\n </svg>\n </div>\n <sd-switch [model]=\"!item.invisible\" (modelChange)=\"item.invisible = !item.invisible\" />\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"title\">\n <th mat-header-cell class=\"c-th px-4\" *matHeaderCellDef>\n {{ 'core.component.table.column-header' | translate }}\n </th>\n <td class=\"px-4\" mat-cell *matCellDef=\"let item\">\n <sd-input class=\"pb-4\" [placeholder]=\"item?.origin?.title\" [(model)]=\"item.title\" hideInlineError></sd-input>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"width\">\n <th mat-header-cell class=\"c-th px-4\" *matHeaderCellDef style=\"width: 80px\">\n {{ 'core.component.table.width' | translate }}\n </th>\n <td class=\"px-4\" mat-cell *matCellDef=\"let item\">\n <sd-input class=\"pb-4\" [placeholder]=\"item?.origin?.width\" [(model)]=\"item.width\" hideInlineError></sd-input>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"fixed\">\n <th mat-header-cell class=\"c-th text-center px-4\" *matHeaderCellDef style=\"width: 80px\">\n {{ 'core.component.table.fixed' | translate }}\n </th>\n <td class=\"text-center px-4\" mat-cell *matCellDef=\"let item\">\n <sd-switch [(model)]=\"item.fixed\" />\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"truncate\">\n <th mat-header-cell class=\"c-th text-center px-4\" *matHeaderCellDef style=\"width: 100px\">\n {{ 'core.component.table.char-limit' | translate }}\n </th>\n <td class=\"text-center px-4\" mat-cell *matCellDef=\"let item\">\n <sd-switch [(model)]=\"item.truncate\" />\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"['invisible', 'title', 'width', 'fixed', 'truncate']; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: ['invisible', 'title', 'width', 'fixed', 'truncate']\"\n cdkDrag\n [cdkDragData]=\"row\"\n cdkDragLockAxis=\"y\"\n [cdkDragDisabled]=\"dragDisabled\">\n </tr>\n </table>\n </div>\n </div>\n }\n <ng-container sdFooter>\n <sd-button class=\"mr-8\" (click)=\"close()\" [title]=\"'core.component.table.skip' | translate\" color=\"secondary\"> </sd-button>\n <sd-button class=\"mr-8\" (click)=\"onReset()\" [title]=\"'core.component.form-builder.default' | translate\" color=\"primary\"> </sd-button>\n <sd-button (click)=\"onSave()\" [title]=\"'core.component.table.apply' | translate\" type=\"fill\" color=\"primary\"> </sd-button>\n </ng-container>\n</sd-modal>\n", styles: [".c-table{position:relative;overflow:auto}.c-table table{width:100%}.c-table .c-th{font-weight:500;font-size:14px;line-height:20px;color:#000}.c-container{position:relative;min-height:200px}.c-handle{color:#ccc;cursor:move}\n"] }]
|
|
1123
|
-
}], ctorParameters: () => [], propDecorators: { tableOption: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableOption", required: false }] }], changes: [{ type: i0.Output, args: ["changes"] }], modal: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SdModal), { isSignal: true }] }], table: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatTable), { isSignal: true }] }] } });
|
|
1179
|
+
], providers: [ConfigService], template: "@let _configuration = configuration();\n@let _autoId = autoId();\n\n<sd-modal width=\"sm\" [title]=\"'core.component.table.setup' | translate\" #modal>\n @if (_configuration) {\n <div class=\"c-container\">\n <div class=\"c-table\" style=\"max-height: 70vh\">\n <table\n mat-table\n [dataSource]=\"_configuration.columns!\"\n cdkDropList\n [cdkDropListData]=\"_configuration.columns\"\n (cdkDropListDropped)=\"dropTable($event)\">\n <ng-container matColumnDef=\"invisible\">\n <th mat-header-cell class=\"c-th text-center px-4\" *matHeaderCellDef style=\"width: 96px\">\n {{ 'core.component.form-builder.display' | translate }}\n </th>\n <td class=\"text-center px-4\" mat-cell *matCellDef=\"let item\">\n <div class=\"d-flex\" style=\"gap: 8px\">\n <div class=\"c-handle\" (mousedown)=\"handleMouseDown()\" (mouseup)=\"handleMouseUp()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\" fill=\"#5f6368\">\n <path d=\"M0 0h24v24H0V0z\" fill=\"none\" />\n <path\n d=\"M11 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm-2-8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" />\n </svg>\n </div>\n <sd-switch [model]=\"!item.invisible\" (modelChange)=\"item.invisible = !item.invisible\" />\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"title\">\n <th mat-header-cell class=\"c-th px-4\" *matHeaderCellDef>\n {{ 'core.component.table.column-header' | translate }}\n </th>\n <td class=\"px-4\" mat-cell *matCellDef=\"let item\">\n <sd-input class=\"pb-4\" [placeholder]=\"item?.origin?.title\" [(model)]=\"item.title\" hideInlineError></sd-input>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"width\">\n <th mat-header-cell class=\"c-th px-4\" *matHeaderCellDef style=\"width: 80px\">\n {{ 'core.component.table.width' | translate }}\n </th>\n <td class=\"px-4\" mat-cell *matCellDef=\"let item\">\n <sd-input class=\"pb-4\" [placeholder]=\"item?.origin?.width\" [(model)]=\"item.width\" hideInlineError></sd-input>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"fixed\">\n <th mat-header-cell class=\"c-th text-center px-4\" *matHeaderCellDef style=\"width: 80px\">\n {{ 'core.component.table.fixed' | translate }}\n </th>\n <td class=\"text-center px-4\" mat-cell *matCellDef=\"let item\">\n <sd-switch [(model)]=\"item.fixed\" />\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"truncate\">\n <th mat-header-cell class=\"c-th text-center px-4\" *matHeaderCellDef style=\"width: 100px\">\n {{ 'core.component.table.char-limit' | translate }}\n </th>\n <td class=\"text-center px-4\" mat-cell *matCellDef=\"let item\">\n <sd-switch [(model)]=\"item.truncate\" />\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"['invisible', 'title', 'width', 'fixed', 'truncate']; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: ['invisible', 'title', 'width', 'fixed', 'truncate']\"\n cdkDrag\n [cdkDragData]=\"row\"\n cdkDragLockAxis=\"y\"\n [cdkDragDisabled]=\"dragDisabled\">\n </tr>\n </table>\n </div>\n </div>\n }\n <ng-container sdFooter>\n <sd-button [autoId]=\"_autoId ? _autoId + '-config-skip' : null\" class=\"mr-8\" (click)=\"close()\" [title]=\"'core.component.table.skip' | translate\" color=\"secondary\"> </sd-button>\n <sd-button [autoId]=\"_autoId ? _autoId + '-config-reset' : null\" class=\"mr-8\" (click)=\"onReset()\" [title]=\"'core.component.form-builder.default' | translate\" color=\"primary\"> </sd-button>\n <sd-button [autoId]=\"_autoId ? _autoId + '-config-apply' : null\" (click)=\"onSave()\" [title]=\"'core.component.table.apply' | translate\" type=\"fill\" color=\"primary\"> </sd-button>\n </ng-container>\n</sd-modal>\n", styles: [".c-table{position:relative;overflow:auto}.c-table table{width:100%}.c-table .c-th{font-weight:500;font-size:14px;line-height:20px;color:#000}.c-container{position:relative;min-height:200px}.c-handle{color:#ccc;cursor:move}\n"] }]
|
|
1180
|
+
}], ctorParameters: () => [], propDecorators: { autoIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], tableOption: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableOption", required: false }] }], changes: [{ type: i0.Output, args: ["changes"] }], modal: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SdModal), { isSignal: true }] }], table: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatTable), { isSignal: true }] }] } });
|
|
1124
1181
|
|
|
1125
1182
|
class ToStringPipe {
|
|
1126
1183
|
transform(value) {
|
|
1127
1184
|
return value !== null && value !== undefined ? String(value) : '';
|
|
1128
1185
|
}
|
|
1129
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1130
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.
|
|
1186
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ToStringPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1187
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.24", ngImport: i0, type: ToStringPipe, isStandalone: true, name: "asString" });
|
|
1131
1188
|
}
|
|
1132
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1189
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ToStringPipe, decorators: [{
|
|
1133
1190
|
type: Pipe,
|
|
1134
1191
|
args: [{
|
|
1135
1192
|
name: 'asString',
|
|
@@ -1174,12 +1231,12 @@ class ViewComponent {
|
|
|
1174
1231
|
toggle = () => {
|
|
1175
1232
|
this.isCollapsed.update(current => !current);
|
|
1176
1233
|
};
|
|
1177
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1178
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
1234
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1235
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: ViewComponent, isStandalone: true, selector: "view", inputs: { autoId: { classPropertyName: "autoId", publicName: "autoId", isSignal: true, isRequired: true, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "contentContainer", first: true, predicate: ["contentContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "@let _column = column();\n@let _item = item();\n@let _autoId = autoId();\n\n@let view = _item.meta.display[_column.field];\n@let _truncateEnable = truncateEnable();\n@let _truncateWidth = truncateWidth();\n@let _isCollapsed = isCollapsed();\n@let isExpandByMore = isOverflowing() && _column?.cell?.truncate?.type === 'more';\n@let isExpandByTooltip = isOverflowing() && _column?.cell?.truncate?.type === 'tooltip';\n\n@if (view) {\n @if (view.isHtml) {\n @if (view.click) {\n <div\n #contentContainer\n [attr.data-autoId]=\"_autoId\"\n (click)=\"view.click()\"\n class=\"text-break cursor-pointer\"\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? htmlClickTooltip : '')\"\n [style]=\"view.cellStyle\"\n [style.max-width]=\"_truncateWidth\"\n [class.c-ellipsis-html]=\"_truncateEnable\"\n [innerHTML]=\"view.data | sdSafeHtml\"\n aria-hidden=\"true\"></div>\n\n <ng-template #htmlClickTooltip>\n <div\n class=\"c-tooltip-inner-content\"\n [style.max-width]=\"'calc(' + _truncateWidth + ' * 1.5)'\"\n style=\"max-height: 200px; overflow-y: auto; scrollbar-width: thin\">\n <div [innerHTML]=\"view.data | sdSafeHtml\"></div>\n </div>\n </ng-template>\n } @else {\n <!-- N\u1EBFu column c\u00F3 b\u1EADt \"gi\u1EDBi h\u1EA1n k\u00FD t\u1EF1\" -->\n @if (_truncateEnable) {\n <div\n #contentContainer\n [style.max-width]=\"_truncateWidth\"\n [class.c-ellipsis-html]=\"_isCollapsed\"\n [attr.data-autoId]=\"_autoId\"\n class=\"text-break\"\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? htmlTooltip : '')\"\n containerClass=\"c-tooltip-html-d374bd93-f136-425c-bcc2-2d88cb163e44\"\n container=\"body\"\n placement=\"bottom\"\n [sdTooltipDelay]=\"100\"\n [style]=\"view.cellStyle\"\n [innerHTML]=\"view.data | sdSafeHtml\"></div>\n\n <ng-template #htmlTooltip>\n <div\n class=\"c-tooltip-inner-content\"\n [style.max-width]=\"'calc(' + _truncateWidth + ' * 1.5)'\"\n style=\"max-height: 200px; overflow-y: auto; scrollbar-width: thin\">\n <div [innerHTML]=\"view.data | sdSafeHtml\"></div>\n </div>\n </ng-template>\n\n @if (isExpandByMore) {\n <button (click)=\"toggle()\" class=\"c-collapse\">{{ _isCollapsed ? ('core.component.form-builder.show-more' | translate) : ('core.component.form-builder.show-less' | translate) }}</button>\n }\n } @else {\n <div\n [attr.data-autoId]=\"_autoId\"\n class=\"text-break\"\n [sdTooltip]=\"view.tooltip || ''\"\n [style]=\"view.cellStyle\"\n [innerHTML]=\"view.data | sdSafeHtml\"></div>\n }\n <!-- End -->\n }\n } @else {\n <!-- N\u1EBFu l\u00E0 gi\u00E1 tr\u1ECB l\u1EA5y hi\u1EC3n th\u1ECB l\u1EA5y tr\u1EF1c ti\u1EBFp t\u1EEB field -->\n @if (view.badge) {\n @if (view.data) {\n <sd-badge\n [attr.data-autoId]=\"_autoId\"\n [type]=\"view.badge.type\"\n [title]=\"view.data\"\n [color]=\"view.badge.color\"\n [icon]=\"view.badge.icon\"\n [sdTooltip]=\"view.tooltip || ''\"\n (click)=\"!!view.click && view.click()\">\n </sd-badge>\n }\n } @else {\n @if (view.click) {\n <div\n #contentContainer\n class=\"text-break\"\n [style]=\"view.cellStyle\"\n [style.max-width]=\"_truncateWidth\"\n [class.c-ellipsis]=\"_truncateEnable\"\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? view.data : '') | asString\">\n <a [attr.data-autoId]=\"_autoId\" href=\"javascript:;\" (click)=\"view.click()\">\n {{ view.data }}\n </a>\n </div>\n } @else {\n <!-- N\u1EBFu column c\u00F3 b\u1EADt \"gi\u1EDBi h\u1EA1n k\u00FD t\u1EF1\" -->\n @if (_truncateEnable) {\n <div\n #contentContainer\n [attr.data-autoId]=\"_autoId\"\n class=\"text-break\"\n [style]=\"view.cellStyle\"\n [style.max-width]=\"_truncateWidth\"\n [class.c-ellipsis]=\"_isCollapsed\"\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? view.data : '') | asString\">\n {{ view.data }}\n </div>\n\n <!-- N\u1EBFu option xem full th\u00F4ng tin l\u00E0 \"btn xem th\u00EAm\" -->\n @if (isExpandByMore) {\n <button (click)=\"toggle()\" class=\"c-collapse\">{{ _isCollapsed ? ('core.component.form-builder.show-more' | translate) : ('core.component.form-builder.show-less' | translate) }}</button>\n }\n } @else {\n <div [attr.data-autoId]=\"_autoId\" class=\"text-break\" [style]=\"view.cellStyle\" [sdTooltip]=\"view.tooltip || ''\">\n {{ view.data }}\n </div>\n }\n <!-- End -->\n }\n }\n }\n}\n", styles: [".c-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c-ellipsis-html{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;line-clamp:1;text-overflow:ellipsis;overflow:hidden}.c-collapse{background:none;color:#00e;border:none;padding:0;font-size:12px;cursor:pointer;outline:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: SdBadge, selector: "sd-badge", inputs: ["type", "color", "primary", "secondary", "success", "info", "warning", "error", "fontSet", "title", "description", "tooltip", "icon", "size"], outputs: ["click"] }, { kind: "directive", type: SdTooltipDirective, selector: "[sdTooltip]", inputs: ["sdTooltip", "sdTooltipPosition", "sdTooltipDelay", "sdTooltipColor"] }, { kind: "pipe", type: SdSafeHtmlPipe, name: "sdSafeHtml" }, { kind: "pipe", type: ToStringPipe, name: "asString" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1179
1236
|
}
|
|
1180
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1237
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ViewComponent, decorators: [{
|
|
1181
1238
|
type: Component,
|
|
1182
|
-
args: [{ selector: 'view', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, SdBadge, SdSafeHtmlPipe, SdTooltipDirective, ToStringPipe, TranslatePipe], template: "@let _column = column();\n@let _item = item();\n@let _autoId = autoId();\n\n@let view = _item.meta.display[_column.field];\n@let _truncateEnable = truncateEnable();\n@let _truncateWidth = truncateWidth();\n@let isExpandByMore = isOverflowing() && _column?.cell?.truncate?.type === 'more';\n@let isExpandByTooltip = isOverflowing() && _column?.cell?.truncate?.type === 'tooltip';\n\n@if (view) {\n @if (view.isHtml) {\n @if (view.click) {\n <div\n #contentContainer\n [attr.data-autoId]=\"
|
|
1239
|
+
args: [{ selector: 'view', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, SdBadge, SdSafeHtmlPipe, SdTooltipDirective, ToStringPipe, TranslatePipe], template: "@let _column = column();\n@let _item = item();\n@let _autoId = autoId();\n\n@let view = _item.meta.display[_column.field];\n@let _truncateEnable = truncateEnable();\n@let _truncateWidth = truncateWidth();\n@let _isCollapsed = isCollapsed();\n@let isExpandByMore = isOverflowing() && _column?.cell?.truncate?.type === 'more';\n@let isExpandByTooltip = isOverflowing() && _column?.cell?.truncate?.type === 'tooltip';\n\n@if (view) {\n @if (view.isHtml) {\n @if (view.click) {\n <div\n #contentContainer\n [attr.data-autoId]=\"_autoId\"\n (click)=\"view.click()\"\n class=\"text-break cursor-pointer\"\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? htmlClickTooltip : '')\"\n [style]=\"view.cellStyle\"\n [style.max-width]=\"_truncateWidth\"\n [class.c-ellipsis-html]=\"_truncateEnable\"\n [innerHTML]=\"view.data | sdSafeHtml\"\n aria-hidden=\"true\"></div>\n\n <ng-template #htmlClickTooltip>\n <div\n class=\"c-tooltip-inner-content\"\n [style.max-width]=\"'calc(' + _truncateWidth + ' * 1.5)'\"\n style=\"max-height: 200px; overflow-y: auto; scrollbar-width: thin\">\n <div [innerHTML]=\"view.data | sdSafeHtml\"></div>\n </div>\n </ng-template>\n } @else {\n <!-- N\u1EBFu column c\u00F3 b\u1EADt \"gi\u1EDBi h\u1EA1n k\u00FD t\u1EF1\" -->\n @if (_truncateEnable) {\n <div\n #contentContainer\n [style.max-width]=\"_truncateWidth\"\n [class.c-ellipsis-html]=\"_isCollapsed\"\n [attr.data-autoId]=\"_autoId\"\n class=\"text-break\"\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? htmlTooltip : '')\"\n containerClass=\"c-tooltip-html-d374bd93-f136-425c-bcc2-2d88cb163e44\"\n container=\"body\"\n placement=\"bottom\"\n [sdTooltipDelay]=\"100\"\n [style]=\"view.cellStyle\"\n [innerHTML]=\"view.data | sdSafeHtml\"></div>\n\n <ng-template #htmlTooltip>\n <div\n class=\"c-tooltip-inner-content\"\n [style.max-width]=\"'calc(' + _truncateWidth + ' * 1.5)'\"\n style=\"max-height: 200px; overflow-y: auto; scrollbar-width: thin\">\n <div [innerHTML]=\"view.data | sdSafeHtml\"></div>\n </div>\n </ng-template>\n\n @if (isExpandByMore) {\n <button (click)=\"toggle()\" class=\"c-collapse\">{{ _isCollapsed ? ('core.component.form-builder.show-more' | translate) : ('core.component.form-builder.show-less' | translate) }}</button>\n }\n } @else {\n <div\n [attr.data-autoId]=\"_autoId\"\n class=\"text-break\"\n [sdTooltip]=\"view.tooltip || ''\"\n [style]=\"view.cellStyle\"\n [innerHTML]=\"view.data | sdSafeHtml\"></div>\n }\n <!-- End -->\n }\n } @else {\n <!-- N\u1EBFu l\u00E0 gi\u00E1 tr\u1ECB l\u1EA5y hi\u1EC3n th\u1ECB l\u1EA5y tr\u1EF1c ti\u1EBFp t\u1EEB field -->\n @if (view.badge) {\n @if (view.data) {\n <sd-badge\n [attr.data-autoId]=\"_autoId\"\n [type]=\"view.badge.type\"\n [title]=\"view.data\"\n [color]=\"view.badge.color\"\n [icon]=\"view.badge.icon\"\n [sdTooltip]=\"view.tooltip || ''\"\n (click)=\"!!view.click && view.click()\">\n </sd-badge>\n }\n } @else {\n @if (view.click) {\n <div\n #contentContainer\n class=\"text-break\"\n [style]=\"view.cellStyle\"\n [style.max-width]=\"_truncateWidth\"\n [class.c-ellipsis]=\"_truncateEnable\"\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? view.data : '') | asString\">\n <a [attr.data-autoId]=\"_autoId\" href=\"javascript:;\" (click)=\"view.click()\">\n {{ view.data }}\n </a>\n </div>\n } @else {\n <!-- N\u1EBFu column c\u00F3 b\u1EADt \"gi\u1EDBi h\u1EA1n k\u00FD t\u1EF1\" -->\n @if (_truncateEnable) {\n <div\n #contentContainer\n [attr.data-autoId]=\"_autoId\"\n class=\"text-break\"\n [style]=\"view.cellStyle\"\n [style.max-width]=\"_truncateWidth\"\n [class.c-ellipsis]=\"_isCollapsed\"\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? view.data : '') | asString\">\n {{ view.data }}\n </div>\n\n <!-- N\u1EBFu option xem full th\u00F4ng tin l\u00E0 \"btn xem th\u00EAm\" -->\n @if (isExpandByMore) {\n <button (click)=\"toggle()\" class=\"c-collapse\">{{ _isCollapsed ? ('core.component.form-builder.show-more' | translate) : ('core.component.form-builder.show-less' | translate) }}</button>\n }\n } @else {\n <div [attr.data-autoId]=\"_autoId\" class=\"text-break\" [style]=\"view.cellStyle\" [sdTooltip]=\"view.tooltip || ''\">\n {{ view.data }}\n </div>\n }\n <!-- End -->\n }\n }\n }\n}\n", styles: [".c-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c-ellipsis-html{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;line-clamp:1;text-overflow:ellipsis;overflow:hidden}.c-collapse{background:none;color:#00e;border:none;padding:0;font-size:12px;cursor:pointer;outline:none}\n"] }]
|
|
1183
1240
|
}], ctorParameters: () => [], propDecorators: { contentContainer: [{ type: i0.ViewChild, args: ['contentContainer', { isSignal: true }] }], autoId: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: true }] }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }], item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: true }] }] } });
|
|
1184
1241
|
|
|
1185
1242
|
class DesktopCellComponent {
|
|
@@ -1240,10 +1297,10 @@ class DesktopCellComponent {
|
|
|
1240
1297
|
}
|
|
1241
1298
|
});
|
|
1242
1299
|
};
|
|
1243
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1244
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
1300
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: DesktopCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1301
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: DesktopCellComponent, isStandalone: true, selector: "desktop-cell", inputs: { column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, cellDef: { classPropertyName: "cellDef", publicName: "cellDef", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "contentContainer", first: true, predicate: ["contentContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "@let _column = column();\n@let _item = item();\n@let _autoId = autoId();\n\n@let _truncateEnable = truncateEnable();\n@let _truncateWidth = truncateWidth();\n@let isExpandByMore = isOverflowing() && _column?.cell?.truncate?.type === 'more';\n@let isExpandByTooltip = isOverflowing() && _column?.cell?.truncate?.type === 'tooltip';\n\n@let _templateRef = templateRef();\n@let context =\n {\n item: _item.data,\n column: _column,\n autoId: _autoId,\n };\n\n@if (_templateRef) {\n <!-- N\u1EBFu column c\u00F3 b\u1EADt \"gi\u1EDBi h\u1EA1n k\u00FD t\u1EF1\" -->\n @if (_truncateEnable) {\n <div\n #contentContainer\n [style.max-width]=\"_truncateWidth\"\n [class.c-ellipsis-html]=\"isCollapsed()\"\n [sdTooltip]=\"isExpandByTooltip ? htmlTooltip : ''\">\n <ng-container *ngTemplateOutlet=\"_templateRef; context: context\" />\n </div>\n\n <!-- N\u1EBFu option xem full th\u00F4ng tin l\u00E0 \"tooltip\" -->\n <ng-template #htmlTooltip>\n <div\n [style.max-width]=\"'calc(' + _truncateWidth + ' * 1.5)'\"\n style=\"max-height: 200px; overflow-y: auto; scrollbar-width: thin\">\n <ng-container *ngTemplateOutlet=\"_templateRef; context: context\" />\n </div>\n </ng-template>\n\n <!-- N\u1EBFu option xem full th\u00F4ng tin l\u00E0 \"btn xem th\u00EAm\" -->\n @if (isExpandByMore) {\n <button (click)=\"toggle()\" class=\"c-collapse\">\n {{ isCollapsed() ? ('core.component.form-builder.show-more' | translate) : ('core.component.form-builder.show-less' | translate) }}\n </button>\n }\n } @else {\n <ng-container *ngTemplateOutlet=\"_templateRef; context: context\" />\n }\n} @else {\n <view [column]=\"column()\" [item]=\"item()\" [autoId]=\"context.autoId\" />\n}\n", styles: [".c-ellipsis-html{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;line-clamp:1;text-overflow:ellipsis;overflow:hidden}.c-collapse{background:none;color:#00e;border:none;padding:0;font-size:12px;cursor:pointer;outline:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: SdTooltipDirective, selector: "[sdTooltip]", inputs: ["sdTooltip", "sdTooltipPosition", "sdTooltipDelay", "sdTooltipColor"] }, { kind: "component", type: ViewComponent, selector: "view", inputs: ["autoId", "column", "item"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1245
1302
|
}
|
|
1246
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1303
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: DesktopCellComponent, decorators: [{
|
|
1247
1304
|
type: Component,
|
|
1248
1305
|
args: [{ selector: 'desktop-cell', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, SdTooltipDirective, ViewComponent, TranslatePipe], template: "@let _column = column();\n@let _item = item();\n@let _autoId = autoId();\n\n@let _truncateEnable = truncateEnable();\n@let _truncateWidth = truncateWidth();\n@let isExpandByMore = isOverflowing() && _column?.cell?.truncate?.type === 'more';\n@let isExpandByTooltip = isOverflowing() && _column?.cell?.truncate?.type === 'tooltip';\n\n@let _templateRef = templateRef();\n@let context =\n {\n item: _item.data,\n column: _column,\n autoId: _autoId,\n };\n\n@if (_templateRef) {\n <!-- N\u1EBFu column c\u00F3 b\u1EADt \"gi\u1EDBi h\u1EA1n k\u00FD t\u1EF1\" -->\n @if (_truncateEnable) {\n <div\n #contentContainer\n [style.max-width]=\"_truncateWidth\"\n [class.c-ellipsis-html]=\"isCollapsed()\"\n [sdTooltip]=\"isExpandByTooltip ? htmlTooltip : ''\">\n <ng-container *ngTemplateOutlet=\"_templateRef; context: context\" />\n </div>\n\n <!-- N\u1EBFu option xem full th\u00F4ng tin l\u00E0 \"tooltip\" -->\n <ng-template #htmlTooltip>\n <div\n [style.max-width]=\"'calc(' + _truncateWidth + ' * 1.5)'\"\n style=\"max-height: 200px; overflow-y: auto; scrollbar-width: thin\">\n <ng-container *ngTemplateOutlet=\"_templateRef; context: context\" />\n </div>\n </ng-template>\n\n <!-- N\u1EBFu option xem full th\u00F4ng tin l\u00E0 \"btn xem th\u00EAm\" -->\n @if (isExpandByMore) {\n <button (click)=\"toggle()\" class=\"c-collapse\">\n {{ isCollapsed() ? ('core.component.form-builder.show-more' | translate) : ('core.component.form-builder.show-less' | translate) }}\n </button>\n }\n } @else {\n <ng-container *ngTemplateOutlet=\"_templateRef; context: context\" />\n }\n} @else {\n <view [column]=\"column()\" [item]=\"item()\" [autoId]=\"context.autoId\" />\n}\n", styles: [".c-ellipsis-html{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;line-clamp:1;text-overflow:ellipsis;overflow:hidden}.c-collapse{background:none;color:#00e;border:none;padding:0;font-size:12px;cursor:pointer;outline:none}\n"] }]
|
|
1249
1306
|
}], ctorParameters: () => [], propDecorators: { contentContainer: [{ type: i0.ViewChild, args: ['contentContainer', { isSignal: true }] }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }], item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: true }] }], cellDef: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellDef", required: true }] }] } });
|
|
@@ -1293,10 +1350,10 @@ class CommandPipe {
|
|
|
1293
1350
|
const tpl = command?.htmlTemplate;
|
|
1294
1351
|
return typeof tpl === 'function' ? tpl(item.data) : undefined;
|
|
1295
1352
|
};
|
|
1296
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1297
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.
|
|
1353
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: CommandPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1354
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.24", ngImport: i0, type: CommandPipe, isStandalone: true, name: "command" });
|
|
1298
1355
|
}
|
|
1299
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1356
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: CommandPipe, decorators: [{
|
|
1300
1357
|
type: Pipe,
|
|
1301
1358
|
args: [{ name: 'command' }]
|
|
1302
1359
|
}] });
|
|
@@ -1382,10 +1439,10 @@ class CommandFilterPipe {
|
|
|
1382
1439
|
const title = this.#title(item, command);
|
|
1383
1440
|
return `${icon || 'noicon'}-${StringUtilities.changeAliasLowerCase(title) || 'notitle'}`;
|
|
1384
1441
|
};
|
|
1385
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1386
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.
|
|
1442
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: CommandFilterPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1443
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.24", ngImport: i0, type: CommandFilterPipe, isStandalone: true, name: "filter" });
|
|
1387
1444
|
}
|
|
1388
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1445
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: CommandFilterPipe, decorators: [{
|
|
1389
1446
|
type: Pipe,
|
|
1390
1447
|
args: [{ name: 'filter' }]
|
|
1391
1448
|
}] });
|
|
@@ -1415,10 +1472,10 @@ class DesktopCommand {
|
|
|
1415
1472
|
}, ...(ngDevMode ? [{ debugName: "autoId" }] : []));
|
|
1416
1473
|
// Commands signal (mặc định mảng rỗng).
|
|
1417
1474
|
_commands = computed(() => this.commands() || [], ...(ngDevMode ? [{ debugName: "_commands" }] : []));
|
|
1418
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1419
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
1475
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: DesktopCommand, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1476
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: DesktopCommand, isStandalone: true, selector: "desktop-command", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, itemIndex: { classPropertyName: "itemIndex", publicName: "itemIndex", isSignal: true, isRequired: true, transformFunction: null }, commands: { classPropertyName: "commands", publicName: "commands", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-autoid": "autoId()" } }, ngImport: i0, template: "@let _autoId = autoId();\n@let _item = item();\n@let filteredCommands = _item | filter: _commands() | async;\n\n@if (filteredCommands?.length) {\n @for (command of filteredCommands; track command.key) {\n @let _meta = _item | command: command;\n @if (command.type === 'normal') {\n <button\n [attr.data-autoid]=\"_autoId + '-' + command.key\"\n (click)=\"command.click(_item.data)\"\n [matTooltip]=\"_meta.title\"\n aria-hidden=\"true\"\n [disabled]=\"_meta.disabled\"\n mat-icon-button>\n <mat-icon class=\"c-icon\" [color]=\"command.color || 'secondary'\" [fontSet]=\"command.fontSet!\">\n {{ _meta.icon }}\n </mat-icon>\n </button>\n } @else {\n <button\n [attr.data-autoid]=\"_autoId + '-' + command.key\"\n [matMenuTriggerFor]=\"menu\"\n aria-hidden=\"true\"\n mat-icon-button>\n @if (_meta.icon) {\n <mat-icon class=\"c-icon\" [fontSet]=\"command.fontSet!\">{{ _meta.icon }}</mat-icon>\n } @else {\n <mat-icon class=\"c-icon\">more_vert</mat-icon>\n }\n </button>\n <mat-menu #menu=\"matMenu\" [attr.data-autoid]=\"_autoId + '-' + command.key + '-menu'\">\n <span>\n @for (childCommand of command.children; track childCommand.key) {\n @let _childMeta = _item | command: childCommand;\n <button\n [attr.data-autoid]=\"_autoId + '-' + command.key + '-' + childCommand.key\"\n mat-menu-item\n (click)=\"childCommand.click(_item.data)\"\n [disabled]=\"_childMeta.disabled\">\n @if (_childMeta.htmlTemplate) {\n <div [innerHTML]=\"_childMeta.htmlTemplate\"></div>\n } @else {\n <div>\n <mat-icon [color]=\"childCommand.color || 'secondary'\" [fontSet]=\"command.fontSet!\">\n {{ _childMeta.icon }}\n </mat-icon>\n <span> {{ _childMeta.title }}</span>\n </div>\n }\n </button>\n }\n </span>\n </mat-menu>\n }\n }\n}\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}:host{display:flex;align-items:center}button[mat-icon-button]{width:24px;height:24px;line-height:24px;padding:0}mat-icon.c-icon{color:var(--sd-black400)!important;width:16px;height:16px;font-size:16px;line-height:16px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i1$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { 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: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: CommandPipe, name: "command" }, { kind: "pipe", type: CommandFilterPipe, name: "filter" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1420
1477
|
}
|
|
1421
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1478
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: DesktopCommand, decorators: [{
|
|
1422
1479
|
type: Component,
|
|
1423
1480
|
args: [{ selector: 'desktop-command', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, host: {
|
|
1424
1481
|
'[attr.data-autoid]': 'autoId()',
|
|
@@ -1707,10 +1764,10 @@ class SdPopupExport {
|
|
|
1707
1764
|
}
|
|
1708
1765
|
return '';
|
|
1709
1766
|
};
|
|
1710
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1711
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.
|
|
1767
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdPopupExport, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.SdLoadingService }, { token: i1$1.SdExcelService }, { token: i1$1.SdNotifyService }, { token: i1$1.SdConfirmService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1768
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.24", type: SdPopupExport, isStandalone: true, selector: "sd-popup-export", inputs: { _tableOption: ["tableOption", "_tableOption"], configuration: "configuration" }, outputs: { export: "export" }, viewQueries: [{ propertyName: "modal", first: true, predicate: ["modal"], descendants: true }, { propertyName: "listGroups", first: true, predicate: ["listGroups"], descendants: true }], ngImport: i0, template: "<sd-modal width=\"907px\" [title]=\"'Exported template'\" #modal>\n <div class=\"row\">\n <div *ngIf=\"!files?.length\" class=\"col-12\">\n <div class=\"c-empty\">\n <img class=\"sd-image-data-empty\" alt=\"empty-image\" />\n <div class=\"T14R\">{{ 'There are no exported templates' }}</div>\n </div>\n </div>\n <ng-container *ngIf=\"files?.length\">\n <div class=\"col-12\">\n <div class=\"c-table\" style=\"max-height: 50vh\">\n <table mat-table [dataSource]=\"files\">\n <ng-container matColumnDef=\"stt\">\n <th mat-header-cell class=\"c-th text-center px-5\" *matHeaderCellDef style=\"width: 50px\">#</th>\n <td class=\"text-center px-5\" mat-cell *matCellDef=\"let item; let idx = index\">\n {{ idx + 1 }}\n </td>\n </ng-container>\n <ng-container matColumnDef=\"fileName\">\n <th mat-header-cell class=\"c-th px-5\" *matHeaderCellDef>\n {{ 'File name' }}\n </th>\n <td class=\"px-5\" mat-cell *matCellDef=\"let item\">\n {{ item.fileName }}\n </td>\n </ng-container>\n <ng-container matColumnDef=\"action\">\n <th mat-header-cell class=\"c-th px-5\" *matHeaderCellDef style=\"width: 80px\"></th>\n <td class=\"px-5\" mat-cell *matCellDef=\"let item\">\n <div class=\"d-flex\">\n <button mat-icon-button aria-label=\"delete\" (click)=\"removeFile(item)\">\n <mat-icon>delete</mat-icon>\n </button>\n <button mat-icon-button aria-label=\"download\" (click)=\"onExport(item)\">\n <mat-icon>download</mat-icon>\n </button>\n </div>\n </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"['stt', 'fileName', 'action']; sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['stt', 'fileName', 'action']\"></tr>\n </table>\n </div>\n </div>\n <div *ngIf=\"files.length < 5\" class=\"col-12 mt-10\">\n <sd-button class=\"mr-4\" [title]=\"'New template'\" (click)=\"enableCreating = true\" color=\"info\" [disabled]=\"enableCreating\">\n </sd-button>\n <sd-button *ngIf=\"exportOption?.enableUpload\" [title]=\"'Upload template'\" (click)=\"uploadTemplate()\" type=\"outline\">\n </sd-button>\n </div>\n </ng-container>\n <ng-container *ngIf=\"enableCreating || !files?.length\">\n <div class=\"col-12 mt-20\">\n <div class=\"T14R\">{{ 'Select columns for creating template' }}:</div>\n </div>\n <div class=\"col-12\">\n <mat-chip-listbox selectable=\"true\" multiple=\"true\">\n <ng-container *ngFor=\"let column of columns\">\n <mat-chip-option [selected]=\"selected[column.field]\" (click)=\"selected[column.field] = !selected[column.field]\">\n {{ column.title }}\n </mat-chip-option>\n </ng-container>\n </mat-chip-listbox>\n </div>\n <div class=\"col-12 row\">\n <div class=\"col-10\">\n <sd-input [form]=\"form\" [label]=\"'Template name'\" [(model)]=\"templateName\" [validator]=\"templateNameValidator\"></sd-input>\n </div>\n <div class=\"col-2 mt-8\">\n <sd-button width=\"100%\" [title]=\"'Save'\" color=\"info\" (click)=\"createTemplate()\"> </sd-button>\n </div>\n </div>\n </ng-container>\n </div>\n</sd-modal>\n", styles: [".c-radio-group{display:flex;flex-direction:column;margin:15px 0}.c-radio-button{margin:5px}.c-empty{display:flex;flex-direction:column;justify-content:center;align-items:center;position:static;height:116px;background:#f6f6f6;border-radius:4px}.c-table{position:relative;overflow:auto}.c-table table{width:100%}.c-table .c-th{font-weight:500;font-size:14px;line-height:20px;color:#000}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i5.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "component", type: i5.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "component", type: SdInput, selector: "sd-input", inputs: ["autoId", "name", "appearance", "floatLabel", "size", "form", "label", "helperText", "placeholder", "type", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "minlength", "maxlength", "pattern", "patternErrorMessage", "validator", "inlineError", "hyperlink", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "cleared", "sdFocusForceBlur"] }, { kind: "component", type: SdModal, selector: "sd-modal", inputs: ["autoId", "title", "color", "width", "height", "view", "modalClass", "lazyLoadContent", "hideClose", "disableBackdropClose"], outputs: ["sdClosed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1712
1769
|
}
|
|
1713
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1770
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdPopupExport, decorators: [{
|
|
1714
1771
|
type: Component,
|
|
1715
1772
|
args: [{ selector: 'sd-popup-export', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, MatTableModule, MatIconModule, MatChipsModule, SdButton, SdInput, SdModal], template: "<sd-modal width=\"907px\" [title]=\"'Exported template'\" #modal>\n <div class=\"row\">\n <div *ngIf=\"!files?.length\" class=\"col-12\">\n <div class=\"c-empty\">\n <img class=\"sd-image-data-empty\" alt=\"empty-image\" />\n <div class=\"T14R\">{{ 'There are no exported templates' }}</div>\n </div>\n </div>\n <ng-container *ngIf=\"files?.length\">\n <div class=\"col-12\">\n <div class=\"c-table\" style=\"max-height: 50vh\">\n <table mat-table [dataSource]=\"files\">\n <ng-container matColumnDef=\"stt\">\n <th mat-header-cell class=\"c-th text-center px-5\" *matHeaderCellDef style=\"width: 50px\">#</th>\n <td class=\"text-center px-5\" mat-cell *matCellDef=\"let item; let idx = index\">\n {{ idx + 1 }}\n </td>\n </ng-container>\n <ng-container matColumnDef=\"fileName\">\n <th mat-header-cell class=\"c-th px-5\" *matHeaderCellDef>\n {{ 'File name' }}\n </th>\n <td class=\"px-5\" mat-cell *matCellDef=\"let item\">\n {{ item.fileName }}\n </td>\n </ng-container>\n <ng-container matColumnDef=\"action\">\n <th mat-header-cell class=\"c-th px-5\" *matHeaderCellDef style=\"width: 80px\"></th>\n <td class=\"px-5\" mat-cell *matCellDef=\"let item\">\n <div class=\"d-flex\">\n <button mat-icon-button aria-label=\"delete\" (click)=\"removeFile(item)\">\n <mat-icon>delete</mat-icon>\n </button>\n <button mat-icon-button aria-label=\"download\" (click)=\"onExport(item)\">\n <mat-icon>download</mat-icon>\n </button>\n </div>\n </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"['stt', 'fileName', 'action']; sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['stt', 'fileName', 'action']\"></tr>\n </table>\n </div>\n </div>\n <div *ngIf=\"files.length < 5\" class=\"col-12 mt-10\">\n <sd-button class=\"mr-4\" [title]=\"'New template'\" (click)=\"enableCreating = true\" color=\"info\" [disabled]=\"enableCreating\">\n </sd-button>\n <sd-button *ngIf=\"exportOption?.enableUpload\" [title]=\"'Upload template'\" (click)=\"uploadTemplate()\" type=\"outline\">\n </sd-button>\n </div>\n </ng-container>\n <ng-container *ngIf=\"enableCreating || !files?.length\">\n <div class=\"col-12 mt-20\">\n <div class=\"T14R\">{{ 'Select columns for creating template' }}:</div>\n </div>\n <div class=\"col-12\">\n <mat-chip-listbox selectable=\"true\" multiple=\"true\">\n <ng-container *ngFor=\"let column of columns\">\n <mat-chip-option [selected]=\"selected[column.field]\" (click)=\"selected[column.field] = !selected[column.field]\">\n {{ column.title }}\n </mat-chip-option>\n </ng-container>\n </mat-chip-listbox>\n </div>\n <div class=\"col-12 row\">\n <div class=\"col-10\">\n <sd-input [form]=\"form\" [label]=\"'Template name'\" [(model)]=\"templateName\" [validator]=\"templateNameValidator\"></sd-input>\n </div>\n <div class=\"col-2 mt-8\">\n <sd-button width=\"100%\" [title]=\"'Save'\" color=\"info\" (click)=\"createTemplate()\"> </sd-button>\n </div>\n </div>\n </ng-container>\n </div>\n</sd-modal>\n", styles: [".c-radio-group{display:flex;flex-direction:column;margin:15px 0}.c-radio-button{margin:5px}.c-empty{display:flex;flex-direction:column;justify-content:center;align-items:center;position:static;height:116px;background:#f6f6f6;border-radius:4px}.c-table{position:relative;overflow:auto}.c-table table{width:100%}.c-table .c-th{font-weight:500;font-size:14px;line-height:20px;color:#000}\n"] }]
|
|
1716
1773
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.SdLoadingService }, { type: i1$1.SdExcelService }, { type: i1$1.SdNotifyService }, { type: i1$1.SdConfirmService }], propDecorators: { modal: [{
|
|
@@ -1734,10 +1791,10 @@ class SdTableColumnFilterDefDirective {
|
|
|
1734
1791
|
}
|
|
1735
1792
|
sdTableColumnFilterDef = input.required(...(ngDevMode ? [{ debugName: "sdTableColumnFilterDef" }] : []));
|
|
1736
1793
|
templateRef = inject(TemplateRef);
|
|
1737
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1738
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.
|
|
1794
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTableColumnFilterDefDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1795
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.24", type: SdTableColumnFilterDefDirective, isStandalone: true, selector: "[sdTableColumnFilterDef]", inputs: { sdTableColumnFilterDef: { classPropertyName: "sdTableColumnFilterDef", publicName: "sdTableColumnFilterDef", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
|
|
1739
1796
|
}
|
|
1740
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1797
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTableColumnFilterDefDirective, decorators: [{
|
|
1741
1798
|
type: Directive,
|
|
1742
1799
|
args: [{
|
|
1743
1800
|
selector: '[sdTableColumnFilterDef]',
|
|
@@ -1840,10 +1897,10 @@ class StickyShadowDirective {
|
|
|
1840
1897
|
this.#setShadow(container, colClass, 'sticky-shadow-left', true);
|
|
1841
1898
|
}
|
|
1842
1899
|
}
|
|
1843
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1844
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.
|
|
1900
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: StickyShadowDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1901
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.24", type: StickyShadowDirective, isStandalone: true, selector: "[stickyShadow]", ngImport: i0 });
|
|
1845
1902
|
}
|
|
1846
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1903
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: StickyShadowDirective, decorators: [{
|
|
1847
1904
|
type: Directive,
|
|
1848
1905
|
args: [{
|
|
1849
1906
|
selector: '[stickyShadow]',
|
|
@@ -1961,10 +2018,10 @@ class SdColumnResizeDirective {
|
|
|
1961
2018
|
const m = /^(\d+(?:\.\d+)?)px$/i.exec(value.trim());
|
|
1962
2019
|
return m ? parseFloat(m[1]) : null;
|
|
1963
2020
|
}
|
|
1964
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1965
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.
|
|
2021
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdColumnResizeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2022
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.24", type: SdColumnResizeDirective, isStandalone: true, selector: "[sdColumnResize]", inputs: { sdColumnResize: { classPropertyName: "sdColumnResize", publicName: "sdColumnResize", isSignal: true, isRequired: true, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { resizeEnd: "resizeEnd" }, ngImport: i0 });
|
|
1966
2023
|
}
|
|
1967
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2024
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdColumnResizeDirective, decorators: [{
|
|
1968
2025
|
type: Directive,
|
|
1969
2026
|
args: [{
|
|
1970
2027
|
selector: '[sdColumnResize]',
|
|
@@ -2052,10 +2109,10 @@ class SdGroupPipe {
|
|
|
2052
2109
|
});
|
|
2053
2110
|
return result;
|
|
2054
2111
|
}
|
|
2055
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
2056
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.
|
|
2112
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdGroupPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
2113
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.24", ngImport: i0, type: SdGroupPipe, isStandalone: true, name: "sdGroup" });
|
|
2057
2114
|
}
|
|
2058
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2115
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdGroupPipe, decorators: [{
|
|
2059
2116
|
type: Pipe,
|
|
2060
2117
|
args: [{ name: 'sdGroup' }]
|
|
2061
2118
|
}] });
|
|
@@ -2112,10 +2169,10 @@ class SdSelectionDisabledPipe {
|
|
|
2112
2169
|
}
|
|
2113
2170
|
return true;
|
|
2114
2171
|
};
|
|
2115
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
2116
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.
|
|
2172
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdSelectionDisabledPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
2173
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.24", ngImport: i0, type: SdSelectionDisabledPipe, isStandalone: true, name: "selectionDisabled" });
|
|
2117
2174
|
}
|
|
2118
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2175
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdSelectionDisabledPipe, decorators: [{
|
|
2119
2176
|
type: Pipe,
|
|
2120
2177
|
args: [{
|
|
2121
2178
|
name: 'selectionDisabled',
|
|
@@ -2148,10 +2205,10 @@ class SdSelectionVisibleSelectAllPipe {
|
|
|
2148
2205
|
}
|
|
2149
2206
|
return false;
|
|
2150
2207
|
};
|
|
2151
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
2152
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.
|
|
2208
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdSelectionVisibleSelectAllPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
2209
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.24", ngImport: i0, type: SdSelectionVisibleSelectAllPipe, isStandalone: true, name: "selectionVisibleSelectAll" });
|
|
2153
2210
|
}
|
|
2154
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2211
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdSelectionVisibleSelectAllPipe, decorators: [{
|
|
2155
2212
|
type: Pipe,
|
|
2156
2213
|
args: [{
|
|
2157
2214
|
name: 'selectionVisibleSelectAll',
|
|
@@ -2227,10 +2284,10 @@ class SdSelectionVisiblePipe {
|
|
|
2227
2284
|
// nếu các action đều thuộc groupedActions và rowData ko phải là dòng group
|
|
2228
2285
|
return rowData.meta.selector.actions.some(action => !groupedActions.includes(action));
|
|
2229
2286
|
};
|
|
2230
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
2231
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.
|
|
2287
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdSelectionVisiblePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
2288
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.24", ngImport: i0, type: SdSelectionVisiblePipe, isStandalone: true, name: "selectionVisible" });
|
|
2232
2289
|
}
|
|
2233
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2290
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdSelectionVisiblePipe, decorators: [{
|
|
2234
2291
|
type: Pipe,
|
|
2235
2292
|
args: [{
|
|
2236
2293
|
name: 'selectionVisible',
|
|
@@ -2487,10 +2544,10 @@ class TableExportService {
|
|
|
2487
2544
|
return [];
|
|
2488
2545
|
return option.export?.columns?.filter(e => !e.export?.disabled) || [];
|
|
2489
2546
|
}
|
|
2490
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
2491
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
2547
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: TableExportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2548
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: TableExportService });
|
|
2492
2549
|
}
|
|
2493
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2550
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: TableExportService, decorators: [{
|
|
2494
2551
|
type: Injectable
|
|
2495
2552
|
}] });
|
|
2496
2553
|
|
|
@@ -2695,10 +2752,10 @@ class TableFormatService {
|
|
|
2695
2752
|
}
|
|
2696
2753
|
return undefined;
|
|
2697
2754
|
}
|
|
2698
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
2699
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
2755
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: TableFormatService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2756
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: TableFormatService });
|
|
2700
2757
|
}
|
|
2701
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2758
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: TableFormatService, decorators: [{
|
|
2702
2759
|
type: Injectable
|
|
2703
2760
|
}] });
|
|
2704
2761
|
|
|
@@ -2929,10 +2986,10 @@ class SdTableFilterService {
|
|
|
2929
2986
|
columnOperator,
|
|
2930
2987
|
};
|
|
2931
2988
|
};
|
|
2932
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
2933
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
2989
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTableFilterService, deps: [{ token: i1$1.SdStorageService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2990
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTableFilterService });
|
|
2934
2991
|
}
|
|
2935
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2992
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTableFilterService, decorators: [{
|
|
2936
2993
|
type: Injectable
|
|
2937
2994
|
}], ctorParameters: () => [{ type: i1$1.SdStorageService }] });
|
|
2938
2995
|
|
|
@@ -2952,10 +3009,10 @@ class MatPaginatorIntlCro extends MatPaginatorIntl {
|
|
|
2952
3009
|
const to = from + (length - page * pageSize > pageSize ? pageSize : length - page * pageSize) - 1;
|
|
2953
3010
|
return `${from}-${to}/${NumberUtilities.toISO(length)}`;
|
|
2954
3011
|
};
|
|
2955
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
2956
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
3012
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: MatPaginatorIntlCro, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
3013
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: MatPaginatorIntlCro });
|
|
2957
3014
|
}
|
|
2958
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
3015
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: MatPaginatorIntlCro, decorators: [{
|
|
2959
3016
|
type: Injectable
|
|
2960
3017
|
}] });
|
|
2961
3018
|
class SdTable extends SdBaseSecureComponent {
|
|
@@ -3041,6 +3098,13 @@ class SdTable extends SdBaseSecureComponent {
|
|
|
3041
3098
|
#itemIndexMap = new WeakMap();
|
|
3042
3099
|
#treeExpandState = new Map();
|
|
3043
3100
|
treeRevision = signal(0, ...(ngDevMode ? [{ debugName: "treeRevision" }] : []));
|
|
3101
|
+
// Search ở cấp con (static tree + type 'local'): predicate khớp 1 dòng theo
|
|
3102
|
+
// column filter hiện hành. Set ở #filterLocal khi có filter active, đọc lại ở
|
|
3103
|
+
// #render/#initTreeMeta/#ensureChildItemsFormatted để prune + auto-expand các
|
|
3104
|
+
// nhánh có node con khớp. undefined = không search → cây render bình thường.
|
|
3105
|
+
#treeSearchPredicate;
|
|
3106
|
+
// Lần render trước có đang ở chế độ search hay không (để xử lý chuyển trạng thái).
|
|
3107
|
+
#treeSearchActive = false;
|
|
3044
3108
|
// 1. Private Services
|
|
3045
3109
|
#ref = inject(ChangeDetectorRef);
|
|
3046
3110
|
#configService = inject(ConfigService);
|
|
@@ -3220,99 +3284,119 @@ class SdTable extends SdBaseSecureComponent {
|
|
|
3220
3284
|
}
|
|
3221
3285
|
Object.assign(cur, next);
|
|
3222
3286
|
};
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
const
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3287
|
+
// True nếu column filter hiện có ít nhất một giá trị đang lọc (để bật search-con).
|
|
3288
|
+
#hasActiveColumnFilter = (rawColumnFilter, columns) => columns.some(col => {
|
|
3289
|
+
const v = rawColumnFilter[col.field];
|
|
3290
|
+
if (Array.isArray(v))
|
|
3291
|
+
return v.length > 0;
|
|
3292
|
+
if (v && typeof v === 'object')
|
|
3293
|
+
return !!v.from || !!v.to;
|
|
3294
|
+
return v !== undefined && v !== null && v !== '';
|
|
3295
|
+
});
|
|
3296
|
+
// Predicate khớp MỘT dòng (raw data) theo column filter. Tách riêng để dùng lại
|
|
3297
|
+
// cho cả lọc root lẫn search-con (subtreeMatches/filterMatchingChildren).
|
|
3298
|
+
#matchesColumnFilter = (data, columns, rawColumnFilter) => {
|
|
3299
|
+
for (const column of columns) {
|
|
3300
|
+
const { field, type } = column;
|
|
3301
|
+
const filterValue = (rawColumnFilter[field] || '').toString().trim().toLowerCase();
|
|
3302
|
+
// SỬA: Dùng getNestedValue để hỗ trợ nested field trong filterLocal
|
|
3303
|
+
const rawColVal = Utilities.getNestedValue(data, field);
|
|
3304
|
+
const columnValue = (rawColVal || '').toString().trim().toLowerCase();
|
|
3305
|
+
if (filterValue) {
|
|
3306
|
+
if (!columnValue && type !== 'datetime' && type !== 'date' && type !== 'time') {
|
|
3307
|
+
return false;
|
|
3308
|
+
}
|
|
3309
|
+
if (type === 'string') {
|
|
3310
|
+
if (columnValue.indexOf(filterValue) === -1) {
|
|
3237
3311
|
return false;
|
|
3238
3312
|
}
|
|
3239
|
-
|
|
3240
|
-
|
|
3313
|
+
}
|
|
3314
|
+
else if (type === 'values' || type === 'lazy-values') {
|
|
3315
|
+
const columnType = column;
|
|
3316
|
+
const isMultiple = columnType.option.selection === 'MULTIPLE';
|
|
3317
|
+
if (isMultiple && Array.isArray(rawColVal)) {
|
|
3318
|
+
const columnValues = rawColVal.map((i) => (Utilities.getNestedValue(i, columnType.option.valueField) ?? '').toString().trim().toLowerCase()) ?? [];
|
|
3319
|
+
const filterValues = rawColumnFilter[field]?.map((v) => (v ?? '').toString().trim().toLowerCase());
|
|
3320
|
+
if (filterValues?.length && filterValues.every(fv => !columnValues.includes(fv))) {
|
|
3241
3321
|
return false;
|
|
3242
3322
|
}
|
|
3243
3323
|
}
|
|
3244
|
-
else
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
if (isMultiple && Array.isArray(rawColVal)) {
|
|
3248
|
-
const columnValues = rawColVal.map((i) => (Utilities.getNestedValue(i, columnType.option.valueField) ?? '').toString().trim().toLowerCase()) ?? [];
|
|
3249
|
-
const filterValues = rawColumnFilter[field]?.map((v) => (v ?? '').toString().trim().toLowerCase());
|
|
3250
|
-
if (filterValues?.length && filterValues.every(fv => !columnValues.includes(fv))) {
|
|
3251
|
-
return false;
|
|
3252
|
-
}
|
|
3253
|
-
}
|
|
3254
|
-
else {
|
|
3255
|
-
if (columnValue !== filterValue) {
|
|
3256
|
-
return false;
|
|
3257
|
-
}
|
|
3324
|
+
else {
|
|
3325
|
+
if (columnValue !== filterValue) {
|
|
3326
|
+
return false;
|
|
3258
3327
|
}
|
|
3259
3328
|
}
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
if (filterValue.indexOf('>=') > -1 && cValue < fValue) {
|
|
3268
|
-
return false;
|
|
3269
|
-
}
|
|
3270
|
-
else if (filterValue.indexOf('<=') > -1 && cValue > fValue) {
|
|
3271
|
-
return false;
|
|
3272
|
-
}
|
|
3273
|
-
else if (filterValue.indexOf('<') > -1 && cValue >= fValue) {
|
|
3274
|
-
return false;
|
|
3275
|
-
}
|
|
3276
|
-
else if (filterValue.indexOf('>') > -1 && cValue <= fValue) {
|
|
3277
|
-
return false;
|
|
3278
|
-
}
|
|
3279
|
-
else if (cValue !== fValue) {
|
|
3280
|
-
return false;
|
|
3281
|
-
}
|
|
3329
|
+
}
|
|
3330
|
+
else if (type === 'number') {
|
|
3331
|
+
const fValue = +filterValue.replace('>=', '').replace('<=', '').replace('>', '').replace('<', '');
|
|
3332
|
+
const cValue = +columnValue;
|
|
3333
|
+
if (fValue || fValue === 0) {
|
|
3334
|
+
if (!cValue && cValue !== 0) {
|
|
3335
|
+
return false;
|
|
3282
3336
|
}
|
|
3283
|
-
|
|
3284
|
-
else if (type === 'boolean') {
|
|
3285
|
-
if ((filterValue === '1' || filterValue === 'true') && columnValue !== '1' && columnValue !== 'true') {
|
|
3337
|
+
if (filterValue.indexOf('>=') > -1 && cValue < fValue) {
|
|
3286
3338
|
return false;
|
|
3287
3339
|
}
|
|
3288
|
-
else if ((
|
|
3340
|
+
else if (filterValue.indexOf('<=') > -1 && cValue > fValue) {
|
|
3341
|
+
return false;
|
|
3342
|
+
}
|
|
3343
|
+
else if (filterValue.indexOf('<') > -1 && cValue >= fValue) {
|
|
3344
|
+
return false;
|
|
3345
|
+
}
|
|
3346
|
+
else if (filterValue.indexOf('>') > -1 && cValue <= fValue) {
|
|
3347
|
+
return false;
|
|
3348
|
+
}
|
|
3349
|
+
else if (cValue !== fValue) {
|
|
3289
3350
|
return false;
|
|
3290
3351
|
}
|
|
3291
3352
|
}
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3353
|
+
}
|
|
3354
|
+
else if (type === 'boolean') {
|
|
3355
|
+
if ((filterValue === '1' || filterValue === 'true') && columnValue !== '1' && columnValue !== 'true') {
|
|
3356
|
+
return false;
|
|
3357
|
+
}
|
|
3358
|
+
else if ((filterValue === '0' || filterValue === 'false') && columnValue !== '0' && columnValue !== 'false') {
|
|
3359
|
+
return false;
|
|
3360
|
+
}
|
|
3361
|
+
}
|
|
3362
|
+
else if (type === 'datetime' || type === 'date' || type === 'time') {
|
|
3363
|
+
const from = rawColumnFilter[field]?.from ?? rawColumnFilter[field];
|
|
3364
|
+
const to = rawColumnFilter[field]?.to ?? rawColumnFilter[field];
|
|
3365
|
+
const fromDate = DateUtilities.begin(from);
|
|
3366
|
+
const toDate = DateUtilities.end(to);
|
|
3367
|
+
if (fromDate || toDate) {
|
|
3368
|
+
if (!columnValue) {
|
|
3369
|
+
return false;
|
|
3370
|
+
}
|
|
3371
|
+
const columnTime = new Date(columnValue).getTime();
|
|
3372
|
+
const fromDateTime = fromDate?.getTime() || null;
|
|
3373
|
+
const toDateTime = toDate?.getTime() || null;
|
|
3374
|
+
if (fromDateTime && fromDateTime > columnTime) {
|
|
3375
|
+
return false;
|
|
3376
|
+
}
|
|
3377
|
+
if (toDateTime && columnTime > toDateTime) {
|
|
3378
|
+
return false;
|
|
3310
3379
|
}
|
|
3311
3380
|
}
|
|
3312
3381
|
}
|
|
3313
3382
|
}
|
|
3314
|
-
|
|
3315
|
-
|
|
3383
|
+
}
|
|
3384
|
+
return true;
|
|
3385
|
+
};
|
|
3386
|
+
#filterLocal = (localItems, filterInfo) => {
|
|
3387
|
+
const opt = this.tableOption();
|
|
3388
|
+
const { columns } = opt;
|
|
3389
|
+
const { rawColumnFilter, orderBy, orderDirection, pageSize, pageNumber } = filterInfo;
|
|
3390
|
+
const matchesData = (data) => this.#matchesColumnFilter(data, columns, rawColumnFilter);
|
|
3391
|
+
// Search ở cấp con: chỉ bật cho table local + static tree + đang có filter.
|
|
3392
|
+
// Khi bật, một root được giữ nếu CHÍNH NÓ hoặc bất kỳ hậu duệ nào khớp; và
|
|
3393
|
+
// lưu predicate để #render prune + auto-expand nhánh khớp.
|
|
3394
|
+
const treeOpt = opt.tree;
|
|
3395
|
+
const treeSearch = opt.type === 'local' && treeOpt?.loadType === 'static' && this.#hasActiveColumnFilter(rawColumnFilter, columns);
|
|
3396
|
+
this.#treeSearchPredicate = treeSearch ? matchesData : undefined;
|
|
3397
|
+
const items = treeSearch
|
|
3398
|
+
? localItems.filter(tableItem => subtreeMatches(tableItem.data, matchesData, treeOpt))
|
|
3399
|
+
: localItems.filter(tableItem => matchesData(tableItem.data));
|
|
3316
3400
|
// Sort
|
|
3317
3401
|
if (orderBy && orderDirection) {
|
|
3318
3402
|
const column = columns.find(e => e.field === orderBy);
|
|
@@ -3480,8 +3564,18 @@ class SdTable extends SdBaseSecureComponent {
|
|
|
3480
3564
|
this.scroll()?.scrollTop();
|
|
3481
3565
|
}
|
|
3482
3566
|
const treeOpt = this.tableOption()?.tree;
|
|
3567
|
+
const searchNow = !!this.#treeSearchPredicate;
|
|
3483
3568
|
if (treeOpt) {
|
|
3484
|
-
|
|
3569
|
+
// why: KHÔNG persist trạng thái bung bị ÉP trong lúc search (tránh nhánh
|
|
3570
|
+
// tự bung do search bị ghi nhầm thành lựa chọn của user sau khi clear).
|
|
3571
|
+
if (!this.#treeSearchActive) {
|
|
3572
|
+
this.#saveTreeExpandState(this.items());
|
|
3573
|
+
}
|
|
3574
|
+
// why: search vừa tắt → childItems đang là tập đã prune theo từ khoá cũ;
|
|
3575
|
+
// xoá cache để dựng lại đầy đủ children ở chế độ thường.
|
|
3576
|
+
if (this.#treeSearchActive && !searchNow) {
|
|
3577
|
+
this.#clearTreeChildCache(this.#localItems);
|
|
3578
|
+
}
|
|
3485
3579
|
}
|
|
3486
3580
|
this.items.set(args?.items || []);
|
|
3487
3581
|
this.total.set(args?.total || 0);
|
|
@@ -3490,6 +3584,7 @@ class SdTable extends SdBaseSecureComponent {
|
|
|
3490
3584
|
await this.#expandDefaultBranches(this.items(), treeOpt);
|
|
3491
3585
|
this.treeRevision.update(n => n + 1);
|
|
3492
3586
|
}
|
|
3587
|
+
this.#treeSearchActive = searchNow;
|
|
3493
3588
|
// Restore selection từ preservedSelectedMap (chỉ khi preserveSelection bật).
|
|
3494
3589
|
// Phải chạy TRƯỚC applyDefaultSelected để user-selection ưu tiên hơn default.
|
|
3495
3590
|
this.#restorePreservedSelection();
|
|
@@ -3587,37 +3682,68 @@ class SdTable extends SdBaseSecureComponent {
|
|
|
3587
3682
|
}
|
|
3588
3683
|
}
|
|
3589
3684
|
};
|
|
3685
|
+
// Children "nhìn thấy được" của một row: bình thường = toàn bộ embedded;
|
|
3686
|
+
// khi search-con = chỉ giữ child có subtree khớp từ khoá (prune).
|
|
3687
|
+
#visibleChildrenData = (data, treeOpt) => {
|
|
3688
|
+
const all = getChildrenFromData(data, treeOpt);
|
|
3689
|
+
const predicate = this.#treeSearchPredicate;
|
|
3690
|
+
return predicate ? filterMatchingChildren(all, predicate, treeOpt) : all;
|
|
3691
|
+
};
|
|
3692
|
+
// Xoá cache childItems trên toàn cây — dùng khi tắt search để dựng lại đầy đủ.
|
|
3693
|
+
#clearTreeChildCache = (rows) => {
|
|
3694
|
+
for (const row of rows) {
|
|
3695
|
+
const children = row.meta.tree?.childItems;
|
|
3696
|
+
if (children?.length) {
|
|
3697
|
+
this.#clearTreeChildCache(children);
|
|
3698
|
+
row.meta.tree.childItems = undefined;
|
|
3699
|
+
}
|
|
3700
|
+
}
|
|
3701
|
+
};
|
|
3590
3702
|
#initTreeMeta = (rows, option, level = 0, parentId) => {
|
|
3703
|
+
const searchActive = !!this.#treeSearchPredicate;
|
|
3591
3704
|
for (const row of rows) {
|
|
3592
3705
|
const saved = this.#treeExpandState.get(row.meta.id);
|
|
3706
|
+
// Khi search: hasChildren tính theo tập con đã prune; auto-expand nhánh còn con.
|
|
3707
|
+
const hasChildren = searchActive
|
|
3708
|
+
? this.#visibleChildrenData(row.data, option).length > 0
|
|
3709
|
+
: resolveHasChildren(row, option);
|
|
3593
3710
|
row.meta.tree = {
|
|
3594
3711
|
...row.meta.tree,
|
|
3595
3712
|
level,
|
|
3596
3713
|
parentId,
|
|
3597
|
-
hasChildren
|
|
3598
|
-
isExpanded: saved ?? resolveDefaultExpanded(level, option),
|
|
3714
|
+
hasChildren,
|
|
3715
|
+
isExpanded: searchActive ? hasChildren : (saved ?? resolveDefaultExpanded(level, option)),
|
|
3599
3716
|
isExpanding: false,
|
|
3600
3717
|
};
|
|
3601
3718
|
}
|
|
3602
3719
|
};
|
|
3603
3720
|
#ensureChildItemsFormatted = async (row) => {
|
|
3604
|
-
if (row.meta.tree?.childItems?.length)
|
|
3605
|
-
return;
|
|
3606
3721
|
const opt = this.tableOption();
|
|
3607
3722
|
const treeOpt = opt.tree;
|
|
3608
|
-
const
|
|
3609
|
-
|
|
3723
|
+
const searchActive = !!this.#treeSearchPredicate;
|
|
3724
|
+
// Bình thường cache childItems. Khi search, LUÔN dựng lại theo tập đã prune
|
|
3725
|
+
// vì tập này phụ thuộc từ khoá (đổi mỗi lần gõ) nên không thể cache.
|
|
3726
|
+
if (!searchActive && row.meta.tree?.childItems?.length)
|
|
3610
3727
|
return;
|
|
3728
|
+
const raw = this.#visibleChildrenData(row.data, treeOpt);
|
|
3729
|
+
if (!raw.length) {
|
|
3730
|
+
if (searchActive && row.meta.tree)
|
|
3731
|
+
row.meta.tree.childItems = [];
|
|
3732
|
+
return;
|
|
3733
|
+
}
|
|
3611
3734
|
const formatted = await this.#tableFormatService.format(raw, opt.columns, this.cacheValues, this.#cacheObjValues);
|
|
3612
3735
|
row.meta.tree.childItems = formatted;
|
|
3613
3736
|
const childLevel = (row.meta.tree.level ?? 0) + 1;
|
|
3614
3737
|
for (const child of formatted) {
|
|
3615
3738
|
const saved = this.#treeExpandState.get(child.meta.id);
|
|
3739
|
+
const childHasChildren = searchActive
|
|
3740
|
+
? this.#visibleChildrenData(child.data, treeOpt).length > 0
|
|
3741
|
+
: resolveHasChildren(child, treeOpt);
|
|
3616
3742
|
child.meta.tree = {
|
|
3617
3743
|
level: childLevel,
|
|
3618
3744
|
parentId: row.meta.id,
|
|
3619
|
-
hasChildren:
|
|
3620
|
-
isExpanded: saved ?? resolveDefaultExpanded(childLevel, treeOpt),
|
|
3745
|
+
hasChildren: childHasChildren,
|
|
3746
|
+
isExpanded: searchActive ? childHasChildren : (saved ?? resolveDefaultExpanded(childLevel, treeOpt)),
|
|
3621
3747
|
isExpanding: false,
|
|
3622
3748
|
};
|
|
3623
3749
|
}
|
|
@@ -3650,7 +3776,8 @@ class SdTable extends SdBaseSecureComponent {
|
|
|
3650
3776
|
return;
|
|
3651
3777
|
}
|
|
3652
3778
|
try {
|
|
3653
|
-
|
|
3779
|
+
// isLazyTree() narrow treeOpt về TableOptionTreeLazy → truy cập onExpandChildren an toàn.
|
|
3780
|
+
if (isLazyTree(treeOpt) && hasLazyChildren(row, treeOpt)) {
|
|
3654
3781
|
row.meta.tree.isExpanding = true;
|
|
3655
3782
|
this.#ref.markForCheck();
|
|
3656
3783
|
const key = getChildrenKey(treeOpt);
|
|
@@ -4258,8 +4385,8 @@ class SdTable extends SdBaseSecureComponent {
|
|
|
4258
4385
|
}
|
|
4259
4386
|
return req;
|
|
4260
4387
|
};
|
|
4261
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
4262
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
4388
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTable, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4389
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: SdTable, isStandalone: true, selector: "sd-table", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, option: { classPropertyName: "option", publicName: "option", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "attr.data-autoid": "autoId()", "attr.data-loading": "loading() ? \"true\" : \"false\"" } }, providers: [
|
|
4263
4390
|
DatePipe,
|
|
4264
4391
|
DecimalPipe,
|
|
4265
4392
|
CdkColumnDef,
|
|
@@ -4271,7 +4398,7 @@ class SdTable extends SdBaseSecureComponent {
|
|
|
4271
4398
|
provide: MatPaginatorIntl,
|
|
4272
4399
|
useClass: MatPaginatorIntlCro,
|
|
4273
4400
|
},
|
|
4274
|
-
], queries: [{ propertyName: "sdSubInformation", first: true, predicate: SdTableExpandDefDirective, descendants: true, isSignal: true }, { propertyName: "sdGroupDef", first: true, predicate: SdTableGroupDefDirective, descendants: true, isSignal: true }, { propertyName: "sdCellDefs", predicate: SdTableCellDefDirective, isSignal: true }, { propertyName: "sdFooterDefs", predicate: SdMaterialFooterDefDirective, isSignal: true }, { propertyName: "sdFilterDefs", predicate: SdTableFilterDefDirective, isSignal: true }, { propertyName: "sdTitleDefs", predicate: SdTableTitleDefDirective, isSignal: true }], viewQueries: [{ propertyName: "table", first: true, predicate: MatTable, descendants: true, isSignal: true }, { propertyName: "configComponent", first: true, predicate: ConfigComponent, descendants: true, isSignal: true }, { propertyName: "sdPopupExport", first: true, predicate: SdPopupExport, descendants: true, isSignal: true }, { propertyName: "scroll", first: true, predicate: SdScrollDirective, descendants: true, isSignal: true }, { propertyName: "quickAction", first: true, predicate: SdQuickAction, descendants: true, isSignal: true }, { propertyName: "externalFilter", first: true, predicate: ExternalFilterComponent, descendants: true, isSignal: true }, { propertyName: "mobileFilter", first: true, predicate: MobileFilterComponent, descendants: true, isSignal: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, isSignal: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@let _configuration = configuration();\n@let _tableOption = tableOption()!;\n@let _loading = loading();\n@let _items = items();\n@let _total = total();\n@let _isFiltered = isFiltered();\n@let _requireFiltered = requireFiltered();\n@let _export = _tableOption?.export;\n@let _exporting = exporting();\n@let _titleDef = titleDef();\n\n@if (_configuration) {\n @if (!_tableOption.filter?.disabled && !!_tableOption.filter?.externalFilters?.length && filterRegister) {\n <external-filter\n class=\"mb-16\"\n [autoId]=\"autoId()\"\n [filterRegister]=\"filterRegister\"\n [filter]=\"_tableOption.filter!\"\n [externalFilters]=\"_tableOption.filter?.externalFilters!\">\n </external-filter>\n }\n @let groupedItems = _items | sdTree: _tableOption.tree : treeRevision() | sdGroup: _tableOption : groupExpandState;\n <ng-content select=\"[sdTableTop]\"></ng-content>\n <div class=\"c-container\">\n @if (_loading) {\n <div class=\"c-loading\">\n <mat-spinner></mat-spinner>\n </div>\n }\n <div\n class=\"c-table\"\n sdScroll\n stickyShadow\n [style.max-height]=\"_tableOption.style?.maxHeight\"\n [style.min-height]=\"_tableOption.style?.minHeight\">\n <table\n mat-table\n [dataSource]=\"groupedItems\"\n [trackBy]=\"trackBy\"\n matSort\n [matSortDisabled]=\"!_tableOption.sort?.enable\"\n multiTemplateDataRows\n cdkDropList\n [cdkDropListData]=\"groupedItems\"\n [cdkDropListDisabled]=\"!_tableOption.rowReorder?.enabled\"\n [cdkDropListSortPredicate]=\"reorderSortPredicate\"\n (cdkDropListDropped)=\"onReorderDrop($event)\">\n @if (_tableOption.rowReorder?.enabled) {\n <ng-container matColumnDef=\"sdReorder\">\n <th mat-header-cell *matHeaderCellDef class=\"sd-reorder-header\" [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td mat-cell *matCellDef=\"let row\" class=\"sd-reorder-cell\">\n @if (!row.meta?.group?.items?.length) {\n <mat-icon cdkDragHandle [class.sd-reorder-disabled]=\"isReorderDisabled(row)\">\n {{ _tableOption.rowReorder?.icon || 'drag_indicator' }}\n </mat-icon>\n }\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n }\n\n @if (_tableOption.tree) {\n <ng-container matColumnDef=\"sdTreeToggle\">\n <th\n mat-header-cell\n *matHeaderCellDef\n class=\"sd-tree-toggle-cell p-0\"\n [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td mat-cell *matCellDef=\"let row\" class=\"sd-tree-toggle-cell p-0\">\n @if (row.meta?.tree) {\n <div\n class=\"sd-tree-toggle-inner\"\n [style.padding-left.px]=\"(row.meta.tree.level ?? 0) * (_tableOption.tree?.indentSize ?? 20)\">\n @if (row.meta.tree.hasChildren) {\n @if (row.meta.tree.isExpanding) {\n <div class=\"lds-ring sd-tree-spinner\">\n <div></div>\n <div></div>\n <div></div>\n <div></div>\n </div>\n } @else {\n <sd-button\n type=\"link\"\n [prefixIcon]=\"row.meta.tree.isExpanded ? 'expand_less' : 'expand_more'\"\n (click)=\"onTreeToggle(row); $event.stopPropagation()\"\n width=\"35px\">\n </sd-button>\n }\n }\n </div>\n }\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n }\n\n <ng-container matColumnDef=\"sdSubInformation\" sticky>\n <td class=\"p-0\" mat-cell *matCellDef=\"let item\" [attr.colspan]=\"_configuration.displayedColumns.length\">\n @if (sdSubInformation()?.templateRef) {\n @if (_tableOption.expand?.always) {\n <ng-container *ngTemplateOutlet=\"sdSubInformation()?.templateRef!; context: { item: item }\"> </ng-container>\n } @else {\n <div [@detailExpand]=\"item.isExpanded ? 'expanded' : 'collapsed'\">\n @if (item.isExpanded) {\n <ng-container *ngTemplateOutlet=\"sdSubInformation()?.templateRef!; context: { item: item }\"> </ng-container>\n }\n </div>\n }\n }\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"sdSubInformationAction\" stickyEnd>\n <th class=\"p-0\" mat-header-cell *matHeaderCellDef style=\"width: 1px\" [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td mat-cell *matCellDef=\"let element\">\n @if (!element.isExpanding && !_tableOption.expand?.always) {\n <sd-button\n type=\"link\"\n [prefixIcon]=\"element.isExpanded ? 'expand_less' : 'expand_more'\"\n (click)=\"onExpand(element)\"\n width=\"35px\">\n </sd-button>\n }\n @if (element.isExpanding) {\n <div class=\"lds-ring\">\n <div></div>\n <div></div>\n <div></div>\n <div></div>\n </div>\n }\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"sdSelection\" sticky>\n <th class=\"sd-selection-cell p-0\" mat-header-cell *matHeaderCellDef [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\">\n @let visibleSelectAll = _items | selectionVisibleSelectAll: _tableOption.selector | async;\n @if (visibleSelectAll) {\n <mat-checkbox\n class=\"c-selection px-8\"\n color=\"primary\"\n [ngModel]=\"isSelectAll()\"\n (ngModelChange)=\"isSelectAll.set($event)\"\n (change)=\"onSelectAll()\">\n </mat-checkbox>\n }\n </th>\n\n <td class=\"sd-selection-cell p-0\" mat-cell *matCellDef=\"let item\">\n @let visible = item | selectionVisible: _tableOption.selector;\n @if (visible) {\n @if (_tableOption.selector?.single) {\n <mat-radio-button\n class=\"c-selection px-8\"\n color=\"primary\"\n [checked]=\"item.meta.selector.isSelected\"\n (change)=\"item.meta.selector.isSelected = true; onSelect(item)\"\n [disabled]=\"selectedTableItems() | selectionDisabled: item : _tableOption.selector!\">\n </mat-radio-button>\n } @else {\n <mat-checkbox\n class=\"c-selection px-8\"\n color=\"primary\"\n [(ngModel)]=\"item.meta.selector.isSelected\"\n (change)=\"onSelect(item)\"\n [disabled]=\"selectedTableItems() | selectionDisabled: item : _tableOption.selector!\">\n </mat-checkbox>\n }\n }\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n @if (_tableOption.index?.enabled) {\n @let _pageOffset = pageOffset();\n @let _indexWidth = _tableOption.index?.width || '50px';\n <ng-container matColumnDef=\"sdIndex\" sticky>\n <th\n class=\"text-center p-0\"\n mat-header-cell\n *matHeaderCellDef\n [style.width]=\"_indexWidth\"\n [style.min-width]=\"_indexWidth\"\n [style.max-width]=\"_indexWidth\"\n [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\">\n {{ _tableOption.index?.title || '#' }}\n </th>\n <td class=\"text-center px-4\" mat-cell *matCellDef=\"let item; let i = dataIndex\" [style.min-width]=\"_indexWidth\" [style.max-width]=\"_indexWidth\">\n @if (!item?.meta?.group?.isGroupHeader) {\n @if (_tableOption.tree && item?.meta?.tree?.indexPath?.length) {\n <!-- why: tree \u2192 STT ph\u00E2n c\u1EA5p 1, 1.2, 1.2.1 (indexPath join '.'). T\u00F4 \u0111\u1EADm root (level 0). -->\n <span [class.sd-stt-root]=\"(item.meta.tree.level ?? 0) === 0\">\n {{ item.meta.tree.indexPath.join('.') }}\n </span>\n } @else {\n {{ _pageOffset + i + 1 }}\n }\n }\n </td>\n <td mat-footer-cell *matFooterCellDef [style.min-width]=\"_indexWidth\" [style.max-width]=\"_indexWidth\"></td>\n </ng-container>\n }\n <ng-container\n matColumnDef=\"sdCommand\"\n [sticky]=\"_tableOption.command?.align !== 'right'\"\n [stickyEnd]=\"_tableOption.command?.align === 'right'\">\n <th class=\"p-0\" mat-header-cell *matHeaderCellDef style=\"width: 50px\" [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td class=\"px-8\" mat-cell *matCellDef=\"let item\">\n <desktop-command\n [autoId]=\"autoId()\"\n [commands]=\"_tableOption.command?.commands || _tableOption.commands || []\"\n [item]=\"item\"\n [itemIndex]=\"groupedItems.indexOf(item)\"></desktop-command>\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n <!-- why: group header row d\u00F9ng matRowDef RI\u00CANG v\u1EDBi column list ['sdGroupHeader']\n qua predicate when:isGroupHeaderRow. Cell colspan = displayedColumns.length \u0111\u1EC3\n span TO\u00C0N B\u1ED8 width data row. Tr\u00E1nh colspan trick overflow row khi c\u00E1c TD kh\u00E1c render. -->\n <ng-container matColumnDef=\"sdGroupHeader\">\n <td\n class=\"p-0 sd-group-header-cell\"\n mat-cell\n *matCellDef=\"let item\"\n [attr.colspan]=\"sdGroupColspan()\">\n <div class=\"sd-group-row d-flex align-items-center py-8\">\n <!-- why: slot 42px kh\u1EDBp width v\u1EDBi sd-selection-cell data row \u2192 checkbox group c\u0103n TR\u1EE4C d\u1ECDc \u0111\u00FAng v\u1EDBi checkbox data. -->\n @if (_tableOption.selector?.visible && !_tableOption.selector?.single) {\n <div class=\"sd-group-selection-slot d-flex align-items-center justify-content-center\">\n <mat-checkbox\n class=\"c-selection\"\n color=\"primary\"\n [checked]=\"isGroupAllSelected(item)\"\n [indeterminate]=\"isGroupIndeterminate(item)\"\n (change)=\"onSelectGroup(item, $event.checked)\">\n </mat-checkbox>\n </div>\n } @else {\n <div class=\"sd-group-selection-slot\"></div>\n }\n @if (_tableOption.group?.collapsible) {\n <sd-button\n type=\"link\"\n [prefixIcon]=\"item.meta.group.isExpanded ? 'expand_more' : 'chevron_right'\"\n width=\"32px\"\n (click)=\"toggleGroupExpand(item)\">\n </sd-button>\n }\n @if (sdGroupDef()?.templateRef; as tpl) {\n <ng-container *ngTemplateOutlet=\"tpl; context: groupContext(item)\"></ng-container>\n } @else {\n <span class=\"T14R\">{{ item.meta.group.values | json }}</span>\n }\n </div>\n </td>\n </ng-container>\n <!-- why: filler column \u1EDF cu\u1ED1i h\u1EA5p th\u1EE5 leftover space khi t\u1ED5ng width c\u00E1c c\u1ED9t data < container \u2014 gi\u1EEF cho selection/STT/command kh\u00F4ng b\u1ECB d\u00E3n. -->\n <ng-container matColumnDef=\"sdFiller\">\n <th class=\"sd-filler-cell p-0\" mat-header-cell *matHeaderCellDef [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td class=\"sd-filler-cell p-0\" mat-cell *matCellDef=\"let item\"></td>\n <td class=\"sd-filler-cell p-0\" mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n @for (column of _configuration.firstColumns; track column.field) {\n <ng-container [matColumnDef]=\"column.field\" [sticky]=\"_configuration.fixedColumn[column.field]\">\n <th\n mat-header-cell\n *matHeaderCellDef\n class=\"px-8 py-8 c-th\"\n [sdColumnResize]=\"!!_tableOption.config?.resizable && column.type !== 'children'\"\n [minWidth]=\"column.minWidth\"\n [maxWidth]=\"column.maxWidth\"\n (resizeEnd)=\"onColumnResize(column.field, $event)\"\n [style.width]=\"column.width\"\n [style.min-width]=\"column.minWidth || column.width\"\n [style.max-width]=\"column.maxWidth\"\n [attr.rowspan]=\"_configuration.multipleHeader && column.type !== 'children' ? 2 : 1\"\n [attr.colspan]=\"column.type === 'children' ? column.children.length : 1\">\n <div>\n @if (column.type === 'children') {\n <div\n aria-hidden=\"true\"\n class=\"c-header-title\"\n [class.justify-content-end]=\"column.align === 'right'\"\n [class.text-right]=\"column.align === 'right'\">\n <column-title [column]=\"column\" [titleDef]=\"_titleDef[column.field]\"></column-title>\n </div>\n } @else {\n <div\n aria-hidden=\"true\"\n mat-sort-header\n class=\"c-header-title\"\n [class.justify-content-end]=\"column.align === 'right'\"\n [class.text-right]=\"column.align === 'right'\"\n [disabled]=\"!column.sortable\">\n <column-title [column]=\"column\" [titleDef]=\"_titleDef[column.field]\"></column-title>\n </div>\n @let hideInlineFilter =\n _tableOption.filter?.disabled ||\n _tableOption.filter?.hideInlineFilter === true ||\n (_tableOption.filter?.hideInlineFilter === 'auto' && !_isFiltered && _total! <= 10);\n @if (!hideInlineFilter) {\n <ng-container *sdDesktop>\n <column-filter\n [autoId]=\"autoId()\"\n [value]=\"columnFilter?.[column.field!]!\"\n [operator]=\"columnOperator[column.field]\"\n (operatorChange)=\"columnOperator[column.field] = $event!; onOperatorChange(column, $event)\"\n [columnFilter]=\"columnFilter!\"\n [cacheValues]=\"cacheValues\"\n [column]=\"column\"\n (filterChange)=\"onFilterChange()\"\n (filterCommit)=\"onFilterCommit()\">\n </column-filter>\n </ng-container>\n }\n }\n </div>\n </th>\n <td\n class=\"c-td px-0\"\n [class.d-none]=\"column.type === 'children'\"\n mat-cell\n *matCellDef=\"let item\"\n [sdHoverCopy]=\"(item.data && item.data[column.field]) || ''\"\n [sdHoverCopyDisabled]=\"!column.cell?.copiable\">\n @if (column.type !== 'children' && !item?.meta?.group?.isGroupHeader) {\n <desktop-cell class=\"d-block px-8\" [column]=\"column\" [item]=\"item\" [cellDef]=\"cellDef()\"> </desktop-cell>\n }\n </td>\n <td mat-footer-cell *matFooterCellDef>\n <ng-container *ngIf=\"footerDef()[column.field]\">\n <ng-container *ngTemplateOutlet=\"footerDef()[column.field].templateRef; context: { items: _items, column: column }\">\n </ng-container>\n </ng-container>\n </td>\n </ng-container>\n }\n @for (column of _configuration.secondColumns; track column.field) {\n <ng-container [matColumnDef]=\"column.field\">\n <th\n mat-header-cell\n *matHeaderCellDef\n class=\"c-th px-8\"\n [style.width]=\"column.width\"\n [style.min-width]=\"column.minWidth || column.width\"\n [style.max-width]=\"column.maxWidth\">\n <div>\n <div\n aria-hidden=\"true\"\n mat-sort-header\n class=\"c-header-title\"\n [class.justify-content-end]=\"column.align === 'right'\"\n [class.text-right]=\"column.align === 'right'\"\n [disabled]=\"!column.sortable\">\n <column-title [column]=\"column\" [titleDef]=\"_titleDef[column.field]\"></column-title>\n </div>\n @if (!_tableOption.filter?.disabled && !_tableOption.filter?.hideInlineFilter && columnOperator) {\n <ng-container *sdDesktop>\n <column-filter\n [autoId]=\"autoId()\"\n [value]=\"columnFilter?.[column.field!]!\"\n [operator]=\"columnOperator[column.field]\"\n [columnFilter]=\"columnFilter!\"\n [cacheValues]=\"cacheValues\"\n [column]=\"column\"\n (operatorChange)=\"columnOperator[column.field] = $event!; onOperatorChange(column, $event)\"\n (filterChange)=\"onFilterChange()\"\n (filterCommit)=\"onFilterCommit()\">\n </column-filter>\n </ng-container>\n }\n </div>\n </th>\n <td\n class=\"c-td px-0\"\n mat-cell\n *matCellDef=\"let item\"\n [sdHoverCopy]=\"item[column.field]\"\n [sdHoverCopyDisabled]=\"!column.cell?.copiable\">\n @if (column.type !== 'children') {\n <desktop-cell class=\"d-block px-8\" [column]=\"column\" [item]=\"item\" [cellDef]=\"cellDef()\"> </desktop-cell>\n }\n </td>\n <td mat-footer-cell *matFooterCellDef>\n <ng-container *ngIf=\"footerDef()[column.field]\">\n <ng-container *ngTemplateOutlet=\"footerDef()[column.field].templateRef; context: { items: _items, column: column }\">\n </ng-container>\n </ng-container>\n </td>\n </ng-container>\n }\n <tr class=\"c-first-header\" mat-header-row *matHeaderRowDef=\"_configuration.firstHeaders; sticky: true\"></tr>\n @if (!!_configuration.secondHeaders.length) {\n <tr class=\"c-second-header\" mat-header-row *matHeaderRowDef=\"_configuration.secondHeaders; sticky: true\"></tr>\n }\n <!-- Group header row \u2014 ch\u1EC9 1 cell sdGroupHeader colspan to\u00E0n width. -->\n <tr\n mat-row\n *matRowDef=\"let row; columns: ['sdGroupHeader']; when: isGroupHeaderRow\"\n class=\"c-group-row-tr\"></tr>\n\n <!-- Data row \u2014 d\u00F9ng displayedColumns \u0111\u1EA7y \u0111\u1EE7; when isDataRow \u0111\u1EC3 lo\u1EA1i tr\u1EEB group header. -->\n <tr\n mat-row\n cdkDrag\n [cdkDragData]=\"row\"\n [cdkDragDisabled]=\"\n !_tableOption.rowReorder?.enabled ||\n !!row.meta?.group?.items?.length ||\n (row.meta?.tree?.level ?? 0) > 0 ||\n isReorderDisabled(row)\n \"\n *matRowDef=\"let row; columns: _configuration.displayedColumns; when: isDataRow\"\n matRipple\n class=\"c-row\"\n [class.sd-tree-row]=\"!!_tableOption.tree\"\n [ngClass]=\"_tableOption.tree ? 'sd-tree-level-' + (row.meta?.tree?.level ?? 0) : null\"\n [ngStyle]=\"rowStyle(row)\"\n [class.selected]=\"row.meta.selector.isSelected\"></tr>\n\n <!-- Sub-information row \u2014 also gated b\u1EDFi isDataRow \u0111\u1EC3 KH\u00D4NG render empty expand row d\u01B0\u1EDBi group header. -->\n <tr mat-row *matRowDef=\"let row; columns: ['sdSubInformation']; when: isDataRow\" class=\"c-detail-row\"></tr>\n @if (hasFooter() && !!_configuration.displayedFooters.length) {\n <tr mat-footer-row *matFooterRowDef=\"_configuration.displayedFooters; sticky: true\"></tr>\n }\n </table>\n @if (!_loading && !_total) {\n <div class=\"c-no-data-row\">\n @if (_isFiltered) {\n @if (tableConfiguration?.images?.filterEmpty) {\n <img class=\"c-image\" [src]=\"tableConfiguration!.images!.filterEmpty\" alt=\"filter-empty\" />\n } @else {\n <img class=\"c-image sd-image-filter-empty\" alt=\"filter-empty\" />\n }\n <div class=\"T16M\">{{ 'core.component.table.no-results' | translate }}</div>\n <div class=\"T16R text-secondary\">{{ 'core.component.table.no-results-hint' | translate }}</div>\n } @else {\n @if (_requireFiltered) {\n @if (tableConfiguration?.images?.filterRequired) {\n <img class=\"c-image\" [src]=\"tableConfiguration!.images!.filterRequired\" alt=\"filter-required\" />\n } @else {\n <img class=\"c-image sd-image-filter-required\" alt=\"filter-required\" />\n }\n <div class=\"T16R text-secondary\">{{ 'core.component.table.choose-filter-hint' | translate }}</div>\n } @else {\n @if (tableConfiguration?.images?.dataEmpty) {\n <img class=\"c-image\" [src]=\"tableConfiguration!.images!.dataEmpty\" alt=\"data-empty\" />\n } @else {\n <img class=\"c-image sd-image-data-empty\" alt=\"data-empty\" />\n }\n <div class=\"T16R text-secondary\">{{ 'core.component.table.no-data' | translate }}</div>\n }\n }\n </div>\n }\n </div>\n <div class=\"c-paginator\">\n <div class=\"c-action\">\n <ng-container *sdDesktop>\n @if (_tableOption.reload?.visible) {\n <sd-button\n class=\"mr-8\"\n [title]=\"'core.component.table.reload' | translate\"\n prefixIcon=\"refresh\"\n (click)=\"reload()\"\n [disabled]=\"!_items.length\"\n type=\"link\">\n </sd-button>\n }\n </ng-container>\n @if (_export && _items.length) {\n @if (_export.type === 'custom') {\n <sd-button class=\"mr-8\" [title]=\"exportTitle()\" prefixIcon=\"get_app\" (click)=\"exportCustom()\" type=\"link\"> </sd-button>\n } @else {\n @if (_export.visible) {\n @if (_exporting) {\n <sd-button class=\"mr-8\" [loading]=\"_exporting\" [title]=\"exportTitle()\" prefixIcon=\"get_app\" type=\"link\"> </sd-button>\n } @else {\n @if (_export.visible === 'ALL' || !_export.visible) {\n <sd-button class=\"mr-8\" [title]=\"exportTitle()\" prefixIcon=\"get_app\" [matMenuTriggerFor]=\"menu\" type=\"link\"> </sd-button>\n <mat-menu #menu=\"matMenu\">\n <button mat-menu-item (click)=\"exportExcel()\" type=\"button\">\n <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\n <span> {{ 'core.component.table.export-excel' | translate }}</span>\n </button>\n <button mat-menu-item (click)=\"exportCSV()\" type=\"button\">\n <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\n <span> {{ 'core.component.table.export-csv' | translate }}</span>\n </button>\n </mat-menu>\n } @else if (_export.visible === 'EXCEL') {\n <sd-button class=\"mr-8\" [title]=\"exportTitle()\" prefixIcon=\"get_app\" (click)=\"exportExcel()\" type=\"link\"> </sd-button>\n } @else if (_export.visible === 'CSV') {\n <sd-button class=\"mr-8\" [title]=\"exportTitle()\" prefixIcon=\"get_app\" (click)=\"exportCSV()\" type=\"link\"> </sd-button>\n }\n }\n }\n }\n }\n\n <ng-container *sdDesktop>\n @if (configComponent()) {\n <sd-button\n class=\"mr-8\"\n [title]=\"'core.component.table.setup-short' | translate\"\n prefixIcon=\"settings\"\n (click)=\"configComponent()!.open()\"\n type=\"link\">\n </sd-button>\n }\n </ng-container>\n <!-- Mobile: n\u00FAt Filter m\u1EDF mobile-filter drawer (inline filter \u1EA9n tr\u00EAn mobile) -->\n <ng-container *sdMobile>\n @if (!_tableOption.filter?.disabled && mobileFilter()) {\n <sd-button\n [autoId]=\"autoId() + 'mobile-filter-open'\"\n class=\"mr-8\"\n prefixIcon=\"filter_alt\"\n (click)=\"mobileFilter()!.open()\"\n type=\"link\">\n </sd-button>\n }\n </ng-container>\n </div>\n @let hidePaginator = !_tableOption.paginate?.pageSize || _total === undefined || _total <= _tableOption.paginate?.pageSize!;\n <!-- Desktop paginator: full config (pageSize dropdown, first/last buttons) -->\n <ng-container *sdDesktop>\n <mat-paginator\n [class.d-none]=\"_tableOption.paginate?.hidden || hidePaginator\"\n [length]=\"_total\"\n [pageSize]=\"_tableOption.paginate?.pageSize\"\n [pageSizeOptions]=\"_tableOption.paginate?.pages!\"\n [showFirstLastButtons]=\"_tableOption.paginate?.showFirstLastButtons\"\n [hidePageSize]=\"_tableOption.paginate?.hidePageSize\"></mat-paginator>\n </ng-container>\n <!-- Mobile paginator: \u1EA9n pageSize dropdown + first/last buttons \u0111\u1EC3 ti\u1EBFt ki\u1EC7m kh\u00F4ng gian -->\n <ng-container *sdMobile>\n <mat-paginator\n [class.d-none]=\"_tableOption.paginate?.hidden || hidePaginator\"\n [length]=\"_total\"\n [pageSize]=\"_tableOption.paginate?.pageSize\"\n [showFirstLastButtons]=\"false\"\n hidePageSize></mat-paginator>\n </ng-container>\n <!-- \"\u0110ang hi\u1EC3n th\u1ECB...\" ch\u1EC9 desktop -->\n <ng-container *sdDesktop>\n @if (!_tableOption.paginate?.hidden && hidePaginator && _total !== undefined && _total > 0) {\n <div class=\"T14R pr-16\">\n {{ 'core.component.table.showing' | translate }} <span class=\"T14M ml-2\">1-{{ _total }}/{{ _total }}</span>\n </div>\n }\n </ng-container>\n </div>\n </div>\n <selector-action [tableOption]=\"_tableOption\" [selectedTableItems]=\"selectedTableItems()\" (clear)=\"onClearSelection(groupedItems)\" />\n @if (_tableOption.config?.visible) {\n <config [tableOption]=\"_tableOption\" />\n }\n <!-- Mobile filter drawer \u2014 ch\u1EC9 instantiate khi c\u1EA7n render tr\u00EAn mobile -->\n @if (!_tableOption.filter?.disabled && filterRegister) {\n <mobile-filter\n [autoId]=\"autoId()\"\n [filter]=\"_tableOption.filter!\"\n [externalFilters]=\"_tableOption.filter?.externalFilters!\"\n [columns]=\"_configuration.firstColumns\"\n [filterDefs]=\"sdFilterDefs()\"\n [filterRegister]=\"filterRegister\"\n [cacheValues]=\"cacheValues\">\n </mobile-filter>\n }\n}\n", styles: [":host{display:flex;flex-direction:column;overflow:auto;width:100%;height:100%}:host .c-header-title{height:40px;display:flex;align-items:center}:host .c-container{position:relative;min-height:50px;display:flex;flex-direction:column;flex:1}:host .c-container .c-table{position:relative;flex:1;display:flex;flex-direction:column}:host .c-container .c-table table{border-collapse:separate;width:100%}:host .c-container .c-table table tr.c-first-header.mat-mdc-header-row{height:40px}:host .c-container .c-table table tr.c-second-header.mat-mdc-header-row{height:40px}:host .c-container .c-table table tr.c-detail-row{height:0}:host .c-container .c-table table tr.c-row.activated{background-color:#e5ecff}:host .c-container .c-table table tr.c-row.selected{background-color:#eef2ff}:host .c-container .c-table table tr.c-row:not(.selected):not(.activated):hover{background-color:#f5f5f5}:host .c-container .c-table table tr.c-row td{border-bottom-width:0}:host .c-container .c-table table tr.c-row.c-expandable{cursor:pointer}:host .c-container .c-table table tr.c-row.c-expandable:hover{background:#f5f5f5}:host .c-container .c-table table th.mat-mdc-header-cell{background-color:#f2f3f4;border-bottom:0!important}:host .c-container .c-table table td.mat-mdc-cell,:host .c-container .c-table table td.mat-mdc-footer-cell,:host .c-container .c-table table th.mat-mdc-header-cell{border-bottom-color:#f2f2f2!important}:host .c-container .c-table .c-th{vertical-align:middle;font-weight:500;font-size:14px;line-height:20px;color:#212121}:host .c-container .c-table .c-th.sd-col-resize-host{position:relative}:host .c-container .c-table .c-th.sd-resizing{-webkit-user-select:none;user-select:none}:host .c-container .c-table .c-th .sd-col-resize-handle{position:absolute;top:0;right:0;width:6px;height:100%;cursor:col-resize;-webkit-user-select:none;user-select:none;z-index:2}:host .c-container .c-table .c-th .sd-col-resize-handle:hover{background:#00000014}:host .c-container .c-table .c-td:first{padding-left:10px}:host .c-container .c-table .c-no-data-row{flex:1;width:100%;position:sticky;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center}:host .c-container .c-table .c-no-data-row .c-image{margin-bottom:16px;width:96px}:host .c-container .c-loading{position:absolute;inset:0 0 56px;background:#00000026;z-index:2;display:flex;align-items:center;justify-content:center}:host .c-container .c-paginator{display:flex;flex-direction:row;justify-content:space-between;align-items:center;background-color:#fff}:host .c-container .c-paginator .c-action{padding:5px}:host .c-container .c-empty{text-align:center;background-color:#fff;border:none!important}:host .c-container .c-empty mat-icon{font-size:150px;margin-top:30px;margin-bottom:30px;opacity:.2;width:auto;height:auto}:host button.c-btn-add{background-color:#fff;box-shadow:0 2px 4px #2f313629}:host .lds-ring{display:inline-block;position:relative;width:40px;height:40px}:host .lds-ring div{box-sizing:border-box;display:block;position:absolute;width:32px;height:32px;margin:4px;border:4px solid #cef;border-radius:50%;animation:lds-ring 1.2s cubic-bezier(.5,0,.5,1) infinite;border-color:#cef transparent transparent transparent}:host .lds-ring div:nth-child(1){animation-delay:-.45s}:host .lds-ring div:nth-child(2){animation-delay:-.3s}:host .lds-ring div:nth-child(3){animation-delay:-.15s}@keyframes lds-ring{0%{transform:rotate(0)}to{transform:rotate(360deg)}}:host .sd-reorder-header,:host .sd-reorder-cell{width:40px;min-width:40px;padding:0 4px;box-sizing:border-box}:host .sd-reorder-cell mat-icon{cursor:grab;color:#00000061;display:flex;align-items:center}:host .sd-reorder-cell mat-icon:active{cursor:grabbing}:host .sd-reorder-cell mat-icon.sd-reorder-disabled{opacity:.3;cursor:not-allowed;pointer-events:none}:host ::ng-deep .mat-sort-header-content{display:block;text-align:left;width:100%}:host ::ng-deep .mat-select-arrow{color:#a6a6a6}:host ::ng-deep .mat-sort-header-disabled{background-image:none!important;cursor:default!important;padding-right:0!important}:host ::ng-deep .mat-sort-header-container{align-items:start!important}:host ::ng-deep .mat-sort-header-arrow{margin-top:4px!important}:host ::ng-deep .mat-sort-header-arrow{display:none!important}:host ::ng-deep .mat-sort-header{cursor:pointer}:host ::ng-deep .mat-sort-header[aria-sort]{background-repeat:no-repeat;background-position:center right 0;background-size:16px 16px;cursor:pointer;padding-right:24px}:host ::ng-deep .mat-sort-header[aria-sort=none]{background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 0 24 24' width='24px' fill='%23000000'%3E%3Cpath d='M0 0h24v24H0V0z' fill='none'/%3E%3Cpath fill='%237A7A7A' d='M12 5.83L15.17 9l1.41-1.41L12 3 7.41 7.59 8.83 9 12 5.83zm0 12.34L8.83 15l-1.41 1.41L12 21l4.59-4.59L15.17 15 12 18.17z'/%3E%3C/svg%3E\")}:host ::ng-deep .mat-sort-header[aria-sort=ascending]{background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 0 24 24' width='24px' fill='%23000000'%3E%3Cpath d='M0 0h24v24H0V0z' fill='none'/%3E%3Cpath fill='%237A7A7A' d='M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z'/%3E%3C/svg%3E\")}:host ::ng-deep .mat-sort-header[aria-sort=descending]{background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 0 24 24' width='24px' fill='%23000000'%3E%3Cpath d='M0 0h24v24H0V0z' fill='none'/%3E%3Cpath fill='%237A7A7A' d='M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z'/%3E%3C/svg%3E\")}:host ::ng-deep .c-paginator .mat-mdc-paginator .mdc-text-field--outlined .mat-mdc-form-field-infix,:host ::ng-deep .c-paginator .mat-mdc-paginator .mdc-text-field--no-label .mat-mdc-form-field-infix{padding-top:2px;padding-bottom:2px;min-height:32px}:host ::ng-deep .c-paginator .mat-mdc-paginator-range-label{margin:0 4px}:host ::ng-deep .c-paginator .mat-mdc-paginator-page-size-select mat-select{margin-top:2px!important}:host ::ng-deep .cdk-drag-preview{box-shadow:0 4px 12px #00000026;background:#fff;display:table;width:100%}:host ::ng-deep .cdk-drag-preview td{padding:0 8px;border-bottom:1px solid rgba(0,0,0,.12)}:host ::ng-deep .cdk-drag-placeholder{opacity:0}:host ::ng-deep .cdk-drop-list-dragging tr.c-row:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host ::ng-deep .sd-selection-cell{width:42px;min-width:42px;max-width:42px}:host ::ng-deep .sd-filler-cell{width:auto;min-width:0;padding:0!important;border:0}:host ::ng-deep .sd-group-header-cell{background:#f5f7fc;border-top:1px solid #e6e9f2;border-bottom:1px solid #e6e9f2}:host ::ng-deep .sd-group-row{min-height:36px}:host ::ng-deep .sd-group-selection-slot{width:42px;min-width:42px;max-width:42px}:host ::ng-deep .c-selection{transform:scale(.85);transform-origin:center}:host ::ng-deep .sd-tree-toggle-cell{width:40px;min-width:40px;max-width:100px}:host ::ng-deep .sd-tree-toggle-inner{display:flex;align-items:center;min-height:40px}:host ::ng-deep .sd-tree-spinner{transform:scale(.5);margin:0 auto}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-0{background:#fbfcfe}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-0>td{font-weight:500}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-1{background:#fff}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-2{background:#fafbfd}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-3{background:#f6f8fb}:host ::ng-deep tr.c-row.sd-tree-row:not(.sd-tree-level-0)>td.sd-tree-toggle-cell .sd-tree-toggle-inner{border-left:1px dashed #d8dde6}:host ::ng-deep .sd-stt-root{font-weight:700;color:#1f2330}\n", ":host ::ng-deep .sticky-shadow-right{overflow:visible!important}:host ::ng-deep .sticky-shadow-right:after{content:\"\";position:absolute;top:0;right:0;bottom:0;width:8px;transform:translate(100%);background:linear-gradient(to right,rgba(0,0,0,.12),transparent);pointer-events:none}:host ::ng-deep .sticky-shadow-left{overflow:visible!important}:host ::ng-deep .sticky-shadow-left:after{content:\"\";position:absolute;top:0;left:0;bottom:0;width:8px;transform:translate(-100%);background:linear-gradient(to left,rgba(0,0,0,.12),transparent);pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { 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: MatPaginatorModule }, { kind: "component", type: i4$1.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i6.MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: i6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i6.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i6.MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i7.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i7.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i9.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatRadioModule }, { kind: "component", type: i10.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i11.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i11.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i11.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "component", type: DesktopCommand, selector: "desktop-command", inputs: ["autoId", "item", "itemIndex", "commands"] }, { kind: "component", type: DesktopCellComponent, selector: "desktop-cell", inputs: ["column", "item", "cellDef"] }, { kind: "component", type: ColumnTitleComponent, selector: "column-title", inputs: ["column", "titleDef"] }, { kind: "component", type: ExternalFilterComponent, selector: "external-filter", inputs: ["autoId", "filter", "externalFilters", "filterRegister"] }, { kind: "component", type: ConfigComponent, selector: "config", inputs: ["tableOption"], outputs: ["changes"] }, { kind: "component", type: ColumnFilterComponent, selector: "column-filter", inputs: ["autoId", "column", "columnFilter", "cacheValues", "value", "operator", "isMobile"], outputs: ["operatorChange", "filterChange", "filterCommit"] }, { kind: "component", type: MobileFilterComponent, selector: "mobile-filter", inputs: ["autoId", "filter", "externalFilters", "columns", "filterDefs", "filterRegister", "cacheValues"] }, { kind: "directive", type: SdScrollDirective, selector: "[sdScroll]" }, { kind: "directive", type: SdDesktopDirective, selector: "[sdDesktop]" }, { kind: "directive", type: SdMobileDirective, selector: "[sdMobile]" }, { kind: "directive", type: SdHoverCopyDirective, selector: "[sdHoverCopy]", inputs: ["sdHoverCopy", "sdHoverCopyDisabled"] }, { kind: "component", type: SelectorActionComponent, selector: "selector-action", inputs: ["tableOption", "selectedTableItems"], outputs: ["clear"] }, { kind: "directive", type: StickyShadowDirective, selector: "[stickyShadow]" }, { kind: "directive", type: SdColumnResizeDirective, selector: "[sdColumnResize]", inputs: ["sdColumnResize", "minWidth", "maxWidth"], outputs: ["resizeEnd"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.JsonPipe, name: "json" }, { kind: "pipe", type: SdGroupPipe, name: "sdGroup" }, { kind: "pipe", type: SdTreePipe, name: "sdTree" }, { kind: "pipe", type: SdSelectionVisiblePipe, name: "selectionVisible" }, { kind: "pipe", type: SdSelectionVisibleSelectAllPipe, name: "selectionVisibleSelectAll" }, { kind: "pipe", type: SdSelectionDisabledPipe, name: "selectionDisabled" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], animations: [
|
|
4401
|
+
], queries: [{ propertyName: "sdSubInformation", first: true, predicate: SdTableExpandDefDirective, descendants: true, isSignal: true }, { propertyName: "sdGroupDef", first: true, predicate: SdTableGroupDefDirective, descendants: true, isSignal: true }, { propertyName: "sdCellDefs", predicate: SdTableCellDefDirective, isSignal: true }, { propertyName: "sdFooterDefs", predicate: SdMaterialFooterDefDirective, isSignal: true }, { propertyName: "sdFilterDefs", predicate: SdTableFilterDefDirective, isSignal: true }, { propertyName: "sdTitleDefs", predicate: SdTableTitleDefDirective, isSignal: true }], viewQueries: [{ propertyName: "table", first: true, predicate: MatTable, descendants: true, isSignal: true }, { propertyName: "configComponent", first: true, predicate: ConfigComponent, descendants: true, isSignal: true }, { propertyName: "sdPopupExport", first: true, predicate: SdPopupExport, descendants: true, isSignal: true }, { propertyName: "scroll", first: true, predicate: SdScrollDirective, descendants: true, isSignal: true }, { propertyName: "quickAction", first: true, predicate: SdQuickAction, descendants: true, isSignal: true }, { propertyName: "externalFilter", first: true, predicate: ExternalFilterComponent, descendants: true, isSignal: true }, { propertyName: "mobileFilter", first: true, predicate: MobileFilterComponent, descendants: true, isSignal: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, isSignal: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@let _configuration = configuration();\n@let _tableOption = tableOption()!;\n@let _loading = loading();\n@let _items = items();\n@let _total = total();\n@let _isFiltered = isFiltered();\n@let _requireFiltered = requireFiltered();\n@let _export = _tableOption?.export;\n@let _exporting = exporting();\n@let _titleDef = titleDef();\n@let _autoId = autoId();\n@let _exportTitle = exportTitle();\n@let _cellDef = cellDef();\n@let _footerDef = footerDef();\n@let _sdSubInformation = sdSubInformation();\n@let _configComponent = configComponent();\n@let _mobileFilter = mobileFilter();\n@let _selectedTableItems = selectedTableItems();\n<!-- why: tree kh\u00F4ng c\u00F2n c\u1ED9t ri\u00EAng \u2014 khi KH\u00D4NG c\u00F3 c\u1ED9t Index, icon expand nh\u00FAng v\u00E0o\n c\u1ED9t data \u0111\u1EA7u ti\u00EAn. \u0110\u00E2y l\u00E0 field c\u1EE7a c\u1ED9t \u0111\u00F3 (null n\u1EBFu c\u00F3 Index ho\u1EB7c kh\u00F4ng tree). -->\n@let _treeFirstField = _tableOption?.tree && !_tableOption.index?.enabled ? _configuration?.firstColumns?.[0]?.field : null;\n\n@if (_configuration) {\n @if (!_tableOption.filter?.disabled && !!_tableOption.filter?.externalFilters?.length && filterRegister) {\n <external-filter\n class=\"mb-16\"\n [autoId]=\"_autoId\"\n [filterRegister]=\"filterRegister\"\n [filter]=\"_tableOption.filter!\"\n [externalFilters]=\"_tableOption.filter?.externalFilters!\">\n </external-filter>\n }\n @let groupedItems = _items | sdTree: _tableOption.tree : treeRevision() | sdGroup: _tableOption : groupExpandState;\n\n <!-- Tree toggle d\u00F9ng chung: indent (theo c\u1EA5p) + slot chevron/spinner. Nh\u00FAng v\u00E0o\n c\u1ED9t Index ho\u1EB7c c\u1ED9t data \u0111\u1EA7u qua *ngTemplateOutlet (context: { row }). -->\n <ng-template #sdTreeToggle let-row=\"row\">\n @let _tree = row?.meta?.tree;\n @if (_tree) {\n <span class=\"sd-tree-indent\" [style.width.px]=\"(_tree.level ?? 0) * (_tableOption.tree?.indentSize ?? 20)\"></span>\n <span class=\"sd-tree-toggle-slot\">\n @if (_tree.hasChildren) {\n @if (_tree.isExpanding) {\n <span class=\"lds-ring sd-tree-spinner\">\n <div></div>\n <div></div>\n <div></div>\n <div></div>\n </span>\n } @else {\n @let _aid = _autoId;\n <button\n type=\"button\"\n class=\"sd-tree-toggle-btn\"\n [attr.data-autoid]=\"_aid ? _aid + '-tree-toggle-' + row.meta.id : null\"\n (click)=\"onTreeToggle(row); $event.stopPropagation()\">\n <mat-icon>{{ _tree.isExpanded ? 'expand_more' : 'chevron_right' }}</mat-icon>\n </button>\n }\n }\n </span>\n }\n </ng-template>\n\n <ng-content select=\"[sdTableTop]\"></ng-content>\n <div class=\"c-container\">\n @if (_loading) {\n <div class=\"c-loading\">\n <mat-spinner></mat-spinner>\n </div>\n }\n <div\n class=\"c-table\"\n sdScroll\n stickyShadow\n [style.max-height]=\"_tableOption.style?.maxHeight\"\n [style.min-height]=\"_tableOption.style?.minHeight\">\n <table\n mat-table\n [dataSource]=\"groupedItems\"\n [trackBy]=\"trackBy\"\n matSort\n [matSortDisabled]=\"!_tableOption.sort?.enable\"\n multiTemplateDataRows\n cdkDropList\n [cdkDropListData]=\"groupedItems\"\n [cdkDropListDisabled]=\"!_tableOption.rowReorder?.enabled\"\n [cdkDropListSortPredicate]=\"reorderSortPredicate\"\n (cdkDropListDropped)=\"onReorderDrop($event)\">\n @if (_tableOption.rowReorder?.enabled) {\n <ng-container matColumnDef=\"sdReorder\">\n <th mat-header-cell *matHeaderCellDef class=\"sd-reorder-header\" [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td mat-cell *matCellDef=\"let row\" class=\"sd-reorder-cell\">\n @if (!row.meta?.group?.items?.length) {\n <mat-icon cdkDragHandle [class.sd-reorder-disabled]=\"isReorderDisabled(row)\">\n {{ _tableOption.rowReorder?.icon || 'drag_indicator' }}\n </mat-icon>\n }\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n }\n\n <ng-container matColumnDef=\"sdSubInformation\" sticky>\n <td class=\"p-0\" mat-cell *matCellDef=\"let item\" [attr.colspan]=\"_configuration.displayedColumns.length\">\n @if (_sdSubInformation?.templateRef) {\n @if (_tableOption.expand?.always) {\n <ng-container *ngTemplateOutlet=\"_sdSubInformation?.templateRef!; context: { item: item }\"> </ng-container>\n } @else {\n <div [@detailExpand]=\"item.isExpanded ? 'expanded' : 'collapsed'\">\n @if (item.isExpanded) {\n <ng-container *ngTemplateOutlet=\"_sdSubInformation?.templateRef!; context: { item: item }\"> </ng-container>\n }\n </div>\n }\n }\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"sdSubInformationAction\" stickyEnd>\n <th class=\"p-0\" mat-header-cell *matHeaderCellDef style=\"width: 1px\" [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td mat-cell *matCellDef=\"let element\">\n @if (!element.isExpanding && !_tableOption.expand?.always) {\n <sd-button\n [autoId]=\"_autoId ? _autoId + '-expand-' + element.meta.id : null\"\n type=\"link\"\n [prefixIcon]=\"element.isExpanded ? 'expand_less' : 'expand_more'\"\n (click)=\"onExpand(element)\"\n width=\"35px\">\n </sd-button>\n }\n @if (element.isExpanding) {\n <div class=\"lds-ring\">\n <div></div>\n <div></div>\n <div></div>\n <div></div>\n </div>\n }\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"sdSelection\" sticky>\n <th class=\"sd-selection-cell p-0\" mat-header-cell *matHeaderCellDef [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\">\n @let visibleSelectAll = _items | selectionVisibleSelectAll: _tableOption.selector | async;\n @if (visibleSelectAll) {\n <mat-checkbox\n class=\"c-selection px-8\"\n color=\"primary\"\n [ngModel]=\"isSelectAll()\"\n (ngModelChange)=\"isSelectAll.set($event)\"\n (change)=\"onSelectAll()\">\n </mat-checkbox>\n }\n </th>\n\n <td class=\"sd-selection-cell p-0\" mat-cell *matCellDef=\"let item\">\n @let visible = item | selectionVisible: _tableOption.selector;\n @if (visible) {\n @if (_tableOption.selector?.single) {\n <mat-radio-button\n class=\"c-selection px-8\"\n color=\"primary\"\n [checked]=\"item.meta.selector.isSelected\"\n (change)=\"item.meta.selector.isSelected = true; onSelect(item)\"\n [disabled]=\"_selectedTableItems | selectionDisabled: item : _tableOption.selector!\">\n </mat-radio-button>\n } @else {\n <mat-checkbox\n class=\"c-selection px-8\"\n color=\"primary\"\n [(ngModel)]=\"item.meta.selector.isSelected\"\n (change)=\"onSelect(item)\"\n [disabled]=\"_selectedTableItems | selectionDisabled: item : _tableOption.selector!\">\n </mat-checkbox>\n }\n }\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n @if (_tableOption.index?.enabled) {\n @let _pageOffset = pageOffset();\n @let _indexWidth = _tableOption.index?.width || '50px';\n <!-- why: khi tree, c\u1ED9t Index \"\u00F4m\" th\u00EAm chevron + indent. D\u00F9ng width:1px +\n nowrap (.sd-tree-index-cell) \u0111\u1EC3 c\u1ED9t co S\u00C1T n\u1ED9i dung, kh\u00F4ng chi\u1EBFm ch\u1ED7\n th\u1EEBa; header \"#\" canh tr\u00E1i l\u00F9i v\u00E0o (.sd-tree-index-header) cho th\u1EB3ng s\u1ED1. -->\n @let _treeIndex = !!_tableOption.tree;\n <ng-container matColumnDef=\"sdIndex\" sticky>\n <th\n [class.p-0]=\"!_treeIndex\"\n [class.text-center]=\"!_treeIndex\"\n [class.sd-tree-index-cell]=\"_treeIndex\"\n [class.sd-tree-index-header]=\"_treeIndex\"\n mat-header-cell\n *matHeaderCellDef\n [style.width]=\"_treeIndex ? '1px' : _indexWidth\"\n [style.min-width]=\"_treeIndex ? null : _indexWidth\"\n [style.max-width]=\"_treeIndex ? null : _indexWidth\"\n [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\">\n {{ _tableOption.index?.title || '#' }}\n </th>\n <td\n [class.px-4]=\"!_treeIndex\"\n [class.text-center]=\"!_treeIndex\"\n [class.sd-tree-index-cell]=\"_treeIndex\"\n mat-cell\n *matCellDef=\"let item; let i = dataIndex\"\n [style.width]=\"_treeIndex ? '1px' : null\"\n [style.min-width]=\"_treeIndex ? null : _indexWidth\"\n [style.max-width]=\"_treeIndex ? null : _indexWidth\">\n @if (!item?.meta?.group?.isGroupHeader) {\n @if (_treeIndex) {\n <!-- why: tree \u2192 chevron + indent + STT ph\u00E2n c\u1EA5p (1, 1.2, 1.2.1). T\u00F4 \u0111\u1EADm root (level 0). -->\n <span class=\"sd-tree-line\">\n <ng-container *ngTemplateOutlet=\"sdTreeToggle; context: { row: item }\"></ng-container>\n @if (item?.meta?.tree?.indexPath?.length) {\n <span class=\"sd-tree-stt\" [class.sd-stt-root]=\"(item.meta.tree.level ?? 0) === 0\">\n {{ item.meta.tree.indexPath.join('.') }}\n </span>\n }\n </span>\n } @else {\n {{ _pageOffset + i + 1 }}\n }\n }\n </td>\n <td mat-footer-cell *matFooterCellDef [style.width]=\"_treeIndex ? '1px' : null\" [style.min-width]=\"_treeIndex ? null : _indexWidth\" [style.max-width]=\"_treeIndex ? null : _indexWidth\"></td>\n </ng-container>\n }\n <ng-container\n matColumnDef=\"sdCommand\"\n [sticky]=\"_tableOption.command?.align !== 'right'\"\n [stickyEnd]=\"_tableOption.command?.align === 'right'\">\n <th class=\"p-0\" mat-header-cell *matHeaderCellDef style=\"width: 50px\" [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td class=\"px-8\" mat-cell *matCellDef=\"let item\">\n <desktop-command\n [autoId]=\"_autoId\"\n [commands]=\"_tableOption.command?.commands || _tableOption.commands || []\"\n [item]=\"item\"\n [itemIndex]=\"groupedItems.indexOf(item)\"></desktop-command>\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n <!-- why: group header row d\u00F9ng matRowDef RI\u00CANG v\u1EDBi column list ['sdGroupHeader']\n qua predicate when:isGroupHeaderRow. Cell colspan = displayedColumns.length \u0111\u1EC3\n span TO\u00C0N B\u1ED8 width data row. Tr\u00E1nh colspan trick overflow row khi c\u00E1c TD kh\u00E1c render. -->\n <ng-container matColumnDef=\"sdGroupHeader\">\n <td\n class=\"p-0 sd-group-header-cell\"\n mat-cell\n *matCellDef=\"let item\"\n [attr.colspan]=\"sdGroupColspan()\">\n <div class=\"sd-group-row d-flex align-items-center py-8\">\n <!-- why: slot 42px kh\u1EDBp width v\u1EDBi sd-selection-cell data row \u2192 checkbox group c\u0103n TR\u1EE4C d\u1ECDc \u0111\u00FAng v\u1EDBi checkbox data. -->\n @if (_tableOption.selector?.visible && !_tableOption.selector?.single) {\n <div class=\"sd-group-selection-slot d-flex align-items-center justify-content-center\">\n <mat-checkbox\n class=\"c-selection\"\n color=\"primary\"\n [checked]=\"isGroupAllSelected(item)\"\n [indeterminate]=\"isGroupIndeterminate(item)\"\n (change)=\"onSelectGroup(item, $event.checked)\">\n </mat-checkbox>\n </div>\n } @else {\n <div class=\"sd-group-selection-slot\"></div>\n }\n @if (_tableOption.group?.collapsible) {\n <sd-button\n [autoId]=\"_autoId ? _autoId + '-group-toggle-' + (item.meta.group?.key || item.meta.id) : null\"\n type=\"link\"\n [prefixIcon]=\"item.meta.group.isExpanded ? 'expand_more' : 'chevron_right'\"\n width=\"32px\"\n (click)=\"toggleGroupExpand(item)\">\n </sd-button>\n }\n @if (sdGroupDef()?.templateRef; as tpl) {\n <ng-container *ngTemplateOutlet=\"tpl; context: groupContext(item)\"></ng-container>\n } @else {\n <span class=\"T14R\">{{ item.meta.group.values | json }}</span>\n }\n </div>\n </td>\n </ng-container>\n <!-- why: filler column \u1EDF cu\u1ED1i h\u1EA5p th\u1EE5 leftover space khi t\u1ED5ng width c\u00E1c c\u1ED9t data < container \u2014 gi\u1EEF cho selection/STT/command kh\u00F4ng b\u1ECB d\u00E3n. -->\n <ng-container matColumnDef=\"sdFiller\">\n <th class=\"sd-filler-cell p-0\" mat-header-cell *matHeaderCellDef [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td class=\"sd-filler-cell p-0\" mat-cell *matCellDef=\"let item\"></td>\n <td class=\"sd-filler-cell p-0\" mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n @for (column of _configuration.firstColumns; track column.field) {\n <ng-container [matColumnDef]=\"column.field\" [sticky]=\"_configuration.fixedColumn[column.field]\">\n <th\n mat-header-cell\n *matHeaderCellDef\n class=\"px-8 py-8 c-th\"\n [sdColumnResize]=\"!!_tableOption.config?.resizable && column.type !== 'children'\"\n [minWidth]=\"column.minWidth\"\n [maxWidth]=\"column.maxWidth\"\n (resizeEnd)=\"onColumnResize(column.field, $event)\"\n [style.width]=\"column.width\"\n [style.min-width]=\"column.minWidth || column.width\"\n [style.max-width]=\"column.maxWidth\"\n [attr.rowspan]=\"_configuration.multipleHeader && column.type !== 'children' ? 2 : 1\"\n [attr.colspan]=\"column.type === 'children' ? column.children.length : 1\">\n <div>\n @if (column.type === 'children') {\n <div\n aria-hidden=\"true\"\n class=\"c-header-title\"\n [class.justify-content-end]=\"column.align === 'right'\"\n [class.text-right]=\"column.align === 'right'\">\n <column-title [column]=\"column\" [titleDef]=\"_titleDef[column.field]\"></column-title>\n </div>\n } @else {\n <div\n aria-hidden=\"true\"\n mat-sort-header\n class=\"c-header-title\"\n [class.justify-content-end]=\"column.align === 'right'\"\n [class.text-right]=\"column.align === 'right'\"\n [disabled]=\"!column.sortable\">\n <column-title [column]=\"column\" [titleDef]=\"_titleDef[column.field]\"></column-title>\n </div>\n @let hideInlineFilter =\n _tableOption.filter?.disabled ||\n _tableOption.filter?.hideInlineFilter === true ||\n (_tableOption.filter?.hideInlineFilter === 'auto' && !_isFiltered && _total! <= 10);\n @if (!hideInlineFilter) {\n <ng-container *sdDesktop>\n <column-filter\n [autoId]=\"_autoId\"\n [value]=\"columnFilter?.[column.field!]!\"\n [operator]=\"columnOperator[column.field]\"\n (operatorChange)=\"columnOperator[column.field] = $event!; onOperatorChange(column, $event)\"\n [columnFilter]=\"columnFilter!\"\n [cacheValues]=\"cacheValues\"\n [column]=\"column\"\n (filterChange)=\"onFilterChange()\"\n (filterCommit)=\"onFilterCommit()\">\n </column-filter>\n </ng-container>\n }\n }\n </div>\n </th>\n <td\n class=\"c-td px-0\"\n [class.d-none]=\"column.type === 'children'\"\n mat-cell\n *matCellDef=\"let item\"\n [sdHoverCopy]=\"(item.data && item.data[column.field]) || ''\"\n [sdHoverCopyDisabled]=\"!column.cell?.copiable\">\n @if (column.type !== 'children' && !item?.meta?.group?.isGroupHeader) {\n @if (_treeFirstField && column.field === _treeFirstField) {\n <!-- why: kh\u00F4ng c\u00F3 c\u1ED9t Index \u2192 chevron + indent nh\u00FAng v\u00E0o c\u1ED9t data \u0111\u1EA7u (nh\u01B0 file explorer). -->\n <span class=\"sd-tree-line px-8\">\n <ng-container *ngTemplateOutlet=\"sdTreeToggle; context: { row: item }\"></ng-container>\n <desktop-cell class=\"d-block\" [column]=\"column\" [item]=\"item\" [cellDef]=\"_cellDef\"></desktop-cell>\n </span>\n } @else {\n <desktop-cell class=\"d-block px-8\" [column]=\"column\" [item]=\"item\" [cellDef]=\"_cellDef\"> </desktop-cell>\n }\n }\n </td>\n <td mat-footer-cell *matFooterCellDef>\n <ng-container *ngIf=\"_footerDef[column.field]\">\n <ng-container *ngTemplateOutlet=\"_footerDef[column.field].templateRef; context: { items: _items, column: column }\">\n </ng-container>\n </ng-container>\n </td>\n </ng-container>\n }\n @for (column of _configuration.secondColumns; track column.field) {\n <ng-container [matColumnDef]=\"column.field\">\n <th\n mat-header-cell\n *matHeaderCellDef\n class=\"c-th px-8\"\n [style.width]=\"column.width\"\n [style.min-width]=\"column.minWidth || column.width\"\n [style.max-width]=\"column.maxWidth\">\n <div>\n <div\n aria-hidden=\"true\"\n mat-sort-header\n class=\"c-header-title\"\n [class.justify-content-end]=\"column.align === 'right'\"\n [class.text-right]=\"column.align === 'right'\"\n [disabled]=\"!column.sortable\">\n <column-title [column]=\"column\" [titleDef]=\"_titleDef[column.field]\"></column-title>\n </div>\n @if (!_tableOption.filter?.disabled && !_tableOption.filter?.hideInlineFilter && columnOperator) {\n <ng-container *sdDesktop>\n <column-filter\n [autoId]=\"_autoId\"\n [value]=\"columnFilter?.[column.field!]!\"\n [operator]=\"columnOperator[column.field]\"\n [columnFilter]=\"columnFilter!\"\n [cacheValues]=\"cacheValues\"\n [column]=\"column\"\n (operatorChange)=\"columnOperator[column.field] = $event!; onOperatorChange(column, $event)\"\n (filterChange)=\"onFilterChange()\"\n (filterCommit)=\"onFilterCommit()\">\n </column-filter>\n </ng-container>\n }\n </div>\n </th>\n <td\n class=\"c-td px-0\"\n mat-cell\n *matCellDef=\"let item\"\n [sdHoverCopy]=\"item[column.field]\"\n [sdHoverCopyDisabled]=\"!column.cell?.copiable\">\n @if (column.type !== 'children') {\n <desktop-cell class=\"d-block px-8\" [column]=\"column\" [item]=\"item\" [cellDef]=\"_cellDef\"> </desktop-cell>\n }\n </td>\n <td mat-footer-cell *matFooterCellDef>\n <ng-container *ngIf=\"_footerDef[column.field]\">\n <ng-container *ngTemplateOutlet=\"_footerDef[column.field].templateRef; context: { items: _items, column: column }\">\n </ng-container>\n </ng-container>\n </td>\n </ng-container>\n }\n <tr class=\"c-first-header\" mat-header-row *matHeaderRowDef=\"_configuration.firstHeaders; sticky: true\"></tr>\n @if (!!_configuration.secondHeaders.length) {\n <tr class=\"c-second-header\" mat-header-row *matHeaderRowDef=\"_configuration.secondHeaders; sticky: true\"></tr>\n }\n <!-- Group header row \u2014 ch\u1EC9 1 cell sdGroupHeader colspan to\u00E0n width. -->\n <tr\n mat-row\n *matRowDef=\"let row; columns: ['sdGroupHeader']; when: isGroupHeaderRow\"\n class=\"c-group-row-tr\"></tr>\n\n <!-- Data row \u2014 d\u00F9ng displayedColumns \u0111\u1EA7y \u0111\u1EE7; when isDataRow \u0111\u1EC3 lo\u1EA1i tr\u1EEB group header. -->\n <tr\n mat-row\n cdkDrag\n [cdkDragData]=\"row\"\n [cdkDragDisabled]=\"\n !_tableOption.rowReorder?.enabled ||\n !!row.meta?.group?.items?.length ||\n (row.meta?.tree?.level ?? 0) > 0 ||\n isReorderDisabled(row)\n \"\n *matRowDef=\"let row; columns: _configuration.displayedColumns; when: isDataRow\"\n matRipple\n class=\"c-row\"\n [class.sd-tree-row]=\"!!_tableOption.tree\"\n [ngClass]=\"_tableOption.tree ? 'sd-tree-level-' + (row.meta?.tree?.level ?? 0) : null\"\n [ngStyle]=\"rowStyle(row)\"\n [class.selected]=\"row.meta.selector.isSelected\"></tr>\n\n <!-- Sub-information row \u2014 also gated b\u1EDFi isDataRow \u0111\u1EC3 KH\u00D4NG render empty expand row d\u01B0\u1EDBi group header. -->\n <tr mat-row *matRowDef=\"let row; columns: ['sdSubInformation']; when: isDataRow\" class=\"c-detail-row\"></tr>\n @if (hasFooter() && !!_configuration.displayedFooters.length) {\n <tr mat-footer-row *matFooterRowDef=\"_configuration.displayedFooters; sticky: true\"></tr>\n }\n </table>\n @if (!_loading && !_total) {\n <div class=\"c-no-data-row\">\n @if (_isFiltered) {\n @if (tableConfiguration?.images?.filterEmpty) {\n <img class=\"c-image\" [src]=\"tableConfiguration!.images!.filterEmpty\" alt=\"filter-empty\" />\n } @else {\n <img class=\"c-image sd-image-filter-empty\" alt=\"filter-empty\" />\n }\n <div class=\"T16M\">{{ 'core.component.table.no-results' | translate }}</div>\n <div class=\"T16R text-secondary\">{{ 'core.component.table.no-results-hint' | translate }}</div>\n } @else {\n @if (_requireFiltered) {\n @if (tableConfiguration?.images?.filterRequired) {\n <img class=\"c-image\" [src]=\"tableConfiguration!.images!.filterRequired\" alt=\"filter-required\" />\n } @else {\n <img class=\"c-image sd-image-filter-required\" alt=\"filter-required\" />\n }\n <div class=\"T16R text-secondary\">{{ 'core.component.table.choose-filter-hint' | translate }}</div>\n } @else {\n @if (tableConfiguration?.images?.dataEmpty) {\n <img class=\"c-image\" [src]=\"tableConfiguration!.images!.dataEmpty\" alt=\"data-empty\" />\n } @else {\n <img class=\"c-image sd-image-data-empty\" alt=\"data-empty\" />\n }\n <div class=\"T16R text-secondary\">{{ 'core.component.table.no-data' | translate }}</div>\n }\n }\n </div>\n }\n </div>\n <div class=\"c-paginator\">\n <div class=\"c-action\">\n <ng-container *sdDesktop>\n @if (_tableOption.reload?.visible) {\n <sd-button\n [autoId]=\"_autoId ? _autoId + '-reload' : null\"\n class=\"mr-8\"\n [title]=\"'core.component.table.reload' | translate\"\n prefixIcon=\"refresh\"\n (click)=\"reload()\"\n [disabled]=\"!_items.length\"\n type=\"link\">\n </sd-button>\n }\n </ng-container>\n @if (_export && _items.length) {\n @if (_export.type === 'custom') {\n <sd-button [autoId]=\"_autoId ? _autoId + '-export' : null\" class=\"mr-8\" [title]=\"_exportTitle\" prefixIcon=\"get_app\" (click)=\"exportCustom()\" type=\"link\"> </sd-button>\n } @else {\n @if (_export.visible) {\n @if (_exporting) {\n <sd-button [autoId]=\"_autoId ? _autoId + '-export' : null\" class=\"mr-8\" [loading]=\"_exporting\" [title]=\"_exportTitle\" prefixIcon=\"get_app\" type=\"link\"> </sd-button>\n } @else {\n @if (_export.visible === 'ALL' || !_export.visible) {\n <sd-button [autoId]=\"_autoId ? _autoId + '-export' : null\" class=\"mr-8\" [title]=\"_exportTitle\" prefixIcon=\"get_app\" [matMenuTriggerFor]=\"menu\" type=\"link\"> </sd-button>\n <mat-menu #menu=\"matMenu\">\n <button mat-menu-item [attr.data-autoid]=\"_autoId ? _autoId + '-export-excel' : null\" (click)=\"exportExcel()\" type=\"button\">\n <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\n <span> {{ 'core.component.table.export-excel' | translate }}</span>\n </button>\n <button mat-menu-item [attr.data-autoid]=\"_autoId ? _autoId + '-export-csv' : null\" (click)=\"exportCSV()\" type=\"button\">\n <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\n <span> {{ 'core.component.table.export-csv' | translate }}</span>\n </button>\n </mat-menu>\n } @else if (_export.visible === 'EXCEL') {\n <sd-button [autoId]=\"_autoId ? _autoId + '-export-excel' : null\" class=\"mr-8\" [title]=\"_exportTitle\" prefixIcon=\"get_app\" (click)=\"exportExcel()\" type=\"link\"> </sd-button>\n } @else if (_export.visible === 'CSV') {\n <sd-button [autoId]=\"_autoId ? _autoId + '-export-csv' : null\" class=\"mr-8\" [title]=\"_exportTitle\" prefixIcon=\"get_app\" (click)=\"exportCSV()\" type=\"link\"> </sd-button>\n }\n }\n }\n }\n }\n\n <ng-container *sdDesktop>\n @if (_configComponent) {\n <sd-button\n [autoId]=\"_autoId ? _autoId + '-config' : null\"\n class=\"mr-8\"\n [title]=\"'core.component.table.setup-short' | translate\"\n prefixIcon=\"settings\"\n (click)=\"_configComponent.open()\"\n type=\"link\">\n </sd-button>\n }\n </ng-container>\n <!-- Mobile: n\u00FAt Filter m\u1EDF mobile-filter drawer (inline filter \u1EA9n tr\u00EAn mobile) -->\n <ng-container *sdMobile>\n @if (!_tableOption.filter?.disabled && _mobileFilter) {\n <sd-button\n [autoId]=\"_autoId ? _autoId + '-mobile-filter-open' : null\"\n class=\"mr-8\"\n prefixIcon=\"filter_alt\"\n (click)=\"_mobileFilter.open()\"\n type=\"link\">\n </sd-button>\n }\n </ng-container>\n </div>\n @let hidePaginator = !_tableOption.paginate?.pageSize || _total === undefined || _total <= _tableOption.paginate?.pageSize!;\n <!-- Desktop paginator: full config (pageSize dropdown, first/last buttons) -->\n <ng-container *sdDesktop>\n <mat-paginator\n [class.d-none]=\"_tableOption.paginate?.hidden || hidePaginator\"\n [length]=\"_total\"\n [pageSize]=\"_tableOption.paginate?.pageSize\"\n [pageSizeOptions]=\"_tableOption.paginate?.pages!\"\n [showFirstLastButtons]=\"_tableOption.paginate?.showFirstLastButtons\"\n [hidePageSize]=\"_tableOption.paginate?.hidePageSize\"></mat-paginator>\n </ng-container>\n <!-- Mobile paginator: \u1EA9n pageSize dropdown + first/last buttons \u0111\u1EC3 ti\u1EBFt ki\u1EC7m kh\u00F4ng gian -->\n <ng-container *sdMobile>\n <mat-paginator\n [class.d-none]=\"_tableOption.paginate?.hidden || hidePaginator\"\n [length]=\"_total\"\n [pageSize]=\"_tableOption.paginate?.pageSize\"\n [showFirstLastButtons]=\"false\"\n hidePageSize></mat-paginator>\n </ng-container>\n <!-- \"\u0110ang hi\u1EC3n th\u1ECB...\" ch\u1EC9 desktop -->\n <ng-container *sdDesktop>\n @if (!_tableOption.paginate?.hidden && hidePaginator && _total !== undefined && _total > 0) {\n <div class=\"T14R pr-16\">\n {{ 'core.component.table.showing' | translate }} <span class=\"T14M ml-2\">1-{{ _total }}/{{ _total }}</span>\n </div>\n }\n </ng-container>\n </div>\n </div>\n <selector-action [autoId]=\"_autoId\" [tableOption]=\"_tableOption\" [selectedTableItems]=\"_selectedTableItems\" (clear)=\"onClearSelection(groupedItems)\" />\n @if (_tableOption.config?.visible) {\n <config [autoId]=\"_autoId\" [tableOption]=\"_tableOption\" />\n }\n <!-- Mobile filter drawer \u2014 ch\u1EC9 instantiate khi c\u1EA7n render tr\u00EAn mobile -->\n @if (!_tableOption.filter?.disabled && filterRegister) {\n <mobile-filter\n [autoId]=\"_autoId\"\n [filter]=\"_tableOption.filter!\"\n [externalFilters]=\"_tableOption.filter?.externalFilters!\"\n [columns]=\"_configuration.firstColumns\"\n [filterDefs]=\"sdFilterDefs()\"\n [filterRegister]=\"filterRegister\"\n [cacheValues]=\"cacheValues\">\n </mobile-filter>\n }\n}\n", styles: [":host{display:flex;flex-direction:column;overflow:auto;width:100%;height:100%}:host .c-header-title{height:40px;display:flex;align-items:center}:host .c-container{position:relative;min-height:50px;display:flex;flex-direction:column;flex:1}:host .c-container .c-table{position:relative;flex:1;display:flex;flex-direction:column}:host .c-container .c-table table{border-collapse:separate;width:100%}:host .c-container .c-table table tr.c-first-header.mat-mdc-header-row{height:40px}:host .c-container .c-table table tr.c-second-header.mat-mdc-header-row{height:40px}:host .c-container .c-table table tr.c-detail-row{height:0}:host .c-container .c-table table tr.c-row.activated{background-color:#e5ecff}:host .c-container .c-table table tr.c-row.selected{background-color:#eef2ff}:host .c-container .c-table table tr.c-row:not(.selected):not(.activated):hover{background-color:#f5f5f5}:host .c-container .c-table table tr.c-row td{border-bottom-width:0}:host .c-container .c-table table tr.c-row.c-expandable{cursor:pointer}:host .c-container .c-table table tr.c-row.c-expandable:hover{background:#f5f5f5}:host .c-container .c-table table th.mat-mdc-header-cell{background-color:#f2f3f4;border-bottom:0!important}:host .c-container .c-table table td.mat-mdc-cell,:host .c-container .c-table table td.mat-mdc-footer-cell,:host .c-container .c-table table th.mat-mdc-header-cell{border-bottom-color:#f2f2f2!important}:host .c-container .c-table .c-th{vertical-align:middle;font-weight:500;font-size:14px;line-height:20px;color:#212121}:host .c-container .c-table .c-th.sd-col-resize-host{position:relative}:host .c-container .c-table .c-th.sd-resizing{-webkit-user-select:none;user-select:none}:host .c-container .c-table .c-th .sd-col-resize-handle{position:absolute;top:0;right:0;width:6px;height:100%;cursor:col-resize;-webkit-user-select:none;user-select:none;z-index:2}:host .c-container .c-table .c-th .sd-col-resize-handle:hover{background:#00000014}:host .c-container .c-table .c-td:first{padding-left:10px}:host .c-container .c-table .c-no-data-row{flex:1;width:100%;position:sticky;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center}:host .c-container .c-table .c-no-data-row .c-image{margin-bottom:16px;width:96px}:host .c-container .c-loading{position:absolute;inset:0 0 56px;background:#00000026;z-index:2;display:flex;align-items:center;justify-content:center}:host .c-container .c-paginator{display:flex;flex-direction:row;justify-content:space-between;align-items:center;background-color:#fff}:host .c-container .c-paginator .c-action{padding:5px}:host .c-container .c-empty{text-align:center;background-color:#fff;border:none!important}:host .c-container .c-empty mat-icon{font-size:150px;margin-top:30px;margin-bottom:30px;opacity:.2;width:auto;height:auto}:host button.c-btn-add{background-color:#fff;box-shadow:0 2px 4px #2f313629}:host .lds-ring{display:inline-block;position:relative;width:40px;height:40px}:host .lds-ring div{box-sizing:border-box;display:block;position:absolute;width:32px;height:32px;margin:4px;border:4px solid #cef;border-radius:50%;animation:lds-ring 1.2s cubic-bezier(.5,0,.5,1) infinite;border-color:#cef transparent transparent transparent}:host .lds-ring div:nth-child(1){animation-delay:-.45s}:host .lds-ring div:nth-child(2){animation-delay:-.3s}:host .lds-ring div:nth-child(3){animation-delay:-.15s}@keyframes lds-ring{0%{transform:rotate(0)}to{transform:rotate(360deg)}}:host .sd-reorder-header,:host .sd-reorder-cell{width:40px;min-width:40px;padding:0 4px;box-sizing:border-box}:host .sd-reorder-cell mat-icon{cursor:grab;color:#00000061;display:flex;align-items:center}:host .sd-reorder-cell mat-icon:active{cursor:grabbing}:host .sd-reorder-cell mat-icon.sd-reorder-disabled{opacity:.3;cursor:not-allowed;pointer-events:none}:host ::ng-deep .mat-sort-header-content{display:block;text-align:left;width:100%}:host ::ng-deep .mat-select-arrow{color:#a6a6a6}:host ::ng-deep .mat-sort-header-disabled{background-image:none!important;cursor:default!important;padding-right:0!important}:host ::ng-deep .mat-sort-header-container{align-items:start!important}:host ::ng-deep .mat-sort-header-arrow{margin-top:4px!important}:host ::ng-deep .mat-sort-header-arrow{display:none!important}:host ::ng-deep .mat-sort-header{cursor:pointer}:host ::ng-deep .mat-sort-header[aria-sort]{background-repeat:no-repeat;background-position:center right 0;background-size:16px 16px;cursor:pointer;padding-right:24px}:host ::ng-deep .mat-sort-header[aria-sort=none]{background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 0 24 24' width='24px' fill='%23000000'%3E%3Cpath d='M0 0h24v24H0V0z' fill='none'/%3E%3Cpath fill='%237A7A7A' d='M12 5.83L15.17 9l1.41-1.41L12 3 7.41 7.59 8.83 9 12 5.83zm0 12.34L8.83 15l-1.41 1.41L12 21l4.59-4.59L15.17 15 12 18.17z'/%3E%3C/svg%3E\")}:host ::ng-deep .mat-sort-header[aria-sort=ascending]{background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 0 24 24' width='24px' fill='%23000000'%3E%3Cpath d='M0 0h24v24H0V0z' fill='none'/%3E%3Cpath fill='%237A7A7A' d='M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z'/%3E%3C/svg%3E\")}:host ::ng-deep .mat-sort-header[aria-sort=descending]{background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 0 24 24' width='24px' fill='%23000000'%3E%3Cpath d='M0 0h24v24H0V0z' fill='none'/%3E%3Cpath fill='%237A7A7A' d='M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z'/%3E%3C/svg%3E\")}:host ::ng-deep .c-paginator .mat-mdc-paginator .mdc-text-field--outlined .mat-mdc-form-field-infix,:host ::ng-deep .c-paginator .mat-mdc-paginator .mdc-text-field--no-label .mat-mdc-form-field-infix{padding-top:2px;padding-bottom:2px;min-height:32px}:host ::ng-deep .c-paginator .mat-mdc-paginator-range-label{margin:0 4px}:host ::ng-deep .c-paginator .mat-mdc-paginator-page-size-select mat-select{margin-top:2px!important}:host ::ng-deep .cdk-drag-preview{box-shadow:0 4px 12px #00000026;background:#fff;display:table;width:100%}:host ::ng-deep .cdk-drag-preview td{padding:0 8px;border-bottom:1px solid rgba(0,0,0,.12)}:host ::ng-deep .cdk-drag-placeholder{opacity:0}:host ::ng-deep .cdk-drop-list-dragging tr.c-row:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host ::ng-deep .sd-selection-cell{width:42px;min-width:42px;max-width:42px}:host ::ng-deep .sd-filler-cell{width:auto;min-width:0;padding:0!important;border:0}:host ::ng-deep .sd-group-header-cell{background:#f5f7fc;border-top:1px solid #e6e9f2;border-bottom:1px solid #e6e9f2}:host ::ng-deep .sd-group-row{min-height:36px}:host ::ng-deep .sd-group-selection-slot{width:42px;min-width:42px;max-width:42px}:host ::ng-deep .c-selection{transform:scale(.85);transform-origin:center}:host ::ng-deep .sd-tree-line{display:inline-flex;align-items:center;min-height:32px}:host ::ng-deep .sd-tree-indent{flex:0 0 auto}:host ::ng-deep .sd-tree-toggle-slot{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px}:host ::ng-deep .sd-tree-toggle-btn{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;border:0;background:transparent;border-radius:50%;cursor:pointer;color:var(--sd-text-secondary, #5b6472);transition:background-color .15s ease}:host ::ng-deep .sd-tree-toggle-btn mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}:host ::ng-deep .sd-tree-toggle-btn:hover{background-color:#0f172a14}:host ::ng-deep .sd-tree-spinner{transform:scale(.45)}:host ::ng-deep .sd-tree-stt{margin-left:2px;white-space:nowrap}:host ::ng-deep .sd-tree-index-cell{text-align:left!important;white-space:nowrap;padding-left:8px;padding-right:8px}:host ::ng-deep .sd-tree-index-header{padding-left:32px}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-0{background:#fbfcfe}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-0>td{font-weight:500}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-1{background:#fff}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-2{background:#fafbfd}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-3{background:#f6f8fb}:host ::ng-deep .sd-stt-root{font-weight:700;color:#1f2330}\n", ":host ::ng-deep .sticky-shadow-right{overflow:visible!important}:host ::ng-deep .sticky-shadow-right:after{content:\"\";position:absolute;top:0;right:0;bottom:0;width:8px;transform:translate(100%);background:linear-gradient(to right,rgba(0,0,0,.12),transparent);pointer-events:none}:host ::ng-deep .sticky-shadow-left{overflow:visible!important}:host ::ng-deep .sticky-shadow-left:after{content:\"\";position:absolute;top:0;left:0;bottom:0;width:8px;transform:translate(-100%);background:linear-gradient(to left,rgba(0,0,0,.12),transparent);pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { 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: MatPaginatorModule }, { kind: "component", type: i4$1.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i6.MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: i6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i6.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i6.MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i7.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i7.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i9.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatRadioModule }, { kind: "component", type: i10.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i11.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i11.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i11.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "component", type: DesktopCommand, selector: "desktop-command", inputs: ["autoId", "item", "itemIndex", "commands"] }, { kind: "component", type: DesktopCellComponent, selector: "desktop-cell", inputs: ["column", "item", "cellDef"] }, { kind: "component", type: ColumnTitleComponent, selector: "column-title", inputs: ["column", "titleDef"] }, { kind: "component", type: ExternalFilterComponent, selector: "external-filter", inputs: ["autoId", "filter", "externalFilters", "filterRegister"] }, { kind: "component", type: ConfigComponent, selector: "config", inputs: ["autoId", "tableOption"], outputs: ["changes"] }, { kind: "component", type: ColumnFilterComponent, selector: "column-filter", inputs: ["autoId", "column", "columnFilter", "cacheValues", "value", "operator", "isMobile"], outputs: ["operatorChange", "filterChange", "filterCommit"] }, { kind: "component", type: MobileFilterComponent, selector: "mobile-filter", inputs: ["autoId", "filter", "externalFilters", "columns", "filterDefs", "filterRegister", "cacheValues"] }, { kind: "directive", type: SdScrollDirective, selector: "[sdScroll]" }, { kind: "directive", type: SdDesktopDirective, selector: "[sdDesktop]" }, { kind: "directive", type: SdMobileDirective, selector: "[sdMobile]" }, { kind: "directive", type: SdHoverCopyDirective, selector: "[sdHoverCopy]", inputs: ["sdHoverCopy", "sdHoverCopyDisabled"] }, { kind: "component", type: SelectorActionComponent, selector: "selector-action", inputs: ["autoId", "tableOption", "selectedTableItems"], outputs: ["clear"] }, { kind: "directive", type: StickyShadowDirective, selector: "[stickyShadow]" }, { kind: "directive", type: SdColumnResizeDirective, selector: "[sdColumnResize]", inputs: ["sdColumnResize", "minWidth", "maxWidth"], outputs: ["resizeEnd"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.JsonPipe, name: "json" }, { kind: "pipe", type: SdGroupPipe, name: "sdGroup" }, { kind: "pipe", type: SdTreePipe, name: "sdTree" }, { kind: "pipe", type: SdSelectionVisiblePipe, name: "selectionVisible" }, { kind: "pipe", type: SdSelectionVisibleSelectAllPipe, name: "selectionVisibleSelectAll" }, { kind: "pipe", type: SdSelectionDisabledPipe, name: "selectionDisabled" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], animations: [
|
|
4275
4402
|
trigger('detailExpand', [
|
|
4276
4403
|
state('collapsed', style({ height: '0', minHeight: '0', visibility: 'hidden' })),
|
|
4277
4404
|
state('expanded', style({ height: '*', visibility: 'visible' })),
|
|
@@ -4279,7 +4406,7 @@ class SdTable extends SdBaseSecureComponent {
|
|
|
4279
4406
|
]),
|
|
4280
4407
|
], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4281
4408
|
}
|
|
4282
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
4409
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdTable, decorators: [{
|
|
4283
4410
|
type: Component,
|
|
4284
4411
|
args: [{ selector: 'sd-table', changeDetection: ChangeDetectionStrategy.OnPush, animations: [
|
|
4285
4412
|
trigger('detailExpand', [
|
|
@@ -4336,7 +4463,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImpo
|
|
|
4336
4463
|
StickyShadowDirective,
|
|
4337
4464
|
SdColumnResizeDirective,
|
|
4338
4465
|
TranslatePipe,
|
|
4339
|
-
], template: "@let _configuration = configuration();\n@let _tableOption = tableOption()!;\n@let _loading = loading();\n@let _items = items();\n@let _total = total();\n@let _isFiltered = isFiltered();\n@let _requireFiltered = requireFiltered();\n@let _export = _tableOption?.export;\n@let _exporting = exporting();\n@let _titleDef = titleDef();\n\n@if (_configuration) {\n @if (!_tableOption.filter?.disabled && !!_tableOption.filter?.externalFilters?.length && filterRegister) {\n <external-filter\n class=\"mb-16\"\n [autoId]=\"autoId()\"\n [filterRegister]=\"filterRegister\"\n [filter]=\"_tableOption.filter!\"\n [externalFilters]=\"_tableOption.filter?.externalFilters!\">\n </external-filter>\n }\n @let groupedItems = _items | sdTree: _tableOption.tree : treeRevision() | sdGroup: _tableOption : groupExpandState;\n <ng-content select=\"[sdTableTop]\"></ng-content>\n <div class=\"c-container\">\n @if (_loading) {\n <div class=\"c-loading\">\n <mat-spinner></mat-spinner>\n </div>\n }\n <div\n class=\"c-table\"\n sdScroll\n stickyShadow\n [style.max-height]=\"_tableOption.style?.maxHeight\"\n [style.min-height]=\"_tableOption.style?.minHeight\">\n <table\n mat-table\n [dataSource]=\"groupedItems\"\n [trackBy]=\"trackBy\"\n matSort\n [matSortDisabled]=\"!_tableOption.sort?.enable\"\n multiTemplateDataRows\n cdkDropList\n [cdkDropListData]=\"groupedItems\"\n [cdkDropListDisabled]=\"!_tableOption.rowReorder?.enabled\"\n [cdkDropListSortPredicate]=\"reorderSortPredicate\"\n (cdkDropListDropped)=\"onReorderDrop($event)\">\n @if (_tableOption.rowReorder?.enabled) {\n <ng-container matColumnDef=\"sdReorder\">\n <th mat-header-cell *matHeaderCellDef class=\"sd-reorder-header\" [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td mat-cell *matCellDef=\"let row\" class=\"sd-reorder-cell\">\n @if (!row.meta?.group?.items?.length) {\n <mat-icon cdkDragHandle [class.sd-reorder-disabled]=\"isReorderDisabled(row)\">\n {{ _tableOption.rowReorder?.icon || 'drag_indicator' }}\n </mat-icon>\n }\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n }\n\n @if (_tableOption.tree) {\n <ng-container matColumnDef=\"sdTreeToggle\">\n <th\n mat-header-cell\n *matHeaderCellDef\n class=\"sd-tree-toggle-cell p-0\"\n [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td mat-cell *matCellDef=\"let row\" class=\"sd-tree-toggle-cell p-0\">\n @if (row.meta?.tree) {\n <div\n class=\"sd-tree-toggle-inner\"\n [style.padding-left.px]=\"(row.meta.tree.level ?? 0) * (_tableOption.tree?.indentSize ?? 20)\">\n @if (row.meta.tree.hasChildren) {\n @if (row.meta.tree.isExpanding) {\n <div class=\"lds-ring sd-tree-spinner\">\n <div></div>\n <div></div>\n <div></div>\n <div></div>\n </div>\n } @else {\n <sd-button\n type=\"link\"\n [prefixIcon]=\"row.meta.tree.isExpanded ? 'expand_less' : 'expand_more'\"\n (click)=\"onTreeToggle(row); $event.stopPropagation()\"\n width=\"35px\">\n </sd-button>\n }\n }\n </div>\n }\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n }\n\n <ng-container matColumnDef=\"sdSubInformation\" sticky>\n <td class=\"p-0\" mat-cell *matCellDef=\"let item\" [attr.colspan]=\"_configuration.displayedColumns.length\">\n @if (sdSubInformation()?.templateRef) {\n @if (_tableOption.expand?.always) {\n <ng-container *ngTemplateOutlet=\"sdSubInformation()?.templateRef!; context: { item: item }\"> </ng-container>\n } @else {\n <div [@detailExpand]=\"item.isExpanded ? 'expanded' : 'collapsed'\">\n @if (item.isExpanded) {\n <ng-container *ngTemplateOutlet=\"sdSubInformation()?.templateRef!; context: { item: item }\"> </ng-container>\n }\n </div>\n }\n }\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"sdSubInformationAction\" stickyEnd>\n <th class=\"p-0\" mat-header-cell *matHeaderCellDef style=\"width: 1px\" [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td mat-cell *matCellDef=\"let element\">\n @if (!element.isExpanding && !_tableOption.expand?.always) {\n <sd-button\n type=\"link\"\n [prefixIcon]=\"element.isExpanded ? 'expand_less' : 'expand_more'\"\n (click)=\"onExpand(element)\"\n width=\"35px\">\n </sd-button>\n }\n @if (element.isExpanding) {\n <div class=\"lds-ring\">\n <div></div>\n <div></div>\n <div></div>\n <div></div>\n </div>\n }\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"sdSelection\" sticky>\n <th class=\"sd-selection-cell p-0\" mat-header-cell *matHeaderCellDef [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\">\n @let visibleSelectAll = _items | selectionVisibleSelectAll: _tableOption.selector | async;\n @if (visibleSelectAll) {\n <mat-checkbox\n class=\"c-selection px-8\"\n color=\"primary\"\n [ngModel]=\"isSelectAll()\"\n (ngModelChange)=\"isSelectAll.set($event)\"\n (change)=\"onSelectAll()\">\n </mat-checkbox>\n }\n </th>\n\n <td class=\"sd-selection-cell p-0\" mat-cell *matCellDef=\"let item\">\n @let visible = item | selectionVisible: _tableOption.selector;\n @if (visible) {\n @if (_tableOption.selector?.single) {\n <mat-radio-button\n class=\"c-selection px-8\"\n color=\"primary\"\n [checked]=\"item.meta.selector.isSelected\"\n (change)=\"item.meta.selector.isSelected = true; onSelect(item)\"\n [disabled]=\"selectedTableItems() | selectionDisabled: item : _tableOption.selector!\">\n </mat-radio-button>\n } @else {\n <mat-checkbox\n class=\"c-selection px-8\"\n color=\"primary\"\n [(ngModel)]=\"item.meta.selector.isSelected\"\n (change)=\"onSelect(item)\"\n [disabled]=\"selectedTableItems() | selectionDisabled: item : _tableOption.selector!\">\n </mat-checkbox>\n }\n }\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n @if (_tableOption.index?.enabled) {\n @let _pageOffset = pageOffset();\n @let _indexWidth = _tableOption.index?.width || '50px';\n <ng-container matColumnDef=\"sdIndex\" sticky>\n <th\n class=\"text-center p-0\"\n mat-header-cell\n *matHeaderCellDef\n [style.width]=\"_indexWidth\"\n [style.min-width]=\"_indexWidth\"\n [style.max-width]=\"_indexWidth\"\n [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\">\n {{ _tableOption.index?.title || '#' }}\n </th>\n <td class=\"text-center px-4\" mat-cell *matCellDef=\"let item; let i = dataIndex\" [style.min-width]=\"_indexWidth\" [style.max-width]=\"_indexWidth\">\n @if (!item?.meta?.group?.isGroupHeader) {\n @if (_tableOption.tree && item?.meta?.tree?.indexPath?.length) {\n <!-- why: tree \u2192 STT ph\u00E2n c\u1EA5p 1, 1.2, 1.2.1 (indexPath join '.'). T\u00F4 \u0111\u1EADm root (level 0). -->\n <span [class.sd-stt-root]=\"(item.meta.tree.level ?? 0) === 0\">\n {{ item.meta.tree.indexPath.join('.') }}\n </span>\n } @else {\n {{ _pageOffset + i + 1 }}\n }\n }\n </td>\n <td mat-footer-cell *matFooterCellDef [style.min-width]=\"_indexWidth\" [style.max-width]=\"_indexWidth\"></td>\n </ng-container>\n }\n <ng-container\n matColumnDef=\"sdCommand\"\n [sticky]=\"_tableOption.command?.align !== 'right'\"\n [stickyEnd]=\"_tableOption.command?.align === 'right'\">\n <th class=\"p-0\" mat-header-cell *matHeaderCellDef style=\"width: 50px\" [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td class=\"px-8\" mat-cell *matCellDef=\"let item\">\n <desktop-command\n [autoId]=\"autoId()\"\n [commands]=\"_tableOption.command?.commands || _tableOption.commands || []\"\n [item]=\"item\"\n [itemIndex]=\"groupedItems.indexOf(item)\"></desktop-command>\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n <!-- why: group header row d\u00F9ng matRowDef RI\u00CANG v\u1EDBi column list ['sdGroupHeader']\n qua predicate when:isGroupHeaderRow. Cell colspan = displayedColumns.length \u0111\u1EC3\n span TO\u00C0N B\u1ED8 width data row. Tr\u00E1nh colspan trick overflow row khi c\u00E1c TD kh\u00E1c render. -->\n <ng-container matColumnDef=\"sdGroupHeader\">\n <td\n class=\"p-0 sd-group-header-cell\"\n mat-cell\n *matCellDef=\"let item\"\n [attr.colspan]=\"sdGroupColspan()\">\n <div class=\"sd-group-row d-flex align-items-center py-8\">\n <!-- why: slot 42px kh\u1EDBp width v\u1EDBi sd-selection-cell data row \u2192 checkbox group c\u0103n TR\u1EE4C d\u1ECDc \u0111\u00FAng v\u1EDBi checkbox data. -->\n @if (_tableOption.selector?.visible && !_tableOption.selector?.single) {\n <div class=\"sd-group-selection-slot d-flex align-items-center justify-content-center\">\n <mat-checkbox\n class=\"c-selection\"\n color=\"primary\"\n [checked]=\"isGroupAllSelected(item)\"\n [indeterminate]=\"isGroupIndeterminate(item)\"\n (change)=\"onSelectGroup(item, $event.checked)\">\n </mat-checkbox>\n </div>\n } @else {\n <div class=\"sd-group-selection-slot\"></div>\n }\n @if (_tableOption.group?.collapsible) {\n <sd-button\n type=\"link\"\n [prefixIcon]=\"item.meta.group.isExpanded ? 'expand_more' : 'chevron_right'\"\n width=\"32px\"\n (click)=\"toggleGroupExpand(item)\">\n </sd-button>\n }\n @if (sdGroupDef()?.templateRef; as tpl) {\n <ng-container *ngTemplateOutlet=\"tpl; context: groupContext(item)\"></ng-container>\n } @else {\n <span class=\"T14R\">{{ item.meta.group.values | json }}</span>\n }\n </div>\n </td>\n </ng-container>\n <!-- why: filler column \u1EDF cu\u1ED1i h\u1EA5p th\u1EE5 leftover space khi t\u1ED5ng width c\u00E1c c\u1ED9t data < container \u2014 gi\u1EEF cho selection/STT/command kh\u00F4ng b\u1ECB d\u00E3n. -->\n <ng-container matColumnDef=\"sdFiller\">\n <th class=\"sd-filler-cell p-0\" mat-header-cell *matHeaderCellDef [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td class=\"sd-filler-cell p-0\" mat-cell *matCellDef=\"let item\"></td>\n <td class=\"sd-filler-cell p-0\" mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n @for (column of _configuration.firstColumns; track column.field) {\n <ng-container [matColumnDef]=\"column.field\" [sticky]=\"_configuration.fixedColumn[column.field]\">\n <th\n mat-header-cell\n *matHeaderCellDef\n class=\"px-8 py-8 c-th\"\n [sdColumnResize]=\"!!_tableOption.config?.resizable && column.type !== 'children'\"\n [minWidth]=\"column.minWidth\"\n [maxWidth]=\"column.maxWidth\"\n (resizeEnd)=\"onColumnResize(column.field, $event)\"\n [style.width]=\"column.width\"\n [style.min-width]=\"column.minWidth || column.width\"\n [style.max-width]=\"column.maxWidth\"\n [attr.rowspan]=\"_configuration.multipleHeader && column.type !== 'children' ? 2 : 1\"\n [attr.colspan]=\"column.type === 'children' ? column.children.length : 1\">\n <div>\n @if (column.type === 'children') {\n <div\n aria-hidden=\"true\"\n class=\"c-header-title\"\n [class.justify-content-end]=\"column.align === 'right'\"\n [class.text-right]=\"column.align === 'right'\">\n <column-title [column]=\"column\" [titleDef]=\"_titleDef[column.field]\"></column-title>\n </div>\n } @else {\n <div\n aria-hidden=\"true\"\n mat-sort-header\n class=\"c-header-title\"\n [class.justify-content-end]=\"column.align === 'right'\"\n [class.text-right]=\"column.align === 'right'\"\n [disabled]=\"!column.sortable\">\n <column-title [column]=\"column\" [titleDef]=\"_titleDef[column.field]\"></column-title>\n </div>\n @let hideInlineFilter =\n _tableOption.filter?.disabled ||\n _tableOption.filter?.hideInlineFilter === true ||\n (_tableOption.filter?.hideInlineFilter === 'auto' && !_isFiltered && _total! <= 10);\n @if (!hideInlineFilter) {\n <ng-container *sdDesktop>\n <column-filter\n [autoId]=\"autoId()\"\n [value]=\"columnFilter?.[column.field!]!\"\n [operator]=\"columnOperator[column.field]\"\n (operatorChange)=\"columnOperator[column.field] = $event!; onOperatorChange(column, $event)\"\n [columnFilter]=\"columnFilter!\"\n [cacheValues]=\"cacheValues\"\n [column]=\"column\"\n (filterChange)=\"onFilterChange()\"\n (filterCommit)=\"onFilterCommit()\">\n </column-filter>\n </ng-container>\n }\n }\n </div>\n </th>\n <td\n class=\"c-td px-0\"\n [class.d-none]=\"column.type === 'children'\"\n mat-cell\n *matCellDef=\"let item\"\n [sdHoverCopy]=\"(item.data && item.data[column.field]) || ''\"\n [sdHoverCopyDisabled]=\"!column.cell?.copiable\">\n @if (column.type !== 'children' && !item?.meta?.group?.isGroupHeader) {\n <desktop-cell class=\"d-block px-8\" [column]=\"column\" [item]=\"item\" [cellDef]=\"cellDef()\"> </desktop-cell>\n }\n </td>\n <td mat-footer-cell *matFooterCellDef>\n <ng-container *ngIf=\"footerDef()[column.field]\">\n <ng-container *ngTemplateOutlet=\"footerDef()[column.field].templateRef; context: { items: _items, column: column }\">\n </ng-container>\n </ng-container>\n </td>\n </ng-container>\n }\n @for (column of _configuration.secondColumns; track column.field) {\n <ng-container [matColumnDef]=\"column.field\">\n <th\n mat-header-cell\n *matHeaderCellDef\n class=\"c-th px-8\"\n [style.width]=\"column.width\"\n [style.min-width]=\"column.minWidth || column.width\"\n [style.max-width]=\"column.maxWidth\">\n <div>\n <div\n aria-hidden=\"true\"\n mat-sort-header\n class=\"c-header-title\"\n [class.justify-content-end]=\"column.align === 'right'\"\n [class.text-right]=\"column.align === 'right'\"\n [disabled]=\"!column.sortable\">\n <column-title [column]=\"column\" [titleDef]=\"_titleDef[column.field]\"></column-title>\n </div>\n @if (!_tableOption.filter?.disabled && !_tableOption.filter?.hideInlineFilter && columnOperator) {\n <ng-container *sdDesktop>\n <column-filter\n [autoId]=\"autoId()\"\n [value]=\"columnFilter?.[column.field!]!\"\n [operator]=\"columnOperator[column.field]\"\n [columnFilter]=\"columnFilter!\"\n [cacheValues]=\"cacheValues\"\n [column]=\"column\"\n (operatorChange)=\"columnOperator[column.field] = $event!; onOperatorChange(column, $event)\"\n (filterChange)=\"onFilterChange()\"\n (filterCommit)=\"onFilterCommit()\">\n </column-filter>\n </ng-container>\n }\n </div>\n </th>\n <td\n class=\"c-td px-0\"\n mat-cell\n *matCellDef=\"let item\"\n [sdHoverCopy]=\"item[column.field]\"\n [sdHoverCopyDisabled]=\"!column.cell?.copiable\">\n @if (column.type !== 'children') {\n <desktop-cell class=\"d-block px-8\" [column]=\"column\" [item]=\"item\" [cellDef]=\"cellDef()\"> </desktop-cell>\n }\n </td>\n <td mat-footer-cell *matFooterCellDef>\n <ng-container *ngIf=\"footerDef()[column.field]\">\n <ng-container *ngTemplateOutlet=\"footerDef()[column.field].templateRef; context: { items: _items, column: column }\">\n </ng-container>\n </ng-container>\n </td>\n </ng-container>\n }\n <tr class=\"c-first-header\" mat-header-row *matHeaderRowDef=\"_configuration.firstHeaders; sticky: true\"></tr>\n @if (!!_configuration.secondHeaders.length) {\n <tr class=\"c-second-header\" mat-header-row *matHeaderRowDef=\"_configuration.secondHeaders; sticky: true\"></tr>\n }\n <!-- Group header row \u2014 ch\u1EC9 1 cell sdGroupHeader colspan to\u00E0n width. -->\n <tr\n mat-row\n *matRowDef=\"let row; columns: ['sdGroupHeader']; when: isGroupHeaderRow\"\n class=\"c-group-row-tr\"></tr>\n\n <!-- Data row \u2014 d\u00F9ng displayedColumns \u0111\u1EA7y \u0111\u1EE7; when isDataRow \u0111\u1EC3 lo\u1EA1i tr\u1EEB group header. -->\n <tr\n mat-row\n cdkDrag\n [cdkDragData]=\"row\"\n [cdkDragDisabled]=\"\n !_tableOption.rowReorder?.enabled ||\n !!row.meta?.group?.items?.length ||\n (row.meta?.tree?.level ?? 0) > 0 ||\n isReorderDisabled(row)\n \"\n *matRowDef=\"let row; columns: _configuration.displayedColumns; when: isDataRow\"\n matRipple\n class=\"c-row\"\n [class.sd-tree-row]=\"!!_tableOption.tree\"\n [ngClass]=\"_tableOption.tree ? 'sd-tree-level-' + (row.meta?.tree?.level ?? 0) : null\"\n [ngStyle]=\"rowStyle(row)\"\n [class.selected]=\"row.meta.selector.isSelected\"></tr>\n\n <!-- Sub-information row \u2014 also gated b\u1EDFi isDataRow \u0111\u1EC3 KH\u00D4NG render empty expand row d\u01B0\u1EDBi group header. -->\n <tr mat-row *matRowDef=\"let row; columns: ['sdSubInformation']; when: isDataRow\" class=\"c-detail-row\"></tr>\n @if (hasFooter() && !!_configuration.displayedFooters.length) {\n <tr mat-footer-row *matFooterRowDef=\"_configuration.displayedFooters; sticky: true\"></tr>\n }\n </table>\n @if (!_loading && !_total) {\n <div class=\"c-no-data-row\">\n @if (_isFiltered) {\n @if (tableConfiguration?.images?.filterEmpty) {\n <img class=\"c-image\" [src]=\"tableConfiguration!.images!.filterEmpty\" alt=\"filter-empty\" />\n } @else {\n <img class=\"c-image sd-image-filter-empty\" alt=\"filter-empty\" />\n }\n <div class=\"T16M\">{{ 'core.component.table.no-results' | translate }}</div>\n <div class=\"T16R text-secondary\">{{ 'core.component.table.no-results-hint' | translate }}</div>\n } @else {\n @if (_requireFiltered) {\n @if (tableConfiguration?.images?.filterRequired) {\n <img class=\"c-image\" [src]=\"tableConfiguration!.images!.filterRequired\" alt=\"filter-required\" />\n } @else {\n <img class=\"c-image sd-image-filter-required\" alt=\"filter-required\" />\n }\n <div class=\"T16R text-secondary\">{{ 'core.component.table.choose-filter-hint' | translate }}</div>\n } @else {\n @if (tableConfiguration?.images?.dataEmpty) {\n <img class=\"c-image\" [src]=\"tableConfiguration!.images!.dataEmpty\" alt=\"data-empty\" />\n } @else {\n <img class=\"c-image sd-image-data-empty\" alt=\"data-empty\" />\n }\n <div class=\"T16R text-secondary\">{{ 'core.component.table.no-data' | translate }}</div>\n }\n }\n </div>\n }\n </div>\n <div class=\"c-paginator\">\n <div class=\"c-action\">\n <ng-container *sdDesktop>\n @if (_tableOption.reload?.visible) {\n <sd-button\n class=\"mr-8\"\n [title]=\"'core.component.table.reload' | translate\"\n prefixIcon=\"refresh\"\n (click)=\"reload()\"\n [disabled]=\"!_items.length\"\n type=\"link\">\n </sd-button>\n }\n </ng-container>\n @if (_export && _items.length) {\n @if (_export.type === 'custom') {\n <sd-button class=\"mr-8\" [title]=\"exportTitle()\" prefixIcon=\"get_app\" (click)=\"exportCustom()\" type=\"link\"> </sd-button>\n } @else {\n @if (_export.visible) {\n @if (_exporting) {\n <sd-button class=\"mr-8\" [loading]=\"_exporting\" [title]=\"exportTitle()\" prefixIcon=\"get_app\" type=\"link\"> </sd-button>\n } @else {\n @if (_export.visible === 'ALL' || !_export.visible) {\n <sd-button class=\"mr-8\" [title]=\"exportTitle()\" prefixIcon=\"get_app\" [matMenuTriggerFor]=\"menu\" type=\"link\"> </sd-button>\n <mat-menu #menu=\"matMenu\">\n <button mat-menu-item (click)=\"exportExcel()\" type=\"button\">\n <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\n <span> {{ 'core.component.table.export-excel' | translate }}</span>\n </button>\n <button mat-menu-item (click)=\"exportCSV()\" type=\"button\">\n <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\n <span> {{ 'core.component.table.export-csv' | translate }}</span>\n </button>\n </mat-menu>\n } @else if (_export.visible === 'EXCEL') {\n <sd-button class=\"mr-8\" [title]=\"exportTitle()\" prefixIcon=\"get_app\" (click)=\"exportExcel()\" type=\"link\"> </sd-button>\n } @else if (_export.visible === 'CSV') {\n <sd-button class=\"mr-8\" [title]=\"exportTitle()\" prefixIcon=\"get_app\" (click)=\"exportCSV()\" type=\"link\"> </sd-button>\n }\n }\n }\n }\n }\n\n <ng-container *sdDesktop>\n @if (configComponent()) {\n <sd-button\n class=\"mr-8\"\n [title]=\"'core.component.table.setup-short' | translate\"\n prefixIcon=\"settings\"\n (click)=\"configComponent()!.open()\"\n type=\"link\">\n </sd-button>\n }\n </ng-container>\n <!-- Mobile: n\u00FAt Filter m\u1EDF mobile-filter drawer (inline filter \u1EA9n tr\u00EAn mobile) -->\n <ng-container *sdMobile>\n @if (!_tableOption.filter?.disabled && mobileFilter()) {\n <sd-button\n [autoId]=\"autoId() + 'mobile-filter-open'\"\n class=\"mr-8\"\n prefixIcon=\"filter_alt\"\n (click)=\"mobileFilter()!.open()\"\n type=\"link\">\n </sd-button>\n }\n </ng-container>\n </div>\n @let hidePaginator = !_tableOption.paginate?.pageSize || _total === undefined || _total <= _tableOption.paginate?.pageSize!;\n <!-- Desktop paginator: full config (pageSize dropdown, first/last buttons) -->\n <ng-container *sdDesktop>\n <mat-paginator\n [class.d-none]=\"_tableOption.paginate?.hidden || hidePaginator\"\n [length]=\"_total\"\n [pageSize]=\"_tableOption.paginate?.pageSize\"\n [pageSizeOptions]=\"_tableOption.paginate?.pages!\"\n [showFirstLastButtons]=\"_tableOption.paginate?.showFirstLastButtons\"\n [hidePageSize]=\"_tableOption.paginate?.hidePageSize\"></mat-paginator>\n </ng-container>\n <!-- Mobile paginator: \u1EA9n pageSize dropdown + first/last buttons \u0111\u1EC3 ti\u1EBFt ki\u1EC7m kh\u00F4ng gian -->\n <ng-container *sdMobile>\n <mat-paginator\n [class.d-none]=\"_tableOption.paginate?.hidden || hidePaginator\"\n [length]=\"_total\"\n [pageSize]=\"_tableOption.paginate?.pageSize\"\n [showFirstLastButtons]=\"false\"\n hidePageSize></mat-paginator>\n </ng-container>\n <!-- \"\u0110ang hi\u1EC3n th\u1ECB...\" ch\u1EC9 desktop -->\n <ng-container *sdDesktop>\n @if (!_tableOption.paginate?.hidden && hidePaginator && _total !== undefined && _total > 0) {\n <div class=\"T14R pr-16\">\n {{ 'core.component.table.showing' | translate }} <span class=\"T14M ml-2\">1-{{ _total }}/{{ _total }}</span>\n </div>\n }\n </ng-container>\n </div>\n </div>\n <selector-action [tableOption]=\"_tableOption\" [selectedTableItems]=\"selectedTableItems()\" (clear)=\"onClearSelection(groupedItems)\" />\n @if (_tableOption.config?.visible) {\n <config [tableOption]=\"_tableOption\" />\n }\n <!-- Mobile filter drawer \u2014 ch\u1EC9 instantiate khi c\u1EA7n render tr\u00EAn mobile -->\n @if (!_tableOption.filter?.disabled && filterRegister) {\n <mobile-filter\n [autoId]=\"autoId()\"\n [filter]=\"_tableOption.filter!\"\n [externalFilters]=\"_tableOption.filter?.externalFilters!\"\n [columns]=\"_configuration.firstColumns\"\n [filterDefs]=\"sdFilterDefs()\"\n [filterRegister]=\"filterRegister\"\n [cacheValues]=\"cacheValues\">\n </mobile-filter>\n }\n}\n", styles: [":host{display:flex;flex-direction:column;overflow:auto;width:100%;height:100%}:host .c-header-title{height:40px;display:flex;align-items:center}:host .c-container{position:relative;min-height:50px;display:flex;flex-direction:column;flex:1}:host .c-container .c-table{position:relative;flex:1;display:flex;flex-direction:column}:host .c-container .c-table table{border-collapse:separate;width:100%}:host .c-container .c-table table tr.c-first-header.mat-mdc-header-row{height:40px}:host .c-container .c-table table tr.c-second-header.mat-mdc-header-row{height:40px}:host .c-container .c-table table tr.c-detail-row{height:0}:host .c-container .c-table table tr.c-row.activated{background-color:#e5ecff}:host .c-container .c-table table tr.c-row.selected{background-color:#eef2ff}:host .c-container .c-table table tr.c-row:not(.selected):not(.activated):hover{background-color:#f5f5f5}:host .c-container .c-table table tr.c-row td{border-bottom-width:0}:host .c-container .c-table table tr.c-row.c-expandable{cursor:pointer}:host .c-container .c-table table tr.c-row.c-expandable:hover{background:#f5f5f5}:host .c-container .c-table table th.mat-mdc-header-cell{background-color:#f2f3f4;border-bottom:0!important}:host .c-container .c-table table td.mat-mdc-cell,:host .c-container .c-table table td.mat-mdc-footer-cell,:host .c-container .c-table table th.mat-mdc-header-cell{border-bottom-color:#f2f2f2!important}:host .c-container .c-table .c-th{vertical-align:middle;font-weight:500;font-size:14px;line-height:20px;color:#212121}:host .c-container .c-table .c-th.sd-col-resize-host{position:relative}:host .c-container .c-table .c-th.sd-resizing{-webkit-user-select:none;user-select:none}:host .c-container .c-table .c-th .sd-col-resize-handle{position:absolute;top:0;right:0;width:6px;height:100%;cursor:col-resize;-webkit-user-select:none;user-select:none;z-index:2}:host .c-container .c-table .c-th .sd-col-resize-handle:hover{background:#00000014}:host .c-container .c-table .c-td:first{padding-left:10px}:host .c-container .c-table .c-no-data-row{flex:1;width:100%;position:sticky;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center}:host .c-container .c-table .c-no-data-row .c-image{margin-bottom:16px;width:96px}:host .c-container .c-loading{position:absolute;inset:0 0 56px;background:#00000026;z-index:2;display:flex;align-items:center;justify-content:center}:host .c-container .c-paginator{display:flex;flex-direction:row;justify-content:space-between;align-items:center;background-color:#fff}:host .c-container .c-paginator .c-action{padding:5px}:host .c-container .c-empty{text-align:center;background-color:#fff;border:none!important}:host .c-container .c-empty mat-icon{font-size:150px;margin-top:30px;margin-bottom:30px;opacity:.2;width:auto;height:auto}:host button.c-btn-add{background-color:#fff;box-shadow:0 2px 4px #2f313629}:host .lds-ring{display:inline-block;position:relative;width:40px;height:40px}:host .lds-ring div{box-sizing:border-box;display:block;position:absolute;width:32px;height:32px;margin:4px;border:4px solid #cef;border-radius:50%;animation:lds-ring 1.2s cubic-bezier(.5,0,.5,1) infinite;border-color:#cef transparent transparent transparent}:host .lds-ring div:nth-child(1){animation-delay:-.45s}:host .lds-ring div:nth-child(2){animation-delay:-.3s}:host .lds-ring div:nth-child(3){animation-delay:-.15s}@keyframes lds-ring{0%{transform:rotate(0)}to{transform:rotate(360deg)}}:host .sd-reorder-header,:host .sd-reorder-cell{width:40px;min-width:40px;padding:0 4px;box-sizing:border-box}:host .sd-reorder-cell mat-icon{cursor:grab;color:#00000061;display:flex;align-items:center}:host .sd-reorder-cell mat-icon:active{cursor:grabbing}:host .sd-reorder-cell mat-icon.sd-reorder-disabled{opacity:.3;cursor:not-allowed;pointer-events:none}:host ::ng-deep .mat-sort-header-content{display:block;text-align:left;width:100%}:host ::ng-deep .mat-select-arrow{color:#a6a6a6}:host ::ng-deep .mat-sort-header-disabled{background-image:none!important;cursor:default!important;padding-right:0!important}:host ::ng-deep .mat-sort-header-container{align-items:start!important}:host ::ng-deep .mat-sort-header-arrow{margin-top:4px!important}:host ::ng-deep .mat-sort-header-arrow{display:none!important}:host ::ng-deep .mat-sort-header{cursor:pointer}:host ::ng-deep .mat-sort-header[aria-sort]{background-repeat:no-repeat;background-position:center right 0;background-size:16px 16px;cursor:pointer;padding-right:24px}:host ::ng-deep .mat-sort-header[aria-sort=none]{background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 0 24 24' width='24px' fill='%23000000'%3E%3Cpath d='M0 0h24v24H0V0z' fill='none'/%3E%3Cpath fill='%237A7A7A' d='M12 5.83L15.17 9l1.41-1.41L12 3 7.41 7.59 8.83 9 12 5.83zm0 12.34L8.83 15l-1.41 1.41L12 21l4.59-4.59L15.17 15 12 18.17z'/%3E%3C/svg%3E\")}:host ::ng-deep .mat-sort-header[aria-sort=ascending]{background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 0 24 24' width='24px' fill='%23000000'%3E%3Cpath d='M0 0h24v24H0V0z' fill='none'/%3E%3Cpath fill='%237A7A7A' d='M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z'/%3E%3C/svg%3E\")}:host ::ng-deep .mat-sort-header[aria-sort=descending]{background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 0 24 24' width='24px' fill='%23000000'%3E%3Cpath d='M0 0h24v24H0V0z' fill='none'/%3E%3Cpath fill='%237A7A7A' d='M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z'/%3E%3C/svg%3E\")}:host ::ng-deep .c-paginator .mat-mdc-paginator .mdc-text-field--outlined .mat-mdc-form-field-infix,:host ::ng-deep .c-paginator .mat-mdc-paginator .mdc-text-field--no-label .mat-mdc-form-field-infix{padding-top:2px;padding-bottom:2px;min-height:32px}:host ::ng-deep .c-paginator .mat-mdc-paginator-range-label{margin:0 4px}:host ::ng-deep .c-paginator .mat-mdc-paginator-page-size-select mat-select{margin-top:2px!important}:host ::ng-deep .cdk-drag-preview{box-shadow:0 4px 12px #00000026;background:#fff;display:table;width:100%}:host ::ng-deep .cdk-drag-preview td{padding:0 8px;border-bottom:1px solid rgba(0,0,0,.12)}:host ::ng-deep .cdk-drag-placeholder{opacity:0}:host ::ng-deep .cdk-drop-list-dragging tr.c-row:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host ::ng-deep .sd-selection-cell{width:42px;min-width:42px;max-width:42px}:host ::ng-deep .sd-filler-cell{width:auto;min-width:0;padding:0!important;border:0}:host ::ng-deep .sd-group-header-cell{background:#f5f7fc;border-top:1px solid #e6e9f2;border-bottom:1px solid #e6e9f2}:host ::ng-deep .sd-group-row{min-height:36px}:host ::ng-deep .sd-group-selection-slot{width:42px;min-width:42px;max-width:42px}:host ::ng-deep .c-selection{transform:scale(.85);transform-origin:center}:host ::ng-deep .sd-tree-toggle-cell{width:40px;min-width:40px;max-width:100px}:host ::ng-deep .sd-tree-toggle-inner{display:flex;align-items:center;min-height:40px}:host ::ng-deep .sd-tree-spinner{transform:scale(.5);margin:0 auto}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-0{background:#fbfcfe}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-0>td{font-weight:500}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-1{background:#fff}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-2{background:#fafbfd}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-3{background:#f6f8fb}:host ::ng-deep tr.c-row.sd-tree-row:not(.sd-tree-level-0)>td.sd-tree-toggle-cell .sd-tree-toggle-inner{border-left:1px dashed #d8dde6}:host ::ng-deep .sd-stt-root{font-weight:700;color:#1f2330}\n", ":host ::ng-deep .sticky-shadow-right{overflow:visible!important}:host ::ng-deep .sticky-shadow-right:after{content:\"\";position:absolute;top:0;right:0;bottom:0;width:8px;transform:translate(100%);background:linear-gradient(to right,rgba(0,0,0,.12),transparent);pointer-events:none}:host ::ng-deep .sticky-shadow-left{overflow:visible!important}:host ::ng-deep .sticky-shadow-left:after{content:\"\";position:absolute;top:0;left:0;bottom:0;width:8px;transform:translate(-100%);background:linear-gradient(to left,rgba(0,0,0,.12),transparent);pointer-events:none}\n"] }]
|
|
4466
|
+
], template: "@let _configuration = configuration();\n@let _tableOption = tableOption()!;\n@let _loading = loading();\n@let _items = items();\n@let _total = total();\n@let _isFiltered = isFiltered();\n@let _requireFiltered = requireFiltered();\n@let _export = _tableOption?.export;\n@let _exporting = exporting();\n@let _titleDef = titleDef();\n@let _autoId = autoId();\n@let _exportTitle = exportTitle();\n@let _cellDef = cellDef();\n@let _footerDef = footerDef();\n@let _sdSubInformation = sdSubInformation();\n@let _configComponent = configComponent();\n@let _mobileFilter = mobileFilter();\n@let _selectedTableItems = selectedTableItems();\n<!-- why: tree kh\u00F4ng c\u00F2n c\u1ED9t ri\u00EAng \u2014 khi KH\u00D4NG c\u00F3 c\u1ED9t Index, icon expand nh\u00FAng v\u00E0o\n c\u1ED9t data \u0111\u1EA7u ti\u00EAn. \u0110\u00E2y l\u00E0 field c\u1EE7a c\u1ED9t \u0111\u00F3 (null n\u1EBFu c\u00F3 Index ho\u1EB7c kh\u00F4ng tree). -->\n@let _treeFirstField = _tableOption?.tree && !_tableOption.index?.enabled ? _configuration?.firstColumns?.[0]?.field : null;\n\n@if (_configuration) {\n @if (!_tableOption.filter?.disabled && !!_tableOption.filter?.externalFilters?.length && filterRegister) {\n <external-filter\n class=\"mb-16\"\n [autoId]=\"_autoId\"\n [filterRegister]=\"filterRegister\"\n [filter]=\"_tableOption.filter!\"\n [externalFilters]=\"_tableOption.filter?.externalFilters!\">\n </external-filter>\n }\n @let groupedItems = _items | sdTree: _tableOption.tree : treeRevision() | sdGroup: _tableOption : groupExpandState;\n\n <!-- Tree toggle d\u00F9ng chung: indent (theo c\u1EA5p) + slot chevron/spinner. Nh\u00FAng v\u00E0o\n c\u1ED9t Index ho\u1EB7c c\u1ED9t data \u0111\u1EA7u qua *ngTemplateOutlet (context: { row }). -->\n <ng-template #sdTreeToggle let-row=\"row\">\n @let _tree = row?.meta?.tree;\n @if (_tree) {\n <span class=\"sd-tree-indent\" [style.width.px]=\"(_tree.level ?? 0) * (_tableOption.tree?.indentSize ?? 20)\"></span>\n <span class=\"sd-tree-toggle-slot\">\n @if (_tree.hasChildren) {\n @if (_tree.isExpanding) {\n <span class=\"lds-ring sd-tree-spinner\">\n <div></div>\n <div></div>\n <div></div>\n <div></div>\n </span>\n } @else {\n @let _aid = _autoId;\n <button\n type=\"button\"\n class=\"sd-tree-toggle-btn\"\n [attr.data-autoid]=\"_aid ? _aid + '-tree-toggle-' + row.meta.id : null\"\n (click)=\"onTreeToggle(row); $event.stopPropagation()\">\n <mat-icon>{{ _tree.isExpanded ? 'expand_more' : 'chevron_right' }}</mat-icon>\n </button>\n }\n }\n </span>\n }\n </ng-template>\n\n <ng-content select=\"[sdTableTop]\"></ng-content>\n <div class=\"c-container\">\n @if (_loading) {\n <div class=\"c-loading\">\n <mat-spinner></mat-spinner>\n </div>\n }\n <div\n class=\"c-table\"\n sdScroll\n stickyShadow\n [style.max-height]=\"_tableOption.style?.maxHeight\"\n [style.min-height]=\"_tableOption.style?.minHeight\">\n <table\n mat-table\n [dataSource]=\"groupedItems\"\n [trackBy]=\"trackBy\"\n matSort\n [matSortDisabled]=\"!_tableOption.sort?.enable\"\n multiTemplateDataRows\n cdkDropList\n [cdkDropListData]=\"groupedItems\"\n [cdkDropListDisabled]=\"!_tableOption.rowReorder?.enabled\"\n [cdkDropListSortPredicate]=\"reorderSortPredicate\"\n (cdkDropListDropped)=\"onReorderDrop($event)\">\n @if (_tableOption.rowReorder?.enabled) {\n <ng-container matColumnDef=\"sdReorder\">\n <th mat-header-cell *matHeaderCellDef class=\"sd-reorder-header\" [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td mat-cell *matCellDef=\"let row\" class=\"sd-reorder-cell\">\n @if (!row.meta?.group?.items?.length) {\n <mat-icon cdkDragHandle [class.sd-reorder-disabled]=\"isReorderDisabled(row)\">\n {{ _tableOption.rowReorder?.icon || 'drag_indicator' }}\n </mat-icon>\n }\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n }\n\n <ng-container matColumnDef=\"sdSubInformation\" sticky>\n <td class=\"p-0\" mat-cell *matCellDef=\"let item\" [attr.colspan]=\"_configuration.displayedColumns.length\">\n @if (_sdSubInformation?.templateRef) {\n @if (_tableOption.expand?.always) {\n <ng-container *ngTemplateOutlet=\"_sdSubInformation?.templateRef!; context: { item: item }\"> </ng-container>\n } @else {\n <div [@detailExpand]=\"item.isExpanded ? 'expanded' : 'collapsed'\">\n @if (item.isExpanded) {\n <ng-container *ngTemplateOutlet=\"_sdSubInformation?.templateRef!; context: { item: item }\"> </ng-container>\n }\n </div>\n }\n }\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"sdSubInformationAction\" stickyEnd>\n <th class=\"p-0\" mat-header-cell *matHeaderCellDef style=\"width: 1px\" [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td mat-cell *matCellDef=\"let element\">\n @if (!element.isExpanding && !_tableOption.expand?.always) {\n <sd-button\n [autoId]=\"_autoId ? _autoId + '-expand-' + element.meta.id : null\"\n type=\"link\"\n [prefixIcon]=\"element.isExpanded ? 'expand_less' : 'expand_more'\"\n (click)=\"onExpand(element)\"\n width=\"35px\">\n </sd-button>\n }\n @if (element.isExpanding) {\n <div class=\"lds-ring\">\n <div></div>\n <div></div>\n <div></div>\n <div></div>\n </div>\n }\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"sdSelection\" sticky>\n <th class=\"sd-selection-cell p-0\" mat-header-cell *matHeaderCellDef [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\">\n @let visibleSelectAll = _items | selectionVisibleSelectAll: _tableOption.selector | async;\n @if (visibleSelectAll) {\n <mat-checkbox\n class=\"c-selection px-8\"\n color=\"primary\"\n [ngModel]=\"isSelectAll()\"\n (ngModelChange)=\"isSelectAll.set($event)\"\n (change)=\"onSelectAll()\">\n </mat-checkbox>\n }\n </th>\n\n <td class=\"sd-selection-cell p-0\" mat-cell *matCellDef=\"let item\">\n @let visible = item | selectionVisible: _tableOption.selector;\n @if (visible) {\n @if (_tableOption.selector?.single) {\n <mat-radio-button\n class=\"c-selection px-8\"\n color=\"primary\"\n [checked]=\"item.meta.selector.isSelected\"\n (change)=\"item.meta.selector.isSelected = true; onSelect(item)\"\n [disabled]=\"_selectedTableItems | selectionDisabled: item : _tableOption.selector!\">\n </mat-radio-button>\n } @else {\n <mat-checkbox\n class=\"c-selection px-8\"\n color=\"primary\"\n [(ngModel)]=\"item.meta.selector.isSelected\"\n (change)=\"onSelect(item)\"\n [disabled]=\"_selectedTableItems | selectionDisabled: item : _tableOption.selector!\">\n </mat-checkbox>\n }\n }\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n @if (_tableOption.index?.enabled) {\n @let _pageOffset = pageOffset();\n @let _indexWidth = _tableOption.index?.width || '50px';\n <!-- why: khi tree, c\u1ED9t Index \"\u00F4m\" th\u00EAm chevron + indent. D\u00F9ng width:1px +\n nowrap (.sd-tree-index-cell) \u0111\u1EC3 c\u1ED9t co S\u00C1T n\u1ED9i dung, kh\u00F4ng chi\u1EBFm ch\u1ED7\n th\u1EEBa; header \"#\" canh tr\u00E1i l\u00F9i v\u00E0o (.sd-tree-index-header) cho th\u1EB3ng s\u1ED1. -->\n @let _treeIndex = !!_tableOption.tree;\n <ng-container matColumnDef=\"sdIndex\" sticky>\n <th\n [class.p-0]=\"!_treeIndex\"\n [class.text-center]=\"!_treeIndex\"\n [class.sd-tree-index-cell]=\"_treeIndex\"\n [class.sd-tree-index-header]=\"_treeIndex\"\n mat-header-cell\n *matHeaderCellDef\n [style.width]=\"_treeIndex ? '1px' : _indexWidth\"\n [style.min-width]=\"_treeIndex ? null : _indexWidth\"\n [style.max-width]=\"_treeIndex ? null : _indexWidth\"\n [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\">\n {{ _tableOption.index?.title || '#' }}\n </th>\n <td\n [class.px-4]=\"!_treeIndex\"\n [class.text-center]=\"!_treeIndex\"\n [class.sd-tree-index-cell]=\"_treeIndex\"\n mat-cell\n *matCellDef=\"let item; let i = dataIndex\"\n [style.width]=\"_treeIndex ? '1px' : null\"\n [style.min-width]=\"_treeIndex ? null : _indexWidth\"\n [style.max-width]=\"_treeIndex ? null : _indexWidth\">\n @if (!item?.meta?.group?.isGroupHeader) {\n @if (_treeIndex) {\n <!-- why: tree \u2192 chevron + indent + STT ph\u00E2n c\u1EA5p (1, 1.2, 1.2.1). T\u00F4 \u0111\u1EADm root (level 0). -->\n <span class=\"sd-tree-line\">\n <ng-container *ngTemplateOutlet=\"sdTreeToggle; context: { row: item }\"></ng-container>\n @if (item?.meta?.tree?.indexPath?.length) {\n <span class=\"sd-tree-stt\" [class.sd-stt-root]=\"(item.meta.tree.level ?? 0) === 0\">\n {{ item.meta.tree.indexPath.join('.') }}\n </span>\n }\n </span>\n } @else {\n {{ _pageOffset + i + 1 }}\n }\n }\n </td>\n <td mat-footer-cell *matFooterCellDef [style.width]=\"_treeIndex ? '1px' : null\" [style.min-width]=\"_treeIndex ? null : _indexWidth\" [style.max-width]=\"_treeIndex ? null : _indexWidth\"></td>\n </ng-container>\n }\n <ng-container\n matColumnDef=\"sdCommand\"\n [sticky]=\"_tableOption.command?.align !== 'right'\"\n [stickyEnd]=\"_tableOption.command?.align === 'right'\">\n <th class=\"p-0\" mat-header-cell *matHeaderCellDef style=\"width: 50px\" [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td class=\"px-8\" mat-cell *matCellDef=\"let item\">\n <desktop-command\n [autoId]=\"_autoId\"\n [commands]=\"_tableOption.command?.commands || _tableOption.commands || []\"\n [item]=\"item\"\n [itemIndex]=\"groupedItems.indexOf(item)\"></desktop-command>\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n <!-- why: group header row d\u00F9ng matRowDef RI\u00CANG v\u1EDBi column list ['sdGroupHeader']\n qua predicate when:isGroupHeaderRow. Cell colspan = displayedColumns.length \u0111\u1EC3\n span TO\u00C0N B\u1ED8 width data row. Tr\u00E1nh colspan trick overflow row khi c\u00E1c TD kh\u00E1c render. -->\n <ng-container matColumnDef=\"sdGroupHeader\">\n <td\n class=\"p-0 sd-group-header-cell\"\n mat-cell\n *matCellDef=\"let item\"\n [attr.colspan]=\"sdGroupColspan()\">\n <div class=\"sd-group-row d-flex align-items-center py-8\">\n <!-- why: slot 42px kh\u1EDBp width v\u1EDBi sd-selection-cell data row \u2192 checkbox group c\u0103n TR\u1EE4C d\u1ECDc \u0111\u00FAng v\u1EDBi checkbox data. -->\n @if (_tableOption.selector?.visible && !_tableOption.selector?.single) {\n <div class=\"sd-group-selection-slot d-flex align-items-center justify-content-center\">\n <mat-checkbox\n class=\"c-selection\"\n color=\"primary\"\n [checked]=\"isGroupAllSelected(item)\"\n [indeterminate]=\"isGroupIndeterminate(item)\"\n (change)=\"onSelectGroup(item, $event.checked)\">\n </mat-checkbox>\n </div>\n } @else {\n <div class=\"sd-group-selection-slot\"></div>\n }\n @if (_tableOption.group?.collapsible) {\n <sd-button\n [autoId]=\"_autoId ? _autoId + '-group-toggle-' + (item.meta.group?.key || item.meta.id) : null\"\n type=\"link\"\n [prefixIcon]=\"item.meta.group.isExpanded ? 'expand_more' : 'chevron_right'\"\n width=\"32px\"\n (click)=\"toggleGroupExpand(item)\">\n </sd-button>\n }\n @if (sdGroupDef()?.templateRef; as tpl) {\n <ng-container *ngTemplateOutlet=\"tpl; context: groupContext(item)\"></ng-container>\n } @else {\n <span class=\"T14R\">{{ item.meta.group.values | json }}</span>\n }\n </div>\n </td>\n </ng-container>\n <!-- why: filler column \u1EDF cu\u1ED1i h\u1EA5p th\u1EE5 leftover space khi t\u1ED5ng width c\u00E1c c\u1ED9t data < container \u2014 gi\u1EEF cho selection/STT/command kh\u00F4ng b\u1ECB d\u00E3n. -->\n <ng-container matColumnDef=\"sdFiller\">\n <th class=\"sd-filler-cell p-0\" mat-header-cell *matHeaderCellDef [attr.rowspan]=\"_configuration.multipleHeader ? 2 : 1\"></th>\n <td class=\"sd-filler-cell p-0\" mat-cell *matCellDef=\"let item\"></td>\n <td class=\"sd-filler-cell p-0\" mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n @for (column of _configuration.firstColumns; track column.field) {\n <ng-container [matColumnDef]=\"column.field\" [sticky]=\"_configuration.fixedColumn[column.field]\">\n <th\n mat-header-cell\n *matHeaderCellDef\n class=\"px-8 py-8 c-th\"\n [sdColumnResize]=\"!!_tableOption.config?.resizable && column.type !== 'children'\"\n [minWidth]=\"column.minWidth\"\n [maxWidth]=\"column.maxWidth\"\n (resizeEnd)=\"onColumnResize(column.field, $event)\"\n [style.width]=\"column.width\"\n [style.min-width]=\"column.minWidth || column.width\"\n [style.max-width]=\"column.maxWidth\"\n [attr.rowspan]=\"_configuration.multipleHeader && column.type !== 'children' ? 2 : 1\"\n [attr.colspan]=\"column.type === 'children' ? column.children.length : 1\">\n <div>\n @if (column.type === 'children') {\n <div\n aria-hidden=\"true\"\n class=\"c-header-title\"\n [class.justify-content-end]=\"column.align === 'right'\"\n [class.text-right]=\"column.align === 'right'\">\n <column-title [column]=\"column\" [titleDef]=\"_titleDef[column.field]\"></column-title>\n </div>\n } @else {\n <div\n aria-hidden=\"true\"\n mat-sort-header\n class=\"c-header-title\"\n [class.justify-content-end]=\"column.align === 'right'\"\n [class.text-right]=\"column.align === 'right'\"\n [disabled]=\"!column.sortable\">\n <column-title [column]=\"column\" [titleDef]=\"_titleDef[column.field]\"></column-title>\n </div>\n @let hideInlineFilter =\n _tableOption.filter?.disabled ||\n _tableOption.filter?.hideInlineFilter === true ||\n (_tableOption.filter?.hideInlineFilter === 'auto' && !_isFiltered && _total! <= 10);\n @if (!hideInlineFilter) {\n <ng-container *sdDesktop>\n <column-filter\n [autoId]=\"_autoId\"\n [value]=\"columnFilter?.[column.field!]!\"\n [operator]=\"columnOperator[column.field]\"\n (operatorChange)=\"columnOperator[column.field] = $event!; onOperatorChange(column, $event)\"\n [columnFilter]=\"columnFilter!\"\n [cacheValues]=\"cacheValues\"\n [column]=\"column\"\n (filterChange)=\"onFilterChange()\"\n (filterCommit)=\"onFilterCommit()\">\n </column-filter>\n </ng-container>\n }\n }\n </div>\n </th>\n <td\n class=\"c-td px-0\"\n [class.d-none]=\"column.type === 'children'\"\n mat-cell\n *matCellDef=\"let item\"\n [sdHoverCopy]=\"(item.data && item.data[column.field]) || ''\"\n [sdHoverCopyDisabled]=\"!column.cell?.copiable\">\n @if (column.type !== 'children' && !item?.meta?.group?.isGroupHeader) {\n @if (_treeFirstField && column.field === _treeFirstField) {\n <!-- why: kh\u00F4ng c\u00F3 c\u1ED9t Index \u2192 chevron + indent nh\u00FAng v\u00E0o c\u1ED9t data \u0111\u1EA7u (nh\u01B0 file explorer). -->\n <span class=\"sd-tree-line px-8\">\n <ng-container *ngTemplateOutlet=\"sdTreeToggle; context: { row: item }\"></ng-container>\n <desktop-cell class=\"d-block\" [column]=\"column\" [item]=\"item\" [cellDef]=\"_cellDef\"></desktop-cell>\n </span>\n } @else {\n <desktop-cell class=\"d-block px-8\" [column]=\"column\" [item]=\"item\" [cellDef]=\"_cellDef\"> </desktop-cell>\n }\n }\n </td>\n <td mat-footer-cell *matFooterCellDef>\n <ng-container *ngIf=\"_footerDef[column.field]\">\n <ng-container *ngTemplateOutlet=\"_footerDef[column.field].templateRef; context: { items: _items, column: column }\">\n </ng-container>\n </ng-container>\n </td>\n </ng-container>\n }\n @for (column of _configuration.secondColumns; track column.field) {\n <ng-container [matColumnDef]=\"column.field\">\n <th\n mat-header-cell\n *matHeaderCellDef\n class=\"c-th px-8\"\n [style.width]=\"column.width\"\n [style.min-width]=\"column.minWidth || column.width\"\n [style.max-width]=\"column.maxWidth\">\n <div>\n <div\n aria-hidden=\"true\"\n mat-sort-header\n class=\"c-header-title\"\n [class.justify-content-end]=\"column.align === 'right'\"\n [class.text-right]=\"column.align === 'right'\"\n [disabled]=\"!column.sortable\">\n <column-title [column]=\"column\" [titleDef]=\"_titleDef[column.field]\"></column-title>\n </div>\n @if (!_tableOption.filter?.disabled && !_tableOption.filter?.hideInlineFilter && columnOperator) {\n <ng-container *sdDesktop>\n <column-filter\n [autoId]=\"_autoId\"\n [value]=\"columnFilter?.[column.field!]!\"\n [operator]=\"columnOperator[column.field]\"\n [columnFilter]=\"columnFilter!\"\n [cacheValues]=\"cacheValues\"\n [column]=\"column\"\n (operatorChange)=\"columnOperator[column.field] = $event!; onOperatorChange(column, $event)\"\n (filterChange)=\"onFilterChange()\"\n (filterCommit)=\"onFilterCommit()\">\n </column-filter>\n </ng-container>\n }\n </div>\n </th>\n <td\n class=\"c-td px-0\"\n mat-cell\n *matCellDef=\"let item\"\n [sdHoverCopy]=\"item[column.field]\"\n [sdHoverCopyDisabled]=\"!column.cell?.copiable\">\n @if (column.type !== 'children') {\n <desktop-cell class=\"d-block px-8\" [column]=\"column\" [item]=\"item\" [cellDef]=\"_cellDef\"> </desktop-cell>\n }\n </td>\n <td mat-footer-cell *matFooterCellDef>\n <ng-container *ngIf=\"_footerDef[column.field]\">\n <ng-container *ngTemplateOutlet=\"_footerDef[column.field].templateRef; context: { items: _items, column: column }\">\n </ng-container>\n </ng-container>\n </td>\n </ng-container>\n }\n <tr class=\"c-first-header\" mat-header-row *matHeaderRowDef=\"_configuration.firstHeaders; sticky: true\"></tr>\n @if (!!_configuration.secondHeaders.length) {\n <tr class=\"c-second-header\" mat-header-row *matHeaderRowDef=\"_configuration.secondHeaders; sticky: true\"></tr>\n }\n <!-- Group header row \u2014 ch\u1EC9 1 cell sdGroupHeader colspan to\u00E0n width. -->\n <tr\n mat-row\n *matRowDef=\"let row; columns: ['sdGroupHeader']; when: isGroupHeaderRow\"\n class=\"c-group-row-tr\"></tr>\n\n <!-- Data row \u2014 d\u00F9ng displayedColumns \u0111\u1EA7y \u0111\u1EE7; when isDataRow \u0111\u1EC3 lo\u1EA1i tr\u1EEB group header. -->\n <tr\n mat-row\n cdkDrag\n [cdkDragData]=\"row\"\n [cdkDragDisabled]=\"\n !_tableOption.rowReorder?.enabled ||\n !!row.meta?.group?.items?.length ||\n (row.meta?.tree?.level ?? 0) > 0 ||\n isReorderDisabled(row)\n \"\n *matRowDef=\"let row; columns: _configuration.displayedColumns; when: isDataRow\"\n matRipple\n class=\"c-row\"\n [class.sd-tree-row]=\"!!_tableOption.tree\"\n [ngClass]=\"_tableOption.tree ? 'sd-tree-level-' + (row.meta?.tree?.level ?? 0) : null\"\n [ngStyle]=\"rowStyle(row)\"\n [class.selected]=\"row.meta.selector.isSelected\"></tr>\n\n <!-- Sub-information row \u2014 also gated b\u1EDFi isDataRow \u0111\u1EC3 KH\u00D4NG render empty expand row d\u01B0\u1EDBi group header. -->\n <tr mat-row *matRowDef=\"let row; columns: ['sdSubInformation']; when: isDataRow\" class=\"c-detail-row\"></tr>\n @if (hasFooter() && !!_configuration.displayedFooters.length) {\n <tr mat-footer-row *matFooterRowDef=\"_configuration.displayedFooters; sticky: true\"></tr>\n }\n </table>\n @if (!_loading && !_total) {\n <div class=\"c-no-data-row\">\n @if (_isFiltered) {\n @if (tableConfiguration?.images?.filterEmpty) {\n <img class=\"c-image\" [src]=\"tableConfiguration!.images!.filterEmpty\" alt=\"filter-empty\" />\n } @else {\n <img class=\"c-image sd-image-filter-empty\" alt=\"filter-empty\" />\n }\n <div class=\"T16M\">{{ 'core.component.table.no-results' | translate }}</div>\n <div class=\"T16R text-secondary\">{{ 'core.component.table.no-results-hint' | translate }}</div>\n } @else {\n @if (_requireFiltered) {\n @if (tableConfiguration?.images?.filterRequired) {\n <img class=\"c-image\" [src]=\"tableConfiguration!.images!.filterRequired\" alt=\"filter-required\" />\n } @else {\n <img class=\"c-image sd-image-filter-required\" alt=\"filter-required\" />\n }\n <div class=\"T16R text-secondary\">{{ 'core.component.table.choose-filter-hint' | translate }}</div>\n } @else {\n @if (tableConfiguration?.images?.dataEmpty) {\n <img class=\"c-image\" [src]=\"tableConfiguration!.images!.dataEmpty\" alt=\"data-empty\" />\n } @else {\n <img class=\"c-image sd-image-data-empty\" alt=\"data-empty\" />\n }\n <div class=\"T16R text-secondary\">{{ 'core.component.table.no-data' | translate }}</div>\n }\n }\n </div>\n }\n </div>\n <div class=\"c-paginator\">\n <div class=\"c-action\">\n <ng-container *sdDesktop>\n @if (_tableOption.reload?.visible) {\n <sd-button\n [autoId]=\"_autoId ? _autoId + '-reload' : null\"\n class=\"mr-8\"\n [title]=\"'core.component.table.reload' | translate\"\n prefixIcon=\"refresh\"\n (click)=\"reload()\"\n [disabled]=\"!_items.length\"\n type=\"link\">\n </sd-button>\n }\n </ng-container>\n @if (_export && _items.length) {\n @if (_export.type === 'custom') {\n <sd-button [autoId]=\"_autoId ? _autoId + '-export' : null\" class=\"mr-8\" [title]=\"_exportTitle\" prefixIcon=\"get_app\" (click)=\"exportCustom()\" type=\"link\"> </sd-button>\n } @else {\n @if (_export.visible) {\n @if (_exporting) {\n <sd-button [autoId]=\"_autoId ? _autoId + '-export' : null\" class=\"mr-8\" [loading]=\"_exporting\" [title]=\"_exportTitle\" prefixIcon=\"get_app\" type=\"link\"> </sd-button>\n } @else {\n @if (_export.visible === 'ALL' || !_export.visible) {\n <sd-button [autoId]=\"_autoId ? _autoId + '-export' : null\" class=\"mr-8\" [title]=\"_exportTitle\" prefixIcon=\"get_app\" [matMenuTriggerFor]=\"menu\" type=\"link\"> </sd-button>\n <mat-menu #menu=\"matMenu\">\n <button mat-menu-item [attr.data-autoid]=\"_autoId ? _autoId + '-export-excel' : null\" (click)=\"exportExcel()\" type=\"button\">\n <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\n <span> {{ 'core.component.table.export-excel' | translate }}</span>\n </button>\n <button mat-menu-item [attr.data-autoid]=\"_autoId ? _autoId + '-export-csv' : null\" (click)=\"exportCSV()\" type=\"button\">\n <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\n <span> {{ 'core.component.table.export-csv' | translate }}</span>\n </button>\n </mat-menu>\n } @else if (_export.visible === 'EXCEL') {\n <sd-button [autoId]=\"_autoId ? _autoId + '-export-excel' : null\" class=\"mr-8\" [title]=\"_exportTitle\" prefixIcon=\"get_app\" (click)=\"exportExcel()\" type=\"link\"> </sd-button>\n } @else if (_export.visible === 'CSV') {\n <sd-button [autoId]=\"_autoId ? _autoId + '-export-csv' : null\" class=\"mr-8\" [title]=\"_exportTitle\" prefixIcon=\"get_app\" (click)=\"exportCSV()\" type=\"link\"> </sd-button>\n }\n }\n }\n }\n }\n\n <ng-container *sdDesktop>\n @if (_configComponent) {\n <sd-button\n [autoId]=\"_autoId ? _autoId + '-config' : null\"\n class=\"mr-8\"\n [title]=\"'core.component.table.setup-short' | translate\"\n prefixIcon=\"settings\"\n (click)=\"_configComponent.open()\"\n type=\"link\">\n </sd-button>\n }\n </ng-container>\n <!-- Mobile: n\u00FAt Filter m\u1EDF mobile-filter drawer (inline filter \u1EA9n tr\u00EAn mobile) -->\n <ng-container *sdMobile>\n @if (!_tableOption.filter?.disabled && _mobileFilter) {\n <sd-button\n [autoId]=\"_autoId ? _autoId + '-mobile-filter-open' : null\"\n class=\"mr-8\"\n prefixIcon=\"filter_alt\"\n (click)=\"_mobileFilter.open()\"\n type=\"link\">\n </sd-button>\n }\n </ng-container>\n </div>\n @let hidePaginator = !_tableOption.paginate?.pageSize || _total === undefined || _total <= _tableOption.paginate?.pageSize!;\n <!-- Desktop paginator: full config (pageSize dropdown, first/last buttons) -->\n <ng-container *sdDesktop>\n <mat-paginator\n [class.d-none]=\"_tableOption.paginate?.hidden || hidePaginator\"\n [length]=\"_total\"\n [pageSize]=\"_tableOption.paginate?.pageSize\"\n [pageSizeOptions]=\"_tableOption.paginate?.pages!\"\n [showFirstLastButtons]=\"_tableOption.paginate?.showFirstLastButtons\"\n [hidePageSize]=\"_tableOption.paginate?.hidePageSize\"></mat-paginator>\n </ng-container>\n <!-- Mobile paginator: \u1EA9n pageSize dropdown + first/last buttons \u0111\u1EC3 ti\u1EBFt ki\u1EC7m kh\u00F4ng gian -->\n <ng-container *sdMobile>\n <mat-paginator\n [class.d-none]=\"_tableOption.paginate?.hidden || hidePaginator\"\n [length]=\"_total\"\n [pageSize]=\"_tableOption.paginate?.pageSize\"\n [showFirstLastButtons]=\"false\"\n hidePageSize></mat-paginator>\n </ng-container>\n <!-- \"\u0110ang hi\u1EC3n th\u1ECB...\" ch\u1EC9 desktop -->\n <ng-container *sdDesktop>\n @if (!_tableOption.paginate?.hidden && hidePaginator && _total !== undefined && _total > 0) {\n <div class=\"T14R pr-16\">\n {{ 'core.component.table.showing' | translate }} <span class=\"T14M ml-2\">1-{{ _total }}/{{ _total }}</span>\n </div>\n }\n </ng-container>\n </div>\n </div>\n <selector-action [autoId]=\"_autoId\" [tableOption]=\"_tableOption\" [selectedTableItems]=\"_selectedTableItems\" (clear)=\"onClearSelection(groupedItems)\" />\n @if (_tableOption.config?.visible) {\n <config [autoId]=\"_autoId\" [tableOption]=\"_tableOption\" />\n }\n <!-- Mobile filter drawer \u2014 ch\u1EC9 instantiate khi c\u1EA7n render tr\u00EAn mobile -->\n @if (!_tableOption.filter?.disabled && filterRegister) {\n <mobile-filter\n [autoId]=\"_autoId\"\n [filter]=\"_tableOption.filter!\"\n [externalFilters]=\"_tableOption.filter?.externalFilters!\"\n [columns]=\"_configuration.firstColumns\"\n [filterDefs]=\"sdFilterDefs()\"\n [filterRegister]=\"filterRegister\"\n [cacheValues]=\"cacheValues\">\n </mobile-filter>\n }\n}\n", styles: [":host{display:flex;flex-direction:column;overflow:auto;width:100%;height:100%}:host .c-header-title{height:40px;display:flex;align-items:center}:host .c-container{position:relative;min-height:50px;display:flex;flex-direction:column;flex:1}:host .c-container .c-table{position:relative;flex:1;display:flex;flex-direction:column}:host .c-container .c-table table{border-collapse:separate;width:100%}:host .c-container .c-table table tr.c-first-header.mat-mdc-header-row{height:40px}:host .c-container .c-table table tr.c-second-header.mat-mdc-header-row{height:40px}:host .c-container .c-table table tr.c-detail-row{height:0}:host .c-container .c-table table tr.c-row.activated{background-color:#e5ecff}:host .c-container .c-table table tr.c-row.selected{background-color:#eef2ff}:host .c-container .c-table table tr.c-row:not(.selected):not(.activated):hover{background-color:#f5f5f5}:host .c-container .c-table table tr.c-row td{border-bottom-width:0}:host .c-container .c-table table tr.c-row.c-expandable{cursor:pointer}:host .c-container .c-table table tr.c-row.c-expandable:hover{background:#f5f5f5}:host .c-container .c-table table th.mat-mdc-header-cell{background-color:#f2f3f4;border-bottom:0!important}:host .c-container .c-table table td.mat-mdc-cell,:host .c-container .c-table table td.mat-mdc-footer-cell,:host .c-container .c-table table th.mat-mdc-header-cell{border-bottom-color:#f2f2f2!important}:host .c-container .c-table .c-th{vertical-align:middle;font-weight:500;font-size:14px;line-height:20px;color:#212121}:host .c-container .c-table .c-th.sd-col-resize-host{position:relative}:host .c-container .c-table .c-th.sd-resizing{-webkit-user-select:none;user-select:none}:host .c-container .c-table .c-th .sd-col-resize-handle{position:absolute;top:0;right:0;width:6px;height:100%;cursor:col-resize;-webkit-user-select:none;user-select:none;z-index:2}:host .c-container .c-table .c-th .sd-col-resize-handle:hover{background:#00000014}:host .c-container .c-table .c-td:first{padding-left:10px}:host .c-container .c-table .c-no-data-row{flex:1;width:100%;position:sticky;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center}:host .c-container .c-table .c-no-data-row .c-image{margin-bottom:16px;width:96px}:host .c-container .c-loading{position:absolute;inset:0 0 56px;background:#00000026;z-index:2;display:flex;align-items:center;justify-content:center}:host .c-container .c-paginator{display:flex;flex-direction:row;justify-content:space-between;align-items:center;background-color:#fff}:host .c-container .c-paginator .c-action{padding:5px}:host .c-container .c-empty{text-align:center;background-color:#fff;border:none!important}:host .c-container .c-empty mat-icon{font-size:150px;margin-top:30px;margin-bottom:30px;opacity:.2;width:auto;height:auto}:host button.c-btn-add{background-color:#fff;box-shadow:0 2px 4px #2f313629}:host .lds-ring{display:inline-block;position:relative;width:40px;height:40px}:host .lds-ring div{box-sizing:border-box;display:block;position:absolute;width:32px;height:32px;margin:4px;border:4px solid #cef;border-radius:50%;animation:lds-ring 1.2s cubic-bezier(.5,0,.5,1) infinite;border-color:#cef transparent transparent transparent}:host .lds-ring div:nth-child(1){animation-delay:-.45s}:host .lds-ring div:nth-child(2){animation-delay:-.3s}:host .lds-ring div:nth-child(3){animation-delay:-.15s}@keyframes lds-ring{0%{transform:rotate(0)}to{transform:rotate(360deg)}}:host .sd-reorder-header,:host .sd-reorder-cell{width:40px;min-width:40px;padding:0 4px;box-sizing:border-box}:host .sd-reorder-cell mat-icon{cursor:grab;color:#00000061;display:flex;align-items:center}:host .sd-reorder-cell mat-icon:active{cursor:grabbing}:host .sd-reorder-cell mat-icon.sd-reorder-disabled{opacity:.3;cursor:not-allowed;pointer-events:none}:host ::ng-deep .mat-sort-header-content{display:block;text-align:left;width:100%}:host ::ng-deep .mat-select-arrow{color:#a6a6a6}:host ::ng-deep .mat-sort-header-disabled{background-image:none!important;cursor:default!important;padding-right:0!important}:host ::ng-deep .mat-sort-header-container{align-items:start!important}:host ::ng-deep .mat-sort-header-arrow{margin-top:4px!important}:host ::ng-deep .mat-sort-header-arrow{display:none!important}:host ::ng-deep .mat-sort-header{cursor:pointer}:host ::ng-deep .mat-sort-header[aria-sort]{background-repeat:no-repeat;background-position:center right 0;background-size:16px 16px;cursor:pointer;padding-right:24px}:host ::ng-deep .mat-sort-header[aria-sort=none]{background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 0 24 24' width='24px' fill='%23000000'%3E%3Cpath d='M0 0h24v24H0V0z' fill='none'/%3E%3Cpath fill='%237A7A7A' d='M12 5.83L15.17 9l1.41-1.41L12 3 7.41 7.59 8.83 9 12 5.83zm0 12.34L8.83 15l-1.41 1.41L12 21l4.59-4.59L15.17 15 12 18.17z'/%3E%3C/svg%3E\")}:host ::ng-deep .mat-sort-header[aria-sort=ascending]{background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 0 24 24' width='24px' fill='%23000000'%3E%3Cpath d='M0 0h24v24H0V0z' fill='none'/%3E%3Cpath fill='%237A7A7A' d='M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z'/%3E%3C/svg%3E\")}:host ::ng-deep .mat-sort-header[aria-sort=descending]{background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 0 24 24' width='24px' fill='%23000000'%3E%3Cpath d='M0 0h24v24H0V0z' fill='none'/%3E%3Cpath fill='%237A7A7A' d='M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z'/%3E%3C/svg%3E\")}:host ::ng-deep .c-paginator .mat-mdc-paginator .mdc-text-field--outlined .mat-mdc-form-field-infix,:host ::ng-deep .c-paginator .mat-mdc-paginator .mdc-text-field--no-label .mat-mdc-form-field-infix{padding-top:2px;padding-bottom:2px;min-height:32px}:host ::ng-deep .c-paginator .mat-mdc-paginator-range-label{margin:0 4px}:host ::ng-deep .c-paginator .mat-mdc-paginator-page-size-select mat-select{margin-top:2px!important}:host ::ng-deep .cdk-drag-preview{box-shadow:0 4px 12px #00000026;background:#fff;display:table;width:100%}:host ::ng-deep .cdk-drag-preview td{padding:0 8px;border-bottom:1px solid rgba(0,0,0,.12)}:host ::ng-deep .cdk-drag-placeholder{opacity:0}:host ::ng-deep .cdk-drop-list-dragging tr.c-row:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host ::ng-deep .sd-selection-cell{width:42px;min-width:42px;max-width:42px}:host ::ng-deep .sd-filler-cell{width:auto;min-width:0;padding:0!important;border:0}:host ::ng-deep .sd-group-header-cell{background:#f5f7fc;border-top:1px solid #e6e9f2;border-bottom:1px solid #e6e9f2}:host ::ng-deep .sd-group-row{min-height:36px}:host ::ng-deep .sd-group-selection-slot{width:42px;min-width:42px;max-width:42px}:host ::ng-deep .c-selection{transform:scale(.85);transform-origin:center}:host ::ng-deep .sd-tree-line{display:inline-flex;align-items:center;min-height:32px}:host ::ng-deep .sd-tree-indent{flex:0 0 auto}:host ::ng-deep .sd-tree-toggle-slot{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px}:host ::ng-deep .sd-tree-toggle-btn{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;border:0;background:transparent;border-radius:50%;cursor:pointer;color:var(--sd-text-secondary, #5b6472);transition:background-color .15s ease}:host ::ng-deep .sd-tree-toggle-btn mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}:host ::ng-deep .sd-tree-toggle-btn:hover{background-color:#0f172a14}:host ::ng-deep .sd-tree-spinner{transform:scale(.45)}:host ::ng-deep .sd-tree-stt{margin-left:2px;white-space:nowrap}:host ::ng-deep .sd-tree-index-cell{text-align:left!important;white-space:nowrap;padding-left:8px;padding-right:8px}:host ::ng-deep .sd-tree-index-header{padding-left:32px}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-0{background:#fbfcfe}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-0>td{font-weight:500}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-1{background:#fff}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-2{background:#fafbfd}:host ::ng-deep tr.c-row.sd-tree-row.sd-tree-level-3{background:#f6f8fb}:host ::ng-deep .sd-stt-root{font-weight:700;color:#1f2330}\n", ":host ::ng-deep .sticky-shadow-right{overflow:visible!important}:host ::ng-deep .sticky-shadow-right:after{content:\"\";position:absolute;top:0;right:0;bottom:0;width:8px;transform:translate(100%);background:linear-gradient(to right,rgba(0,0,0,.12),transparent);pointer-events:none}:host ::ng-deep .sticky-shadow-left{overflow:visible!important}:host ::ng-deep .sticky-shadow-left:after{content:\"\";position:absolute;top:0;left:0;bottom:0;width:8px;transform:translate(-100%);background:linear-gradient(to left,rgba(0,0,0,.12),transparent);pointer-events:none}\n"] }]
|
|
4340
4467
|
}], ctorParameters: () => [], propDecorators: { autoIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], option: [{ type: i0.Input, args: [{ isSignal: true, alias: "option", required: true }] }], table: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatTable), { isSignal: true }] }], configComponent: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ConfigComponent), { isSignal: true }] }], sdPopupExport: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SdPopupExport), { isSignal: true }] }], scroll: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SdScrollDirective), { isSignal: true }] }], quickAction: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SdQuickAction), { isSignal: true }] }], externalFilter: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ExternalFilterComponent), { isSignal: true }] }], mobileFilter: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MobileFilterComponent), { isSignal: true }] }], paginator: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatPaginator), { isSignal: true }] }], sort: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatSort), { isSignal: true }] }], sdSubInformation: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdTableExpandDefDirective), { isSignal: true }] }], sdGroupDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdTableGroupDefDirective), { isSignal: true }] }], sdCellDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SdTableCellDefDirective), { isSignal: true }] }], sdFooterDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SdMaterialFooterDefDirective), { isSignal: true }] }], sdFilterDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SdTableFilterDefDirective), { isSignal: true }] }], sdTitleDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SdTableTitleDefDirective), { isSignal: true }] }] } });
|
|
4341
4468
|
|
|
4342
4469
|
const SdConvertToPagingReq = (filterRequest, args) => {
|