@sdcorejs/angular 21.1.2 → 21.1.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.
Files changed (60) hide show
  1. package/README.md +124 -807
  2. package/fesm2022/sdcorejs-angular-components-form-generic.mjs +150 -60
  3. package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
  4. package/fesm2022/sdcorejs-angular-components-import-excel.mjs +2 -7
  5. package/fesm2022/sdcorejs-angular-components-import-excel.mjs.map +1 -1
  6. package/fesm2022/sdcorejs-angular-components-query-bar.mjs +7 -15
  7. package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
  8. package/fesm2022/sdcorejs-angular-components-query-builder.mjs +1 -1
  9. package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
  10. package/fesm2022/sdcorejs-angular-components-tab-router.mjs +60 -30
  11. package/fesm2022/sdcorejs-angular-components-tab-router.mjs.map +1 -1
  12. package/fesm2022/sdcorejs-angular-components-table.mjs +32 -31
  13. package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
  14. package/fesm2022/sdcorejs-angular-components-tree.mjs +2 -1
  15. package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -1
  16. package/fesm2022/sdcorejs-angular-components-upload-file.mjs +2 -1
  17. package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
  18. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +2 -1
  19. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
  20. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +2 -1
  21. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
  22. package/fesm2022/sdcorejs-angular-forms-chip.mjs +2 -1
  23. package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
  24. package/fesm2022/sdcorejs-angular-forms-date-range.mjs +2 -1
  25. package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
  26. package/fesm2022/sdcorejs-angular-forms-date.mjs +6 -5
  27. package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
  28. package/fesm2022/sdcorejs-angular-forms-datetime.mjs +14 -465
  29. package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
  30. package/fesm2022/sdcorejs-angular-forms-input-color.mjs +5 -3
  31. package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
  32. package/fesm2022/sdcorejs-angular-forms-input-number.mjs +9 -6
  33. package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
  34. package/fesm2022/sdcorejs-angular-forms-input.mjs +10 -6
  35. package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
  36. package/fesm2022/sdcorejs-angular-forms-select.mjs +2 -1
  37. package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
  38. package/fesm2022/sdcorejs-angular-forms-textarea.mjs +2 -1
  39. package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
  40. package/fesm2022/sdcorejs-angular-modules-icon.mjs.map +1 -1
  41. package/fesm2022/sdcorejs-angular-modules-layout.mjs +1 -1
  42. package/fesm2022/sdcorejs-angular-modules-layout.mjs.map +1 -1
  43. package/fesm2022/sdcorejs-angular-modules.mjs +0 -1
  44. package/fesm2022/sdcorejs-angular-modules.mjs.map +1 -1
  45. package/fesm2022/sdcorejs-angular-pipes.mjs.map +1 -1
  46. package/fesm2022/sdcorejs-angular-services-loading.mjs +23 -14
  47. package/fesm2022/sdcorejs-angular-services-loading.mjs.map +1 -1
  48. package/package.json +2 -5
  49. package/types/sdcorejs-angular-components-form-generic.d.ts +25 -2
  50. package/types/sdcorejs-angular-forms-date.d.ts +1 -1
  51. package/types/sdcorejs-angular-forms-datetime.d.ts +1 -1
  52. package/types/sdcorejs-angular-forms-input-color.d.ts +3 -1
  53. package/types/sdcorejs-angular-forms-input-number.d.ts +3 -1
  54. package/types/sdcorejs-angular-forms-input.d.ts +3 -1
  55. package/types/sdcorejs-angular-modules-icon.d.ts +2 -3
  56. package/types/sdcorejs-angular-modules.d.ts +0 -1
  57. package/types/sdcorejs-angular-services-loading.d.ts +1 -1
  58. package/fesm2022/sdcorejs-angular-modules-authom.mjs +0 -360
  59. package/fesm2022/sdcorejs-angular-modules-authom.mjs.map +0 -1
  60. package/types/sdcorejs-angular-modules-authom.d.ts +0 -70
@@ -877,7 +877,7 @@ class SdQueryBuilder {
877
877
  return `${this.resolvedAutoId() ?? 'qb'}-${suffix}`;
878
878
  }
