@simplysm/angular 14.0.46 → 14.0.48
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 +468 -0
- package/dist/controls/dropdown/sd-dropdown-popup.d.ts +1 -0
- package/dist/controls/dropdown/sd-dropdown-popup.d.ts.map +1 -1
- package/dist/controls/dropdown/sd-dropdown-popup.js +6 -1
- package/dist/controls/dropdown/sd-dropdown.d.ts.map +1 -1
- package/dist/controls/dropdown/sd-dropdown.js +6 -2
- package/dist/controls/select/sd-select.d.ts.map +1 -1
- package/dist/controls/select/sd-select.js +12 -34
- package/dist/core/routing/injectViewTypeSignal.d.ts +1 -1
- package/dist/core/routing/injectViewTypeSignal.d.ts.map +1 -1
- package/dist/core/routing/injectViewTypeSignal.js +15 -7
- package/dist/core/selection/useSelectionManager.d.ts +1 -0
- package/dist/core/selection/useSelectionManager.d.ts.map +1 -1
- package/dist/core/selection/useSelectionManager.js +54 -14
- package/dist/data/shared-data/sd-shared-data-select-button.d.ts +11 -5
- package/dist/data/shared-data/sd-shared-data-select-button.d.ts.map +1 -1
- package/dist/data/shared-data/sd-shared-data-select-button.js +68 -29
- package/dist/data/sheet/sd-sheet.d.ts +4 -1
- package/dist/data/sheet/sd-sheet.d.ts.map +1 -1
- package/dist/data/sheet/sd-sheet.js +23 -4
- package/dist/index.d.ts +0 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -17
- package/docs/bootstrap.md +38 -0
- package/docs/directives.md +236 -0
- package/docs/features.md +169 -0
- package/docs/pipes.md +32 -0
- package/docs/plugins.md +37 -0
- package/docs/provider-types.md +283 -0
- package/docs/providers.md +379 -0
- package/docs/recipes/crud-detail.md +860 -0
- package/docs/recipes/crud-list.md +779 -0
- package/docs/recipes/data-select-button.md +319 -0
- package/docs/recipes/page-modal-container.md +178 -0
- package/docs/styling.md +222 -0
- package/docs/type-utilities.md +250 -0
- package/docs/ui-data.md +333 -0
- package/docs/ui-form.md +502 -0
- package/docs/ui-layout.md +140 -0
- package/docs/ui-navigation.md +273 -0
- package/docs/ui-overlay.md +157 -0
- package/docs/ui-visual.md +127 -0
- package/docs/utils.md +244 -0
- package/package.json +27 -26
- package/src/controls/dropdown/sd-dropdown-popup.ts +6 -2
- package/src/controls/dropdown/sd-dropdown.ts +3 -4
- package/src/controls/select/sd-select.ts +6 -30
- package/src/core/routing/injectViewTypeSignal.ts +17 -10
- package/src/core/selection/useSelectionManager.ts +62 -12
- package/src/data/shared-data/sd-shared-data-select-button.ts +49 -14
- package/src/data/sheet/sd-sheet.ts +21 -0
- package/src/index.ts +0 -29
- package/dist/core/commons.d.ts +0 -2
- package/dist/core/commons.d.ts.map +0 -1
- package/dist/core/commons.js +0 -4
- package/dist/core/injectParent.d.ts +0 -7
- package/dist/core/injectParent.d.ts.map +0 -1
- package/dist/core/injectParent.js +0 -30
- package/dist/core/selection/setupCumulateSelectedKeys.d.ts +0 -9
- package/dist/core/selection/setupCumulateSelectedKeys.d.ts.map +0 -1
- package/dist/core/selection/setupCumulateSelectedKeys.js +0 -27
- package/dist/core/withBusy.d.ts +0 -3
- package/dist/core/withBusy.d.ts.map +0 -1
- package/dist/core/withBusy.js +0 -9
- package/dist/data/data-detail/sd-data-detail.base.d.ts +0 -51
- package/dist/data/data-detail/sd-data-detail.base.d.ts.map +0 -1
- package/dist/data/data-detail/sd-data-detail.base.js +0 -127
- package/dist/data/data-detail/sd-data-detail.d.ts +0 -30
- package/dist/data/data-detail/sd-data-detail.d.ts.map +0 -1
- package/dist/data/data-detail/sd-data-detail.js +0 -495
- package/dist/data/data-select-button/sd-data-select-button.base.d.ts +0 -24
- package/dist/data/data-select-button/sd-data-select-button.base.d.ts.map +0 -1
- package/dist/data/data-select-button/sd-data-select-button.base.js +0 -68
- package/dist/data/data-select-button/sd-data-select-button.d.ts +0 -15
- package/dist/data/data-select-button/sd-data-select-button.d.ts.map +0 -1
- package/dist/data/data-select-button/sd-data-select-button.js +0 -152
- package/dist/data/data-sheet/injectDataSheetExcelManager.d.ts +0 -14
- package/dist/data/data-sheet/injectDataSheetExcelManager.d.ts.map +0 -1
- package/dist/data/data-sheet/injectDataSheetExcelManager.js +0 -31
- package/dist/data/data-sheet/injectDataSheetInlineEditManager.d.ts +0 -26
- package/dist/data/data-sheet/injectDataSheetInlineEditManager.d.ts.map +0 -1
- package/dist/data/data-sheet/injectDataSheetInlineEditManager.js +0 -54
- package/dist/data/data-sheet/injectDataSheetModalEditManager.d.ts +0 -19
- package/dist/data/data-sheet/injectDataSheetModalEditManager.d.ts.map +0 -1
- package/dist/data/data-sheet/injectDataSheetModalEditManager.js +0 -44
- package/dist/data/data-sheet/injectDataSheetRefreshManager.d.ts +0 -25
- package/dist/data/data-sheet/injectDataSheetRefreshManager.d.ts.map +0 -1
- package/dist/data/data-sheet/injectDataSheetRefreshManager.js +0 -50
- package/dist/data/data-sheet/sd-data-sheet-column.d.ts +0 -8
- package/dist/data/data-sheet/sd-data-sheet-column.d.ts.map +0 -1
- package/dist/data/data-sheet/sd-data-sheet-column.js +0 -15
- package/dist/data/data-sheet/sd-data-sheet.base.d.ts +0 -75
- package/dist/data/data-sheet/sd-data-sheet.base.d.ts.map +0 -1
- package/dist/data/data-sheet/sd-data-sheet.base.js +0 -188
- package/dist/data/data-sheet/sd-data-sheet.d.ts +0 -49
- package/dist/data/data-sheet/sd-data-sheet.d.ts.map +0 -1
- package/dist/data/data-sheet/sd-data-sheet.js +0 -968
- package/dist/data/data-sheet/sd-data-sheet.types.d.ts +0 -17
- package/dist/data/data-sheet/sd-data-sheet.types.d.ts.map +0 -1
- package/dist/data/data-sheet/sd-data-sheet.types.js +0 -1
- package/dist/data/data-sheet/setupCloserWhenSingleSelectionChange.d.ts +0 -9
- package/dist/data/data-sheet/setupCloserWhenSingleSelectionChange.d.ts.map +0 -1
- package/dist/data/data-sheet/setupCloserWhenSingleSelectionChange.js +0 -20
- package/dist/data/data-sheet/useDataSheetFilterManager.d.ts +0 -13
- package/dist/data/data-sheet/useDataSheetFilterManager.d.ts.map +0 -1
- package/dist/data/data-sheet/useDataSheetFilterManager.js +0 -19
- package/dist/layout/base-container/sd-base-container.d.ts +0 -27
- package/dist/layout/base-container/sd-base-container.d.ts.map +0 -1
- package/dist/layout/base-container/sd-base-container.js +0 -193
- package/src/core/commons.ts +0 -4
- package/src/core/injectParent.ts +0 -45
- package/src/core/selection/setupCumulateSelectedKeys.ts +0 -38
- package/src/core/withBusy.ts +0 -13
- package/src/data/data-detail/sd-data-detail.base.ts +0 -187
- package/src/data/data-detail/sd-data-detail.ts +0 -237
- package/src/data/data-select-button/sd-data-select-button.base.ts +0 -104
- package/src/data/data-select-button/sd-data-select-button.ts +0 -105
- package/src/data/data-sheet/injectDataSheetExcelManager.ts +0 -57
- package/src/data/data-sheet/injectDataSheetInlineEditManager.ts +0 -89
- package/src/data/data-sheet/injectDataSheetModalEditManager.ts +0 -76
- package/src/data/data-sheet/injectDataSheetRefreshManager.ts +0 -90
- package/src/data/data-sheet/sd-data-sheet-column.ts +0 -10
- package/src/data/data-sheet/sd-data-sheet.base.ts +0 -294
- package/src/data/data-sheet/sd-data-sheet.ts +0 -479
- package/src/data/data-sheet/sd-data-sheet.types.ts +0 -18
- package/src/data/data-sheet/setupCloserWhenSingleSelectionChange.ts +0 -29
- package/src/data/data-sheet/useDataSheetFilterManager.ts +0 -30
- package/src/layout/base-container/sd-base-container.ts +0 -121
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { NgTemplateOutlet } from "@angular/common";
|
|
2
2
|
import {
|
|
3
|
+
booleanAttribute,
|
|
3
4
|
ChangeDetectionStrategy,
|
|
4
5
|
Component,
|
|
5
6
|
contentChild,
|
|
7
|
+
effect,
|
|
6
8
|
input,
|
|
9
|
+
model,
|
|
10
|
+
signal,
|
|
7
11
|
TemplateRef,
|
|
8
12
|
ViewEncapsulation,
|
|
9
13
|
} from "@angular/core";
|
|
@@ -12,11 +16,10 @@ import {
|
|
|
12
16
|
SdItemOfTemplate,
|
|
13
17
|
type SdItemOfTemplateContext,
|
|
14
18
|
} from "../../core/template/sd-item-of-template";
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
SdSelectModalInfo,
|
|
19
|
+
import {
|
|
20
|
+
SdModalSelectButton,
|
|
21
|
+
type SdSelectModal,
|
|
22
|
+
type SdSelectModalInfo,
|
|
20
23
|
} from "../../controls/button/sd-modal-select-button";
|
|
21
24
|
import type { SelectModeValue } from "../../controls/select/sd-select";
|
|
22
25
|
|
|
@@ -25,10 +28,22 @@ import type { SelectModeValue } from "../../controls/select/sd-select";
|
|
|
25
28
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
26
29
|
encapsulation: ViewEncapsulation.None,
|
|
27
30
|
standalone: true,
|
|
28
|
-
imports: [
|
|
31
|
+
imports: [SdModalSelectButton, NgTemplateOutlet],
|
|
29
32
|
template: `
|
|
30
|
-
<sd-
|
|
31
|
-
|
|
33
|
+
<sd-modal-select-button
|
|
34
|
+
[(value)]="value"
|
|
35
|
+
[(selectedItems)]="_selectedItems"
|
|
36
|
+
[modal]="modal()"
|
|
37
|
+
[disabled]="disabled()"
|
|
38
|
+
[required]="required()"
|
|
39
|
+
[inset]="inset()"
|
|
40
|
+
[size]="size()"
|
|
41
|
+
[selectMode]="selectMode()"
|
|
42
|
+
>
|
|
43
|
+
@for (item of _selectedItems(); track item; let index = $index) {
|
|
44
|
+
@if (index !== 0) {
|
|
45
|
+
<span>, </span>
|
|
46
|
+
}
|
|
32
47
|
<ng-template
|
|
33
48
|
[ngTemplateOutlet]="itemTplRef()"
|
|
34
49
|
[ngTemplateOutletContext]="{
|
|
@@ -38,25 +53,45 @@ import type { SelectModeValue } from "../../controls/select/sd-select";
|
|
|
38
53
|
depth: 0,
|
|
39
54
|
}"
|
|
40
55
|
/>
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
</sd-data-select-button>
|
|
56
|
+
}
|
|
57
|
+
</sd-modal-select-button>
|
|
44
58
|
`,
|
|
45
59
|
})
|
|
46
60
|
export class SdSharedDataSelectButton<
|
|
47
61
|
TItem extends SharedDataBase<string | number>,
|
|
48
62
|
TMode extends keyof SelectModeValue<string | number>,
|
|
49
63
|
TModal extends SdSelectModal<any>,
|
|
50
|
-
>
|
|
64
|
+
> {
|
|
65
|
+
value = model<SelectModeValue<string | number>[TMode]>();
|
|
51
66
|
items = input<TItem[]>([]);
|
|
52
67
|
modal = input.required<SdSelectModalInfo<TModal>>();
|
|
68
|
+
selectMode = input<TMode>("single" as TMode);
|
|
69
|
+
disabled = input(false, { transform: booleanAttribute });
|
|
70
|
+
required = input(false, { transform: booleanAttribute });
|
|
71
|
+
inset = input(false, { transform: booleanAttribute });
|
|
72
|
+
size = input<"sm" | "lg">();
|
|
53
73
|
|
|
54
74
|
itemTplRef = contentChild.required<any, TemplateRef<SdItemOfTemplateContext<TItem>>>(
|
|
55
75
|
SdItemOfTemplate,
|
|
56
76
|
{ read: TemplateRef },
|
|
57
77
|
);
|
|
58
78
|
|
|
59
|
-
|
|
60
|
-
|
|
79
|
+
protected readonly _selectedItems = signal<TItem[]>([]);
|
|
80
|
+
|
|
81
|
+
constructor() {
|
|
82
|
+
effect(() => {
|
|
83
|
+
const v = this.value();
|
|
84
|
+
const items = this.items();
|
|
85
|
+
const mode = this.selectMode();
|
|
86
|
+
|
|
87
|
+
if (mode === "multi" && Array.isArray(v) && v.filterExists().length > 0) {
|
|
88
|
+
const keys = v.filterExists() as (string | number)[];
|
|
89
|
+
this._selectedItems.set(items.filter((it) => keys.includes(it.__valueKey)));
|
|
90
|
+
} else if (mode === "single" && !Array.isArray(v) && v != null) {
|
|
91
|
+
this._selectedItems.set(items.filter((it) => it.__valueKey === v));
|
|
92
|
+
} else {
|
|
93
|
+
this._selectedItems.set([]);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
61
96
|
}
|
|
62
97
|
}
|
|
@@ -4,11 +4,13 @@ import {
|
|
|
4
4
|
Component,
|
|
5
5
|
computed,
|
|
6
6
|
contentChildren,
|
|
7
|
+
effect,
|
|
7
8
|
inject,
|
|
8
9
|
input,
|
|
9
10
|
model,
|
|
10
11
|
output,
|
|
11
12
|
signal,
|
|
13
|
+
untracked,
|
|
12
14
|
ViewEncapsulation,
|
|
13
15
|
} from "@angular/core";
|
|
14
16
|
import { NgTemplateOutlet } from "@angular/common";
|
|
@@ -578,6 +580,7 @@ export class SdSheet<T> {
|
|
|
578
580
|
getItemCellClassFn = input<(item: T, colKey: string) => string>();
|
|
579
581
|
getItemCellStyleFn = input<(item: T, colKey: string) => string | undefined>();
|
|
580
582
|
hideConfigBar = input(false, { transform: booleanAttribute });
|
|
583
|
+
cumulativeSelection = input(false, { transform: booleanAttribute });
|
|
581
584
|
|
|
582
585
|
// Outputs
|
|
583
586
|
itemKeydown = output<SdSheetItemKeydownEventParam<T>>();
|
|
@@ -696,6 +699,24 @@ export class SdSheet<T> {
|
|
|
696
699
|
selectedItems: this.selectedItems,
|
|
697
700
|
selectMode: this.selectMode,
|
|
698
701
|
getItemSelectableFn: this.getItemSelectableFn,
|
|
702
|
+
trackByFn: this.trackByFn,
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
// cumulativeSelection=false면 items 변경 시 selectedItems를 초기화한다.
|
|
706
|
+
// 첫 실행(초기 마운트)은 skip하여 소비자가 넘긴 초기 selectedItems 값을 보존한다.
|
|
707
|
+
private _resetOnItemsChangeSkipFirst = true;
|
|
708
|
+
private readonly _resetOnItemsChange = effect(() => {
|
|
709
|
+
this.items(); // track only items
|
|
710
|
+
if (this._resetOnItemsChangeSkipFirst) {
|
|
711
|
+
this._resetOnItemsChangeSkipFirst = false;
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
untracked(() => {
|
|
715
|
+
if (this.cumulativeSelection()) return;
|
|
716
|
+
if (this.selectedItems().length > 0) {
|
|
717
|
+
this.selectedItems.set([]);
|
|
718
|
+
}
|
|
719
|
+
});
|
|
699
720
|
});
|
|
700
721
|
|
|
701
722
|
// Icons
|
package/src/index.ts
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import "@simplysm/core-browser";
|
|
2
2
|
|
|
3
3
|
// core
|
|
4
|
-
export { TXT_CHANGE_IGNORE_CONFIRM } from "./core/commons";
|
|
5
4
|
export { provideSdAngular } from "./core/provideSdAngular";
|
|
6
5
|
export { setupBgTheme } from "./core/setupBgTheme";
|
|
7
6
|
export { setSafeStyle } from "./core/setSafeStyle";
|
|
8
7
|
export { setupModelHook } from "./core/setupModelHook";
|
|
9
|
-
export { injectParent } from "./core/injectParent";
|
|
10
|
-
export { withBusy } from "./core/withBusy";
|
|
11
8
|
export { mark } from "./core/mark";
|
|
12
9
|
export { FormatPipe } from "./core/format.pipe";
|
|
13
10
|
export type { SelectModalOutputResult } from "./core/select-modal-output-result";
|
|
@@ -96,7 +93,6 @@ export {
|
|
|
96
93
|
} from "./core/shared-data/sd-shared-data.provider";
|
|
97
94
|
|
|
98
95
|
// core/selection
|
|
99
|
-
export { setupCumulateSelectedKeys } from "./core/selection/setupCumulateSelectedKeys";
|
|
100
96
|
export {
|
|
101
97
|
useExpandingManager,
|
|
102
98
|
type ExpandItemDef,
|
|
@@ -199,9 +195,6 @@ export { SdPagination } from "./controls/pagination/sd-pagination";
|
|
|
199
195
|
export { SdDockContainer } from "./layout/dock/sd-dock-container";
|
|
200
196
|
export { SdDock } from "./layout/dock/sd-dock";
|
|
201
197
|
|
|
202
|
-
// layout/base-container
|
|
203
|
-
export { SdBaseContainer } from "./layout/base-container/sd-base-container";
|
|
204
|
-
|
|
205
198
|
// layout/sidebar
|
|
206
199
|
export { SdSidebarContainer } from "./layout/sidebar/sd-sidebar-container";
|
|
207
200
|
export { SdSidebar } from "./layout/sidebar/sd-sidebar";
|
|
@@ -233,31 +226,9 @@ export type {
|
|
|
233
226
|
SdSheetCellKeydownEventParam,
|
|
234
227
|
} from "./data/sheet/types";
|
|
235
228
|
|
|
236
|
-
// data/data-sheet
|
|
237
|
-
export { SdDataSheet } from "./data/data-sheet/sd-data-sheet";
|
|
238
|
-
export {
|
|
239
|
-
SdDataSheetBase,
|
|
240
|
-
type SdDataSheetItemPropInfo,
|
|
241
|
-
type SdDataSheetItemInfo,
|
|
242
|
-
type SdDataSheetSearchResult,
|
|
243
|
-
} from "./data/data-sheet/sd-data-sheet.base";
|
|
244
|
-
export { SdDataSheetColumn } from "./data/data-sheet/sd-data-sheet-column";
|
|
245
|
-
export { setupCloserWhenSingleSelectionChange } from "./data/data-sheet/setupCloserWhenSingleSelectionChange";
|
|
246
|
-
|
|
247
|
-
// data/data-detail
|
|
248
|
-
export { SdDataDetail } from "./data/data-detail/sd-data-detail";
|
|
249
|
-
export {
|
|
250
|
-
SdDataDetailBase,
|
|
251
|
-
type SdDataDetailDataInfo,
|
|
252
|
-
} from "./data/data-detail/sd-data-detail.base";
|
|
253
|
-
|
|
254
229
|
// data/utils
|
|
255
230
|
export { getOrmDataEditToastErrorMessage } from "./data/getOrmDataEditToastErrorMessage";
|
|
256
231
|
|
|
257
|
-
// data/data-select-button
|
|
258
|
-
export { SdDataSelectButton } from "./data/data-select-button/sd-data-select-button";
|
|
259
|
-
export { SdDataSelectButtonBase } from "./data/data-select-button/sd-data-select-button.base";
|
|
260
|
-
|
|
261
232
|
// data/shared-data
|
|
262
233
|
export { SdSharedDataSelect } from "./data/shared-data/sd-shared-data-select";
|
|
263
234
|
export { SdSharedDataSelectButton } from "./data/shared-data/sd-shared-data-select-button";
|
package/dist/core/commons.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"commons.d.ts","sourceRoot":"","sources":["../../src/core/commons.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,QAGC,CAAC"}
|
package/dist/core/commons.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { type AbstractType } from "@angular/core";
|
|
2
|
-
export declare function injectParent<T = object>(): T;
|
|
3
|
-
export declare function injectParent<T = object>(type: AbstractType<T>): T;
|
|
4
|
-
export declare function injectParent<T = object>(type: AbstractType<T>, options: {
|
|
5
|
-
optional: true;
|
|
6
|
-
}): T | undefined;
|
|
7
|
-
//# sourceMappingURL=injectParent.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"injectParent.d.ts","sourceRoot":"","sources":["../../src/core/injectParent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAsC,MAAM,eAAe,CAAC;AAEtF,wBAAgB,YAAY,CAAC,CAAC,GAAG,MAAM,KAAK,CAAC,CAAC;AAC9C,wBAAgB,YAAY,CAAC,CAAC,GAAG,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AACnE,wBAAgB,YAAY,CAAC,CAAC,GAAG,MAAM,EACrC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,EACrB,OAAO,EAAE;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAE,GAC1B,CAAC,GAAG,SAAS,CAAC"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { inject, Injector, ViewContainerRef } from "@angular/core";
|
|
2
|
-
export function injectParent(type, options) {
|
|
3
|
-
let currentInjector = inject(ViewContainerRef).injector;
|
|
4
|
-
while (currentInjector != null) {
|
|
5
|
-
// Angular internal: NodeInjector._lView[CONTEXT=8]에 컴포넌트 인스턴스 저장
|
|
6
|
-
const lView = currentInjector._lView;
|
|
7
|
-
if (lView == null) {
|
|
8
|
-
break;
|
|
9
|
-
}
|
|
10
|
-
const comp = lView[8];
|
|
11
|
-
// 컴포넌트 인스턴스 검증: null, primitive, plain object({})는 건너뜀
|
|
12
|
-
// Angular 내부 슬롯 변경 시 잘못된 객체 반환을 방지하는 방어 코드
|
|
13
|
-
if (comp != null && typeof comp === "object" && comp.constructor !== Object) {
|
|
14
|
-
if (type == null) {
|
|
15
|
-
return comp;
|
|
16
|
-
}
|
|
17
|
-
if (comp instanceof type) {
|
|
18
|
-
return comp;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
currentInjector = currentInjector.get(Injector, undefined, {
|
|
22
|
-
skipSelf: true,
|
|
23
|
-
optional: true,
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
if (options?.optional) {
|
|
27
|
-
return undefined;
|
|
28
|
-
}
|
|
29
|
-
throw new Error("부모 컴포넌트를 찾을 수 없습니다.");
|
|
30
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type Signal, type WritableSignal } from "@angular/core";
|
|
2
|
-
export declare function setupCumulateSelectedKeys<TItem, TKey>(options: {
|
|
3
|
-
items: Signal<TItem[]>;
|
|
4
|
-
selectedItems: WritableSignal<TItem[]>;
|
|
5
|
-
selectedItemKeys: WritableSignal<TKey[]>;
|
|
6
|
-
selectMode: () => "single" | "multi" | undefined;
|
|
7
|
-
keySelectorFn: (item: TItem) => TKey | undefined;
|
|
8
|
-
}): void;
|
|
9
|
-
//# sourceMappingURL=setupCumulateSelectedKeys.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"setupCumulateSelectedKeys.d.ts","sourceRoot":"","sources":["../../../src/core/selection/setupCumulateSelectedKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,cAAc,EAAqB,MAAM,eAAe,CAAC;AAEpF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE;IAC9D,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IACvB,aAAa,EAAE,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC;IACvC,gBAAgB,EAAE,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,UAAU,EAAE,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IACjD,aAAa,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,GAAG,SAAS,CAAC;CAClD,GAAG,IAAI,CA6BP"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { effect, untracked } from "@angular/core";
|
|
2
|
-
export function setupCumulateSelectedKeys(options) {
|
|
3
|
-
// items 변경 시 selectedItems에서 현재 items에 존재하지 않는 항목 제거
|
|
4
|
-
// selectedItems는 untracked로 읽어 effect 재실행 방지
|
|
5
|
-
effect(() => {
|
|
6
|
-
const items = options.items();
|
|
7
|
-
const selectedItems = untracked(() => options.selectedItems());
|
|
8
|
-
if (selectedItems.length === 0)
|
|
9
|
-
return;
|
|
10
|
-
const itemKeySet = new Set(items.map((item) => options.keySelectorFn(item)).filter((k) => k != null));
|
|
11
|
-
const filtered = selectedItems.filter((item) => {
|
|
12
|
-
const key = options.keySelectorFn(item);
|
|
13
|
-
return key != null && itemKeySet.has(key);
|
|
14
|
-
});
|
|
15
|
-
if (filtered.length !== selectedItems.length) {
|
|
16
|
-
options.selectedItems.set(filtered);
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
// selectedItems 변경 시 selectedItemKeys 갱신
|
|
20
|
-
effect(() => {
|
|
21
|
-
const selectedItems = options.selectedItems();
|
|
22
|
-
const keys = selectedItems
|
|
23
|
-
.map((item) => options.keySelectorFn(item))
|
|
24
|
-
.filter((k) => k != null);
|
|
25
|
-
options.selectedItemKeys.set(keys);
|
|
26
|
-
});
|
|
27
|
-
}
|
package/dist/core/withBusy.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"withBusy.d.ts","sourceRoot":"","sources":["../../src/core/withBusy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,wBAAsB,QAAQ,CAC5B,SAAS,EAAE,cAAc,CAAC,MAAM,CAAC,EACjC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GACtB,OAAO,CAAC,IAAI,CAAC,CAOf"}
|
package/dist/core/withBusy.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { ErrorHandler, type Signal, TemplateRef } from "@angular/core";
|
|
2
|
-
import { DateTime } from "@simplysm/core-common";
|
|
3
|
-
import { SdSharedDataProvider } from "../../core/shared-data/sd-shared-data.provider";
|
|
4
|
-
import { type SdModalContentDef } from "../../core/modal/sd-modal.provider";
|
|
5
|
-
import { SdToastProvider } from "../../core/toast/sd-toast.provider";
|
|
6
|
-
import * as i0 from "@angular/core";
|
|
7
|
-
export interface SdDataDetailDataInfo {
|
|
8
|
-
isNew: boolean;
|
|
9
|
-
isDeleted: boolean;
|
|
10
|
-
lastModifiedAt: DateTime | undefined;
|
|
11
|
-
lastModifiedBy: string | undefined;
|
|
12
|
-
}
|
|
13
|
-
export declare abstract class SdDataDetailBase<T extends object, R = boolean> implements SdModalContentDef<R> {
|
|
14
|
-
abstract canUse: Signal<boolean>;
|
|
15
|
-
abstract canEdit: Signal<boolean>;
|
|
16
|
-
canDelete?: Signal<boolean>;
|
|
17
|
-
prepareRefreshEffect?(): void;
|
|
18
|
-
abstract load(): Promise<{
|
|
19
|
-
data: T;
|
|
20
|
-
info: SdDataDetailDataInfo;
|
|
21
|
-
}> | {
|
|
22
|
-
data: T;
|
|
23
|
-
info: SdDataDetailDataInfo;
|
|
24
|
-
};
|
|
25
|
-
toggleDelete?(del: boolean): Promise<R | undefined> | R | undefined;
|
|
26
|
-
submit?(data: T): Promise<R | undefined> | R | undefined;
|
|
27
|
-
protected readonly _sdToast: SdToastProvider;
|
|
28
|
-
protected readonly _sdSharedData: SdSharedDataProvider<Record<string, import("../..").SharedDataBase<string | number>>>;
|
|
29
|
-
protected readonly _errorHandler: ErrorHandler;
|
|
30
|
-
viewType: Signal<import("../..").SdViewType>;
|
|
31
|
-
busyCount: import("@angular/core").WritableSignal<number>;
|
|
32
|
-
busyMessage: import("@angular/core").WritableSignal<string | undefined>;
|
|
33
|
-
initialized: import("@angular/core").WritableSignal<boolean>;
|
|
34
|
-
close: import("@angular/core").OutputEmitterRef<R>;
|
|
35
|
-
actionTplRef?: TemplateRef<any>;
|
|
36
|
-
data: import("@angular/core").WritableSignal<T>;
|
|
37
|
-
dataInfo: import("@angular/core").WritableSignal<SdDataDetailDataInfo | undefined>;
|
|
38
|
-
private _dataSnapshot?;
|
|
39
|
-
constructor();
|
|
40
|
-
checkIgnoreChanges(): boolean;
|
|
41
|
-
doRefresh(): Promise<void>;
|
|
42
|
-
refresh(): Promise<void>;
|
|
43
|
-
doToggleDelete(del: boolean): Promise<void>;
|
|
44
|
-
doSubmit(opt?: {
|
|
45
|
-
permCheck?: boolean;
|
|
46
|
-
hideNoChangeMessage?: boolean;
|
|
47
|
-
}): Promise<void>;
|
|
48
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<SdDataDetailBase<any, any>, never>;
|
|
49
|
-
static ɵdir: i0.ɵɵDirectiveDeclaration<SdDataDetailBase<any, any>, never, never, {}, { "close": "close"; }, never, never, true, never>;
|
|
50
|
-
}
|
|
51
|
-
//# sourceMappingURL=sd-data-detail.base.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sd-data-detail.base.d.ts","sourceRoot":"","sources":["../../../src/data/data-detail/sd-data-detail.base.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EAIZ,KAAK,MAAM,EACX,WAAW,EACZ,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAO,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gDAAgD,CAAC;AAItF,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;;AAGrE,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,QAAQ,GAAG,SAAS,CAAC;IACrC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED,8BACsB,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,GAAG,OAAO,CAClE,YAAW,iBAAiB,CAAC,CAAC,CAAC;IAI/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAE5B,oBAAoB,CAAC,IAAI,IAAI;IAE7B,QAAQ,CAAC,IAAI,IACT,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAC;QAAC,IAAI,EAAE,oBAAoB,CAAA;KAAE,CAAC,GAChD;QAAE,IAAI,EAAE,CAAC,CAAC;QAAC,IAAI,EAAE,oBAAoB,CAAA;KAAE;IAE3C,YAAY,CAAC,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,SAAS;IAEnE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,SAAS;IAIxD,SAAS,CAAC,QAAQ,CAAC,QAAQ,kBAA2B;IACtD,SAAS,CAAC,QAAQ,CAAC,aAAa,wFAAgC;IAChE,SAAS,CAAC,QAAQ,CAAC,aAAa,eAAwB;IAExD,QAAQ,qCAAoC;IAE5C,SAAS,iDAAa;IACtB,WAAW,6DAAyC;IACpD,WAAW,kDAAiB;IAC5B,KAAK,8CAAe;IACpB,YAAY,CAAC,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC;IAEhC,IAAI,4CAAsB;IAE1B,QAAQ,2EAAuD;IAE/D,OAAO,CAAC,aAAa,CAAC,CAAI;;IAoC1B,kBAAkB;IAQZ,SAAS;IAYT,OAAO;IASP,cAAc,CAAC,GAAG,EAAE,OAAO;IAqB3B,QAAQ,CAAC,GAAG,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,mBAAmB,CAAC,EAAE,OAAO,CAAA;KAAE;yCA3HvD,gBAAgB;2CAAhB,gBAAgB;CA8JrC"}
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import { Directive, effect, ErrorHandler, inject, output, signal, TemplateRef, } from "@angular/core";
|
|
2
|
-
import { DateTime, obj } from "@simplysm/core-common";
|
|
3
|
-
import { TXT_CHANGE_IGNORE_CONFIRM } from "../../core/commons";
|
|
4
|
-
import { SdSharedDataProvider } from "../../core/shared-data/sd-shared-data.provider";
|
|
5
|
-
import { setupCanDeactivate } from "../../core/routing/setupCanDeactivate";
|
|
6
|
-
import { injectViewTypeSignal } from "../../core/routing/injectViewTypeSignal";
|
|
7
|
-
import { withBusy } from "../../core/withBusy";
|
|
8
|
-
import {} from "../../core/modal/sd-modal.provider";
|
|
9
|
-
import { SdToastProvider } from "../../core/toast/sd-toast.provider";
|
|
10
|
-
import { getOrmDataEditToastErrorMessage } from "../getOrmDataEditToastErrorMessage";
|
|
11
|
-
import * as i0 from "@angular/core";
|
|
12
|
-
export class SdDataDetailBase {
|
|
13
|
-
canDelete;
|
|
14
|
-
//-- implement
|
|
15
|
-
_sdToast = inject(SdToastProvider);
|
|
16
|
-
_sdSharedData = inject(SdSharedDataProvider);
|
|
17
|
-
_errorHandler = inject(ErrorHandler);
|
|
18
|
-
viewType = injectViewTypeSignal(() => this);
|
|
19
|
-
busyCount = signal(0, ...(ngDevMode ? [{ debugName: "busyCount" }] : /* istanbul ignore next */ []));
|
|
20
|
-
busyMessage = signal(undefined, ...(ngDevMode ? [{ debugName: "busyMessage" }] : /* istanbul ignore next */ []));
|
|
21
|
-
initialized = signal(false, ...(ngDevMode ? [{ debugName: "initialized" }] : /* istanbul ignore next */ []));
|
|
22
|
-
close = output();
|
|
23
|
-
actionTplRef;
|
|
24
|
-
data = signal({}, ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
25
|
-
dataInfo = signal(undefined, ...(ngDevMode ? [{ debugName: "dataInfo" }] : /* istanbul ignore next */ []));
|
|
26
|
-
_dataSnapshot;
|
|
27
|
-
constructor() {
|
|
28
|
-
effect((onCleanup) => {
|
|
29
|
-
this.prepareRefreshEffect?.();
|
|
30
|
-
let cancelled = false;
|
|
31
|
-
onCleanup(() => {
|
|
32
|
-
cancelled = true;
|
|
33
|
-
});
|
|
34
|
-
queueMicrotask(async () => {
|
|
35
|
-
try {
|
|
36
|
-
if (cancelled)
|
|
37
|
-
return;
|
|
38
|
-
if (!this.canUse()) {
|
|
39
|
-
this.initialized.set(true);
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
await withBusy(this.busyCount, () => this._sdToast.try(async () => {
|
|
43
|
-
await this._sdSharedData.wait();
|
|
44
|
-
await this.refresh();
|
|
45
|
-
}));
|
|
46
|
-
this.initialized.set(true);
|
|
47
|
-
}
|
|
48
|
-
catch (err) {
|
|
49
|
-
this._errorHandler.handleError(err);
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
setupCanDeactivate(() => this.viewType() === "modal" || this.checkIgnoreChanges());
|
|
54
|
-
}
|
|
55
|
-
checkIgnoreChanges() {
|
|
56
|
-
return (this._dataSnapshot == null ||
|
|
57
|
-
obj.equal(this.data(), this._dataSnapshot) ||
|
|
58
|
-
confirm(TXT_CHANGE_IGNORE_CONFIRM));
|
|
59
|
-
}
|
|
60
|
-
async doRefresh() {
|
|
61
|
-
if (this.busyCount() > 0)
|
|
62
|
-
return;
|
|
63
|
-
if (!this.canUse())
|
|
64
|
-
return;
|
|
65
|
-
if (!this.checkIgnoreChanges())
|
|
66
|
-
return;
|
|
67
|
-
await withBusy(this.busyCount, () => this._sdToast.try(async () => {
|
|
68
|
-
await this.refresh();
|
|
69
|
-
}));
|
|
70
|
-
}
|
|
71
|
-
async refresh() {
|
|
72
|
-
const result = await this.load();
|
|
73
|
-
this.data.set(result.data);
|
|
74
|
-
this.dataInfo.set(result.info);
|
|
75
|
-
if (!result.info.isNew) {
|
|
76
|
-
this._dataSnapshot = obj.clone(result.data);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
async doToggleDelete(del) {
|
|
80
|
-
if (this.busyCount() > 0)
|
|
81
|
-
return;
|
|
82
|
-
if (!this.canEdit())
|
|
83
|
-
return;
|
|
84
|
-
if (this.canDelete && !this.canDelete())
|
|
85
|
-
return;
|
|
86
|
-
if (!this.toggleDelete)
|
|
87
|
-
return;
|
|
88
|
-
await withBusy(this.busyCount, () => this._sdToast.try(async () => {
|
|
89
|
-
const result = await this.toggleDelete(del);
|
|
90
|
-
if (!result)
|
|
91
|
-
return;
|
|
92
|
-
this._sdToast.success(`${del ? "삭제" : "복구"}되었습니다.`);
|
|
93
|
-
this.close.emit(result);
|
|
94
|
-
}, (err) => getOrmDataEditToastErrorMessage(err)));
|
|
95
|
-
}
|
|
96
|
-
async doSubmit(opt) {
|
|
97
|
-
if (this.busyCount() > 0)
|
|
98
|
-
return;
|
|
99
|
-
if (opt?.permCheck && !this.canEdit())
|
|
100
|
-
return;
|
|
101
|
-
if (!this.submit)
|
|
102
|
-
return;
|
|
103
|
-
const dataInfo = this.dataInfo();
|
|
104
|
-
if (dataInfo == null)
|
|
105
|
-
return;
|
|
106
|
-
if (!dataInfo.isNew &&
|
|
107
|
-
(this._dataSnapshot == null || obj.equal(this.data(), this._dataSnapshot))) {
|
|
108
|
-
if (!opt?.hideNoChangeMessage) {
|
|
109
|
-
this._sdToast.info("변경사항이 없습니다.");
|
|
110
|
-
}
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
await withBusy(this.busyCount, () => this._sdToast.try(async () => {
|
|
114
|
-
const result = await this.submit(this.data());
|
|
115
|
-
if (!result)
|
|
116
|
-
return;
|
|
117
|
-
this._sdToast.success("저장되었습니다.");
|
|
118
|
-
this.close.emit(result);
|
|
119
|
-
await this.refresh();
|
|
120
|
-
}, (err) => getOrmDataEditToastErrorMessage(err)));
|
|
121
|
-
}
|
|
122
|
-
static ɵfac = function SdDataDetailBase_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SdDataDetailBase)(); };
|
|
123
|
-
static ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: SdDataDetailBase, outputs: { close: "close" } });
|
|
124
|
-
}
|
|
125
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SdDataDetailBase, [{
|
|
126
|
-
type: Directive
|
|
127
|
-
}], () => [], { close: [{ type: i0.Output, args: ["close"] }] }); })();
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { TemplateRef } from "@angular/core";
|
|
2
|
-
import { SdForm } from "../../controls/form/sd-form";
|
|
3
|
-
import { SdDataDetailBase } from "./sd-data-detail.base";
|
|
4
|
-
import * as i0 from "@angular/core";
|
|
5
|
-
import * as i1 from "../../core/commands/sd-command";
|
|
6
|
-
export type { SdDataDetailDataInfo } from "./sd-data-detail.base";
|
|
7
|
-
export declare class SdDataDetail {
|
|
8
|
-
parent: SdDataDetailBase<any, boolean>;
|
|
9
|
-
formCtrl: import("@angular/core").Signal<SdForm | undefined>;
|
|
10
|
-
toolTplRef: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
11
|
-
prevTplRef: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
12
|
-
contentTplRef: import("@angular/core").Signal<TemplateRef<any>>;
|
|
13
|
-
nextTplRef: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
14
|
-
modalActionTplRef: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
15
|
-
constructor();
|
|
16
|
-
onRefreshButtonClick(): Promise<void>;
|
|
17
|
-
onDeleteButtonClick(): Promise<void>;
|
|
18
|
-
onRestoreButtonClick(): Promise<void>;
|
|
19
|
-
onSubmitButtonClick(): void;
|
|
20
|
-
onSubmit(): Promise<void>;
|
|
21
|
-
protected readonly icons: {
|
|
22
|
-
tablerDeviceFloppy: string;
|
|
23
|
-
tablerRefresh: string;
|
|
24
|
-
tablerRestore: string;
|
|
25
|
-
tablerEraser: string;
|
|
26
|
-
};
|
|
27
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<SdDataDetail, never>;
|
|
28
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<SdDataDetail, "sd-data-detail", never, {}, {}, ["toolTplRef", "prevTplRef", "contentTplRef", "nextTplRef"], never, true, [{ directive: typeof i1.SdCommandDirective; inputs: {}; outputs: { "sdRefreshCommand": "sdRefreshCommand"; "sdSaveCommand": "sdSaveCommand"; }; }]>;
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=sd-data-detail.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sd-data-detail.d.ts","sourceRoot":"","sources":["../../../src/data/data-detail/sd-data-detail.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,WAAW,EAGZ,MAAM,eAAe,CAAC;AAKvB,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AASrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;;;AAGzD,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAIlE,qBAgKa,YAAY;IACvB,MAAM,iCAAyC;IAE/C,QAAQ,qDAAiC;IAEzC,UAAU,+DAAkD;IAC5D,UAAU,+DAAkD;IAC5D,aAAa,mDAA8D;IAC3E,UAAU,+DAAkD;IAE5D,iBAAiB,+DAAsD;;IAQjE,oBAAoB;IAIpB,mBAAmB;IAInB,oBAAoB;IAI1B,mBAAmB;IAIb,QAAQ;IAId,SAAS,CAAC,QAAQ,CAAC,KAAK;;;;;MAKtB;yCA3CS,YAAY;2CAAZ,YAAY;CA4CxB"}
|