@simplysm/angular 14.0.53 → 14.0.54

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.
Files changed (51) hide show
  1. package/dist/controls/button/sd-modal-select-button.d.ts +9 -10
  2. package/dist/controls/button/sd-modal-select-button.d.ts.map +1 -1
  3. package/dist/controls/button/sd-modal-select-button.js +4 -7
  4. package/dist/core/select-modal-output-result.d.ts +2 -3
  5. package/dist/core/select-modal-output-result.d.ts.map +1 -1
  6. package/dist/core/selection/useSelectionManager.d.ts +11 -11
  7. package/dist/core/selection/useSelectionManager.d.ts.map +1 -1
  8. package/dist/core/selection/useSelectionManager.js +29 -28
  9. package/dist/data/crud/sd-base-container.d.ts +21 -0
  10. package/dist/data/crud/sd-base-container.d.ts.map +1 -0
  11. package/dist/data/crud/sd-base-container.js +200 -0
  12. package/dist/data/crud/sd-crud-detail.d.ts +22 -0
  13. package/dist/data/crud/sd-crud-detail.d.ts.map +1 -0
  14. package/dist/data/crud/sd-crud-detail.js +267 -0
  15. package/dist/data/crud/sd-crud-list.d.ts +54 -0
  16. package/dist/data/crud/sd-crud-list.d.ts.map +1 -0
  17. package/dist/data/crud/sd-crud-list.js +592 -0
  18. package/dist/data/shared-data/sd-shared-data-select-button.d.ts.map +1 -1
  19. package/dist/data/shared-data/sd-shared-data-select-button.js +4 -5
  20. package/dist/data/shared-data/sd-shared-data-select-list.js +2 -2
  21. package/dist/data/shared-data/sd-shared-data-select.js +3 -3
  22. package/dist/data/sheet/injectSheetSelectRowIndicator.d.ts +4 -3
  23. package/dist/data/sheet/injectSheetSelectRowIndicator.d.ts.map +1 -1
  24. package/dist/data/sheet/injectSheetSelectRowIndicator.js +12 -4
  25. package/dist/data/sheet/sd-sheet.d.ts +39 -39
  26. package/dist/data/sheet/sd-sheet.d.ts.map +1 -1
  27. package/dist/data/sheet/sd-sheet.js +96 -74
  28. package/dist/data/sheet/types.d.ts +1 -0
  29. package/dist/data/sheet/types.d.ts.map +1 -1
  30. package/dist/data/sheet/useSheetLayoutEngine.d.ts.map +1 -1
  31. package/dist/data/sheet/useSheetLayoutEngine.js +3 -1
  32. package/dist/index.d.ts +3 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +4 -0
  35. package/dist/styles.css +2 -2
  36. package/package.json +13 -13
  37. package/scss/commons/_variables.scss +2 -2
  38. package/src/controls/button/sd-modal-select-button.ts +9 -13
  39. package/src/core/select-modal-output-result.ts +2 -3
  40. package/src/core/selection/useSelectionManager.ts +47 -49
  41. package/src/data/crud/sd-base-container.ts +115 -0
  42. package/src/data/crud/sd-crud-detail.ts +122 -0
  43. package/src/data/crud/sd-crud-list.ts +316 -0
  44. package/src/data/shared-data/sd-shared-data-select-button.ts +0 -1
  45. package/src/data/shared-data/sd-shared-data-select-list.ts +2 -2
  46. package/src/data/shared-data/sd-shared-data-select.ts +3 -3
  47. package/src/data/sheet/injectSheetSelectRowIndicator.ts +17 -7
  48. package/src/data/sheet/sd-sheet.ts +59 -42
  49. package/src/data/sheet/types.ts +1 -0
  50. package/src/data/sheet/useSheetLayoutEngine.ts +3 -1
  51. package/src/index.ts +5 -0
@@ -5,21 +5,20 @@ import type { SelectModalOutputResult } from "../../core/select-modal-output-res
5
5
  import * as i0 from "@angular/core";
6
6
  /**
7
7
  * 모달 선택 컴포넌트가 구현해야 하는 인터페이스
8
- * SdModalContentDef을 확장하여 selectMode와 selectedItemKeys를 추가한다.
8
+ * SdModalContentDef을 확장하여 selectMode와 selectedKeys를 추가한다.
9
9
  */