879
879
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdQueryBuilder, deps: [], target: i0.ɵɵFactoryTarget.Component });
880
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", 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()) {\n <div class=\"qb-view\" [attr.data-autoid]=\"autoIdFor('view')\" aria-readonly=\"true\">\n @if (tokens().length) {\n @for (t of tokens(); track $index) {\n <span class=\"qb-tok qb-tok-{{ t.kind }}\">{{ t.text }}</span>\n }\n } @else {\n <span class=\"qb-view-empty\">\u2014</span>\n }\n </div>\n} @else {\n <div class=\"qb-container\" [class.is-disabled]=\"resolvedDisabled()\" (click)=\"closeAllDropdowns()\">\n <ng-container [ngTemplateOutlet]=\"groupTpl\" [ngTemplateOutletContext]=\"{ $implicit: tree(), isRoot: true }\"></ng-container>\n </div>\n}\n\n<!-- Recursive group node -->\n<ng-template #groupTpl let-group let-isRoot=\"isRoot\" let-parent=\"parent\" let-index=\"index\">\n <div class=\"qb-group\" [class.is-root]=\"isRoot\">\n <div class=\"qb-header\" [class.is-open]=\"group.open\">\n <div class=\"qb-logic-switch\">\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>\n\n <div class=\"qb-actions\">\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>\n @if (group.open) {\n <div class=\"qb-dropdown\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" (click)=\"addRule(group)\">+ \u0110i\u1EC1u ki\u1EC7n</button>\n <button type=\"button\" (click)=\"addGroup(group)\">+ Nh\u00F3m</button>\n </div>\n }\n @if (!isRoot) {\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>\n }\n </div>\n </div>\n\n <div class=\"qb-body\">\n @for (node of group.children; track node.id; let i = $index) {\n <div class=\"qb-treenode\" [class.is-group]=\"isGroup(node)\" [class.is-rule]=\"!isGroup(node)\">\n @if (isGroup(node)) {\n <ng-container\n [ngTemplateOutlet]=\"groupTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: node, isRoot: false, parent: group, index: i }\"\n ></ng-container>\n } @else {\n <ng-container [ngTemplateOutlet]=\"ruleTpl\" [ngTemplateOutletContext]=\"{ $implicit: node, parent: group, index: i }\"></ng-container>\n }\n </div>\n } @empty {\n <div class=\"qb-empty\">Ch\u01B0a c\u00F3 \u0111i\u1EC1u ki\u1EC7n</div>\n }\n </div>\n </div>\n</ng-template>\n\n<!-- Single rule node: field \u2192 operator \u2192 value -->\n<ng-template #ruleTpl let-rule let-parent=\"parent\" let-index=\"index\">\n <div class=\"qb-rule\">\n <sd-select\n class=\"qb-field\"\n [items]=\"resolvedFields()\"\n valueField=\"key\"\n displayField=\"label\"\n placeholder=\"Ch\u1ECDn tr\u01B0\u1EDDng\"\n size=\"sm\"\n [model]=\"rule.field\"\n (modelChange)=\"setField(rule, $event)\"\n [disabled]=\"resolvedDisabled()\"\n [clearable]=\"false\"\n hideInlineError\n [autoId]=\"autoIdFor('field-' + index)\"\n >\n <!-- Option trong dropdown: icon th\u1EC3 hi\u1EC7n type + label. -->\n <ng-template sdItemDef let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"fieldIcon($any(item))\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item).label }}</span>\n </span>\n </ng-template>\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. -->\n <ng-template #sdSelected let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"fieldIcon($any(item))\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item)?.label }}</span>\n </span>\n </ng-template>\n </sd-select>\n\n @if (rule.field) {\n <div class=\"qb-divider\"></div>\n\n @if (showOperatorSelector(rule)) {\n <sd-operator\n class=\"qb-op\"\n [operators]=\"allowedOperators(rule)\"\n [model]=\"rule.operator\"\n (modelChange)=\"setOperator(rule, $event)\"\n [disabled]=\"resolvedDisabled()\"\n [autoId]=\"autoIdFor('op-' + index)\"\n ></sd-operator>\n }\n\n @if (rule.operator && !isNoData(rule.operator)) {\n <div class=\"qb-divider\"></div>\n\n @if (showValueSourceSelector(rule)) {\n <sd-select\n class=\"qb-value-source\"\n [items]=\"valueSourceOptions\"\n valueField=\"value\"\n displayField=\"display\"\n size=\"sm\"\n [model]=\"valueSourceOf(rule)\"\n (modelChange)=\"setValueSource(rule, $event)\"\n [disabled]=\"resolvedDisabled()\"\n [clearable]=\"false\"\n hideInlineError\n [autoId]=\"autoIdFor('valuesource-' + index)\"\n >\n <ng-template sdItemDef let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"$any(item).icon\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item).display }}</span>\n </span>\n </ng-template>\n <ng-template #sdSelected let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"$any(item)?.icon\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item)?.display }}</span>\n </span>\n </ng-template>\n </sd-select>\n <div class=\"qb-divider\"></div>\n }\n\n @if (isFieldSource(rule)) {\n <sd-select\n class=\"qb-val qb-compare-field\"\n [items]=\"compareFields(rule)\"\n valueField=\"key\"\n displayField=\"label\"\n placeholder=\"Ch\u1ECDn tr\u01B0\u1EDDng\"\n size=\"sm\"\n [model]=\"rule.compareField\"\n (modelChange)=\"setCompareField(rule, $event)\"\n [disabled]=\"resolvedDisabled()\"\n [clearable]=\"false\"\n hideInlineError\n [autoId]=\"autoIdFor('compare-field-' + index)\"\n >\n <ng-template sdItemDef let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"fieldIcon($any(item))\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item).label }}</span>\n </span>\n </ng-template>\n <ng-template #sdSelected let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"fieldIcon($any(item))\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item)?.label }}</span>\n </span>\n </ng-template>\n </sd-select>\n } @else if (rule.operator === 'BETWEEN') {\n <div class=\"qb-between\">\n @switch (fieldOf(rule)?.type) {\n @case ('number') {\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>\n <span class=\"qb-dash\">\u2014</span>\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>\n }\n @case ('date') {\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>\n <span class=\"qb-dash\">\u2014</span>\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>\n }\n @case ('datetime') {\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>\n <span class=\"qb-dash\">\u2014</span>\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>\n }\n }\n </div>\n } @else {\n @switch (fieldOf(rule)?.type) {\n @case ('string') {\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>\n }\n @case ('number') {\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>\n }\n @case ('boolean') {\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>\n }\n @case ('date') {\n @let _dateMode = dateMode(rule);\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)\">\n <ng-template sdItemDef let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"$any(item).icon\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item).display }}</span>\n </span>\n </ng-template>\n <ng-template #sdSelected let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"$any(item)?.icon\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item)?.display }}</span>\n </span>\n </ng-template>\n </sd-select>\n @switch (_dateMode) {\n @case ('absolute') {\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>\n }\n @case ('relative') {\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>\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>\n }\n }\n }\n @case ('datetime') {\n @let _dtMode = dateMode(rule);\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)\">\n <ng-template sdItemDef let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"$any(item).icon\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item).display }}</span>\n </span>\n </ng-template>\n <ng-template #sdSelected let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"$any(item)?.icon\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item)?.display }}</span>\n </span>\n </ng-template>\n </sd-select>\n @switch (_dtMode) {\n @case ('absolute') {\n <sd-datetime class=\"qb-val\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-datetime>\n }\n @case ('relative') {\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>\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>\n }\n }\n }\n @case ('values') {\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>\n }\n }\n }\n }\n }\n\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>\n </div>\n</ng-template>\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, #005cbb);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, #005cbb);color:#fff}.qb-logic-switch button:hover:not(.active):not([disabled]){background:var(--sd-primary-light, #d7e3ff);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, #d7e3ff);color:var(--sd-primary, #005cbb)}.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, #d7e3ff);color:var(--sd-primary, #005cbb)}.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-iconsd-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, #005cbb);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: "component", type: SdIcon, selector: "sd-icon", inputs: ["name", "fontIcon", "color", "set", "fontSet", "size", "strokeWidth", "absoluteStrokeWidth", "ariaLabel"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { 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 });
880
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", 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()) {\n <div class=\"qb-view\" [attr.data-autoid]=\"autoIdFor('view')\" aria-readonly=\"true\">\n @if (tokens().length) {\n @for (t of tokens(); track $index) {\n <span class=\"qb-tok qb-tok-{{ t.kind }}\">{{ t.text }}</span>\n }\n } @else {\n <span class=\"qb-view-empty\">\u2014</span>\n }\n </div>\n} @else {\n <div class=\"qb-container\" [class.is-disabled]=\"resolvedDisabled()\" (click)=\"closeAllDropdowns()\">\n <ng-container [ngTemplateOutlet]=\"groupTpl\" [ngTemplateOutletContext]=\"{ $implicit: tree(), isRoot: true }\"></ng-container>\n </div>\n}\n\n<!-- Recursive group node -->\n<ng-template #groupTpl let-group let-isRoot=\"isRoot\" let-parent=\"parent\" let-index=\"index\">\n <div class=\"qb-group\" [class.is-root]=\"isRoot\">\n <div class=\"qb-header\" [class.is-open]=\"group.open\">\n <div class=\"qb-logic-switch\">\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>\n\n <div class=\"qb-actions\">\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>\n @if (group.open) {\n <div class=\"qb-dropdown\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" (click)=\"addRule(group)\">+ \u0110i\u1EC1u ki\u1EC7n</button>\n <button type=\"button\" (click)=\"addGroup(group)\">+ Nh\u00F3m</button>\n </div>\n }\n @if (!isRoot) {\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>\n }\n </div>\n </div>\n\n <div class=\"qb-body\">\n @for (node of group.children; track node.id; let i = $index) {\n <div class=\"qb-treenode\" [class.is-group]=\"isGroup(node)\" [class.is-rule]=\"!isGroup(node)\">\n @if (isGroup(node)) {\n <ng-container\n [ngTemplateOutlet]=\"groupTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: node, isRoot: false, parent: group, index: i }\"\n ></ng-container>\n } @else {\n <ng-container [ngTemplateOutlet]=\"ruleTpl\" [ngTemplateOutletContext]=\"{ $implicit: node, parent: group, index: i }\"></ng-container>\n }\n </div>\n } @empty {\n <div class=\"qb-empty\">Ch\u01B0a c\u00F3 \u0111i\u1EC1u ki\u1EC7n</div>\n }\n </div>\n </div>\n</ng-template>\n\n<!-- Single rule node: field \u2192 operator \u2192 value -->\n<ng-template #ruleTpl let-rule let-parent=\"parent\" let-index=\"index\">\n <div class=\"qb-rule\">\n <sd-select\n class=\"qb-field\"\n [items]=\"resolvedFields()\"\n valueField=\"key\"\n displayField=\"label\"\n placeholder=\"Ch\u1ECDn tr\u01B0\u1EDDng\"\n size=\"sm\"\n [model]=\"rule.field\"\n (modelChange)=\"setField(rule, $event)\"\n [disabled]=\"resolvedDisabled()\"\n [clearable]=\"false\"\n hideInlineError\n [autoId]=\"autoIdFor('field-' + index)\"\n >\n <!-- Option trong dropdown: icon th\u1EC3 hi\u1EC7n type + label. -->\n <ng-template sdItemDef let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"fieldIcon($any(item))\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item).label }}</span>\n </span>\n </ng-template>\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. -->\n <ng-template #sdSelected let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"fieldIcon($any(item))\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item)?.label }}</span>\n </span>\n </ng-template>\n </sd-select>\n\n @if (rule.field) {\n <div class=\"qb-divider\"></div>\n\n @if (showOperatorSelector(rule)) {\n <sd-operator\n class=\"qb-op\"\n [operators]=\"allowedOperators(rule)\"\n [model]=\"rule.operator\"\n (modelChange)=\"setOperator(rule, $event)\"\n [disabled]=\"resolvedDisabled()\"\n [autoId]=\"autoIdFor('op-' + index)\"\n ></sd-operator>\n }\n\n @if (rule.operator && !isNoData(rule.operator)) {\n <div class=\"qb-divider\"></div>\n\n @if (showValueSourceSelector(rule)) {\n <sd-select\n class=\"qb-value-source\"\n [items]=\"valueSourceOptions\"\n valueField=\"value\"\n displayField=\"display\"\n size=\"sm\"\n [model]=\"valueSourceOf(rule)\"\n (modelChange)=\"setValueSource(rule, $event)\"\n [disabled]=\"resolvedDisabled()\"\n [clearable]=\"false\"\n hideInlineError\n [autoId]=\"autoIdFor('valuesource-' + index)\"\n >\n <ng-template sdItemDef let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"$any(item).icon\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item).display }}</span>\n </span>\n </ng-template>\n <ng-template #sdSelected let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"$any(item)?.icon\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item)?.display }}</span>\n </span>\n </ng-template>\n </sd-select>\n <div class=\"qb-divider\"></div>\n }\n\n @if (isFieldSource(rule)) {\n <sd-select\n class=\"qb-val qb-compare-field\"\n [items]=\"compareFields(rule)\"\n valueField=\"key\"\n displayField=\"label\"\n placeholder=\"Ch\u1ECDn tr\u01B0\u1EDDng\"\n size=\"sm\"\n [model]=\"rule.compareField\"\n (modelChange)=\"setCompareField(rule, $event)\"\n [disabled]=\"resolvedDisabled()\"\n [clearable]=\"false\"\n hideInlineError\n [autoId]=\"autoIdFor('compare-field-' + index)\"\n >\n <ng-template sdItemDef let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"fieldIcon($any(item))\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item).label }}</span>\n </span>\n </ng-template>\n <ng-template #sdSelected let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"fieldIcon($any(item))\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item)?.label }}</span>\n </span>\n </ng-template>\n </sd-select>\n } @else if (rule.operator === 'BETWEEN') {\n <div class=\"qb-between\">\n @switch (fieldOf(rule)?.type) {\n @case ('number') {\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>\n <span class=\"qb-dash\">\u2014</span>\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>\n }\n @case ('date') {\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>\n <span class=\"qb-dash\">\u2014</span>\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>\n }\n @case ('datetime') {\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>\n <span class=\"qb-dash\">\u2014</span>\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>\n }\n }\n </div>\n } @else {\n @switch (fieldOf(rule)?.type) {\n @case ('string') {\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>\n }\n @case ('number') {\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>\n }\n @case ('boolean') {\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>\n }\n @case ('date') {\n @let _dateMode = dateMode(rule);\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)\">\n <ng-template sdItemDef let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"$any(item).icon\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item).display }}</span>\n </span>\n </ng-template>\n <ng-template #sdSelected let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"$any(item)?.icon\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item)?.display }}</span>\n </span>\n </ng-template>\n </sd-select>\n @switch (_dateMode) {\n @case ('absolute') {\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>\n }\n @case ('relative') {\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>\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>\n }\n }\n }\n @case ('datetime') {\n @let _dtMode = dateMode(rule);\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)\">\n <ng-template sdItemDef let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"$any(item).icon\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item).display }}</span>\n </span>\n </ng-template>\n <ng-template #sdSelected let-item=\"item\">\n <span class=\"qb-opt\">\n <sd-icon class=\"qb-opt-icon\" [name]=\"$any(item)?.icon\"></sd-icon>\n <span class=\"qb-opt-label\">{{ $any(item)?.display }}</span>\n </span>\n </ng-template>\n </sd-select>\n @switch (_dtMode) {\n @case ('absolute') {\n <sd-datetime class=\"qb-val\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"resolvedDisabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-datetime>\n }\n @case ('relative') {\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>\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>\n }\n }\n }\n @case ('values') {\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>\n }\n }\n }\n }\n }\n\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>\n </div>\n</ng-template>\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, #005cbb);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, #005cbb);color:#fff}.qb-logic-switch button:hover:not(.active):not([disabled]){background:var(--sd-primary-light, #d7e3ff);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, #d7e3ff);color:var(--sd-primary, #005cbb)}.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, #d7e3ff);color:var(--sd-primary, #005cbb)}.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-iconsd-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, #005cbb);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: "component", type: SdIcon, selector: "sd-icon", inputs: ["name", "fontIcon", "color", "set", "fontSet", "size", "strokeWidth", "absoluteStrokeWidth", "ariaLabel"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { 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", "clearable", "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", "clearable", "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
881
  }
882
882
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdQueryBuilder, decorators: [{
883
883
  type: Component,