@simplysm/angular 14.0.56 → 14.0.58
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/dist/core/selection/useSelectionManager.d.ts +1 -1
- package/dist/core/selection/useSelectionManager.d.ts.map +1 -1
- package/dist/data/crud/sd-base-container.d.ts +3 -2
- package/dist/data/crud/sd-base-container.d.ts.map +1 -1
- package/dist/data/crud/sd-base-container.js +24 -13
- package/dist/data/crud/sd-crud-detail.d.ts +2 -1
- package/dist/data/crud/sd-crud-detail.d.ts.map +1 -1
- package/dist/data/crud/sd-crud-detail.js +87 -86
- package/dist/data/crud/sd-crud-list.d.ts +1 -1
- package/dist/data/crud/sd-crud-list.d.ts.map +1 -1
- package/dist/data/crud/sd-crud-list.js +154 -147
- package/dist/data/sheet/injectSheetSelectRowIndicator.d.ts +1 -1
- package/dist/data/sheet/injectSheetSelectRowIndicator.d.ts.map +1 -1
- package/dist/data/sheet/sd-sheet.d.ts +5 -5
- package/dist/data/sheet/sd-sheet.d.ts.map +1 -1
- package/dist/data/sheet/sd-sheet.js +10 -2
- package/package.json +5 -5
- package/src/core/selection/useSelectionManager.ts +2 -2
- package/src/data/crud/sd-base-container.ts +5 -2
- package/src/data/crud/sd-crud-detail.ts +13 -13
- package/src/data/crud/sd-crud-list.ts +53 -52
- package/src/data/sheet/injectSheetSelectRowIndicator.ts +1 -1
- package/src/data/sheet/sd-sheet.ts +18 -5
|
@@ -410,7 +410,7 @@ export class SdSheet {
|
|
|
410
410
|
// Inputs
|
|
411
411
|
key = input(...(ngDevMode ? [undefined, { debugName: "key" }] : /* istanbul ignore next */ []));
|
|
412
412
|
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
413
|
-
trackByFn = input
|
|
413
|
+
trackByFn = input((item) => item, ...(ngDevMode ? [{ debugName: "trackByFn" }] : /* istanbul ignore next */ []));
|
|
414
414
|
selectMode = input(...(ngDevMode ? [undefined, { debugName: "selectMode" }] : /* istanbul ignore next */ []));
|
|
415
415
|
autoSelect = input(...(ngDevMode ? [undefined, { debugName: "autoSelect" }] : /* istanbul ignore next */ []));
|
|
416
416
|
getItemSelectableFn = input(...(ngDevMode ? [undefined, { debugName: "getItemSelectableFn" }] : /* istanbul ignore next */ []));
|
|
@@ -649,6 +649,14 @@ export class SdSheet {
|
|
|
649
649
|
return;
|
|
650
650
|
event.preventDefault();
|
|
651
651
|
event.stopPropagation();
|
|
652
|
+
// SdCheckbox host의 (click) 자체 토글이 microtask로 적용한 범위 selection을 되돌리는 것을 방지
|
|
653
|
+
const checkboxEl = event.currentTarget;
|
|
654
|
+
if (checkboxEl instanceof HTMLElement) {
|
|
655
|
+
checkboxEl.addEventListener("click", (e) => {
|
|
656
|
+
e.preventDefault();
|
|
657
|
+
e.stopImmediatePropagation();
|
|
658
|
+
}, { once: true, capture: true });
|
|
659
|
+
}
|
|
652
660
|
const focusedEl = document.activeElement;
|
|
653
661
|
if (!(focusedEl instanceof HTMLElement))
|
|
654
662
|
return;
|
|
@@ -1053,5 +1061,5 @@ export class SdSheet {
|
|
|
1053
1061
|
<div class="_select-row-indicator-container"></div>
|
|
1054
1062
|
</div>
|
|
1055
1063
|
`, styles: ["sd-sheet {\n border: 1px solid var(--theme-gray-lighter);\n border-radius: var(--border-radius-default);\n}\nsd-sheet > ._tool {\n background: var(--control-color);\n border-top-left-radius: var(--border-radius-default);\n border-top-right-radius: var(--border-radius-default);\n border-bottom: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container {\n position: relative;\n background: var(--sheet-bg);\n border-bottom-left-radius: var(--border-radius-default);\n border-bottom-right-radius: var(--border-radius-default);\n overflow: auto;\n}\nsd-sheet > ._sheet-container > table {\n border-spacing: 0;\n table-layout: fixed;\n margin-right: 2px;\n margin-bottom: 2px;\n border-bottom-right-radius: var(--border-radius-default);\n}\nsd-sheet > ._sheet-container > table > * > tr > *:last-child {\n border-right: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container > table > * > tr:last-child > * {\n border-bottom: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container > table > *:last-child > tr:last-child > td:last-child {\n border-bottom-right-radius: var(--border-radius-default);\n overflow: hidden;\n}\nsd-sheet > ._sheet-container > table > * > tr > * {\n border-right: 1px solid var(--theme-gray-lighter);\n border-bottom: 1px solid var(--theme-gray-lighter);\n white-space: nowrap;\n overflow: hidden;\n padding: 0;\n position: relative;\n}\nsd-sheet > ._sheet-container > table > * > tr > *._fixed:has(+ :not(._fixed)) + :not(._fixed):not([data-c=\"0\"]) {\n border-left: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container > table > * > tr > *._feature-cell {\n background: var(--theme-gray-lightest);\n min-width: calc(var(--font-size-default) + 2px + var(--sheet-ph) * 2);\n padding: var(--sheet-pv) var(--sheet-ph);\n text-align: left;\n}\nsd-sheet > ._sheet-container > table > * > tr > *._feature-cell > ng-icon {\n cursor: pointer;\n color: var(--text-trans-lightest);\n}\nsd-sheet > ._sheet-container > table > * > tr > *._fixed {\n position: sticky;\n left: 0;\n}\nsd-sheet > ._sheet-container > table > * > tr > *._fixed:has(+ :not(._fixed)) {\n border-right: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container > table > thead {\n position: sticky;\n top: 0;\n z-index: 3;\n}\nsd-sheet > ._sheet-container > table > thead > tr > th {\n position: relative;\n background: var(--theme-gray-lightest);\n vertical-align: middle;\n}\nsd-sheet > ._sheet-container > table > thead > tr > th._fixed {\n z-index: 4;\n}\nsd-sheet > ._sheet-container > table > thead > tr > th._last-depth {\n border-bottom: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container > table > thead > tr > th._feature-cell {\n border-bottom: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container > table > thead > tr > th._sort {\n cursor: pointer;\n}\nsd-sheet > ._sheet-container > table > thead > tr > th._sort:hover {\n text-decoration: underline;\n}\nsd-sheet > ._sheet-container > table > thead > tr > th > ._headerContent > ._sort-icon {\n padding: var(--gap-xs) var(--gap-xs) var(--gap-xs) 0;\n background-color: var(--theme-gray-lightest);\n}\nsd-sheet > ._sheet-container > table > thead > tr > th > ._resizer {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 2px;\n cursor: ew-resize;\n}\nsd-sheet > ._sheet-container > table > thead:has(> tr._summary-row) > tr > th._last-depth {\n border-bottom: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container > table > thead:has(> tr._summary-row) > tr._summary-row > th {\n background: var(--theme-warning-lightest);\n text-align: left;\n border-bottom: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container > table > tbody > tr > td {\n background: var(--control-color);\n vertical-align: top;\n}\nsd-sheet > ._sheet-container > table > tbody > tr > td._fixed {\n z-index: 2;\n}\nsd-sheet > ._sheet-container > table > tbody > tr > td > ._depth-indicator {\n display: inline-block;\n margin-top: 0.4em;\n width: 0.5em;\n height: 0.5em;\n border-left: 1px solid var(--text-trans-default);\n border-bottom: 1px solid var(--text-trans-default);\n vertical-align: top;\n}\nsd-sheet > ._sheet-container > ._focus-row-indicator {\n display: none;\n position: absolute;\n pointer-events: none;\n background: rgba(158, 158, 158, 0.1);\n z-index: 6;\n}\nsd-sheet > ._sheet-container > ._focus-row-indicator > ._focus-cell-indicator {\n position: absolute;\n border: 2px solid var(--theme-primary-default);\n border-radius: var(--border-radius-default);\n}\nsd-sheet > ._sheet-container > ._resize-indicator {\n display: none;\n position: absolute;\n pointer-events: none;\n top: 0;\n height: 100%;\n border: 1px dotted var(--theme-gray-light);\n z-index: 7;\n}\nsd-sheet > ._sheet-container > ._select-row-indicator-container {\n display: none;\n position: absolute;\n pointer-events: none;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 5;\n}\nsd-sheet > ._sheet-container > ._select-row-indicator-container > ._select-row-indicator {\n display: block;\n left: 0;\n position: absolute;\n pointer-events: none;\n background: var(--theme-primary-default);\n opacity: 0.1;\n}\nsd-sheet ._p-sheet {\n padding: var(--sheet-pv) var(--sheet-ph);\n}\nsd-sheet[data-sd-focus-mode=row] > ._sheet-container > ._focus-row-indicator > ._focus-cell-indicator {\n display: none !important;\n}\nsd-sheet[data-sd-inset=true] {\n border: none;\n border-radius: 0;\n}"] }]
|
|
1056
|
-
}], null, { key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], trackByFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackByFn", required:
|
|
1064
|
+
}], null, { key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], trackByFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackByFn", required: false }] }], selectMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectMode", required: false }] }], autoSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoSelect", required: false }] }], getItemSelectableFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "getItemSelectableFn", required: false }] }], getChildrenFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "getChildrenFn", required: false }] }], useAutoSort: [{ type: i0.Input, args: [{ isSignal: true, alias: "useAutoSort", required: false }] }], visiblePageCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "visiblePageCount", required: false }] }], totalPageCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalPageCount", required: false }] }], itemsPerPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemsPerPage", required: false }] }], focusMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "focusMode", required: false }] }], inset: [{ type: i0.Input, args: [{ isSignal: true, alias: "inset", required: false }] }], contentStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentStyle", required: false }] }], getItemCellClassFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "getItemCellClassFn", required: false }] }], getItemCellStyleFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "getItemCellStyleFn", required: false }] }], hideConfigBar: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideConfigBar", required: false }] }], itemKeydown: [{ type: i0.Output, args: ["itemKeydown"] }], cellKeydown: [{ type: i0.Output, args: ["cellKeydown"] }], selectedKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedKeys", required: false }] }, { type: i0.Output, args: ["selectedKeysChange"] }], expandedItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedItems", required: false }] }, { type: i0.Output, args: ["expandedItemsChange"] }], sorts: [{ type: i0.Input, args: [{ isSignal: true, alias: "sorts", required: false }] }, { type: i0.Output, args: ["sortsChange"] }], currentPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentPage", required: false }] }, { type: i0.Output, args: ["currentPageChange"] }], columnControls: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SdSheetColumn), { isSignal: true }] }], columnControlsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnControlsInput", required: false }] }] }); })();
|
|
1057
1065
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SdSheet, { className: "SdSheet", filePath: "packages/angular/src/data/sheet/sd-sheet.ts", lineNumber: 585 }); })();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/angular",
|
|
3
|
-
"version": "14.0.
|
|
3
|
+
"version": "14.0.58",
|
|
4
4
|
"description": "심플리즘 패키지 - Angular",
|
|
5
5
|
"author": "심플리즘",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -50,10 +50,10 @@
|
|
|
50
50
|
"jspdf": "^4.2.1",
|
|
51
51
|
"rxjs": "^7.8.2",
|
|
52
52
|
"tabbable": "^6.4.0",
|
|
53
|
-
"@simplysm/core-
|
|
54
|
-
"@simplysm/core-
|
|
55
|
-
"@simplysm/service-
|
|
56
|
-
"@simplysm/service-
|
|
53
|
+
"@simplysm/core-common": "14.0.58",
|
|
54
|
+
"@simplysm/core-browser": "14.0.58",
|
|
55
|
+
"@simplysm/service-common": "14.0.58",
|
|
56
|
+
"@simplysm/service-client": "14.0.58"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@angular/compiler": "^21.2.10",
|
|
@@ -3,7 +3,7 @@ import { obj } from "@simplysm/core-common";
|
|
|
3
3
|
|
|
4
4
|
export function useSelectionManager<TItem, TKey>(options: {
|
|
5
5
|
displayItems: Signal<TItem[]>;
|
|
6
|
-
selectedKeys: WritableSignal<
|
|
6
|
+
selectedKeys: WritableSignal<TKey[]>;
|
|
7
7
|
selectMode: Signal<"single" | "multi" | undefined>;
|
|
8
8
|
getItemSelectableFn: Signal<((item: TItem) => boolean | string) | undefined>;
|
|
9
9
|
trackByFn: Signal<(item: TItem, index: number) => TKey>;
|
|
@@ -128,7 +128,7 @@ export function useSelectionManager<TItem, TKey>(options: {
|
|
|
128
128
|
options.selectedKeys.update((arr) => {
|
|
129
129
|
const newKeys = selectable
|
|
130
130
|
.map((it) => fn(it, idxMap.get(it) ?? 0))
|
|
131
|
-
.filter((k): k is
|
|
131
|
+
.filter((k): k is TKey => k != null)
|
|
132
132
|
.filter((k) => !arr.some((ek) => isKeyEqual(ek, k)));
|
|
133
133
|
return [...arr, ...newKeys];
|
|
134
134
|
});
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
inject,
|
|
7
7
|
input,
|
|
8
8
|
model,
|
|
9
|
-
TemplateRef,
|
|
9
|
+
type TemplateRef,
|
|
10
10
|
untracked,
|
|
11
11
|
ViewEncapsulation,
|
|
12
12
|
} from "@angular/core";
|
|
@@ -63,7 +63,9 @@ import { NgTemplateOutlet } from "@angular/common";
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
<div class="flex-fill">
|
|
66
|
-
|
|
66
|
+
@if (contentTplRef()) {
|
|
67
|
+
<ng-template [ngTemplateOutlet]="contentTplRef()" />
|
|
68
|
+
}
|
|
67
69
|
</div>
|
|
68
70
|
|
|
69
71
|
@if (bottomCommandTplRef()) {
|
|
@@ -91,6 +93,7 @@ export class SdBaseContainer {
|
|
|
91
93
|
|
|
92
94
|
topbarTplRef = contentChild<TemplateRef<void>>("topbarTpl");
|
|
93
95
|
commandTplRef = contentChild<TemplateRef<void>>("commandTpl");
|
|
96
|
+
contentTplRef = contentChild<TemplateRef<void>>("contentTpl");
|
|
94
97
|
bottomCommandTplRef = contentChild<TemplateRef<void>>("bottomCommandTpl");
|
|
95
98
|
|
|
96
99
|
constructor() {
|
|
@@ -82,19 +82,18 @@ import { tablerDeviceFloppy } from "@ng-icons/tabler-icons";
|
|
|
82
82
|
</ng-template>
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
</sd-form>
|
|
85
|
+
@if (contentTplRef()) {
|
|
86
|
+
<ng-template #contentTpl>
|
|
87
|
+
@if (readonly()) {
|
|
88
|
+
<div class="fill">
|
|
89
|
+
<ng-template [ngTemplateOutlet]="contentTplRef()" />
|
|
90
|
+
</div>
|
|
91
|
+
} @else {
|
|
92
|
+
<sd-form #formCtrl (formSubmit)="submit.emit()" class="block fill">
|
|
93
|
+
<ng-template [ngTemplateOutlet]="contentTplRef()" />
|
|
94
|
+
</sd-form>
|
|
95
|
+
}
|
|
96
|
+
</ng-template>
|
|
98
97
|
}
|
|
99
98
|
</sd-base-container>
|
|
100
99
|
`,
|
|
@@ -112,6 +111,7 @@ export class SdCrudDetail {
|
|
|
112
111
|
submit = output();
|
|
113
112
|
|
|
114
113
|
commandTplRef = contentChild<TemplateRef<void>>("commandTpl");
|
|
114
|
+
contentTplRef = contentChild<TemplateRef<void>>("contentTpl");
|
|
115
115
|
bottomCommandTplRef = contentChild<TemplateRef<void>>("bottomCommandTpl");
|
|
116
116
|
|
|
117
117
|
onSaveButtonClick() {
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
input,
|
|
9
9
|
model,
|
|
10
10
|
output,
|
|
11
|
-
TemplateRef,
|
|
11
|
+
type TemplateRef,
|
|
12
12
|
viewChild,
|
|
13
13
|
ViewEncapsulation,
|
|
14
14
|
} from "@angular/core";
|
|
@@ -115,68 +115,69 @@ import {
|
|
|
115
115
|
</ng-template>
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
118
|
+
<ng-template #contentTpl>
|
|
119
|
+
<div class="flex-column fill">
|
|
120
|
+
@if (filterTplRef()) {
|
|
121
|
+
<sd-form (formSubmit)="filterSubmit.emit()" class="block p-default">
|
|
122
|
+
<div class="form-box-inline">
|
|
123
|
+
<div>
|
|
124
|
+
<sd-button [type]="'submit'" [theme]="'info'">
|
|
125
|
+
<ng-icon [svg]="tablerSearch" />
|
|
126
|
+
조회
|
|
127
|
+
</sd-button>
|
|
128
|
+
</div>
|
|
129
|
+
<ng-template [ngTemplateOutlet]="filterTplRef()" />
|
|
128
130
|
</div>
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
</sd-form>
|
|
132
|
-
}
|
|
131
|
+
</sd-form>
|
|
132
|
+
}
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
</sd-button>
|
|
141
|
-
@if (selectMode() !== "single") {
|
|
142
|
-
<sd-button
|
|
143
|
-
[size]="'sm'"
|
|
144
|
-
[theme]="'link-danger'"
|
|
145
|
-
(click)="delete.emit(currSelectedItems())"
|
|
146
|
-
[disabled]="!hasSelectedNotDeleted()"
|
|
147
|
-
>
|
|
148
|
-
<ng-icon [svg]="tablerEraser" />
|
|
149
|
-
선택 삭제
|
|
134
|
+
@if (!readonly() || toolTplRef()) {
|
|
135
|
+
<div class="flex-row gap-sm p-xs-default">
|
|
136
|
+
@if (!readonly()) {
|
|
137
|
+
<sd-button [size]="'sm'" [theme]="'link-primary'" (click)="create.emit()">
|
|
138
|
+
<ng-icon [svg]="tablerCirclePlus" />
|
|
139
|
+
등록
|
|
150
140
|
</sd-button>
|
|
151
|
-
@if (
|
|
141
|
+
@if (selectMode() !== "single") {
|
|
152
142
|
<sd-button
|
|
153
143
|
[size]="'sm'"
|
|
154
|
-
[theme]="'link-
|
|
155
|
-
(click)="
|
|
144
|
+
[theme]="'link-danger'"
|
|
145
|
+
(click)="delete.emit(currSelectedItems())"
|
|
146
|
+
[disabled]="!hasSelectedNotDeleted()"
|
|
156
147
|
>
|
|
157
|
-
<ng-icon [svg]="
|
|
158
|
-
선택
|
|
148
|
+
<ng-icon [svg]="tablerEraser" />
|
|
149
|
+
선택 삭제
|
|
159
150
|
</sd-button>
|
|
151
|
+
@if (hasSelectedDeleted()) {
|
|
152
|
+
<sd-button
|
|
153
|
+
[size]="'sm'"
|
|
154
|
+
[theme]="'link-warning'"
|
|
155
|
+
(click)="restore.emit(currSelectedItems())"
|
|
156
|
+
>
|
|
157
|
+
<ng-icon [svg]="tablerRestore" />
|
|
158
|
+
선택 복구
|
|
159
|
+
</sd-button>
|
|
160
|
+
}
|
|
160
161
|
}
|
|
161
162
|
}
|
|
162
|
-
}
|
|
163
163
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
164
|
+
@if (toolTplRef()) {
|
|
165
|
+
<ng-template [ngTemplateOutlet]="toolTplRef()" />
|
|
166
|
+
}
|
|
167
|
+
</div>
|
|
168
|
+
}
|
|
169
169
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
170
|
+
@if (readonly()) {
|
|
171
|
+
<div class="flex-fill p-default pt-0">
|
|
172
|
+
<ng-template [ngTemplateOutlet]="sheet" />
|
|
173
|
+
</div>
|
|
174
|
+
} @else {
|
|
175
|
+
<sd-form #formCtrl (formSubmit)="submit.emit()" class="flex-fill p-default pt-0">
|
|
176
|
+
<ng-template [ngTemplateOutlet]="sheet" />
|
|
177
|
+
</sd-form>
|
|
178
|
+
}
|
|
179
|
+
</div>
|
|
180
|
+
</ng-template>
|
|
180
181
|
</sd-base-container>
|
|
181
182
|
|
|
182
183
|
<ng-template #sheet>
|
|
@@ -9,7 +9,7 @@ function isKeyEqual(a: unknown, b: unknown): boolean {
|
|
|
9
9
|
|
|
10
10
|
export function injectSheetSelectRowIndicator<TItem, TKey>(options: {
|
|
11
11
|
domAccessor: ReturnType<typeof injectSheetDomAccessor>;
|
|
12
|
-
selectedKeys: Signal<
|
|
12
|
+
selectedKeys: Signal<TKey[]>;
|
|
13
13
|
displayItems: Signal<TItem[]>;
|
|
14
14
|
trackByFn: Signal<(item: TItem, index: number) => TKey>;
|
|
15
15
|
}) {
|
|
@@ -582,11 +582,11 @@ import { SdEvents } from "../../core/events/sd-events";
|
|
|
582
582
|
`,
|
|
583
583
|
],
|
|
584
584
|
})
|
|
585
|
-
export class SdSheet<TItem
|
|
585
|
+
export class SdSheet<TItem> {
|
|
586
586
|
// Inputs
|
|
587
587
|
key = input<string>();
|
|
588
588
|
items = input<TItem[]>([]);
|
|
589
|
-
trackByFn = input
|
|
589
|
+
trackByFn = input<(item: TItem, index: number) => unknown>((item) => item);
|
|
590
590
|
selectMode = input<"single" | "multi">();
|
|
591
591
|
autoSelect = input<"click" | "focus">();
|
|
592
592
|
getItemSelectableFn = input<(item: TItem) => boolean | string>();
|
|
@@ -607,7 +607,7 @@ export class SdSheet<TItem, TKey> {
|
|
|
607
607
|
cellKeydown = output<SdSheetCellKeydownEventParam<TItem>>();
|
|
608
608
|
|
|
609
609
|
// Models
|
|
610
|
-
selectedKeys = model<
|
|
610
|
+
selectedKeys = model<unknown[]>([]);
|
|
611
611
|
expandedItems = model<TItem[]>([]);
|
|
612
612
|
sorts = model<SortingDef[]>([]); // Re-exported from useSortingManager
|
|
613
613
|
currentPage = model(0);
|
|
@@ -699,7 +699,7 @@ export class SdSheet<TItem, TKey> {
|
|
|
699
699
|
});
|
|
700
700
|
|
|
701
701
|
// Select row indicator
|
|
702
|
-
private readonly _selectRowIndicator = injectSheetSelectRowIndicator<TItem,
|
|
702
|
+
private readonly _selectRowIndicator = injectSheetSelectRowIndicator<TItem, unknown>({
|
|
703
703
|
domAccessor: this.domAccessor,
|
|
704
704
|
selectedKeys: this.selectedKeys,
|
|
705
705
|
displayItems: this.displayItems,
|
|
@@ -707,7 +707,7 @@ export class SdSheet<TItem, TKey> {
|
|
|
707
707
|
});
|
|
708
708
|
|
|
709
709
|
// Selection manager
|
|
710
|
-
selection = useSelectionManager<TItem,
|
|
710
|
+
selection = useSelectionManager<TItem, unknown>({
|
|
711
711
|
displayItems: this.displayItems,
|
|
712
712
|
selectedKeys: this.selectedKeys,
|
|
713
713
|
selectMode: this.selectMode,
|
|
@@ -856,6 +856,19 @@ export class SdSheet<TItem, TKey> {
|
|
|
856
856
|
event.preventDefault();
|
|
857
857
|
event.stopPropagation();
|
|
858
858
|
|
|
859
|
+
// SdCheckbox host의 (click) 자체 토글이 microtask로 적용한 범위 selection을 되돌리는 것을 방지
|
|
860
|
+
const checkboxEl = event.currentTarget;
|
|
861
|
+
if (checkboxEl instanceof HTMLElement) {
|
|
862
|
+
checkboxEl.addEventListener(
|
|
863
|
+
"click",
|
|
864
|
+
(e) => {
|
|
865
|
+
e.preventDefault();
|
|
866
|
+
e.stopImmediatePropagation();
|
|
867
|
+
},
|
|
868
|
+
{ once: true, capture: true },
|
|
869
|
+
);
|
|
870
|
+
}
|
|
871
|
+
|
|
859
872
|
const focusedEl = document.activeElement;
|
|
860
873
|
if (!(focusedEl instanceof HTMLElement)) return;
|
|
861
874
|
|