10
- export interface SdSelectModal<T> extends SdModalContentDef<SelectModalOutputResult<T>> {
10
+ export interface SdSelectModal<TKey> extends SdModalContentDef<SelectModalOutputResult<TKey>> {
11
11
  selectMode: InputSignal<"single" | "multi" | undefined>;
12
- selectedItemKeys: InputSignal<any[]>;
12
+ selectedKeys: InputSignal<TKey[]>;
13
13
  }
14
14
  /**
15
- * 모달 선택 정보 (selectMode/selectedItemKeys를 제외한 inputs)
15
+ * 모달 선택 정보 (selectMode/selectedKeys를 제외한 inputs)
16
16
  */
17
- export type SdSelectModalInfo<T extends SdSelectModal<any>> = SdModalInfo<T, "selectMode" | "selectedItemKeys">;
18
- export declare class SdModalSelectButton<T extends object, K, M extends keyof SelectModeValue<K> = keyof SelectModeValue<K>> {
17
+ export type SdSelectModalInfo<T extends SdSelectModal<any>> = SdModalInfo<T, "selectMode" | "selectedKeys">;
18
+ export declare class SdModalSelectButton<K, M extends keyof SelectModeValue<K> = keyof SelectModeValue<K>> {
19
19
  private readonly _sdModal;
20
- modal: InputSignal<SdSelectModalInfo<SdSelectModal<T>>>;
20
+ modal: InputSignal<SdSelectModalInfo<SdSelectModal<K>>>;
21
21
  value: import("@angular/core").ModelSignal<SelectModeValue<K>[M] | undefined>;
22
- selectedItems: import("@angular/core").ModelSignal<T[]>;
23
22
  disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
24
23
  required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
25
24
  inset: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
@@ -32,7 +31,7 @@ export declare class SdModalSelectButton<T extends object, K, M extends keyof Se
32
31
  constructor();
33
32
  onEraseClick(): void;
34
33
  onSearchClick(event: MouseEvent): Promise<void>;
35
- static ɵfac: i0.ɵɵFactoryDeclaration<SdModalSelectButton<any, any, any>, never>;
36
- static ɵcmp: i0.ɵɵComponentDeclaration<SdModalSelectButton<any, any, any>, "sd-modal-select-button", never, { "modal": { "alias": "modal"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "selectedItems": { "alias": "selectedItems"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "inset": { "alias": "inset"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "selectMode": { "alias": "selectMode"; "required": false; "isSignal": true; }; "modalOptions": { "alias": "modalOptions"; "required": false; "isSignal": true; }; "searchIcon": { "alias": "searchIcon"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "selectedItems": "selectedItemsChange"; }, never, ["*"], true, never>;
34
+ static ɵfac: i0.ɵɵFactoryDeclaration<SdModalSelectButton<any, any>, never>;
35
+ static ɵcmp: i0.ɵɵComponentDeclaration<SdModalSelectButton<any, any>, "sd-modal-select-button", never, { "modal": { "alias": "modal"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "inset": { "alias": "inset"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "selectMode": { "alias": "selectMode"; "required": false; "isSignal": true; }; "modalOptions": { "alias": "modalOptions"; "required": false; "isSignal": true; }; "searchIcon": { "alias": "searchIcon"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, ["*"], true, never>;
37
36
  }
38
37
  //# sourceMappingURL=sd-modal-select-button.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sd-modal-select-button.d.ts","sourceRoot":"","sources":["../../../src/controls/button/sd-modal-select-button.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,WAAW,EAEjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,cAAc,EACpB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAI3D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;;AAIrF;;;GAGG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,CAAE,SAAQ,iBAAiB,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC;IACrF,UAAU,EAAE,WAAW,CAAC,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IACxD,gBAAgB,EAAE,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,aAAa,CAAC,GAAG,CAAC,IAAI,WAAW,CACvE,CAAC,EACD,YAAY,GAAG,kBAAkB,CAClC,CAAC;AAEF,qBAyGa,mBAAmB,CAC9B,CAAC,SAAS,MAAM,EAChB,CAAC,EACD,CAAC,SAAS,MAAM,eAAe,CAAC,CAAC,CAAC,GAAG,MAAM,eAAe,CAAC,CAAC,CAAC;IAE7D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;IAEpD,KAAK,mDAAyD;IAE9D,KAAK,yEAAkC;IACvC,aAAa,2CAAkB;IAE/B,QAAQ,qEAAiD;IACzD,QAAQ,qEAAiD;IACzD,KAAK,qEAAiD;IACtD,IAAI,uCAAwB;IAC5B,UAAU,iBAA2B;IACrC,YAAY,0CAA2B;IAEvC,UAAU,sBAAuB;IAEjC,SAAS,CAAC,QAAQ,CAAC,YAAY,obAAgB;IAE/C,SAAS,0CAKN;;IAYH,YAAY,IAAI,IAAI;IAKd,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;yCA7C1C,mBAAmB;2CAAnB,mBAAmB;CAqE/B"}
1
+ {"version":3,"file":"sd-modal-select-button.d.ts","sourceRoot":"","sources":["../../../src/controls/button/sd-modal-select-button.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,WAAW,EAEjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,cAAc,EACpB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAI3D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;;AAIrF;;;GAGG;AACH,MAAM,WAAW,aAAa,CAAC,IAAI,CAAE,SAAQ,iBAAiB,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAC3F,UAAU,EAAE,WAAW,CAAC,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IACxD,YAAY,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,aAAa,CAAC,GAAG,CAAC,IAAI,WAAW,CACvE,CAAC,EACD,YAAY,GAAG,cAAc,CAC9B,CAAC;AAEF,qBAyGa,mBAAmB,CAC9B,CAAC,EACD,CAAC,SAAS,MAAM,eAAe,CAAC,CAAC,CAAC,GAAG,MAAM,eAAe,CAAC,CAAC,CAAC;IAE7D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;IAEpD,KAAK,mDAAyD;IAE9D,KAAK,yEAAkC;IAEvC,QAAQ,qEAAiD;IACzD,QAAQ,qEAAiD;IACzD,KAAK,qEAAiD;IACtD,IAAI,uCAAwB;IAC5B,UAAU,iBAA2B;IACrC,YAAY,0CAA2B;IAEvC,UAAU,sBAAuB;IAEjC,SAAS,CAAC,QAAQ,CAAC,YAAY,obAAgB;IAE/C,SAAS,0CAKN;;IAYH,YAAY,IAAI,IAAI;IAId,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;yCA1C1C,mBAAmB;2CAAnB,mBAAmB;CAiE/B"}
@@ -35,7 +35,6 @@ export class SdModalSelectButton {
35
35
  _sdModal = inject(SdModalProvider);
36
36
  modal = input.required(...(ngDevMode ? [{ debugName: "modal" }] : /* istanbul ignore next */ []));
37
37
  value = model(...(ngDevMode ? [undefined, { debugName: "value" }] : /* istanbul ignore next */ []));
38
- selectedItems = model([], ...(ngDevMode ? [{ debugName: "selectedItems" }] : /* istanbul ignore next */ []));
39
38
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
40
39
  required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
41
40
  inset = input(false, { ...(ngDevMode ? { debugName: "inset" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
@@ -66,7 +65,6 @@ export class SdModalSelectButton {
66
65
  }
67
66
  onEraseClick() {
68
67
  this.value.set((this.selectMode() === "multi" ? [] : undefined));
69
- this.selectedItems.set([]);
70
68
  }
71
69
  async onSearchClick(event) {
72
70
  event.preventDefault();
@@ -76,22 +74,21 @@ export class SdModalSelectButton {
76
74
  ...modal,
77
75
  inputs: {
78
76
  selectMode: this.selectMode(),
79
- selectedItemKeys: (this.selectMode() === "multi"
77
+ selectedKeys: (this.selectMode() === "multi"
80
78
  ? (this.value() ?? [])
81
79
  : [this.value()]).filterExists(),
82
80
  ...modal.inputs,
83
81
  },
84
82
  });
85
83
  if (result) {
86
- const newValue = this.selectMode() === "multi" ? result.selectedItemKeys : result.selectedItemKeys[0];
84
+ const newValue = this.selectMode() === "multi" ? result.selectedKeys : result.selectedKeys[0];
87
85
  this.value.set(newValue);
88
- this.selectedItems.set(result.selectedItems);
89
86
  }
90
87
  }
91
88
  static ɵfac = function SdModalSelectButton_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SdModalSelectButton)(); };
92
89
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SdModalSelectButton, selectors: [["sd-modal-select-button"]], hostVars: 3, hostBindings: function SdModalSelectButton_HostBindings(rf, ctx) { if (rf & 2) {
93
90
  i0.ɵɵattribute("data-sd-size", ctx.size())("data-sd-inset", ctx.inset())("data-sd-disabled", ctx.disabled());
94
- } }, inputs: { modal: [1, "modal"], value: [1, "value"], selectedItems: [1, "selectedItems"], disabled: [1, "disabled"], required: [1, "required"], inset: [1, "inset"], size: [1, "size"], selectMode: [1, "selectMode"], modalOptions: [1, "modalOptions"], searchIcon: [1, "searchIcon"] }, outputs: { value: "valueChange", selectedItems: "selectedItemsChange" }, ngContentSelectors: _c0, decls: 5, vars: 2, consts: [[1, "_content"], [1, "_button"], ["data-sd-eraser", "", 3, "theme"], [3, "inset"], ["data-sd-eraser", "", 3, "click", "theme"], [3, "svg"], [3, "click", "inset"]], template: function SdModalSelectButton_Template(rf, ctx) { if (rf & 1) {
91
+ } }, inputs: { modal: [1, "modal"], value: [1, "value"], disabled: [1, "disabled"], required: [1, "required"], inset: [1, "inset"], size: [1, "size"], selectMode: [1, "selectMode"], modalOptions: [1, "modalOptions"], searchIcon: [1, "searchIcon"] }, outputs: { value: "valueChange" }, ngContentSelectors: _c0, decls: 5, vars: 2, consts: [[1, "_content"], [1, "_button"], ["data-sd-eraser", "", 3, "theme"], [3, "inset"], ["data-sd-eraser", "", 3, "click", "theme"], [3, "svg"], [3, "click", "inset"]], template: function SdModalSelectButton_Template(rf, ctx) { if (rf & 1) {
95
92
  i0.ɵɵprojectionDef();
96
93
  i0.ɵɵelementStart(0, "div", 0);
97
94
  i0.ɵɵprojection(1);
@@ -130,5 +127,5 @@ export class SdModalSelectButton {
130
127
  "[attr.data-sd-inset]": "inset()",
131
128
  "[attr.data-sd-disabled]": "disabled()",
132
129
  }, styles: ["sd-modal-select-button {\n display: flex;\n flex-direction: row;\n gap: var(--gap-sm);\n position: relative;\n width: 100%;\n min-width: 3em;\n border: 1px solid var(--trans-light);\n border-radius: var(--border-radius-default);\n overflow: hidden;\n}\nsd-modal-select-button > ._content {\n flex: 1;\n padding: var(--gap-sm) var(--gap-default);\n}\nsd-modal-select-button > ._button {\n display: flex;\n flex-wrap: nowrap;\n flex-direction: row;\n}\n@supports not (appearance: auto) {\n sd-modal-select-button > ._button.gap-xxs {\n gap: 0;\n }\n sd-modal-select-button > ._button.gap-xxs > * + * {\n margin-left: var(--gap-xxs);\n }\n sd-modal-select-button > ._button.gap-xs {\n gap: 0;\n }\n sd-modal-select-button > ._button.gap-xs > * + * {\n margin-left: var(--gap-xs);\n }\n sd-modal-select-button > ._button.gap-sm {\n gap: 0;\n }\n sd-modal-select-button > ._button.gap-sm > * + * {\n margin-left: var(--gap-sm);\n }\n sd-modal-select-button > ._button.gap-default {\n gap: 0;\n }\n sd-modal-select-button > ._button.gap-default > * + * {\n margin-left: var(--gap-default);\n }\n sd-modal-select-button > ._button.gap-lg {\n gap: 0;\n }\n sd-modal-select-button > ._button.gap-lg > * + * {\n margin-left: var(--gap-lg);\n }\n sd-modal-select-button > ._button.gap-xl {\n gap: 0;\n }\n sd-modal-select-button > ._button.gap-xl > * + * {\n margin-left: var(--gap-xl);\n }\n sd-modal-select-button > ._button.gap-xxl {\n gap: 0;\n }\n sd-modal-select-button > ._button.gap-xxl > * + * {\n margin-left: var(--gap-xxl);\n }\n sd-modal-select-button > ._button.gap-0 {\n gap: 0;\n }\n sd-modal-select-button > ._button.gap-0 > * + * {\n margin-left: var(--gap-0);\n }\n sd-modal-select-button > ._button.gap-auto {\n gap: 0;\n }\n sd-modal-select-button > ._button.gap-auto > * + * {\n margin-left: var(--gap-auto);\n }\n}\nsd-modal-select-button > ._button > sd-anchor {\n padding: var(--gap-sm) !important;\n}\nsd-modal-select-button > ._button > sd-button > button {\n border-left: 1px solid var(--trans-lighter) !important;\n padding: var(--gap-sm) !important;\n height: 100%;\n}\nsd-modal-select-button[data-sd-inset=true] {\n border-radius: 0;\n border: none;\n}\nsd-modal-select-button[data-sd-size=sm] > ._content {\n padding: var(--gap-xs) var(--gap-default);\n}\nsd-modal-select-button[data-sd-size=sm] > ._button > sd-anchor {\n padding: var(--gap-xs) var(--gap-sm) !important;\n}\nsd-modal-select-button[data-sd-size=sm] > ._button > sd-button > button {\n padding: var(--gap-xs) var(--gap-sm) !important;\n}\nsd-modal-select-button[data-sd-size=lg] > ._content {\n padding: var(--gap-default) var(--gap-xl);\n}\nsd-modal-select-button[data-sd-size=lg] > ._button > sd-anchor {\n padding: var(--gap-default) !important;\n}\nsd-modal-select-button[data-sd-size=lg] > ._button > sd-button > button {\n padding: var(--gap-default) !important;\n}"] }]
133
- }], () => [], { modal: [{ type: i0.Input, args: [{ isSignal: true, alias: "modal", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], selectedItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedItems", required: false }] }, { type: i0.Output, args: ["selectedItemsChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], inset: [{ type: i0.Input, args: [{ isSignal: true, alias: "inset", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], selectMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectMode", required: false }] }], modalOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "modalOptions", required: false }] }], searchIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchIcon", required: false }] }] }); })();
130
+ }], () => [], { modal: [{ type: i0.Input, args: [{ isSignal: true, alias: "modal", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], inset: [{ type: i0.Input, args: [{ isSignal: true, alias: "inset", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], selectMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectMode", required: false }] }], modalOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "modalOptions", required: false }] }], searchIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchIcon", required: false }] }] }); })();
134
131
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SdModalSelectButton, { className: "SdModalSelectButton", filePath: "packages/angular/src/controls/button/sd-modal-select-button.ts", lineNumber: 148 }); })();
@@ -1,8 +1,7 @@
1
1
  /**
2
2
  * 모달 선택 결과
3
3
  */
4
- export interface SelectModalOutputResult<T> {
5
- selectedItemKeys: any[];
6
- selectedItems: T[];
4
+ export interface SelectModalOutputResult<TKey = any> {
5
+ selectedKeys: TKey[];
7
6
  }
8
7
  //# sourceMappingURL=select-modal-output-result.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"select-modal-output-result.d.ts","sourceRoot":"","sources":["../../src/core/select-modal-output-result.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,uBAAuB,CAAC,CAAC;IACxC,gBAAgB,EAAE,GAAG,EAAE,CAAC;IACxB,aAAa,EAAE,CAAC,EAAE,CAAC;CACpB"}
1
+ {"version":3,"file":"select-modal-output-result.d.ts","sourceRoot":"","sources":["../../src/core/select-modal-output-result.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,uBAAuB,CAAC,IAAI,GAAG,GAAG;IACjD,YAAY,EAAE,IAAI,EAAE,CAAC;CACtB"}
@@ -1,19 +1,19 @@
1
1
  import { type Signal, type WritableSignal } from "@angular/core";
2
- export declare function useSelectionManager<T>(options: {
3
- displayItems: Signal<T[]>;
4
- selectedItems: WritableSignal<T[]>;
2
+ export declare function useSelectionManager<TItem, TKey>(options: {
3
+ displayItems: Signal<TItem[]>;
4
+ selectedKeys: WritableSignal<NonNullable<TKey>[]>;
5
5
  selectMode: Signal<"single" | "multi" | undefined>;
6
- getItemSelectableFn: Signal<((item: T) => boolean | string) | undefined>;
7
- trackByFn: Signal<(item: T, index: number) => unknown>;
6
+ getItemSelectableFn: Signal<((item: TItem) => boolean | string) | undefined>;
7
+ trackByFn: Signal<(item: TItem, index: number) => TKey>;
8
8
  }): {
9
9
  hasSelectable: Signal<boolean>;
10
10
  isAllSelected: Signal<boolean>;
11
- getSelectable(item: T): true | string | undefined;
12
- getCanChangeFn(item: T): () => boolean;
13
- select(item: T): void;
14
- deselect(item: T): void;
15
- toggle(item: T): void;
11
+ getSelectable(item: TItem): true | string | undefined;
12
+ getCanChangeFn(item: TItem): () => boolean;
13
+ select(item: TItem): void;
14
+ deselect(item: TItem): void;
15
+ toggle(item: TItem): void;
16
16
  toggleAll(): void;
17
- isSelected(item: T): boolean;
17
+ isSelected(item: TItem): boolean;
18
18
  };
19
19
  //# sourceMappingURL=useSelectionManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSelectionManager.d.ts","sourceRoot":"","sources":["../../../src/core/selection/useSelectionManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,MAAM,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAG3E,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,OAAO,EAAE;IAC9C,YAAY,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1B,aAAa,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IACnD,mBAAmB,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,GAAG,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC;IACzE,SAAS,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC;CACxD,GAAG;IACF,aAAa,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/B,aAAa,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/B,aAAa,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;IAClD,cAAc,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,OAAO,CAAC;IACvC,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACtB,SAAS,IAAI,IAAI,CAAC;IAClB,UAAU,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC;CAC9B,CAwIA"}
1
+ {"version":3,"file":"useSelectionManager.d.ts","sourceRoot":"","sources":["../../../src/core/selection/useSelectionManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,MAAM,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAG3E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE;IACxD,YAAY,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IAC9B,YAAY,EAAE,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClD,UAAU,EAAE,MAAM,CAAC,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IACnD,mBAAmB,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,GAAG,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC;IAC7E,SAAS,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC;CACzD,GAAG;IACF,aAAa,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/B,aAAa,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/B,aAAa,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;IACtD,cAAc,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,OAAO,CAAC;IAC3C,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC;IAC5B,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC;IAC1B,SAAS,IAAI,IAAI,CAAC;IAClB,UAAU,CAAC,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC;CAClC,CAsIA"}
@@ -2,10 +2,17 @@ import { computed } from "@angular/core";
2
2
  import { obj } from "@simplysm/core-common";
3
3
  export function useSelectionManager(options) {
4
4
  const selectableItems = computed(() => {
5
+ const trackFn = options.trackByFn();
6
+ const idxMap = new Map();
7
+ options.displayItems().forEach((it, i) => idxMap.set(it, i));
5
8
  const fn = options.getItemSelectableFn();
6
- if (fn == null)
7
- return options.displayItems();
8
- return options.displayItems().filter((item) => fn(item) === true);
9
+ return options.displayItems().filter((item) => {
10
+ if (trackFn(item, idxMap.get(item) ?? 0) == null)
11
+ return false;
12
+ if (fn == null)
13
+ return true;
14
+ return fn(item) === true;
15
+ });
9
16
  }, ...(ngDevMode ? [{ debugName: "selectableItems" }] : /* istanbul ignore next */ []));
10
17
  const hasSelectable = computed(() => {
11
18
  return options.selectMode() != null;
@@ -15,10 +22,6 @@ export function useSelectionManager(options) {
15
22
  options.displayItems().forEach((it, i) => map.set(it, i));
16
23
  return map;
17
24
  }, ...(ngDevMode ? [{ debugName: "displayItemIndexMap" }] : /* istanbul ignore next */ []));
18
- const selectedKeys = computed(() => {
19
- const fn = options.trackByFn();
20
- return options.selectedItems().map((it, i) => fn(it, i));
21
- }, ...(ngDevMode ? [{ debugName: "selectedKeys" }] : /* istanbul ignore next */ []));
22
25
  function isKeyEqual(a, b) {
23
26
  if (a === b)
24
27
  return true;
@@ -32,7 +35,7 @@ export function useSelectionManager(options) {
32
35
  const items = selectableItems();
33
36
  if (items.length === 0)
34
37
  return false;
35
- const keys = selectedKeys();
38
+ const keys = options.selectedKeys();
36
39
  const fn = options.trackByFn();
37
40
  return items.every((it, i) => {
38
41
  const key = fn(it, i);
@@ -43,6 +46,8 @@ export function useSelectionManager(options) {
43
46
  const mode = options.selectMode();
44
47
  if (mode == null)
45
48
  return undefined;
49
+ if (keyOf(item) == null)
50
+ return undefined;
46
51
  const fn = options.getItemSelectableFn();
47
52
  if (fn == null)
48
53
  return true;
@@ -65,22 +70,22 @@ export function useSelectionManager(options) {
65
70
  return;
66
71
  if (getSelectable(item) !== true)
67
72
  return;
73
+ const key = keyOf(item);
74
+ if (key == null)
75
+ return;
68
76
  if (mode === "single") {
69
- options.selectedItems.set([item]);
77
+ options.selectedKeys.set([key]);
70
78
  return;
71
79
  }
72
- const key = keyOf(item);
73
- const fn = options.trackByFn();
74
- options.selectedItems.update((arr) => {
75
- if (arr.some((it, i) => isKeyEqual(fn(it, i), key)))
80
+ options.selectedKeys.update((arr) => {
81
+ if (arr.some((k) => isKeyEqual(k, key)))
76
82
  return arr;
77
- return [...arr, item];
83
+ return [...arr, key];
78
84
  });
79
85
  }
80
86
  function deselect(item) {
81
87
  const key = keyOf(item);
82
- const fn = options.trackByFn();
83
- options.selectedItems.update((arr) => arr.filter((it, i) => !isKeyEqual(fn(it, i), key)));
88
+ options.selectedKeys.update((arr) => arr.filter((k) => !isKeyEqual(k, key)));
84
89
  }
85
90
  function toggle(item) {
86
91
  if (isSelected(item)) {
@@ -96,25 +101,21 @@ export function useSelectionManager(options) {
96
101
  const idxMap = displayItemIndexMap();
97
102
  if (isAllSelected()) {
98
103
  const keysToRemove = selectable.map((it) => fn(it, idxMap.get(it) ?? 0));
99
- options.selectedItems.update((arr) => arr.filter((it, i) => {
100
- const k = fn(it, i);
101
- return !keysToRemove.some((rk) => isKeyEqual(rk, k));
102
- }));
104
+ options.selectedKeys.update((arr) => arr.filter((k) => !keysToRemove.some((rk) => isKeyEqual(rk, k))));
103
105
  }
104
106
  else {
105
- options.selectedItems.update((arr) => {
106
- const existingKeys = arr.map((it, i) => fn(it, i));
107
- const toAdd = selectable.filter((it) => {
108
- const k = fn(it, idxMap.get(it) ?? 0);
109
- return !existingKeys.some((ek) => isKeyEqual(ek, k));
110
- });
111
- return [...arr, ...toAdd];
107
+ options.selectedKeys.update((arr) => {
108
+ const newKeys = selectable
109
+ .map((it) => fn(it, idxMap.get(it) ?? 0))
110
+ .filter((k) => k != null)
111
+ .filter((k) => !arr.some((ek) => isKeyEqual(ek, k)));
112
+ return [...arr, ...newKeys];
112
113
  });
113
114
  }
114
115
  }
115
116
  function isSelected(item) {
116
117
  const key = keyOf(item);
117
- return selectedKeys().some((k) => isKeyEqual(k, key));
118
+ return options.selectedKeys().some((k) => isKeyEqual(k, key));
118
119
  }
119
120
  return {
120
121
  hasSelectable,
@@ -0,0 +1,21 @@
1
+ import { TemplateRef } from "@angular/core";
2
+ import type { SdViewType } from "../../core/routing/injectViewTypeSignal";
3
+ import * as i0 from "@angular/core";
4
+ export declare class SdBaseContainer {
5
+ private readonly _sdSharedData;
6
+ private readonly _sdToast;
7
+ viewTitle: import("@angular/core").Signal<string>;
8
+ ready: import("@angular/core").ModelSignal<boolean>;
9
+ initialized: import("@angular/core").InputSignal<boolean>;
10
+ busyCount: import("@angular/core").ModelSignal<number>;
11
+ restricted: import("@angular/core").InputSignal<boolean>;
12
+ viewType: import("@angular/core").InputSignal<SdViewType>;
13
+ topbarTplRef: import("@angular/core").Signal<TemplateRef<void> | undefined>;
14
+ commandTplRef: import("@angular/core").Signal<TemplateRef<void> | undefined>;
15
+ bottomCommandTplRef: import("@angular/core").Signal<TemplateRef<void> | undefined>;
16
+ constructor();
17
+ protected readonly tablerAlertTriangle = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"stroke-width:var(--ng-icon__stroke-width, 2)\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path><path d=\"M12 9v4\"></path><path d=\"M10.363 3.591l-8.106 13.534a1.914 1.914 0 0 0 1.636 2.871h16.214a1.914 1.914 0 0 0 1.636 -2.87l-8.106 -13.536a1.914 1.914 0 0 0 -3.274 0z\"></path><path d=\"M12 16h.01\"></path></svg>";
18
+ static ɵfac: i0.ɵɵFactoryDeclaration<SdBaseContainer, never>;
19
+ static ɵcmp: i0.ɵɵComponentDeclaration<SdBaseContainer, "sd-base-container", never, { "ready": { "alias": "ready"; "required": false; "isSignal": true; }; "initialized": { "alias": "initialized"; "required": false; "isSignal": true; }; "busyCount": { "alias": "busyCount"; "required": false; "isSignal": true; }; "restricted": { "alias": "restricted"; "required": false; "isSignal": true; }; "viewType": { "alias": "viewType"; "required": true; "isSignal": true; }; }, { "ready": "readyChange"; "busyCount": "busyCountChange"; }, ["topbarTplRef", "commandTplRef", "bottomCommandTplRef"], ["*"], true, never>;
20
+ }
21
+ //# sourceMappingURL=sd-base-container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sd-base-container.d.ts","sourceRoot":"","sources":["../../../src/data/crud/sd-base-container.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,WAAW,EAGZ,MAAM,eAAe,CAAC;AAOvB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;;AAK1E,qBAsDa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgC;IAC9D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;IAEpD,SAAS,yCAA2B;IAEpC,KAAK,+CAAgB;IACrB,WAAW,+CAAgB;IAC3B,SAAS,8CAAY;IAErB,UAAU,+CAAgB;IAE1B,QAAQ,kDAAgC;IAExC,YAAY,gEAAgD;IAC5D,aAAa,gEAAiD;IAC9D,mBAAmB,gEAAuD;;IAoB1E,SAAS,CAAC,QAAQ,CAAC,mBAAmB,ifAAuB;yCApClD,eAAe;2CAAf,eAAe;CAqC3B"}
@@ -0,0 +1,200 @@
1
+ import { ChangeDetectionStrategy, Component, contentChild, effect, inject, input, model, TemplateRef, untracked, ViewEncapsulation, } from "@angular/core";
2
+ import { injectViewTitleSignal } from "../../core/routing/injectViewTitleSignal";
3
+ import { SdBusyContainer } from "../../core/busy/sd-busy-container";
4
+ import { SdSharedDataProvider } from "../../core/shared-data/sd-shared-data.provider";
5
+ import { SdToastProvider } from "../../core/toast/sd-toast.provider";
6
+ import { SdTopbar } from "../../layout/topbar/sd-topbar";
7
+ import { SdTopbarContainer } from "../../layout/topbar/sd-topbar-container";
8
+ import { NgIcon } from "@ng-icons/core";
9
+ import { tablerAlertTriangle } from "@ng-icons/tabler-icons";
10
+ import { NgTemplateOutlet } from "@angular/common";
11
+ import * as i0 from "@angular/core";
12
+ const _c0 = ["topbarTpl"];
13
+ const _c1 = ["commandTpl"];
14
+ const _c2 = ["bottomCommandTpl"];
15
+ const _c3 = ["*"];
16
+ function SdBaseContainer_Conditional_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
17
+ i0.ɵɵelementStart(0, "div", 2);
18
+ i0.ɵɵelement(1, "br")(2, "ng-icon", 4)(3, "br")(4, "br");
19
+ i0.ɵɵtext(5);
20
+ i0.ɵɵelementEnd();
21
+ } if (rf & 2) {
22
+ const ctx_r0 = i0.ɵɵnextContext(2);
23
+ i0.ɵɵadvance(2);
24
+ i0.ɵɵproperty("svg", ctx_r0.tablerAlertTriangle)("size", "5rem");
25
+ i0.ɵɵadvance(3);
26
+ i0.ɵɵtextInterpolate1(" '", ctx_r0.viewTitle(), "'\uC5D0 \uB300\uD55C \uC0AC\uC6A9\uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uC2DC\uC2A4\uD15C \uAD00\uB9AC\uC790\uC5D0\uAC8C \uBB38\uC758\uD558\uC138\uC694. ");
27
+ } }
28
+ function SdBaseContainer_Conditional_1_Conditional_1_ng_template_4_Template(rf, ctx) { }
29
+ function SdBaseContainer_Conditional_1_Conditional_1_ng_template_5_Template(rf, ctx) { }
30
+ function SdBaseContainer_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
31
+ i0.ɵɵelementStart(0, "sd-topbar-container")(1, "sd-topbar")(2, "h4");
32
+ i0.ɵɵtext(3);
33
+ i0.ɵɵelementEnd();
34
+ i0.ɵɵtemplate(4, SdBaseContainer_Conditional_1_Conditional_1_ng_template_4_Template, 0, 0, "ng-template", 3);
35
+ i0.ɵɵelementEnd();
36
+ i0.ɵɵtemplate(5, SdBaseContainer_Conditional_1_Conditional_1_ng_template_5_Template, 0, 0, "ng-template", 3);
37
+ i0.ɵɵelementEnd();
38
+ } if (rf & 2) {
39
+ const ctx_r0 = i0.ɵɵnextContext(2);
40
+ const content_r2 = i0.ɵɵreference(3);
41
+ i0.ɵɵadvance(3);
42
+ i0.ɵɵtextInterpolate(ctx_r0.viewTitle());
43
+ i0.ɵɵadvance();
44
+ i0.ɵɵproperty("ngTemplateOutlet", ctx_r0.topbarTplRef());
45
+ i0.ɵɵadvance();
46
+ i0.ɵɵproperty("ngTemplateOutlet", content_r2);
47
+ } }
48
+ function SdBaseContainer_Conditional_1_Conditional_2_ng_template_0_Template(rf, ctx) { }
49
+ function SdBaseContainer_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
50
+ i0.ɵɵtemplate(0, SdBaseContainer_Conditional_1_Conditional_2_ng_template_0_Template, 0, 0, "ng-template", 3);
51
+ } if (rf & 2) {
52
+ i0.ɵɵnextContext(2);
53
+ const content_r2 = i0.ɵɵreference(3);
54
+ i0.ɵɵproperty("ngTemplateOutlet", content_r2);
55
+ } }
56
+ function SdBaseContainer_Conditional_1_Template(rf, ctx) { if (rf & 1) {
57
+ i0.ɵɵconditionalCreate(0, SdBaseContainer_Conditional_1_Conditional_0_Template, 6, 3, "div", 2)(1, SdBaseContainer_Conditional_1_Conditional_1_Template, 6, 3, "sd-topbar-container")(2, SdBaseContainer_Conditional_1_Conditional_2_Template, 1, 1, null, 3);
58
+ } if (rf & 2) {
59
+ const ctx_r0 = i0.ɵɵnextContext();
60
+ i0.ɵɵconditional(ctx_r0.restricted() ? 0 : ctx_r0.viewType() === "page" ? 1 : 2);
61
+ } }
62
+ function SdBaseContainer_ng_template_2_Conditional_1_ng_template_1_Template(rf, ctx) { }
63
+ function SdBaseContainer_ng_template_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
64
+ i0.ɵɵelementStart(0, "div", 6);
65
+ i0.ɵɵtemplate(1, SdBaseContainer_ng_template_2_Conditional_1_ng_template_1_Template, 0, 0, "ng-template", 3);
66
+ i0.ɵɵelementEnd();
67
+ } if (rf & 2) {
68
+ const ctx_r0 = i0.ɵɵnextContext(2);
69
+ i0.ɵɵadvance();
70
+ i0.ɵɵproperty("ngTemplateOutlet", ctx_r0.commandTplRef());
71
+ } }
72
+ function SdBaseContainer_ng_template_2_Conditional_4_ng_template_1_Template(rf, ctx) { }
73
+ function SdBaseContainer_ng_template_2_Conditional_4_Template(rf, ctx) { if (rf & 1) {
74
+ i0.ɵɵelementStart(0, "div", 8);
75
+ i0.ɵɵtemplate(1, SdBaseContainer_ng_template_2_Conditional_4_ng_template_1_Template, 0, 0, "ng-template", 3);
76
+ i0.ɵɵelementEnd();
77
+ } if (rf & 2) {
78
+ const ctx_r0 = i0.ɵɵnextContext(2);
79
+ i0.ɵɵadvance();
80
+ i0.ɵɵproperty("ngTemplateOutlet", ctx_r0.bottomCommandTplRef());
81
+ } }
82
+ function SdBaseContainer_ng_template_2_Template(rf, ctx) { if (rf & 1) {
83
+ i0.ɵɵelementStart(0, "div", 5);
84
+ i0.ɵɵconditionalCreate(1, SdBaseContainer_ng_template_2_Conditional_1_Template, 2, 1, "div", 6);
85
+ i0.ɵɵelementStart(2, "div", 7);
86
+ i0.ɵɵprojection(3);
87
+ i0.ɵɵelementEnd();
88
+ i0.ɵɵconditionalCreate(4, SdBaseContainer_ng_template_2_Conditional_4_Template, 2, 1, "div", 8);
89
+ i0.ɵɵelementEnd();
90
+ } if (rf & 2) {
91
+ const ctx_r0 = i0.ɵɵnextContext();
92
+ i0.ɵɵadvance();
93
+ i0.ɵɵconditional(ctx_r0.commandTplRef() ? 1 : -1);
94
+ i0.ɵɵadvance(3);
95
+ i0.ɵɵconditional(ctx_r0.bottomCommandTplRef() ? 4 : -1);
96
+ } }
97
+ export class SdBaseContainer {
98
+ _sdSharedData = inject(SdSharedDataProvider);
99
+ _sdToast = inject(SdToastProvider);
100
+ viewTitle = injectViewTitleSignal();
101
+ ready = model(false, ...(ngDevMode ? [{ debugName: "ready" }] : /* istanbul ignore next */ []));
102
+ initialized = input(false, ...(ngDevMode ? [{ debugName: "initialized" }] : /* istanbul ignore next */ []));
103
+ busyCount = model(0, ...(ngDevMode ? [{ debugName: "busyCount" }] : /* istanbul ignore next */ []));
104
+ restricted = input(false, ...(ngDevMode ? [{ debugName: "restricted" }] : /* istanbul ignore next */ []));
105
+ viewType = input.required(...(ngDevMode ? [{ debugName: "viewType" }] : /* istanbul ignore next */ []));
106
+ topbarTplRef = contentChild("topbarTpl", ...(ngDevMode ? [{ debugName: "topbarTplRef" }] : /* istanbul ignore next */ []));
107
+ commandTplRef = contentChild("commandTpl", ...(ngDevMode ? [{ debugName: "commandTplRef" }] : /* istanbul ignore next */ []));
108
+ bottomCommandTplRef = contentChild("bottomCommandTpl", ...(ngDevMode ? [{ debugName: "bottomCommandTplRef" }] : /* istanbul ignore next */ []));
109
+ constructor() {
110
+ effect(() => {
111
+ if (this.restricted()) {
112
+ this.ready.set(true);
113
+ return;
114
+ }
115
+ void untracked(async () => {
116
+ this.busyCount.update((v) => v + 1);
117
+ await this._sdToast.try(async () => {
118
+ await this._sdSharedData.wait();
119
+ });
120
+ this.busyCount.update((v) => v - 1);
121
+ this.ready.set(true);
122
+ });
123
+ });
124
+ }
125
+ tablerAlertTriangle = tablerAlertTriangle;
126
+ static ɵfac = function SdBaseContainer_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SdBaseContainer)(); };
127
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SdBaseContainer, selectors: [["sd-base-container"]], contentQueries: function SdBaseContainer_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) {
128
+ i0.ɵɵcontentQuerySignal(dirIndex, ctx.topbarTplRef, _c0, 5)(dirIndex, ctx.commandTplRef, _c1, 5)(dirIndex, ctx.bottomCommandTplRef, _c2, 5);
129
+ } if (rf & 2) {
130
+ i0.ɵɵqueryAdvance(3);
131
+ } }, inputs: { ready: [1, "ready"], initialized: [1, "initialized"], busyCount: [1, "busyCount"], restricted: [1, "restricted"], viewType: [1, "viewType"] }, outputs: { ready: "readyChange", busyCount: "busyCountChange" }, ngContentSelectors: _c3, decls: 4, vars: 2, consts: [["content", ""], [3, "busy"], [1, "fill", "tx-theme-gray-light", "p-xxl", "tx-center"], [3, "ngTemplateOutlet"], [3, "svg", "size"], [1, "flex-column", "fill"], [1, "p-default", "flex-row", "gap-default", "bdb", "bdb-theme-gray-lightest"], [1, "flex-fill"], [1, "p-sm-default", "flex-row", "main-align-end", "gap-sm", "bdt", "bdt-theme-gray-lightest"]], template: function SdBaseContainer_Template(rf, ctx) { if (rf & 1) {
132
+ i0.ɵɵprojectionDef();
133
+ i0.ɵɵelementStart(0, "sd-busy-container", 1);
134
+ i0.ɵɵconditionalCreate(1, SdBaseContainer_Conditional_1_Template, 3, 1);
135
+ i0.ɵɵelementEnd();
136
+ i0.ɵɵtemplate(2, SdBaseContainer_ng_template_2_Template, 5, 2, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
137
+ } if (rf & 2) {
138
+ i0.ɵɵproperty("busy", ctx.initialized() && ctx.busyCount() > 0);
139
+ i0.ɵɵadvance();
140
+ i0.ɵɵconditional(ctx.initialized() ? 1 : -1);
141
+ } }, dependencies: [SdBusyContainer, NgIcon, SdTopbarContainer, NgTemplateOutlet, SdTopbar], encapsulation: 2, changeDetection: 0 });
142
+ }
143
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SdBaseContainer, [{
144
+ type: Component,
145
+ args: [{
146
+ selector: "sd-base-container",
147
+ changeDetection: ChangeDetectionStrategy.OnPush,
148
+ encapsulation: ViewEncapsulation.None,
149
+ standalone: true,
150
+ imports: [SdBusyContainer, NgIcon, SdTopbarContainer, NgTemplateOutlet, SdTopbar],
151
+ template: `
152
+ <sd-busy-container [busy]="initialized() && busyCount() > 0">
153
+ @if (initialized()) {
154
+ @if (restricted()) {
155
+ <div class="fill tx-theme-gray-light p-xxl tx-center">
156
+ <br />
157
+ <ng-icon [svg]="tablerAlertTriangle" [size]="'5rem'" />
158
+ <br />
159
+ <br />
160
+ '{{ viewTitle() }}'에 대한 사용권한이 없습니다. 시스템 관리자에게 문의하세요.
161
+ </div>
162
+ } @else if (viewType() === "page") {
163
+ <sd-topbar-container>
164
+ <sd-topbar>
165
+ <h4>{{ viewTitle() }}</h4>
166
+
167
+ <ng-template [ngTemplateOutlet]="topbarTplRef()" />
168
+ </sd-topbar>
169
+
170
+ <ng-template [ngTemplateOutlet]="content" />
171
+ </sd-topbar-container>
172
+ } @else {
173
+ <ng-template [ngTemplateOutlet]="content" />
174
+ }
175
+ }
176
+ </sd-busy-container>
177
+
178
+ <ng-template #content>
179
+ <div class="flex-column fill">
180
+ @if (commandTplRef()) {
181
+ <div class="p-default flex-row gap-default bdb bdb-theme-gray-lightest">
182
+ <ng-template [ngTemplateOutlet]="commandTplRef()" />
183
+ </div>
184
+ }
185
+
186
+ <div class="flex-fill">
187
+ <ng-content />
188
+ </div>
189
+
190
+ @if (bottomCommandTplRef()) {
191
+ <div class="p-sm-default flex-row main-align-end gap-sm bdt bdt-theme-gray-lightest">
192
+ <ng-template [ngTemplateOutlet]="bottomCommandTplRef()" />
193
+ </div>
194
+ }
195
+ </div>
196
+ </ng-template>
197
+ `,
198
+ }]
199
+ }], () => [], { ready: [{ type: i0.Input, args: [{ isSignal: true, alias: "ready", required: false }] }, { type: i0.Output, args: ["readyChange"] }], initialized: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialized", required: false }] }], busyCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "busyCount", required: false }] }, { type: i0.Output, args: ["busyCountChange"] }], restricted: [{ type: i0.Input, args: [{ isSignal: true, alias: "restricted", required: false }] }], viewType: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewType", required: true }] }], topbarTplRef: [{ type: i0.ContentChild, args: ["topbarTpl", { isSignal: true }] }], commandTplRef: [{ type: i0.ContentChild, args: ["commandTpl", { isSignal: true }] }], bottomCommandTplRef: [{ type: i0.ContentChild, args: ["bottomCommandTpl", { isSignal: true }] }] }); })();
200
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SdBaseContainer, { className: "SdBaseContainer", filePath: "packages/angular/src/data/crud/sd-base-container.ts", lineNumber: 78 }); })();
@@ -0,0 +1,22 @@
1
+ import { type TemplateRef } from "@angular/core";
2
+ import { SdForm } from "../../controls/form/sd-form";
3
+ import type { SdViewType } from "../../core/routing/injectViewTypeSignal";
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "../../core/commands/sd-command";
6
+ export declare class SdCrudDetail {
7
+ ready: import("@angular/core").ModelSignal<boolean>;
8
+ initialized: import("@angular/core").InputSignal<boolean>;
9
+ busyCount: import("@angular/core").ModelSignal<number>;
10
+ restricted: import("@angular/core").InputSignal<boolean>;
11
+ readonly: import("@angular/core").InputSignal<boolean>;
12
+ viewType: import("@angular/core").InputSignal<SdViewType>;
13
+ formCtrl: import("@angular/core").Signal<SdForm | undefined>;
14
+ submit: import("@angular/core").OutputEmitterRef<void>;
15
+ commandTplRef: import("@angular/core").Signal<TemplateRef<void> | undefined>;
16
+ bottomCommandTplRef: import("@angular/core").Signal<TemplateRef<void> | undefined>;
17
+ onSaveButtonClick(): void;
18
+ protected readonly tablerDeviceFloppy = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"stroke-width:var(--ng-icon__stroke-width, 2)\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path><path d=\"M6 4h10l4 4v10a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2\"></path><path d=\"M12 14m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0\"></path><path d=\"M14 4l0 4l-6 0l0 -4\"></path></svg>";
19
+ static ɵfac: i0.ɵɵFactoryDeclaration<SdCrudDetail, never>;
20
+ static ɵcmp: i0.ɵɵComponentDeclaration<SdCrudDetail, "sd-crud-detail", never, { "ready": { "alias": "ready"; "required": false; "isSignal": true; }; "initialized": { "alias": "initialized"; "required": false; "isSignal": true; }; "busyCount": { "alias": "busyCount"; "required": false; "isSignal": true; }; "restricted": { "alias": "restricted"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "viewType": { "alias": "viewType"; "required": true; "isSignal": true; }; }, { "ready": "readyChange"; "busyCount": "busyCountChange"; "submit": "submit"; }, ["commandTplRef", "bottomCommandTplRef"], ["*"], true, [{ directive: typeof i1.SdCommandDirective; inputs: {}; outputs: { "sdSaveCommand": "sdSaveCommand"; }; }]>;
21
+ }
22
+ //# sourceMappingURL=sd-crud-detail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sd-crud-detail.d.ts","sourceRoot":"","sources":["../../../src/data/crud/sd-crud-detail.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,WAAW,EAGjB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;;;AAM1E,qBAiFa,YAAY;IACvB,KAAK,+CAAgB;IACrB,WAAW,+CAAgB;IAC3B,SAAS,8CAAY;IACrB,UAAU,+CAAgB;IAC1B,QAAQ,+CAAgB;IACxB,QAAQ,kDAAgC;IAExC,QAAQ,qDAAiC;IAEzC,MAAM,iDAAY;IAElB,aAAa,gEAAiD;IAC9D,mBAAmB,gEAAuD;IAE1E,iBAAiB;IAIjB,SAAS,CAAC,QAAQ,CAAC,kBAAkB,sdAAsB;yCAnBhD,YAAY;2CAAZ,YAAY;CAoBxB"}