@sdcorejs/angular 20.0.4 → 20.0.5
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/assets/{scss/README.md → STYLE-GUIDE.md} +3 -0
- package/components/index.d.ts +2 -0
- package/components/org-chart/index.d.ts +67 -0
- package/components/query-bar/index.d.ts +37 -2
- package/components/query-builder/index.d.ts +96 -30
- package/components/section/index.d.ts +4 -1
- package/components/splitter/index.d.ts +20 -1
- package/components/table/index.d.ts +2 -0
- package/components/tree/index.d.ts +253 -0
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs +2 -2
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-org-chart.mjs +110 -0
- package/fesm2022/sdcorejs-angular-components-org-chart.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs +37 -8
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs +258 -60
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-section.mjs +8 -5
- package/fesm2022/sdcorejs-angular-components-section.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-splitter.mjs +24 -13
- package/fesm2022/sdcorejs-angular-components-splitter.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-table.mjs +6 -2
- package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tree.mjs +526 -0
- package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-components.mjs +2 -0
- package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +2 -2
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-select.mjs +34 -4
- package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
- package/forms/select/index.d.ts +9 -1
- package/package.json +9 -1
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
|
|
47
47
|
```
|
|
48
48
|
projects/sdcorejs-angular/assets/
|
|
49
|
+
├── STYLE-GUIDE.md # Tài liệu này (assets + SCSS reference cho người + AI agent)
|
|
49
50
|
├── fonts/
|
|
50
51
|
│ ├── fonts.scss # @font-face khai báo cho Roboto + Material Icons + Material Symbols
|
|
51
52
|
│ ├── material-icons/ # 2 file .woff2 (icons-v145 + outlined-v110)
|
|
@@ -321,6 +322,8 @@ p-{n} pt-{n} pr-{n} pb-{n} pl-{n} px-{n} py-{n}
|
|
|
321
322
|
|
|
322
323
|
Ví dụ: `m-0`, `mt-8`, `px-16`, `py-24`, `mb-4`.
|
|
323
324
|
|
|
325
|
+
**Spacing scale rule:** với spacing dùng cho layout element, chỉ dùng giá trị là **bội số của 4px**: `m-4`, `m-8`, `m-12`, `m-16`, `p-4`, `p-8`, `px-16`, `py-24`, `gap-8`, `gap-16`... Tránh sinh các class lẻ như `m-3`, `p-5`, `gap-7` trừ khi đang xử lý pixel-perfect exception đã được review rõ ràng.
|
|
326
|
+
|
|
324
327
|
**Auto margin:** `m-auto`, `mt-auto`, `mr-auto`, `mb-auto`, `ml-auto`, `mx-auto`, `my-auto`.
|
|
325
328
|
|
|
326
329
|
### 7.2 Gap (px-based, 0–200)
|
package/components/index.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export * from '@sdcorejs/angular/components/upload-file';
|
|
|
12
12
|
export * from '@sdcorejs/angular/components/section';
|
|
13
13
|
export * from '@sdcorejs/angular/components/anchor';
|
|
14
14
|
export * from '@sdcorejs/angular/components/query-builder';
|
|
15
|
+
export * from '@sdcorejs/angular/components/org-chart';
|
|
16
|
+
export * from '@sdcorejs/angular/components/tree';
|
|
15
17
|
export * from '@sdcorejs/angular/components/import-excel';
|
|
16
18
|
export * from '@sdcorejs/angular/components/document-builder';
|
|
17
19
|
export * from '@sdcorejs/angular/components/mini-editor';
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { TemplateRef } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
interface SdOrgChartItem {
|
|
5
|
+
id: string | number;
|
|
6
|
+
image?: string | null;
|
|
7
|
+
title: string;
|
|
8
|
+
description?: string | null;
|
|
9
|
+
color?: string | null;
|
|
10
|
+
expanded?: boolean;
|
|
11
|
+
children?: SdOrgChartItem[];
|
|
12
|
+
}
|
|
13
|
+
interface SdOrgChartItemContext<T extends SdOrgChartItem = SdOrgChartItem> {
|
|
14
|
+
$implicit: T;
|
|
15
|
+
item: T;
|
|
16
|
+
depth: number;
|
|
17
|
+
parent: T | null;
|
|
18
|
+
expanded: boolean;
|
|
19
|
+
hasChildren: boolean;
|
|
20
|
+
isLeaf: boolean;
|
|
21
|
+
toggle: () => void;
|
|
22
|
+
}
|
|
23
|
+
type SdOrgChartItemTemplate<T extends SdOrgChartItem = SdOrgChartItem> = TemplateRef<SdOrgChartItemContext<T>>;
|
|
24
|
+
interface SdOrgChartToggleEvent<T extends SdOrgChartItem = SdOrgChartItem> {
|
|
25
|
+
item: T;
|
|
26
|
+
expanded: boolean;
|
|
27
|
+
}
|
|
28
|
+
interface SdOrgChartOption<T extends SdOrgChartItem = SdOrgChartItem> {
|
|
29
|
+
autoId?: string | null;
|
|
30
|
+
items: T[];
|
|
31
|
+
itemTemplate?: TemplateRef<SdOrgChartItemContext<T>> | null;
|
|
32
|
+
collapsible?: boolean;
|
|
33
|
+
onToggle?: (event: SdOrgChartToggleEvent<T>) => void;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
declare class SdOrgChartItemDefDirective<T extends SdOrgChartItem = SdOrgChartItem> {
|
|
37
|
+
static ngTemplateContextGuard<T extends SdOrgChartItem>(_dir: SdOrgChartItemDefDirective<T>, _ctx: unknown): _ctx is SdOrgChartItemContext<T>;
|
|
38
|
+
readonly templateRef: TemplateRef<SdOrgChartItemContext<T>>;
|
|
39
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdOrgChartItemDefDirective<any>, never>;
|
|
40
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SdOrgChartItemDefDirective<any>, "[sdOrgChartItemDef]", never, {}, {}, never, never, true, never>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
declare class SdOrgChart {
|
|
44
|
+
#private;
|
|
45
|
+
readonly autoIdInput: _angular_core.InputSignal<string | null | undefined>;
|
|
46
|
+
readonly option: _angular_core.InputSignal<SdOrgChartOption<SdOrgChartItem> | undefined>;
|
|
47
|
+
readonly autoId: _angular_core.Signal<string | undefined>;
|
|
48
|
+
readonly items: _angular_core.InputSignal<SdOrgChartItem[] | undefined>;
|
|
49
|
+
readonly itemTemplate: _angular_core.InputSignal<TemplateRef<SdOrgChartItemContext<SdOrgChartItem>> | null | undefined>;
|
|
50
|
+
readonly collapsible: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
51
|
+
readonly itemDef: _angular_core.Signal<SdOrgChartItemDefDirective<any> | undefined>;
|
|
52
|
+
readonly resolvedItems: _angular_core.Signal<SdOrgChartItem[]>;
|
|
53
|
+
readonly resolvedCollapsible: _angular_core.Signal<boolean>;
|
|
54
|
+
readonly resolvedItemTemplate: _angular_core.Signal<TemplateRef<SdOrgChartItemContext<SdOrgChartItem>> | undefined>;
|
|
55
|
+
readonly trackByItem: (_index: number, item: SdOrgChartItem) => string | number;
|
|
56
|
+
hasChildren: (item: SdOrgChartItem) => boolean;
|
|
57
|
+
childrenOf: (item: SdOrgChartItem) => SdOrgChartItem[];
|
|
58
|
+
isExpanded: (item: SdOrgChartItem) => boolean;
|
|
59
|
+
toggle: (item: SdOrgChartItem, event?: Event) => void;
|
|
60
|
+
createContext: (item: SdOrgChartItem, depth: number, parent: SdOrgChartItem | null) => SdOrgChartItemContext;
|
|
61
|
+
nodeAutoId: (item: SdOrgChartItem, part: "node" | "image" | "title" | "description" | "toggle") => string | undefined;
|
|
62
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdOrgChart, never>;
|
|
63
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdOrgChart, "sd-org-chart", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "option": { "alias": "option"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": false; "isSignal": true; }; "itemTemplate": { "alias": "itemTemplate"; "required": false; "isSignal": true; }; "collapsible": { "alias": "collapsible"; "required": false; "isSignal": true; }; }, {}, ["itemDef"], never, true, never>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { SdOrgChart, SdOrgChartItemDefDirective };
|
|
67
|
+
export type { SdOrgChartItem, SdOrgChartItemContext, SdOrgChartItemTemplate, SdOrgChartOption, SdOrgChartToggleEvent };
|
|
@@ -88,6 +88,28 @@ interface SdQuery<T = any> {
|
|
|
88
88
|
/** Free-text search box (only present when `showSearch=true`). */
|
|
89
89
|
search?: string;
|
|
90
90
|
}
|
|
91
|
+
interface SdQueryBarOption<T = any> {
|
|
92
|
+
/** Prefix for auto-generated `data-autoid` on inner controls. */
|
|
93
|
+
autoId?: string;
|
|
94
|
+
/** Available fields the user can filter by. */
|
|
95
|
+
fields: SdQueryField<T>[];
|
|
96
|
+
/** Initial active filter chips. */
|
|
97
|
+
filters?: Filter<T>[];
|
|
98
|
+
/** Initial global connector between filters. */
|
|
99
|
+
logic?: SdQueryLogic;
|
|
100
|
+
/** Initial free-text search string. */
|
|
101
|
+
search?: string;
|
|
102
|
+
mode?: 'popover' | 'inline';
|
|
103
|
+
density?: 'compact' | 'comfortable';
|
|
104
|
+
showSearch?: boolean;
|
|
105
|
+
showSavedFilters?: boolean;
|
|
106
|
+
savedFiltersKey?: string;
|
|
107
|
+
showLogicToggle?: boolean;
|
|
108
|
+
showClearAll?: boolean;
|
|
109
|
+
showOperatorOnChip?: boolean;
|
|
110
|
+
onQueryChange?: (query: SdQuery<T>) => void;
|
|
111
|
+
onApply?: (query: SdQuery<T>) => void;
|
|
112
|
+
}
|
|
91
113
|
/** Persisted bookmark of a query (filters + logic + search) — managed by `[savedFiltersKey]`. */
|
|
92
114
|
interface SdSavedFilter<T = any> {
|
|
93
115
|
id: string;
|
|
@@ -248,6 +270,8 @@ declare class SdQueryBar {
|
|
|
248
270
|
private readonly buildChip;
|
|
249
271
|
/** The extracted chip popover — owns operator+value staging + commit-on-close. */
|
|
250
272
|
readonly chipPopover: _angular_core.Signal<SdQueryChipPopover | undefined>;
|
|
273
|
+
/** Main option object. Prefer this API for new usage; individual inputs stay as a migration bridge. */
|
|
274
|
+
readonly option: _angular_core.InputSignal<SdQueryBarOption<any> | undefined>;
|
|
251
275
|
/** Prefix for auto-generated `data-autoid` on inner controls (chips, operator/value editors, buttons). */
|
|
252
276
|
readonly autoIdInput: _angular_core.InputSignalWithTransform<string | undefined, string | null | undefined>;
|
|
253
277
|
/** Available fields the user can filter by. Required for the field picker. */
|
|
@@ -302,6 +326,17 @@ declare class SdQueryBar {
|
|
|
302
326
|
/** Fires when the user presses "Áp dụng" inside a chip popover — host should reload data. */
|
|
303
327
|
readonly apply: _angular_core.OutputEmitterRef<SdQuery<any>>;
|
|
304
328
|
/** Map of `field.key` → `SdQueryField` for fast lookup from filters[]. */
|
|
329
|
+
readonly resolvedAutoId: _angular_core.Signal<string | undefined>;
|
|
330
|
+
readonly resolvedFields: _angular_core.Signal<SdQueryField[]>;
|
|
331
|
+
readonly resolvedMode: _angular_core.Signal<"popover" | "inline">;
|
|
332
|
+
readonly resolvedDensity: _angular_core.Signal<Density>;
|
|
333
|
+
readonly resolvedShowSearch: _angular_core.Signal<boolean>;
|
|
334
|
+
readonly resolvedShowSavedFilters: _angular_core.Signal<boolean>;
|
|
335
|
+
readonly resolvedSavedFiltersKey: _angular_core.Signal<string | undefined>;
|
|
336
|
+
readonly resolvedShowLogicToggle: _angular_core.Signal<boolean>;
|
|
337
|
+
readonly resolvedShowClearAll: _angular_core.Signal<boolean>;
|
|
338
|
+
readonly resolvedShowOperatorOnChip: _angular_core.Signal<boolean>;
|
|
339
|
+
constructor();
|
|
305
340
|
readonly fieldByKey: _angular_core.Signal<Record<string, SdQueryField>>;
|
|
306
341
|
/** Field keys already chained on a chip — the picker greys these out. */
|
|
307
342
|
readonly usedFieldKeys: _angular_core.Signal<Set<string>>;
|
|
@@ -368,8 +403,8 @@ declare class SdQueryBar {
|
|
|
368
403
|
/** Receive `(commit)` from the child popover — splice into filters, null the index. */
|
|
369
404
|
onChipPopoverCommit(next: Filter): void;
|
|
370
405
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdQueryBar, never>;
|
|
371
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdQueryBar, "sd-query-bar", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "fields": { "alias": "fields"; "required": false; "isSignal": true; }; "filters": { "alias": "filters"; "required": false; "isSignal": true; }; "logic": { "alias": "logic"; "required": false; "isSignal": true; }; "search": { "alias": "search"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "showSearch": { "alias": "showSearch"; "required": false; "isSignal": true; }; "showSavedFilters": { "alias": "showSavedFilters"; "required": false; "isSignal": true; }; "savedFiltersKey": { "alias": "savedFiltersKey"; "required": false; "isSignal": true; }; "showLogicToggle": { "alias": "showLogicToggle"; "required": false; "isSignal": true; }; "showClearAll": { "alias": "showClearAll"; "required": false; "isSignal": true; }; "showOperatorOnChip": { "alias": "showOperatorOnChip"; "required": false; "isSignal": true; }; }, { "filters": "filtersChange"; "logic": "logicChange"; "search": "searchChange"; "queryChange": "queryChange"; "apply": "apply"; }, never, never, true, never>;
|
|
406
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdQueryBar, "sd-query-bar", never, { "option": { "alias": "option"; "required": false; "isSignal": true; }; "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "fields": { "alias": "fields"; "required": false; "isSignal": true; }; "filters": { "alias": "filters"; "required": false; "isSignal": true; }; "logic": { "alias": "logic"; "required": false; "isSignal": true; }; "search": { "alias": "search"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "showSearch": { "alias": "showSearch"; "required": false; "isSignal": true; }; "showSavedFilters": { "alias": "showSavedFilters"; "required": false; "isSignal": true; }; "savedFiltersKey": { "alias": "savedFiltersKey"; "required": false; "isSignal": true; }; "showLogicToggle": { "alias": "showLogicToggle"; "required": false; "isSignal": true; }; "showClearAll": { "alias": "showClearAll"; "required": false; "isSignal": true; }; "showOperatorOnChip": { "alias": "showOperatorOnChip"; "required": false; "isSignal": true; }; }, { "filters": "filtersChange"; "logic": "logicChange"; "search": "searchChange"; "queryChange": "queryChange"; "apply": "apply"; }, never, never, true, never>;
|
|
372
407
|
}
|
|
373
408
|
|
|
374
409
|
export { SD_QUERY_DEFAULT_OPERATOR_BY_TYPE, SD_QUERY_MULTI_OPERATORS, SD_QUERY_NO_DATA_OPERATORS, SD_QUERY_OPERATORS_BY_TYPE, SD_QUERY_TYPE_ICON, SdQueryBar, sdQueryAllowedOperators, sdQueryDefaultOperator, sdQueryFieldIcon, sdQueryShowOperatorSelector };
|
|
375
|
-
export type { BuildingChip, SdQuery, SdQueryField, SdQueryFieldBoolean, SdQueryFieldDate, SdQueryFieldLazyValues, SdQueryFieldNumber, SdQueryFieldString, SdQueryFieldType, SdQueryFieldValues, SdQueryLogic, SdSavedFilter };
|
|
410
|
+
export type { BuildingChip, SdQuery, SdQueryBarOption, SdQueryField, SdQueryFieldBoolean, SdQueryFieldDate, SdQueryFieldLazyValues, SdQueryFieldNumber, SdQueryFieldString, SdQueryFieldType, SdQueryFieldValues, SdQueryLogic, SdSavedFilter };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import * as _sdcorejs_angular_components_query_builder from '@sdcorejs/angular/components/query-builder';
|
|
1
2
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { Operator, Filter } from '@sdcorejs/utils/models';
|
|
3
|
+
import { Operator, DateRelative, Filter } from '@sdcorejs/utils/models';
|
|
3
4
|
|
|
4
5
|
/** Field kinds the builder understands. Drives the operator set + value editor. */
|
|
5
6
|
type SdQueryBuilderFieldType = 'string' | 'number' | 'boolean' | 'date' | 'datetime' | 'values';
|
|
@@ -21,6 +22,8 @@ interface SdQueryBuilderField {
|
|
|
21
22
|
label: string;
|
|
22
23
|
/** Field type — picks the default operator set + value editor control. */
|
|
23
24
|
type: SdQueryBuilderFieldType;
|
|
25
|
+
/** Material icon shown before the label in the field picker; falls back to `QB_TYPE_ICON[type]` then `'tune'`. */
|
|
26
|
+
icon?: string;
|
|
24
27
|
/** Override the allowed operator set (otherwise `QB_OPERATORS_BY_TYPE[type]`). */
|
|
25
28
|
operators?: Operator[];
|
|
26
29
|
/** Override the starting operator (otherwise `QB_DEFAULT_OPERATOR_BY_TYPE[type]`). */
|
|
@@ -35,8 +38,29 @@ interface SdQueryBuilderField {
|
|
|
35
38
|
min?: number | string;
|
|
36
39
|
/** Upper bound for number / date value editors. */
|
|
37
40
|
max?: number | string;
|
|
41
|
+
/** Optional domain guard for field-to-field comparison candidates. */
|
|
42
|
+
compareGroup?: string;
|
|
43
|
+
/** Set false to hide this field from field-to-field comparison. */
|
|
44
|
+
allowFieldCompare?: boolean;
|
|
45
|
+
}
|
|
46
|
+
interface SdQueryBuilderOption {
|
|
47
|
+
autoId?: string;
|
|
48
|
+
fields: SdQueryBuilderField[];
|
|
49
|
+
mode?: 'edit' | 'view';
|
|
50
|
+
comparisonMode?: QbComparisonMode;
|
|
51
|
+
disabled?: boolean;
|
|
52
|
+
value?: Filter | null;
|
|
53
|
+
filters?: Filter[];
|
|
54
|
+
rootLogic?: 'AND' | 'OR';
|
|
55
|
+
onValueChange?: (value: Filter | null) => void;
|
|
56
|
+
onFiltersChange?: (filters: Filter[]) => void;
|
|
57
|
+
onRootLogicChange?: (logic: 'AND' | 'OR') => void;
|
|
38
58
|
}
|
|
39
59
|
type QbNode = QbGroup | QbRule;
|
|
60
|
+
/** Component-level capability for right-hand operands. */
|
|
61
|
+
type QbComparisonMode = 'value-only' | 'value-or-field';
|
|
62
|
+
/** Per-rule right-hand operand source. */
|
|
63
|
+
type QbValueSource = 'literal' | 'field';
|
|
40
64
|
/** A logical group of nodes joined by AND / OR. Maps to `FilterAndOr`. */
|
|
41
65
|
interface QbGroup {
|
|
42
66
|
id: string;
|
|
@@ -54,6 +78,10 @@ interface QbRule {
|
|
|
54
78
|
operator?: Operator;
|
|
55
79
|
/** Single value, `{ from, to }` for BETWEEN, or an array for IN / NOT_IN. */
|
|
56
80
|
value?: any;
|
|
81
|
+
/** Internal UI state: literal input or a same-type field reference. */
|
|
82
|
+
valueSource?: QbValueSource;
|
|
83
|
+
/** Right-hand field key when `valueSource` is `'field'`. */
|
|
84
|
+
compareField?: string;
|
|
57
85
|
}
|
|
58
86
|
/** Type guard — narrows a `QbNode` to a `QbGroup`. */
|
|
59
87
|
declare function isQbGroup(node: QbNode): node is QbGroup;
|
|
@@ -79,38 +107,59 @@ declare function qbDefaultOperator(field: SdQueryBuilderField | undefined): Oper
|
|
|
79
107
|
declare function qbIsNoDataOperator(op: Operator | undefined): boolean;
|
|
80
108
|
/** True when `op` is IN / NOT_IN (array value). */
|
|
81
109
|
declare function qbIsMultiOperator(op: Operator | undefined): boolean;
|
|
110
|
+
/** True when the operator accepts one right-hand operand, including a field reference. */
|
|
111
|
+
declare function qbSupportsFieldCompareOperator(op: Operator | undefined): boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Icon fallback per field type when `SdQueryBuilderField.icon` is not set.
|
|
114
|
+
* Mirrors query-bar's `SD_QUERY_TYPE_ICON` so the two components read consistently,
|
|
115
|
+
* but kept local so query-builder has no dependency on the query-bar package.
|
|
116
|
+
*/
|
|
117
|
+
declare const QB_TYPE_ICON: Record<SdQueryBuilderFieldType, string>;
|
|
118
|
+
/**
|
|
119
|
+
* Icon shown before a field in the field picker / selected trigger.
|
|
120
|
+
* Priority: `field.icon` → `QB_TYPE_ICON[field.type]` → `'tune'` (default, like query-bar).
|
|
121
|
+
*/
|
|
122
|
+
declare function qbFieldIcon(field: SdQueryBuilderField | undefined): string;
|
|
82
123
|
/** Next stable node id with the given prefix. */
|
|
83
124
|
declare function qbId(prefix?: string): string;
|
|
84
125
|
/** Build a fresh rule node (optionally pre-filled). */
|
|
85
|
-
declare function qbNewRule(field?: string, operator?: Operator, value?: any): QbRule;
|
|
126
|
+
declare function qbNewRule(field?: string, operator?: Operator, value?: any, valueSource?: QbValueSource, compareField?: string): QbRule;
|
|
86
127
|
/** Build a fresh group node. */
|
|
87
128
|
declare function qbNewGroup(logic?: 'AND' | 'OR', children?: QbNode[]): QbGroup;
|
|
88
|
-
/** Offset unit for a relative date. */
|
|
89
|
-
type SdQbRelativeUnit = '
|
|
90
|
-
/** Offset direction for a relative date. */
|
|
91
|
-
type SdQbRelativeDirection = '
|
|
92
|
-
/**
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
/** Offset unit — only for `rel: 'offset'`. */
|
|
97
|
-
unit?: SdQbRelativeUnit;
|
|
98
|
-
/** Offset magnitude (>= 1) — only for `rel: 'offset'`. */
|
|
99
|
-
amount?: number;
|
|
100
|
-
/** Offset direction — only for `rel: 'offset'`. */
|
|
101
|
-
direction?: SdQbRelativeDirection;
|
|
102
|
-
}
|
|
129
|
+
/** Offset unit for a relative date — re-exported from the utils `DateRelative` model. */
|
|
130
|
+
type SdQbRelativeUnit = DateRelative['unit'];
|
|
131
|
+
/** Offset direction for a relative date — re-exported from the utils `DateRelative` model. */
|
|
132
|
+
type SdQbRelativeDirection = DateRelative['direction'];
|
|
133
|
+
/** Sentinel held as a rule value (and emitted as `data`) for the "today" date mode. */
|
|
134
|
+
declare const QB_TODAY = "TODAY";
|
|
135
|
+
/** The `'TODAY'` sentinel type (matches the utils `date-today` data literal). */
|
|
136
|
+
type QbToday = typeof QB_TODAY;
|
|
103
137
|
/** Date value editor mode for a date/datetime rule (derived from the rule value). */
|
|
104
138
|
type QbDateMode = 'absolute' | 'now' | 'relative';
|
|
105
|
-
/** Type guard — narrows
|
|
106
|
-
declare
|
|
139
|
+
/** Type guard — narrows a rule value to a utils `DateRelative` (offset spec). */
|
|
140
|
+
declare const qbIsRelativeDate: (v: any) => v is DateRelative;
|
|
141
|
+
/** Type guard — narrows a rule value to the `'TODAY'` sentinel ("now"/today mode). */
|
|
142
|
+
declare function qbIsToday(v: any): v is QbToday;
|
|
107
143
|
/** Starting relative value when a rule first switches to "relative" mode. */
|
|
108
|
-
declare function qbDefaultRelative():
|
|
109
|
-
/**
|
|
110
|
-
|
|
144
|
+
declare function qbDefaultRelative(): DateRelative;
|
|
145
|
+
/** One date-mode option — carries a Material icon shown in the dropdown + selected trigger. */
|
|
146
|
+
interface QbDateModeOption {
|
|
111
147
|
value: QbDateMode;
|
|
112
148
|
display: string;
|
|
113
|
-
|
|
149
|
+
/** Material icon name (outlined set). */
|
|
150
|
+
icon: string;
|
|
151
|
+
}
|
|
152
|
+
/** Stable option list for the date-mode select (module ref — never reallocated). */
|
|
153
|
+
declare const QB_DATE_MODES: ReadonlyArray<QbDateModeOption>;
|
|
154
|
+
/** One value-source option for field-to-field comparison UI. */
|
|
155
|
+
interface QbValueSourceOption {
|
|
156
|
+
value: QbValueSource;
|
|
157
|
+
display: string;
|
|
158
|
+
/** Material icon name (outlined set). */
|
|
159
|
+
icon: string;
|
|
160
|
+
}
|
|
161
|
+
/** Stable option list for choosing between a literal value and another field. */
|
|
162
|
+
declare const QB_VALUE_SOURCE_OPTIONS: ReadonlyArray<QbValueSourceOption>;
|
|
114
163
|
/** Stable combined direction×unit option list (token `'unit:direction'`). */
|
|
115
164
|
declare const QB_RELATIVE_UNIT_OPTIONS: ReadonlyArray<{
|
|
116
165
|
value: string;
|
|
@@ -128,10 +177,14 @@ declare const QB_EMPTY_OPTIONS: SdQueryBuilderFieldOption[];
|
|
|
128
177
|
*/
|
|
129
178
|
declare class SdQueryBuilder {
|
|
130
179
|
#private;
|
|
180
|
+
/** Main option object. Prefer this API for new usage; individual inputs stay as a migration bridge. */
|
|
181
|
+
readonly option: _angular_core.InputSignal<SdQueryBuilderOption | undefined>;
|
|
131
182
|
/** Filterable fields — each declares a `type` that drives the operator set + value editor. */
|
|
132
183
|
readonly fields: _angular_core.InputSignal<SdQueryBuilderField[]>;
|
|
133
184
|
/** `'edit'` (default) = interactive tree · `'view'` = read-only raw-query string. */
|
|
134
185
|
readonly mode: _angular_core.InputSignal<"edit" | "view">;
|
|
186
|
+
/** `value-only` = literal operands only · `value-or-field` = each rule may compare against another field. */
|
|
187
|
+
readonly comparisonMode: _angular_core.InputSignal<QbComparisonMode>;
|
|
135
188
|
/** Disable all editing controls. */
|
|
136
189
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
137
190
|
/** Prefix for `data-autoid` on inner controls (E2E selectors). */
|
|
@@ -144,12 +197,16 @@ declare class SdQueryBuilder {
|
|
|
144
197
|
readonly rootLogic: _angular_core.ModelSignal<"AND" | "OR">;
|
|
145
198
|
readonly tree: _angular_core.Signal<QbGroup>;
|
|
146
199
|
/** `field.key` → field, for fast lookup from a rule. */
|
|
200
|
+
readonly resolvedFields: _angular_core.Signal<SdQueryBuilderField[]>;
|
|
201
|
+
readonly resolvedMode: _angular_core.Signal<"edit" | "view">;
|
|
202
|
+
readonly resolvedComparisonMode: _angular_core.Signal<QbComparisonMode>;
|
|
203
|
+
readonly resolvedDisabled: _angular_core.Signal<boolean>;
|
|
204
|
+
readonly resolvedAutoId: _angular_core.Signal<string | undefined>;
|
|
147
205
|
readonly fieldByKey: _angular_core.Signal<Record<string, SdQueryBuilderField>>;
|
|
148
206
|
/** Stable option list for the date-mode select. */
|
|
149
|
-
readonly dateModes: readonly
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}[];
|
|
207
|
+
readonly dateModes: readonly _sdcorejs_angular_components_query_builder.QbDateModeOption[];
|
|
208
|
+
/** Stable option list for the literal-vs-field operand select. */
|
|
209
|
+
readonly valueSourceOptions: readonly _sdcorejs_angular_components_query_builder.QbValueSourceOption[];
|
|
153
210
|
/** Stable combined unit×direction option list for the relative select. */
|
|
154
211
|
readonly relativeUnitOptions: readonly {
|
|
155
212
|
value: string;
|
|
@@ -160,6 +217,8 @@ declare class SdQueryBuilder {
|
|
|
160
217
|
readonly isView: _angular_core.Signal<boolean>;
|
|
161
218
|
/** Expose the type-guard to the template. */
|
|
162
219
|
readonly isGroup: typeof isQbGroup;
|
|
220
|
+
/** Resolve the leading icon for a field (own `icon` → per-type → `'tune'`) — used by the field picker. */
|
|
221
|
+
readonly fieldIcon: typeof qbFieldIcon;
|
|
163
222
|
constructor();
|
|
164
223
|
/** Switch a group's AND/OR connector and re-emit. No-op when disabled or unchanged. */
|
|
165
224
|
setGroupLogic(group: QbGroup, logic: 'AND' | 'OR'): void;
|
|
@@ -189,12 +248,19 @@ declare class SdQueryBuilder {
|
|
|
189
248
|
setBetweenFrom(rule: QbRule, raw: any): void;
|
|
190
249
|
/** Set the upper bound of a BETWEEN rule's `{ from, to }` value. */
|
|
191
250
|
setBetweenTo(rule: QbRule, raw: any): void;
|
|
251
|
+
setValueSource(rule: QbRule, source: QbValueSource): void;
|
|
252
|
+
setCompareField(rule: QbRule, key: any): void;
|
|
192
253
|
/** The field metadata for a rule's current `field` key (or undefined if unset). */
|
|
193
254
|
fieldOf(rule: QbRule): SdQueryBuilderField | undefined;
|
|
194
255
|
/** Operators allowed for a rule, derived from its field's type / override. */
|
|
195
256
|
allowedOperators(rule: QbRule): Operator[];
|
|
196
257
|
/** Whether to render the operator picker — hidden when only one operator is allowed. */
|
|
197
258
|
showOperatorSelector(rule: QbRule): boolean;
|
|
259
|
+
compareFields(rule: QbRule): SdQueryBuilderField[];
|
|
260
|
+
canCompareWithField(rule: QbRule): boolean;
|
|
261
|
+
showValueSourceSelector(rule: QbRule): boolean;
|
|
262
|
+
valueSourceOf(rule: QbRule): QbValueSource;
|
|
263
|
+
isFieldSource(rule: QbRule): boolean;
|
|
198
264
|
/** True for NULL / NOT_NULL — the template then renders no value editor. */
|
|
199
265
|
isNoData(op: Operator | undefined): boolean;
|
|
200
266
|
/** True for IN / NOT_IN — the template then renders a multi-select value editor. */
|
|
@@ -216,7 +282,7 @@ declare class SdQueryBuilder {
|
|
|
216
282
|
/** Build a `data-autoid` for an inner control under this builder's `autoId` prefix. */
|
|
217
283
|
autoIdFor(suffix: string): string;
|
|
218
284
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdQueryBuilder, never>;
|
|
219
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdQueryBuilder, "sd-query-builder", never, { "fields": { "alias": "fields"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "autoId": { "alias": "autoId"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "filters": { "alias": "filters"; "required": false; "isSignal": true; }; "rootLogic": { "alias": "rootLogic"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "filters": "filtersChange"; "rootLogic": "rootLogicChange"; }, never, never, true, never>;
|
|
285
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdQueryBuilder, "sd-query-builder", never, { "option": { "alias": "option"; "required": false; "isSignal": true; }; "fields": { "alias": "fields"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "comparisonMode": { "alias": "comparisonMode"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "autoId": { "alias": "autoId"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "filters": { "alias": "filters"; "required": false; "isSignal": true; }; "rootLogic": { "alias": "rootLogic"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "filters": "filtersChange"; "rootLogic": "rootLogicChange"; }, never, never, true, never>;
|
|
220
286
|
}
|
|
221
287
|
|
|
222
288
|
/**
|
|
@@ -250,5 +316,5 @@ declare function filterToTree(filter: Filter | null | undefined): QbGroup;
|
|
|
250
316
|
*/
|
|
251
317
|
declare function filterToTokens(filter: Filter | null | undefined, fields: SdQueryBuilderField[]): QbToken[];
|
|
252
318
|
|
|
253
|
-
export { QB_DATE_MODES, QB_DEFAULT_OPERATOR_BY_TYPE, QB_EMPTY_OPTIONS, QB_MULTI_OPERATORS, QB_NO_DATA_OPERATORS, QB_OPERATORS_BY_TYPE, QB_RELATIVE_UNIT_OPTIONS, SdQueryBuilder, filterToTokens, filterToTree, isQbGroup, qbAllowedOperators, qbDefaultOperator, qbDefaultRelative, qbId, qbIsMultiOperator, qbIsNoDataOperator, qbIsRelativeDate, qbNewGroup, qbNewRule, treeToFilter };
|
|
254
|
-
export type { QbDateMode, QbGroup, QbNode, QbRule, QbToken, QbTokenKind,
|
|
319
|
+
export { QB_DATE_MODES, QB_DEFAULT_OPERATOR_BY_TYPE, QB_EMPTY_OPTIONS, QB_MULTI_OPERATORS, QB_NO_DATA_OPERATORS, QB_OPERATORS_BY_TYPE, QB_RELATIVE_UNIT_OPTIONS, QB_TODAY, QB_TYPE_ICON, QB_VALUE_SOURCE_OPTIONS, SdQueryBuilder, filterToTokens, filterToTree, isQbGroup, qbAllowedOperators, qbDefaultOperator, qbDefaultRelative, qbFieldIcon, qbId, qbIsMultiOperator, qbIsNoDataOperator, qbIsRelativeDate, qbIsToday, qbNewGroup, qbNewRule, qbSupportsFieldCompareOperator, treeToFilter };
|
|
320
|
+
export type { QbComparisonMode, QbDateMode, QbDateModeOption, QbGroup, QbNode, QbRule, QbToday, QbToken, QbTokenKind, QbValueSource, QbValueSourceOption, SdQbRelativeDirection, SdQbRelativeUnit, SdQueryBuilderField, SdQueryBuilderFieldOption, SdQueryBuilderFieldType, SdQueryBuilderOption };
|
|
@@ -8,13 +8,16 @@ declare class SdSection {
|
|
|
8
8
|
icon: _angular_core.InputSignal<string | null | undefined>;
|
|
9
9
|
iconColor: _angular_core.InputSignal<Color>;
|
|
10
10
|
collapsed: _angular_core.ModelSignal<boolean>;
|
|
11
|
+
collapsible: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
12
|
+
/** @deprecated Use `collapsible` instead. */
|
|
11
13
|
collapsable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
14
|
+
readonly isCollapsible: _angular_core.Signal<boolean>;
|
|
12
15
|
hideHeader: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
13
16
|
noPaddingBody: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
14
17
|
constructor();
|
|
15
18
|
toggleCollapse: () => void;
|
|
16
19
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdSection, never>;
|
|
17
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdSection, "sd-section", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "subTitle": { "alias": "subTitle"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "iconColor": { "alias": "iconColor"; "required": false; "isSignal": true; }; "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; "collapsable": { "alias": "collapsable"; "required": false; "isSignal": true; }; "hideHeader": { "alias": "hideHeader"; "required": false; "isSignal": true; }; "noPaddingBody": { "alias": "noPaddingBody"; "required": false; "isSignal": true; }; }, { "collapsed": "collapsedChange"; }, never, ["[sdHeaderLeft]", "[sdHeaderRight]", "*"], true, never>;
|
|
20
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdSection, "sd-section", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "subTitle": { "alias": "subTitle"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "iconColor": { "alias": "iconColor"; "required": false; "isSignal": true; }; "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; "collapsible": { "alias": "collapsible"; "required": false; "isSignal": true; }; "collapsable": { "alias": "collapsable"; "required": false; "isSignal": true; }; "hideHeader": { "alias": "hideHeader"; "required": false; "isSignal": true; }; "noPaddingBody": { "alias": "noPaddingBody"; "required": false; "isSignal": true; }; }, { "collapsed": "collapsedChange"; }, never, ["[sdHeaderLeft]", "[sdHeaderRight]", "*"], true, never>;
|
|
18
21
|
}
|
|
19
22
|
|
|
20
23
|
declare class SdSectionItem {
|
|
@@ -13,6 +13,19 @@ interface SplitterLayoutState {
|
|
|
13
13
|
v: 1;
|
|
14
14
|
panels: SplitterPanelState[];
|
|
15
15
|
}
|
|
16
|
+
interface SdSplitterOption {
|
|
17
|
+
orientation?: SplitterOrientation;
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
storageKey?: string;
|
|
20
|
+
snapThreshold?: number;
|
|
21
|
+
keyboardStep?: number;
|
|
22
|
+
onResizeEnd?: (state: SplitterLayoutState) => void;
|
|
23
|
+
onCollapsedChange?: (event: {
|
|
24
|
+
panelId: string | number;
|
|
25
|
+
collapsed: boolean;
|
|
26
|
+
}) => void;
|
|
27
|
+
onLayoutChange?: (state: SplitterLayoutState) => void;
|
|
28
|
+
}
|
|
16
29
|
|
|
17
30
|
declare class SdSplitterPanelComponent {
|
|
18
31
|
readonly elementRef: ElementRef<HTMLElement>;
|
|
@@ -30,11 +43,17 @@ declare class SdSplitterPanelComponent {
|
|
|
30
43
|
|
|
31
44
|
declare class SdSplitterComponent {
|
|
32
45
|
#private;
|
|
46
|
+
option: _angular_core.InputSignal<SdSplitterOption | undefined>;
|
|
33
47
|
orientation: _angular_core.InputSignal<SplitterOrientation>;
|
|
34
48
|
disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
35
49
|
storageKey: _angular_core.InputSignal<string | undefined>;
|
|
36
50
|
snapThreshold: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
37
51
|
keyboardStep: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
52
|
+
resolvedOrientation: _angular_core.Signal<SplitterOrientation>;
|
|
53
|
+
resolvedDisabled: _angular_core.Signal<boolean>;
|
|
54
|
+
resolvedStorageKey: _angular_core.Signal<string | undefined>;
|
|
55
|
+
resolvedSnapThreshold: _angular_core.Signal<number>;
|
|
56
|
+
resolvedKeyboardStep: _angular_core.Signal<number>;
|
|
38
57
|
readonly resizeEnd: _angular_core.OutputEmitterRef<SplitterLayoutState>;
|
|
39
58
|
readonly collapsedChange: _angular_core.OutputEmitterRef<{
|
|
40
59
|
panelId: string | number;
|
|
@@ -51,7 +70,7 @@ declare class SdSplitterComponent {
|
|
|
51
70
|
toggle(target: number | string): void;
|
|
52
71
|
resizePanel(target: number | string, size: number): void;
|
|
53
72
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdSplitterComponent, never>;
|
|
54
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdSplitterComponent, "sd-splitter", never, { "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "storageKey": { "alias": "storageKey"; "required": false; "isSignal": true; }; "snapThreshold": { "alias": "snapThreshold"; "required": false; "isSignal": true; }; "keyboardStep": { "alias": "keyboardStep"; "required": false; "isSignal": true; }; }, { "resizeEnd": "resizeEnd"; "collapsedChange": "collapsedChange"; "layoutChange": "layoutChange"; }, ["panels"], ["sd-splitter-panel"], true, never>;
|
|
73
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdSplitterComponent, "sd-splitter", never, { "option": { "alias": "option"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "storageKey": { "alias": "storageKey"; "required": false; "isSignal": true; }; "snapThreshold": { "alias": "snapThreshold"; "required": false; "isSignal": true; }; "keyboardStep": { "alias": "keyboardStep"; "required": false; "isSignal": true; }; }, { "resizeEnd": "resizeEnd"; "collapsedChange": "collapsedChange"; "layoutChange": "layoutChange"; }, ["panels"], ["sd-splitter-panel"], true, never>;
|
|
55
74
|
}
|
|
56
75
|
|
|
57
76
|
export { SdSplitterComponent, SdSplitterPanelComponent };
|
|
@@ -339,6 +339,8 @@ interface SdTableOptionFilter<T = any> {
|
|
|
339
339
|
/** Chế độ thủ công: phải nhấn nút áp dụng mới gửi filter */
|
|
340
340
|
manualFilter?: boolean;
|
|
341
341
|
/** Có thể thu gọn bộ lọc hay không */
|
|
342
|
+
collapsible?: boolean;
|
|
343
|
+
/** @deprecated Use `collapsible` instead. */
|
|
342
344
|
collapsable?: boolean;
|
|
343
345
|
/** Ẩn toolbar (xóa bộ lọc, thiết lập) của external filter, khi có ít external filter user không cần chức năng này */
|
|
344
346
|
hideExternalFilterToolbar?: boolean;
|