@sdcorejs/angular 19.0.1 → 19.0.4
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 +22 -4
- package/assets/scss/core/_inline-edit.scss +105 -0
- package/assets/scss/core/form.scss +15 -0
- package/components/autoid-inspector/src/models/autoid-element.model.d.ts +11 -0
- package/components/autoid-inspector/src/models/autoid-export-format.model.d.ts +19 -0
- package/components/autoid-inspector/src/services/autoid-export.service.d.ts +7 -1
- package/components/autoid-inspector/src/services/autoid-scanner.service.d.ts +15 -2
- package/components/button/src/button.component.d.ts +1 -2
- package/components/form-generic/src/components/form-builder/form-builder.component.d.ts +13 -15
- package/components/form-generic/src/components/form-render/form-render.component.d.ts +1 -2
- package/components/form-generic/src/components/sd-feel-expression/sd-feel-expression.component.d.ts +1 -2
- package/components/index.d.ts +1 -0
- package/components/modal-resizable/index.d.ts +1 -0
- package/components/modal-resizable/src/modal-resizable.component.d.ts +29 -0
- package/components/query-bar/src/components/inline-chip/inline-chip.component.d.ts +11 -22
- package/components/query-bar/src/components/inline-value-chip/inline-value-chip.component.d.ts +3 -7
- package/components/query-builder/index.d.ts +2 -0
- package/components/query-builder/src/query-builder.component.d.ts +98 -22
- package/components/query-builder/src/query-builder.model.d.ts +118 -0
- package/components/query-builder/src/query-builder.serializer.d.ts +32 -0
- package/components/section/src/section.component.d.ts +1 -2
- package/components/side-drawer/src/side-drawer.component.d.ts +1 -2
- package/components/stepper/src/stepper.component.d.ts +1 -2
- package/components/tab/src/tab-group.component.d.ts +1 -2
- package/components/table/src/components/config/config.component.d.ts +3 -1
- package/components/table/src/components/selector-action/selector-action.component.d.ts +3 -1
- package/components/table/src/models/table-option-tree.model.d.ts +96 -8
- package/components/table/src/services/tree/tree.util.d.ts +43 -2
- package/components/table/src/table.component.d.ts +1 -2
- package/components/upload-file/src/upload-file.component.d.ts +2 -0
- package/components/view/src/view.component.d.ts +33 -0
- package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs +97 -10
- package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-avatar.mjs +2 -2
- package/fesm2022/sdcorejs-angular-components-avatar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-button.mjs +3 -5
- package/fesm2022/sdcorejs-angular-components-button.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs +106 -197
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
- 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-operator.mjs +3 -1
- package/fesm2022/sdcorejs-angular-components-operator.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-preview.mjs +4 -4
- package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs +41 -87
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs +669 -57
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-section.mjs +2 -4
- package/fesm2022/sdcorejs-angular-components-section.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +3 -5
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-stepper.mjs +2 -4
- package/fesm2022/sdcorejs-angular-components-stepper.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tab.mjs +2 -4
- package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-table.mjs +235 -110
- package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs +15 -4
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-view.mjs +43 -11
- 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-forms-autocomplete.mjs +32 -7
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs +9 -4
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +10 -5
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip.mjs +10 -5
- package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs +18 -9
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date.mjs +20 -8
- package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs +20 -8
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
- 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 +5 -3
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs +41 -8
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input.mjs +35 -9
- package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
- 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 +9 -4
- package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-select.mjs +33 -9
- package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-switch.mjs +9 -4
- package/fesm2022/sdcorejs-angular-forms-switch.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs +15 -5
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-i18n.mjs +20 -0
- package/fesm2022/sdcorejs-angular-i18n.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-confirm.mjs +1 -1
- package/fesm2022/sdcorejs-angular-services-confirm.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-notify.mjs +40 -9
- package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
- package/forms/autocomplete/src/autocomplete.component.d.ts +16 -3
- package/forms/checkbox/src/checkbox.component.d.ts +5 -1
- package/forms/chip/src/chip.component.d.ts +5 -2
- package/forms/chip-calendar/src/chip-calendar.component.d.ts +5 -2
- package/forms/date/src/date.component.d.ts +14 -5
- package/forms/date-range/src/date-range.component.d.ts +12 -5
- package/forms/datetime/src/datetime.component.d.ts +14 -5
- package/forms/inline-text/index.d.ts +1 -0
- package/forms/inline-text/src/inline-text.component.d.ts +76 -0
- package/forms/input/src/input.component.d.ts +14 -2
- package/forms/input-color/src/input-color.component.d.ts +3 -1
- package/forms/input-number/src/input-number.component.d.ts +14 -2
- package/forms/models/index.d.ts +1 -0
- package/forms/models/src/sd-viewed.d.ts +38 -0
- package/forms/radio/src/radio.component.d.ts +5 -2
- package/forms/select/src/select.component.d.ts +23 -5
- package/forms/switch/src/switch.component.d.ts +5 -2
- package/forms/textarea/src/textarea.component.d.ts +9 -2
- package/i18n/src/en.d.ts +4 -0
- package/package.json +9 -1
- package/services/notify/src/components/toast/toast.component.d.ts +16 -1
- package/services/notify/src/notify.model.d.ts +17 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Operator } from '@sdcorejs/utils/models';
|
|
2
|
+
/** Field kinds the builder understands. Drives the operator set + value editor. */
|
|
3
|
+
export type SdQueryBuilderFieldType = 'string' | 'number' | 'boolean' | 'date' | 'datetime' | 'values';
|
|
4
|
+
/** One option for a `values`-type field (enum / lookup). */
|
|
5
|
+
export interface SdQueryBuilderFieldOption {
|
|
6
|
+
/** Stored value (sent inside the `Filter`). */
|
|
7
|
+
value: any;
|
|
8
|
+
/** Human-readable label shown in the select + view-mode string. */
|
|
9
|
+
display: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* One filterable field. `key` matches `Filter.field` (dot-notation allowed);
|
|
13
|
+
* `label` is what the view-mode raw string renders (field token = label).
|
|
14
|
+
*/
|
|
15
|
+
export interface SdQueryBuilderField {
|
|
16
|
+
/** Dot-notation field path — written to `Filter.field`. */
|
|
17
|
+
key: string;
|
|
18
|
+
/** Human label — shown in the field picker AND as the view-mode field token. */
|
|
19
|
+
label: string;
|
|
20
|
+
/** Field type — picks the default operator set + value editor control. */
|
|
21
|
+
type: SdQueryBuilderFieldType;
|
|
22
|
+
/** Override the allowed operator set (otherwise `QB_OPERATORS_BY_TYPE[type]`). */
|
|
23
|
+
operators?: Operator[];
|
|
24
|
+
/** Override the starting operator (otherwise `QB_DEFAULT_OPERATOR_BY_TYPE[type]`). */
|
|
25
|
+
defaultOperator?: Operator;
|
|
26
|
+
/** Options for `type: 'values'` — the select list + display-label lookup. */
|
|
27
|
+
values?: SdQueryBuilderFieldOption[];
|
|
28
|
+
/** Label for the `true` branch of a boolean field (default `'Có'`). */
|
|
29
|
+
trueLabel?: string;
|
|
30
|
+
/** Label for the `false` branch of a boolean field (default `'Không'`). */
|
|
31
|
+
falseLabel?: string;
|
|
32
|
+
/** Lower bound for number / date value editors. */
|
|
33
|
+
min?: number | string;
|
|
34
|
+
/** Upper bound for number / date value editors. */
|
|
35
|
+
max?: number | string;
|
|
36
|
+
}
|
|
37
|
+
export type QbNode = QbGroup | QbRule;
|
|
38
|
+
/** A logical group of nodes joined by AND / OR. Maps to `FilterAndOr`. */
|
|
39
|
+
export interface QbGroup {
|
|
40
|
+
id: string;
|
|
41
|
+
kind: 'group';
|
|
42
|
+
logic: 'AND' | 'OR';
|
|
43
|
+
children: QbNode[];
|
|
44
|
+
/** UI-only: whether this group's "+" dropdown is open. */
|
|
45
|
+
open?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/** A single `field operator value` condition. Maps to a leaf `Filter`. */
|
|
48
|
+
export interface QbRule {
|
|
49
|
+
id: string;
|
|
50
|
+
kind: 'rule';
|
|
51
|
+
field?: string;
|
|
52
|
+
operator?: Operator;
|
|
53
|
+
/** Single value, `{ from, to }` for BETWEEN, or an array for IN / NOT_IN. */
|
|
54
|
+
value?: any;
|
|
55
|
+
}
|
|
56
|
+
/** Type guard — narrows a `QbNode` to a `QbGroup`. */
|
|
57
|
+
export declare function isQbGroup(node: QbNode): node is QbGroup;
|
|
58
|
+
export type QbTokenKind = 'field' | 'op' | 'value' | 'logic' | 'paren' | 'plain';
|
|
59
|
+
/** One piece of the rendered raw query string, tagged for highlight styling. */
|
|
60
|
+
export interface QbToken {
|
|
61
|
+
text: string;
|
|
62
|
+
kind: QbTokenKind;
|
|
63
|
+
}
|
|
64
|
+
/** Allowed operators per field type — used when `field.operators` is not set. */
|
|
65
|
+
export declare const QB_OPERATORS_BY_TYPE: Record<SdQueryBuilderFieldType, Operator[]>;
|
|
66
|
+
/** Default operator when a rule is first created for a field. */
|
|
67
|
+
export declare const QB_DEFAULT_OPERATOR_BY_TYPE: Record<SdQueryBuilderFieldType, Operator>;
|
|
68
|
+
/** Operators with no value payload — the value editor is hidden for these. */
|
|
69
|
+
export declare const QB_NO_DATA_OPERATORS: Operator[];
|
|
70
|
+
/** Operators whose value is an array — the value editor offers multi-select. */
|
|
71
|
+
export declare const QB_MULTI_OPERATORS: Operator[];
|
|
72
|
+
/** Operators allowed for `field` — explicit override wins, else the per-type set. */
|
|
73
|
+
export declare function qbAllowedOperators(field: SdQueryBuilderField | undefined): Operator[];
|
|
74
|
+
/** Starting operator for a new rule on `field` — falls back to the per-type default. */
|
|
75
|
+
export declare function qbDefaultOperator(field: SdQueryBuilderField | undefined): Operator | undefined;
|
|
76
|
+
/** True when `op` is NULL / NOT_NULL (no value editor). */
|
|
77
|
+
export declare function qbIsNoDataOperator(op: Operator | undefined): boolean;
|
|
78
|
+
/** True when `op` is IN / NOT_IN (array value). */
|
|
79
|
+
export declare function qbIsMultiOperator(op: Operator | undefined): boolean;
|
|
80
|
+
/** Next stable node id with the given prefix. */
|
|
81
|
+
export declare function qbId(prefix?: string): string;
|
|
82
|
+
/** Build a fresh rule node (optionally pre-filled). */
|
|
83
|
+
export declare function qbNewRule(field?: string, operator?: Operator, value?: any): QbRule;
|
|
84
|
+
/** Build a fresh group node. */
|
|
85
|
+
export declare function qbNewGroup(logic?: 'AND' | 'OR', children?: QbNode[]): QbGroup;
|
|
86
|
+
/** Offset unit for a relative date. */
|
|
87
|
+
export type SdQbRelativeUnit = 'day' | 'week' | 'month';
|
|
88
|
+
/** Offset direction for a relative date. */
|
|
89
|
+
export type SdQbRelativeDirection = 'previous' | 'next';
|
|
90
|
+
/** A relative (resolved-at-query-time) date value stored in `Filter.data`. */
|
|
91
|
+
export interface SdQbRelativeDate {
|
|
92
|
+
/** `'now'` = current moment / today · `'offset'` = now ± amount × unit. */
|
|
93
|
+
rel: 'now' | 'offset';
|
|
94
|
+
/** Offset unit — only for `rel: 'offset'`. */
|
|
95
|
+
unit?: SdQbRelativeUnit;
|
|
96
|
+
/** Offset magnitude (>= 1) — only for `rel: 'offset'`. */
|
|
97
|
+
amount?: number;
|
|
98
|
+
/** Offset direction — only for `rel: 'offset'`. */
|
|
99
|
+
direction?: SdQbRelativeDirection;
|
|
100
|
+
}
|
|
101
|
+
/** Date value editor mode for a date/datetime rule (derived from the rule value). */
|
|
102
|
+
export type QbDateMode = 'absolute' | 'now' | 'relative';
|
|
103
|
+
/** Type guard — narrows an arbitrary value to a relative-date spec. */
|
|
104
|
+
export declare function qbIsRelativeDate(v: any): v is SdQbRelativeDate;
|
|
105
|
+
/** Starting relative value when a rule first switches to "relative" mode. */
|
|
106
|
+
export declare function qbDefaultRelative(): SdQbRelativeDate;
|
|
107
|
+
/** Stable option list for the date-mode select (module ref — never reallocated). */
|
|
108
|
+
export declare const QB_DATE_MODES: ReadonlyArray<{
|
|
109
|
+
value: QbDateMode;
|
|
110
|
+
display: string;
|
|
111
|
+
}>;
|
|
112
|
+
/** Stable combined direction×unit option list (token `'unit:direction'`). */
|
|
113
|
+
export declare const QB_RELATIVE_UNIT_OPTIONS: ReadonlyArray<{
|
|
114
|
+
value: string;
|
|
115
|
+
display: string;
|
|
116
|
+
}>;
|
|
117
|
+
/** Shared empty option array — stable ref for fallbacks (avoids per-call allocation). */
|
|
118
|
+
export declare const QB_EMPTY_OPTIONS: SdQueryBuilderFieldOption[];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Filter } from '@sdcorejs/utils/models';
|
|
2
|
+
import { QbGroup, QbToken, SdQueryBuilderField } from './query-builder.model';
|
|
3
|
+
/**
|
|
4
|
+
* Map the internal builder tree to the public `Filter` (the root is always a
|
|
5
|
+
* `FilterAndOr`). Rules missing field / operator / value — and empty nested
|
|
6
|
+
* groups — are dropped so the result is always a valid `Filter`.
|
|
7
|
+
*
|
|
8
|
+
* @param group - the editable tree's root group.
|
|
9
|
+
* @returns the canonical nested `Filter`, or `null` when no complete rule survives.
|
|
10
|
+
*/
|
|
11
|
+
export declare function treeToFilter(group: QbGroup): Filter | null;
|
|
12
|
+
/**
|
|
13
|
+
* Inverse of {@link treeToFilter} — rebuild the editable tree from a `Filter` so a
|
|
14
|
+
* consumer can seed `[value]`. A non-group (bare) filter is wrapped in an AND root;
|
|
15
|
+
* `null` yields an empty AND root.
|
|
16
|
+
*
|
|
17
|
+
* @param filter - a `Filter` (group or leaf), or `null` / `undefined` for an empty tree.
|
|
18
|
+
* @returns a fresh root `QbGroup` mirroring the filter's structure.
|
|
19
|
+
*/
|
|
20
|
+
export declare function filterToTree(filter: Filter | null | undefined): QbGroup;
|
|
21
|
+
/**
|
|
22
|
+
* Render a `Filter` to a SQL-ish token stream for view mode. Field tokens use the
|
|
23
|
+
* matching field's `label`; operators map to SQL syntax (`= != like between is null …`);
|
|
24
|
+
* `and` / `or` are lowercase; nested multi-child groups are wrapped in parentheses.
|
|
25
|
+
* Returns a token stream (not a string) so the template can wrap each piece in a
|
|
26
|
+
* highlight `<span>` keyed by `QbToken.kind`.
|
|
27
|
+
*
|
|
28
|
+
* @param filter - the `Filter` to render, or `null` / `undefined`.
|
|
29
|
+
* @param fields - field metadata, used to resolve each field key to its display label + value formatting.
|
|
30
|
+
* @returns the ordered tokens, or `[]` when `filter` is empty.
|
|
31
|
+
*/
|
|
32
|
+
export declare function filterToTokens(filter: Filter | null | undefined, fields: SdQueryBuilderField[]): QbToken[];
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { SdBaseSecureComponent } from '@sdcorejs/angular/components/base';
|
|
2
1
|
import { Color } from '@sdcorejs/utils/models';
|
|
3
2
|
import * as i0 from "@angular/core";
|
|
4
|
-
export declare class SdSection
|
|
3
|
+
export declare class SdSection {
|
|
5
4
|
#private;
|
|
6
5
|
title: import("@angular/core").InputSignal<string | null | undefined>;
|
|
7
6
|
subTitle: import("@angular/core").InputSignal<string | null | undefined>;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { CdkPortal } from '@angular/cdk/portal';
|
|
2
|
-
import { SdBaseSecureComponent } from '@sdcorejs/angular/components/base';
|
|
3
2
|
import { Observable } from 'rxjs';
|
|
4
3
|
import * as i0 from "@angular/core";
|
|
5
|
-
export declare class SdSideDrawer
|
|
4
|
+
export declare class SdSideDrawer {
|
|
6
5
|
#private;
|
|
7
6
|
id: string;
|
|
8
7
|
portal: import("@angular/core").Signal<CdkPortal>;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { StepperSelectionEvent } from '@angular/cdk/stepper';
|
|
2
2
|
import { MatStepper } from '@angular/material/stepper';
|
|
3
|
-
import { SdBaseSecureComponent } from '@sdcorejs/angular/components/base';
|
|
4
3
|
import { Color } from '@sdcorejs/utils/models';
|
|
5
4
|
import { SdStep } from './step.component';
|
|
6
5
|
import * as i0 from "@angular/core";
|
|
7
|
-
export declare class SdStepper
|
|
6
|
+
export declare class SdStepper {
|
|
8
7
|
steps: import("@angular/core").Signal<readonly SdStep[]>;
|
|
9
8
|
selectedIndex: import("@angular/core").ModelSignal<number>;
|
|
10
9
|
linear: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { MatTabGroup } from '@angular/material/tabs';
|
|
2
|
-
import { SdBaseSecureComponent } from '@sdcorejs/angular/components/base';
|
|
3
2
|
import { Color } from '@sdcorejs/utils/models';
|
|
4
3
|
import { SdTab } from './tab.component';
|
|
5
4
|
import * as i0 from "@angular/core";
|
|
@@ -7,7 +6,7 @@ export interface SdTabClosedEvent {
|
|
|
7
6
|
index: number;
|
|
8
7
|
tab: SdTab;
|
|
9
8
|
}
|
|
10
|
-
export declare class SdTabGroup
|
|
9
|
+
export declare class SdTabGroup {
|
|
11
10
|
tabs: import("@angular/core").Signal<readonly SdTab[]>;
|
|
12
11
|
selectedIndex: import("@angular/core").ModelSignal<number>;
|
|
13
12
|
variant: import("@angular/core").InputSignal<"line" | "pills" | "segmented">;
|
|
@@ -6,8 +6,10 @@ import { SdTableOption } from '../../models/table-option.model';
|
|
|
6
6
|
import * as i0 from "@angular/core";
|
|
7
7
|
export declare class ConfigComponent {
|
|
8
8
|
#private;
|
|
9
|
+
autoIdInput: import("@angular/core").InputSignal<string | null | undefined>;
|
|
9
10
|
tableOption: import("@angular/core").InputSignal<SdTableOption | undefined>;
|
|
10
11
|
changes: import("@angular/core").OutputEmitterRef<ConfiguredTableResult>;
|
|
12
|
+
autoId: import("@angular/core").Signal<string>;
|
|
11
13
|
modal: import("@angular/core").Signal<SdModal | undefined>;
|
|
12
14
|
table: import("@angular/core").Signal<MatTable<SdTableColumn>>;
|
|
13
15
|
configuration: import("@angular/core").WritableSignal<ConfiguredTable | undefined>;
|
|
@@ -21,5 +23,5 @@ export declare class ConfigComponent {
|
|
|
21
23
|
handleMouseDown(): void;
|
|
22
24
|
handleMouseUp(): void;
|
|
23
25
|
static ɵfac: i0.ɵɵFactoryDeclaration<ConfigComponent, never>;
|
|
24
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<ConfigComponent, "config", never, { "tableOption": { "alias": "tableOption"; "required": false; "isSignal": true; }; }, { "changes": "changes"; }, never, never, true, never>;
|
|
26
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ConfigComponent, "config", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "tableOption": { "alias": "tableOption"; "required": false; "isSignal": true; }; }, { "changes": "changes"; }, never, never, true, never>;
|
|
25
27
|
}
|
|
@@ -4,13 +4,15 @@ import { Action } from './action-filter.pipe';
|
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
5
5
|
export declare class SelectorActionComponent {
|
|
6
6
|
#private;
|
|
7
|
+
autoIdInput: import("@angular/core").InputSignal<string | null | undefined>;
|
|
7
8
|
tableOption: import("@angular/core").InputSignal<SdTableOption | undefined>;
|
|
8
9
|
selectedTableItems: import("@angular/core").InputSignal<SdTableItem<any>[] | undefined>;
|
|
9
10
|
clear: import("@angular/core").OutputEmitterRef<void>;
|
|
11
|
+
autoId: import("@angular/core").Signal<string>;
|
|
10
12
|
message: import("@angular/core").Signal<string>;
|
|
11
13
|
opened: import("@angular/core").Signal<boolean>;
|
|
12
14
|
onClear: () => void;
|
|
13
15
|
onClickAction: (action: Action) => void;
|
|
14
16
|
static ɵfac: i0.ɵɵFactoryDeclaration<SelectorActionComponent, never>;
|
|
15
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<SelectorActionComponent, "selector-action", never, { "tableOption": { "alias": "tableOption"; "required": false; "isSignal": true; }; "selectedTableItems": { "alias": "selectedTableItems"; "required": false; "isSignal": true; }; }, { "clear": "clear"; }, never, never, true, never>;
|
|
17
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SelectorActionComponent, "selector-action", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "tableOption": { "alias": "tableOption"; "required": false; "isSignal": true; }; "selectedTableItems": { "alias": "selectedTableItems"; "required": false; "isSignal": true; }; }, { "clear": "clear"; }, never, never, true, never>;
|
|
16
18
|
}
|
|
@@ -1,12 +1,100 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { NestedKeyOf } from '@sdcorejs/utils/models';
|
|
2
|
+
/**
|
|
3
|
+
* Cấu hình tree-rows cho `<sd-table>` — render dòng con inline dưới dòng cha
|
|
4
|
+
* kèm expand/collapse.
|
|
5
|
+
*
|
|
6
|
+
* Đây là discriminated union theo `loadType`:
|
|
7
|
+
* - `'static'` ({@link TableOptionTreeStatic}) — children đã nằm sẵn trong data
|
|
8
|
+
* (embedded array tại `childrenKey`). Không gọi API khi bung.
|
|
9
|
+
* - `'lazy'` ({@link TableOptionTreeLazy}) — children nạp theo yêu cầu qua
|
|
10
|
+
* `onExpandChildren` khi người dùng bung dòng lần đầu.
|
|
11
|
+
*
|
|
12
|
+
* `loadType` là discriminant: TypeScript dựa vào nó để narrow union (vd chỉ
|
|
13
|
+
* `static` mới có `childrenKey`/`defaultExpanded`, chỉ `lazy` mới có
|
|
14
|
+
* `onExpandChildren`). Dùng type-guard `isLazyTree()` trong `tree.util.ts` để
|
|
15
|
+
* narrow an toàn thay vì truy cập field trực tiếp trên union.
|
|
16
|
+
*
|
|
17
|
+
* @example Static (children embedded)
|
|
18
|
+
* ```ts
|
|
19
|
+
* tree: { loadType: 'static', childrenKey: 'children', defaultExpanded: 1 }
|
|
20
|
+
* ```
|
|
21
|
+
* @example Lazy (nạp theo yêu cầu)
|
|
22
|
+
* ```ts
|
|
23
|
+
* tree: { loadType: 'lazy', onExpandChildren: row => api.getChildren(row.id) }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export type SdTableOptionTree<T = any> = TableOptionTreeStatic<T> | TableOptionTreeLazy<T>;
|
|
27
|
+
/**
|
|
28
|
+
* Tree với dữ liệu children **embedded** sẵn trong mỗi row.
|
|
29
|
+
*
|
|
30
|
+
* Table đọc mảng con tại `childrenKey` ngay trên object data; không có lời gọi
|
|
31
|
+
* bất đồng bộ nào khi bung dòng. Đây cũng là chế độ hỗ trợ **search ở cấp con**
|
|
32
|
+
* cho table `type: 'local'` (xem `tree.util.ts#subtreeMatches` /
|
|
33
|
+
* `filterMatchingChildren`): khi lọc, một nhánh được giữ lại nếu chính nó hoặc
|
|
34
|
+
* bất kỳ hậu duệ nào khớp từ khoá, và nhánh khớp sẽ tự bung.
|
|
35
|
+
*/
|
|
36
|
+
export interface TableOptionTreeStatic<T = any> {
|
|
37
|
+
/** Chế độ nạp children: dữ liệu đã embedded sẵn trong row. */
|
|
38
|
+
loadType: 'static';
|
|
39
|
+
/**
|
|
40
|
+
* Key trên object row chứa mảng children.
|
|
41
|
+
* Mặc định: `'children'`.
|
|
42
|
+
*/
|
|
43
|
+
childrenKey?: NestedKeyOf<T> | 'children';
|
|
44
|
+
/**
|
|
45
|
+
* Giới hạn độ sâu cây (level gốc = 0).
|
|
46
|
+
* `undefined` = không giới hạn.
|
|
47
|
+
*/
|
|
5
48
|
maxDepth?: number;
|
|
6
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Trạng thái bung mặc định khi load:
|
|
51
|
+
* - `false` — thu gọn hết (mặc định)
|
|
52
|
+
* - `true` — bung toàn bộ
|
|
53
|
+
* - `number N` — bung tới cấp `N` (row có `level < N` được bung)
|
|
54
|
+
*/
|
|
7
55
|
defaultExpanded?: boolean | number;
|
|
8
|
-
/**
|
|
9
|
-
|
|
10
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Số pixel thụt lề (indent) cho mỗi cấp sâu.
|
|
58
|
+
* Mặc định: `20`.
|
|
59
|
+
*/
|
|
60
|
+
indentSize?: number;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Tree với children **nạp lười (lazy)** theo yêu cầu.
|
|
64
|
+
*
|
|
65
|
+
* Khi người dùng bung một dòng lần đầu mà dòng đó chưa có children embedded,
|
|
66
|
+
* table gọi `onExpandChildren(row)` để nạp; kết quả được cache lại trên row
|
|
67
|
+
* (ghi vào key `'children'`) nên các lần bung sau không gọi lại.
|
|
68
|
+
*
|
|
69
|
+
* Lazy tree **không hỗ trợ** `childrenKey` tuỳ biến (luôn dùng `'children'` làm
|
|
70
|
+
* nơi lưu kết quả) và **không hỗ trợ** `defaultExpanded` (không thể bung mặc
|
|
71
|
+
* định nhánh chưa nạp).
|
|
72
|
+
*/
|
|
73
|
+
export interface TableOptionTreeLazy<T = any> {
|
|
74
|
+
/** Chế độ nạp children: nạp lười theo yêu cầu khi bung. */
|
|
75
|
+
loadType: 'lazy';
|
|
76
|
+
/**
|
|
77
|
+
* Giới hạn độ sâu cây (level gốc = 0).
|
|
78
|
+
* `undefined` = không giới hạn.
|
|
79
|
+
*/
|
|
80
|
+
maxDepth?: number;
|
|
81
|
+
/**
|
|
82
|
+
* Hàm nạp children khi bung dòng chưa có children embedded.
|
|
83
|
+
* Trả về `Promise<T[]>`; kết quả được ghi vào key `'children'` của row data
|
|
84
|
+
* và cache cho các lần bung sau.
|
|
85
|
+
*/
|
|
86
|
+
onExpandChildren: (rowData: T) => Promise<T[]>;
|
|
87
|
+
/**
|
|
88
|
+
* Xác định một row có con hay không — để quyết định có hiển thị icon expand.
|
|
89
|
+
* - Không truyền: MỌI lazy node đều hiện icon expand (không biết trước được).
|
|
90
|
+
* - Truyền: chỉ hiện icon khi trả `true`; trả `false` ⇒ row là lá (ẩn icon,
|
|
91
|
+
* không gọi `onExpandChildren`).
|
|
92
|
+
* Lưu ý: nếu row đã có children embedded sẵn thì luôn coi là có con (bỏ qua hàm này).
|
|
93
|
+
*/
|
|
94
|
+
hasChildren?: (rowData: T) => boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Số pixel thụt lề (indent) cho mỗi cấp sâu.
|
|
97
|
+
* Mặc định: `20`.
|
|
98
|
+
*/
|
|
11
99
|
indentSize?: number;
|
|
12
100
|
}
|
|
@@ -1,10 +1,51 @@
|
|
|
1
|
-
import { SdTableOptionTree } from '../../models/table-option-tree.model';
|
|
1
|
+
import { SdTableOptionTree, TableOptionTreeLazy } from '../../models/table-option-tree.model';
|
|
2
2
|
import { SdTableItem } from '../../models/table-item.model';
|
|
3
|
+
/**
|
|
4
|
+
* Type-guard: tree có nạp children lười (lazy) hay không.
|
|
5
|
+
* Dùng để narrow discriminated union `SdTableOptionTree` một cách an toàn —
|
|
6
|
+
* thay vì truy cập `option.onExpandChildren` trực tiếp trên union (chỉ tồn tại
|
|
7
|
+
* ở nhánh lazy).
|
|
8
|
+
*/
|
|
9
|
+
export declare const isLazyTree: <T = any>(option?: SdTableOptionTree<T>) => option is TableOptionTreeLazy<T>;
|
|
10
|
+
/**
|
|
11
|
+
* Key chứa mảng children trên object row.
|
|
12
|
+
* - `static`: lấy `childrenKey` đã cấu hình, mặc định `'children'`.
|
|
13
|
+
* - `lazy`: không có `childrenKey` riêng → luôn dùng `'children'` làm nơi lưu
|
|
14
|
+
* kết quả nạp lười.
|
|
15
|
+
*/
|
|
3
16
|
export declare const getChildrenKey: (option?: SdTableOptionTree) => string;
|
|
4
17
|
export declare const getChildrenFromData: <T>(data: T, option?: SdTableOptionTree) => T[];
|
|
18
|
+
/**
|
|
19
|
+
* Trạng thái bung mặc định cho một cấp.
|
|
20
|
+
* Chỉ `static` mới có `defaultExpanded`; lazy luôn trả `false` (không thể bung
|
|
21
|
+
* mặc định nhánh chưa nạp).
|
|
22
|
+
*/
|
|
5
23
|
export declare const resolveDefaultExpanded: (level: number, option?: SdTableOptionTree) => boolean;
|
|
6
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Row có khả năng có children hay không (để hiện nút bung).
|
|
26
|
+
* - Có children embedded → true.
|
|
27
|
+
* - Lazy tree: dùng `hasChildren(row.data)` nếu được cấu hình; không thì luôn
|
|
28
|
+
* true (chưa biết cho tới khi nạp).
|
|
29
|
+
*/
|
|
30
|
+
export declare const resolveHasChildren: <T>(row: SdTableItem<T>, option?: SdTableOptionTree<T>) => boolean;
|
|
31
|
+
/** Row cần nạp lười (lazy) khi bung: là lazy tree và chưa có children embedded. */
|
|
7
32
|
export declare const hasLazyChildren: <T>(row: SdTableItem<T>, option?: SdTableOptionTree) => boolean;
|
|
33
|
+
/**
|
|
34
|
+
* True nếu `data` HOẶC bất kỳ hậu duệ nào (theo `childrenKey`) thoả `predicate`.
|
|
35
|
+
*
|
|
36
|
+
* Dùng cho search ở cấp con (static tree, table `type: 'local'`): một nhánh
|
|
37
|
+
* gốc được giữ lại trong kết quả lọc nếu subtree của nó có ít nhất một node
|
|
38
|
+
* khớp từ khoá. `visited` chống đệ quy vô hạn khi data có circular reference.
|
|
39
|
+
*/
|
|
40
|
+
export declare const subtreeMatches: <T>(data: T, predicate: (data: T) => boolean, option?: SdTableOptionTree, visited?: Set<unknown>) => boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Lọc mảng children: chỉ giữ child có subtree khớp `predicate`.
|
|
43
|
+
*
|
|
44
|
+
* Trả về MẢNG MỚI nhưng GIỮ NGUYÊN object reference của từng child (không clone)
|
|
45
|
+
* — nhờ vậy `meta.id` (hash từ data) ổn định, selection / trạng thái bung không
|
|
46
|
+
* bị mất khi từ khoá search đổi. Đây là bước "prune" của tính năng search-con.
|
|
47
|
+
*/
|
|
48
|
+
export declare const filterMatchingChildren: <T>(children: T[], predicate: (data: T) => boolean, option?: SdTableOptionTree) => T[];
|
|
8
49
|
export declare const flattenTree: <T>(roots: SdTableItem<T>[], option?: SdTableOptionTree, visited?: Set<string>) => SdTableItem<T>[];
|
|
9
50
|
/** Thu thập mọi SdTableItem đã format trong cây (kể cả node đang collapse). */
|
|
10
51
|
export declare const collectFormattedTreeRows: <T>(roots: SdTableItem<T>[]) => SdTableItem<T>[];
|
|
@@ -13,7 +13,6 @@ import { SdTableColumn } from './models/table-column.model';
|
|
|
13
13
|
import { SdTableOption } from './models/table-option.model';
|
|
14
14
|
import { SdTableFilterRequest, TableFilterRegister } from './services/table-filter/table-filter.model';
|
|
15
15
|
import { CdkDrag, CdkDragDrop, CdkDropList } from '@angular/cdk/drag-drop';
|
|
16
|
-
import { SdBaseSecureComponent } from '@sdcorejs/angular/components/base';
|
|
17
16
|
import { SdQuickAction } from '@sdcorejs/angular/components/quick-action';
|
|
18
17
|
import { SdScrollDirective } from '@sdcorejs/angular/directives';
|
|
19
18
|
import { Operator } from '@sdcorejs/utils/models';
|
|
@@ -35,7 +34,7 @@ export declare class MatPaginatorIntlCro extends MatPaginatorIntl {
|
|
|
35
34
|
static ɵfac: i0.ɵɵFactoryDeclaration<MatPaginatorIntlCro, never>;
|
|
36
35
|
static ɵprov: i0.ɵɵInjectableDeclaration<MatPaginatorIntlCro>;
|
|
37
36
|
}
|
|
38
|
-
export declare class SdTable<T = unknown>
|
|
37
|
+
export declare class SdTable<T = unknown> implements OnInit, AfterViewInit, OnDestroy {
|
|
39
38
|
#private;
|
|
40
39
|
autoIdInput: import("@angular/core").InputSignal<string | null | undefined>;
|
|
41
40
|
autoId: import("@angular/core").Signal<string | undefined>;
|
|
@@ -11,6 +11,8 @@ export declare class SdUploadFile<TArgs = any> {
|
|
|
11
11
|
#private;
|
|
12
12
|
readonly id: string;
|
|
13
13
|
readonly formControl: SdFormControl;
|
|
14
|
+
/** Hiển thị message "vui lòng upload": không disabled + đã touched + còn lỗi required. */
|
|
15
|
+
readonly showRequiredError: import("@angular/core").Signal<boolean>;
|
|
14
16
|
readonly previewFiles: import("@angular/core").WritableSignal<PreviewFile[]>;
|
|
15
17
|
readonly selectedFile: import("@angular/core").WritableSignal<PreviewFile | null | undefined>;
|
|
16
18
|
readonly previewFileComponent: import("@angular/core").Signal<PreviewComponent | undefined>;
|
|
@@ -1,16 +1,49 @@
|
|
|
1
1
|
import { TemplateRef } from '@angular/core';
|
|
2
2
|
import * as i0 from "@angular/core";
|
|
3
|
+
/**
|
|
4
|
+
* `<sd-view>` — pure read-only display of a value (text, hyperlink, or a custom template).
|
|
5
|
+
*
|
|
6
|
+
* Presentational proxy with no state of its own: the parent form control (`<sd-select>`,
|
|
7
|
+
* `<sd-input>`, …) computes the display string + resolved selection and passes them in;
|
|
8
|
+
* `<sd-view>` only decides WHICH template renders. It is the single rendering path for every
|
|
9
|
+
* "viewed" state across the form controls (DETAIL `viewed=true` and the `viewed='inline'`
|
|
10
|
+
* text face), so a custom `valueTemplate` (e.g. `sdViewDef` / `#sdValue`) looks identical in
|
|
11
|
+
* both. OnPush — re-renders only when an input signal changes.
|
|
12
|
+
*/
|
|
3
13
|
export declare class SdView {
|
|
14
|
+
/** Optional label rendered above the value (omitted when a parent supplies its own label). */
|
|
4
15
|
label: import("@angular/core").InputSignal<string | null | undefined>;
|
|
16
|
+
/** Raw selected value — NOT rendered directly; only exposed in the `valueTemplate` context as `value`. */
|
|
5
17
|
value: import("@angular/core").InputSignal<any>;
|
|
18
|
+
/**
|
|
19
|
+
* Display string — what shows when no custom value template is bound.
|
|
20
|
+
* why: `input.required()` forces the parent to bind `[display]` (compile error otherwise),
|
|
21
|
+
* so the component never has to guess a fallback string from `value`.
|
|
22
|
+
*/
|
|
6
23
|
display: import("@angular/core").InputSignal<string | null | undefined>;
|
|
24
|
+
/** When set, the value renders as a link (`<a [sdHref]>`) instead of plain text. */
|
|
7
25
|
hyperlink: import("@angular/core").InputSignal<string | null | undefined>;
|
|
26
|
+
/** Label template handed down by a parent control (wins over `label` + `#sdLabel`). */
|
|
8
27
|
labelTemplate: import("@angular/core").InputSignal<TemplateRef<any> | undefined>;
|
|
28
|
+
/** Value template handed down by a parent control (wins over `display` + `#sdValue`). */
|
|
9
29
|
valueTemplate: import("@angular/core").InputSignal<TemplateRef<any> | undefined>;
|
|
30
|
+
/**
|
|
31
|
+
* Resolved selected-item objects passed by the parent (e.g. `<sd-select>`).
|
|
32
|
+
* why: the parent owns option/lazy resolution — `<sd-view>` is a proxy and must NOT rebuild
|
|
33
|
+
* the list. Exposed in the value-template context so a "head +N" template can read `displayField`.
|
|
34
|
+
*/
|
|
10
35
|
selectedItems: import("@angular/core").InputSignal<any[] | undefined>;
|
|
36
|
+
/** `#sdLabel` template projected directly into `<sd-view>` (fallback when no `[labelTemplate]`). */
|
|
11
37
|
contentLabelTemplate: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
38
|
+
/** `#sdValue` template projected directly into `<sd-view>` (fallback when no `[valueTemplate]`). */
|
|
12
39
|
contentValueTemplate: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
40
|
+
/**
|
|
41
|
+
* Effective label template: input from parent wins, else the projected `#sdLabel`.
|
|
42
|
+
* why: `computed` caches the choice so the template's `@if (activeLabelTemplate())` doesn't
|
|
43
|
+
* re-evaluate two content-child reads on every change-detection pass.
|
|
44
|
+
*/
|
|
13
45
|
activeLabelTemplate: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
46
|
+
/** Effective value template: input from parent wins, else the projected `#sdValue`. Cached for the same reason. */
|
|
14
47
|
activeValueTemplate: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
15
48
|
static ɵfac: i0.ɵɵFactoryDeclaration<SdView, never>;
|
|
16
49
|
static ɵcmp: i0.ɵɵComponentDeclaration<SdView, "sd-view", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "display": { "alias": "display"; "required": true; "isSignal": true; }; "hyperlink": { "alias": "hyperlink"; "required": false; "isSignal": true; }; "labelTemplate": { "alias": "labelTemplate"; "required": false; "isSignal": true; }; "valueTemplate": { "alias": "valueTemplate"; "required": false; "isSignal": true; }; "selectedItems": { "alias": "selectedItems"; "required": false; "isSignal": true; }; }, {}, ["contentLabelTemplate", "contentValueTemplate"], never, true, never>;
|