@sdcorejs/angular 21.0.0 → 21.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -19
- package/assets/scss/core/_inline-edit.scss +105 -0
- package/assets/scss/core/form.scss +15 -0
- package/fesm2022/sdcorejs-angular-components-anchor.mjs +9 -9
- package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs +111 -24
- package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-avatar.mjs +4 -4
- package/fesm2022/sdcorejs-angular-components-avatar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-badge.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-base.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-button.mjs +4 -4
- package/fesm2022/sdcorejs-angular-components-button.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-chart.mjs +12 -12
- package/fesm2022/sdcorejs-angular-components-ckeditor-styles.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-code-editor.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-document-builder.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-editor.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs +288 -375
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-history.mjs +7 -7
- package/fesm2022/sdcorejs-angular-components-import-excel.mjs +10 -10
- package/fesm2022/sdcorejs-angular-components-inform.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-mini-editor.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs +158 -0
- package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-components-modal.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-operator.mjs +6 -4
- package/fesm2022/sdcorejs-angular-components-operator.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-preview.mjs +8 -8
- package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs +60 -106
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-quick-action.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-section.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +4 -4
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-splitter.mjs +12 -12
- package/fesm2022/sdcorejs-angular-components-stepper.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-tab-router.mjs +18 -18
- package/fesm2022/sdcorejs-angular-components-tab.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-table.mjs +335 -208
- package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs +16 -16
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-view.mjs +45 -13
- package/fesm2022/sdcorejs-angular-components-view.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components.mjs +1 -0
- package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-directives.mjs +21 -21
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +28 -8
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs +11 -6
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +15 -10
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip.mjs +15 -10
- package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs +21 -12
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date.mjs +29 -17
- package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs +34 -22
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-directives.mjs +12 -12
- package/fesm2022/sdcorejs-angular-forms-inline-text.mjs +167 -0
- package/fesm2022/sdcorejs-angular-forms-inline-text.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs +7 -5
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs +37 -10
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input.mjs +38 -12
- package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-label.mjs +3 -3
- package/fesm2022/sdcorejs-angular-forms-models.mjs +32 -2
- package/fesm2022/sdcorejs-angular-forms-models.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-radio.mjs +11 -6
- package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-select.mjs +36 -12
- package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-switch.mjs +11 -6
- package/fesm2022/sdcorejs-angular-forms-switch.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs +17 -7
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms.mjs +4 -4
- package/fesm2022/sdcorejs-angular-handlers.mjs +3 -3
- package/fesm2022/sdcorejs-angular-i18n.mjs +26 -6
- package/fesm2022/sdcorejs-angular-i18n.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-interceptors.mjs +6 -6
- package/fesm2022/sdcorejs-angular-modules-auth.mjs +9 -9
- package/fesm2022/sdcorejs-angular-modules-authom.mjs +7 -7
- package/fesm2022/sdcorejs-angular-modules-keycloak.mjs +7 -7
- package/fesm2022/sdcorejs-angular-modules-layout.mjs +73 -73
- package/fesm2022/sdcorejs-angular-modules-permission.mjs +9 -9
- package/fesm2022/sdcorejs-angular-pipes.mjs +14 -14
- package/fesm2022/sdcorejs-angular-services-api.mjs +10 -10
- package/fesm2022/sdcorejs-angular-services-cache.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-confirm.mjs +6 -6
- package/fesm2022/sdcorejs-angular-services-confirm.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-docx.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-excel.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-license.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-loading.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-notify.mjs +23 -10
- package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-storage.mjs +3 -3
- package/package.json +10 -1
- package/types/sdcorejs-angular-components-autoid-inspector.d.ts +53 -4
- package/types/sdcorejs-angular-components-form-generic.d.ts +12 -13
- package/types/sdcorejs-angular-components-modal-resizable.d.ts +32 -0
- package/types/sdcorejs-angular-components-table.d.ts +99 -10
- package/types/sdcorejs-angular-components-view.d.ts +33 -0
- package/types/sdcorejs-angular-components.d.ts +1 -0
- package/types/sdcorejs-angular-forms-autocomplete.d.ts +16 -3
- package/types/sdcorejs-angular-forms-checkbox.d.ts +5 -1
- package/types/sdcorejs-angular-forms-chip-calendar.d.ts +5 -2
- package/types/sdcorejs-angular-forms-chip.d.ts +5 -2
- package/types/sdcorejs-angular-forms-date-range.d.ts +12 -5
- package/types/sdcorejs-angular-forms-date.d.ts +14 -5
- package/types/sdcorejs-angular-forms-datetime.d.ts +14 -5
- package/types/sdcorejs-angular-forms-inline-text.d.ts +80 -0
- package/types/sdcorejs-angular-forms-input-color.d.ts +3 -1
- package/types/sdcorejs-angular-forms-input-number.d.ts +14 -2
- package/types/sdcorejs-angular-forms-input.d.ts +14 -2
- package/types/sdcorejs-angular-forms-models.d.ts +40 -2
- package/types/sdcorejs-angular-forms-radio.d.ts +5 -2
- package/types/sdcorejs-angular-forms-select.d.ts +23 -5
- package/types/sdcorejs-angular-forms-switch.d.ts +5 -2
- package/types/sdcorejs-angular-forms-textarea.d.ts +9 -2
- package/types/sdcorejs-angular-i18n.d.ts +4 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { CommonModule } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { input, output, signal, computed, effect, ChangeDetectionStrategy, Component, booleanAttribute, model, viewChild,
|
|
4
|
-
import * as i1$
|
|
3
|
+
import { input, output, signal, computed, effect, ChangeDetectionStrategy, Component, booleanAttribute, model, viewChild, isSignal, inject, Injector, viewChildren, afterNextRender } from '@angular/core';
|
|
4
|
+
import * as i1$2 from '@angular/forms';
|
|
5
5
|
import { FormsModule } from '@angular/forms';
|
|
6
|
-
import * as
|
|
6
|
+
import * as i1$1 from '@angular/material/icon';
|
|
7
7
|
import { MatIconModule } from '@angular/material/icon';
|
|
8
8
|
import * as i1 from '@angular/material/menu';
|
|
9
9
|
import { MatMenuModule, MatMenu, MatMenuTrigger } from '@angular/material/menu';
|
|
@@ -17,6 +17,7 @@ import { SdDatetime } from '@sdcorejs/angular/forms/datetime';
|
|
|
17
17
|
import { SdInput } from '@sdcorejs/angular/forms/input';
|
|
18
18
|
import { SdInputNumber } from '@sdcorejs/angular/forms/input-number';
|
|
19
19
|
import { SdSelect } from '@sdcorejs/angular/forms/select';
|
|
20
|
+
import { SdInlineText } from '@sdcorejs/angular/forms/inline-text';
|
|
20
21
|
import { isObservable } from 'rxjs';
|
|
21
22
|
import { SdButton } from '@sdcorejs/angular/components/button';
|
|
22
23
|
|
|
@@ -105,10 +106,10 @@ class SdQuerySavedFiltersMenu {
|
|
|
105
106
|
this.savedFilters.set(next);
|
|
106
107
|
this.#persist(next);
|
|
107
108
|
}
|
|
108
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
109
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
109
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQuerySavedFiltersMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
110
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: SdQuerySavedFiltersMenu, isStandalone: true, selector: "sd-query-saved-filters-menu", inputs: { key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: false, transformFunction: null }, query: { classPropertyName: "query", publicName: "query", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { apply: "apply" }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"c-saved-filters\"\n [disabled]=\"!key()\"\n [matMenuTriggerFor]=\"menu\"\n [matTooltip]=\"key() ? 'B\u1ED9 l\u1ECDc \u0111\u00E3 l\u01B0u' : 'C\u1EA7n [savedFiltersKey] \u0111\u1EC3 b\u1EADt'\">\n <mat-icon fontSet=\"material-icons-outlined\">bookmark_border</mat-icon>\n</button>\n\n<mat-menu #menu=\"matMenu\" class=\"c-saved-filters-menu\" xPosition=\"before\" yPosition=\"below\">\n @for (f of savedFilters(); track f.id) {\n <button type=\"button\" mat-menu-item class=\"c-sf-row\" (click)=\"pick(f)\">\n <mat-icon class=\"c-sf-lead\" fontSet=\"material-icons-outlined\">filter_alt</mat-icon>\n <span class=\"c-sf-name\">{{ f.name }}</span>\n <span\n role=\"button\"\n tabindex=\"0\"\n class=\"c-sf-del\"\n aria-label=\"Xo\u00E1 b\u1ED9 l\u1ECDc\"\n (click)=\"remove(f.id, $event)\"\n (keydown.enter)=\"remove(f.id, $event)\">\n <mat-icon fontSet=\"material-icons-outlined\">close</mat-icon>\n </span>\n </button>\n } @empty {\n <div class=\"c-sf-empty\">Ch\u01B0a c\u00F3 b\u1ED9 l\u1ECDc n\u00E0o.</div>\n }\n <!-- why: footer save action s\u1ED1ng trong mat-menu \u0111\u1EC3 dropdown gom 1 v\u00F9ng (list +\n save) \u2014 user m\u1EDF dropdown th\u1EA5y ngay c\u1EA3 2 h\u00E0nh \u0111\u1ED9ng, kh\u00F4ng ph\u1EA3i t\u00ECm n\u00FAt l\u01B0u\n \u1EDF ch\u1ED7 kh\u00E1c tr\u00EAn toolbar. -->\n <hr class=\"c-sf-divider\" aria-hidden=\"true\" />\n <button type=\"button\" mat-menu-item class=\"c-sf-save\" [disabled]=\"!key()\" (click)=\"promptSave()\">\n <mat-icon fontSet=\"material-icons-outlined\">bookmark_add</mat-icon>\n <span>L\u01B0u b\u1ED9 l\u1ECDc hi\u1EC7n t\u1EA1i</span>\n </button>\n</mat-menu>\n", styles: [":host{display:inline-flex}.c-saved-filters{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1px solid #d6d8db;border-radius:6px;background:#fff;color:#5f6368;cursor:pointer;padding:0}.c-saved-filters mat-icon{font-size:18px;width:18px;height:18px}.c-saved-filters:hover:not([disabled]){border-color:var(--sd-primary);color:var(--sd-primary)}.c-saved-filters[disabled]{opacity:.5;cursor:not-allowed}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu{min-width:220px;max-width:320px}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .mat-mdc-menu-item.c-sf-row{min-height:40px;padding-left:16px;padding-right:4px}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .mat-mdc-menu-item.c-sf-row .mat-mdc-menu-item-text{display:flex;align-items:center;gap:8px;min-width:0;line-height:1.4}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .c-sf-lead{display:inline-flex;align-items:center;justify-content:center;font-size:18px!important;width:18px!important;height:18px!important;line-height:1}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .c-sf-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .c-sf-del{flex:0 0 auto;margin-left:auto;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:50%;color:#7a7a7a;cursor:pointer;padding:0}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .c-sf-del mat-icon{margin:0!important;padding:0;font-size:16px!important;width:16px!important;height:16px!important;line-height:16px!important;text-align:center;overflow:hidden}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .c-sf-del:hover{background:#0000000f;color:#d23535}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .c-sf-empty{padding:12px 16px;font-size:13px;color:#7a7a7a}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .c-sf-divider{border:0;border-top:1px solid #e2e4e7;margin:4px 0}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .c-sf-save mat-icon{margin-right:8px}\n"], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
110
111
|
}
|
|
111
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
112
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQuerySavedFiltersMenu, decorators: [{
|
|
112
113
|
type: Component,
|
|
113
114
|
args: [{ selector: 'sd-query-saved-filters-menu', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatMenuModule, MatIconModule, MatTooltipModule], template: "<button\n type=\"button\"\n class=\"c-saved-filters\"\n [disabled]=\"!key()\"\n [matMenuTriggerFor]=\"menu\"\n [matTooltip]=\"key() ? 'B\u1ED9 l\u1ECDc \u0111\u00E3 l\u01B0u' : 'C\u1EA7n [savedFiltersKey] \u0111\u1EC3 b\u1EADt'\">\n <mat-icon fontSet=\"material-icons-outlined\">bookmark_border</mat-icon>\n</button>\n\n<mat-menu #menu=\"matMenu\" class=\"c-saved-filters-menu\" xPosition=\"before\" yPosition=\"below\">\n @for (f of savedFilters(); track f.id) {\n <button type=\"button\" mat-menu-item class=\"c-sf-row\" (click)=\"pick(f)\">\n <mat-icon class=\"c-sf-lead\" fontSet=\"material-icons-outlined\">filter_alt</mat-icon>\n <span class=\"c-sf-name\">{{ f.name }}</span>\n <span\n role=\"button\"\n tabindex=\"0\"\n class=\"c-sf-del\"\n aria-label=\"Xo\u00E1 b\u1ED9 l\u1ECDc\"\n (click)=\"remove(f.id, $event)\"\n (keydown.enter)=\"remove(f.id, $event)\">\n <mat-icon fontSet=\"material-icons-outlined\">close</mat-icon>\n </span>\n </button>\n } @empty {\n <div class=\"c-sf-empty\">Ch\u01B0a c\u00F3 b\u1ED9 l\u1ECDc n\u00E0o.</div>\n }\n <!-- why: footer save action s\u1ED1ng trong mat-menu \u0111\u1EC3 dropdown gom 1 v\u00F9ng (list +\n save) \u2014 user m\u1EDF dropdown th\u1EA5y ngay c\u1EA3 2 h\u00E0nh \u0111\u1ED9ng, kh\u00F4ng ph\u1EA3i t\u00ECm n\u00FAt l\u01B0u\n \u1EDF ch\u1ED7 kh\u00E1c tr\u00EAn toolbar. -->\n <hr class=\"c-sf-divider\" aria-hidden=\"true\" />\n <button type=\"button\" mat-menu-item class=\"c-sf-save\" [disabled]=\"!key()\" (click)=\"promptSave()\">\n <mat-icon fontSet=\"material-icons-outlined\">bookmark_add</mat-icon>\n <span>L\u01B0u b\u1ED9 l\u1ECDc hi\u1EC7n t\u1EA1i</span>\n </button>\n</mat-menu>\n", styles: [":host{display:inline-flex}.c-saved-filters{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1px solid #d6d8db;border-radius:6px;background:#fff;color:#5f6368;cursor:pointer;padding:0}.c-saved-filters mat-icon{font-size:18px;width:18px;height:18px}.c-saved-filters:hover:not([disabled]){border-color:var(--sd-primary);color:var(--sd-primary)}.c-saved-filters[disabled]{opacity:.5;cursor:not-allowed}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu{min-width:220px;max-width:320px}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .mat-mdc-menu-item.c-sf-row{min-height:40px;padding-left:16px;padding-right:4px}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .mat-mdc-menu-item.c-sf-row .mat-mdc-menu-item-text{display:flex;align-items:center;gap:8px;min-width:0;line-height:1.4}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .c-sf-lead{display:inline-flex;align-items:center;justify-content:center;font-size:18px!important;width:18px!important;height:18px!important;line-height:1}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .c-sf-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .c-sf-del{flex:0 0 auto;margin-left:auto;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:50%;color:#7a7a7a;cursor:pointer;padding:0}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .c-sf-del mat-icon{margin:0!important;padding:0;font-size:16px!important;width:16px!important;height:16px!important;line-height:16px!important;text-align:center;overflow:hidden}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .c-sf-del:hover{background:#0000000f;color:#d23535}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .c-sf-empty{padding:12px 16px;font-size:13px;color:#7a7a7a}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .c-sf-divider{border:0;border-top:1px solid #e2e4e7;margin:4px 0}::ng-deep .mat-mdc-menu-panel.c-saved-filters-menu .c-sf-save mat-icon{margin-right:8px}\n"] }]
|
|
114
115
|
}], propDecorators: { key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: false }] }], query: [{ type: i0.Input, args: [{ isSignal: true, alias: "query", required: false }] }], apply: [{ type: i0.Output, args: ["apply"] }] } });
|
|
@@ -145,10 +146,10 @@ class SdQueryActionsBar {
|
|
|
145
146
|
return;
|
|
146
147
|
this.logic.set(value);
|
|
147
148
|
}
|
|
148
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
149
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
149
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQueryActionsBar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
150
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: SdQueryActionsBar, isStandalone: true, selector: "sd-query-actions-bar", inputs: { showLogicToggle: { classPropertyName: "showLogicToggle", publicName: "showLogicToggle", isSignal: true, isRequired: false, transformFunction: null }, logic: { classPropertyName: "logic", publicName: "logic", isSignal: true, isRequired: false, transformFunction: null }, filtersCount: { classPropertyName: "filtersCount", publicName: "filtersCount", isSignal: true, isRequired: false, transformFunction: null }, showSavedFilters: { classPropertyName: "showSavedFilters", publicName: "showSavedFilters", isSignal: true, isRequired: false, transformFunction: null }, savedFiltersKey: { classPropertyName: "savedFiltersKey", publicName: "savedFiltersKey", isSignal: true, isRequired: false, transformFunction: null }, query: { classPropertyName: "query", publicName: "query", isSignal: true, isRequired: false, transformFunction: null }, showClearAll: { classPropertyName: "showClearAll", publicName: "showClearAll", isSignal: true, isRequired: false, transformFunction: null }, canSearch: { classPropertyName: "canSearch", publicName: "canSearch", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { logic: "logicChange", applyFilter: "applyFilter", clear: "clear", search: "search" }, ngImport: i0, template: "<!-- Vertical separator between the wrapping filter area (left) and the pinned toolbar. -->\n<span class=\"c-bar-divider\" aria-hidden=\"true\"></span>\n\n<div class=\"c-query-bar__actions\">\n <!-- AND / OR toggle -->\n @if (showLogicToggle() && filtersCount() >= 2) {\n <div class=\"c-logic-toggle\" role=\"group\" aria-label=\"Logic operator\">\n <button\n type=\"button\"\n class=\"c-logic-segment\"\n [class.c-logic-active]=\"logic() === 'AND'\"\n (click)=\"setLogic('AND')\">\n AND\n </button>\n <button\n type=\"button\"\n class=\"c-logic-segment\"\n [class.c-logic-active]=\"logic() === 'OR'\"\n (click)=\"setLogic('OR')\">\n OR\n </button>\n </div>\n }\n\n @if (showClearAll() && filtersCount() > 0) {\n <button\n type=\"button\"\n class=\"c-clear-all\"\n [matTooltip]=\"'X\u00F3a t\u1EA5t c\u1EA3 (' + filtersCount() + ')'\"\n (click)=\"clear.emit()\">\n <mat-icon fontSet=\"material-icons-outlined\">delete_sweep</mat-icon>\n </button>\n }\n\n <!-- why: saved-filters dropdown \u0111\u1EB7t s\u00E1t ngay tr\u01B0\u1EDBc Search \u2014 gom to\u00E0n b\u1ED9\n h\u00E0nh \u0111\u1ED9ng v\u1EC1 b\u1ED9 l\u1ECDc (apply view c\u0169 / l\u01B0u view hi\u1EC7n t\u1EA1i) c\u1EA1nh n\u00FAt submit,\n user th\u1EA5y 1 c\u1EE5m. Footer \"L\u01B0u b\u1ED9 l\u1ECDc hi\u1EC7n t\u1EA1i\" s\u1ED1ng trong mat-menu c\u1EE7a\n saved-filters-menu, kh\u00F4ng t\u00E1ch ra n\u00FAt ri\u00EAng n\u1EEFa. -->\n @if (showSavedFilters()) {\n <sd-query-saved-filters-menu\n [key]=\"savedFiltersKey()\"\n [query]=\"query()\"\n (apply)=\"applyFilter.emit($event)\" />\n }\n\n <!-- why: far-right \"submit at the end of the toolbar\" position; sole query trigger. -->\n <button\n type=\"button\"\n class=\"c-search-trigger\"\n [disabled]=\"!canSearch()\"\n matTooltip=\"T\u00ECm ki\u1EBFm\"\n (click)=\"search.emit()\">\n <mat-icon fontSet=\"material-icons-outlined\">search</mat-icon>\n </button>\n</div>\n", styles: [":host{display:contents}.c-bar-divider{flex:0 0 auto;align-self:stretch;width:1px;min-height:28px;background:#e2e4e7}.c-query-bar__actions{flex:0 0 auto;display:flex;align-items:center;gap:6px}.c-logic-toggle{display:inline-flex;align-items:center;padding:2px;background:#f5f6f7;border:1px solid #e2e4e7;border-radius:6px}:host-context(.c-density-compact) .c-logic-toggle{height:28px}:host-context(.c-density-comfortable) .c-logic-toggle{height:32px}.c-logic-toggle .c-logic-segment{height:100%;padding:0 10px;border:none;background:transparent;font-family:Roboto Mono,monospace;font-size:11px;font-weight:600;letter-spacing:.4px;color:#5f6368;cursor:pointer;border-radius:4px}.c-logic-toggle .c-logic-segment.c-logic-active{background:#fff;color:var(--sd-primary);box-shadow:0 1px 2px #00000014}.c-clear-all,.c-search-trigger{display:inline-flex;align-items:center;justify-content:center;border:1px solid #d6d8db;border-radius:6px;background:#fff;color:#5f6368;cursor:pointer;padding:0}:host-context(.c-density-compact) .c-clear-all,:host-context(.c-density-compact) .c-search-trigger{width:28px;height:28px}:host-context(.c-density-comfortable) .c-clear-all,:host-context(.c-density-comfortable) .c-search-trigger{width:32px;height:32px}.c-clear-all mat-icon,.c-search-trigger mat-icon{font-size:18px;width:18px;height:18px}.c-clear-all:hover:not([disabled]),.c-search-trigger:hover:not([disabled]){border-color:var(--sd-primary);color:var(--sd-primary)}.c-clear-all[disabled],.c-search-trigger[disabled]{opacity:.5;cursor:not-allowed}.c-clear-all:hover{border-color:#dc2626;color:#dc2626}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: SdQuerySavedFiltersMenu, selector: "sd-query-saved-filters-menu", inputs: ["key", "query"], outputs: ["apply"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
150
151
|
}
|
|
151
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
152
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQueryActionsBar, decorators: [{
|
|
152
153
|
type: Component,
|
|
153
154
|
args: [{ selector: 'sd-query-actions-bar', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIconModule, MatTooltipModule, SdQuerySavedFiltersMenu], template: "<!-- Vertical separator between the wrapping filter area (left) and the pinned toolbar. -->\n<span class=\"c-bar-divider\" aria-hidden=\"true\"></span>\n\n<div class=\"c-query-bar__actions\">\n <!-- AND / OR toggle -->\n @if (showLogicToggle() && filtersCount() >= 2) {\n <div class=\"c-logic-toggle\" role=\"group\" aria-label=\"Logic operator\">\n <button\n type=\"button\"\n class=\"c-logic-segment\"\n [class.c-logic-active]=\"logic() === 'AND'\"\n (click)=\"setLogic('AND')\">\n AND\n </button>\n <button\n type=\"button\"\n class=\"c-logic-segment\"\n [class.c-logic-active]=\"logic() === 'OR'\"\n (click)=\"setLogic('OR')\">\n OR\n </button>\n </div>\n }\n\n @if (showClearAll() && filtersCount() > 0) {\n <button\n type=\"button\"\n class=\"c-clear-all\"\n [matTooltip]=\"'X\u00F3a t\u1EA5t c\u1EA3 (' + filtersCount() + ')'\"\n (click)=\"clear.emit()\">\n <mat-icon fontSet=\"material-icons-outlined\">delete_sweep</mat-icon>\n </button>\n }\n\n <!-- why: saved-filters dropdown \u0111\u1EB7t s\u00E1t ngay tr\u01B0\u1EDBc Search \u2014 gom to\u00E0n b\u1ED9\n h\u00E0nh \u0111\u1ED9ng v\u1EC1 b\u1ED9 l\u1ECDc (apply view c\u0169 / l\u01B0u view hi\u1EC7n t\u1EA1i) c\u1EA1nh n\u00FAt submit,\n user th\u1EA5y 1 c\u1EE5m. Footer \"L\u01B0u b\u1ED9 l\u1ECDc hi\u1EC7n t\u1EA1i\" s\u1ED1ng trong mat-menu c\u1EE7a\n saved-filters-menu, kh\u00F4ng t\u00E1ch ra n\u00FAt ri\u00EAng n\u1EEFa. -->\n @if (showSavedFilters()) {\n <sd-query-saved-filters-menu\n [key]=\"savedFiltersKey()\"\n [query]=\"query()\"\n (apply)=\"applyFilter.emit($event)\" />\n }\n\n <!-- why: far-right \"submit at the end of the toolbar\" position; sole query trigger. -->\n <button\n type=\"button\"\n class=\"c-search-trigger\"\n [disabled]=\"!canSearch()\"\n matTooltip=\"T\u00ECm ki\u1EBFm\"\n (click)=\"search.emit()\">\n <mat-icon fontSet=\"material-icons-outlined\">search</mat-icon>\n </button>\n</div>\n", styles: [":host{display:contents}.c-bar-divider{flex:0 0 auto;align-self:stretch;width:1px;min-height:28px;background:#e2e4e7}.c-query-bar__actions{flex:0 0 auto;display:flex;align-items:center;gap:6px}.c-logic-toggle{display:inline-flex;align-items:center;padding:2px;background:#f5f6f7;border:1px solid #e2e4e7;border-radius:6px}:host-context(.c-density-compact) .c-logic-toggle{height:28px}:host-context(.c-density-comfortable) .c-logic-toggle{height:32px}.c-logic-toggle .c-logic-segment{height:100%;padding:0 10px;border:none;background:transparent;font-family:Roboto Mono,monospace;font-size:11px;font-weight:600;letter-spacing:.4px;color:#5f6368;cursor:pointer;border-radius:4px}.c-logic-toggle .c-logic-segment.c-logic-active{background:#fff;color:var(--sd-primary);box-shadow:0 1px 2px #00000014}.c-clear-all,.c-search-trigger{display:inline-flex;align-items:center;justify-content:center;border:1px solid #d6d8db;border-radius:6px;background:#fff;color:#5f6368;cursor:pointer;padding:0}:host-context(.c-density-compact) .c-clear-all,:host-context(.c-density-compact) .c-search-trigger{width:28px;height:28px}:host-context(.c-density-comfortable) .c-clear-all,:host-context(.c-density-comfortable) .c-search-trigger{width:32px;height:32px}.c-clear-all mat-icon,.c-search-trigger mat-icon{font-size:18px;width:18px;height:18px}.c-clear-all:hover:not([disabled]),.c-search-trigger:hover:not([disabled]){border-color:var(--sd-primary);color:var(--sd-primary)}.c-clear-all[disabled],.c-search-trigger[disabled]{opacity:.5;cursor:not-allowed}.c-clear-all:hover{border-color:#dc2626;color:#dc2626}\n"] }]
|
|
154
155
|
}], propDecorators: { showLogicToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLogicToggle", required: false }] }], logic: [{ type: i0.Input, args: [{ isSignal: true, alias: "logic", required: false }] }, { type: i0.Output, args: ["logicChange"] }], filtersCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "filtersCount", required: false }] }], showSavedFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSavedFilters", required: false }] }], savedFiltersKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "savedFiltersKey", required: false }] }], query: [{ type: i0.Input, args: [{ isSignal: true, alias: "query", required: false }] }], applyFilter: [{ type: i0.Output, args: ["applyFilter"] }], showClearAll: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClearAll", required: false }] }], clear: [{ type: i0.Output, args: ["clear"] }], canSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "canSearch", required: false }] }], search: [{ type: i0.Output, args: ["search"] }] } });
|
|
@@ -299,27 +300,15 @@ class SdQueryInlineValueChip {
|
|
|
299
300
|
this.draft.set(this.#format(v));
|
|
300
301
|
}
|
|
301
302
|
});
|
|
302
|
-
//
|
|
303
|
-
afterNextRender
|
|
304
|
-
if (this.autofocus())
|
|
305
|
-
this.firstInput()?.nativeElement.focus();
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* Width in chars — hugs the current value; falls back to the placeholder width only when
|
|
310
|
-
* empty. why: using placeholder.length unconditionally left a long trailing gap before the
|
|
311
|
-
* × for short values (e.g. a 1-digit number under the 'giá trị' placeholder).
|
|
312
|
-
*/
|
|
313
|
-
sizeFor(text, placeholder) {
|
|
314
|
-
const base = text && text.length > 0 ? text.length : placeholder.length;
|
|
315
|
-
return Math.max(base, 2);
|
|
303
|
+
// why: the build chip lands focused (autofocus) so the user types straight away —
|
|
304
|
+
// <sd-inline-text> owns that via its own [autofocus] input, so no afterNextRender here.
|
|
316
305
|
}
|
|
317
306
|
/** Click anywhere in the pill (except × or an input) focuses the first input. */
|
|
318
307
|
focusFromShell(ev) {
|
|
319
308
|
const target = ev.target;
|
|
320
309
|
if (target.closest('.c-seamless__x') || target.closest('input'))
|
|
321
310
|
return;
|
|
322
|
-
this.firstInput()?.
|
|
311
|
+
this.firstInput()?.focus();
|
|
323
312
|
}
|
|
324
313
|
onFocus() {
|
|
325
314
|
this.focused.set(true);
|
|
@@ -348,7 +337,7 @@ class SdQueryInlineValueChip {
|
|
|
348
337
|
this.valueChange.emit({ from: from.value, to: to.value });
|
|
349
338
|
}
|
|
350
339
|
/** Esc — revert drafts to the committed value and blur without emitting. */
|
|
351
|
-
revertAndBlur(
|
|
340
|
+
revertAndBlur(ref) {
|
|
352
341
|
const v = this.value();
|
|
353
342
|
if (this.isBetween()) {
|
|
354
343
|
const r = (v ?? {});
|
|
@@ -360,7 +349,7 @@ class SdQueryInlineValueChip {
|
|
|
360
349
|
}
|
|
361
350
|
this.hasError.set(false);
|
|
362
351
|
this.focused.set(false);
|
|
363
|
-
|
|
352
|
+
ref?.blur();
|
|
364
353
|
}
|
|
365
354
|
onRemove(ev) {
|
|
366
355
|
ev.stopPropagation();
|
|
@@ -392,12 +381,12 @@ class SdQueryInlineValueChip {
|
|
|
392
381
|
}
|
|
393
382
|
return { ok: true, value: t };
|
|
394
383
|
}
|
|
395
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
396
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
384
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQueryInlineValueChip, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
385
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: SdQueryInlineValueChip, isStandalone: true, selector: "sd-query-inline-value-chip", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, operator: { classPropertyName: "operator", publicName: "operator", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, showOperator: { classPropertyName: "showOperator", publicName: "showOperator", isSignal: true, isRequired: false, transformFunction: null }, autoId: { classPropertyName: "autoId", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", remove: "remove" }, viewQueries: [{ propertyName: "firstInput", first: true, predicate: ["firstInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<!--\n Seamless string/number chip \u2014 the pill IS the input. One border, three flush\n segments: label \u00B7 input(s) \u00B7 \u00D7. State styling driven by [data-state]. The value\n field is the shared <sd-inline-text> primitive (chrome=\"seamless\") so width hugs\n content; the chip keeps the envelope + parse/commit logic.\n-->\n@let _state = state();\n@let _autoId = autoId();\n@let _isNoData = isNoData();\n@let _density = density();\n@let _operator = operator();\n\n<span\n class=\"c-seamless\"\n [attr.data-state]=\"_state\"\n [class.c-seamless--compact]=\"_density === 'compact'\"\n [class.c-seamless--comfortable]=\"_density === 'comfortable'\"\n (click)=\"focusFromShell($event)\">\n\n <!-- Label segment: icon + field name (+ optional operator pill) -->\n <span class=\"c-seamless__label\">\n <mat-icon class=\"c-seamless__icon\" fontSet=\"material-icons-outlined\">{{ icon() }}</mat-icon>\n <span class=\"c-seamless__field\">{{ field().label }}</span>\n @if (showOperator() && !_isNoData) {\n <sd-operator class=\"c-seamless__op\" [operators]=\"[_operator]\" [model]=\"_operator\" [disabled]=\"true\" />\n } @else if (!_isNoData) {\n <span class=\"c-seamless__sep\">:</span>\n }\n </span>\n\n <!-- Input segment \u2014 seamless borderless primitive; hidden for NULL / NOT_NULL -->\n @if (!_isNoData) {\n <span class=\"c-seamless__input\">\n @if (isBetween()) {\n <sd-inline-text\n #firstInput\n chrome=\"seamless\"\n [clearable]=\"false\"\n [autofocus]=\"autofocus()\"\n [state]=\"_state\"\n [value]=\"draftFrom()\"\n (valueChange)=\"draftFrom.set($event)\"\n [placeholder]=\"phFrom()\"\n [autoId]=\"_autoId ? _autoId + '-from' : undefined\"\n (sdFocus)=\"onFocus()\"\n (sdBlur)=\"commitRange()\"\n (keyupEnter)=\"firstInput.blur()\"\n (keydownEscape)=\"revertAndBlur(firstInput)\" />\n <span class=\"c-seamless__dash\" aria-hidden=\"true\">\u2014</span>\n <sd-inline-text\n #secondInput\n chrome=\"seamless\"\n [clearable]=\"false\"\n [state]=\"_state\"\n [value]=\"draftTo()\"\n (valueChange)=\"draftTo.set($event)\"\n [placeholder]=\"phTo()\"\n [autoId]=\"_autoId ? _autoId + '-to' : undefined\"\n (sdFocus)=\"onFocus()\"\n (sdBlur)=\"commitRange()\"\n (keyupEnter)=\"secondInput.blur()\"\n (keydownEscape)=\"revertAndBlur(secondInput)\" />\n } @else {\n <sd-inline-text\n #firstInput\n chrome=\"seamless\"\n [clearable]=\"false\"\n [autofocus]=\"autofocus()\"\n [state]=\"_state\"\n [value]=\"draft()\"\n (valueChange)=\"draft.set($event)\"\n [placeholder]=\"ph()\"\n [autoId]=\"_autoId ?? undefined\"\n (sdFocus)=\"onFocus()\"\n (sdBlur)=\"commitSingle()\"\n (keyupEnter)=\"firstInput.blur()\"\n (keydownEscape)=\"revertAndBlur(firstInput)\" />\n }\n </span>\n }\n\n <!-- \u00D7 segment -->\n <button type=\"button\" class=\"c-seamless__x\" aria-label=\"Remove filter\" (click)=\"onRemove($event)\">\n <mat-icon fontSet=\"material-icons-outlined\">close</mat-icon>\n </button>\n</span>\n", styles: [":host{display:inline-flex}.c-seamless{display:inline-flex;align-items:stretch;border-radius:999px;overflow:hidden;font-family:inherit;font-size:13px;line-height:1;cursor:text;border:1px solid #d6d8db;background:#fff;color:#5f6368;transition:border-color .12s ease,background-color .12s ease,box-shadow .12s ease,color .12s ease}.c-seamless--compact{height:28px}.c-seamless--comfortable{height:32px}.c-seamless:hover:not([data-state=focus]):not([data-state=error]){border-color:var(--sd-primary)}.c-seamless[data-state=pending]{border-style:dashed;border-color:#d6d8db;background:#fff;color:#5f6368}.c-seamless[data-state=active]{border-color:var(--sd-primary-light);background:var(--sd-primary-light)}.c-seamless[data-state=focus]{border-color:var(--sd-primary);background:#fff;box-shadow:0 0 0 3px var(--sd-primary-light)}.c-seamless[data-state=error]{border-color:#d23535;background:#fff5f5;color:#d23535;box-shadow:0 0 0 3px #d235351f}.c-seamless__label{display:inline-flex;align-items:center;gap:4px;font-weight:500;white-space:nowrap;cursor:text;color:inherit}.c-seamless--compact .c-seamless__label{padding:0 0 0 12px}.c-seamless--comfortable .c-seamless__label{padding:0 0 0 14px}.c-seamless__icon{font-size:14px;width:14px;height:14px;color:inherit}.c-seamless__field{color:inherit}.c-seamless__op{display:inline-flex;align-items:center;color:inherit}.c-seamless__sep{color:#7a7a7a}.c-seamless__input{display:inline-flex;align-items:center;gap:4px}.c-seamless--compact .c-seamless__input{padding:0 8px 0 4px}.c-seamless--comfortable .c-seamless__input{padding:0 10px 0 6px}.c-seamless__dash{color:#7a7a7a}.c-seamless__x{display:inline-flex;align-items:center;justify-content:center;border:0;border-left:1px solid rgba(0,0,0,.04);background:transparent;cursor:pointer;color:inherit}.c-seamless--compact .c-seamless__x{width:26px}.c-seamless--comfortable .c-seamless__x{width:28px}.c-seamless__x mat-icon{font-size:14px;width:14px;height:14px}.c-seamless__x:hover{background:#0000000d}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.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: SdInlineText, selector: "sd-inline-text", inputs: ["value", "control", "placeholder", "disabled", "clearable", "state", "chrome", "autoId", "autofocus", "minSize"], outputs: ["valueChange", "cleared", "keyupEnter", "keydownEscape", "sdFocus", "sdBlur", "sdKeydown", "sdPaste", "sdCompositionStart", "sdCompositionEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
397
386
|
}
|
|
398
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
387
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQueryInlineValueChip, decorators: [{
|
|
399
388
|
type: Component,
|
|
400
|
-
args: [{ selector: 'sd-query-inline-value-chip', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
389
|
+
args: [{ selector: 'sd-query-inline-value-chip', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIconModule, SdOperator, SdInlineText], template: "<!--\n Seamless string/number chip \u2014 the pill IS the input. One border, three flush\n segments: label \u00B7 input(s) \u00B7 \u00D7. State styling driven by [data-state]. The value\n field is the shared <sd-inline-text> primitive (chrome=\"seamless\") so width hugs\n content; the chip keeps the envelope + parse/commit logic.\n-->\n@let _state = state();\n@let _autoId = autoId();\n@let _isNoData = isNoData();\n@let _density = density();\n@let _operator = operator();\n\n<span\n class=\"c-seamless\"\n [attr.data-state]=\"_state\"\n [class.c-seamless--compact]=\"_density === 'compact'\"\n [class.c-seamless--comfortable]=\"_density === 'comfortable'\"\n (click)=\"focusFromShell($event)\">\n\n <!-- Label segment: icon + field name (+ optional operator pill) -->\n <span class=\"c-seamless__label\">\n <mat-icon class=\"c-seamless__icon\" fontSet=\"material-icons-outlined\">{{ icon() }}</mat-icon>\n <span class=\"c-seamless__field\">{{ field().label }}</span>\n @if (showOperator() && !_isNoData) {\n <sd-operator class=\"c-seamless__op\" [operators]=\"[_operator]\" [model]=\"_operator\" [disabled]=\"true\" />\n } @else if (!_isNoData) {\n <span class=\"c-seamless__sep\">:</span>\n }\n </span>\n\n <!-- Input segment \u2014 seamless borderless primitive; hidden for NULL / NOT_NULL -->\n @if (!_isNoData) {\n <span class=\"c-seamless__input\">\n @if (isBetween()) {\n <sd-inline-text\n #firstInput\n chrome=\"seamless\"\n [clearable]=\"false\"\n [autofocus]=\"autofocus()\"\n [state]=\"_state\"\n [value]=\"draftFrom()\"\n (valueChange)=\"draftFrom.set($event)\"\n [placeholder]=\"phFrom()\"\n [autoId]=\"_autoId ? _autoId + '-from' : undefined\"\n (sdFocus)=\"onFocus()\"\n (sdBlur)=\"commitRange()\"\n (keyupEnter)=\"firstInput.blur()\"\n (keydownEscape)=\"revertAndBlur(firstInput)\" />\n <span class=\"c-seamless__dash\" aria-hidden=\"true\">\u2014</span>\n <sd-inline-text\n #secondInput\n chrome=\"seamless\"\n [clearable]=\"false\"\n [state]=\"_state\"\n [value]=\"draftTo()\"\n (valueChange)=\"draftTo.set($event)\"\n [placeholder]=\"phTo()\"\n [autoId]=\"_autoId ? _autoId + '-to' : undefined\"\n (sdFocus)=\"onFocus()\"\n (sdBlur)=\"commitRange()\"\n (keyupEnter)=\"secondInput.blur()\"\n (keydownEscape)=\"revertAndBlur(secondInput)\" />\n } @else {\n <sd-inline-text\n #firstInput\n chrome=\"seamless\"\n [clearable]=\"false\"\n [autofocus]=\"autofocus()\"\n [state]=\"_state\"\n [value]=\"draft()\"\n (valueChange)=\"draft.set($event)\"\n [placeholder]=\"ph()\"\n [autoId]=\"_autoId ?? undefined\"\n (sdFocus)=\"onFocus()\"\n (sdBlur)=\"commitSingle()\"\n (keyupEnter)=\"firstInput.blur()\"\n (keydownEscape)=\"revertAndBlur(firstInput)\" />\n }\n </span>\n }\n\n <!-- \u00D7 segment -->\n <button type=\"button\" class=\"c-seamless__x\" aria-label=\"Remove filter\" (click)=\"onRemove($event)\">\n <mat-icon fontSet=\"material-icons-outlined\">close</mat-icon>\n </button>\n</span>\n", styles: [":host{display:inline-flex}.c-seamless{display:inline-flex;align-items:stretch;border-radius:999px;overflow:hidden;font-family:inherit;font-size:13px;line-height:1;cursor:text;border:1px solid #d6d8db;background:#fff;color:#5f6368;transition:border-color .12s ease,background-color .12s ease,box-shadow .12s ease,color .12s ease}.c-seamless--compact{height:28px}.c-seamless--comfortable{height:32px}.c-seamless:hover:not([data-state=focus]):not([data-state=error]){border-color:var(--sd-primary)}.c-seamless[data-state=pending]{border-style:dashed;border-color:#d6d8db;background:#fff;color:#5f6368}.c-seamless[data-state=active]{border-color:var(--sd-primary-light);background:var(--sd-primary-light)}.c-seamless[data-state=focus]{border-color:var(--sd-primary);background:#fff;box-shadow:0 0 0 3px var(--sd-primary-light)}.c-seamless[data-state=error]{border-color:#d23535;background:#fff5f5;color:#d23535;box-shadow:0 0 0 3px #d235351f}.c-seamless__label{display:inline-flex;align-items:center;gap:4px;font-weight:500;white-space:nowrap;cursor:text;color:inherit}.c-seamless--compact .c-seamless__label{padding:0 0 0 12px}.c-seamless--comfortable .c-seamless__label{padding:0 0 0 14px}.c-seamless__icon{font-size:14px;width:14px;height:14px;color:inherit}.c-seamless__field{color:inherit}.c-seamless__op{display:inline-flex;align-items:center;color:inherit}.c-seamless__sep{color:#7a7a7a}.c-seamless__input{display:inline-flex;align-items:center;gap:4px}.c-seamless--compact .c-seamless__input{padding:0 8px 0 4px}.c-seamless--comfortable .c-seamless__input{padding:0 10px 0 6px}.c-seamless__dash{color:#7a7a7a}.c-seamless__x{display:inline-flex;align-items:center;justify-content:center;border:0;border-left:1px solid rgba(0,0,0,.04);background:transparent;cursor:pointer;color:inherit}.c-seamless--compact .c-seamless__x{width:26px}.c-seamless--comfortable .c-seamless__x{width:28px}.c-seamless__x mat-icon{font-size:14px;width:14px;height:14px}.c-seamless__x:hover{background:#0000000d}\n"] }]
|
|
401
390
|
}], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], operator: [{ type: i0.Input, args: [{ isSignal: true, alias: "operator", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], showOperator: [{ type: i0.Input, args: [{ isSignal: true, alias: "showOperator", required: false }] }], autoId: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], autofocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autofocus", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], remove: [{ type: i0.Output, args: ["remove"] }], firstInput: [{ type: i0.ViewChild, args: ['firstInput', { isSignal: true }] }] } });
|
|
402
391
|
|
|
403
392
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
@@ -479,10 +468,10 @@ class SdQueryBuildChip {
|
|
|
479
468
|
const t = b.field.type;
|
|
480
469
|
return t === 'string' || t === 'number';
|
|
481
470
|
}, ...(ngDevMode ? [{ debugName: "isSeamless" }] : /* istanbul ignore next */ []));
|
|
482
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
483
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: SdQueryBuildChip, isStandalone: true, selector: "sd-query-build-chip", inputs: { building: { classPropertyName: "building", publicName: "building", isSignal: true, isRequired: true, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, allowedOperators: { classPropertyName: "allowedOperators", publicName: "allowedOperators", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, showOperator: { classPropertyName: "showOperator", publicName: "showOperator", isSignal: true, isRequired: false, transformFunction: null }, autoId: { classPropertyName: "autoId", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pickOperator: "pickOperator", commitValue: "commitValue", cancel: "cancel", seamlessCommit: "seamlessCommit", draftChange: "draftChange", draftCommit: "draftCommit" }, viewQueries: [{ propertyName: "opMenu", first: true, predicate: ["buildOperator"], descendants: true, isSignal: true }, { propertyName: "picker", first: true, predicate: ["bPicker"], descendants: true, isSignal: true }], ngImport: i0, template: "<!--\n In-progress chip (inline-mode token build flow).\n Seamless string/number branch keeps its own pill; everything else renders inside\n the dashed .c-token.c-token-building shell.\n-->\n@let _b = building();\n\n@if (isSeamless()) {\n <sd-query-inline-value-chip\n [field]=\"_b.field\"\n [operator]=\"$any(_b.operator)\"\n [value]=\"_b.value ?? null\"\n [density]=\"density()\"\n [showOperator]=\"showOperator()\"\n [autoId]=\"autoId()\"\n [autofocus]=\"true\"\n (valueChange)=\"seamlessCommit.emit($event)\"\n (remove)=\"cancel.emit()\" />\n} @else {\n <div class=\"c-token c-token-building\">\n <span class=\"c-token-field\">{{ _b.field.label }}</span>\n\n @if (_b.step === 'operator') {\n <sd-operator\n #buildOperator\n class=\"c-token-op\"\n [operators]=\"allowedOperators()\"\n [model]=\"_b.operator\"\n (modelChange)=\"pickOperator.emit($any($event))\" />\n } @else {\n <!-- why: badge readonly cho operator \u0111\u00E3 ch\u1ECDn \u2014 v\u1EABn render <sd-operator>\n \u0111\u1EC3 gi\u1EEF th\u1ECB gi\u00E1c gi\u1ED1ng chip ho\u00E0n th\u00E0nh (icon + tooltip). -->\n <sd-operator\n class=\"c-token-op\"\n [operators]=\"[$any(_b.operator)]\"\n [model]=\"$any(_b.operator)\"\n [disabled]=\"true\" />\n\n @if (_b.field.type === 'values' || _b.field.type === 'lazy-values') {\n @let _bopt = $any(_b.field).option;\n <span class=\"c-token-value c-token-value-edit\">\n <sd-select #bPicker bare size=\"sm\" minWidthPanel=\"300px\"\n [autoId]=\"autoId()\"\n [items]=\"_b.field.type === 'lazy-values' ? $any(_bopt).search : $any(_bopt.items)\"\n [valueField]=\"_bopt.valueField\"\n [displayField]=\"_bopt.displayField\"\n [multiple]=\"multiple()\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"commitValue.emit($event)\">\n <!-- why: build chip multi-select c\u0169ng c\u1EA7n \"head +N\" \u0111\u1EC3 g\u1ECDn (gi\u1ED1ng completed chip). -->\n <ng-template #sdValue let-selectedItems=\"selectedItems\">\n @if ((selectedItems?.length ?? 0) > 1) {\n <span class=\"c-token-multi-head\">{{ $any(selectedItems)[0][_bopt.displayField] }}</span> +{{ selectedItems.length - 1 }}\n } @else if ((selectedItems?.length ?? 0) === 1) {\n <span class=\"c-token-multi-head\">{{ $any(selectedItems)[0][_bopt.displayField] }}</span>\n }\n </ng-template>\n </sd-select>\n </span>\n } @else if (_b.field.type === 'date') {\n <span class=\"c-token-value c-token-value-edit\">\n @if (_b.operator === 'BETWEEN') {\n <!-- why: 1 sd-date-range thay 2 sd-date \u2014 g\u1ECDn h\u01A1n, h\u00E0nh vi th\u1ED1ng nh\u1EA5t v\u1EDBi completed chip. -->\n <sd-date-range #bPicker bare size=\"sm\"\n [autoId]=\"autoId()\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"commitValue.emit($event)\"></sd-date-range>\n } @else {\n <sd-date #bPicker bare size=\"sm\"\n [autoId]=\"autoId()\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"commitValue.emit($event)\"></sd-date>\n }\n </span>\n } @else if (_b.field.type === 'datetime') {\n <span class=\"c-token-value c-token-value-edit\">\n @if (_b.operator === 'BETWEEN') {\n <!-- why: datetime BETWEEN downgrade v\u1EC1 date-range (m\u1EA5t time precision; \u0111\u00E3 th\u1ED1ng nh\u1EA5t). -->\n <sd-date-range #bPicker bare size=\"sm\"\n [autoId]=\"autoId()\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"commitValue.emit($event)\"></sd-date-range>\n } @else {\n <sd-datetime #bPicker bare size=\"sm\"\n [autoId]=\"autoId()\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"commitValue.emit($event)\"></sd-datetime>\n }\n </span>\n } @else if (_b.field.type === 'boolean') {\n <!-- why: native button thay sd-button (tr\u00E1nh mat-button baseline 36px g\u00E2y tr\u00E0n).\n Pill nh\u1ECF v\u1EBD b\u1EB1ng CSS scoped trong chip \u2014 gi\u1EEF semantic colour qua class\n .c-bool-true / .c-bool-false. -->\n <span class=\"c-token-value c-token-value-edit c-bool-toggle\">\n <button\n type=\"button\"\n class=\"c-bool-btn c-bool-true\"\n [class.c-bool-active]=\"_b.value === true\"\n [attr.data-autoId]=\"autoId() + '-true'\"\n (click)=\"commitValue.emit(true)\">\n {{ $any(_b.field).trueLabel || 'C\u00F3' }}\n </button>\n <button\n type=\"button\"\n class=\"c-bool-btn c-bool-false\"\n [class.c-bool-active]=\"_b.value === false\"\n [attr.data-autoId]=\"autoId() + '-false'\"\n (click)=\"commitValue.emit(false)\">\n {{ $any(_b.field).falseLabel || 'Kh\u00F4ng' }}\n </button>\n </span>\n } @else {\n <!-- Fallback (e.g. unforeseen type) \u2014 generic sd-input wired via draft outputs. -->\n <span class=\"c-token-value c-token-value-edit\">\n <sd-input size=\"sm\"\n [autoId]=\"autoId()\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"draftChange.emit($event)\"\n (keyupEnter)=\"draftCommit.emit()\"></sd-input>\n </span>\n }\n }\n\n <button type=\"button\" class=\"c-token-remove\" aria-label=\"Cancel\" (click)=\"cancel.emit()\">\n <mat-icon fontSet=\"material-icons-outlined\">close</mat-icon>\n </button>\n </div>\n}\n", styles: [":host{display:contents}.c-token{display:inline-flex;align-items:center;gap:4px;padding:0 0 0 12px;border:1px solid var(--sd-primary-light);border-radius:999px;background:var(--sd-primary-light);font-size:13px;color:#5f6368;white-space:nowrap;overflow:hidden}:host-context(.c-density-compact) .c-token{height:28px}:host-context(.c-density-comfortable) .c-token{height:32px}.c-token-field{font-weight:500;line-height:1}.c-token-op{display:inline-flex;align-items:center;color:inherit}.c-token-op ::ng-deep .c-op-trigger{padding:0;color:inherit}.c-token-op ::ng-deep .c-op-icon svg{width:14px;height:14px;display:block}.c-token-value{border:none;background:transparent;padding:0;font:inherit;font-weight:500;color:var(--sd-primary)}.c-token-value-edit{display:inline-flex;align-items:center;gap:4px;max-width:240px}.c-token-value-edit sd-input,.c-token-value-edit sd-input-number{display:inline-flex;max-width:140px}.c-token-value-edit sd-date-range{display:inline-flex;max-width:220px;min-width:0;flex:0 1 auto}.c-token-value-edit sd-select,.c-token-value-edit sd-date,.c-token-value-edit sd-datetime{display:inline-flex;align-items:center;line-height:1}.c-token ::ng-deep .mat-mdc-form-field{line-height:1}.c-token ::ng-deep .mat-mdc-text-field-wrapper,.c-token ::ng-deep .mat-mdc-form-field-flex{padding:0;min-height:0;background:transparent}.c-token ::ng-deep .mat-mdc-form-field-infix{padding:0;min-height:0;width:auto;border:0;display:inline-flex;align-items:center}.c-token ::ng-deep .mat-mdc-select-value,.c-token ::ng-deep .mat-mdc-input-element,.c-token ::ng-deep input{line-height:1;font-size:13px;padding:0;height:auto;color:inherit}.c-token ::ng-deep .mat-mdc-select-value{display:inline-flex;align-items:center;min-width:0;max-width:200px;overflow:hidden;text-overflow:ellipsis;color:var(--sd-primary);font-weight:500}.c-token ::ng-deep .sd-suffix-icon{display:none}.c-token-multi-head{display:inline-block;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}.c-token-building{border-style:dashed}.c-bool-toggle{display:inline-flex;align-items:center;gap:4px}.c-bool-btn{display:inline-flex;align-items:center;justify-content:center;height:18px;min-width:0;padding:0 8px;border:1px solid currentColor;border-radius:999px;background:transparent;font:inherit;font-size:11px;font-weight:500;line-height:1;cursor:pointer;white-space:nowrap;-webkit-user-select:none;user-select:none;transition:background .12s ease,color .12s ease}:host-context(.c-density-comfortable) .c-bool-btn{height:20px;padding:0 10px;font-size:12px}.c-bool-true{color:var(--sd-success)}.c-bool-false{color:var(--sd-warning)}.c-bool-active.c-bool-true{background:var(--sd-success);color:#fff;border-color:var(--sd-success)}.c-bool-active.c-bool-false{background:var(--sd-warning);color:#fff;border-color:var(--sd-warning)}.c-bool-btn:hover:not(.c-bool-active).c-bool-true{background:var(--sd-success-light)}.c-bool-btn:hover:not(.c-bool-active).c-bool-false{background:var(--sd-warning-light)}.c-token-remove{align-self:stretch;display:inline-flex;align-items:center;justify-content:center;border:none;border-left:1px solid rgba(0,0,0,.04);border-radius:0;background:transparent;cursor:pointer;color:inherit}:host-context(.c-density-compact) .c-token-remove{width:26px}:host-context(.c-density-comfortable) .c-token-remove{width:28px}.c-token-remove mat-icon{font-size:14px;width:14px;height:14px}.c-token-remove:hover{background:#0000000d}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.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: SdDate, selector: "sd-date", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "bare", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdDateRange, selector: "sd-date-range", inputs: ["autoId", "name", "size", "form", "label", "helperText", "hideInlineError", "required", "disabled", "bare", "viewed", "appearance", "floatLabel", "min", "max", "model"], outputs: ["modelChange", "sdChange"] }, { kind: "component", type: SdDatetime, selector: "sd-datetime", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "showSeconds", "bare", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: 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: SdSelect, selector: "sd-select", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "valueField", "displayField", "disabledField", "cacheChecksum", "limit", "hyperlink", "minWidthPanel", "hideInlineError", "required", "disabled", "viewed", "multiple", "bare", "validator", "inlineError", "appearance", "floatLabel", "items", "model"], outputs: ["modelChange", "sdChange", "sdSelection"] }, { kind: "component", type: SdQueryInlineValueChip, selector: "sd-query-inline-value-chip", inputs: ["field", "operator", "value", "density", "showOperator", "autoId", "autofocus"], outputs: ["valueChange", "remove"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
471
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQueryBuildChip, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
472
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: SdQueryBuildChip, isStandalone: true, selector: "sd-query-build-chip", inputs: { building: { classPropertyName: "building", publicName: "building", isSignal: true, isRequired: true, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, allowedOperators: { classPropertyName: "allowedOperators", publicName: "allowedOperators", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, showOperator: { classPropertyName: "showOperator", publicName: "showOperator", isSignal: true, isRequired: false, transformFunction: null }, autoId: { classPropertyName: "autoId", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pickOperator: "pickOperator", commitValue: "commitValue", cancel: "cancel", seamlessCommit: "seamlessCommit", draftChange: "draftChange", draftCommit: "draftCommit" }, viewQueries: [{ propertyName: "opMenu", first: true, predicate: ["buildOperator"], descendants: true, isSignal: true }, { propertyName: "picker", first: true, predicate: ["bPicker"], descendants: true, isSignal: true }], ngImport: i0, template: "<!--\n In-progress chip (inline-mode token build flow).\n Seamless string/number branch keeps its own pill; everything else renders inside\n the dashed .c-token.c-token-building shell.\n-->\n@let _b = building();\n@let _autoId = autoId();\n\n@if (isSeamless()) {\n <sd-query-inline-value-chip\n [field]=\"_b.field\"\n [operator]=\"$any(_b.operator)\"\n [value]=\"_b.value ?? null\"\n [density]=\"density()\"\n [showOperator]=\"showOperator()\"\n [autoId]=\"_autoId\"\n [autofocus]=\"true\"\n (valueChange)=\"seamlessCommit.emit($event)\"\n (remove)=\"cancel.emit()\" />\n} @else {\n <div class=\"c-token c-token-building\">\n <span class=\"c-token-field\">{{ _b.field.label }}</span>\n\n @if (_b.step === 'operator') {\n <sd-operator\n #buildOperator\n class=\"c-token-op\"\n [operators]=\"allowedOperators()\"\n [model]=\"_b.operator\"\n (modelChange)=\"pickOperator.emit($any($event))\" />\n } @else {\n <!-- why: badge readonly cho operator \u0111\u00E3 ch\u1ECDn \u2014 v\u1EABn render <sd-operator>\n \u0111\u1EC3 gi\u1EEF th\u1ECB gi\u00E1c gi\u1ED1ng chip ho\u00E0n th\u00E0nh (icon + tooltip). -->\n <sd-operator\n class=\"c-token-op\"\n [operators]=\"[$any(_b.operator)]\"\n [model]=\"$any(_b.operator)\"\n [disabled]=\"true\" />\n\n @if (_b.field.type === 'values' || _b.field.type === 'lazy-values') {\n @let _bopt = $any(_b.field).option;\n <span class=\"c-token-value c-token-value-edit\">\n <sd-select #bPicker size=\"sm\" [viewed]=\"'inline'\" [clearable]=\"false\" minWidthPanel=\"300px\"\n [autoId]=\"_autoId\"\n [items]=\"_b.field.type === 'lazy-values' ? $any(_bopt).search : $any(_bopt.items)\"\n [valueField]=\"_bopt.valueField\"\n [displayField]=\"_bopt.displayField\"\n [multiple]=\"multiple()\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"commitValue.emit($event)\">\n <!-- why: build chip multi-select c\u0169ng c\u1EA7n \"head +N\" \u0111\u1EC3 g\u1ECDn (gi\u1ED1ng completed chip). -->\n <ng-template #sdValue let-selectedItems=\"selectedItems\">\n @if ((selectedItems?.length ?? 0) > 1) {\n <span class=\"c-token-multi-head\">{{ $any(selectedItems)[0][_bopt.displayField] }}</span> +{{ selectedItems.length - 1 }}\n } @else if ((selectedItems?.length ?? 0) === 1) {\n <span class=\"c-token-multi-head\">{{ $any(selectedItems)[0][_bopt.displayField] }}</span>\n }\n </ng-template>\n </sd-select>\n </span>\n } @else if (_b.field.type === 'date') {\n <span class=\"c-token-value c-token-value-edit\">\n @if (_b.operator === 'BETWEEN') {\n <!-- why: 1 sd-date-range thay 2 sd-date \u2014 g\u1ECDn h\u01A1n, h\u00E0nh vi th\u1ED1ng nh\u1EA5t v\u1EDBi completed chip. -->\n <sd-date-range #bPicker size=\"sm\" [viewed]=\"'inline'\" [clearable]=\"false\"\n [autoId]=\"_autoId\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"commitValue.emit($event)\"></sd-date-range>\n } @else {\n <sd-date #bPicker size=\"sm\" [viewed]=\"'inline'\" [clearable]=\"false\"\n [autoId]=\"_autoId\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"commitValue.emit($event)\"></sd-date>\n }\n </span>\n } @else if (_b.field.type === 'datetime') {\n <span class=\"c-token-value c-token-value-edit\">\n @if (_b.operator === 'BETWEEN') {\n <!-- why: datetime BETWEEN downgrade v\u1EC1 date-range (m\u1EA5t time precision; \u0111\u00E3 th\u1ED1ng nh\u1EA5t). -->\n <sd-date-range #bPicker size=\"sm\" [viewed]=\"'inline'\" [clearable]=\"false\"\n [autoId]=\"_autoId\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"commitValue.emit($event)\"></sd-date-range>\n } @else {\n <sd-datetime #bPicker size=\"sm\" [viewed]=\"'inline'\" [clearable]=\"false\"\n [autoId]=\"_autoId\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"commitValue.emit($event)\"></sd-datetime>\n }\n </span>\n } @else if (_b.field.type === 'boolean') {\n <!-- why: native button thay sd-button (tr\u00E1nh mat-button baseline 36px g\u00E2y tr\u00E0n).\n Pill nh\u1ECF v\u1EBD b\u1EB1ng CSS scoped trong chip \u2014 gi\u1EEF semantic colour qua class\n .c-bool-true / .c-bool-false. -->\n <span class=\"c-token-value c-token-value-edit c-bool-toggle\">\n <button\n type=\"button\"\n class=\"c-bool-btn c-bool-true\"\n [class.c-bool-active]=\"_b.value === true\"\n [attr.data-autoId]=\"_autoId + '-true'\"\n (click)=\"commitValue.emit(true)\">\n {{ $any(_b.field).trueLabel || 'C\u00F3' }}\n </button>\n <button\n type=\"button\"\n class=\"c-bool-btn c-bool-false\"\n [class.c-bool-active]=\"_b.value === false\"\n [attr.data-autoId]=\"_autoId + '-false'\"\n (click)=\"commitValue.emit(false)\">\n {{ $any(_b.field).falseLabel || 'Kh\u00F4ng' }}\n </button>\n </span>\n } @else {\n <!-- Fallback (e.g. unforeseen type) \u2014 generic sd-input wired via draft outputs. -->\n <span class=\"c-token-value c-token-value-edit\">\n <sd-input size=\"sm\"\n [autoId]=\"_autoId\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"draftChange.emit($event)\"\n (keyupEnter)=\"draftCommit.emit()\"></sd-input>\n </span>\n }\n }\n\n <button type=\"button\" class=\"c-token-remove\" aria-label=\"Cancel\" (click)=\"cancel.emit()\">\n <mat-icon fontSet=\"material-icons-outlined\">close</mat-icon>\n </button>\n </div>\n}\n", styles: [":host{display:contents}.c-token{display:inline-flex;align-items:center;gap:4px;padding:0 0 0 12px;border:1px solid var(--sd-primary-light);border-radius:999px;background:var(--sd-primary-light);font-size:13px;color:#5f6368;white-space:nowrap;overflow:hidden}:host-context(.c-density-compact) .c-token{height:28px}:host-context(.c-density-comfortable) .c-token{height:32px}.c-token-field{font-weight:500;line-height:1}.c-token-op{display:inline-flex;align-items:center;color:inherit}.c-token-op ::ng-deep .c-op-trigger{padding:0;color:inherit}.c-token-op ::ng-deep .c-op-icon svg{width:14px;height:14px;display:block}.c-token-value{border:none;background:transparent;padding:0;font:inherit;font-weight:500;color:var(--sd-primary)}.c-token-value-edit{display:inline-flex;align-items:center;gap:4px;max-width:240px}.c-token-value-edit sd-input,.c-token-value-edit sd-input-number{display:inline-flex;max-width:140px}.c-token-value-edit sd-date-range{display:inline-flex;max-width:220px;min-width:0;flex:0 1 auto}.c-token-value-edit sd-select,.c-token-value-edit sd-date,.c-token-value-edit sd-datetime{display:inline-flex;align-items:center;line-height:1}.c-token ::ng-deep .mat-mdc-form-field{line-height:1}.c-token ::ng-deep .mat-mdc-text-field-wrapper,.c-token ::ng-deep .mat-mdc-form-field-flex{padding:0;min-height:0;background:transparent}.c-token ::ng-deep .mat-mdc-form-field-infix{padding:0;min-height:0;width:auto;border:0;display:inline-flex;align-items:center}.c-token ::ng-deep .mat-mdc-select-value,.c-token ::ng-deep .mat-mdc-input-element,.c-token ::ng-deep input{line-height:1;font-size:13px;padding:0;height:auto;color:inherit}.c-token ::ng-deep .mat-mdc-select-value{display:inline-flex;align-items:center;min-width:0;max-width:200px;overflow:hidden;text-overflow:ellipsis;color:var(--sd-primary);font-weight:500}.c-token ::ng-deep .sd-suffix-icon{display:none}.c-token-multi-head{display:inline-block;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}.c-token-building{border-style:dashed}.c-bool-toggle{display:inline-flex;align-items:center;gap:4px}.c-bool-btn{display:inline-flex;align-items:center;justify-content:center;height:18px;min-width:0;padding:0 8px;border:1px solid currentColor;border-radius:999px;background:transparent;font:inherit;font-size:11px;font-weight:500;line-height:1;cursor:pointer;white-space:nowrap;-webkit-user-select:none;user-select:none;transition:background .12s ease,color .12s ease}:host-context(.c-density-comfortable) .c-bool-btn{height:20px;padding:0 10px;font-size:12px}.c-bool-true{color:var(--sd-success)}.c-bool-false{color:var(--sd-warning)}.c-bool-active.c-bool-true{background:var(--sd-success);color:#fff;border-color:var(--sd-success)}.c-bool-active.c-bool-false{background:var(--sd-warning);color:#fff;border-color:var(--sd-warning)}.c-bool-btn:hover:not(.c-bool-active).c-bool-true{background:var(--sd-success-light)}.c-bool-btn:hover:not(.c-bool-active).c-bool-false{background:var(--sd-warning-light)}.c-token-remove{align-self:stretch;display:inline-flex;align-items:center;justify-content:center;border:none;border-left:1px solid rgba(0,0,0,.04);border-radius:0;background:transparent;cursor:pointer;color:inherit}:host-context(.c-density-compact) .c-token-remove{width:26px}:host-context(.c-density-comfortable) .c-token-remove{width:28px}.c-token-remove mat-icon{font-size:14px;width:14px;height:14px}.c-token-remove:hover{background:#0000000d}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.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: SdDate, selector: "sd-date", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "clearable", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdDateRange, selector: "sd-date-range", inputs: ["autoId", "name", "size", "form", "label", "helperText", "hideInlineError", "required", "disabled", "viewed", "clearable", "appearance", "floatLabel", "min", "max", "model"], outputs: ["modelChange", "sdChange"] }, { kind: "component", type: SdDatetime, selector: "sd-datetime", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "showSeconds", "clearable", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: 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: 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: SdQueryInlineValueChip, selector: "sd-query-inline-value-chip", inputs: ["field", "operator", "value", "density", "showOperator", "autoId", "autofocus"], outputs: ["valueChange", "remove"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
484
473
|
}
|
|
485
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
474
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQueryBuildChip, decorators: [{
|
|
486
475
|
type: Component,
|
|
487
476
|
args: [{ selector: 'sd-query-build-chip', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
488
477
|
CommonModule,
|
|
@@ -495,7 +484,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
495
484
|
SdInputNumber,
|
|
496
485
|
SdSelect,
|
|
497
486
|
SdQueryInlineValueChip,
|
|
498
|
-
], template: "<!--\n In-progress chip (inline-mode token build flow).\n Seamless string/number branch keeps its own pill; everything else renders inside\n the dashed .c-token.c-token-building shell.\n-->\n@let _b = building();\n\n@if (isSeamless()) {\n <sd-query-inline-value-chip\n [field]=\"_b.field\"\n [operator]=\"$any(_b.operator)\"\n [value]=\"_b.value ?? null\"\n [density]=\"density()\"\n [showOperator]=\"showOperator()\"\n [autoId]=\"
|
|
487
|
+
], template: "<!--\n In-progress chip (inline-mode token build flow).\n Seamless string/number branch keeps its own pill; everything else renders inside\n the dashed .c-token.c-token-building shell.\n-->\n@let _b = building();\n@let _autoId = autoId();\n\n@if (isSeamless()) {\n <sd-query-inline-value-chip\n [field]=\"_b.field\"\n [operator]=\"$any(_b.operator)\"\n [value]=\"_b.value ?? null\"\n [density]=\"density()\"\n [showOperator]=\"showOperator()\"\n [autoId]=\"_autoId\"\n [autofocus]=\"true\"\n (valueChange)=\"seamlessCommit.emit($event)\"\n (remove)=\"cancel.emit()\" />\n} @else {\n <div class=\"c-token c-token-building\">\n <span class=\"c-token-field\">{{ _b.field.label }}</span>\n\n @if (_b.step === 'operator') {\n <sd-operator\n #buildOperator\n class=\"c-token-op\"\n [operators]=\"allowedOperators()\"\n [model]=\"_b.operator\"\n (modelChange)=\"pickOperator.emit($any($event))\" />\n } @else {\n <!-- why: badge readonly cho operator \u0111\u00E3 ch\u1ECDn \u2014 v\u1EABn render <sd-operator>\n \u0111\u1EC3 gi\u1EEF th\u1ECB gi\u00E1c gi\u1ED1ng chip ho\u00E0n th\u00E0nh (icon + tooltip). -->\n <sd-operator\n class=\"c-token-op\"\n [operators]=\"[$any(_b.operator)]\"\n [model]=\"$any(_b.operator)\"\n [disabled]=\"true\" />\n\n @if (_b.field.type === 'values' || _b.field.type === 'lazy-values') {\n @let _bopt = $any(_b.field).option;\n <span class=\"c-token-value c-token-value-edit\">\n <sd-select #bPicker size=\"sm\" [viewed]=\"'inline'\" [clearable]=\"false\" minWidthPanel=\"300px\"\n [autoId]=\"_autoId\"\n [items]=\"_b.field.type === 'lazy-values' ? $any(_bopt).search : $any(_bopt.items)\"\n [valueField]=\"_bopt.valueField\"\n [displayField]=\"_bopt.displayField\"\n [multiple]=\"multiple()\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"commitValue.emit($event)\">\n <!-- why: build chip multi-select c\u0169ng c\u1EA7n \"head +N\" \u0111\u1EC3 g\u1ECDn (gi\u1ED1ng completed chip). -->\n <ng-template #sdValue let-selectedItems=\"selectedItems\">\n @if ((selectedItems?.length ?? 0) > 1) {\n <span class=\"c-token-multi-head\">{{ $any(selectedItems)[0][_bopt.displayField] }}</span> +{{ selectedItems.length - 1 }}\n } @else if ((selectedItems?.length ?? 0) === 1) {\n <span class=\"c-token-multi-head\">{{ $any(selectedItems)[0][_bopt.displayField] }}</span>\n }\n </ng-template>\n </sd-select>\n </span>\n } @else if (_b.field.type === 'date') {\n <span class=\"c-token-value c-token-value-edit\">\n @if (_b.operator === 'BETWEEN') {\n <!-- why: 1 sd-date-range thay 2 sd-date \u2014 g\u1ECDn h\u01A1n, h\u00E0nh vi th\u1ED1ng nh\u1EA5t v\u1EDBi completed chip. -->\n <sd-date-range #bPicker size=\"sm\" [viewed]=\"'inline'\" [clearable]=\"false\"\n [autoId]=\"_autoId\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"commitValue.emit($event)\"></sd-date-range>\n } @else {\n <sd-date #bPicker size=\"sm\" [viewed]=\"'inline'\" [clearable]=\"false\"\n [autoId]=\"_autoId\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"commitValue.emit($event)\"></sd-date>\n }\n </span>\n } @else if (_b.field.type === 'datetime') {\n <span class=\"c-token-value c-token-value-edit\">\n @if (_b.operator === 'BETWEEN') {\n <!-- why: datetime BETWEEN downgrade v\u1EC1 date-range (m\u1EA5t time precision; \u0111\u00E3 th\u1ED1ng nh\u1EA5t). -->\n <sd-date-range #bPicker size=\"sm\" [viewed]=\"'inline'\" [clearable]=\"false\"\n [autoId]=\"_autoId\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"commitValue.emit($event)\"></sd-date-range>\n } @else {\n <sd-datetime #bPicker size=\"sm\" [viewed]=\"'inline'\" [clearable]=\"false\"\n [autoId]=\"_autoId\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"commitValue.emit($event)\"></sd-datetime>\n }\n </span>\n } @else if (_b.field.type === 'boolean') {\n <!-- why: native button thay sd-button (tr\u00E1nh mat-button baseline 36px g\u00E2y tr\u00E0n).\n Pill nh\u1ECF v\u1EBD b\u1EB1ng CSS scoped trong chip \u2014 gi\u1EEF semantic colour qua class\n .c-bool-true / .c-bool-false. -->\n <span class=\"c-token-value c-token-value-edit c-bool-toggle\">\n <button\n type=\"button\"\n class=\"c-bool-btn c-bool-true\"\n [class.c-bool-active]=\"_b.value === true\"\n [attr.data-autoId]=\"_autoId + '-true'\"\n (click)=\"commitValue.emit(true)\">\n {{ $any(_b.field).trueLabel || 'C\u00F3' }}\n </button>\n <button\n type=\"button\"\n class=\"c-bool-btn c-bool-false\"\n [class.c-bool-active]=\"_b.value === false\"\n [attr.data-autoId]=\"_autoId + '-false'\"\n (click)=\"commitValue.emit(false)\">\n {{ $any(_b.field).falseLabel || 'Kh\u00F4ng' }}\n </button>\n </span>\n } @else {\n <!-- Fallback (e.g. unforeseen type) \u2014 generic sd-input wired via draft outputs. -->\n <span class=\"c-token-value c-token-value-edit\">\n <sd-input size=\"sm\"\n [autoId]=\"_autoId\"\n [model]=\"$any(_b.value)\"\n (sdChange)=\"draftChange.emit($event)\"\n (keyupEnter)=\"draftCommit.emit()\"></sd-input>\n </span>\n }\n }\n\n <button type=\"button\" class=\"c-token-remove\" aria-label=\"Cancel\" (click)=\"cancel.emit()\">\n <mat-icon fontSet=\"material-icons-outlined\">close</mat-icon>\n </button>\n </div>\n}\n", styles: [":host{display:contents}.c-token{display:inline-flex;align-items:center;gap:4px;padding:0 0 0 12px;border:1px solid var(--sd-primary-light);border-radius:999px;background:var(--sd-primary-light);font-size:13px;color:#5f6368;white-space:nowrap;overflow:hidden}:host-context(.c-density-compact) .c-token{height:28px}:host-context(.c-density-comfortable) .c-token{height:32px}.c-token-field{font-weight:500;line-height:1}.c-token-op{display:inline-flex;align-items:center;color:inherit}.c-token-op ::ng-deep .c-op-trigger{padding:0;color:inherit}.c-token-op ::ng-deep .c-op-icon svg{width:14px;height:14px;display:block}.c-token-value{border:none;background:transparent;padding:0;font:inherit;font-weight:500;color:var(--sd-primary)}.c-token-value-edit{display:inline-flex;align-items:center;gap:4px;max-width:240px}.c-token-value-edit sd-input,.c-token-value-edit sd-input-number{display:inline-flex;max-width:140px}.c-token-value-edit sd-date-range{display:inline-flex;max-width:220px;min-width:0;flex:0 1 auto}.c-token-value-edit sd-select,.c-token-value-edit sd-date,.c-token-value-edit sd-datetime{display:inline-flex;align-items:center;line-height:1}.c-token ::ng-deep .mat-mdc-form-field{line-height:1}.c-token ::ng-deep .mat-mdc-text-field-wrapper,.c-token ::ng-deep .mat-mdc-form-field-flex{padding:0;min-height:0;background:transparent}.c-token ::ng-deep .mat-mdc-form-field-infix{padding:0;min-height:0;width:auto;border:0;display:inline-flex;align-items:center}.c-token ::ng-deep .mat-mdc-select-value,.c-token ::ng-deep .mat-mdc-input-element,.c-token ::ng-deep input{line-height:1;font-size:13px;padding:0;height:auto;color:inherit}.c-token ::ng-deep .mat-mdc-select-value{display:inline-flex;align-items:center;min-width:0;max-width:200px;overflow:hidden;text-overflow:ellipsis;color:var(--sd-primary);font-weight:500}.c-token ::ng-deep .sd-suffix-icon{display:none}.c-token-multi-head{display:inline-block;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}.c-token-building{border-style:dashed}.c-bool-toggle{display:inline-flex;align-items:center;gap:4px}.c-bool-btn{display:inline-flex;align-items:center;justify-content:center;height:18px;min-width:0;padding:0 8px;border:1px solid currentColor;border-radius:999px;background:transparent;font:inherit;font-size:11px;font-weight:500;line-height:1;cursor:pointer;white-space:nowrap;-webkit-user-select:none;user-select:none;transition:background .12s ease,color .12s ease}:host-context(.c-density-comfortable) .c-bool-btn{height:20px;padding:0 10px;font-size:12px}.c-bool-true{color:var(--sd-success)}.c-bool-false{color:var(--sd-warning)}.c-bool-active.c-bool-true{background:var(--sd-success);color:#fff;border-color:var(--sd-success)}.c-bool-active.c-bool-false{background:var(--sd-warning);color:#fff;border-color:var(--sd-warning)}.c-bool-btn:hover:not(.c-bool-active).c-bool-true{background:var(--sd-success-light)}.c-bool-btn:hover:not(.c-bool-active).c-bool-false{background:var(--sd-warning-light)}.c-token-remove{align-self:stretch;display:inline-flex;align-items:center;justify-content:center;border:none;border-left:1px solid rgba(0,0,0,.04);border-radius:0;background:transparent;cursor:pointer;color:inherit}:host-context(.c-density-compact) .c-token-remove{width:26px}:host-context(.c-density-comfortable) .c-token-remove{width:28px}.c-token-remove mat-icon{font-size:14px;width:14px;height:14px}.c-token-remove:hover{background:#0000000d}\n"] }]
|
|
499
488
|
}], propDecorators: { building: [{ type: i0.Input, args: [{ isSignal: true, alias: "building", required: true }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], allowedOperators: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowedOperators", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], showOperator: [{ type: i0.Input, args: [{ isSignal: true, alias: "showOperator", required: false }] }], autoId: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], pickOperator: [{ type: i0.Output, args: ["pickOperator"] }], commitValue: [{ type: i0.Output, args: ["commitValue"] }], cancel: [{ type: i0.Output, args: ["cancel"] }], seamlessCommit: [{ type: i0.Output, args: ["seamlessCommit"] }], draftChange: [{ type: i0.Output, args: ["draftChange"] }], draftCommit: [{ type: i0.Output, args: ["draftCommit"] }], opMenu: [{ type: i0.ViewChild, args: ['buildOperator', { isSignal: true }] }], picker: [{ type: i0.ViewChild, args: ['bPicker', { isSignal: true }] }] } });
|
|
500
489
|
|
|
501
490
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
@@ -718,10 +707,10 @@ class SdQueryChipPopover {
|
|
|
718
707
|
.finally(() => this.editingOptionsLoading.set(false));
|
|
719
708
|
}
|
|
720
709
|
}
|
|
721
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
722
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: SdQueryChipPopover, isStandalone: true, selector: "sd-query-chip-popover", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, chipIndex: { classPropertyName: "chipIndex", publicName: "chipIndex", isSignal: true, isRequired: false, transformFunction: null }, autoIdBase: { classPropertyName: "autoIdBase", publicName: "autoIdBase", isSignal: true, isRequired: false, transformFunction: null }, switchPickerMenu: { classPropertyName: "switchPickerMenu", publicName: "switchPickerMenu", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { commit: "commit", swapField: "swapField" }, viewQueries: [{ propertyName: "menu", first: true, predicate: ["menu"], descendants: true, isSignal: true }], ngImport: i0, template: "<!--\n Chip popover \u2014 operator + value editor for the popover-mode chip.\n Visual layout mirrors the previous inline `<mat-menu #chipPopover>` in query-bar.\n Body branches on operator + field.type \u2014 8 paths preserved exactly.\n-->\n<mat-menu #menu=\"matMenu\" class=\"c-chip-popover\" xPosition=\"after\" yPosition=\"below\" (closed)=\"onMenuClosed()\">\n <ng-template matMenuContent>\n @let _field = field();\n @let _op = editingOperator();\n @let _val = editingValue();\n @let _options = editingOptions();\n @let _loading = editingOptionsLoading();\n @let _switchMenu = switchPickerMenu();\n\n @if (_field) {\n <div class=\"c-pop-header\" (click)=\"$event.stopPropagation()\">\n <mat-icon fontSet=\"material-icons-outlined\">{{ iconFor(_field) }}</mat-icon>\n <!-- why: nested mat-menu trigger to swap the chip's field \u2014 parent provides\n the field-picker MatMenu via [switchPickerMenu]. -->\n @if (_switchMenu) {\n <button\n type=\"button\"\n class=\"c-pop-header-field\"\n [matMenuTriggerFor]=\"_switchMenu\"\n matTooltip=\"\u0110\u1ED5i field\">\n <span>{{ _field.label }}</span>\n <mat-icon fontSet=\"material-icons-outlined\">unfold_more</mat-icon>\n </button>\n } @else {\n <span class=\"c-pop-header-field\">{{ _field.label }}</span>\n }\n <!-- Operator selector (right-aligned). Disabled when field has \u22641 operator. -->\n <sd-operator\n class=\"c-pop-header-operator\"\n [autoId]=\"chipAutoId('operator')\"\n [operators]=\"allowedOperators()\"\n [model]=\"_op\"\n [disabled]=\"!showOperatorSelector()\"\n (modelChange)=\"onEditingOperatorChange($any($event))\" />\n </div>\n\n <div class=\"c-pop-body\" (click)=\"$event.stopPropagation()\">\n @if (!isNoDataOperator(_op)) {\n @if (_op === 'BETWEEN') {\n @if (_field.type === 'date') {\n <div class=\"c-pop-between\">\n <sd-date size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value-from')\"\n placeholder=\"T\u1EEB\"\n [model]=\"$any(_val)?.from\"\n (sdChange)=\"onEditingRangeFrom($event)\">\n </sd-date>\n <sd-date size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value-to')\"\n placeholder=\"\u0110\u1EBFn\"\n [model]=\"$any(_val)?.to\"\n (sdChange)=\"onEditingRangeTo($event)\">\n </sd-date>\n </div>\n } @else if (_field.type === 'datetime') {\n <div class=\"c-pop-between\">\n <sd-datetime size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value-from')\"\n placeholder=\"T\u1EEB\"\n [model]=\"$any(_val)?.from\"\n (sdChange)=\"onEditingRangeFrom($event)\">\n </sd-datetime>\n <sd-datetime size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value-to')\"\n placeholder=\"\u0110\u1EBFn\"\n [model]=\"$any(_val)?.to\"\n (sdChange)=\"onEditingRangeTo($event)\">\n </sd-datetime>\n </div>\n } @else {\n <div class=\"c-pop-between\">\n <sd-input-number size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value-from')\"\n placeholder=\"T\u1EEB\"\n [model]=\"$any(_val)?.from\"\n (sdChange)=\"onEditingRangeFrom($event)\">\n </sd-input-number>\n <sd-input-number size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value-to')\"\n placeholder=\"\u0110\u1EBFn\"\n [model]=\"$any(_val)?.to\"\n (sdChange)=\"onEditingRangeTo($event)\">\n </sd-input-number>\n </div>\n }\n } @else if (_field.type === 'boolean') {\n <div class=\"c-pop-boolean c-bool-toggle\">\n <sd-button\n [autoId]=\"chipAutoId('value-true')\"\n [type]=\"_val === true ? 'fill' : 'outline'\"\n color=\"success\"\n [title]=\"$any(_field).trueLabel || 'C\u00F3'\"\n (click)=\"onEditingValueInput(true)\">\n </sd-button>\n <sd-button\n [autoId]=\"chipAutoId('value-false')\"\n [type]=\"_val === false ? 'fill' : 'outline'\"\n color=\"warning\"\n [title]=\"$any(_field).falseLabel || 'Kh\u00F4ng'\"\n (click)=\"onEditingValueInput(false)\">\n </sd-button>\n </div>\n } @else if (_field.type === 'values' || _field.type === 'lazy-values') {\n @let _opt = $any(_field).option;\n <sd-select size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value')\"\n placeholder=\"Ch\u1ECDn gi\u00E1 tr\u1ECB\"\n [items]=\"_options\"\n [valueField]=\"_opt.valueField\"\n [displayField]=\"_opt.displayField\"\n [multiple]=\"multiple()\"\n [model]=\"$any(_val)\"\n (sdChange)=\"onEditingValueInput($event)\">\n </sd-select>\n @if (_loading) {\n <div class=\"c-pop-values-loading\">\u0110ang t\u1EA3i...</div>\n }\n } @else if (_field.type === 'date') {\n <sd-date size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value')\"\n placeholder=\"Ch\u1ECDn gi\u00E1 tr\u1ECB\"\n [model]=\"$any(_val)\"\n (sdChange)=\"onEditingValueInput($event)\">\n </sd-date>\n } @else if (_field.type === 'datetime') {\n <sd-datetime size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value')\"\n placeholder=\"Ch\u1ECDn gi\u00E1 tr\u1ECB\"\n [model]=\"$any(_val)\"\n (sdChange)=\"onEditingValueInput($event)\">\n </sd-datetime>\n } @else if (_field.type === 'number') {\n <sd-input-number size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value')\"\n placeholder=\"Nh\u1EADp gi\u00E1 tr\u1ECB\"\n [model]=\"$any(_val)\"\n (sdChange)=\"onEditingValueInput($event)\">\n </sd-input-number>\n } @else {\n <sd-input size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value')\"\n placeholder=\"Nh\u1EADp gi\u00E1 tr\u1ECB\"\n [model]=\"$any(_val)\"\n (sdChange)=\"onEditingValueInput($event)\">\n </sd-input>\n }\n }\n </div>\n }\n </ng-template>\n</mat-menu>\n", styles: [":host{display:contents}::ng-deep .mat-mdc-menu-panel.c-chip-popover{min-width:280px;max-width:320px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid #e2e4e7;font-size:13px;font-weight:500;color:#212121}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header mat-icon{font-size:16px;width:16px;height:16px;color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header .c-pop-header-operator{margin-left:auto}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field{display:inline-flex;align-items:center;gap:4px;padding:2px 4px 2px 6px;margin-left:-4px;background:transparent;border:1px solid transparent;border-radius:4px;font:inherit;font-weight:500;color:#212121;cursor:pointer;transition:background-color .12s ease,border-color .12s ease}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#7a7a7a!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field:hover{background:#f5f6f7;border-color:#e2e4e7}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-body{padding:10px 12px;display:flex;flex-direction:column;gap:12px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-between{display:grid;grid-template-columns:1fr 1fr;gap:8px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-boolean{display:flex;gap:8px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-boolean button{flex:1;height:32px;border:1px solid #d6d8db;border-radius:6px;background:#fff;font:inherit;font-size:13px;cursor:pointer}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values-loading{padding:10px 8px;font-size:12px;color:#7a7a7a}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-bool-toggle{display:inline-flex;align-items:center;gap:4px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-bool-toggle .mdc-button,::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-bool-toggle button[mat-button],::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-bool-toggle button[mat-stroked-button],::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-bool-toggle button[mat-flat-button]{border-radius:999px;min-width:0;padding:0 12px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "directive", type: i1.MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "directive", type: i1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "component", type: 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", "bare", "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", "bare", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdDatetime, selector: "sd-datetime", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "showSeconds", "bare", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
710
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQueryChipPopover, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
711
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: SdQueryChipPopover, isStandalone: true, selector: "sd-query-chip-popover", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, chipIndex: { classPropertyName: "chipIndex", publicName: "chipIndex", isSignal: true, isRequired: false, transformFunction: null }, autoIdBase: { classPropertyName: "autoIdBase", publicName: "autoIdBase", isSignal: true, isRequired: false, transformFunction: null }, switchPickerMenu: { classPropertyName: "switchPickerMenu", publicName: "switchPickerMenu", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { commit: "commit", swapField: "swapField" }, viewQueries: [{ propertyName: "menu", first: true, predicate: ["menu"], descendants: true, isSignal: true }], ngImport: i0, template: "<!--\n Chip popover \u2014 operator + value editor for the popover-mode chip.\n Visual layout mirrors the previous inline `<mat-menu #chipPopover>` in query-bar.\n Body branches on operator + field.type \u2014 8 paths preserved exactly.\n-->\n<mat-menu #menu=\"matMenu\" class=\"c-chip-popover\" xPosition=\"after\" yPosition=\"below\" (closed)=\"onMenuClosed()\">\n <ng-template matMenuContent>\n @let _field = field();\n @let _op = editingOperator();\n @let _val = editingValue();\n @let _options = editingOptions();\n @let _loading = editingOptionsLoading();\n @let _switchMenu = switchPickerMenu();\n\n @if (_field) {\n <div class=\"c-pop-header\" (click)=\"$event.stopPropagation()\">\n <mat-icon fontSet=\"material-icons-outlined\">{{ iconFor(_field) }}</mat-icon>\n <!-- why: nested mat-menu trigger to swap the chip's field \u2014 parent provides\n the field-picker MatMenu via [switchPickerMenu]. -->\n @if (_switchMenu) {\n <button\n type=\"button\"\n class=\"c-pop-header-field\"\n [matMenuTriggerFor]=\"_switchMenu\"\n matTooltip=\"\u0110\u1ED5i field\">\n <span>{{ _field.label }}</span>\n <mat-icon fontSet=\"material-icons-outlined\">unfold_more</mat-icon>\n </button>\n } @else {\n <span class=\"c-pop-header-field\">{{ _field.label }}</span>\n }\n <!-- Operator selector (right-aligned). Disabled when field has \u22641 operator. -->\n <sd-operator\n class=\"c-pop-header-operator\"\n [autoId]=\"chipAutoId('operator')\"\n [operators]=\"allowedOperators()\"\n [model]=\"_op\"\n [disabled]=\"!showOperatorSelector()\"\n (modelChange)=\"onEditingOperatorChange($any($event))\" />\n </div>\n\n <div class=\"c-pop-body\" (click)=\"$event.stopPropagation()\">\n @if (!isNoDataOperator(_op)) {\n @if (_op === 'BETWEEN') {\n @if (_field.type === 'date') {\n <div class=\"c-pop-between\">\n <sd-date size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value-from')\"\n placeholder=\"T\u1EEB\"\n [model]=\"$any(_val)?.from\"\n (sdChange)=\"onEditingRangeFrom($event)\">\n </sd-date>\n <sd-date size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value-to')\"\n placeholder=\"\u0110\u1EBFn\"\n [model]=\"$any(_val)?.to\"\n (sdChange)=\"onEditingRangeTo($event)\">\n </sd-date>\n </div>\n } @else if (_field.type === 'datetime') {\n <div class=\"c-pop-between\">\n <sd-datetime size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value-from')\"\n placeholder=\"T\u1EEB\"\n [model]=\"$any(_val)?.from\"\n (sdChange)=\"onEditingRangeFrom($event)\">\n </sd-datetime>\n <sd-datetime size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value-to')\"\n placeholder=\"\u0110\u1EBFn\"\n [model]=\"$any(_val)?.to\"\n (sdChange)=\"onEditingRangeTo($event)\">\n </sd-datetime>\n </div>\n } @else {\n <div class=\"c-pop-between\">\n <sd-input-number size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value-from')\"\n placeholder=\"T\u1EEB\"\n [model]=\"$any(_val)?.from\"\n (sdChange)=\"onEditingRangeFrom($event)\">\n </sd-input-number>\n <sd-input-number size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value-to')\"\n placeholder=\"\u0110\u1EBFn\"\n [model]=\"$any(_val)?.to\"\n (sdChange)=\"onEditingRangeTo($event)\">\n </sd-input-number>\n </div>\n }\n } @else if (_field.type === 'boolean') {\n <div class=\"c-pop-boolean c-bool-toggle\">\n <sd-button\n [autoId]=\"chipAutoId('value-true')\"\n [type]=\"_val === true ? 'fill' : 'outline'\"\n color=\"success\"\n [title]=\"$any(_field).trueLabel || 'C\u00F3'\"\n (click)=\"onEditingValueInput(true)\">\n </sd-button>\n <sd-button\n [autoId]=\"chipAutoId('value-false')\"\n [type]=\"_val === false ? 'fill' : 'outline'\"\n color=\"warning\"\n [title]=\"$any(_field).falseLabel || 'Kh\u00F4ng'\"\n (click)=\"onEditingValueInput(false)\">\n </sd-button>\n </div>\n } @else if (_field.type === 'values' || _field.type === 'lazy-values') {\n @let _opt = $any(_field).option;\n <sd-select size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value')\"\n placeholder=\"Ch\u1ECDn gi\u00E1 tr\u1ECB\"\n [items]=\"_options\"\n [valueField]=\"_opt.valueField\"\n [displayField]=\"_opt.displayField\"\n [multiple]=\"multiple()\"\n [model]=\"$any(_val)\"\n (sdChange)=\"onEditingValueInput($event)\">\n </sd-select>\n @if (_loading) {\n <div class=\"c-pop-values-loading\">\u0110ang t\u1EA3i...</div>\n }\n } @else if (_field.type === 'date') {\n <sd-date size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value')\"\n placeholder=\"Ch\u1ECDn gi\u00E1 tr\u1ECB\"\n [model]=\"$any(_val)\"\n (sdChange)=\"onEditingValueInput($event)\">\n </sd-date>\n } @else if (_field.type === 'datetime') {\n <sd-datetime size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value')\"\n placeholder=\"Ch\u1ECDn gi\u00E1 tr\u1ECB\"\n [model]=\"$any(_val)\"\n (sdChange)=\"onEditingValueInput($event)\">\n </sd-datetime>\n } @else if (_field.type === 'number') {\n <sd-input-number size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value')\"\n placeholder=\"Nh\u1EADp gi\u00E1 tr\u1ECB\"\n [model]=\"$any(_val)\"\n (sdChange)=\"onEditingValueInput($event)\">\n </sd-input-number>\n } @else {\n <sd-input size=\"sm\" hideInlineError\n [autoId]=\"chipAutoId('value')\"\n placeholder=\"Nh\u1EADp gi\u00E1 tr\u1ECB\"\n [model]=\"$any(_val)\"\n (sdChange)=\"onEditingValueInput($event)\">\n </sd-input>\n }\n }\n </div>\n }\n </ng-template>\n</mat-menu>\n", styles: [":host{display:contents}::ng-deep .mat-mdc-menu-panel.c-chip-popover{min-width:280px;max-width:320px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid #e2e4e7;font-size:13px;font-weight:500;color:#212121}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header mat-icon{font-size:16px;width:16px;height:16px;color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header .c-pop-header-operator{margin-left:auto}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field{display:inline-flex;align-items:center;gap:4px;padding:2px 4px 2px 6px;margin-left:-4px;background:transparent;border:1px solid transparent;border-radius:4px;font:inherit;font-weight:500;color:#212121;cursor:pointer;transition:background-color .12s ease,border-color .12s ease}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#7a7a7a!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field:hover{background:#f5f6f7;border-color:#e2e4e7}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-body{padding:10px 12px;display:flex;flex-direction:column;gap:12px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-between{display:grid;grid-template-columns:1fr 1fr;gap:8px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-boolean{display:flex;gap:8px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-boolean button{flex:1;height:32px;border:1px solid #d6d8db;border-radius:6px;background:#fff;font:inherit;font-size:13px;cursor:pointer}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values-loading{padding:10px 8px;font-size:12px;color:#7a7a7a}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-bool-toggle{display:inline-flex;align-items:center;gap:4px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-bool-toggle .mdc-button,::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-bool-toggle button[mat-button],::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-bool-toggle button[mat-stroked-button],::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-bool-toggle button[mat-flat-button]{border-radius:999px;min-width:0;padding:0 12px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "directive", type: i1.MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "directive", type: i1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "component", type: 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
723
712
|
}
|
|
724
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
713
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQueryChipPopover, decorators: [{
|
|
725
714
|
type: Component,
|
|
726
715
|
args: [{ selector: 'sd-query-chip-popover', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
727
716
|
CommonModule,
|
|
@@ -783,10 +772,10 @@ class SdQueryFieldPicker {
|
|
|
783
772
|
isUsed(field) {
|
|
784
773
|
return this.usedKeys().has(field.key);
|
|
785
774
|
}
|
|
786
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
787
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
775
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQueryFieldPicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
776
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: SdQueryFieldPicker, isStandalone: true, selector: "sd-query-field-picker", inputs: { fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: false, transformFunction: null }, currentKey: { classPropertyName: "currentKey", publicName: "currentKey", isSignal: true, isRequired: false, transformFunction: null }, usedKeys: { classPropertyName: "usedKeys", publicName: "usedKeys", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pick: "pick" }, viewQueries: [{ propertyName: "menu", first: true, predicate: MatMenu, descendants: true, isSignal: true }], ngImport: i0, template: "<mat-menu #m=\"matMenu\" xPosition=\"after\" yPosition=\"below\" class=\"c-field-picker-menu\">\n @for (field of fields(); track $index) {\n <button\n type=\"button\"\n mat-menu-item\n [disabled]=\"isDisabled(field)\"\n (click)=\"pick.emit(field)\">\n <mat-icon fontSet=\"material-icons-outlined\" class=\"c-field-item-icon\">\n {{ iconFor(field) }}\n </mat-icon>\n <span class=\"c-field-item-label\">{{ field.label }}</span>\n <span class=\"c-field-item-type\">{{ field.type }}</span>\n @if (isCurrent(field) || isUsed(field)) {\n <mat-icon class=\"c-field-item-check\" fontSet=\"material-icons-outlined\">check</mat-icon>\n }\n </button>\n } @empty {\n <div class=\"c-field-empty\">Ch\u01B0a c\u00F3 field n\u00E0o \u0111\u01B0\u1EE3c c\u1EA5u h\u00ECnh.</div>\n }\n</mat-menu>\n", styles: ["::ng-deep .mat-mdc-menu-panel.c-field-picker-menu{min-width:200px;max-width:260px}::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-menu-item{min-height:36px}::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-menu-item .mat-mdc-menu-item-text{display:flex;align-items:center;flex:1;min-width:0}::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .c-field-item-icon{font-size:16px;width:16px;height:16px;margin-right:8px;color:#5f6368;flex-shrink:0}::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .c-field-item-label{flex:1 1 auto;min-width:0;font-size:13px;color:#212121;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .c-field-item-type{flex-shrink:0;margin-left:auto;padding-left:12px;font-family:Roboto Mono,monospace;font-size:11px;color:#7a7a7a}::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .c-field-item-check{flex-shrink:0;font-size:14px;width:14px;height:14px;margin-left:6px;color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .c-field-empty{padding:12px 16px;font-size:13px;color:#7a7a7a}\n"], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
788
777
|
}
|
|
789
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
778
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQueryFieldPicker, decorators: [{
|
|
790
779
|
type: Component,
|
|
791
780
|
args: [{ selector: 'sd-query-field-picker', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatMenuModule, MatIconModule], template: "<mat-menu #m=\"matMenu\" xPosition=\"after\" yPosition=\"below\" class=\"c-field-picker-menu\">\n @for (field of fields(); track $index) {\n <button\n type=\"button\"\n mat-menu-item\n [disabled]=\"isDisabled(field)\"\n (click)=\"pick.emit(field)\">\n <mat-icon fontSet=\"material-icons-outlined\" class=\"c-field-item-icon\">\n {{ iconFor(field) }}\n </mat-icon>\n <span class=\"c-field-item-label\">{{ field.label }}</span>\n <span class=\"c-field-item-type\">{{ field.type }}</span>\n @if (isCurrent(field) || isUsed(field)) {\n <mat-icon class=\"c-field-item-check\" fontSet=\"material-icons-outlined\">check</mat-icon>\n }\n </button>\n } @empty {\n <div class=\"c-field-empty\">Ch\u01B0a c\u00F3 field n\u00E0o \u0111\u01B0\u1EE3c c\u1EA5u h\u00ECnh.</div>\n }\n</mat-menu>\n", styles: ["::ng-deep .mat-mdc-menu-panel.c-field-picker-menu{min-width:200px;max-width:260px}::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-menu-item{min-height:36px}::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-menu-item .mat-mdc-menu-item-text{display:flex;align-items:center;flex:1;min-width:0}::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .c-field-item-icon{font-size:16px;width:16px;height:16px;margin-right:8px;color:#5f6368;flex-shrink:0}::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .c-field-item-label{flex:1 1 auto;min-width:0;font-size:13px;color:#212121;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .c-field-item-type{flex-shrink:0;margin-left:auto;padding-left:12px;font-family:Roboto Mono,monospace;font-size:11px;color:#7a7a7a}::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .c-field-item-check{flex-shrink:0;font-size:14px;width:14px;height:14px;margin-left:6px;color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .c-field-empty{padding:12px 16px;font-size:13px;color:#7a7a7a}\n"] }]
|
|
792
781
|
}], propDecorators: { fields: [{ type: i0.Input, args: [{ isSignal: true, alias: "fields", required: false }] }], currentKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentKey", required: false }] }], usedKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "usedKeys", required: false }] }], pick: [{ type: i0.Output, args: ["pick"] }], menu: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatMenu), { isSignal: true }] }] } });
|
|
@@ -802,10 +791,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
802
791
|
* Covers types: boolean, date, datetime, values, lazy-values, plus a fallback else
|
|
803
792
|
* branch. BETWEEN (date / datetime) uses a single `<sd-date-range>` (datetime
|
|
804
793
|
* downgrades to date precision).
|
|
794
|
+
*
|
|
795
|
+
* why: `values` / `lazy-values` đã chuyển sang `<sd-select [viewed]="'inline'">` — sd-select
|
|
796
|
+
* tự quản click→edit + focusout→thoát + bare editor, nên các nhánh đó KHÔNG dùng
|
|
797
|
+
* `enterEdit` / `onFocusOut` / `#editing` nữa. Các nhánh còn lại (boolean / date / datetime /
|
|
798
|
+
* BETWEEN) vẫn dùng lifecycle thủ công cho tới khi control tương ứng có inline mode (rollout).
|
|
805
799
|
*/
|
|
806
800
|
class SdQueryInlineChip {
|
|
807
|
-
#injector = inject(Injector);
|
|
808
|
-
#cdr = inject(ChangeDetectorRef);
|
|
809
801
|
// ---------------------------------------------------------------------------
|
|
810
802
|
// Inputs
|
|
811
803
|
// ---------------------------------------------------------------------------
|
|
@@ -839,11 +831,13 @@ class SdQueryInlineChip {
|
|
|
839
831
|
// ---------------------------------------------------------------------------
|
|
840
832
|
// Internal state
|
|
841
833
|
// ---------------------------------------------------------------------------
|
|
842
|
-
/**
|
|
834
|
+
/**
|
|
835
|
+
* Edit toggle for the BOOLEAN branch only — viewed (false) ↔ toggle buttons (true).
|
|
836
|
+
* why: boolean isn't a `viewed`-aware form control (no inline mode); it keeps the chip's own
|
|
837
|
+
* click-to-edit. values/date/datetime/BETWEEN delegate to their control's `viewed='inline'`.
|
|
838
|
+
*/
|
|
843
839
|
#editing = signal(false, ...(ngDevMode ? [{ debugName: "#editing" }] : /* istanbul ignore next */ []));
|
|
844
840
|
editing = this.#editing.asReadonly();
|
|
845
|
-
/** Active picker reference — auto-opened right after entering edit. */
|
|
846
|
-
chipPicker = viewChild('chipPicker', ...(ngDevMode ? [{ debugName: "chipPicker" }] : /* istanbul ignore next */ []));
|
|
847
841
|
// ---------------------------------------------------------------------------
|
|
848
842
|
// Template helpers
|
|
849
843
|
// ---------------------------------------------------------------------------
|
|
@@ -855,68 +849,28 @@ class SdQueryInlineChip {
|
|
|
855
849
|
// ---------------------------------------------------------------------------
|
|
856
850
|
// Edit lifecycle
|
|
857
851
|
// ---------------------------------------------------------------------------
|
|
858
|
-
/** Enter edit mode
|
|
852
|
+
/** Enter edit mode (BOOLEAN branch — shows the toggle buttons; exits on toggle commit). */
|
|
859
853
|
enterEdit() {
|
|
860
854
|
if (this.#editing())
|
|
861
855
|
return;
|
|
862
856
|
this.#editing.set(true);
|
|
863
|
-
afterNextRender(() => this.chipPicker()?.open?.(), { injector: this.#injector });
|
|
864
|
-
}
|
|
865
|
-
/**
|
|
866
|
-
* Exit edit only when focus actually leaves the wrapper subtree.
|
|
867
|
-
* why: focusout fires for every internal blur — only exit when relatedTarget
|
|
868
|
-
* is OUTSIDE the wrapper AND không thuộc cdk-overlay (mat-select panel, mat-calendar,
|
|
869
|
-
* datetime overlay đều render trong document.body). Tick option trong panel multi-
|
|
870
|
-
* select sẽ chuyển focus sang `<mat-option>` (nằm trong cdk-overlay-container) →
|
|
871
|
-
* nếu exit ngay sẽ flip viewed → kill panel sớm. Chỉ exit khi panel đã close
|
|
872
|
-
* (relatedTarget không nằm trong overlay). markForCheck vì overlay focusout
|
|
873
|
-
* không kéo theo CD cho OnPush parent.
|
|
874
|
-
*/
|
|
875
|
-
onFocusOut(ev) {
|
|
876
|
-
const wrapper = ev.currentTarget;
|
|
877
|
-
const next = ev.relatedTarget;
|
|
878
|
-
if (!wrapper)
|
|
879
|
-
return;
|
|
880
|
-
if (next && wrapper.contains(next))
|
|
881
|
-
return;
|
|
882
|
-
if (next instanceof Element && next.closest('.cdk-overlay-container'))
|
|
883
|
-
return;
|
|
884
|
-
if (this.#editing()) {
|
|
885
|
-
this.#editing.set(false);
|
|
886
|
-
this.#cdr.markForCheck();
|
|
887
|
-
// why: sd-date-range / sd-datetime đôi khi emit sdChange NGAY SAU focusout —
|
|
888
|
-
// viewed flip xảy ra trước khi model mới về tới [model] input → viewed text
|
|
889
|
-
// format dùng giá trị cũ. Schedule thêm 1 CD pass để re-render với model mới
|
|
890
|
-
// (user-visible bug: "click ra lần đầu chưa update, click vào rồi ra lần 2 mới đúng").
|
|
891
|
-
queueMicrotask(() => this.#cdr.markForCheck());
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
/** Test-only shim — direct call avoids dispatching real FocusEvent in JSDOM. */
|
|
895
|
-
onFocusOutForTest(ev) {
|
|
896
|
-
this.onFocusOut(ev);
|
|
897
857
|
}
|
|
898
858
|
// ---------------------------------------------------------------------------
|
|
899
859
|
// Commit handlers — single emit per category
|
|
900
860
|
// ---------------------------------------------------------------------------
|
|
901
|
-
/**
|
|
861
|
+
/**
|
|
862
|
+
* Single-value commit (sd-date, sd-datetime, single sd-select).
|
|
863
|
+
* why: date/datetime/values render via `viewed='inline'` (self-managed) — the chip only
|
|
864
|
+
* forwards the value; it no longer toggles `#editing` (that's boolean-only now).
|
|
865
|
+
*/
|
|
902
866
|
emitSingleCommit(v) {
|
|
903
867
|
this.commit.emit(v);
|
|
904
|
-
this.#editing.set(false);
|
|
905
868
|
}
|
|
906
|
-
/**
|
|
907
|
-
* BETWEEN commit — sd-date-range emits {from, to}.
|
|
908
|
-
* why: nếu cả from + to đều có giá trị → coi như range đã chọn xong → exit edit
|
|
909
|
-
* ngay tại commit (đồng bộ với model.set của parent), không chờ focusout. Tránh
|
|
910
|
-
* race "focusout firing trước sdChange" làm viewed text render với model cũ.
|
|
911
|
-
*/
|
|
869
|
+
/** BETWEEN commit — sd-date-range (viewed='inline') emits `{from, to}`; chip just forwards it. */
|
|
912
870
|
emitRangeCommit(ev) {
|
|
913
871
|
this.commitRange.emit(ev ?? null);
|
|
914
|
-
if (ev && ev.from != null && ev.to != null) {
|
|
915
|
-
this.#editing.set(false);
|
|
916
|
-
this.#cdr.markForCheck();
|
|
917
|
-
}
|
|
918
872
|
}
|
|
919
|
-
/** Multi-select live emit
|
|
873
|
+
/** Multi-select live emit (sd-select inline). */
|
|
920
874
|
emitLive(v) {
|
|
921
875
|
this.liveChange.emit(v);
|
|
922
876
|
}
|
|
@@ -925,10 +879,10 @@ class SdQueryInlineChip {
|
|
|
925
879
|
this.commit.emit(v);
|
|
926
880
|
this.#editing.set(false);
|
|
927
881
|
}
|
|
928
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
929
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: SdQueryInlineChip, isStandalone: true, selector: "sd-query-inline-chip", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: true, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, showOperator: { classPropertyName: "showOperator", publicName: "showOperator", isSignal: true, isRequired: false, transformFunction: null }, autoId: { classPropertyName: "autoId", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, valueText: { classPropertyName: "valueText", publicName: "valueText", isSignal: true, isRequired: false, transformFunction: null }, isNoData: { classPropertyName: "isNoData", publicName: "isNoData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { commit: "commit", commitRange: "commitRange", liveChange: "liveChange", remove: "remove" }, viewQueries: [{ propertyName: "chipPicker", first: true, predicate: ["chipPicker"], descendants: true, isSignal: true }], ngImport: i0, template: "<!--\n Completed inline chip \u2014 non-string/number/seamless branches.\n Edit lifecycle is self-managed: click enters edit + auto-opens picker,\n focusout outside the wrapper exits edit, picker emits commit single OR\n liveChange (multi) OR commitRange (BETWEEN).\n-->\n@let _f = field();\n@let _op = operator();\n@let _data = data();\n@let _multi = multiple();\n@let _editing = editing();\n@let _isNoData = isNoData();\n\n<div class=\"c-token\" [class.c-token-editing]=\"_editing\">\n <mat-icon class=\"c-token-icon\" fontSet=\"material-icons-outlined\">{{ iconName() }}</mat-icon>\n <span class=\"c-token-field\">{{ _f.label }}</span>\n\n @if (!_isNoData && showOperator()) {\n <sd-operator class=\"c-token-op\" [operators]=\"[_op]\" [model]=\"_op\" [disabled]=\"true\" />\n } @else if (!_isNoData) {\n <span class=\"c-token-sep\">:</span>\n }\n\n @if (!_isNoData) {\n @if (_f.type === 'boolean') {\n @if (_editing) {\n <!-- why: native button thay sd-button \u2014 mat-button MDC baseline 36px bu\u1ED9c\n ph\u1EA3i hack height/padding overrides; chip 28/32px nh\u1ECF h\u01A1n nhi\u1EC1u. T\u1EF1 v\u1EBD\n pill nh\u1ECF v\u1EDBi CSS scoped trong chip, kh\u00F4ng qua MDC, g\u1ECDn + chu\u1EA9n baseline. -->\n <span class=\"c-token-value c-token-value-edit c-bool-toggle\">\n <button\n type=\"button\"\n class=\"c-bool-btn c-bool-true\"\n [class.c-bool-active]=\"_data === true\"\n [attr.data-autoId]=\"autoId() + '-true'\"\n (click)=\"emitBoolean(true)\">\n {{ $any(_f).trueLabel || 'C\u00F3' }}\n </button>\n <button\n type=\"button\"\n class=\"c-bool-btn c-bool-false\"\n [class.c-bool-active]=\"_data === false\"\n [attr.data-autoId]=\"autoId() + '-false'\"\n (click)=\"emitBoolean(false)\">\n {{ $any(_f).falseLabel || 'Kh\u00F4ng' }}\n </button>\n </span>\n } @else {\n <button type=\"button\" class=\"c-token-value\" (click)=\"enterEdit()\">{{ valueText() }}</button>\n }\n } @else if ((_f.type === 'date' || _f.type === 'datetime') && _op === 'BETWEEN') {\n <!-- why: d\u00F9ng sd-date-range th\u1ED1ng nh\u1EA5t cho c\u1EA3 date + datetime BETWEEN (datetime downgrade v\u1EC1 date). -->\n <span\n class=\"c-token-value c-token-value-edit\"\n (click)=\"enterEdit()\"\n (focusout)=\"onFocusOut($event)\">\n <sd-date-range #chipPicker bare size=\"sm\"\n [autoId]=\"autoId()\"\n [viewed]=\"!_editing\"\n [model]=\"$any(_data)\"\n (sdChange)=\"emitRangeCommit($any($event))\"></sd-date-range>\n </span>\n } @else if (_f.type === 'values' || _f.type === 'lazy-values') {\n @let _opt = $any(_f).option;\n <span\n class=\"c-token-value c-token-value-edit\"\n (click)=\"enterEdit()\"\n (focusout)=\"onFocusOut($event)\">\n <sd-select #chipPicker bare size=\"sm\" minWidthPanel=\"300px\"\n [autoId]=\"autoId()\"\n [items]=\"_f.type === 'lazy-values' ? $any(_opt).search : $any(_opt.items)\"\n [valueField]=\"_opt.valueField\"\n [displayField]=\"_opt.displayField\"\n [multiple]=\"_multi\"\n [viewed]=\"!_editing\"\n [model]=\"$any(_data)\"\n (sdChange)=\"_multi ? emitLive($event) : emitSingleCommit($event)\">\n <!-- why: viewed mode m\u1EB7c \u0111\u1ECBnh d\u00F9ng comma-joined cho multi \u2014 qu\u00E1 d\u00E0i cho chip.\n Override b\u1EB1ng template \"head +N\" gi\u1ED1ng popover chipValueText. -->\n <ng-template #sdValue let-selectedItems=\"selectedItems\">\n @if ((selectedItems?.length ?? 0) > 1) {\n <span class=\"c-token-multi-head\">{{ $any(selectedItems)[0][_opt.displayField] }}</span> +{{ selectedItems.length - 1 }}\n } @else if ((selectedItems?.length ?? 0) === 1) {\n <span class=\"c-token-multi-head\">{{ $any(selectedItems)[0][_opt.displayField] }}</span>\n }\n </ng-template>\n </sd-select>\n </span>\n } @else if (_f.type === 'date') {\n <span\n class=\"c-token-value c-token-value-edit\"\n (click)=\"enterEdit()\"\n (focusout)=\"onFocusOut($event)\">\n <sd-date #chipPicker bare size=\"sm\"\n [autoId]=\"autoId()\"\n [viewed]=\"!_editing\"\n [model]=\"$any(_data)\"\n (sdChange)=\"emitSingleCommit($any($event))\"></sd-date>\n </span>\n } @else if (_f.type === 'datetime') {\n <span\n class=\"c-token-value c-token-value-edit\"\n (click)=\"enterEdit()\"\n (focusout)=\"onFocusOut($event)\">\n <sd-datetime #chipPicker bare size=\"sm\"\n [autoId]=\"autoId()\"\n [viewed]=\"!_editing\"\n [model]=\"$any(_data)\"\n (sdChange)=\"emitSingleCommit($any($event))\"></sd-datetime>\n </span>\n } @else {\n <!-- Fallback (unforeseen type) \u2014 read-only display via valueText. -->\n <span class=\"c-token-value\">{{ valueText() }}</span>\n }\n }\n\n <button type=\"button\" class=\"c-token-remove\" aria-label=\"Remove filter\" (click)=\"remove.emit()\">\n <mat-icon fontSet=\"material-icons-outlined\">close</mat-icon>\n </button>\n</div>\n", styles: [":host{display:contents}.c-token{display:inline-flex;align-items:center;gap:4px;padding:0 0 0 12px;border:1px solid var(--sd-primary-light);border-radius:999px;background:var(--sd-primary-light);font-size:13px;color:#5f6368;white-space:nowrap;overflow:hidden}:host-context(.c-density-compact) .c-token{height:28px}:host-context(.c-density-comfortable) .c-token{height:32px}.c-token-icon{font-size:14px;width:14px;height:14px;line-height:14px;color:inherit}.c-token-field{font-weight:500;line-height:1}.c-token-op{display:inline-flex;align-items:center;color:inherit}.c-token-op ::ng-deep .c-op-trigger{padding:0;color:inherit}.c-token-op ::ng-deep .c-op-icon svg{width:14px;height:14px;display:block}.c-token-sep{color:#7a7a7a}.c-token-value{border:none;background:transparent;padding:0;font:inherit;font-weight:500;color:var(--sd-primary);cursor:pointer}.c-token-value:hover{text-decoration:underline}.c-token-value-edit{display:inline-flex;align-items:center;gap:4px;max-width:240px}.c-token-value-edit sd-date-range{display:inline-flex;max-width:220px;min-width:0;flex:0 1 auto}.c-token-value-edit sd-select,.c-token-value-edit sd-date,.c-token-value-edit sd-datetime{display:inline-flex;align-items:center;line-height:1}.c-token ::ng-deep .mat-mdc-form-field{line-height:1}.c-token ::ng-deep .mat-mdc-text-field-wrapper,.c-token ::ng-deep .mat-mdc-form-field-flex{padding:0;min-height:0;background:transparent}.c-token ::ng-deep .mat-mdc-form-field-infix{padding:0;min-height:0;width:auto;border:0;display:inline-flex;align-items:center}.c-token ::ng-deep .mat-mdc-select-value,.c-token ::ng-deep .mat-mdc-input-element,.c-token ::ng-deep input{line-height:1;font-size:13px;padding:0;height:auto;color:inherit}.c-token ::ng-deep .mat-mdc-select-value{display:inline-flex;align-items:center;min-width:0;max-width:200px;overflow:hidden;text-overflow:ellipsis;color:var(--sd-primary);font-weight:500}.c-token ::ng-deep .sd-suffix-icon{display:none}.c-token-multi-head{display:inline-block;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}.c-bool-toggle{display:inline-flex;align-items:center;gap:4px}.c-bool-btn{display:inline-flex;align-items:center;justify-content:center;height:18px;min-width:0;padding:0 8px;border:1px solid currentColor;border-radius:999px;background:transparent;font:inherit;font-size:11px;font-weight:500;line-height:1;cursor:pointer;white-space:nowrap;-webkit-user-select:none;user-select:none;transition:background .12s ease,color .12s ease}:host-context(.c-density-comfortable) .c-bool-btn{height:20px;padding:0 10px;font-size:12px}.c-bool-true{color:var(--sd-success)}.c-bool-false{color:var(--sd-warning)}.c-bool-active.c-bool-true{background:var(--sd-success);color:#fff;border-color:var(--sd-success)}.c-bool-active.c-bool-false{background:var(--sd-warning);color:#fff;border-color:var(--sd-warning)}.c-bool-btn:hover:not(.c-bool-active).c-bool-true{background:var(--sd-success-light)}.c-bool-btn:hover:not(.c-bool-active).c-bool-false{background:var(--sd-warning-light)}.c-token-remove{align-self:stretch;display:inline-flex;align-items:center;justify-content:center;border:none;border-left:1px solid rgba(0,0,0,.04);border-radius:0;background:transparent;cursor:pointer;color:inherit}:host-context(.c-density-compact) .c-token-remove{width:26px}:host-context(.c-density-comfortable) .c-token-remove{width:28px}.c-token-remove mat-icon{font-size:14px;width:14px;height:14px}.c-token-remove:hover{background:#0000000d}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.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: SdDate, selector: "sd-date", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "bare", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdDateRange, selector: "sd-date-range", inputs: ["autoId", "name", "size", "form", "label", "helperText", "hideInlineError", "required", "disabled", "bare", "viewed", "appearance", "floatLabel", "min", "max", "model"], outputs: ["modelChange", "sdChange"] }, { kind: "component", type: SdDatetime, selector: "sd-datetime", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "showSeconds", "bare", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdSelect, selector: "sd-select", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "valueField", "displayField", "disabledField", "cacheChecksum", "limit", "hyperlink", "minWidthPanel", "hideInlineError", "required", "disabled", "viewed", "multiple", "bare", "validator", "inlineError", "appearance", "floatLabel", "items", "model"], outputs: ["modelChange", "sdChange", "sdSelection"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
882
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQueryInlineChip, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
883
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: SdQueryInlineChip, isStandalone: true, selector: "sd-query-inline-chip", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: true, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, showOperator: { classPropertyName: "showOperator", publicName: "showOperator", isSignal: true, isRequired: false, transformFunction: null }, autoId: { classPropertyName: "autoId", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, valueText: { classPropertyName: "valueText", publicName: "valueText", isSignal: true, isRequired: false, transformFunction: null }, isNoData: { classPropertyName: "isNoData", publicName: "isNoData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { commit: "commit", commitRange: "commitRange", liveChange: "liveChange", remove: "remove" }, ngImport: i0, template: "<!--\n Completed inline chip \u2014 non-string/number/seamless branches.\n Edit lifecycle is self-managed: click enters edit + auto-opens picker,\n focusout outside the wrapper exits edit, picker emits commit single OR\n liveChange (multi) OR commitRange (BETWEEN).\n-->\n@let _f = field();\n@let _op = operator();\n@let _data = data();\n@let _multi = multiple();\n@let _editing = editing();\n@let _isNoData = isNoData();\n@let _autoId = autoId();\n\n<div class=\"c-token\" [class.c-token-editing]=\"_editing\">\n <mat-icon class=\"c-token-icon\" fontSet=\"material-icons-outlined\">{{ iconName() }}</mat-icon>\n <span class=\"c-token-field\">{{ _f.label }}</span>\n\n @if (!_isNoData && showOperator()) {\n <sd-operator class=\"c-token-op\" [operators]=\"[_op]\" [model]=\"_op\" [disabled]=\"true\" />\n } @else if (!_isNoData) {\n <span class=\"c-token-sep\">:</span>\n }\n\n @if (!_isNoData) {\n @if (_f.type === 'boolean') {\n @if (_editing) {\n <!-- why: native button thay sd-button \u2014 mat-button MDC baseline 36px bu\u1ED9c\n ph\u1EA3i hack height/padding overrides; chip 28/32px nh\u1ECF h\u01A1n nhi\u1EC1u. T\u1EF1 v\u1EBD\n pill nh\u1ECF v\u1EDBi CSS scoped trong chip, kh\u00F4ng qua MDC, g\u1ECDn + chu\u1EA9n baseline. -->\n <span class=\"c-token-value c-token-value-edit c-bool-toggle\">\n <button\n type=\"button\"\n class=\"c-bool-btn c-bool-true\"\n [class.c-bool-active]=\"_data === true\"\n [attr.data-autoId]=\"_autoId + '-true'\"\n (click)=\"emitBoolean(true)\">\n {{ $any(_f).trueLabel || 'C\u00F3' }}\n </button>\n <button\n type=\"button\"\n class=\"c-bool-btn c-bool-false\"\n [class.c-bool-active]=\"_data === false\"\n [attr.data-autoId]=\"_autoId + '-false'\"\n (click)=\"emitBoolean(false)\">\n {{ $any(_f).falseLabel || 'Kh\u00F4ng' }}\n </button>\n </span>\n } @else {\n <button type=\"button\" class=\"c-token-value\" (click)=\"enterEdit()\">{{ valueText() }}</button>\n }\n } @else if ((_f.type === 'date' || _f.type === 'datetime') && _op === 'BETWEEN') {\n <!-- why: sd-date-range [viewed]=\"'inline'\" t\u1EF1 qu\u1EA3n click\u2192edit + focusout (datetime downgrade v\u1EC1 date).\n Chip kh\u00F4ng wiring lifecycle n\u1EEFa; [clearable]=false v\u00EC chip c\u00F3 \u00D7 ri\u00EAng. -->\n <span class=\"c-token-value c-token-value-edit\">\n <sd-date-range size=\"sm\"\n [autoId]=\"_autoId\"\n [viewed]=\"'inline'\"\n [clearable]=\"false\"\n [model]=\"$any(_data)\"\n (sdChange)=\"emitRangeCommit($any($event))\"></sd-date-range>\n </span>\n } @else if (_f.type === 'values' || _f.type === 'lazy-values') {\n @let _opt = $any(_f).option;\n <!-- why: sd-select [viewed]=\"'inline'\" t\u1EF1 qu\u1EA3n click\u2192edit + focusout\u2192tho\u00E1t + bare editor.\n Chip kh\u00F4ng wiring lifecycle cho nh\u00E1nh n\u00E0y n\u1EEFa (b\u1ECF enterEdit/onFocusOut/bare). -->\n <span class=\"c-token-value c-token-value-edit\">\n <sd-select #chipPicker size=\"sm\" minWidthPanel=\"300px\"\n [autoId]=\"_autoId\"\n [items]=\"_f.type === 'lazy-values' ? $any(_opt).search : $any(_opt.items)\"\n [valueField]=\"_opt.valueField\"\n [displayField]=\"_opt.displayField\"\n [multiple]=\"_multi\"\n [viewed]=\"'inline'\"\n [clearable]=\"false\"\n [model]=\"$any(_data)\"\n (sdChange)=\"_multi ? emitLive($event) : emitSingleCommit($event)\">\n <!-- why: viewed mode m\u1EB7c \u0111\u1ECBnh d\u00F9ng comma-joined cho multi \u2014 qu\u00E1 d\u00E0i cho chip.\n Override b\u1EB1ng template \"head +N\" gi\u1ED1ng popover chipValueText. -->\n <ng-template #sdValue let-selectedItems=\"selectedItems\">\n @if ((selectedItems?.length ?? 0) > 1) {\n <span class=\"c-token-multi-head\">{{ $any(selectedItems)[0][_opt.displayField] }}</span> +{{ selectedItems.length - 1 }}\n } @else if ((selectedItems?.length ?? 0) === 1) {\n <span class=\"c-token-multi-head\">{{ $any(selectedItems)[0][_opt.displayField] }}</span>\n }\n </ng-template>\n </sd-select>\n </span>\n } @else if (_f.type === 'date') {\n <span class=\"c-token-value c-token-value-edit\">\n <sd-date size=\"sm\"\n [autoId]=\"_autoId\"\n [viewed]=\"'inline'\"\n [clearable]=\"false\"\n [model]=\"$any(_data)\"\n (sdChange)=\"emitSingleCommit($any($event))\"></sd-date>\n </span>\n } @else if (_f.type === 'datetime') {\n <span class=\"c-token-value c-token-value-edit\">\n <sd-datetime size=\"sm\"\n [autoId]=\"_autoId\"\n [viewed]=\"'inline'\"\n [clearable]=\"false\"\n [model]=\"$any(_data)\"\n (sdChange)=\"emitSingleCommit($any($event))\"></sd-datetime>\n </span>\n } @else {\n <!-- Fallback (unforeseen type) \u2014 read-only display via valueText. -->\n <span class=\"c-token-value\">{{ valueText() }}</span>\n }\n }\n\n <button type=\"button\" class=\"c-token-remove\" aria-label=\"Remove filter\" (click)=\"remove.emit()\">\n <mat-icon fontSet=\"material-icons-outlined\">close</mat-icon>\n </button>\n</div>\n", styles: [":host{display:contents}.c-token{display:inline-flex;align-items:center;gap:4px;padding:0 0 0 12px;border:1px solid var(--sd-primary-light);border-radius:999px;background:var(--sd-primary-light);font-size:13px;color:#5f6368;white-space:nowrap;overflow:hidden}:host-context(.c-density-compact) .c-token{height:28px}:host-context(.c-density-comfortable) .c-token{height:32px}.c-token-icon{font-size:14px;width:14px;height:14px;line-height:14px;color:inherit}.c-token-field{font-weight:500;line-height:1}.c-token-op{display:inline-flex;align-items:center;color:inherit}.c-token-op ::ng-deep .c-op-trigger{padding:0;color:inherit}.c-token-op ::ng-deep .c-op-icon svg{width:14px;height:14px;display:block}.c-token-sep{color:#7a7a7a}.c-token-value{border:none;background:transparent;padding:0;font:inherit;font-weight:500;color:var(--sd-primary);cursor:pointer}.c-token-value:hover{text-decoration:underline}.c-token-value-edit{display:inline-flex;align-items:center;gap:4px;max-width:240px}.c-token-value-edit sd-date-range{display:inline-flex;max-width:220px;min-width:0;flex:0 1 auto}.c-token-value-edit sd-select,.c-token-value-edit sd-date,.c-token-value-edit sd-datetime{display:inline-flex;align-items:center;line-height:1}.c-token ::ng-deep .mat-mdc-form-field{line-height:1}.c-token ::ng-deep .mat-mdc-text-field-wrapper,.c-token ::ng-deep .mat-mdc-form-field-flex{padding:0;min-height:0;background:transparent}.c-token ::ng-deep .mat-mdc-form-field-infix{padding:0;min-height:0;width:auto;border:0;display:inline-flex;align-items:center}.c-token ::ng-deep .mat-mdc-select-value,.c-token ::ng-deep .mat-mdc-input-element,.c-token ::ng-deep input{line-height:1;font-size:13px;padding:0;height:auto;color:inherit}.c-token ::ng-deep .mat-mdc-select-value{display:inline-flex;align-items:center;min-width:0;max-width:200px;overflow:hidden;text-overflow:ellipsis;color:var(--sd-primary);font-weight:500}.c-token ::ng-deep .sd-suffix-icon{display:none}.c-token-multi-head{display:inline-block;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}.c-bool-toggle{display:inline-flex;align-items:center;gap:4px}.c-bool-btn{display:inline-flex;align-items:center;justify-content:center;height:18px;min-width:0;padding:0 8px;border:1px solid currentColor;border-radius:999px;background:transparent;font:inherit;font-size:11px;font-weight:500;line-height:1;cursor:pointer;white-space:nowrap;-webkit-user-select:none;user-select:none;transition:background .12s ease,color .12s ease}:host-context(.c-density-comfortable) .c-bool-btn{height:20px;padding:0 10px;font-size:12px}.c-bool-true{color:var(--sd-success)}.c-bool-false{color:var(--sd-warning)}.c-bool-active.c-bool-true{background:var(--sd-success);color:#fff;border-color:var(--sd-success)}.c-bool-active.c-bool-false{background:var(--sd-warning);color:#fff;border-color:var(--sd-warning)}.c-bool-btn:hover:not(.c-bool-active).c-bool-true{background:var(--sd-success-light)}.c-bool-btn:hover:not(.c-bool-active).c-bool-false{background:var(--sd-warning-light)}.c-token-remove{align-self:stretch;display:inline-flex;align-items:center;justify-content:center;border:none;border-left:1px solid rgba(0,0,0,.04);border-radius:0;background:transparent;cursor:pointer;color:inherit}:host-context(.c-density-compact) .c-token-remove{width:26px}:host-context(.c-density-comfortable) .c-token-remove{width:28px}.c-token-remove mat-icon{font-size:14px;width:14px;height:14px}.c-token-remove:hover{background:#0000000d}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.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: SdDate, selector: "sd-date", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "clearable", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdDateRange, selector: "sd-date-range", inputs: ["autoId", "name", "size", "form", "label", "helperText", "hideInlineError", "required", "disabled", "viewed", "clearable", "appearance", "floatLabel", "min", "max", "model"], outputs: ["modelChange", "sdChange"] }, { kind: "component", type: SdDatetime, selector: "sd-datetime", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "showSeconds", "clearable", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
930
884
|
}
|
|
931
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
885
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQueryInlineChip, decorators: [{
|
|
932
886
|
type: Component,
|
|
933
887
|
args: [{ selector: 'sd-query-inline-chip', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
934
888
|
CommonModule,
|
|
@@ -938,8 +892,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
938
892
|
SdDateRange,
|
|
939
893
|
SdDatetime,
|
|
940
894
|
SdSelect,
|
|
941
|
-
], template: "<!--\n Completed inline chip \u2014 non-string/number/seamless branches.\n Edit lifecycle is self-managed: click enters edit + auto-opens picker,\n focusout outside the wrapper exits edit, picker emits commit single OR\n liveChange (multi) OR commitRange (BETWEEN).\n-->\n@let _f = field();\n@let _op = operator();\n@let _data = data();\n@let _multi = multiple();\n@let _editing = editing();\n@let _isNoData = isNoData();\n\n<div class=\"c-token\" [class.c-token-editing]=\"_editing\">\n <mat-icon class=\"c-token-icon\" fontSet=\"material-icons-outlined\">{{ iconName() }}</mat-icon>\n <span class=\"c-token-field\">{{ _f.label }}</span>\n\n @if (!_isNoData && showOperator()) {\n <sd-operator class=\"c-token-op\" [operators]=\"[_op]\" [model]=\"_op\" [disabled]=\"true\" />\n } @else if (!_isNoData) {\n <span class=\"c-token-sep\">:</span>\n }\n\n @if (!_isNoData) {\n @if (_f.type === 'boolean') {\n @if (_editing) {\n <!-- why: native button thay sd-button \u2014 mat-button MDC baseline 36px bu\u1ED9c\n ph\u1EA3i hack height/padding overrides; chip 28/32px nh\u1ECF h\u01A1n nhi\u1EC1u. T\u1EF1 v\u1EBD\n pill nh\u1ECF v\u1EDBi CSS scoped trong chip, kh\u00F4ng qua MDC, g\u1ECDn + chu\u1EA9n baseline. -->\n <span class=\"c-token-value c-token-value-edit c-bool-toggle\">\n <button\n type=\"button\"\n class=\"c-bool-btn c-bool-true\"\n [class.c-bool-active]=\"_data === true\"\n [attr.data-autoId]=\"
|
|
942
|
-
}], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: true }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], showOperator: [{ type: i0.Input, args: [{ isSignal: true, alias: "showOperator", required: false }] }], autoId: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], valueText: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueText", required: false }] }], isNoData: [{ type: i0.Input, args: [{ isSignal: true, alias: "isNoData", required: false }] }], commit: [{ type: i0.Output, args: ["commit"] }], commitRange: [{ type: i0.Output, args: ["commitRange"] }], liveChange: [{ type: i0.Output, args: ["liveChange"] }], remove: [{ type: i0.Output, args: ["remove"] }]
|
|
895
|
+
], template: "<!--\n Completed inline chip \u2014 non-string/number/seamless branches.\n Edit lifecycle is self-managed: click enters edit + auto-opens picker,\n focusout outside the wrapper exits edit, picker emits commit single OR\n liveChange (multi) OR commitRange (BETWEEN).\n-->\n@let _f = field();\n@let _op = operator();\n@let _data = data();\n@let _multi = multiple();\n@let _editing = editing();\n@let _isNoData = isNoData();\n@let _autoId = autoId();\n\n<div class=\"c-token\" [class.c-token-editing]=\"_editing\">\n <mat-icon class=\"c-token-icon\" fontSet=\"material-icons-outlined\">{{ iconName() }}</mat-icon>\n <span class=\"c-token-field\">{{ _f.label }}</span>\n\n @if (!_isNoData && showOperator()) {\n <sd-operator class=\"c-token-op\" [operators]=\"[_op]\" [model]=\"_op\" [disabled]=\"true\" />\n } @else if (!_isNoData) {\n <span class=\"c-token-sep\">:</span>\n }\n\n @if (!_isNoData) {\n @if (_f.type === 'boolean') {\n @if (_editing) {\n <!-- why: native button thay sd-button \u2014 mat-button MDC baseline 36px bu\u1ED9c\n ph\u1EA3i hack height/padding overrides; chip 28/32px nh\u1ECF h\u01A1n nhi\u1EC1u. T\u1EF1 v\u1EBD\n pill nh\u1ECF v\u1EDBi CSS scoped trong chip, kh\u00F4ng qua MDC, g\u1ECDn + chu\u1EA9n baseline. -->\n <span class=\"c-token-value c-token-value-edit c-bool-toggle\">\n <button\n type=\"button\"\n class=\"c-bool-btn c-bool-true\"\n [class.c-bool-active]=\"_data === true\"\n [attr.data-autoId]=\"_autoId + '-true'\"\n (click)=\"emitBoolean(true)\">\n {{ $any(_f).trueLabel || 'C\u00F3' }}\n </button>\n <button\n type=\"button\"\n class=\"c-bool-btn c-bool-false\"\n [class.c-bool-active]=\"_data === false\"\n [attr.data-autoId]=\"_autoId + '-false'\"\n (click)=\"emitBoolean(false)\">\n {{ $any(_f).falseLabel || 'Kh\u00F4ng' }}\n </button>\n </span>\n } @else {\n <button type=\"button\" class=\"c-token-value\" (click)=\"enterEdit()\">{{ valueText() }}</button>\n }\n } @else if ((_f.type === 'date' || _f.type === 'datetime') && _op === 'BETWEEN') {\n <!-- why: sd-date-range [viewed]=\"'inline'\" t\u1EF1 qu\u1EA3n click\u2192edit + focusout (datetime downgrade v\u1EC1 date).\n Chip kh\u00F4ng wiring lifecycle n\u1EEFa; [clearable]=false v\u00EC chip c\u00F3 \u00D7 ri\u00EAng. -->\n <span class=\"c-token-value c-token-value-edit\">\n <sd-date-range size=\"sm\"\n [autoId]=\"_autoId\"\n [viewed]=\"'inline'\"\n [clearable]=\"false\"\n [model]=\"$any(_data)\"\n (sdChange)=\"emitRangeCommit($any($event))\"></sd-date-range>\n </span>\n } @else if (_f.type === 'values' || _f.type === 'lazy-values') {\n @let _opt = $any(_f).option;\n <!-- why: sd-select [viewed]=\"'inline'\" t\u1EF1 qu\u1EA3n click\u2192edit + focusout\u2192tho\u00E1t + bare editor.\n Chip kh\u00F4ng wiring lifecycle cho nh\u00E1nh n\u00E0y n\u1EEFa (b\u1ECF enterEdit/onFocusOut/bare). -->\n <span class=\"c-token-value c-token-value-edit\">\n <sd-select #chipPicker size=\"sm\" minWidthPanel=\"300px\"\n [autoId]=\"_autoId\"\n [items]=\"_f.type === 'lazy-values' ? $any(_opt).search : $any(_opt.items)\"\n [valueField]=\"_opt.valueField\"\n [displayField]=\"_opt.displayField\"\n [multiple]=\"_multi\"\n [viewed]=\"'inline'\"\n [clearable]=\"false\"\n [model]=\"$any(_data)\"\n (sdChange)=\"_multi ? emitLive($event) : emitSingleCommit($event)\">\n <!-- why: viewed mode m\u1EB7c \u0111\u1ECBnh d\u00F9ng comma-joined cho multi \u2014 qu\u00E1 d\u00E0i cho chip.\n Override b\u1EB1ng template \"head +N\" gi\u1ED1ng popover chipValueText. -->\n <ng-template #sdValue let-selectedItems=\"selectedItems\">\n @if ((selectedItems?.length ?? 0) > 1) {\n <span class=\"c-token-multi-head\">{{ $any(selectedItems)[0][_opt.displayField] }}</span> +{{ selectedItems.length - 1 }}\n } @else if ((selectedItems?.length ?? 0) === 1) {\n <span class=\"c-token-multi-head\">{{ $any(selectedItems)[0][_opt.displayField] }}</span>\n }\n </ng-template>\n </sd-select>\n </span>\n } @else if (_f.type === 'date') {\n <span class=\"c-token-value c-token-value-edit\">\n <sd-date size=\"sm\"\n [autoId]=\"_autoId\"\n [viewed]=\"'inline'\"\n [clearable]=\"false\"\n [model]=\"$any(_data)\"\n (sdChange)=\"emitSingleCommit($any($event))\"></sd-date>\n </span>\n } @else if (_f.type === 'datetime') {\n <span class=\"c-token-value c-token-value-edit\">\n <sd-datetime size=\"sm\"\n [autoId]=\"_autoId\"\n [viewed]=\"'inline'\"\n [clearable]=\"false\"\n [model]=\"$any(_data)\"\n (sdChange)=\"emitSingleCommit($any($event))\"></sd-datetime>\n </span>\n } @else {\n <!-- Fallback (unforeseen type) \u2014 read-only display via valueText. -->\n <span class=\"c-token-value\">{{ valueText() }}</span>\n }\n }\n\n <button type=\"button\" class=\"c-token-remove\" aria-label=\"Remove filter\" (click)=\"remove.emit()\">\n <mat-icon fontSet=\"material-icons-outlined\">close</mat-icon>\n </button>\n</div>\n", styles: [":host{display:contents}.c-token{display:inline-flex;align-items:center;gap:4px;padding:0 0 0 12px;border:1px solid var(--sd-primary-light);border-radius:999px;background:var(--sd-primary-light);font-size:13px;color:#5f6368;white-space:nowrap;overflow:hidden}:host-context(.c-density-compact) .c-token{height:28px}:host-context(.c-density-comfortable) .c-token{height:32px}.c-token-icon{font-size:14px;width:14px;height:14px;line-height:14px;color:inherit}.c-token-field{font-weight:500;line-height:1}.c-token-op{display:inline-flex;align-items:center;color:inherit}.c-token-op ::ng-deep .c-op-trigger{padding:0;color:inherit}.c-token-op ::ng-deep .c-op-icon svg{width:14px;height:14px;display:block}.c-token-sep{color:#7a7a7a}.c-token-value{border:none;background:transparent;padding:0;font:inherit;font-weight:500;color:var(--sd-primary);cursor:pointer}.c-token-value:hover{text-decoration:underline}.c-token-value-edit{display:inline-flex;align-items:center;gap:4px;max-width:240px}.c-token-value-edit sd-date-range{display:inline-flex;max-width:220px;min-width:0;flex:0 1 auto}.c-token-value-edit sd-select,.c-token-value-edit sd-date,.c-token-value-edit sd-datetime{display:inline-flex;align-items:center;line-height:1}.c-token ::ng-deep .mat-mdc-form-field{line-height:1}.c-token ::ng-deep .mat-mdc-text-field-wrapper,.c-token ::ng-deep .mat-mdc-form-field-flex{padding:0;min-height:0;background:transparent}.c-token ::ng-deep .mat-mdc-form-field-infix{padding:0;min-height:0;width:auto;border:0;display:inline-flex;align-items:center}.c-token ::ng-deep .mat-mdc-select-value,.c-token ::ng-deep .mat-mdc-input-element,.c-token ::ng-deep input{line-height:1;font-size:13px;padding:0;height:auto;color:inherit}.c-token ::ng-deep .mat-mdc-select-value{display:inline-flex;align-items:center;min-width:0;max-width:200px;overflow:hidden;text-overflow:ellipsis;color:var(--sd-primary);font-weight:500}.c-token ::ng-deep .sd-suffix-icon{display:none}.c-token-multi-head{display:inline-block;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}.c-bool-toggle{display:inline-flex;align-items:center;gap:4px}.c-bool-btn{display:inline-flex;align-items:center;justify-content:center;height:18px;min-width:0;padding:0 8px;border:1px solid currentColor;border-radius:999px;background:transparent;font:inherit;font-size:11px;font-weight:500;line-height:1;cursor:pointer;white-space:nowrap;-webkit-user-select:none;user-select:none;transition:background .12s ease,color .12s ease}:host-context(.c-density-comfortable) .c-bool-btn{height:20px;padding:0 10px;font-size:12px}.c-bool-true{color:var(--sd-success)}.c-bool-false{color:var(--sd-warning)}.c-bool-active.c-bool-true{background:var(--sd-success);color:#fff;border-color:var(--sd-success)}.c-bool-active.c-bool-false{background:var(--sd-warning);color:#fff;border-color:var(--sd-warning)}.c-bool-btn:hover:not(.c-bool-active).c-bool-true{background:var(--sd-success-light)}.c-bool-btn:hover:not(.c-bool-active).c-bool-false{background:var(--sd-warning-light)}.c-token-remove{align-self:stretch;display:inline-flex;align-items:center;justify-content:center;border:none;border-left:1px solid rgba(0,0,0,.04);border-radius:0;background:transparent;cursor:pointer;color:inherit}:host-context(.c-density-compact) .c-token-remove{width:26px}:host-context(.c-density-comfortable) .c-token-remove{width:28px}.c-token-remove mat-icon{font-size:14px;width:14px;height:14px}.c-token-remove:hover{background:#0000000d}\n"] }]
|
|
896
|
+
}], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: true }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], showOperator: [{ type: i0.Input, args: [{ isSignal: true, alias: "showOperator", required: false }] }], autoId: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], valueText: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueText", required: false }] }], isNoData: [{ type: i0.Input, args: [{ isSignal: true, alias: "isNoData", required: false }] }], commit: [{ type: i0.Output, args: ["commit"] }], commitRange: [{ type: i0.Output, args: ["commitRange"] }], liveChange: [{ type: i0.Output, args: ["liveChange"] }], remove: [{ type: i0.Output, args: ["remove"] }] } });
|
|
943
897
|
|
|
944
898
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
945
899
|
/**
|
|
@@ -973,12 +927,12 @@ class SdQueryPopoverChip {
|
|
|
973
927
|
trigger = viewChild('chipTrigger', { ...(ngDevMode ? { debugName: "trigger" } : /* istanbul ignore next */ {}), read: MatMenuTrigger });
|
|
974
928
|
openMenu() { this.trigger()?.openMenu(); }
|
|
975
929
|
closeMenu() { this.trigger()?.closeMenu(); }
|
|
976
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
977
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
930
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQueryPopoverChip, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
931
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: SdQueryPopoverChip, isStandalone: true, selector: "sd-query-popover-chip", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: true, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: true, transformFunction: null }, showOperator: { classPropertyName: "showOperator", publicName: "showOperator", isSignal: true, isRequired: false, transformFunction: null }, valueText: { classPropertyName: "valueText", publicName: "valueText", isSignal: true, isRequired: false, transformFunction: null }, menu: { classPropertyName: "menu", publicName: "menu", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { open: "open", remove: "remove" }, viewQueries: [{ propertyName: "trigger", first: true, predicate: ["chipTrigger"], descendants: true, read: MatMenuTrigger, isSignal: true }], ngImport: i0, template: "<!-- why: div[role=button] (not <button>) so the nested <sd-operator> isn't button-in-button (invalid HTML). -->\n@let _active = active();\n@let _field = field();\n@let _filterField = filterField();\n@let _filterOperator = filterOperator();\n\n<div\n #chipTrigger=\"matMenuTrigger\"\n role=\"button\"\n tabindex=\"0\"\n class=\"c-chip\"\n [class.c-chip-active]=\"_active\"\n [class.c-chip-inactive]=\"!_active\"\n [attr.data-field]=\"_filterField\"\n [matTooltip]=\"_field?.label || _filterField\"\n [matMenuTriggerFor]=\"menu()\"\n (menuOpened)=\"open.emit()\"\n (keydown.enter)=\"chipTrigger.openMenu()\"\n (keydown.space)=\"$event.preventDefault(); chipTrigger.openMenu()\">\n <mat-icon class=\"c-chip-icon\" fontSet=\"material-icons-outlined\">\n {{ _field ? iconFor(_field) : 'tune' }}\n </mat-icon>\n <span class=\"c-chip-label\">{{ _field?.label || _filterField }}</span>\n\n @if (showOperator() && _active) {\n <sd-operator class=\"c-chip-operator\" [operators]=\"[_filterOperator]\" [model]=\"_filterOperator\" [disabled]=\"true\" />\n } @else if (_active) {\n <span class=\"c-chip-sep\">:</span>\n }\n\n @if (_active) {\n <span class=\"c-chip-value\">{{ valueText() }}</span>\n }\n\n <mat-icon class=\"c-chip-chevron\" fontSet=\"material-icons-outlined\">arrow_drop_down</mat-icon>\n\n @if (_active) {\n <span\n role=\"button\"\n tabindex=\"0\"\n class=\"c-chip-remove\"\n aria-label=\"Remove filter\"\n (click)=\"$event.stopPropagation(); remove.emit()\"\n (keydown.enter)=\"$event.stopPropagation(); remove.emit()\">\n <mat-icon fontSet=\"material-icons-outlined\">close</mat-icon>\n </span>\n }\n</div>\n", styles: [":host{display:contents}.c-chip{display:inline-flex;align-items:center;gap:4px;padding:0 4px 0 10px;border-radius:999px;border:1px solid #d6d8db;background:#fff;cursor:pointer;font-family:inherit;font-size:13px;font-weight:500;color:#5f6368;transition:background-color .12s ease,border-color .12s ease,color .12s ease}:host-context(.c-density-compact) .c-chip{height:28px}:host-context(.c-density-comfortable) .c-chip{height:32px}.c-chip:hover{border-color:var(--sd-primary)}.c-chip.c-chip-active{border-color:var(--sd-primary-light);background:var(--sd-primary-light)}.c-chip.c-chip-active .c-chip-value{color:var(--sd-primary)}.c-chip.c-chip-inactive{padding-right:10px}.c-chip .c-chip-icon{font-size:16px;width:16px;height:16px}.c-chip .c-chip-label{font-weight:500;white-space:nowrap}.c-chip .c-chip-operator{display:inline-flex;align-items:center;color:inherit}.c-chip .c-chip-sep{color:#7a7a7a}.c-chip .c-chip-value{font-weight:500;max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c-chip .c-chip-chevron{font-size:18px;width:18px;height:18px;color:currentColor}.c-chip .c-chip-remove{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;cursor:pointer;color:#7a7a7a}.c-chip .c-chip-remove mat-icon{font-size:14px;width:14px;height:14px}.c-chip .c-chip-remove:hover{background:#0000000f}.c-chip-operator ::ng-deep .c-op-trigger{padding:0;color:inherit}.c-chip-operator ::ng-deep .c-op-icon svg{width:14px;height:14px;display:block}\n"], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { kind: "directive", type: i1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: SdOperator, selector: "sd-operator", inputs: ["model", "operators", "disabled", "autoId"], outputs: ["modelChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
978
932
|
}
|
|
979
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
933
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQueryPopoverChip, decorators: [{
|
|
980
934
|
type: Component,
|
|
981
|
-
args: [{ selector: 'sd-query-popover-chip', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatMenuModule, MatIconModule, MatTooltipModule, SdOperator], template: "<!-- why: div[role=button] (not <button>) so the nested <sd-operator> isn't button-in-button (invalid HTML). -->\n<div\n #chipTrigger=\"matMenuTrigger\"\n role=\"button\"\n tabindex=\"0\"\n class=\"c-chip\"\n [class.c-chip-active]=\"
|
|
935
|
+
args: [{ selector: 'sd-query-popover-chip', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatMenuModule, MatIconModule, MatTooltipModule, SdOperator], template: "<!-- why: div[role=button] (not <button>) so the nested <sd-operator> isn't button-in-button (invalid HTML). -->\n@let _active = active();\n@let _field = field();\n@let _filterField = filterField();\n@let _filterOperator = filterOperator();\n\n<div\n #chipTrigger=\"matMenuTrigger\"\n role=\"button\"\n tabindex=\"0\"\n class=\"c-chip\"\n [class.c-chip-active]=\"_active\"\n [class.c-chip-inactive]=\"!_active\"\n [attr.data-field]=\"_filterField\"\n [matTooltip]=\"_field?.label || _filterField\"\n [matMenuTriggerFor]=\"menu()\"\n (menuOpened)=\"open.emit()\"\n (keydown.enter)=\"chipTrigger.openMenu()\"\n (keydown.space)=\"$event.preventDefault(); chipTrigger.openMenu()\">\n <mat-icon class=\"c-chip-icon\" fontSet=\"material-icons-outlined\">\n {{ _field ? iconFor(_field) : 'tune' }}\n </mat-icon>\n <span class=\"c-chip-label\">{{ _field?.label || _filterField }}</span>\n\n @if (showOperator() && _active) {\n <sd-operator class=\"c-chip-operator\" [operators]=\"[_filterOperator]\" [model]=\"_filterOperator\" [disabled]=\"true\" />\n } @else if (_active) {\n <span class=\"c-chip-sep\">:</span>\n }\n\n @if (_active) {\n <span class=\"c-chip-value\">{{ valueText() }}</span>\n }\n\n <mat-icon class=\"c-chip-chevron\" fontSet=\"material-icons-outlined\">arrow_drop_down</mat-icon>\n\n @if (_active) {\n <span\n role=\"button\"\n tabindex=\"0\"\n class=\"c-chip-remove\"\n aria-label=\"Remove filter\"\n (click)=\"$event.stopPropagation(); remove.emit()\"\n (keydown.enter)=\"$event.stopPropagation(); remove.emit()\">\n <mat-icon fontSet=\"material-icons-outlined\">close</mat-icon>\n </span>\n }\n</div>\n", styles: [":host{display:contents}.c-chip{display:inline-flex;align-items:center;gap:4px;padding:0 4px 0 10px;border-radius:999px;border:1px solid #d6d8db;background:#fff;cursor:pointer;font-family:inherit;font-size:13px;font-weight:500;color:#5f6368;transition:background-color .12s ease,border-color .12s ease,color .12s ease}:host-context(.c-density-compact) .c-chip{height:28px}:host-context(.c-density-comfortable) .c-chip{height:32px}.c-chip:hover{border-color:var(--sd-primary)}.c-chip.c-chip-active{border-color:var(--sd-primary-light);background:var(--sd-primary-light)}.c-chip.c-chip-active .c-chip-value{color:var(--sd-primary)}.c-chip.c-chip-inactive{padding-right:10px}.c-chip .c-chip-icon{font-size:16px;width:16px;height:16px}.c-chip .c-chip-label{font-weight:500;white-space:nowrap}.c-chip .c-chip-operator{display:inline-flex;align-items:center;color:inherit}.c-chip .c-chip-sep{color:#7a7a7a}.c-chip .c-chip-value{font-weight:500;max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c-chip .c-chip-chevron{font-size:18px;width:18px;height:18px;color:currentColor}.c-chip .c-chip-remove{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;cursor:pointer;color:#7a7a7a}.c-chip .c-chip-remove mat-icon{font-size:14px;width:14px;height:14px}.c-chip .c-chip-remove:hover{background:#0000000f}.c-chip-operator ::ng-deep .c-op-trigger{padding:0;color:inherit}.c-chip-operator ::ng-deep .c-op-icon svg{width:14px;height:14px;display:block}\n"] }]
|
|
982
936
|
}], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: true }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: true }] }], showOperator: [{ type: i0.Input, args: [{ isSignal: true, alias: "showOperator", required: false }] }], valueText: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueText", required: false }] }], menu: [{ type: i0.Input, args: [{ isSignal: true, alias: "menu", required: true }] }], open: [{ type: i0.Output, args: ["open"] }], remove: [{ type: i0.Output, args: ["remove"] }], trigger: [{ type: i0.ViewChild, args: ['chipTrigger', { ...{ read: MatMenuTrigger }, isSignal: true }] }] } });
|
|
983
937
|
|
|
984
938
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
@@ -1393,10 +1347,10 @@ class SdQueryBar {
|
|
|
1393
1347
|
return items();
|
|
1394
1348
|
return null;
|
|
1395
1349
|
}
|
|
1396
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1397
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: SdQueryBar, isStandalone: true, selector: "sd-query-bar", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: false, transformFunction: null }, filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, logic: { classPropertyName: "logic", publicName: "logic", isSignal: true, isRequired: false, transformFunction: null }, search: { classPropertyName: "search", publicName: "search", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, showSavedFilters: { classPropertyName: "showSavedFilters", publicName: "showSavedFilters", isSignal: true, isRequired: false, transformFunction: null }, savedFiltersKey: { classPropertyName: "savedFiltersKey", publicName: "savedFiltersKey", isSignal: true, isRequired: false, transformFunction: null }, showLogicToggle: { classPropertyName: "showLogicToggle", publicName: "showLogicToggle", isSignal: true, isRequired: false, transformFunction: null }, showClearAll: { classPropertyName: "showClearAll", publicName: "showClearAll", isSignal: true, isRequired: false, transformFunction: null }, showOperatorOnChip: { classPropertyName: "showOperatorOnChip", publicName: "showOperatorOnChip", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filters: "filtersChange", logic: "logicChange", search: "searchChange", queryChange: "queryChange", apply: "apply" }, viewQueries: [{ propertyName: "popoverChips", predicate: SdQueryPopoverChip, descendants: true, isSignal: true }, { propertyName: "buildChip", first: true, predicate: SdQueryBuildChip, descendants: true, isSignal: true }, { propertyName: "chipPopover", first: true, predicate: SdQueryChipPopover, descendants: true, isSignal: true }], ngImport: i0, template: "<!--\n sd-query-bar \u2014 unified filter chip row (Jira/Linear/Notion style).\n Visual spec: refs/design_handoff_sd_query_bar/README.md\n TODO(next-iter): replace inline placeholders for field-picker + chip-popover\n with extracted sub-components driven by CDK overlay.\n-->\n@let _filters = filters();\n@let _fields = fields();\n@let _density = density();\n@let _showOr = showOrConnector();\n@let _used = usedFieldKeys();\n\n<div\n class=\"c-query-bar\"\n [class.c-density-compact]=\"_density === 'compact'\"\n [class.c-density-comfortable]=\"_density === 'comfortable'\">\n\n <!-- Main region \u2014 search + filters + add-filter. Wraps internally; the right\n action toolbar stays anchored and does NOT flow with this. -->\n <div class=\"c-query-bar__main\">\n\n <!-- Free-text search (left, optional) -->\n @if (showSearch()) {\n <div class=\"c-search\">\n <mat-icon class=\"c-search-icon\" fontSet=\"material-icons-outlined\">search</mat-icon>\n <input\n class=\"c-search-input\"\n type=\"text\"\n [ngModel]=\"search()\"\n (ngModelChange)=\"setSearch($event)\"\n (keydown.enter)=\"triggerApply()\"\n placeholder=\"T\u00ECm ki\u1EBFm...\" />\n </div>\n <span class=\"c-divider\" aria-hidden=\"true\"></span>\n }\n\n <!-- Field switcher (used by chipPopover header) \u2014 declared first so chipPopover's\n nested ng-template can resolve the template ref. -->\n <!-- Field switcher used by chipPopover header \u2014 current field key comes from editingIndex. -->\n <sd-query-field-picker\n #switchPicker\n [fields]=\"_fields\"\n [currentKey]=\"editingIndex() !== null ? $any(filters()[editingIndex()!])?.field : undefined\"\n (pick)=\"editingIndex() !== null && changeFilterField(editingIndex()!, $event)\" />\n\n <!-- Chip popover \u2014 extracted into <sd-query-chip-popover>. Declared BEFORE chips\n so the popover-mode @for chips can bind their [menu] to `chipPopover.menu()`. -->\n <sd-query-chip-popover\n #chipPopover\n [field]=\"editingField() ?? undefined\"\n [filter]=\"editingIndex() !== null ? $any(filters()[editingIndex()!]) : undefined\"\n [chipIndex]=\"editingIndex()\"\n [autoIdBase]=\"autoIdInput() ?? 'qb'\"\n [switchPickerMenu]=\"switchPicker.menu()!\"\n (commit)=\"onChipPopoverCommit($event)\"\n (swapField)=\"editingIndex() !== null && changeFilterField(editingIndex()!, $event)\" />\n\n @if (mode() === 'inline') {\n <!-- ===== INLINE MODE (GitLab-style token builder) ===== -->\n\n <!-- Completed chips -->\n @for (filter of _filters; track $index; let i = $index) {\n @if (_showOr && i > 0) {\n <span class=\"c-or-connector\" aria-hidden=\"true\">OR</span>\n }\n @let _field = fieldByKey()[$any(filter).field];\n @if (_field) {\n @let _op = $any(filter.operator);\n @let _data = $any(filter).data;\n @if (_field.type === 'string' || _field.type === 'number') {\n <!-- Seamless chip \u2014 the pill is the input (string / number). -->\n <sd-query-inline-value-chip\n [field]=\"_field\"\n [operator]=\"_op\"\n [value]=\"_data\"\n [density]=\"_density\"\n [showOperator]=\"showOperatorOnChip()\"\n [autoId]=\"inlineAutoId(i, 'value')\"\n (valueChange)=\"updateFilter(i, { data: $event })\"\n (remove)=\"removeFilter(i)\" />\n } @else {\n <sd-query-inline-chip\n [field]=\"_field\"\n [filter]=\"filter\"\n [density]=\"_density\"\n [multiple]=\"multiple(_op)\"\n [showOperator]=\"showOperatorOnChip()\"\n [autoId]=\"inlineAutoId(i, 'value')\"\n [valueText]=\"chipValueText(filter)\"\n [isNoData]=\"isNoDataOperator(_op)\"\n (commit)=\"updateFilter(i, { data: $event })\"\n (commitRange)=\"setFilterRange(i, $event)\"\n (liveChange)=\"updateFilter(i, { data: $event })\"\n (remove)=\"removeFilter(i)\" />\n }\n }\n }\n\n <!-- Building chip (in-progress) \u2014 extracted into <sd-query-build-chip>. -->\n @if (building(); as _b) {\n <sd-query-build-chip\n [building]=\"_b\"\n [density]=\"_density\"\n [allowedOperators]=\"allowedOperatorsFor(_b.field)\"\n [multiple]=\"multiple($any(_b.operator))\"\n [showOperator]=\"showOperatorOnChip()\"\n (pickOperator)=\"pickBuildOperator($any($event))\"\n (commitValue)=\"commitBuildValue($event)\"\n (cancel)=\"cancelBuild()\"\n (seamlessCommit)=\"onBuildSeamlessCommit($event)\" />\n }\n\n <!-- Add filter -->\n <button\n type=\"button\"\n class=\"c-add-filter\"\n [matMenuTriggerFor]=\"addPicker.menu()\"\n [disabled]=\"_fields.length === 0 || _used.size >= _fields.length\"\n [matTooltip]=\"_fields.length === 0 ? 'Ch\u01B0a c\u1EA5u h\u00ECnh fields' : 'Th\u00EAm filter'\">\n <mat-icon fontSet=\"material-icons-outlined\">add</mat-icon>\n </button>\n } @else {\n <!-- ===== POPOVER MODE (default) \u2014 compact chips edited via mat-menu ===== -->\n @for (filter of _filters; track $index; let i = $index) {\n @if (_showOr && i > 0) {\n <span class=\"c-or-connector\" aria-hidden=\"true\">OR</span>\n }\n @let _field = fieldByKey()[$any(filter).field];\n @let _active = isFilterActive(filter);\n <!-- why: menu close commit is handled by chipPopover's (commit) \u2192\n onChipPopoverCommit; popover-chip only signals open + remove here. -->\n <sd-query-popover-chip\n [field]=\"_field\"\n [filter]=\"filter\"\n [active]=\"_active\"\n [showOperator]=\"showOperatorOnChip()\"\n [valueText]=\"chipValueText(filter)\"\n [menu]=\"chipPopover.menu()!\"\n (open)=\"openChipPopover(i)\"\n (remove)=\"removeFilter(i)\" />\n }\n\n <!-- Add filter trigger -->\n <button\n type=\"button\"\n class=\"c-add-filter\"\n [matMenuTriggerFor]=\"addPicker.menu()\"\n [disabled]=\"_fields.length === 0 || _used.size >= _fields.length\"\n [matTooltip]=\"_fields.length === 0 ? 'Ch\u01B0a c\u1EA5u h\u00ECnh fields' : 'Th\u00EAm filter'\">\n <mat-icon fontSet=\"material-icons-outlined\">add</mat-icon>\n </button>\n }\n\n </div><!-- /.c-query-bar__main -->\n\n <!-- Field picker \u2014 list available fields, fade ones already in use. -->\n <sd-query-field-picker\n #addPicker\n [fields]=\"_fields\"\n [usedKeys]=\"_used\"\n (pick)=\"mode() === 'inline' ? beginBuild($event) : addFilter($event)\" />\n\n <sd-query-actions-bar\n [showLogicToggle]=\"showLogicToggle()\"\n [(logic)]=\"logic\"\n [filtersCount]=\"_filters.length\"\n [showSavedFilters]=\"showSavedFilters()\"\n [savedFiltersKey]=\"savedFiltersKey()\"\n [query]=\"currentQuery()\"\n (applyFilter)=\"onApplyFilter($event)\"\n [showClearAll]=\"showClearAll()\"\n [canSearch]=\"canSearch()\"\n (clear)=\"clearAll()\"\n (search)=\"triggerApply()\" />\n</div>\n", styles: [":host{display:block;font-family:Roboto,system-ui,sans-serif}.c-query-bar{display:flex;align-items:flex-start;flex-wrap:nowrap;gap:8px;background:#fff;border:1px solid #e2e4e7;border-radius:8px;box-shadow:0 1px 2px #0f172a0a}.c-query-bar.c-density-compact{padding:8px}.c-query-bar.c-density-comfortable{padding:10px}.c-query-bar__main{flex:1 1 auto;min-width:0;display:flex;align-items:center;flex-wrap:wrap;gap:6px}.c-search{display:flex;align-items:center;gap:6px;min-width:220px;padding:0 10px;border:1px solid #d6d8db;border-radius:6px;background:#fff}.c-density-compact .c-search{height:28px}.c-density-comfortable .c-search{height:32px}.c-search .c-search-icon{font-size:16px;width:16px;height:16px;color:#7a7a7a}.c-search .c-search-input{flex:1;border:none;outline:none;background:transparent;font-size:13px;color:#212121}.c-search .c-search-input::placeholder{color:#7a7a7a}.c-search .c-search-kbd{font-family:Roboto Mono,monospace;font-size:10px;padding:1px 4px;border:1px solid #e2e4e7;border-radius:3px;color:#7a7a7a}.c-divider{width:1px;height:16px;background:#e2e4e7;margin:0 2px}.c-token{display:inline-flex;align-items:center;gap:4px;padding:0 0 0 12px;border:1px solid var(--sd-primary-light);border-radius:999px;background:var(--sd-primary-light);font-size:13px;color:#5f6368;white-space:nowrap;overflow:hidden}.c-density-compact .c-token{height:28px}.c-density-comfortable .c-token{height:32px}.c-token-icon{font-size:14px;width:14px;height:14px;line-height:14px;color:inherit}.c-token-field{font-weight:500;line-height:1}.c-token-op{display:inline-flex;align-items:center;color:inherit}.c-token-op ::ng-deep .c-op-trigger{padding:0;color:inherit}.c-token-op ::ng-deep .c-op-icon svg{width:14px;height:14px;display:block}.c-token-value-edit sd-select,.c-token-value-edit sd-date,.c-token-value-edit sd-datetime{display:inline-flex;align-items:center;line-height:1}.c-token ::ng-deep .mat-mdc-form-field{line-height:1}.c-token ::ng-deep .mat-mdc-text-field-wrapper,.c-token ::ng-deep .mat-mdc-form-field-flex{padding:0;min-height:0;background:transparent}.c-token ::ng-deep .mat-mdc-form-field-infix{padding:0;min-height:0;width:auto;border:0;display:inline-flex;align-items:center}.c-token ::ng-deep .mat-mdc-select-value,.c-token ::ng-deep .mat-mdc-input-element,.c-token ::ng-deep input{line-height:1;font-size:13px;padding:0;height:auto;color:inherit}.c-token ::ng-deep .mat-mdc-select-value{display:inline-flex;align-items:center;min-width:0;max-width:200px;overflow:hidden;text-overflow:ellipsis;color:var(--sd-primary);font-weight:500}.c-token ::ng-deep .sd-suffix-icon{display:none}.c-token-sep{color:#7a7a7a}.c-token-dash{color:#7a7a7a;padding:0 4px;line-height:1}.c-token-value{border:none;background:transparent;padding:0;font:inherit;font-weight:500;color:var(--sd-primary);cursor:pointer}.c-token-value:hover{text-decoration:underline}.c-token-value-edit{display:inline-flex;align-items:center;gap:4px;max-width:240px}.c-token-value-edit sd-input,.c-token-value-edit sd-input-number{display:inline-flex;max-width:140px}.c-token-value-edit sd-date-range{display:inline-flex;max-width:220px;min-width:0;flex:0 1 auto}.c-token-multi-head{display:inline-block;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}.c-token-remove{align-self:stretch;display:inline-flex;align-items:center;justify-content:center;border:none;border-left:1px solid rgba(0,0,0,.04);border-radius:0;background:transparent;cursor:pointer;color:inherit}.c-density-compact .c-token-remove{width:26px}.c-density-comfortable .c-token-remove{width:28px}.c-token-remove mat-icon{font-size:14px;width:14px;height:14px}.c-token-remove:hover{background:#0000000d}.c-add-filter{display:inline-flex;align-items:center;justify-content:center;padding:0;border-radius:999px;border:1px dashed #d6d8db;background:transparent;cursor:pointer;color:#5f6368;transition:border-color .12s ease,color .12s ease,background-color .12s ease}.c-density-compact .c-add-filter{width:28px;height:28px}.c-density-comfortable .c-add-filter{width:32px;height:32px}.c-add-filter mat-icon{font-size:18px;width:18px;height:18px}.c-add-filter:hover:not([disabled]){border-color:var(--sd-primary);color:var(--sd-primary)}.c-add-filter[disabled]{opacity:.5;cursor:not-allowed}.c-or-connector{font-family:Roboto Mono,monospace;font-size:10px;font-weight:700;letter-spacing:.6px;color:#7a7a7a;padding:0 2px}::ng-deep .mat-mdc-menu-panel.c-chip-popover{min-width:280px;max-width:320px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid #e2e4e7;font-size:13px;font-weight:500;color:#212121}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header mat-icon{font-size:16px;width:16px;height:16px;color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header .c-pop-header-operator{margin-left:auto}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field{display:inline-flex;align-items:center;gap:4px;padding:2px 4px 2px 6px;margin-left:-4px;background:transparent;border:1px solid transparent;border-radius:4px;font:inherit;font-weight:500;color:#212121;cursor:pointer;transition:background-color .12s ease,border-color .12s ease}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#7a7a7a!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field:hover{background:#f5f6f7;border-color:#e2e4e7}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-body{padding:10px 12px;display:flex;flex-direction:column;gap:12px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-input{width:100%;height:32px;padding:0 10px;border:1px solid #d6d8db;border-radius:6px;background:#fff;font-family:inherit;font-size:13px;color:#212121;outline:none}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-input:focus{border-color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-between{display:grid;grid-template-columns:1fr 1fr;gap:8px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-boolean{display:flex;gap:8px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-boolean button{flex:1;height:32px;border:1px solid #d6d8db;border-radius:6px;background:#fff;font:inherit;font-size:13px;cursor:pointer}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-boolean button.c-pop-boolean-active{background:var(--sd-primary-light);border-color:var(--sd-primary);color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values{max-height:220px;overflow-y:auto;margin:0;padding:0;list-style:none}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:4px;font-size:13px;cursor:pointer;-webkit-user-select:none;user-select:none}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li:hover{background:#f5f6f7}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li.c-pop-value-selected{background:var(--sd-primary-light);color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li input[type=checkbox],::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li input[type=radio]{accent-color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values-loading,::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values-empty{padding:10px 8px;font-size:12px;color:#7a7a7a}.c-bool-toggle{display:inline-flex;align-items:center;gap:4px}.c-bool-toggle ::ng-deep .mdc-button,.c-bool-toggle ::ng-deep button[mat-button],.c-bool-toggle ::ng-deep button[mat-stroked-button],.c-bool-toggle ::ng-deep button[mat-flat-button]{border-radius:999px;min-width:0;padding:0 12px}\n", ".c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__leading,.c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__notch,.c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__trailing{border-color:#d6d8db!important;transition:border-color .12s ease}.c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__leading{border-radius:6px 0 0 6px!important}.c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__trailing{border-radius:0 6px 6px 0!important}.c-query-bar ::ng-deep .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__leading,.c-query-bar ::ng-deep .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__notch,.c-query-bar ::ng-deep .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__trailing{border-color:#b9bdc3!important}.c-query-bar ::ng-deep .mat-mdc-form-field.mat-focused .mdc-notched-outline__leading,.c-query-bar ::ng-deep .mat-mdc-form-field.mat-focused .mdc-notched-outline__notch,.c-query-bar ::ng-deep .mat-mdc-form-field.mat-focused .mdc-notched-outline__trailing{border-color:var(--sd-primary)!important;border-width:1px!important}.c-query-bar ::ng-deep .mat-mdc-form-field .mat-mdc-select-arrow,.c-query-bar ::ng-deep .mat-mdc-form-field .mat-mdc-form-field-icon-suffix .mat-icon{color:#5f6368}.c-query-bar ::ng-deep .mat-mdc-form-field.mat-focused .mat-mdc-select-arrow{color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__trailing,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__trailing{border-color:#d6d8db!important;transition:border-color .12s ease}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__leading{border-radius:6px 0 0 6px!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__trailing,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__trailing{border-radius:0 6px 6px 0!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__trailing,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__trailing{border-color:#b9bdc3!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field.mat-focused .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field.mat-focused .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field.mat-focused .mdc-notched-outline__trailing,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field.mat-focused .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field.mat-focused .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field.mat-focused .mdc-notched-outline__trailing{border-color:var(--sd-primary)!important;border-width:1px!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mat-mdc-select-arrow,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mat-mdc-form-field-icon-suffix .mat-icon,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mat-mdc-select-arrow,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mat-mdc-form-field-icon-suffix .mat-icon{color:#5f6368}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field.mat-focused .mat-mdc-select-arrow,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field.mat-focused .mat-mdc-select-arrow{color:var(--sd-primary)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "directive", type: i1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: SdQueryActionsBar, selector: "sd-query-actions-bar", inputs: ["showLogicToggle", "logic", "filtersCount", "showSavedFilters", "savedFiltersKey", "query", "showClearAll", "canSearch"], outputs: ["logicChange", "applyFilter", "clear", "search"] }, { kind: "component", type: SdQueryBuildChip, selector: "sd-query-build-chip", inputs: ["building", "density", "allowedOperators", "multiple", "showOperator", "autoId"], outputs: ["pickOperator", "commitValue", "cancel", "seamlessCommit", "draftChange", "draftCommit"] }, { kind: "component", type: SdQueryChipPopover, selector: "sd-query-chip-popover", inputs: ["field", "filter", "chipIndex", "autoIdBase", "switchPickerMenu"], outputs: ["commit", "swapField"] }, { kind: "component", type: SdQueryFieldPicker, selector: "sd-query-field-picker", inputs: ["fields", "currentKey", "usedKeys"], outputs: ["pick"] }, { kind: "component", type: SdQueryInlineChip, selector: "sd-query-inline-chip", inputs: ["field", "filter", "density", "multiple", "showOperator", "autoId", "valueText", "isNoData"], outputs: ["commit", "commitRange", "liveChange", "remove"] }, { kind: "component", type: SdQueryInlineValueChip, selector: "sd-query-inline-value-chip", inputs: ["field", "operator", "value", "density", "showOperator", "autoId", "autofocus"], outputs: ["valueChange", "remove"] }, { kind: "component", type: SdQueryPopoverChip, selector: "sd-query-popover-chip", inputs: ["field", "filter", "active", "showOperator", "valueText", "menu"], outputs: ["open", "remove"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1350
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQueryBar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1351
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: SdQueryBar, isStandalone: true, selector: "sd-query-bar", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: false, transformFunction: null }, filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, logic: { classPropertyName: "logic", publicName: "logic", isSignal: true, isRequired: false, transformFunction: null }, search: { classPropertyName: "search", publicName: "search", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, showSavedFilters: { classPropertyName: "showSavedFilters", publicName: "showSavedFilters", isSignal: true, isRequired: false, transformFunction: null }, savedFiltersKey: { classPropertyName: "savedFiltersKey", publicName: "savedFiltersKey", isSignal: true, isRequired: false, transformFunction: null }, showLogicToggle: { classPropertyName: "showLogicToggle", publicName: "showLogicToggle", isSignal: true, isRequired: false, transformFunction: null }, showClearAll: { classPropertyName: "showClearAll", publicName: "showClearAll", isSignal: true, isRequired: false, transformFunction: null }, showOperatorOnChip: { classPropertyName: "showOperatorOnChip", publicName: "showOperatorOnChip", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filters: "filtersChange", logic: "logicChange", search: "searchChange", queryChange: "queryChange", apply: "apply" }, viewQueries: [{ propertyName: "popoverChips", predicate: SdQueryPopoverChip, descendants: true, isSignal: true }, { propertyName: "buildChip", first: true, predicate: SdQueryBuildChip, descendants: true, isSignal: true }, { propertyName: "chipPopover", first: true, predicate: SdQueryChipPopover, descendants: true, isSignal: true }], ngImport: i0, template: "<!--\n sd-query-bar \u2014 unified filter chip row (Jira/Linear/Notion style).\n Visual spec: refs/design_handoff_sd_query_bar/README.md\n TODO(next-iter): replace inline placeholders for field-picker + chip-popover\n with extracted sub-components driven by CDK overlay.\n-->\n@let _filters = filters();\n@let _fields = fields();\n@let _density = density();\n@let _showOr = showOrConnector();\n@let _used = usedFieldKeys();\n@let _editingIndex = editingIndex();\n@let _mode = mode();\n@let _showOpOnChip = showOperatorOnChip();\n\n<div\n class=\"c-query-bar\"\n [class.c-density-compact]=\"_density === 'compact'\"\n [class.c-density-comfortable]=\"_density === 'comfortable'\">\n\n <!-- Main region \u2014 search + filters + add-filter. Wraps internally; the right\n action toolbar stays anchored and does NOT flow with this. -->\n <div class=\"c-query-bar__main\">\n\n <!-- Free-text search (left, optional) -->\n @if (showSearch()) {\n <div class=\"c-search\">\n <mat-icon class=\"c-search-icon\" fontSet=\"material-icons-outlined\">search</mat-icon>\n <input\n class=\"c-search-input\"\n type=\"text\"\n [ngModel]=\"search()\"\n (ngModelChange)=\"setSearch($event)\"\n (keydown.enter)=\"triggerApply()\"\n placeholder=\"T\u00ECm ki\u1EBFm...\" />\n </div>\n <span class=\"c-divider\" aria-hidden=\"true\"></span>\n }\n\n <!-- Field switcher (used by chipPopover header) \u2014 declared first so chipPopover's\n nested ng-template can resolve the template ref. -->\n <!-- Field switcher used by chipPopover header \u2014 current field key comes from editingIndex. -->\n <sd-query-field-picker\n #switchPicker\n [fields]=\"_fields\"\n [currentKey]=\"_editingIndex !== null ? $any(_filters[_editingIndex!])?.field : undefined\"\n (pick)=\"_editingIndex !== null && changeFilterField(_editingIndex!, $event)\" />\n\n <!-- Chip popover \u2014 extracted into <sd-query-chip-popover>. Declared BEFORE chips\n so the popover-mode @for chips can bind their [menu] to `chipPopover.menu()`. -->\n <sd-query-chip-popover\n #chipPopover\n [field]=\"editingField() ?? undefined\"\n [filter]=\"_editingIndex !== null ? $any(_filters[_editingIndex!]) : undefined\"\n [chipIndex]=\"_editingIndex\"\n [autoIdBase]=\"autoIdInput() ?? 'qb'\"\n [switchPickerMenu]=\"switchPicker.menu()!\"\n (commit)=\"onChipPopoverCommit($event)\"\n (swapField)=\"_editingIndex !== null && changeFilterField(_editingIndex!, $event)\" />\n\n @if (_mode === 'inline') {\n <!-- ===== INLINE MODE (GitLab-style token builder) ===== -->\n\n <!-- Completed chips -->\n @for (filter of _filters; track $index; let i = $index) {\n @if (_showOr && i > 0) {\n <span class=\"c-or-connector\" aria-hidden=\"true\">OR</span>\n }\n @let _field = fieldByKey()[$any(filter).field];\n @if (_field) {\n @let _op = $any(filter.operator);\n @let _data = $any(filter).data;\n @if (_field.type === 'string' || _field.type === 'number') {\n <!-- Seamless chip \u2014 the pill is the input (string / number). -->\n <sd-query-inline-value-chip\n [field]=\"_field\"\n [operator]=\"_op\"\n [value]=\"_data\"\n [density]=\"_density\"\n [showOperator]=\"_showOpOnChip\"\n [autoId]=\"inlineAutoId(i, 'value')\"\n (valueChange)=\"updateFilter(i, { data: $event })\"\n (remove)=\"removeFilter(i)\" />\n } @else {\n <sd-query-inline-chip\n [field]=\"_field\"\n [filter]=\"filter\"\n [density]=\"_density\"\n [multiple]=\"multiple(_op)\"\n [showOperator]=\"_showOpOnChip\"\n [autoId]=\"inlineAutoId(i, 'value')\"\n [valueText]=\"chipValueText(filter)\"\n [isNoData]=\"isNoDataOperator(_op)\"\n (commit)=\"updateFilter(i, { data: $event })\"\n (commitRange)=\"setFilterRange(i, $event)\"\n (liveChange)=\"updateFilter(i, { data: $event })\"\n (remove)=\"removeFilter(i)\" />\n }\n }\n }\n\n <!-- Building chip (in-progress) \u2014 extracted into <sd-query-build-chip>. -->\n @if (building(); as _b) {\n <sd-query-build-chip\n [building]=\"_b\"\n [density]=\"_density\"\n [allowedOperators]=\"allowedOperatorsFor(_b.field)\"\n [multiple]=\"multiple($any(_b.operator))\"\n [showOperator]=\"_showOpOnChip\"\n (pickOperator)=\"pickBuildOperator($any($event))\"\n (commitValue)=\"commitBuildValue($event)\"\n (cancel)=\"cancelBuild()\"\n (seamlessCommit)=\"onBuildSeamlessCommit($event)\" />\n }\n\n <!-- Add filter -->\n <button\n type=\"button\"\n class=\"c-add-filter\"\n [matMenuTriggerFor]=\"addPicker.menu()\"\n [disabled]=\"_fields.length === 0 || _used.size >= _fields.length\"\n [matTooltip]=\"_fields.length === 0 ? 'Ch\u01B0a c\u1EA5u h\u00ECnh fields' : 'Th\u00EAm filter'\">\n <mat-icon fontSet=\"material-icons-outlined\">add</mat-icon>\n </button>\n } @else {\n <!-- ===== POPOVER MODE (default) \u2014 compact chips edited via mat-menu ===== -->\n @for (filter of _filters; track $index; let i = $index) {\n @if (_showOr && i > 0) {\n <span class=\"c-or-connector\" aria-hidden=\"true\">OR</span>\n }\n @let _field = fieldByKey()[$any(filter).field];\n @let _active = isFilterActive(filter);\n <!-- why: menu close commit is handled by chipPopover's (commit) \u2192\n onChipPopoverCommit; popover-chip only signals open + remove here. -->\n <sd-query-popover-chip\n [field]=\"_field\"\n [filter]=\"filter\"\n [active]=\"_active\"\n [showOperator]=\"_showOpOnChip\"\n [valueText]=\"chipValueText(filter)\"\n [menu]=\"chipPopover.menu()!\"\n (open)=\"openChipPopover(i)\"\n (remove)=\"removeFilter(i)\" />\n }\n\n <!-- Add filter trigger -->\n <button\n type=\"button\"\n class=\"c-add-filter\"\n [matMenuTriggerFor]=\"addPicker.menu()\"\n [disabled]=\"_fields.length === 0 || _used.size >= _fields.length\"\n [matTooltip]=\"_fields.length === 0 ? 'Ch\u01B0a c\u1EA5u h\u00ECnh fields' : 'Th\u00EAm filter'\">\n <mat-icon fontSet=\"material-icons-outlined\">add</mat-icon>\n </button>\n }\n\n </div><!-- /.c-query-bar__main -->\n\n <!-- Field picker \u2014 list available fields, fade ones already in use. -->\n <sd-query-field-picker\n #addPicker\n [fields]=\"_fields\"\n [usedKeys]=\"_used\"\n (pick)=\"_mode === 'inline' ? beginBuild($event) : addFilter($event)\" />\n\n <sd-query-actions-bar\n [showLogicToggle]=\"showLogicToggle()\"\n [(logic)]=\"logic\"\n [filtersCount]=\"_filters.length\"\n [showSavedFilters]=\"showSavedFilters()\"\n [savedFiltersKey]=\"savedFiltersKey()\"\n [query]=\"currentQuery()\"\n (applyFilter)=\"onApplyFilter($event)\"\n [showClearAll]=\"showClearAll()\"\n [canSearch]=\"canSearch()\"\n (clear)=\"clearAll()\"\n (search)=\"triggerApply()\" />\n</div>\n", styles: [":host{display:block;font-family:Roboto,system-ui,sans-serif}.c-query-bar{display:flex;align-items:flex-start;flex-wrap:nowrap;gap:8px;background:#fff;border:1px solid #e2e4e7;border-radius:8px;box-shadow:0 1px 2px #0f172a0a}.c-query-bar.c-density-compact{padding:8px}.c-query-bar.c-density-comfortable{padding:10px}.c-query-bar__main{flex:1 1 auto;min-width:0;display:flex;align-items:center;flex-wrap:wrap;gap:6px}.c-search{display:flex;align-items:center;gap:6px;min-width:220px;padding:0 10px;border:1px solid #d6d8db;border-radius:6px;background:#fff}.c-density-compact .c-search{height:28px}.c-density-comfortable .c-search{height:32px}.c-search .c-search-icon{font-size:16px;width:16px;height:16px;color:#7a7a7a}.c-search .c-search-input{flex:1;border:none;outline:none;background:transparent;font-size:13px;color:#212121}.c-search .c-search-input::placeholder{color:#7a7a7a}.c-search .c-search-kbd{font-family:Roboto Mono,monospace;font-size:10px;padding:1px 4px;border:1px solid #e2e4e7;border-radius:3px;color:#7a7a7a}.c-divider{width:1px;height:16px;background:#e2e4e7;margin:0 2px}.c-token{display:inline-flex;align-items:center;gap:4px;padding:0 0 0 12px;border:1px solid var(--sd-primary-light);border-radius:999px;background:var(--sd-primary-light);font-size:13px;color:#5f6368;white-space:nowrap;overflow:hidden}.c-density-compact .c-token{height:28px}.c-density-comfortable .c-token{height:32px}.c-token-icon{font-size:14px;width:14px;height:14px;line-height:14px;color:inherit}.c-token-field{font-weight:500;line-height:1}.c-token-op{display:inline-flex;align-items:center;color:inherit}.c-token-op ::ng-deep .c-op-trigger{padding:0;color:inherit}.c-token-op ::ng-deep .c-op-icon svg{width:14px;height:14px;display:block}.c-token-value-edit sd-select,.c-token-value-edit sd-date,.c-token-value-edit sd-datetime{display:inline-flex;align-items:center;line-height:1}.c-token ::ng-deep .mat-mdc-form-field{line-height:1}.c-token ::ng-deep .mat-mdc-text-field-wrapper,.c-token ::ng-deep .mat-mdc-form-field-flex{padding:0;min-height:0;background:transparent}.c-token ::ng-deep .mat-mdc-form-field-infix{padding:0;min-height:0;width:auto;border:0;display:inline-flex;align-items:center}.c-token ::ng-deep .mat-mdc-select-value,.c-token ::ng-deep .mat-mdc-input-element,.c-token ::ng-deep input{line-height:1;font-size:13px;padding:0;height:auto;color:inherit}.c-token ::ng-deep .mat-mdc-select-value{display:inline-flex;align-items:center;min-width:0;max-width:200px;overflow:hidden;text-overflow:ellipsis;color:var(--sd-primary);font-weight:500}.c-token ::ng-deep .sd-suffix-icon{display:none}.c-token-sep{color:#7a7a7a}.c-token-dash{color:#7a7a7a;padding:0 4px;line-height:1}.c-token-value{border:none;background:transparent;padding:0;font:inherit;font-weight:500;color:var(--sd-primary);cursor:pointer}.c-token-value:hover{text-decoration:underline}.c-token-value-edit{display:inline-flex;align-items:center;gap:4px;max-width:240px}.c-token-value-edit sd-input,.c-token-value-edit sd-input-number{display:inline-flex;max-width:140px}.c-token-value-edit sd-date-range{display:inline-flex;max-width:220px;min-width:0;flex:0 1 auto}.c-token-multi-head{display:inline-block;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}.c-token-remove{align-self:stretch;display:inline-flex;align-items:center;justify-content:center;border:none;border-left:1px solid rgba(0,0,0,.04);border-radius:0;background:transparent;cursor:pointer;color:inherit}.c-density-compact .c-token-remove{width:26px}.c-density-comfortable .c-token-remove{width:28px}.c-token-remove mat-icon{font-size:14px;width:14px;height:14px}.c-token-remove:hover{background:#0000000d}.c-add-filter{display:inline-flex;align-items:center;justify-content:center;padding:0;border-radius:999px;border:1px dashed #d6d8db;background:transparent;cursor:pointer;color:#5f6368;transition:border-color .12s ease,color .12s ease,background-color .12s ease}.c-density-compact .c-add-filter{width:28px;height:28px}.c-density-comfortable .c-add-filter{width:32px;height:32px}.c-add-filter mat-icon{font-size:18px;width:18px;height:18px}.c-add-filter:hover:not([disabled]){border-color:var(--sd-primary);color:var(--sd-primary)}.c-add-filter[disabled]{opacity:.5;cursor:not-allowed}.c-or-connector{font-family:Roboto Mono,monospace;font-size:10px;font-weight:700;letter-spacing:.6px;color:#7a7a7a;padding:0 2px}::ng-deep .mat-mdc-menu-panel.c-chip-popover{min-width:280px;max-width:320px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid #e2e4e7;font-size:13px;font-weight:500;color:#212121}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header mat-icon{font-size:16px;width:16px;height:16px;color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header .c-pop-header-operator{margin-left:auto}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field{display:inline-flex;align-items:center;gap:4px;padding:2px 4px 2px 6px;margin-left:-4px;background:transparent;border:1px solid transparent;border-radius:4px;font:inherit;font-weight:500;color:#212121;cursor:pointer;transition:background-color .12s ease,border-color .12s ease}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#7a7a7a!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field:hover{background:#f5f6f7;border-color:#e2e4e7}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-body{padding:10px 12px;display:flex;flex-direction:column;gap:12px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-input{width:100%;height:32px;padding:0 10px;border:1px solid #d6d8db;border-radius:6px;background:#fff;font-family:inherit;font-size:13px;color:#212121;outline:none}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-input:focus{border-color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-between{display:grid;grid-template-columns:1fr 1fr;gap:8px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-boolean{display:flex;gap:8px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-boolean button{flex:1;height:32px;border:1px solid #d6d8db;border-radius:6px;background:#fff;font:inherit;font-size:13px;cursor:pointer}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-boolean button.c-pop-boolean-active{background:var(--sd-primary-light);border-color:var(--sd-primary);color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values{max-height:220px;overflow-y:auto;margin:0;padding:0;list-style:none}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:4px;font-size:13px;cursor:pointer;-webkit-user-select:none;user-select:none}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li:hover{background:#f5f6f7}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li.c-pop-value-selected{background:var(--sd-primary-light);color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li input[type=checkbox],::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li input[type=radio]{accent-color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values-loading,::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values-empty{padding:10px 8px;font-size:12px;color:#7a7a7a}.c-bool-toggle{display:inline-flex;align-items:center;gap:4px}.c-bool-toggle ::ng-deep .mdc-button,.c-bool-toggle ::ng-deep button[mat-button],.c-bool-toggle ::ng-deep button[mat-stroked-button],.c-bool-toggle ::ng-deep button[mat-flat-button]{border-radius:999px;min-width:0;padding:0 12px}\n", ".c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__leading,.c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__notch,.c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__trailing{border-color:#d6d8db!important;transition:border-color .12s ease}.c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__leading{border-radius:6px 0 0 6px!important}.c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__trailing{border-radius:0 6px 6px 0!important}.c-query-bar ::ng-deep .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__leading,.c-query-bar ::ng-deep .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__notch,.c-query-bar ::ng-deep .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__trailing{border-color:#b9bdc3!important}.c-query-bar ::ng-deep .mat-mdc-form-field.mat-focused .mdc-notched-outline__leading,.c-query-bar ::ng-deep .mat-mdc-form-field.mat-focused .mdc-notched-outline__notch,.c-query-bar ::ng-deep .mat-mdc-form-field.mat-focused .mdc-notched-outline__trailing{border-color:var(--sd-primary)!important;border-width:1px!important}.c-query-bar ::ng-deep .mat-mdc-form-field .mat-mdc-select-arrow,.c-query-bar ::ng-deep .mat-mdc-form-field .mat-mdc-form-field-icon-suffix .mat-icon{color:#5f6368}.c-query-bar ::ng-deep .mat-mdc-form-field.mat-focused .mat-mdc-select-arrow{color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__trailing,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__trailing{border-color:#d6d8db!important;transition:border-color .12s ease}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__leading{border-radius:6px 0 0 6px!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__trailing,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__trailing{border-radius:0 6px 6px 0!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__trailing,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__trailing{border-color:#b9bdc3!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field.mat-focused .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field.mat-focused .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field.mat-focused .mdc-notched-outline__trailing,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field.mat-focused .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field.mat-focused .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field.mat-focused .mdc-notched-outline__trailing{border-color:var(--sd-primary)!important;border-width:1px!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mat-mdc-select-arrow,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mat-mdc-form-field-icon-suffix .mat-icon,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mat-mdc-select-arrow,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mat-mdc-form-field-icon-suffix .mat-icon{color:#5f6368}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field.mat-focused .mat-mdc-select-arrow,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field.mat-focused .mat-mdc-select-arrow{color:var(--sd-primary)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "directive", type: i1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: SdQueryActionsBar, selector: "sd-query-actions-bar", inputs: ["showLogicToggle", "logic", "filtersCount", "showSavedFilters", "savedFiltersKey", "query", "showClearAll", "canSearch"], outputs: ["logicChange", "applyFilter", "clear", "search"] }, { kind: "component", type: SdQueryBuildChip, selector: "sd-query-build-chip", inputs: ["building", "density", "allowedOperators", "multiple", "showOperator", "autoId"], outputs: ["pickOperator", "commitValue", "cancel", "seamlessCommit", "draftChange", "draftCommit"] }, { kind: "component", type: SdQueryChipPopover, selector: "sd-query-chip-popover", inputs: ["field", "filter", "chipIndex", "autoIdBase", "switchPickerMenu"], outputs: ["commit", "swapField"] }, { kind: "component", type: SdQueryFieldPicker, selector: "sd-query-field-picker", inputs: ["fields", "currentKey", "usedKeys"], outputs: ["pick"] }, { kind: "component", type: SdQueryInlineChip, selector: "sd-query-inline-chip", inputs: ["field", "filter", "density", "multiple", "showOperator", "autoId", "valueText", "isNoData"], outputs: ["commit", "commitRange", "liveChange", "remove"] }, { kind: "component", type: SdQueryInlineValueChip, selector: "sd-query-inline-value-chip", inputs: ["field", "operator", "value", "density", "showOperator", "autoId", "autofocus"], outputs: ["valueChange", "remove"] }, { kind: "component", type: SdQueryPopoverChip, selector: "sd-query-popover-chip", inputs: ["field", "filter", "active", "showOperator", "valueText", "menu"], outputs: ["open", "remove"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1398
1352
|
}
|
|
1399
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1353
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: SdQueryBar, decorators: [{
|
|
1400
1354
|
type: Component,
|
|
1401
1355
|
args: [{ selector: 'sd-query-bar', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
1402
1356
|
CommonModule,
|
|
@@ -1411,7 +1365,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
1411
1365
|
SdQueryInlineChip,
|
|
1412
1366
|
SdQueryInlineValueChip,
|
|
1413
1367
|
SdQueryPopoverChip,
|
|
1414
|
-
], template: "<!--\n sd-query-bar \u2014 unified filter chip row (Jira/Linear/Notion style).\n Visual spec: refs/design_handoff_sd_query_bar/README.md\n TODO(next-iter): replace inline placeholders for field-picker + chip-popover\n with extracted sub-components driven by CDK overlay.\n-->\n@let _filters = filters();\n@let _fields = fields();\n@let _density = density();\n@let _showOr = showOrConnector();\n@let _used = usedFieldKeys();\n\n<div\n class=\"c-query-bar\"\n [class.c-density-compact]=\"_density === 'compact'\"\n [class.c-density-comfortable]=\"_density === 'comfortable'\">\n\n <!-- Main region \u2014 search + filters + add-filter. Wraps internally; the right\n action toolbar stays anchored and does NOT flow with this. -->\n <div class=\"c-query-bar__main\">\n\n <!-- Free-text search (left, optional) -->\n @if (showSearch()) {\n <div class=\"c-search\">\n <mat-icon class=\"c-search-icon\" fontSet=\"material-icons-outlined\">search</mat-icon>\n <input\n class=\"c-search-input\"\n type=\"text\"\n [ngModel]=\"search()\"\n (ngModelChange)=\"setSearch($event)\"\n (keydown.enter)=\"triggerApply()\"\n placeholder=\"T\u00ECm ki\u1EBFm...\" />\n </div>\n <span class=\"c-divider\" aria-hidden=\"true\"></span>\n }\n\n <!-- Field switcher (used by chipPopover header) \u2014 declared first so chipPopover's\n nested ng-template can resolve the template ref. -->\n <!-- Field switcher used by chipPopover header \u2014 current field key comes from editingIndex. -->\n <sd-query-field-picker\n #switchPicker\n [fields]=\"_fields\"\n [currentKey]=\"editingIndex() !== null ? $any(filters()[editingIndex()!])?.field : undefined\"\n (pick)=\"editingIndex() !== null && changeFilterField(editingIndex()!, $event)\" />\n\n <!-- Chip popover \u2014 extracted into <sd-query-chip-popover>. Declared BEFORE chips\n so the popover-mode @for chips can bind their [menu] to `chipPopover.menu()`. -->\n <sd-query-chip-popover\n #chipPopover\n [field]=\"editingField() ?? undefined\"\n [filter]=\"editingIndex() !== null ? $any(filters()[editingIndex()!]) : undefined\"\n [chipIndex]=\"editingIndex()\"\n [autoIdBase]=\"autoIdInput() ?? 'qb'\"\n [switchPickerMenu]=\"switchPicker.menu()!\"\n (commit)=\"onChipPopoverCommit($event)\"\n (swapField)=\"editingIndex() !== null && changeFilterField(editingIndex()!, $event)\" />\n\n @if (mode() === 'inline') {\n <!-- ===== INLINE MODE (GitLab-style token builder) ===== -->\n\n <!-- Completed chips -->\n @for (filter of _filters; track $index; let i = $index) {\n @if (_showOr && i > 0) {\n <span class=\"c-or-connector\" aria-hidden=\"true\">OR</span>\n }\n @let _field = fieldByKey()[$any(filter).field];\n @if (_field) {\n @let _op = $any(filter.operator);\n @let _data = $any(filter).data;\n @if (_field.type === 'string' || _field.type === 'number') {\n <!-- Seamless chip \u2014 the pill is the input (string / number). -->\n <sd-query-inline-value-chip\n [field]=\"_field\"\n [operator]=\"_op\"\n [value]=\"_data\"\n [density]=\"_density\"\n [showOperator]=\"showOperatorOnChip()\"\n [autoId]=\"inlineAutoId(i, 'value')\"\n (valueChange)=\"updateFilter(i, { data: $event })\"\n (remove)=\"removeFilter(i)\" />\n } @else {\n <sd-query-inline-chip\n [field]=\"_field\"\n [filter]=\"filter\"\n [density]=\"_density\"\n [multiple]=\"multiple(_op)\"\n [showOperator]=\"showOperatorOnChip()\"\n [autoId]=\"inlineAutoId(i, 'value')\"\n [valueText]=\"chipValueText(filter)\"\n [isNoData]=\"isNoDataOperator(_op)\"\n (commit)=\"updateFilter(i, { data: $event })\"\n (commitRange)=\"setFilterRange(i, $event)\"\n (liveChange)=\"updateFilter(i, { data: $event })\"\n (remove)=\"removeFilter(i)\" />\n }\n }\n }\n\n <!-- Building chip (in-progress) \u2014 extracted into <sd-query-build-chip>. -->\n @if (building(); as _b) {\n <sd-query-build-chip\n [building]=\"_b\"\n [density]=\"_density\"\n [allowedOperators]=\"allowedOperatorsFor(_b.field)\"\n [multiple]=\"multiple($any(_b.operator))\"\n [showOperator]=\"showOperatorOnChip()\"\n (pickOperator)=\"pickBuildOperator($any($event))\"\n (commitValue)=\"commitBuildValue($event)\"\n (cancel)=\"cancelBuild()\"\n (seamlessCommit)=\"onBuildSeamlessCommit($event)\" />\n }\n\n <!-- Add filter -->\n <button\n type=\"button\"\n class=\"c-add-filter\"\n [matMenuTriggerFor]=\"addPicker.menu()\"\n [disabled]=\"_fields.length === 0 || _used.size >= _fields.length\"\n [matTooltip]=\"_fields.length === 0 ? 'Ch\u01B0a c\u1EA5u h\u00ECnh fields' : 'Th\u00EAm filter'\">\n <mat-icon fontSet=\"material-icons-outlined\">add</mat-icon>\n </button>\n } @else {\n <!-- ===== POPOVER MODE (default) \u2014 compact chips edited via mat-menu ===== -->\n @for (filter of _filters; track $index; let i = $index) {\n @if (_showOr && i > 0) {\n <span class=\"c-or-connector\" aria-hidden=\"true\">OR</span>\n }\n @let _field = fieldByKey()[$any(filter).field];\n @let _active = isFilterActive(filter);\n <!-- why: menu close commit is handled by chipPopover's (commit) \u2192\n onChipPopoverCommit; popover-chip only signals open + remove here. -->\n <sd-query-popover-chip\n [field]=\"_field\"\n [filter]=\"filter\"\n [active]=\"_active\"\n [showOperator]=\"showOperatorOnChip()\"\n [valueText]=\"chipValueText(filter)\"\n [menu]=\"chipPopover.menu()!\"\n (open)=\"openChipPopover(i)\"\n (remove)=\"removeFilter(i)\" />\n }\n\n <!-- Add filter trigger -->\n <button\n type=\"button\"\n class=\"c-add-filter\"\n [matMenuTriggerFor]=\"addPicker.menu()\"\n [disabled]=\"_fields.length === 0 || _used.size >= _fields.length\"\n [matTooltip]=\"_fields.length === 0 ? 'Ch\u01B0a c\u1EA5u h\u00ECnh fields' : 'Th\u00EAm filter'\">\n <mat-icon fontSet=\"material-icons-outlined\">add</mat-icon>\n </button>\n }\n\n </div><!-- /.c-query-bar__main -->\n\n <!-- Field picker \u2014 list available fields, fade ones already in use. -->\n <sd-query-field-picker\n #addPicker\n [fields]=\"_fields\"\n [usedKeys]=\"_used\"\n (pick)=\"mode() === 'inline' ? beginBuild($event) : addFilter($event)\" />\n\n <sd-query-actions-bar\n [showLogicToggle]=\"showLogicToggle()\"\n [(logic)]=\"logic\"\n [filtersCount]=\"_filters.length\"\n [showSavedFilters]=\"showSavedFilters()\"\n [savedFiltersKey]=\"savedFiltersKey()\"\n [query]=\"currentQuery()\"\n (applyFilter)=\"onApplyFilter($event)\"\n [showClearAll]=\"showClearAll()\"\n [canSearch]=\"canSearch()\"\n (clear)=\"clearAll()\"\n (search)=\"triggerApply()\" />\n</div>\n", styles: [":host{display:block;font-family:Roboto,system-ui,sans-serif}.c-query-bar{display:flex;align-items:flex-start;flex-wrap:nowrap;gap:8px;background:#fff;border:1px solid #e2e4e7;border-radius:8px;box-shadow:0 1px 2px #0f172a0a}.c-query-bar.c-density-compact{padding:8px}.c-query-bar.c-density-comfortable{padding:10px}.c-query-bar__main{flex:1 1 auto;min-width:0;display:flex;align-items:center;flex-wrap:wrap;gap:6px}.c-search{display:flex;align-items:center;gap:6px;min-width:220px;padding:0 10px;border:1px solid #d6d8db;border-radius:6px;background:#fff}.c-density-compact .c-search{height:28px}.c-density-comfortable .c-search{height:32px}.c-search .c-search-icon{font-size:16px;width:16px;height:16px;color:#7a7a7a}.c-search .c-search-input{flex:1;border:none;outline:none;background:transparent;font-size:13px;color:#212121}.c-search .c-search-input::placeholder{color:#7a7a7a}.c-search .c-search-kbd{font-family:Roboto Mono,monospace;font-size:10px;padding:1px 4px;border:1px solid #e2e4e7;border-radius:3px;color:#7a7a7a}.c-divider{width:1px;height:16px;background:#e2e4e7;margin:0 2px}.c-token{display:inline-flex;align-items:center;gap:4px;padding:0 0 0 12px;border:1px solid var(--sd-primary-light);border-radius:999px;background:var(--sd-primary-light);font-size:13px;color:#5f6368;white-space:nowrap;overflow:hidden}.c-density-compact .c-token{height:28px}.c-density-comfortable .c-token{height:32px}.c-token-icon{font-size:14px;width:14px;height:14px;line-height:14px;color:inherit}.c-token-field{font-weight:500;line-height:1}.c-token-op{display:inline-flex;align-items:center;color:inherit}.c-token-op ::ng-deep .c-op-trigger{padding:0;color:inherit}.c-token-op ::ng-deep .c-op-icon svg{width:14px;height:14px;display:block}.c-token-value-edit sd-select,.c-token-value-edit sd-date,.c-token-value-edit sd-datetime{display:inline-flex;align-items:center;line-height:1}.c-token ::ng-deep .mat-mdc-form-field{line-height:1}.c-token ::ng-deep .mat-mdc-text-field-wrapper,.c-token ::ng-deep .mat-mdc-form-field-flex{padding:0;min-height:0;background:transparent}.c-token ::ng-deep .mat-mdc-form-field-infix{padding:0;min-height:0;width:auto;border:0;display:inline-flex;align-items:center}.c-token ::ng-deep .mat-mdc-select-value,.c-token ::ng-deep .mat-mdc-input-element,.c-token ::ng-deep input{line-height:1;font-size:13px;padding:0;height:auto;color:inherit}.c-token ::ng-deep .mat-mdc-select-value{display:inline-flex;align-items:center;min-width:0;max-width:200px;overflow:hidden;text-overflow:ellipsis;color:var(--sd-primary);font-weight:500}.c-token ::ng-deep .sd-suffix-icon{display:none}.c-token-sep{color:#7a7a7a}.c-token-dash{color:#7a7a7a;padding:0 4px;line-height:1}.c-token-value{border:none;background:transparent;padding:0;font:inherit;font-weight:500;color:var(--sd-primary);cursor:pointer}.c-token-value:hover{text-decoration:underline}.c-token-value-edit{display:inline-flex;align-items:center;gap:4px;max-width:240px}.c-token-value-edit sd-input,.c-token-value-edit sd-input-number{display:inline-flex;max-width:140px}.c-token-value-edit sd-date-range{display:inline-flex;max-width:220px;min-width:0;flex:0 1 auto}.c-token-multi-head{display:inline-block;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}.c-token-remove{align-self:stretch;display:inline-flex;align-items:center;justify-content:center;border:none;border-left:1px solid rgba(0,0,0,.04);border-radius:0;background:transparent;cursor:pointer;color:inherit}.c-density-compact .c-token-remove{width:26px}.c-density-comfortable .c-token-remove{width:28px}.c-token-remove mat-icon{font-size:14px;width:14px;height:14px}.c-token-remove:hover{background:#0000000d}.c-add-filter{display:inline-flex;align-items:center;justify-content:center;padding:0;border-radius:999px;border:1px dashed #d6d8db;background:transparent;cursor:pointer;color:#5f6368;transition:border-color .12s ease,color .12s ease,background-color .12s ease}.c-density-compact .c-add-filter{width:28px;height:28px}.c-density-comfortable .c-add-filter{width:32px;height:32px}.c-add-filter mat-icon{font-size:18px;width:18px;height:18px}.c-add-filter:hover:not([disabled]){border-color:var(--sd-primary);color:var(--sd-primary)}.c-add-filter[disabled]{opacity:.5;cursor:not-allowed}.c-or-connector{font-family:Roboto Mono,monospace;font-size:10px;font-weight:700;letter-spacing:.6px;color:#7a7a7a;padding:0 2px}::ng-deep .mat-mdc-menu-panel.c-chip-popover{min-width:280px;max-width:320px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid #e2e4e7;font-size:13px;font-weight:500;color:#212121}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header mat-icon{font-size:16px;width:16px;height:16px;color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header .c-pop-header-operator{margin-left:auto}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field{display:inline-flex;align-items:center;gap:4px;padding:2px 4px 2px 6px;margin-left:-4px;background:transparent;border:1px solid transparent;border-radius:4px;font:inherit;font-weight:500;color:#212121;cursor:pointer;transition:background-color .12s ease,border-color .12s ease}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#7a7a7a!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field:hover{background:#f5f6f7;border-color:#e2e4e7}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-body{padding:10px 12px;display:flex;flex-direction:column;gap:12px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-input{width:100%;height:32px;padding:0 10px;border:1px solid #d6d8db;border-radius:6px;background:#fff;font-family:inherit;font-size:13px;color:#212121;outline:none}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-input:focus{border-color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-between{display:grid;grid-template-columns:1fr 1fr;gap:8px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-boolean{display:flex;gap:8px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-boolean button{flex:1;height:32px;border:1px solid #d6d8db;border-radius:6px;background:#fff;font:inherit;font-size:13px;cursor:pointer}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-boolean button.c-pop-boolean-active{background:var(--sd-primary-light);border-color:var(--sd-primary);color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values{max-height:220px;overflow-y:auto;margin:0;padding:0;list-style:none}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:4px;font-size:13px;cursor:pointer;-webkit-user-select:none;user-select:none}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li:hover{background:#f5f6f7}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li.c-pop-value-selected{background:var(--sd-primary-light);color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li input[type=checkbox],::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li input[type=radio]{accent-color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values-loading,::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values-empty{padding:10px 8px;font-size:12px;color:#7a7a7a}.c-bool-toggle{display:inline-flex;align-items:center;gap:4px}.c-bool-toggle ::ng-deep .mdc-button,.c-bool-toggle ::ng-deep button[mat-button],.c-bool-toggle ::ng-deep button[mat-stroked-button],.c-bool-toggle ::ng-deep button[mat-flat-button]{border-radius:999px;min-width:0;padding:0 12px}\n", ".c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__leading,.c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__notch,.c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__trailing{border-color:#d6d8db!important;transition:border-color .12s ease}.c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__leading{border-radius:6px 0 0 6px!important}.c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__trailing{border-radius:0 6px 6px 0!important}.c-query-bar ::ng-deep .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__leading,.c-query-bar ::ng-deep .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__notch,.c-query-bar ::ng-deep .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__trailing{border-color:#b9bdc3!important}.c-query-bar ::ng-deep .mat-mdc-form-field.mat-focused .mdc-notched-outline__leading,.c-query-bar ::ng-deep .mat-mdc-form-field.mat-focused .mdc-notched-outline__notch,.c-query-bar ::ng-deep .mat-mdc-form-field.mat-focused .mdc-notched-outline__trailing{border-color:var(--sd-primary)!important;border-width:1px!important}.c-query-bar ::ng-deep .mat-mdc-form-field .mat-mdc-select-arrow,.c-query-bar ::ng-deep .mat-mdc-form-field .mat-mdc-form-field-icon-suffix .mat-icon{color:#5f6368}.c-query-bar ::ng-deep .mat-mdc-form-field.mat-focused .mat-mdc-select-arrow{color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__trailing,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__trailing{border-color:#d6d8db!important;transition:border-color .12s ease}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__leading{border-radius:6px 0 0 6px!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__trailing,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__trailing{border-radius:0 6px 6px 0!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__trailing,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__trailing{border-color:#b9bdc3!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field.mat-focused .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field.mat-focused .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field.mat-focused .mdc-notched-outline__trailing,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field.mat-focused .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field.mat-focused .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field.mat-focused .mdc-notched-outline__trailing{border-color:var(--sd-primary)!important;border-width:1px!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mat-mdc-select-arrow,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mat-mdc-form-field-icon-suffix .mat-icon,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mat-mdc-select-arrow,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mat-mdc-form-field-icon-suffix .mat-icon{color:#5f6368}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field.mat-focused .mat-mdc-select-arrow,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field.mat-focused .mat-mdc-select-arrow{color:var(--sd-primary)}\n"] }]
|
|
1368
|
+
], template: "<!--\n sd-query-bar \u2014 unified filter chip row (Jira/Linear/Notion style).\n Visual spec: refs/design_handoff_sd_query_bar/README.md\n TODO(next-iter): replace inline placeholders for field-picker + chip-popover\n with extracted sub-components driven by CDK overlay.\n-->\n@let _filters = filters();\n@let _fields = fields();\n@let _density = density();\n@let _showOr = showOrConnector();\n@let _used = usedFieldKeys();\n@let _editingIndex = editingIndex();\n@let _mode = mode();\n@let _showOpOnChip = showOperatorOnChip();\n\n<div\n class=\"c-query-bar\"\n [class.c-density-compact]=\"_density === 'compact'\"\n [class.c-density-comfortable]=\"_density === 'comfortable'\">\n\n <!-- Main region \u2014 search + filters + add-filter. Wraps internally; the right\n action toolbar stays anchored and does NOT flow with this. -->\n <div class=\"c-query-bar__main\">\n\n <!-- Free-text search (left, optional) -->\n @if (showSearch()) {\n <div class=\"c-search\">\n <mat-icon class=\"c-search-icon\" fontSet=\"material-icons-outlined\">search</mat-icon>\n <input\n class=\"c-search-input\"\n type=\"text\"\n [ngModel]=\"search()\"\n (ngModelChange)=\"setSearch($event)\"\n (keydown.enter)=\"triggerApply()\"\n placeholder=\"T\u00ECm ki\u1EBFm...\" />\n </div>\n <span class=\"c-divider\" aria-hidden=\"true\"></span>\n }\n\n <!-- Field switcher (used by chipPopover header) \u2014 declared first so chipPopover's\n nested ng-template can resolve the template ref. -->\n <!-- Field switcher used by chipPopover header \u2014 current field key comes from editingIndex. -->\n <sd-query-field-picker\n #switchPicker\n [fields]=\"_fields\"\n [currentKey]=\"_editingIndex !== null ? $any(_filters[_editingIndex!])?.field : undefined\"\n (pick)=\"_editingIndex !== null && changeFilterField(_editingIndex!, $event)\" />\n\n <!-- Chip popover \u2014 extracted into <sd-query-chip-popover>. Declared BEFORE chips\n so the popover-mode @for chips can bind their [menu] to `chipPopover.menu()`. -->\n <sd-query-chip-popover\n #chipPopover\n [field]=\"editingField() ?? undefined\"\n [filter]=\"_editingIndex !== null ? $any(_filters[_editingIndex!]) : undefined\"\n [chipIndex]=\"_editingIndex\"\n [autoIdBase]=\"autoIdInput() ?? 'qb'\"\n [switchPickerMenu]=\"switchPicker.menu()!\"\n (commit)=\"onChipPopoverCommit($event)\"\n (swapField)=\"_editingIndex !== null && changeFilterField(_editingIndex!, $event)\" />\n\n @if (_mode === 'inline') {\n <!-- ===== INLINE MODE (GitLab-style token builder) ===== -->\n\n <!-- Completed chips -->\n @for (filter of _filters; track $index; let i = $index) {\n @if (_showOr && i > 0) {\n <span class=\"c-or-connector\" aria-hidden=\"true\">OR</span>\n }\n @let _field = fieldByKey()[$any(filter).field];\n @if (_field) {\n @let _op = $any(filter.operator);\n @let _data = $any(filter).data;\n @if (_field.type === 'string' || _field.type === 'number') {\n <!-- Seamless chip \u2014 the pill is the input (string / number). -->\n <sd-query-inline-value-chip\n [field]=\"_field\"\n [operator]=\"_op\"\n [value]=\"_data\"\n [density]=\"_density\"\n [showOperator]=\"_showOpOnChip\"\n [autoId]=\"inlineAutoId(i, 'value')\"\n (valueChange)=\"updateFilter(i, { data: $event })\"\n (remove)=\"removeFilter(i)\" />\n } @else {\n <sd-query-inline-chip\n [field]=\"_field\"\n [filter]=\"filter\"\n [density]=\"_density\"\n [multiple]=\"multiple(_op)\"\n [showOperator]=\"_showOpOnChip\"\n [autoId]=\"inlineAutoId(i, 'value')\"\n [valueText]=\"chipValueText(filter)\"\n [isNoData]=\"isNoDataOperator(_op)\"\n (commit)=\"updateFilter(i, { data: $event })\"\n (commitRange)=\"setFilterRange(i, $event)\"\n (liveChange)=\"updateFilter(i, { data: $event })\"\n (remove)=\"removeFilter(i)\" />\n }\n }\n }\n\n <!-- Building chip (in-progress) \u2014 extracted into <sd-query-build-chip>. -->\n @if (building(); as _b) {\n <sd-query-build-chip\n [building]=\"_b\"\n [density]=\"_density\"\n [allowedOperators]=\"allowedOperatorsFor(_b.field)\"\n [multiple]=\"multiple($any(_b.operator))\"\n [showOperator]=\"_showOpOnChip\"\n (pickOperator)=\"pickBuildOperator($any($event))\"\n (commitValue)=\"commitBuildValue($event)\"\n (cancel)=\"cancelBuild()\"\n (seamlessCommit)=\"onBuildSeamlessCommit($event)\" />\n }\n\n <!-- Add filter -->\n <button\n type=\"button\"\n class=\"c-add-filter\"\n [matMenuTriggerFor]=\"addPicker.menu()\"\n [disabled]=\"_fields.length === 0 || _used.size >= _fields.length\"\n [matTooltip]=\"_fields.length === 0 ? 'Ch\u01B0a c\u1EA5u h\u00ECnh fields' : 'Th\u00EAm filter'\">\n <mat-icon fontSet=\"material-icons-outlined\">add</mat-icon>\n </button>\n } @else {\n <!-- ===== POPOVER MODE (default) \u2014 compact chips edited via mat-menu ===== -->\n @for (filter of _filters; track $index; let i = $index) {\n @if (_showOr && i > 0) {\n <span class=\"c-or-connector\" aria-hidden=\"true\">OR</span>\n }\n @let _field = fieldByKey()[$any(filter).field];\n @let _active = isFilterActive(filter);\n <!-- why: menu close commit is handled by chipPopover's (commit) \u2192\n onChipPopoverCommit; popover-chip only signals open + remove here. -->\n <sd-query-popover-chip\n [field]=\"_field\"\n [filter]=\"filter\"\n [active]=\"_active\"\n [showOperator]=\"_showOpOnChip\"\n [valueText]=\"chipValueText(filter)\"\n [menu]=\"chipPopover.menu()!\"\n (open)=\"openChipPopover(i)\"\n (remove)=\"removeFilter(i)\" />\n }\n\n <!-- Add filter trigger -->\n <button\n type=\"button\"\n class=\"c-add-filter\"\n [matMenuTriggerFor]=\"addPicker.menu()\"\n [disabled]=\"_fields.length === 0 || _used.size >= _fields.length\"\n [matTooltip]=\"_fields.length === 0 ? 'Ch\u01B0a c\u1EA5u h\u00ECnh fields' : 'Th\u00EAm filter'\">\n <mat-icon fontSet=\"material-icons-outlined\">add</mat-icon>\n </button>\n }\n\n </div><!-- /.c-query-bar__main -->\n\n <!-- Field picker \u2014 list available fields, fade ones already in use. -->\n <sd-query-field-picker\n #addPicker\n [fields]=\"_fields\"\n [usedKeys]=\"_used\"\n (pick)=\"_mode === 'inline' ? beginBuild($event) : addFilter($event)\" />\n\n <sd-query-actions-bar\n [showLogicToggle]=\"showLogicToggle()\"\n [(logic)]=\"logic\"\n [filtersCount]=\"_filters.length\"\n [showSavedFilters]=\"showSavedFilters()\"\n [savedFiltersKey]=\"savedFiltersKey()\"\n [query]=\"currentQuery()\"\n (applyFilter)=\"onApplyFilter($event)\"\n [showClearAll]=\"showClearAll()\"\n [canSearch]=\"canSearch()\"\n (clear)=\"clearAll()\"\n (search)=\"triggerApply()\" />\n</div>\n", styles: [":host{display:block;font-family:Roboto,system-ui,sans-serif}.c-query-bar{display:flex;align-items:flex-start;flex-wrap:nowrap;gap:8px;background:#fff;border:1px solid #e2e4e7;border-radius:8px;box-shadow:0 1px 2px #0f172a0a}.c-query-bar.c-density-compact{padding:8px}.c-query-bar.c-density-comfortable{padding:10px}.c-query-bar__main{flex:1 1 auto;min-width:0;display:flex;align-items:center;flex-wrap:wrap;gap:6px}.c-search{display:flex;align-items:center;gap:6px;min-width:220px;padding:0 10px;border:1px solid #d6d8db;border-radius:6px;background:#fff}.c-density-compact .c-search{height:28px}.c-density-comfortable .c-search{height:32px}.c-search .c-search-icon{font-size:16px;width:16px;height:16px;color:#7a7a7a}.c-search .c-search-input{flex:1;border:none;outline:none;background:transparent;font-size:13px;color:#212121}.c-search .c-search-input::placeholder{color:#7a7a7a}.c-search .c-search-kbd{font-family:Roboto Mono,monospace;font-size:10px;padding:1px 4px;border:1px solid #e2e4e7;border-radius:3px;color:#7a7a7a}.c-divider{width:1px;height:16px;background:#e2e4e7;margin:0 2px}.c-token{display:inline-flex;align-items:center;gap:4px;padding:0 0 0 12px;border:1px solid var(--sd-primary-light);border-radius:999px;background:var(--sd-primary-light);font-size:13px;color:#5f6368;white-space:nowrap;overflow:hidden}.c-density-compact .c-token{height:28px}.c-density-comfortable .c-token{height:32px}.c-token-icon{font-size:14px;width:14px;height:14px;line-height:14px;color:inherit}.c-token-field{font-weight:500;line-height:1}.c-token-op{display:inline-flex;align-items:center;color:inherit}.c-token-op ::ng-deep .c-op-trigger{padding:0;color:inherit}.c-token-op ::ng-deep .c-op-icon svg{width:14px;height:14px;display:block}.c-token-value-edit sd-select,.c-token-value-edit sd-date,.c-token-value-edit sd-datetime{display:inline-flex;align-items:center;line-height:1}.c-token ::ng-deep .mat-mdc-form-field{line-height:1}.c-token ::ng-deep .mat-mdc-text-field-wrapper,.c-token ::ng-deep .mat-mdc-form-field-flex{padding:0;min-height:0;background:transparent}.c-token ::ng-deep .mat-mdc-form-field-infix{padding:0;min-height:0;width:auto;border:0;display:inline-flex;align-items:center}.c-token ::ng-deep .mat-mdc-select-value,.c-token ::ng-deep .mat-mdc-input-element,.c-token ::ng-deep input{line-height:1;font-size:13px;padding:0;height:auto;color:inherit}.c-token ::ng-deep .mat-mdc-select-value{display:inline-flex;align-items:center;min-width:0;max-width:200px;overflow:hidden;text-overflow:ellipsis;color:var(--sd-primary);font-weight:500}.c-token ::ng-deep .sd-suffix-icon{display:none}.c-token-sep{color:#7a7a7a}.c-token-dash{color:#7a7a7a;padding:0 4px;line-height:1}.c-token-value{border:none;background:transparent;padding:0;font:inherit;font-weight:500;color:var(--sd-primary);cursor:pointer}.c-token-value:hover{text-decoration:underline}.c-token-value-edit{display:inline-flex;align-items:center;gap:4px;max-width:240px}.c-token-value-edit sd-input,.c-token-value-edit sd-input-number{display:inline-flex;max-width:140px}.c-token-value-edit sd-date-range{display:inline-flex;max-width:220px;min-width:0;flex:0 1 auto}.c-token-multi-head{display:inline-block;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}.c-token-remove{align-self:stretch;display:inline-flex;align-items:center;justify-content:center;border:none;border-left:1px solid rgba(0,0,0,.04);border-radius:0;background:transparent;cursor:pointer;color:inherit}.c-density-compact .c-token-remove{width:26px}.c-density-comfortable .c-token-remove{width:28px}.c-token-remove mat-icon{font-size:14px;width:14px;height:14px}.c-token-remove:hover{background:#0000000d}.c-add-filter{display:inline-flex;align-items:center;justify-content:center;padding:0;border-radius:999px;border:1px dashed #d6d8db;background:transparent;cursor:pointer;color:#5f6368;transition:border-color .12s ease,color .12s ease,background-color .12s ease}.c-density-compact .c-add-filter{width:28px;height:28px}.c-density-comfortable .c-add-filter{width:32px;height:32px}.c-add-filter mat-icon{font-size:18px;width:18px;height:18px}.c-add-filter:hover:not([disabled]){border-color:var(--sd-primary);color:var(--sd-primary)}.c-add-filter[disabled]{opacity:.5;cursor:not-allowed}.c-or-connector{font-family:Roboto Mono,monospace;font-size:10px;font-weight:700;letter-spacing:.6px;color:#7a7a7a;padding:0 2px}::ng-deep .mat-mdc-menu-panel.c-chip-popover{min-width:280px;max-width:320px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid #e2e4e7;font-size:13px;font-weight:500;color:#212121}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header mat-icon{font-size:16px;width:16px;height:16px;color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header .c-pop-header-operator{margin-left:auto}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field{display:inline-flex;align-items:center;gap:4px;padding:2px 4px 2px 6px;margin-left:-4px;background:transparent;border:1px solid transparent;border-radius:4px;font:inherit;font-weight:500;color:#212121;cursor:pointer;transition:background-color .12s ease,border-color .12s ease}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#7a7a7a!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-header-field:hover{background:#f5f6f7;border-color:#e2e4e7}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-body{padding:10px 12px;display:flex;flex-direction:column;gap:12px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-input{width:100%;height:32px;padding:0 10px;border:1px solid #d6d8db;border-radius:6px;background:#fff;font-family:inherit;font-size:13px;color:#212121;outline:none}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-input:focus{border-color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-between{display:grid;grid-template-columns:1fr 1fr;gap:8px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-boolean{display:flex;gap:8px}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-boolean button{flex:1;height:32px;border:1px solid #d6d8db;border-radius:6px;background:#fff;font:inherit;font-size:13px;cursor:pointer}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-boolean button.c-pop-boolean-active{background:var(--sd-primary-light);border-color:var(--sd-primary);color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values{max-height:220px;overflow-y:auto;margin:0;padding:0;list-style:none}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:4px;font-size:13px;cursor:pointer;-webkit-user-select:none;user-select:none}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li:hover{background:#f5f6f7}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li.c-pop-value-selected{background:var(--sd-primary-light);color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li input[type=checkbox],::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values li input[type=radio]{accent-color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values-loading,::ng-deep .mat-mdc-menu-panel.c-chip-popover .c-pop-values-empty{padding:10px 8px;font-size:12px;color:#7a7a7a}.c-bool-toggle{display:inline-flex;align-items:center;gap:4px}.c-bool-toggle ::ng-deep .mdc-button,.c-bool-toggle ::ng-deep button[mat-button],.c-bool-toggle ::ng-deep button[mat-stroked-button],.c-bool-toggle ::ng-deep button[mat-flat-button]{border-radius:999px;min-width:0;padding:0 12px}\n", ".c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__leading,.c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__notch,.c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__trailing{border-color:#d6d8db!important;transition:border-color .12s ease}.c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__leading{border-radius:6px 0 0 6px!important}.c-query-bar ::ng-deep .mat-mdc-form-field .mdc-notched-outline__trailing{border-radius:0 6px 6px 0!important}.c-query-bar ::ng-deep .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__leading,.c-query-bar ::ng-deep .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__notch,.c-query-bar ::ng-deep .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__trailing{border-color:#b9bdc3!important}.c-query-bar ::ng-deep .mat-mdc-form-field.mat-focused .mdc-notched-outline__leading,.c-query-bar ::ng-deep .mat-mdc-form-field.mat-focused .mdc-notched-outline__notch,.c-query-bar ::ng-deep .mat-mdc-form-field.mat-focused .mdc-notched-outline__trailing{border-color:var(--sd-primary)!important;border-width:1px!important}.c-query-bar ::ng-deep .mat-mdc-form-field .mat-mdc-select-arrow,.c-query-bar ::ng-deep .mat-mdc-form-field .mat-mdc-form-field-icon-suffix .mat-icon{color:#5f6368}.c-query-bar ::ng-deep .mat-mdc-form-field.mat-focused .mat-mdc-select-arrow{color:var(--sd-primary)}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__trailing,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__trailing{border-color:#d6d8db!important;transition:border-color .12s ease}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__leading{border-radius:6px 0 0 6px!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mdc-notched-outline__trailing,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mdc-notched-outline__trailing{border-radius:0 6px 6px 0!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__trailing,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field:hover:not(.mat-focused):not(.mat-form-field-disabled) .mdc-notched-outline__trailing{border-color:#b9bdc3!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field.mat-focused .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field.mat-focused .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field.mat-focused .mdc-notched-outline__trailing,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field.mat-focused .mdc-notched-outline__leading,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field.mat-focused .mdc-notched-outline__notch,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field.mat-focused .mdc-notched-outline__trailing{border-color:var(--sd-primary)!important;border-width:1px!important}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mat-mdc-select-arrow,::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field .mat-mdc-form-field-icon-suffix .mat-icon,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mat-mdc-select-arrow,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field .mat-mdc-form-field-icon-suffix .mat-icon{color:#5f6368}::ng-deep .mat-mdc-menu-panel.c-chip-popover .mat-mdc-form-field.mat-focused .mat-mdc-select-arrow,::ng-deep .mat-mdc-menu-panel.c-field-picker-menu .mat-mdc-form-field.mat-focused .mat-mdc-select-arrow{color:var(--sd-primary)}\n"] }]
|
|
1415
1369
|
}], propDecorators: { popoverChips: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => SdQueryPopoverChip), { isSignal: true }] }], buildChip: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SdQueryBuildChip), { isSignal: true }] }], chipPopover: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SdQueryChipPopover), { isSignal: true }] }], autoIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], fields: [{ type: i0.Input, args: [{ isSignal: true, alias: "fields", required: false }] }], filters: [{ type: i0.Input, args: [{ isSignal: true, alias: "filters", required: false }] }, { type: i0.Output, args: ["filtersChange"] }], logic: [{ type: i0.Input, args: [{ isSignal: true, alias: "logic", required: false }] }, { type: i0.Output, args: ["logicChange"] }], search: [{ type: i0.Input, args: [{ isSignal: true, alias: "search", required: false }] }, { type: i0.Output, args: ["searchChange"] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], showSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSearch", required: false }] }], showSavedFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSavedFilters", required: false }] }], savedFiltersKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "savedFiltersKey", required: false }] }], showLogicToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLogicToggle", required: false }] }], showClearAll: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClearAll", required: false }] }], showOperatorOnChip: [{ type: i0.Input, args: [{ isSignal: true, alias: "showOperatorOnChip", required: false }] }], queryChange: [{ type: i0.Output, args: ["queryChange"] }], apply: [{ type: i0.Output, args: ["apply"] }] } });
|
|
1416
1370
|
|
|
1417
1371
|
/**
|