@sd-angular/core 19.0.11 → 19.0.12
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 +20 -20
- package/assets/STYLE-GUIDE.md +19 -19
- package/assets/fonts/fonts.scss +115 -115
- package/assets/scss/core/scrollbar.scss +30 -30
- package/assets/scss/core/utilities/_grid.scss +149 -149
- package/components/form-generic/src/components/form-builder/components/expression-builder/expression-builder.component.d.ts +1 -1
- package/components/form-generic/src/components/form-builder/components/table/control/table-control.component.d.ts +1 -1
- package/components/form-generic/src/components/sd-feel-expression/sd-feel-expression.component.d.ts +1 -1
- package/components/table/src/components/filter/column-filter/column-filter.component.d.ts +1 -1
- package/fesm2022/sd-angular-core-components-anchor.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-autoid-inspector.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-avatar.mjs +2 -2
- package/fesm2022/sd-angular-core-components-avatar.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-button.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-chart.mjs +40 -40
- package/fesm2022/sd-angular-core-components-chart.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-editor.mjs +2 -2
- package/fesm2022/sd-angular-core-components-editor.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-form-generic.mjs +2 -2
- package/fesm2022/sd-angular-core-components-form-generic.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-inform.mjs +2 -2
- package/fesm2022/sd-angular-core-components-inform.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-modal.mjs +2 -2
- package/fesm2022/sd-angular-core-components-modal.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-org-chart.mjs +2 -2
- package/fesm2022/sd-angular-core-components-org-chart.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-preview.mjs +4 -4
- package/fesm2022/sd-angular-core-components-preview.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-query-bar.mjs +10 -10
- package/fesm2022/sd-angular-core-components-query-bar.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-query-builder.mjs +2 -2
- package/fesm2022/sd-angular-core-components-query-builder.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-quick-action.mjs +2 -2
- package/fesm2022/sd-angular-core-components-quick-action.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-section.mjs +2 -2
- package/fesm2022/sd-angular-core-components-section.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-side-drawer.mjs +2 -2
- package/fesm2022/sd-angular-core-components-side-drawer.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-splitter.mjs +6 -6
- package/fesm2022/sd-angular-core-components-splitter.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-stepper.mjs +2 -2
- package/fesm2022/sd-angular-core-components-stepper.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-tab-router.mjs +60 -30
- package/fesm2022/sd-angular-core-components-tab-router.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-tab.mjs +2 -2
- package/fesm2022/sd-angular-core-components-tab.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-table.mjs +31 -31
- package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-tree.mjs +2 -2
- package/fesm2022/sd-angular-core-components-tree.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-view.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-chip-calendar.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-chip.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-date-range.mjs +2 -2
- package/fesm2022/sd-angular-core-forms-date-range.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-datetime.mjs +4 -4
- package/fesm2022/sd-angular-core-forms-datetime.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-inline-text.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-input-number.mjs +2 -2
- package/fesm2022/sd-angular-core-forms-input-number.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-label.mjs +2 -2
- package/fesm2022/sd-angular-core-forms-label.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-models.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-select.mjs +2 -2
- package/fesm2022/sd-angular-core-forms-select.mjs.map +1 -1
- package/fesm2022/sd-angular-core-i18n.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-authom.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-keycloak.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-layout.mjs +2 -2
- package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
- package/fesm2022/sd-angular-core-pipes.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-api.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-confirm.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-excel.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-loading.mjs +23 -14
- package/fesm2022/sd-angular-core-services-loading.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-notify.mjs +2 -2
- package/fesm2022/sd-angular-core-services-notify.mjs.map +1 -1
- package/fesm2022/sd-angular-core-utilities-extensions.mjs.map +1 -1
- package/fesm2022/sd-angular-core-utilities-models.mjs.map +1 -1
- package/fesm2022/sd-angular-core.mjs.map +1 -1
- package/modules/keycloak/htmls/auth-keycloak-error.html +54 -54
- package/modules/keycloak/htmls/silent-renew.html +7 -7
- package/package.json +67 -67
- package/sd-angular-core-19.0.12.tgz +0 -0
- package/services/loading/src/loading.service.d.ts +1 -1
- package/sd-angular-core-19.0.11.tgz +0 -0
|
@@ -878,11 +878,11 @@ class SdQueryBuilder {
|
|
|
878
878
|
return `${this.resolvedAutoId() ?? 'qb'}-${suffix}`;
|
|
879
879
|
}
|
|
880
880
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdQueryBuilder, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
881
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SdQueryBuilder, isStandalone: true, selector: "sd-query-builder", inputs: { option: { classPropertyName: "option", publicName: "option", isSignal: true, isRequired: false, transformFunction: null }, fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, comparisonMode: { classPropertyName: "comparisonMode", publicName: "comparisonMode", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, autoId: { classPropertyName: "autoId", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, rootLogic: { classPropertyName: "rootLogic", publicName: "rootLogic", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", filters: "filtersChange", rootLogic: "rootLogicChange" }, ngImport: i0, template: "@if (isView()) {\r\n <div class=\"qb-view\" [attr.data-autoid]=\"autoIdFor('view')\" aria-readonly=\"true\">\r\n @if (tokens().length) {\r\n @for (t of tokens(); track $index) {\r\n <span class=\"qb-tok qb-tok-{{ t.kind }}\">{{ t.text }}</span>\r\n }\r\n } @else {\r\n <span class=\"qb-view-empty\">\u2014</span>\r\n }\r\n </div>\r\n} @else {\r\n <div class=\"qb-container\" [class.is-disabled]=\"resolvedDisabled()\" (click)=\"closeAllDropdowns()\">\r\n <ng-container [ngTemplateOutlet]=\"groupTpl\" [ngTemplateOutletContext]=\"{ $implicit: tree(), isRoot: true }\"></ng-container>\r\n </div>\r\n}\r\n\r\n<!-- Recursive group node -->\r\n<ng-template #groupTpl let-group let-isRoot=\"isRoot\" let-parent=\"parent\" let-index=\"index\">\r\n <div class=\"qb-group\" [class.is-root]=\"isRoot\">\r\n <div class=\"qb-header\" [class.is-open]=\"group.open\">\r\n <div class=\"qb-logic-switch\">\r\n <button type=\"button\" [class.active]=\"group.logic === 'AND'\" [disabled]=\"resolvedDisabled()\" (click)=\"setGroupLogic(group, 'AND')\">AND</button>\r\n <button type=\"button\" [class.active]=\"group.logic === 'OR'\" [disabled]=\"resolvedDisabled()\" (click)=\"setGroupLogic(group, 'OR')\">OR</button>\r\n </div>\r\n\r\n <div class=\"qb-actions\">\r\n <button type=\"button\" class=\"qb-btn qb-btn-add\" title=\"Th\u00EAm\" aria-label=\"Th\u00EAm \u0111i\u1EC1u ki\u1EC7n ho\u1EB7c nh\u00F3m\" [disabled]=\"resolvedDisabled()\" (click)=\"toggleDropdown(group, $event)\">+</button>\r\n @if (group.open) {\r\n <div class=\"qb-dropdown\" (click)=\"$event.stopPropagation()\">\r\n <button type=\"button\" (click)=\"addRule(group)\">+ \u0110i\u1EC1u ki\u1EC7n</button>\r\n <button type=\"button\" (click)=\"addGroup(group)\">+ Nh\u00F3m</button>\r\n </div>\r\n }\r\n @if (!isRoot) {\r\n <button type=\"button\" class=\"qb-btn qb-btn-remove\" title=\"Xo\u00E1 nh\u00F3m\" aria-label=\"Xo\u00E1 nh\u00F3m\" [disabled]=\"resolvedDisabled()\" (click)=\"removeNode(parent, index)\">\u2715</button>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"qb-body\">\r\n @for (node of group.children; track node.id; let i = $index) {\r\n <div class=\"qb-treenode\" [class.is-group]=\"isGroup(node)\" [class.is-rule]=\"!isGroup(node)\">\r\n @if (isGroup(node)) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"groupTpl\"\r\n [ngTemplateOutletContext]=\"{ $implicit: node, isRoot: false, parent: group, index: i }\"\r\n ></ng-container>\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"ruleTpl\" [ngTemplateOutletContext]=\"{ $implicit: node, parent: group, index: i }\"></ng-container>\r\n }\r\n </div>\r\n } @empty {\r\n <div class=\"qb-empty\">Ch\u01B0a c\u00F3 \u0111i\u1EC1u ki\u1EC7n</div>\r\n }\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Single rule node: field \u2192 operator \u2192 value -->\r\n<ng-template #ruleTpl let-rule let-parent=\"parent\" let-index=\"index\">\r\n <div class=\"qb-rule\">\r\n <sd-select\r\n class=\"qb-field\"\r\n [items]=\"resolvedFields()\"\r\n valueField=\"key\"\r\n displayField=\"label\"\r\n placeholder=\"Ch\u1ECDn tr\u01B0\u1EDDng\"\r\n size=\"sm\"\r\n [model]=\"rule.field\"\r\n (modelChange)=\"setField(rule, $event)\"\r\n [disabled]=\"resolvedDisabled()\"\r\n [clearable]=\"false\"\r\n hideInlineError\r\n [autoId]=\"autoIdFor('field-' + index)\"\r\n >\r\n <!-- Option trong dropdown: icon th\u1EC3 hi\u1EC7n type + label. -->\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ fieldIcon(item) }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.label }}</span>\r\n </span>\r\n </ng-template>\r\n <!-- Gi\u00E1 tr\u1ECB \u0111\u00E3 ch\u1ECDn \u1EDF trigger: icon m\u1EB7c \u0111\u1ECBnh theo type khi field ch\u01B0a c\u00F3 icon ri\u00EAng. -->\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ fieldIcon(item) }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.label }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n\r\n @if (rule.field) {\r\n <div class=\"qb-divider\"></div>\r\n\r\n @if (showOperatorSelector(rule)) {\r\n <sd-operator\r\n class=\"qb-op\"\r\n [operators]=\"allowedOperators(rule)\"\r\n [model]=\"rule.operator\"\r\n (modelChange)=\"setOperator(rule, $event)\"\r\n [disabled]=\"resolvedDisabled()\"\r\n [autoId]=\"autoIdFor('op-' + index)\"\r\n ></sd-operator>\r\n }\r\n\r\n @if (rule.operator && !isNoData(rule.operator)) {\r\n <div class=\"qb-divider\"></div>\r\n\r\n @if (showValueSourceSelector(rule)) {\r\n <sd-select\r\n class=\"qb-value-source\"\r\n [items]=\"valueSourceOptions\"\r\n valueField=\"value\"\r\n displayField=\"display\"\r\n size=\"sm\"\r\n [model]=\"valueSourceOf(rule)\"\r\n (modelChange)=\"setValueSource(rule, $event)\"\r\n [disabled]=\"resolvedDisabled()\"\r\n [clearable]=\"false\"\r\n hideInlineError\r\n [autoId]=\"autoIdFor('valuesource-' + index)\"\r\n >\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.display }}</span>\r\n </span>\r\n </ng-template>\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item?.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.display }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n <div class=\"qb-divider\"></div>\r\n }\r\n\r\n @if (isFieldSource(rule)) {\r\n <sd-select\r\n class=\"qb-val qb-compare-field\"\r\n [items]=\"compareFields(rule)\"\r\n valueField=\"key\"\r\n displayField=\"label\"\r\n placeholder=\"Ch\u1ECDn tr\u01B0\u1EDDng\"\r\n size=\"sm\"\r\n [model]=\"rule.compareField\"\r\n (modelChange)=\"setCompareField(rule, $event)\"\r\n [disabled]=\"resolvedDisabled()\"\r\n [clearable]=\"false\"\r\n hideInlineError\r\n [autoId]=\"autoIdFor('compare-field-' + index)\"\r\n >\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ fieldIcon(item) }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.label }}</span>\r\n </span>\r\n </ng-template>\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ fieldIcon(item) }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.label }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n } @else if (rule.operator === 'BETWEEN') {\r\n <div class=\"qb-between\">\r\n @switch (fieldOf(rule)?.type) {\r\n @case ('number') {\r\n <sd-input-number class=\"qb-val\" placeholder=\"T\u1EEB\" size=\"sm\" [model]=\"rule.value?.from\" (modelChange)=\"setBetweenFrom(rule, $event)\" [min]=\"fieldOf(rule)?.min\" [max]=\"fieldOf(rule)?.max\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('from-' + index)\"></sd-input-number>\r\n <span class=\"qb-dash\">\u2014</span>\r\n <sd-input-number class=\"qb-val\" placeholder=\"\u0110\u1EBFn\" size=\"sm\" [model]=\"rule.value?.to\" (modelChange)=\"setBetweenTo(rule, $event)\" [min]=\"fieldOf(rule)?.min\" [max]=\"fieldOf(rule)?.max\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('to-' + index)\"></sd-input-number>\r\n }\r\n @case ('date') {\r\n <sd-date class=\"qb-val qb-date-val\" size=\"sm\" [model]=\"rule.value?.from\" (modelChange)=\"setBetweenFrom(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('from-' + index)\"></sd-date>\r\n <span class=\"qb-dash\">\u2014</span>\r\n <sd-date class=\"qb-val qb-date-val\" size=\"sm\" [model]=\"rule.value?.to\" (modelChange)=\"setBetweenTo(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('to-' + index)\"></sd-date>\r\n }\r\n @case ('datetime') {\r\n <sd-datetime class=\"qb-val\" size=\"sm\" [model]=\"rule.value?.from\" (modelChange)=\"setBetweenFrom(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('from-' + index)\"></sd-datetime>\r\n <span class=\"qb-dash\">\u2014</span>\r\n <sd-datetime class=\"qb-val\" size=\"sm\" [model]=\"rule.value?.to\" (modelChange)=\"setBetweenTo(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('to-' + index)\"></sd-datetime>\r\n }\r\n }\r\n </div>\r\n } @else {\r\n @switch (fieldOf(rule)?.type) {\r\n @case ('string') {\r\n <sd-input class=\"qb-val\" placeholder=\"Gi\u00E1 tr\u1ECB\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-input>\r\n }\r\n @case ('number') {\r\n <sd-input-number class=\"qb-val\" placeholder=\"Gi\u00E1 tr\u1ECB\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [min]=\"fieldOf(rule)?.min\" [max]=\"fieldOf(rule)?.max\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-input-number>\r\n }\r\n @case ('boolean') {\r\n <sd-select class=\"qb-val\" [items]=\"booleanItems(fieldOf(rule)!)\" valueField=\"value\" displayField=\"display\" placeholder=\"Gi\u00E1 tr\u1ECB\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-select>\r\n }\r\n @case ('date') {\r\n @let _dateMode = dateMode(rule);\r\n <sd-select class=\"qb-date-mode\" [items]=\"dateModes\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"_dateMode\" (modelChange)=\"setDateMode(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('datemode-' + index)\">\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.display }}</span>\r\n </span>\r\n </ng-template>\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item?.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.display }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n @switch (_dateMode) {\r\n @case ('absolute') {\r\n <sd-date class=\"qb-val qb-date-val\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-date>\r\n }\r\n @case ('relative') {\r\n <sd-input-number class=\"qb-rel-amount\" type=\"positive\" [precision]=\"0\" size=\"sm\" [model]=\"relativeAmount(rule)\" (modelChange)=\"setRelativeAmount(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('rel-amount-' + index)\"></sd-input-number>\r\n <sd-select class=\"qb-rel-unit\" [items]=\"relativeUnitOptions\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"relativeUnitDirValue(rule)\" (modelChange)=\"setRelativeUnitDir(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('rel-unit-' + index)\"></sd-select>\r\n }\r\n }\r\n }\r\n @case ('datetime') {\r\n @let _dtMode = dateMode(rule);\r\n <sd-select class=\"qb-date-mode\" [items]=\"dateModes\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"_dtMode\" (modelChange)=\"setDateMode(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('datemode-' + index)\">\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.display }}</span>\r\n </span>\r\n </ng-template>\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item?.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.display }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n @switch (_dtMode) {\r\n @case ('absolute') {\r\n <sd-datetime class=\"qb-val\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-datetime>\r\n }\r\n @case ('relative') {\r\n <sd-input-number class=\"qb-rel-amount\" type=\"positive\" [precision]=\"0\" size=\"sm\" [model]=\"relativeAmount(rule)\" (modelChange)=\"setRelativeAmount(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('rel-amount-' + index)\"></sd-input-number>\r\n <sd-select class=\"qb-rel-unit\" [items]=\"relativeUnitOptions\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"relativeUnitDirValue(rule)\" (modelChange)=\"setRelativeUnitDir(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('rel-unit-' + index)\"></sd-select>\r\n }\r\n }\r\n }\r\n @case ('values') {\r\n <sd-select class=\"qb-val\" [items]=\"fieldOf(rule)!.values || []\" valueField=\"value\" displayField=\"display\" [multiple]=\"isMulti(rule.operator)\" placeholder=\"Gi\u00E1 tr\u1ECB\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-select>\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n <button type=\"button\" class=\"qb-btn qb-btn-remove-rule\" title=\"Xo\u00E1 \u0111i\u1EC1u ki\u1EC7n\" aria-label=\"Xo\u00E1 \u0111i\u1EC1u ki\u1EC7n\" [disabled]=\"resolvedDisabled()\" (click)=\"removeNode(parent, index)\">\u2715</button>\r\n </div>\r\n</ng-template>\r\n", styles: [":host{display:block;font-size:14px;color:var(--sd-text, #333)}.qb-view{display:block;width:100%;min-height:38px;padding:8px 12px;border:1px solid #d0d5dd;border-radius:6px;background:var(--sd-disabled-bg, #f6f7f9);color:var(--sd-text, #333);font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:13px;line-height:1.7;cursor:default;-webkit-user-select:text;user-select:text;white-space:pre-wrap;word-break:break-word}.qb-view-empty{color:#98a2b3}.qb-tok{white-space:pre}.qb-tok.qb-tok-field{color:var(--sd-text, #1d2939);font-weight:600}.qb-tok.qb-tok-op{color:var(--sd-primary, #2a66f4);font-weight:600}.qb-tok.qb-tok-value{color:var(--sd-success, #1a7f37)}.qb-tok.qb-tok-logic{color:#98a2b3;font-weight:700;text-transform:uppercase}.qb-tok.qb-tok-paren{color:#667085}.qb-container{padding:16px;background:#fff;border:1px solid #e0e0e0;border-radius:6px}.qb-container.is-disabled{opacity:.7;pointer-events:none}.qb-header{display:flex;align-items:center;gap:8px;margin-bottom:12px;position:relative;z-index:1}.qb-header.is-open{z-index:1000}.qb-logic-switch{display:inline-flex;border:1px solid #e0e0e0;border-radius:4px;overflow:hidden;height:30px}.qb-logic-switch button{border:none;background:transparent;padding:0 14px;font-weight:600;font-size:12px;cursor:pointer;color:#667085;height:100%}.qb-logic-switch button.active{background:var(--sd-primary, #2a66f4);color:#fff}.qb-logic-switch button:hover:not(.active):not([disabled]){background:var(--sd-primary-light, #eaf1ff);color:var(--sd-primary-dark, #1c4ad9)}.qb-logic-switch button[disabled]{cursor:default}.qb-actions{position:relative;display:flex;align-items:center;gap:4px}.qb-btn{background:transparent;border:none;cursor:pointer;font-size:16px;color:#667085;width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;border-radius:4px}.qb-btn:hover:not([disabled]){background:var(--sd-primary-light, #eaf1ff);color:var(--sd-primary, #2a66f4)}.qb-btn[disabled]{cursor:default;color:#cbd2dc}.qb-btn-remove:hover:not([disabled]),.qb-btn-remove-rule:hover:not([disabled]){background:#fee4e2;color:#d92d20}.qb-btn-remove-rule{margin-left:auto}.qb-dropdown{position:absolute;top:100%;left:0;margin-top:4px;background:#fff;border:1px solid #e0e0e0;box-shadow:0 4px 12px #1018281f;border-radius:6px;min-width:150px;z-index:100;overflow:hidden}.qb-dropdown button{display:block;width:100%;text-align:left;background:none;border:none;padding:9px 14px;cursor:pointer;font-size:13px;color:#344054}.qb-dropdown button:hover{background:var(--sd-primary-light, #eaf1ff);color:var(--sd-primary, #2a66f4)}.qb-body{padding-left:24px}.qb-treenode{position:relative;padding-left:22px;margin-bottom:12px}.qb-treenode:last-child{margin-bottom:0}.qb-treenode:before{content:\"\";position:absolute;left:0;top:-12px;bottom:0;border-left:1px dashed #d0d5dd}.qb-treenode:after{content:\"\";position:absolute;left:0;top:50%;width:18px;border-top:1px dashed #d0d5dd}.qb-treenode:last-child:before{bottom:auto;height:calc(50% + 12px)}.qb-empty{color:#98a2b3;font-style:italic;font-size:13px;padding:4px 0}.qb-rule{display:flex;align-items:center;gap:8px;background:#fafbfc;border:1px solid #e0e0e0;border-radius:6px;padding:6px 10px}.qb-rule:hover{border-color:#c2c8d0}.qb-field{min-width:170px}.qb-val{min-width:140px}.qb-value-source{min-width:132px}.qb-compare-field{min-width:170px}.qb-date-val{min-width:0;width:132px;flex:0 0 auto}::ng-deep .qb-opt{display:flex;align-items:center;gap:6px;min-width:0}::ng-deep .qb-opt .qb-opt-icon.mat-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;margin:0;font-size:18px;width:18px;height:18px;line-height:1;color:#667085}::ng-deep .qb-opt .qb-opt-label{min-width:0}.qb-between{display:flex;align-items:center;gap:6px}.qb-dash{color:#98a2b3}.qb-divider{width:1px;align-self:stretch;background:#e0e0e0}.qb-treenode.is-group>.qb-group{border:1px solid #e0e0e0;border-left:2px solid var(--sd-primary, #2a66f4);border-radius:6px;padding:12px;background:#fff}.qb-date-mode{min-width:160px}.qb-rel-amount{width:72px}.qb-rel-unit{min-width:110px}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: SdOperator, selector: "sd-operator", inputs: ["model", "operators", "disabled", "autoId"], outputs: ["modelChange"] }, { 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: 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: 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: "directive", type: SdItemDefDefDirective, selector: "[sdItemDef]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
881
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SdQueryBuilder, isStandalone: true, selector: "sd-query-builder", inputs: { option: { classPropertyName: "option", publicName: "option", isSignal: true, isRequired: false, transformFunction: null }, fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, comparisonMode: { classPropertyName: "comparisonMode", publicName: "comparisonMode", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, autoId: { classPropertyName: "autoId", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, rootLogic: { classPropertyName: "rootLogic", publicName: "rootLogic", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", filters: "filtersChange", rootLogic: "rootLogicChange" }, ngImport: i0, template: "@if (isView()) {\r\n <div class=\"qb-view\" [attr.data-autoid]=\"autoIdFor('view')\" aria-readonly=\"true\">\r\n @if (tokens().length) {\r\n @for (t of tokens(); track $index) {\r\n <span class=\"qb-tok qb-tok-{{ t.kind }}\">{{ t.text }}</span>\r\n }\r\n } @else {\r\n <span class=\"qb-view-empty\">\u2014</span>\r\n }\r\n </div>\r\n} @else {\r\n <div class=\"qb-container\" [class.is-disabled]=\"resolvedDisabled()\" (click)=\"closeAllDropdowns()\">\n <ng-container [ngTemplateOutlet]=\"groupTpl\" [ngTemplateOutletContext]=\"{ $implicit: tree(), isRoot: true }\"></ng-container>\r\n </div>\r\n}\r\n\r\n<!-- Recursive group node -->\r\n<ng-template #groupTpl let-group let-isRoot=\"isRoot\" let-parent=\"parent\" let-index=\"index\">\r\n <div class=\"qb-group\" [class.is-root]=\"isRoot\">\r\n <div class=\"qb-header\" [class.is-open]=\"group.open\">\r\n <div class=\"qb-logic-switch\">\r\n <button type=\"button\" [class.active]=\"group.logic === 'AND'\" [disabled]=\"resolvedDisabled()\" (click)=\"setGroupLogic(group, 'AND')\">AND</button>\n <button type=\"button\" [class.active]=\"group.logic === 'OR'\" [disabled]=\"resolvedDisabled()\" (click)=\"setGroupLogic(group, 'OR')\">OR</button>\n </div>\r\n\r\n <div class=\"qb-actions\">\r\n <button type=\"button\" class=\"qb-btn qb-btn-add\" title=\"Th\u00EAm\" aria-label=\"Th\u00EAm \u0111i\u1EC1u ki\u1EC7n ho\u1EB7c nh\u00F3m\" [disabled]=\"resolvedDisabled()\" (click)=\"toggleDropdown(group, $event)\">+</button>\r\n @if (group.open) {\r\n <div class=\"qb-dropdown\" (click)=\"$event.stopPropagation()\">\r\n <button type=\"button\" (click)=\"addRule(group)\">+ \u0110i\u1EC1u ki\u1EC7n</button>\r\n <button type=\"button\" (click)=\"addGroup(group)\">+ Nh\u00F3m</button>\r\n </div>\r\n }\r\n @if (!isRoot) {\r\n <button type=\"button\" class=\"qb-btn qb-btn-remove\" title=\"Xo\u00E1 nh\u00F3m\" aria-label=\"Xo\u00E1 nh\u00F3m\" [disabled]=\"resolvedDisabled()\" (click)=\"removeNode(parent, index)\">\u2715</button>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"qb-body\">\r\n @for (node of group.children; track node.id; let i = $index) {\r\n <div class=\"qb-treenode\" [class.is-group]=\"isGroup(node)\" [class.is-rule]=\"!isGroup(node)\">\r\n @if (isGroup(node)) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"groupTpl\"\r\n [ngTemplateOutletContext]=\"{ $implicit: node, isRoot: false, parent: group, index: i }\"\r\n ></ng-container>\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"ruleTpl\" [ngTemplateOutletContext]=\"{ $implicit: node, parent: group, index: i }\"></ng-container>\r\n }\r\n </div>\r\n } @empty {\r\n <div class=\"qb-empty\">Ch\u01B0a c\u00F3 \u0111i\u1EC1u ki\u1EC7n</div>\r\n }\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Single rule node: field \u2192 operator \u2192 value -->\r\n<ng-template #ruleTpl let-rule let-parent=\"parent\" let-index=\"index\">\r\n <div class=\"qb-rule\">\r\n <sd-select\r\n class=\"qb-field\"\r\n [items]=\"resolvedFields()\"\n valueField=\"key\"\r\n displayField=\"label\"\r\n placeholder=\"Ch\u1ECDn tr\u01B0\u1EDDng\"\r\n size=\"sm\"\r\n [model]=\"rule.field\"\r\n (modelChange)=\"setField(rule, $event)\"\r\n [disabled]=\"resolvedDisabled()\"\r\n [clearable]=\"false\"\r\n hideInlineError\r\n [autoId]=\"autoIdFor('field-' + index)\"\r\n >\r\n <!-- Option trong dropdown: icon th\u1EC3 hi\u1EC7n type + label. -->\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ fieldIcon(item) }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.label }}</span>\r\n </span>\r\n </ng-template>\r\n <!-- Gi\u00E1 tr\u1ECB \u0111\u00E3 ch\u1ECDn \u1EDF trigger: icon m\u1EB7c \u0111\u1ECBnh theo type khi field ch\u01B0a c\u00F3 icon ri\u00EAng. -->\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ fieldIcon(item) }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.label }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n\r\n @if (rule.field) {\r\n <div class=\"qb-divider\"></div>\r\n\r\n @if (showOperatorSelector(rule)) {\r\n <sd-operator\r\n class=\"qb-op\"\r\n [operators]=\"allowedOperators(rule)\"\r\n [model]=\"rule.operator\"\r\n (modelChange)=\"setOperator(rule, $event)\"\r\n [disabled]=\"resolvedDisabled()\"\r\n [autoId]=\"autoIdFor('op-' + index)\"\r\n ></sd-operator>\r\n }\r\n\r\n @if (rule.operator && !isNoData(rule.operator)) {\r\n <div class=\"qb-divider\"></div>\r\n\r\n @if (showValueSourceSelector(rule)) {\r\n <sd-select\r\n class=\"qb-value-source\"\r\n [items]=\"valueSourceOptions\"\r\n valueField=\"value\"\r\n displayField=\"display\"\r\n size=\"sm\"\r\n [model]=\"valueSourceOf(rule)\"\r\n (modelChange)=\"setValueSource(rule, $event)\"\r\n [disabled]=\"resolvedDisabled()\"\r\n [clearable]=\"false\"\r\n hideInlineError\r\n [autoId]=\"autoIdFor('valuesource-' + index)\"\r\n >\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.display }}</span>\r\n </span>\r\n </ng-template>\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item?.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.display }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n <div class=\"qb-divider\"></div>\r\n }\r\n\r\n @if (isFieldSource(rule)) {\r\n <sd-select\r\n class=\"qb-val qb-compare-field\"\r\n [items]=\"compareFields(rule)\"\r\n valueField=\"key\"\r\n displayField=\"label\"\r\n placeholder=\"Ch\u1ECDn tr\u01B0\u1EDDng\"\r\n size=\"sm\"\r\n [model]=\"rule.compareField\"\r\n (modelChange)=\"setCompareField(rule, $event)\"\r\n [disabled]=\"resolvedDisabled()\"\r\n [clearable]=\"false\"\r\n hideInlineError\r\n [autoId]=\"autoIdFor('compare-field-' + index)\"\r\n >\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ fieldIcon(item) }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.label }}</span>\r\n </span>\r\n </ng-template>\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ fieldIcon(item) }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.label }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n } @else if (rule.operator === 'BETWEEN') {\r\n <div class=\"qb-between\">\r\n @switch (fieldOf(rule)?.type) {\r\n @case ('number') {\r\n <sd-input-number class=\"qb-val\" placeholder=\"T\u1EEB\" size=\"sm\" [model]=\"rule.value?.from\" (modelChange)=\"setBetweenFrom(rule, $event)\" [min]=\"fieldOf(rule)?.min\" [max]=\"fieldOf(rule)?.max\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('from-' + index)\"></sd-input-number>\r\n <span class=\"qb-dash\">\u2014</span>\r\n <sd-input-number class=\"qb-val\" placeholder=\"\u0110\u1EBFn\" size=\"sm\" [model]=\"rule.value?.to\" (modelChange)=\"setBetweenTo(rule, $event)\" [min]=\"fieldOf(rule)?.min\" [max]=\"fieldOf(rule)?.max\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('to-' + index)\"></sd-input-number>\r\n }\r\n @case ('date') {\r\n <sd-date class=\"qb-val qb-date-val\" size=\"sm\" [model]=\"rule.value?.from\" (modelChange)=\"setBetweenFrom(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('from-' + index)\"></sd-date>\r\n <span class=\"qb-dash\">\u2014</span>\r\n <sd-date class=\"qb-val qb-date-val\" size=\"sm\" [model]=\"rule.value?.to\" (modelChange)=\"setBetweenTo(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('to-' + index)\"></sd-date>\r\n }\r\n @case ('datetime') {\r\n <sd-datetime class=\"qb-val\" size=\"sm\" [model]=\"rule.value?.from\" (modelChange)=\"setBetweenFrom(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('from-' + index)\"></sd-datetime>\r\n <span class=\"qb-dash\">\u2014</span>\r\n <sd-datetime class=\"qb-val\" size=\"sm\" [model]=\"rule.value?.to\" (modelChange)=\"setBetweenTo(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('to-' + index)\"></sd-datetime>\r\n }\r\n }\r\n </div>\r\n } @else {\r\n @switch (fieldOf(rule)?.type) {\r\n @case ('string') {\r\n <sd-input class=\"qb-val\" placeholder=\"Gi\u00E1 tr\u1ECB\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-input>\r\n }\r\n @case ('number') {\r\n <sd-input-number class=\"qb-val\" placeholder=\"Gi\u00E1 tr\u1ECB\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [min]=\"fieldOf(rule)?.min\" [max]=\"fieldOf(rule)?.max\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-input-number>\r\n }\r\n @case ('boolean') {\r\n <sd-select class=\"qb-val\" [items]=\"booleanItems(fieldOf(rule)!)\" valueField=\"value\" displayField=\"display\" placeholder=\"Gi\u00E1 tr\u1ECB\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-select>\r\n }\r\n @case ('date') {\r\n @let _dateMode = dateMode(rule);\r\n <sd-select class=\"qb-date-mode\" [items]=\"dateModes\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"_dateMode\" (modelChange)=\"setDateMode(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('datemode-' + index)\">\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.display }}</span>\r\n </span>\r\n </ng-template>\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item?.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.display }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n @switch (_dateMode) {\r\n @case ('absolute') {\r\n <sd-date class=\"qb-val qb-date-val\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-date>\r\n }\r\n @case ('relative') {\r\n <sd-input-number class=\"qb-rel-amount\" type=\"positive\" [precision]=\"0\" size=\"sm\" [model]=\"relativeAmount(rule)\" (modelChange)=\"setRelativeAmount(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('rel-amount-' + index)\"></sd-input-number>\r\n <sd-select class=\"qb-rel-unit\" [items]=\"relativeUnitOptions\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"relativeUnitDirValue(rule)\" (modelChange)=\"setRelativeUnitDir(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('rel-unit-' + index)\"></sd-select>\r\n }\r\n }\r\n }\r\n @case ('datetime') {\r\n @let _dtMode = dateMode(rule);\r\n <sd-select class=\"qb-date-mode\" [items]=\"dateModes\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"_dtMode\" (modelChange)=\"setDateMode(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('datemode-' + index)\">\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.display }}</span>\r\n </span>\r\n </ng-template>\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item?.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.display }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n @switch (_dtMode) {\r\n @case ('absolute') {\r\n <sd-datetime class=\"qb-val\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-datetime>\r\n }\r\n @case ('relative') {\r\n <sd-input-number class=\"qb-rel-amount\" type=\"positive\" [precision]=\"0\" size=\"sm\" [model]=\"relativeAmount(rule)\" (modelChange)=\"setRelativeAmount(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('rel-amount-' + index)\"></sd-input-number>\r\n <sd-select class=\"qb-rel-unit\" [items]=\"relativeUnitOptions\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"relativeUnitDirValue(rule)\" (modelChange)=\"setRelativeUnitDir(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('rel-unit-' + index)\"></sd-select>\r\n }\r\n }\r\n }\r\n @case ('values') {\r\n <sd-select class=\"qb-val\" [items]=\"fieldOf(rule)!.values || []\" valueField=\"value\" displayField=\"display\" [multiple]=\"isMulti(rule.operator)\" placeholder=\"Gi\u00E1 tr\u1ECB\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-select>\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n <button type=\"button\" class=\"qb-btn qb-btn-remove-rule\" title=\"Xo\u00E1 \u0111i\u1EC1u ki\u1EC7n\" aria-label=\"Xo\u00E1 \u0111i\u1EC1u ki\u1EC7n\" [disabled]=\"resolvedDisabled()\" (click)=\"removeNode(parent, index)\">\u2715</button>\r\n </div>\r\n</ng-template>\r\n", styles: [":host{display:block;font-size:14px;color:var(--sd-text, #333)}.qb-view{display:block;width:100%;min-height:38px;padding:8px 12px;border:1px solid #d0d5dd;border-radius:6px;background:var(--sd-disabled-bg, #f6f7f9);color:var(--sd-text, #333);font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:13px;line-height:1.7;cursor:default;-webkit-user-select:text;user-select:text;white-space:pre-wrap;word-break:break-word}.qb-view-empty{color:#98a2b3}.qb-tok{white-space:pre}.qb-tok.qb-tok-field{color:var(--sd-text, #1d2939);font-weight:600}.qb-tok.qb-tok-op{color:var(--sd-primary, #2a66f4);font-weight:600}.qb-tok.qb-tok-value{color:var(--sd-success, #1a7f37)}.qb-tok.qb-tok-logic{color:#98a2b3;font-weight:700;text-transform:uppercase}.qb-tok.qb-tok-paren{color:#667085}.qb-container{padding:16px;background:#fff;border:1px solid #e0e0e0;border-radius:6px}.qb-container.is-disabled{opacity:.7;pointer-events:none}.qb-header{display:flex;align-items:center;gap:8px;margin-bottom:12px;position:relative;z-index:1}.qb-header.is-open{z-index:1000}.qb-logic-switch{display:inline-flex;border:1px solid #e0e0e0;border-radius:4px;overflow:hidden;height:30px}.qb-logic-switch button{border:none;background:transparent;padding:0 14px;font-weight:600;font-size:12px;cursor:pointer;color:#667085;height:100%}.qb-logic-switch button.active{background:var(--sd-primary, #2a66f4);color:#fff}.qb-logic-switch button:hover:not(.active):not([disabled]){background:var(--sd-primary-light, #eaf1ff);color:var(--sd-primary-dark, #1c4ad9)}.qb-logic-switch button[disabled]{cursor:default}.qb-actions{position:relative;display:flex;align-items:center;gap:4px}.qb-btn{background:transparent;border:none;cursor:pointer;font-size:16px;color:#667085;width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;border-radius:4px}.qb-btn:hover:not([disabled]){background:var(--sd-primary-light, #eaf1ff);color:var(--sd-primary, #2a66f4)}.qb-btn[disabled]{cursor:default;color:#cbd2dc}.qb-btn-remove:hover:not([disabled]),.qb-btn-remove-rule:hover:not([disabled]){background:#fee4e2;color:#d92d20}.qb-btn-remove-rule{margin-left:auto}.qb-dropdown{position:absolute;top:100%;left:0;margin-top:4px;background:#fff;border:1px solid #e0e0e0;box-shadow:0 4px 12px #1018281f;border-radius:6px;min-width:150px;z-index:100;overflow:hidden}.qb-dropdown button{display:block;width:100%;text-align:left;background:none;border:none;padding:9px 14px;cursor:pointer;font-size:13px;color:#344054}.qb-dropdown button:hover{background:var(--sd-primary-light, #eaf1ff);color:var(--sd-primary, #2a66f4)}.qb-body{padding-left:24px}.qb-treenode{position:relative;padding-left:22px;margin-bottom:12px}.qb-treenode:last-child{margin-bottom:0}.qb-treenode:before{content:\"\";position:absolute;left:0;top:-12px;bottom:0;border-left:1px dashed #d0d5dd}.qb-treenode:after{content:\"\";position:absolute;left:0;top:50%;width:18px;border-top:1px dashed #d0d5dd}.qb-treenode:last-child:before{bottom:auto;height:calc(50% + 12px)}.qb-empty{color:#98a2b3;font-style:italic;font-size:13px;padding:4px 0}.qb-rule{display:flex;align-items:center;gap:8px;background:#fafbfc;border:1px solid #e0e0e0;border-radius:6px;padding:6px 10px}.qb-rule:hover{border-color:#c2c8d0}.qb-field{min-width:170px}.qb-val{min-width:140px}.qb-value-source{min-width:132px}.qb-compare-field{min-width:170px}.qb-date-val{min-width:0;width:132px;flex:0 0 auto}::ng-deep .qb-opt{display:flex;align-items:center;gap:6px;min-width:0}::ng-deep .qb-opt .qb-opt-icon.mat-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;margin:0;font-size:18px;width:18px;height:18px;line-height:1;color:#667085}::ng-deep .qb-opt .qb-opt-label{min-width:0}.qb-between{display:flex;align-items:center;gap:6px}.qb-dash{color:#98a2b3}.qb-divider{width:1px;align-self:stretch;background:#e0e0e0}.qb-treenode.is-group>.qb-group{border:1px solid #e0e0e0;border-left:2px solid var(--sd-primary, #2a66f4);border-radius:6px;padding:12px;background:#fff}.qb-date-mode{min-width:160px}.qb-rel-amount{width:72px}.qb-rel-unit{min-width:110px}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: SdOperator, selector: "sd-operator", inputs: ["model", "operators", "disabled", "autoId"], outputs: ["modelChange"] }, { 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: 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: 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: "directive", type: SdItemDefDefDirective, selector: "[sdItemDef]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
882
882
|
}
|
|
883
883
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdQueryBuilder, decorators: [{
|
|
884
884
|
type: Component,
|
|
885
|
-
args: [{ selector: 'sd-query-builder', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet, MatIconModule, SdOperator, SdSelect, SdInput, SdInputNumber, SdDate, SdDatetime, SdItemDefDefDirective], template: "@if (isView()) {\r\n <div class=\"qb-view\" [attr.data-autoid]=\"autoIdFor('view')\" aria-readonly=\"true\">\r\n @if (tokens().length) {\r\n @for (t of tokens(); track $index) {\r\n <span class=\"qb-tok qb-tok-{{ t.kind }}\">{{ t.text }}</span>\r\n }\r\n } @else {\r\n <span class=\"qb-view-empty\">\u2014</span>\r\n }\r\n </div>\r\n} @else {\r\n <div class=\"qb-container\" [class.is-disabled]=\"resolvedDisabled()\" (click)=\"closeAllDropdowns()\">\r\n <ng-container [ngTemplateOutlet]=\"groupTpl\" [ngTemplateOutletContext]=\"{ $implicit: tree(), isRoot: true }\"></ng-container>\r\n </div>\r\n}\r\n\r\n<!-- Recursive group node -->\r\n<ng-template #groupTpl let-group let-isRoot=\"isRoot\" let-parent=\"parent\" let-index=\"index\">\r\n <div class=\"qb-group\" [class.is-root]=\"isRoot\">\r\n <div class=\"qb-header\" [class.is-open]=\"group.open\">\r\n <div class=\"qb-logic-switch\">\r\n <button type=\"button\" [class.active]=\"group.logic === 'AND'\" [disabled]=\"resolvedDisabled()\" (click)=\"setGroupLogic(group, 'AND')\">AND</button>\r\n <button type=\"button\" [class.active]=\"group.logic === 'OR'\" [disabled]=\"resolvedDisabled()\" (click)=\"setGroupLogic(group, 'OR')\">OR</button>\r\n </div>\r\n\r\n <div class=\"qb-actions\">\r\n <button type=\"button\" class=\"qb-btn qb-btn-add\" title=\"Th\u00EAm\" aria-label=\"Th\u00EAm \u0111i\u1EC1u ki\u1EC7n ho\u1EB7c nh\u00F3m\" [disabled]=\"resolvedDisabled()\" (click)=\"toggleDropdown(group, $event)\">+</button>\r\n @if (group.open) {\r\n <div class=\"qb-dropdown\" (click)=\"$event.stopPropagation()\">\r\n <button type=\"button\" (click)=\"addRule(group)\">+ \u0110i\u1EC1u ki\u1EC7n</button>\r\n <button type=\"button\" (click)=\"addGroup(group)\">+ Nh\u00F3m</button>\r\n </div>\r\n }\r\n @if (!isRoot) {\r\n <button type=\"button\" class=\"qb-btn qb-btn-remove\" title=\"Xo\u00E1 nh\u00F3m\" aria-label=\"Xo\u00E1 nh\u00F3m\" [disabled]=\"resolvedDisabled()\" (click)=\"removeNode(parent, index)\">\u2715</button>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"qb-body\">\r\n @for (node of group.children; track node.id; let i = $index) {\r\n <div class=\"qb-treenode\" [class.is-group]=\"isGroup(node)\" [class.is-rule]=\"!isGroup(node)\">\r\n @if (isGroup(node)) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"groupTpl\"\r\n [ngTemplateOutletContext]=\"{ $implicit: node, isRoot: false, parent: group, index: i }\"\r\n ></ng-container>\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"ruleTpl\" [ngTemplateOutletContext]=\"{ $implicit: node, parent: group, index: i }\"></ng-container>\r\n }\r\n </div>\r\n } @empty {\r\n <div class=\"qb-empty\">Ch\u01B0a c\u00F3 \u0111i\u1EC1u ki\u1EC7n</div>\r\n }\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Single rule node: field \u2192 operator \u2192 value -->\r\n<ng-template #ruleTpl let-rule let-parent=\"parent\" let-index=\"index\">\r\n <div class=\"qb-rule\">\r\n <sd-select\r\n class=\"qb-field\"\r\n [items]=\"resolvedFields()\"\r\n valueField=\"key\"\r\n displayField=\"label\"\r\n placeholder=\"Ch\u1ECDn tr\u01B0\u1EDDng\"\r\n size=\"sm\"\r\n [model]=\"rule.field\"\r\n (modelChange)=\"setField(rule, $event)\"\r\n [disabled]=\"resolvedDisabled()\"\r\n [clearable]=\"false\"\r\n hideInlineError\r\n [autoId]=\"autoIdFor('field-' + index)\"\r\n >\r\n <!-- Option trong dropdown: icon th\u1EC3 hi\u1EC7n type + label. -->\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ fieldIcon(item) }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.label }}</span>\r\n </span>\r\n </ng-template>\r\n <!-- Gi\u00E1 tr\u1ECB \u0111\u00E3 ch\u1ECDn \u1EDF trigger: icon m\u1EB7c \u0111\u1ECBnh theo type khi field ch\u01B0a c\u00F3 icon ri\u00EAng. -->\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ fieldIcon(item) }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.label }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n\r\n @if (rule.field) {\r\n <div class=\"qb-divider\"></div>\r\n\r\n @if (showOperatorSelector(rule)) {\r\n <sd-operator\r\n class=\"qb-op\"\r\n [operators]=\"allowedOperators(rule)\"\r\n [model]=\"rule.operator\"\r\n (modelChange)=\"setOperator(rule, $event)\"\r\n [disabled]=\"resolvedDisabled()\"\r\n [autoId]=\"autoIdFor('op-' + index)\"\r\n ></sd-operator>\r\n }\r\n\r\n @if (rule.operator && !isNoData(rule.operator)) {\r\n <div class=\"qb-divider\"></div>\r\n\r\n @if (showValueSourceSelector(rule)) {\r\n <sd-select\r\n class=\"qb-value-source\"\r\n [items]=\"valueSourceOptions\"\r\n valueField=\"value\"\r\n displayField=\"display\"\r\n size=\"sm\"\r\n [model]=\"valueSourceOf(rule)\"\r\n (modelChange)=\"setValueSource(rule, $event)\"\r\n [disabled]=\"resolvedDisabled()\"\r\n [clearable]=\"false\"\r\n hideInlineError\r\n [autoId]=\"autoIdFor('valuesource-' + index)\"\r\n >\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.display }}</span>\r\n </span>\r\n </ng-template>\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item?.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.display }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n <div class=\"qb-divider\"></div>\r\n }\r\n\r\n @if (isFieldSource(rule)) {\r\n <sd-select\r\n class=\"qb-val qb-compare-field\"\r\n [items]=\"compareFields(rule)\"\r\n valueField=\"key\"\r\n displayField=\"label\"\r\n placeholder=\"Ch\u1ECDn tr\u01B0\u1EDDng\"\r\n size=\"sm\"\r\n [model]=\"rule.compareField\"\r\n (modelChange)=\"setCompareField(rule, $event)\"\r\n [disabled]=\"resolvedDisabled()\"\r\n [clearable]=\"false\"\r\n hideInlineError\r\n [autoId]=\"autoIdFor('compare-field-' + index)\"\r\n >\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ fieldIcon(item) }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.label }}</span>\r\n </span>\r\n </ng-template>\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ fieldIcon(item) }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.label }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n } @else if (rule.operator === 'BETWEEN') {\r\n <div class=\"qb-between\">\r\n @switch (fieldOf(rule)?.type) {\r\n @case ('number') {\r\n <sd-input-number class=\"qb-val\" placeholder=\"T\u1EEB\" size=\"sm\" [model]=\"rule.value?.from\" (modelChange)=\"setBetweenFrom(rule, $event)\" [min]=\"fieldOf(rule)?.min\" [max]=\"fieldOf(rule)?.max\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('from-' + index)\"></sd-input-number>\r\n <span class=\"qb-dash\">\u2014</span>\r\n <sd-input-number class=\"qb-val\" placeholder=\"\u0110\u1EBFn\" size=\"sm\" [model]=\"rule.value?.to\" (modelChange)=\"setBetweenTo(rule, $event)\" [min]=\"fieldOf(rule)?.min\" [max]=\"fieldOf(rule)?.max\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('to-' + index)\"></sd-input-number>\r\n }\r\n @case ('date') {\r\n <sd-date class=\"qb-val qb-date-val\" size=\"sm\" [model]=\"rule.value?.from\" (modelChange)=\"setBetweenFrom(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('from-' + index)\"></sd-date>\r\n <span class=\"qb-dash\">\u2014</span>\r\n <sd-date class=\"qb-val qb-date-val\" size=\"sm\" [model]=\"rule.value?.to\" (modelChange)=\"setBetweenTo(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('to-' + index)\"></sd-date>\r\n }\r\n @case ('datetime') {\r\n <sd-datetime class=\"qb-val\" size=\"sm\" [model]=\"rule.value?.from\" (modelChange)=\"setBetweenFrom(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('from-' + index)\"></sd-datetime>\r\n <span class=\"qb-dash\">\u2014</span>\r\n <sd-datetime class=\"qb-val\" size=\"sm\" [model]=\"rule.value?.to\" (modelChange)=\"setBetweenTo(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('to-' + index)\"></sd-datetime>\r\n }\r\n }\r\n </div>\r\n } @else {\r\n @switch (fieldOf(rule)?.type) {\r\n @case ('string') {\r\n <sd-input class=\"qb-val\" placeholder=\"Gi\u00E1 tr\u1ECB\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-input>\r\n }\r\n @case ('number') {\r\n <sd-input-number class=\"qb-val\" placeholder=\"Gi\u00E1 tr\u1ECB\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [min]=\"fieldOf(rule)?.min\" [max]=\"fieldOf(rule)?.max\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-input-number>\r\n }\r\n @case ('boolean') {\r\n <sd-select class=\"qb-val\" [items]=\"booleanItems(fieldOf(rule)!)\" valueField=\"value\" displayField=\"display\" placeholder=\"Gi\u00E1 tr\u1ECB\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-select>\r\n }\r\n @case ('date') {\r\n @let _dateMode = dateMode(rule);\r\n <sd-select class=\"qb-date-mode\" [items]=\"dateModes\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"_dateMode\" (modelChange)=\"setDateMode(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('datemode-' + index)\">\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.display }}</span>\r\n </span>\r\n </ng-template>\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item?.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.display }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n @switch (_dateMode) {\r\n @case ('absolute') {\r\n <sd-date class=\"qb-val qb-date-val\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-date>\r\n }\r\n @case ('relative') {\r\n <sd-input-number class=\"qb-rel-amount\" type=\"positive\" [precision]=\"0\" size=\"sm\" [model]=\"relativeAmount(rule)\" (modelChange)=\"setRelativeAmount(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('rel-amount-' + index)\"></sd-input-number>\r\n <sd-select class=\"qb-rel-unit\" [items]=\"relativeUnitOptions\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"relativeUnitDirValue(rule)\" (modelChange)=\"setRelativeUnitDir(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('rel-unit-' + index)\"></sd-select>\r\n }\r\n }\r\n }\r\n @case ('datetime') {\r\n @let _dtMode = dateMode(rule);\r\n <sd-select class=\"qb-date-mode\" [items]=\"dateModes\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"_dtMode\" (modelChange)=\"setDateMode(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('datemode-' + index)\">\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.display }}</span>\r\n </span>\r\n </ng-template>\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item?.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.display }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n @switch (_dtMode) {\r\n @case ('absolute') {\r\n <sd-datetime class=\"qb-val\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-datetime>\r\n }\r\n @case ('relative') {\r\n <sd-input-number class=\"qb-rel-amount\" type=\"positive\" [precision]=\"0\" size=\"sm\" [model]=\"relativeAmount(rule)\" (modelChange)=\"setRelativeAmount(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('rel-amount-' + index)\"></sd-input-number>\r\n <sd-select class=\"qb-rel-unit\" [items]=\"relativeUnitOptions\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"relativeUnitDirValue(rule)\" (modelChange)=\"setRelativeUnitDir(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('rel-unit-' + index)\"></sd-select>\r\n }\r\n }\r\n }\r\n @case ('values') {\r\n <sd-select class=\"qb-val\" [items]=\"fieldOf(rule)!.values || []\" valueField=\"value\" displayField=\"display\" [multiple]=\"isMulti(rule.operator)\" placeholder=\"Gi\u00E1 tr\u1ECB\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-select>\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n <button type=\"button\" class=\"qb-btn qb-btn-remove-rule\" title=\"Xo\u00E1 \u0111i\u1EC1u ki\u1EC7n\" aria-label=\"Xo\u00E1 \u0111i\u1EC1u ki\u1EC7n\" [disabled]=\"resolvedDisabled()\" (click)=\"removeNode(parent, index)\">\u2715</button>\r\n </div>\r\n</ng-template>\r\n", styles: [":host{display:block;font-size:14px;color:var(--sd-text, #333)}.qb-view{display:block;width:100%;min-height:38px;padding:8px 12px;border:1px solid #d0d5dd;border-radius:6px;background:var(--sd-disabled-bg, #f6f7f9);color:var(--sd-text, #333);font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:13px;line-height:1.7;cursor:default;-webkit-user-select:text;user-select:text;white-space:pre-wrap;word-break:break-word}.qb-view-empty{color:#98a2b3}.qb-tok{white-space:pre}.qb-tok.qb-tok-field{color:var(--sd-text, #1d2939);font-weight:600}.qb-tok.qb-tok-op{color:var(--sd-primary, #2a66f4);font-weight:600}.qb-tok.qb-tok-value{color:var(--sd-success, #1a7f37)}.qb-tok.qb-tok-logic{color:#98a2b3;font-weight:700;text-transform:uppercase}.qb-tok.qb-tok-paren{color:#667085}.qb-container{padding:16px;background:#fff;border:1px solid #e0e0e0;border-radius:6px}.qb-container.is-disabled{opacity:.7;pointer-events:none}.qb-header{display:flex;align-items:center;gap:8px;margin-bottom:12px;position:relative;z-index:1}.qb-header.is-open{z-index:1000}.qb-logic-switch{display:inline-flex;border:1px solid #e0e0e0;border-radius:4px;overflow:hidden;height:30px}.qb-logic-switch button{border:none;background:transparent;padding:0 14px;font-weight:600;font-size:12px;cursor:pointer;color:#667085;height:100%}.qb-logic-switch button.active{background:var(--sd-primary, #2a66f4);color:#fff}.qb-logic-switch button:hover:not(.active):not([disabled]){background:var(--sd-primary-light, #eaf1ff);color:var(--sd-primary-dark, #1c4ad9)}.qb-logic-switch button[disabled]{cursor:default}.qb-actions{position:relative;display:flex;align-items:center;gap:4px}.qb-btn{background:transparent;border:none;cursor:pointer;font-size:16px;color:#667085;width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;border-radius:4px}.qb-btn:hover:not([disabled]){background:var(--sd-primary-light, #eaf1ff);color:var(--sd-primary, #2a66f4)}.qb-btn[disabled]{cursor:default;color:#cbd2dc}.qb-btn-remove:hover:not([disabled]),.qb-btn-remove-rule:hover:not([disabled]){background:#fee4e2;color:#d92d20}.qb-btn-remove-rule{margin-left:auto}.qb-dropdown{position:absolute;top:100%;left:0;margin-top:4px;background:#fff;border:1px solid #e0e0e0;box-shadow:0 4px 12px #1018281f;border-radius:6px;min-width:150px;z-index:100;overflow:hidden}.qb-dropdown button{display:block;width:100%;text-align:left;background:none;border:none;padding:9px 14px;cursor:pointer;font-size:13px;color:#344054}.qb-dropdown button:hover{background:var(--sd-primary-light, #eaf1ff);color:var(--sd-primary, #2a66f4)}.qb-body{padding-left:24px}.qb-treenode{position:relative;padding-left:22px;margin-bottom:12px}.qb-treenode:last-child{margin-bottom:0}.qb-treenode:before{content:\"\";position:absolute;left:0;top:-12px;bottom:0;border-left:1px dashed #d0d5dd}.qb-treenode:after{content:\"\";position:absolute;left:0;top:50%;width:18px;border-top:1px dashed #d0d5dd}.qb-treenode:last-child:before{bottom:auto;height:calc(50% + 12px)}.qb-empty{color:#98a2b3;font-style:italic;font-size:13px;padding:4px 0}.qb-rule{display:flex;align-items:center;gap:8px;background:#fafbfc;border:1px solid #e0e0e0;border-radius:6px;padding:6px 10px}.qb-rule:hover{border-color:#c2c8d0}.qb-field{min-width:170px}.qb-val{min-width:140px}.qb-value-source{min-width:132px}.qb-compare-field{min-width:170px}.qb-date-val{min-width:0;width:132px;flex:0 0 auto}::ng-deep .qb-opt{display:flex;align-items:center;gap:6px;min-width:0}::ng-deep .qb-opt .qb-opt-icon.mat-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;margin:0;font-size:18px;width:18px;height:18px;line-height:1;color:#667085}::ng-deep .qb-opt .qb-opt-label{min-width:0}.qb-between{display:flex;align-items:center;gap:6px}.qb-dash{color:#98a2b3}.qb-divider{width:1px;align-self:stretch;background:#e0e0e0}.qb-treenode.is-group>.qb-group{border:1px solid #e0e0e0;border-left:2px solid var(--sd-primary, #2a66f4);border-radius:6px;padding:12px;background:#fff}.qb-date-mode{min-width:160px}.qb-rel-amount{width:72px}.qb-rel-unit{min-width:110px}\n"] }]
|
|
885
|
+
args: [{ selector: 'sd-query-builder', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet, MatIconModule, SdOperator, SdSelect, SdInput, SdInputNumber, SdDate, SdDatetime, SdItemDefDefDirective], template: "@if (isView()) {\r\n <div class=\"qb-view\" [attr.data-autoid]=\"autoIdFor('view')\" aria-readonly=\"true\">\r\n @if (tokens().length) {\r\n @for (t of tokens(); track $index) {\r\n <span class=\"qb-tok qb-tok-{{ t.kind }}\">{{ t.text }}</span>\r\n }\r\n } @else {\r\n <span class=\"qb-view-empty\">\u2014</span>\r\n }\r\n </div>\r\n} @else {\r\n <div class=\"qb-container\" [class.is-disabled]=\"resolvedDisabled()\" (click)=\"closeAllDropdowns()\">\n <ng-container [ngTemplateOutlet]=\"groupTpl\" [ngTemplateOutletContext]=\"{ $implicit: tree(), isRoot: true }\"></ng-container>\r\n </div>\r\n}\r\n\r\n<!-- Recursive group node -->\r\n<ng-template #groupTpl let-group let-isRoot=\"isRoot\" let-parent=\"parent\" let-index=\"index\">\r\n <div class=\"qb-group\" [class.is-root]=\"isRoot\">\r\n <div class=\"qb-header\" [class.is-open]=\"group.open\">\r\n <div class=\"qb-logic-switch\">\r\n <button type=\"button\" [class.active]=\"group.logic === 'AND'\" [disabled]=\"resolvedDisabled()\" (click)=\"setGroupLogic(group, 'AND')\">AND</button>\n <button type=\"button\" [class.active]=\"group.logic === 'OR'\" [disabled]=\"resolvedDisabled()\" (click)=\"setGroupLogic(group, 'OR')\">OR</button>\n </div>\r\n\r\n <div class=\"qb-actions\">\r\n <button type=\"button\" class=\"qb-btn qb-btn-add\" title=\"Th\u00EAm\" aria-label=\"Th\u00EAm \u0111i\u1EC1u ki\u1EC7n ho\u1EB7c nh\u00F3m\" [disabled]=\"resolvedDisabled()\" (click)=\"toggleDropdown(group, $event)\">+</button>\r\n @if (group.open) {\r\n <div class=\"qb-dropdown\" (click)=\"$event.stopPropagation()\">\r\n <button type=\"button\" (click)=\"addRule(group)\">+ \u0110i\u1EC1u ki\u1EC7n</button>\r\n <button type=\"button\" (click)=\"addGroup(group)\">+ Nh\u00F3m</button>\r\n </div>\r\n }\r\n @if (!isRoot) {\r\n <button type=\"button\" class=\"qb-btn qb-btn-remove\" title=\"Xo\u00E1 nh\u00F3m\" aria-label=\"Xo\u00E1 nh\u00F3m\" [disabled]=\"resolvedDisabled()\" (click)=\"removeNode(parent, index)\">\u2715</button>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"qb-body\">\r\n @for (node of group.children; track node.id; let i = $index) {\r\n <div class=\"qb-treenode\" [class.is-group]=\"isGroup(node)\" [class.is-rule]=\"!isGroup(node)\">\r\n @if (isGroup(node)) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"groupTpl\"\r\n [ngTemplateOutletContext]=\"{ $implicit: node, isRoot: false, parent: group, index: i }\"\r\n ></ng-container>\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"ruleTpl\" [ngTemplateOutletContext]=\"{ $implicit: node, parent: group, index: i }\"></ng-container>\r\n }\r\n </div>\r\n } @empty {\r\n <div class=\"qb-empty\">Ch\u01B0a c\u00F3 \u0111i\u1EC1u ki\u1EC7n</div>\r\n }\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Single rule node: field \u2192 operator \u2192 value -->\r\n<ng-template #ruleTpl let-rule let-parent=\"parent\" let-index=\"index\">\r\n <div class=\"qb-rule\">\r\n <sd-select\r\n class=\"qb-field\"\r\n [items]=\"resolvedFields()\"\n valueField=\"key\"\r\n displayField=\"label\"\r\n placeholder=\"Ch\u1ECDn tr\u01B0\u1EDDng\"\r\n size=\"sm\"\r\n [model]=\"rule.field\"\r\n (modelChange)=\"setField(rule, $event)\"\r\n [disabled]=\"resolvedDisabled()\"\r\n [clearable]=\"false\"\r\n hideInlineError\r\n [autoId]=\"autoIdFor('field-' + index)\"\r\n >\r\n <!-- Option trong dropdown: icon th\u1EC3 hi\u1EC7n type + label. -->\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ fieldIcon(item) }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.label }}</span>\r\n </span>\r\n </ng-template>\r\n <!-- Gi\u00E1 tr\u1ECB \u0111\u00E3 ch\u1ECDn \u1EDF trigger: icon m\u1EB7c \u0111\u1ECBnh theo type khi field ch\u01B0a c\u00F3 icon ri\u00EAng. -->\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ fieldIcon(item) }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.label }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n\r\n @if (rule.field) {\r\n <div class=\"qb-divider\"></div>\r\n\r\n @if (showOperatorSelector(rule)) {\r\n <sd-operator\r\n class=\"qb-op\"\r\n [operators]=\"allowedOperators(rule)\"\r\n [model]=\"rule.operator\"\r\n (modelChange)=\"setOperator(rule, $event)\"\r\n [disabled]=\"resolvedDisabled()\"\r\n [autoId]=\"autoIdFor('op-' + index)\"\r\n ></sd-operator>\r\n }\r\n\r\n @if (rule.operator && !isNoData(rule.operator)) {\r\n <div class=\"qb-divider\"></div>\r\n\r\n @if (showValueSourceSelector(rule)) {\r\n <sd-select\r\n class=\"qb-value-source\"\r\n [items]=\"valueSourceOptions\"\r\n valueField=\"value\"\r\n displayField=\"display\"\r\n size=\"sm\"\r\n [model]=\"valueSourceOf(rule)\"\r\n (modelChange)=\"setValueSource(rule, $event)\"\r\n [disabled]=\"resolvedDisabled()\"\r\n [clearable]=\"false\"\r\n hideInlineError\r\n [autoId]=\"autoIdFor('valuesource-' + index)\"\r\n >\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.display }}</span>\r\n </span>\r\n </ng-template>\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item?.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.display }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n <div class=\"qb-divider\"></div>\r\n }\r\n\r\n @if (isFieldSource(rule)) {\r\n <sd-select\r\n class=\"qb-val qb-compare-field\"\r\n [items]=\"compareFields(rule)\"\r\n valueField=\"key\"\r\n displayField=\"label\"\r\n placeholder=\"Ch\u1ECDn tr\u01B0\u1EDDng\"\r\n size=\"sm\"\r\n [model]=\"rule.compareField\"\r\n (modelChange)=\"setCompareField(rule, $event)\"\r\n [disabled]=\"resolvedDisabled()\"\r\n [clearable]=\"false\"\r\n hideInlineError\r\n [autoId]=\"autoIdFor('compare-field-' + index)\"\r\n >\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ fieldIcon(item) }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.label }}</span>\r\n </span>\r\n </ng-template>\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ fieldIcon(item) }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.label }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n } @else if (rule.operator === 'BETWEEN') {\r\n <div class=\"qb-between\">\r\n @switch (fieldOf(rule)?.type) {\r\n @case ('number') {\r\n <sd-input-number class=\"qb-val\" placeholder=\"T\u1EEB\" size=\"sm\" [model]=\"rule.value?.from\" (modelChange)=\"setBetweenFrom(rule, $event)\" [min]=\"fieldOf(rule)?.min\" [max]=\"fieldOf(rule)?.max\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('from-' + index)\"></sd-input-number>\r\n <span class=\"qb-dash\">\u2014</span>\r\n <sd-input-number class=\"qb-val\" placeholder=\"\u0110\u1EBFn\" size=\"sm\" [model]=\"rule.value?.to\" (modelChange)=\"setBetweenTo(rule, $event)\" [min]=\"fieldOf(rule)?.min\" [max]=\"fieldOf(rule)?.max\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('to-' + index)\"></sd-input-number>\r\n }\r\n @case ('date') {\r\n <sd-date class=\"qb-val qb-date-val\" size=\"sm\" [model]=\"rule.value?.from\" (modelChange)=\"setBetweenFrom(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('from-' + index)\"></sd-date>\r\n <span class=\"qb-dash\">\u2014</span>\r\n <sd-date class=\"qb-val qb-date-val\" size=\"sm\" [model]=\"rule.value?.to\" (modelChange)=\"setBetweenTo(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('to-' + index)\"></sd-date>\r\n }\r\n @case ('datetime') {\r\n <sd-datetime class=\"qb-val\" size=\"sm\" [model]=\"rule.value?.from\" (modelChange)=\"setBetweenFrom(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('from-' + index)\"></sd-datetime>\r\n <span class=\"qb-dash\">\u2014</span>\r\n <sd-datetime class=\"qb-val\" size=\"sm\" [model]=\"rule.value?.to\" (modelChange)=\"setBetweenTo(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('to-' + index)\"></sd-datetime>\r\n }\r\n }\r\n </div>\r\n } @else {\r\n @switch (fieldOf(rule)?.type) {\r\n @case ('string') {\r\n <sd-input class=\"qb-val\" placeholder=\"Gi\u00E1 tr\u1ECB\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-input>\r\n }\r\n @case ('number') {\r\n <sd-input-number class=\"qb-val\" placeholder=\"Gi\u00E1 tr\u1ECB\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [min]=\"fieldOf(rule)?.min\" [max]=\"fieldOf(rule)?.max\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-input-number>\r\n }\r\n @case ('boolean') {\r\n <sd-select class=\"qb-val\" [items]=\"booleanItems(fieldOf(rule)!)\" valueField=\"value\" displayField=\"display\" placeholder=\"Gi\u00E1 tr\u1ECB\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-select>\r\n }\r\n @case ('date') {\r\n @let _dateMode = dateMode(rule);\r\n <sd-select class=\"qb-date-mode\" [items]=\"dateModes\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"_dateMode\" (modelChange)=\"setDateMode(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('datemode-' + index)\">\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.display }}</span>\r\n </span>\r\n </ng-template>\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item?.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.display }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n @switch (_dateMode) {\r\n @case ('absolute') {\r\n <sd-date class=\"qb-val qb-date-val\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-date>\r\n }\r\n @case ('relative') {\r\n <sd-input-number class=\"qb-rel-amount\" type=\"positive\" [precision]=\"0\" size=\"sm\" [model]=\"relativeAmount(rule)\" (modelChange)=\"setRelativeAmount(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('rel-amount-' + index)\"></sd-input-number>\r\n <sd-select class=\"qb-rel-unit\" [items]=\"relativeUnitOptions\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"relativeUnitDirValue(rule)\" (modelChange)=\"setRelativeUnitDir(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('rel-unit-' + index)\"></sd-select>\r\n }\r\n }\r\n }\r\n @case ('datetime') {\r\n @let _dtMode = dateMode(rule);\r\n <sd-select class=\"qb-date-mode\" [items]=\"dateModes\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"_dtMode\" (modelChange)=\"setDateMode(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('datemode-' + index)\">\r\n <ng-template sdItemDef let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item.display }}</span>\r\n </span>\r\n </ng-template>\r\n <ng-template #sdSelected let-item=\"item\">\r\n <span class=\"qb-opt\">\r\n <mat-icon class=\"qb-opt-icon\" fontSet=\"material-icons-outlined\">{{ item?.icon }}</mat-icon>\r\n <span class=\"qb-opt-label\">{{ item?.display }}</span>\r\n </span>\r\n </ng-template>\r\n </sd-select>\r\n @switch (_dtMode) {\r\n @case ('absolute') {\r\n <sd-datetime class=\"qb-val\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-datetime>\r\n }\r\n @case ('relative') {\r\n <sd-input-number class=\"qb-rel-amount\" type=\"positive\" [precision]=\"0\" size=\"sm\" [model]=\"relativeAmount(rule)\" (modelChange)=\"setRelativeAmount(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('rel-amount-' + index)\"></sd-input-number>\r\n <sd-select class=\"qb-rel-unit\" [items]=\"relativeUnitOptions\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"relativeUnitDirValue(rule)\" (modelChange)=\"setRelativeUnitDir(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('rel-unit-' + index)\"></sd-select>\r\n }\r\n }\r\n }\r\n @case ('values') {\r\n <sd-select class=\"qb-val\" [items]=\"fieldOf(rule)!.values || []\" valueField=\"value\" displayField=\"display\" [multiple]=\"isMulti(rule.operator)\" placeholder=\"Gi\u00E1 tr\u1ECB\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-select>\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n <button type=\"button\" class=\"qb-btn qb-btn-remove-rule\" title=\"Xo\u00E1 \u0111i\u1EC1u ki\u1EC7n\" aria-label=\"Xo\u00E1 \u0111i\u1EC1u ki\u1EC7n\" [disabled]=\"resolvedDisabled()\" (click)=\"removeNode(parent, index)\">\u2715</button>\r\n </div>\r\n</ng-template>\r\n", styles: [":host{display:block;font-size:14px;color:var(--sd-text, #333)}.qb-view{display:block;width:100%;min-height:38px;padding:8px 12px;border:1px solid #d0d5dd;border-radius:6px;background:var(--sd-disabled-bg, #f6f7f9);color:var(--sd-text, #333);font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:13px;line-height:1.7;cursor:default;-webkit-user-select:text;user-select:text;white-space:pre-wrap;word-break:break-word}.qb-view-empty{color:#98a2b3}.qb-tok{white-space:pre}.qb-tok.qb-tok-field{color:var(--sd-text, #1d2939);font-weight:600}.qb-tok.qb-tok-op{color:var(--sd-primary, #2a66f4);font-weight:600}.qb-tok.qb-tok-value{color:var(--sd-success, #1a7f37)}.qb-tok.qb-tok-logic{color:#98a2b3;font-weight:700;text-transform:uppercase}.qb-tok.qb-tok-paren{color:#667085}.qb-container{padding:16px;background:#fff;border:1px solid #e0e0e0;border-radius:6px}.qb-container.is-disabled{opacity:.7;pointer-events:none}.qb-header{display:flex;align-items:center;gap:8px;margin-bottom:12px;position:relative;z-index:1}.qb-header.is-open{z-index:1000}.qb-logic-switch{display:inline-flex;border:1px solid #e0e0e0;border-radius:4px;overflow:hidden;height:30px}.qb-logic-switch button{border:none;background:transparent;padding:0 14px;font-weight:600;font-size:12px;cursor:pointer;color:#667085;height:100%}.qb-logic-switch button.active{background:var(--sd-primary, #2a66f4);color:#fff}.qb-logic-switch button:hover:not(.active):not([disabled]){background:var(--sd-primary-light, #eaf1ff);color:var(--sd-primary-dark, #1c4ad9)}.qb-logic-switch button[disabled]{cursor:default}.qb-actions{position:relative;display:flex;align-items:center;gap:4px}.qb-btn{background:transparent;border:none;cursor:pointer;font-size:16px;color:#667085;width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;border-radius:4px}.qb-btn:hover:not([disabled]){background:var(--sd-primary-light, #eaf1ff);color:var(--sd-primary, #2a66f4)}.qb-btn[disabled]{cursor:default;color:#cbd2dc}.qb-btn-remove:hover:not([disabled]),.qb-btn-remove-rule:hover:not([disabled]){background:#fee4e2;color:#d92d20}.qb-btn-remove-rule{margin-left:auto}.qb-dropdown{position:absolute;top:100%;left:0;margin-top:4px;background:#fff;border:1px solid #e0e0e0;box-shadow:0 4px 12px #1018281f;border-radius:6px;min-width:150px;z-index:100;overflow:hidden}.qb-dropdown button{display:block;width:100%;text-align:left;background:none;border:none;padding:9px 14px;cursor:pointer;font-size:13px;color:#344054}.qb-dropdown button:hover{background:var(--sd-primary-light, #eaf1ff);color:var(--sd-primary, #2a66f4)}.qb-body{padding-left:24px}.qb-treenode{position:relative;padding-left:22px;margin-bottom:12px}.qb-treenode:last-child{margin-bottom:0}.qb-treenode:before{content:\"\";position:absolute;left:0;top:-12px;bottom:0;border-left:1px dashed #d0d5dd}.qb-treenode:after{content:\"\";position:absolute;left:0;top:50%;width:18px;border-top:1px dashed #d0d5dd}.qb-treenode:last-child:before{bottom:auto;height:calc(50% + 12px)}.qb-empty{color:#98a2b3;font-style:italic;font-size:13px;padding:4px 0}.qb-rule{display:flex;align-items:center;gap:8px;background:#fafbfc;border:1px solid #e0e0e0;border-radius:6px;padding:6px 10px}.qb-rule:hover{border-color:#c2c8d0}.qb-field{min-width:170px}.qb-val{min-width:140px}.qb-value-source{min-width:132px}.qb-compare-field{min-width:170px}.qb-date-val{min-width:0;width:132px;flex:0 0 auto}::ng-deep .qb-opt{display:flex;align-items:center;gap:6px;min-width:0}::ng-deep .qb-opt .qb-opt-icon.mat-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;margin:0;font-size:18px;width:18px;height:18px;line-height:1;color:#667085}::ng-deep .qb-opt .qb-opt-label{min-width:0}.qb-between{display:flex;align-items:center;gap:6px}.qb-dash{color:#98a2b3}.qb-divider{width:1px;align-self:stretch;background:#e0e0e0}.qb-treenode.is-group>.qb-group{border:1px solid #e0e0e0;border-left:2px solid var(--sd-primary, #2a66f4);border-radius:6px;padding:12px;background:#fff}.qb-date-mode{min-width:160px}.qb-rel-amount{width:72px}.qb-rel-unit{min-width:110px}\n"] }]
|
|
886
886
|
}], ctorParameters: () => [] });
|
|
887
887
|
|
|
888
888
|
/**
|