@simplysm/angular 14.0.11 → 14.0.12

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 (165) hide show
  1. package/README.md +8 -5
  2. package/dist/core/directives/sd-router-link.directive.js +2 -2
  3. package/dist/core/pipes/format.pipe.d.ts.map +1 -1
  4. package/dist/core/pipes/format.pipe.js +2 -0
  5. package/dist/core/plugins/commands/findTopOpenModalEl.d.ts +1 -1
  6. package/dist/core/plugins/commands/findTopOpenModalEl.d.ts.map +1 -1
  7. package/dist/core/plugins/commands/findTopOpenModalEl.js +2 -2
  8. package/dist/core/plugins/commands/sd-insert-command-event.plugin.d.ts +1 -0
  9. package/dist/core/plugins/commands/sd-insert-command-event.plugin.d.ts.map +1 -1
  10. package/dist/core/plugins/commands/sd-insert-command-event.plugin.js +4 -3
  11. package/dist/core/plugins/commands/sd-refresh-command-event.plugin.d.ts +1 -0
  12. package/dist/core/plugins/commands/sd-refresh-command-event.plugin.d.ts.map +1 -1
  13. package/dist/core/plugins/commands/sd-refresh-command-event.plugin.js +4 -3
  14. package/dist/core/plugins/commands/sd-save-command-event.plugin.d.ts +1 -0
  15. package/dist/core/plugins/commands/sd-save-command-event.plugin.d.ts.map +1 -1
  16. package/dist/core/plugins/commands/sd-save-command-event.plugin.js +4 -3
  17. package/dist/core/plugins/events/sd-intersection-event.plugin.d.ts.map +1 -1
  18. package/dist/core/plugins/events/sd-intersection-event.plugin.js +2 -3
  19. package/dist/core/plugins/events/sd-option-event.plugin.d.ts +1 -0
  20. package/dist/core/plugins/events/sd-option-event.plugin.d.ts.map +1 -1
  21. package/dist/core/plugins/events/sd-option-event.plugin.js +2 -1
  22. package/dist/core/plugins/sd-global-error-handler.plugin.d.ts.map +1 -1
  23. package/dist/core/plugins/sd-global-error-handler.plugin.js +3 -1
  24. package/dist/core/provideSdAngular.d.ts.map +1 -1
  25. package/dist/core/provideSdAngular.js +14 -4
  26. package/dist/core/providers/sd-app-structure.provider.d.ts.map +1 -1
  27. package/dist/core/providers/sd-app-structure.provider.js +8 -7
  28. package/dist/core/providers/sd-file-dialog.provider.d.ts.map +1 -1
  29. package/dist/core/providers/sd-file-dialog.provider.js +15 -7
  30. package/dist/core/providers/sd-local-storage.provider.d.ts.map +1 -1
  31. package/dist/core/providers/sd-local-storage.provider.js +6 -1
  32. package/dist/core/providers/sd-navigate-window.provider.js +4 -1
  33. package/dist/core/providers/sd-print.provider.js +2 -2
  34. package/dist/core/providers/sd-shared-data.provider.d.ts.map +1 -1
  35. package/dist/core/providers/sd-shared-data.provider.js +14 -3
  36. package/dist/core/utils/injectParent.js +9 -5
  37. package/dist/core/utils/setups/setupModelHook.d.ts.map +1 -1
  38. package/dist/core/utils/setups/setupModelHook.js +4 -1
  39. package/dist/core/utils/setups/setupRevealOnShow.d.ts.map +1 -1
  40. package/dist/core/utils/setups/setupRevealOnShow.js +3 -2
  41. package/dist/core/utils/useExpandingManager.d.ts.map +1 -1
  42. package/dist/core/utils/useExpandingManager.js +3 -2
  43. package/dist/core/utils/useSdSystemConfigResource.d.ts +1 -1
  44. package/dist/core/utils/useSdSystemConfigResource.d.ts.map +1 -1
  45. package/dist/core/utils/useSdSystemConfigResource.js +13 -12
  46. package/dist/core/utils/withBusy.d.ts +3 -0
  47. package/dist/core/utils/withBusy.d.ts.map +1 -0
  48. package/dist/core/utils/withBusy.js +9 -0
  49. package/dist/features/address/sd-address-search.modal.d.ts.map +1 -1
  50. package/dist/features/address/sd-address-search.modal.js +5 -2
  51. package/dist/features/data-view/sd-data-detail.control.d.ts.map +1 -1
  52. package/dist/features/data-view/sd-data-detail.control.js +14 -18
  53. package/dist/features/data-view/sd-data-sheet.control.d.ts.map +1 -1
  54. package/dist/features/data-view/sd-data-sheet.control.js +23 -30
  55. package/dist/features/permission-table/sd-permission-table.control.d.ts +4 -0
  56. package/dist/features/permission-table/sd-permission-table.control.d.ts.map +1 -1
  57. package/dist/features/permission-table/sd-permission-table.control.js +113 -43
  58. package/dist/features/shared-data/matchesSearchText.d.ts +2 -0
  59. package/dist/features/shared-data/matchesSearchText.d.ts.map +1 -0
  60. package/dist/features/shared-data/matchesSearchText.js +11 -0
  61. package/dist/features/shared-data/sd-shared-data-select-button.control.d.ts +2 -2
  62. package/dist/features/shared-data/sd-shared-data-select-button.control.d.ts.map +1 -1
  63. package/dist/features/shared-data/sd-shared-data-select-list.control.d.ts +1 -0
  64. package/dist/features/shared-data/sd-shared-data-select-list.control.d.ts.map +1 -1
  65. package/dist/features/shared-data/sd-shared-data-select-list.control.js +16 -11
  66. package/dist/features/shared-data/sd-shared-data-select.control.d.ts +2 -1
  67. package/dist/features/shared-data/sd-shared-data-select.control.d.ts.map +1 -1
  68. package/dist/features/shared-data/sd-shared-data-select.control.js +44 -29
  69. package/dist/index.d.ts +4 -3
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +3 -2
  72. package/dist/ui/data/sheet/sd-sheet.control.d.ts +5 -2
  73. package/dist/ui/data/sheet/sd-sheet.control.d.ts.map +1 -1
  74. package/dist/ui/data/sheet/sd-sheet.control.js +48 -47
  75. package/dist/ui/data/sheet/types.d.ts +5 -1
  76. package/dist/ui/data/sheet/types.d.ts.map +1 -1
  77. package/dist/ui/data/sheet/useSheetCellAgent.d.ts.map +1 -1
  78. package/dist/ui/data/sheet/useSheetCellAgent.js +8 -4
  79. package/dist/ui/data/sheet/useSheetColumnFixing.d.ts +6 -0
  80. package/dist/ui/data/sheet/useSheetColumnFixing.d.ts.map +1 -1
  81. package/dist/ui/data/sheet/useSheetColumnFixing.js +6 -0
  82. package/dist/ui/form/editor/sd-tiptap-editor.control.d.ts +2 -2
  83. package/dist/ui/form/editor/sd-tiptap-editor.control.d.ts.map +1 -1
  84. package/dist/ui/form/editor/sd-tiptap-editor.control.js +15 -13
  85. package/dist/ui/form/input/sd-date-range.picker.d.ts.map +1 -1
  86. package/dist/ui/form/input/sd-date-range.picker.js +8 -1
  87. package/dist/ui/form/select/sd-select.control.d.ts.map +1 -1
  88. package/dist/ui/form/select/sd-select.control.js +20 -16
  89. package/dist/ui/layout/dock/sd-dock.control.js +4 -4
  90. package/dist/ui/navigation/pagination/sd-pagination.control.js +1 -1
  91. package/dist/ui/navigation/sidebar/sd-sidebar-menu.control.d.ts +7 -13
  92. package/dist/ui/navigation/sidebar/sd-sidebar-menu.control.d.ts.map +1 -1
  93. package/dist/ui/navigation/sidebar/sd-sidebar-menu.control.js +1 -1
  94. package/dist/ui/navigation/topbar/sd-topbar-menu.control.d.ts +7 -13
  95. package/dist/ui/navigation/topbar/sd-topbar-menu.control.d.ts.map +1 -1
  96. package/dist/ui/navigation/topbar/sd-topbar-menu.control.js +1 -1
  97. package/dist/ui/overlay/dropdown/sd-dropdown-popup.control.d.ts +0 -3
  98. package/dist/ui/overlay/dropdown/sd-dropdown-popup.control.d.ts.map +1 -1
  99. package/dist/ui/overlay/dropdown/sd-dropdown-popup.control.js +8 -21
  100. package/dist/ui/overlay/dropdown/sd-dropdown.control.d.ts +1 -1
  101. package/dist/ui/overlay/dropdown/sd-dropdown.control.d.ts.map +1 -1
  102. package/dist/ui/overlay/dropdown/sd-dropdown.control.js +19 -20
  103. package/dist/ui/overlay/modal/sd-modal.control.d.ts.map +1 -1
  104. package/dist/ui/overlay/modal/sd-modal.control.js +21 -5
  105. package/dist/ui/overlay/toast/sd-toast.provider.d.ts +1 -0
  106. package/dist/ui/overlay/toast/sd-toast.provider.d.ts.map +1 -1
  107. package/dist/ui/overlay/toast/sd-toast.provider.js +16 -2
  108. package/dist/ui/visual/sd-barcode.control.d.ts +2 -2
  109. package/dist/ui/visual/sd-barcode.control.d.ts.map +1 -1
  110. package/dist/ui/visual/sd-barcode.control.js +25 -18
  111. package/dist/ui/visual/sd-progress.control.d.ts.map +1 -1
  112. package/dist/ui/visual/sd-progress.control.js +1 -1
  113. package/docs/core.md +19 -0
  114. package/docs/features.md +25 -0
  115. package/docs/ui-data.md +20 -4
  116. package/docs/ui-navigation.md +8 -44
  117. package/package.json +25 -25
  118. package/src/core/directives/sd-router-link.directive.ts +1 -1
  119. package/src/core/pipes/format.pipe.ts +1 -0
  120. package/src/core/plugins/commands/findTopOpenModalEl.ts +2 -2
  121. package/src/core/plugins/commands/sd-insert-command-event.plugin.ts +5 -3
  122. package/src/core/plugins/commands/sd-refresh-command-event.plugin.ts +5 -3
  123. package/src/core/plugins/commands/sd-save-command-event.plugin.ts +5 -3
  124. package/src/core/plugins/events/sd-intersection-event.plugin.ts +2 -3
  125. package/src/core/plugins/events/sd-option-event.plugin.ts +3 -1
  126. package/src/core/plugins/sd-global-error-handler.plugin.ts +4 -1
  127. package/src/core/provideSdAngular.ts +17 -4
  128. package/src/core/providers/sd-app-structure.provider.ts +7 -7
  129. package/src/core/providers/sd-file-dialog.provider.ts +18 -9
  130. package/src/core/providers/sd-local-storage.provider.ts +5 -1
  131. package/src/core/providers/sd-navigate-window.provider.ts +3 -3
  132. package/src/core/providers/sd-print.provider.ts +2 -2
  133. package/src/core/providers/sd-shared-data.provider.ts +14 -3
  134. package/src/core/utils/injectParent.ts +10 -6
  135. package/src/core/utils/setups/setupModelHook.ts +6 -1
  136. package/src/core/utils/setups/setupRevealOnShow.ts +3 -2
  137. package/src/core/utils/useExpandingManager.ts +4 -2
  138. package/src/core/utils/useSdSystemConfigResource.ts +13 -11
  139. package/src/core/utils/withBusy.ts +13 -0
  140. package/src/features/address/sd-address-search.modal.ts +5 -2
  141. package/src/features/data-view/sd-data-detail.control.ts +37 -33
  142. package/src/features/data-view/sd-data-sheet.control.ts +61 -54
  143. package/src/features/permission-table/sd-permission-table.control.ts +127 -51
  144. package/src/features/shared-data/matchesSearchText.ts +16 -0
  145. package/src/features/shared-data/sd-shared-data-select-button.control.ts +4 -4
  146. package/src/features/shared-data/sd-shared-data-select-list.control.ts +19 -11
  147. package/src/features/shared-data/sd-shared-data-select.control.ts +50 -30
  148. package/src/index.ts +4 -8
  149. package/src/ui/data/sheet/sd-sheet.control.ts +51 -48
  150. package/src/ui/data/sheet/types.ts +6 -1
  151. package/src/ui/data/sheet/useSheetCellAgent.ts +5 -3
  152. package/src/ui/data/sheet/useSheetColumnFixing.ts +6 -0
  153. package/src/ui/form/editor/sd-tiptap-editor.control.ts +14 -12
  154. package/src/ui/form/input/sd-date-range.picker.ts +7 -1
  155. package/src/ui/form/select/sd-select.control.ts +18 -14
  156. package/src/ui/layout/dock/sd-dock.control.ts +4 -4
  157. package/src/ui/navigation/pagination/sd-pagination.control.ts +1 -1
  158. package/src/ui/navigation/sidebar/sd-sidebar-menu.control.ts +7 -14
  159. package/src/ui/navigation/topbar/sd-topbar-menu.control.ts +7 -14
  160. package/src/ui/overlay/dropdown/sd-dropdown-popup.control.ts +2 -17
  161. package/src/ui/overlay/dropdown/sd-dropdown.control.ts +19 -19
  162. package/src/ui/overlay/modal/sd-modal.control.ts +21 -5
  163. package/src/ui/overlay/toast/sd-toast.provider.ts +14 -1
  164. package/src/ui/visual/sd-barcode.control.ts +18 -16
  165. package/src/ui/visual/sd-progress.control.ts +1 -1
package/README.md CHANGED
@@ -62,6 +62,7 @@ Providers, plugins, directives, pipes, and utility functions that form the frame
62
62
  | `useViewTitleSignal` | function | Current view title signal |
63
63
  | `useViewTypeSignal` | function | View context type signal (page/modal/control) |
64
64
  | `useExpandingManager` | function | Tree expand/collapse state manager |
65
+ | `IExpandItemDef` | interface | Tree node definition (item, depth, hasChildren) |
65
66
  | `useSelectionManager` | function | Item selection state manager |
66
67
  | `useSortingManager` | function | Multi-column sorting state manager |
67
68
  | `injectParent` | function | Finds parent component instance |
@@ -79,10 +80,12 @@ Providers, plugins, directives, pipes, and utility functions that form the frame
79
80
  | `ISdPrintInput` | interface | Print template input descriptor |
80
81
  | `SdItemOfTemplateContext` | interface | Template context for item iteration |
81
82
  | `ISortingDef` | interface | Sort definition (key + direction) |
83
+ | `withBusy` | function | Wraps async function with busy signal increment/decrement |
82
84
  | `ISdStatePreset` | interface | Named state preset |
83
85
  | `TSdViewType` | type | `"page" \| "modal" \| "control"` |
84
86
  | `TDirectiveInputSignals` | type | Extracts input signal value types from component |
85
87
  | `TUndefToOptional` | type | Converts undefined-accepting props to optional |
88
+ | `TWithOptional` | type | Converts specified keys to optional |
86
89
 
87
90
  → See [docs/core.md](./docs/core.md) for details.
88
91
 
@@ -93,6 +96,7 @@ High-level feature components: address search, base container, data views, and s
93
96
  | API | Type | Description |
94
97
  |-----|------|-------------|
95
98
  | `SdAddressSearchModal` | component | Korean address search via Daum Postcode widget |
99
+ | `SdPermissionTableControl` | component | Permission matrix table with use/edit checkboxes |
96
100
  | `SdBaseContainerControl` | component | Page/modal layout shell with busy state and access restriction |
97
101
  | `SdDataSheetControl` | component | Presentation layer for data sheet views |
98
102
  | `AbsSdDataSheet` | abstract directive | Base for data sheet screens (CRUD, pagination, sorting) |
@@ -183,10 +187,8 @@ High-level feature components: address search, base container, data views, and s
183
187
  | `SdTopbarControl` | component | Top navigation bar |
184
188
  | `SdTopbarMenuControl` | component | Horizontal topbar menu |
185
189
  | `SdTopbarUserControl` | component | Topbar user dropdown |
186
- | `ISdSidebarMenu` | interface | Sidebar menu item |
187
- | `ISidebarUserMenu` | interface | Sidebar user menu |
188
- | `ISdTopbarMenu` | interface | Topbar menu item |
189
- | `ISdTopbarUserMenu` | interface | Topbar user menu item |
190
+ | `ISidebarUserMenu` | interface | Sidebar user dropdown menu item |
191
+ | `ISdTopbarUserMenu` | interface | Topbar user dropdown menu item |
190
192
 
191
193
  → See [docs/ui-navigation.md](./docs/ui-navigation.md) for details.
192
194
 
@@ -202,7 +204,8 @@ High-level feature components: address search, base container, data views, and s
202
204
  | `ISdSheetColumnDef` | interface | Runtime column definition |
203
205
  | `ISdSheetHeaderDef` | interface | Header cell definition |
204
206
  | `ISdSheetConfig` | interface | Persisted sheet configuration |
205
- | `ISdSheetItemKeydownEventParam` | interface | Sheet keydown event payload |
207
+ | `ISdSheetItemKeydownEventParam` | interface | Sheet row keydown event payload |
208
+ | `ISdSheetCellKeydownEventParam` | interface | Sheet cell keydown event payload |
206
209
 
207
210
  → See [docs/ui-data.md](./docs/ui-data.md) for details.
208
211
 
@@ -43,7 +43,7 @@ export class SdRouterLinkDirective {
43
43
  static ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: SdRouterLinkDirective, selectors: [["", "sd-router-link", ""]], hostVars: 2, hostBindings: function SdRouterLinkDirective_HostBindings(rf, ctx) { if (rf & 1) {
44
44
  i0.ɵɵlistener("click", function SdRouterLinkDirective_click_HostBindingHandler($event) { return ctx.onClick($event); });
45
45
  } if (rf & 2) {
46
- i0.ɵɵstyleProp("cursor", "pointer");
46
+ i0.ɵɵstyleProp("cursor", ctx.option() ? "pointer" : "");
47
47
  } }, inputs: { option: [1, "sd-router-link", "option"] } });
48
48
  }
49
49
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SdRouterLinkDirective, [{
@@ -52,7 +52,7 @@ export class SdRouterLinkDirective {
52
52
  selector: "[sd-router-link]",
53
53
  standalone: true,
54
54
  host: {
55
- "[style.cursor]": "'pointer'",
55
+ "[style.cursor]": "option() ? 'pointer' : ''",
56
56
  "(click)": "onClick($event)",
57
57
  },
58
58
  }]
@@ -1 +1 @@
1
- {"version":3,"file":"format.pipe.d.ts","sourceRoot":"","sources":["../../../src/core/pipes/format.pipe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;;AAE3D,qBAIa,UAAW,YAAW,aAAa;IAC9C,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;yCADvE,UAAU;uCAAV,UAAU;CA6BtB"}
1
+ {"version":3,"file":"format.pipe.d.ts","sourceRoot":"","sources":["../../../src/core/pipes/format.pipe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;;AAE3D,qBAIa,UAAW,YAAW,aAAa;IAC9C,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;yCADvE,UAAU;uCAAV,UAAU;CA8BtB"}
@@ -13,6 +13,8 @@ export class FormatPipe {
13
13
  const formatItems = format.split("|");
14
14
  for (const formatItem of formatItems) {
15
15
  const fullLength = formatItem.match(/X/g)?.length;
16
+ if (fullLength == null)
17
+ continue;
16
18
  if (fullLength === value.length) {
17
19
  let result = "";
18
20
  let valCur = 0;
@@ -4,5 +4,5 @@
4
4
  *
5
5
  * SdModalProvider를 import하지 않아 순환 의존을 회피한다.
6
6
  */
7
- export declare function findTopOpenModalEl(): HTMLElement | null;
7
+ export declare function findTopOpenModalEl(doc: Document): HTMLElement | null;
8
8
  //# sourceMappingURL=findTopOpenModalEl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"findTopOpenModalEl.d.ts","sourceRoot":"","sources":["../../../../src/core/plugins/commands/findTopOpenModalEl.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,WAAW,GAAG,IAAI,CAgBvD"}
1
+ {"version":3,"file":"findTopOpenModalEl.d.ts","sourceRoot":"","sources":["../../../../src/core/plugins/commands/findTopOpenModalEl.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,QAAQ,GAAG,WAAW,GAAG,IAAI,CAgBpE"}
@@ -4,8 +4,8 @@
4
4
  *
5
5
  * SdModalProvider를 import하지 않아 순환 의존을 회피한다.
6
6
  */
7
- export function findTopOpenModalEl() {
8
- const openModals = document.querySelectorAll("sd-modal[data-sd-open]");
7
+ export function findTopOpenModalEl(doc) {
8
+ const openModals = doc.querySelectorAll("sd-modal[data-sd-open]");
9
9
  if (openModals.length === 0)
10
10
  return null;
11
11
  let topModal = openModals[0];
@@ -1,6 +1,7 @@
1
1
  import { EventManagerPlugin } from "@angular/platform-browser";
2
2
  import * as i0 from "@angular/core";
3
3
  export declare class SdInsertCommandEventPlugin extends EventManagerPlugin {
4
+ private readonly _document;
4
5
  constructor();
5
6
  supports(eventName: string): boolean;
6
7
  addEventListener(element: HTMLElement, eventName: string, handler: (event: Event) => void): () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"sd-insert-command-event.plugin.d.ts","sourceRoot":"","sources":["../../../../src/core/plugins/commands/sd-insert-command-event.plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;;AAI/D,qBACa,0BAA2B,SAAQ,kBAAkB;;IAKvD,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIpC,gBAAgB,CACvB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAC9B,MAAM,IAAI;yCAbF,0BAA0B;6CAA1B,0BAA0B;CA+BtC"}
1
+ {"version":3,"file":"sd-insert-command-event.plugin.d.ts","sourceRoot":"","sources":["../../../../src/core/plugins/commands/sd-insert-command-event.plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;;AAI/D,qBACa,0BAA2B,SAAQ,kBAAkB;IAChE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;;IAMrC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIpC,gBAAgB,CACvB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAC9B,MAAM,IAAI;yCAfF,0BAA0B;6CAA1B,0BAA0B;CAiCtC"}
@@ -4,6 +4,7 @@ import { DOCUMENT } from "@angular/common";
4
4
  import { findTopOpenModalEl } from "./findTopOpenModalEl";
5
5
  import * as i0 from "@angular/core";
6
6
  export class SdInsertCommandEventPlugin extends EventManagerPlugin {
7
+ _document = inject(DOCUMENT);
7
8
  constructor() {
8
9
  super(inject(DOCUMENT));
9
10
  }
@@ -13,7 +14,7 @@ export class SdInsertCommandEventPlugin extends EventManagerPlugin {
13
14
  addEventListener(element, eventName, handler) {
14
15
  const listener = (event) => {
15
16
  if (event.key === "Insert" && event.ctrlKey && !event.altKey && !event.shiftKey) {
16
- const topModal = findTopOpenModalEl();
17
+ const topModal = findTopOpenModalEl(this._document);
17
18
  if (topModal != null && !topModal.contains(element))
18
19
  return;
19
20
  event.preventDefault();
@@ -21,9 +22,9 @@ export class SdInsertCommandEventPlugin extends EventManagerPlugin {
21
22
  handler(event);
22
23
  }
23
24
  };
24
- document.addEventListener("keydown", listener);
25
+ this._document.addEventListener("keydown", listener);
25
26
  return () => {
26
- document.removeEventListener("keydown", listener);
27
+ this._document.removeEventListener("keydown", listener);
27
28
  };
28
29
  }
29
30
  static ɵfac = function SdInsertCommandEventPlugin_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SdInsertCommandEventPlugin)(); };
@@ -1,6 +1,7 @@
1
1
  import { EventManagerPlugin } from "@angular/platform-browser";
2
2
  import * as i0 from "@angular/core";
3
3
  export declare class SdRefreshCommandEventPlugin extends EventManagerPlugin {
4
+ private readonly _document;
4
5
  constructor();
5
6
  supports(eventName: string): eventName is "sdRefreshCommand";
6
7
  addEventListener(element: HTMLElement, eventName: string, handler: (event: Event) => void): () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"sd-refresh-command-event.plugin.d.ts","sourceRoot":"","sources":["../../../../src/core/plugins/commands/sd-refresh-command-event.plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;;AAI/D,qBACa,2BAA4B,SAAQ,kBAAkB;;IAKxD,QAAQ,CAAC,SAAS,EAAE,MAAM;IAI1B,gBAAgB,CACvB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAC9B,MAAM,IAAI;yCAbF,2BAA2B;6CAA3B,2BAA2B;CAoCvC"}
1
+ {"version":3,"file":"sd-refresh-command-event.plugin.d.ts","sourceRoot":"","sources":["../../../../src/core/plugins/commands/sd-refresh-command-event.plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;;AAI/D,qBACa,2BAA4B,SAAQ,kBAAkB;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;;IAMrC,QAAQ,CAAC,SAAS,EAAE,MAAM;IAI1B,gBAAgB,CACvB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAC9B,MAAM,IAAI;yCAfF,2BAA2B;6CAA3B,2BAA2B;CAsCvC"}
@@ -4,6 +4,7 @@ import { DOCUMENT } from "@angular/common";
4
4
  import { findTopOpenModalEl } from "./findTopOpenModalEl";
5
5
  import * as i0 from "@angular/core";
6
6
  export class SdRefreshCommandEventPlugin extends EventManagerPlugin {
7
+ _document = inject(DOCUMENT);
7
8
  constructor() {
8
9
  super(inject(DOCUMENT));
9
10
  }
@@ -16,7 +17,7 @@ export class SdRefreshCommandEventPlugin extends EventManagerPlugin {
16
17
  event.ctrlKey &&
17
18
  event.altKey &&
18
19
  !event.shiftKey) {
19
- const topModal = findTopOpenModalEl();
20
+ const topModal = findTopOpenModalEl(this._document);
20
21
  if (topModal != null && !topModal.contains(element))
21
22
  return;
22
23
  event.preventDefault();
@@ -24,9 +25,9 @@ export class SdRefreshCommandEventPlugin extends EventManagerPlugin {
24
25
  handler(event);
25
26
  }
26
27
  };
27
- document.addEventListener("keydown", listener);
28
+ this._document.addEventListener("keydown", listener);
28
29
  return () => {
29
- document.removeEventListener("keydown", listener);
30
+ this._document.removeEventListener("keydown", listener);
30
31
  };
31
32
  }
32
33
  static ɵfac = function SdRefreshCommandEventPlugin_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SdRefreshCommandEventPlugin)(); };
@@ -1,6 +1,7 @@
1
1
  import { EventManagerPlugin } from "@angular/platform-browser";
2
2
  import * as i0 from "@angular/core";
3
3
  export declare class SdSaveCommandEventPlugin extends EventManagerPlugin {
4
+ private readonly _document;
4
5
  constructor();
5
6
  supports(eventName: string): eventName is "sdSaveCommand";
6
7
  addEventListener(element: HTMLElement, eventName: string, handler: (event: Event) => void): () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"sd-save-command-event.plugin.d.ts","sourceRoot":"","sources":["../../../../src/core/plugins/commands/sd-save-command-event.plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;;AAI/D,qBACa,wBAAyB,SAAQ,kBAAkB;;IAKrD,QAAQ,CAAC,SAAS,EAAE,MAAM;IAI1B,gBAAgB,CACvB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAC9B,MAAM,IAAI;yCAbF,wBAAwB;6CAAxB,wBAAwB;CAoCpC"}
1
+ {"version":3,"file":"sd-save-command-event.plugin.d.ts","sourceRoot":"","sources":["../../../../src/core/plugins/commands/sd-save-command-event.plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;;AAI/D,qBACa,wBAAyB,SAAQ,kBAAkB;IAC9D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;;IAMrC,QAAQ,CAAC,SAAS,EAAE,MAAM;IAI1B,gBAAgB,CACvB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAC9B,MAAM,IAAI;yCAfF,wBAAwB;6CAAxB,wBAAwB;CAsCpC"}
@@ -4,6 +4,7 @@ import { DOCUMENT } from "@angular/common";
4
4
  import { findTopOpenModalEl } from "./findTopOpenModalEl";
5
5
  import * as i0 from "@angular/core";
6
6
  export class SdSaveCommandEventPlugin extends EventManagerPlugin {
7
+ _document = inject(DOCUMENT);
7
8
  constructor() {
8
9
  super(inject(DOCUMENT));
9
10
  }
@@ -16,7 +17,7 @@ export class SdSaveCommandEventPlugin extends EventManagerPlugin {
16
17
  event.ctrlKey &&
17
18
  !event.altKey &&
18
19
  !event.shiftKey) {
19
- const topModal = findTopOpenModalEl();
20
+ const topModal = findTopOpenModalEl(this._document);
20
21
  if (topModal != null && !topModal.contains(element))
21
22
  return;
22
23
  event.preventDefault();
@@ -24,9 +25,9 @@ export class SdSaveCommandEventPlugin extends EventManagerPlugin {
24
25
  handler(event);
25
26
  }
26
27
  };
27
- document.addEventListener("keydown", listener);
28
+ this._document.addEventListener("keydown", listener);
28
29
  return () => {
29
- document.removeEventListener("keydown", listener);
30
+ this._document.removeEventListener("keydown", listener);
30
31
  };
31
32
  }
32
33
  static ɵfac = function SdSaveCommandEventPlugin_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SdSaveCommandEventPlugin)(); };
@@ -1 +1 @@
1
- {"version":3,"file":"sd-intersection-event.plugin.d.ts","sourceRoot":"","sources":["../../../../src/core/plugins/events/sd-intersection-event.plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;;AAG/D,qBACa,yBAA0B,SAAQ,kBAAkB;;IAKtD,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIpC,gBAAgB,CACvB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,GAC7C,MAAM,IAAI;yCAbF,yBAAyB;6CAAzB,yBAAyB;CA0BrC;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,yBAAyB,CAAC;CAClC"}
1
+ {"version":3,"file":"sd-intersection-event.plugin.d.ts","sourceRoot":"","sources":["../../../../src/core/plugins/events/sd-intersection-event.plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;;AAG/D,qBACa,yBAA0B,SAAQ,kBAAkB;;IAKtD,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIpC,gBAAgB,CACvB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,GAC7C,MAAM,IAAI;yCAbF,yBAAyB;6CAAzB,yBAAyB;CAyBrC;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,yBAAyB,CAAC;CAClC"}
@@ -11,10 +11,9 @@ export class SdIntersectionEventPlugin extends EventManagerPlugin {
11
11
  }
12
12
  addEventListener(element, eventName, handler) {
13
13
  const observer = new IntersectionObserver((entries) => {
14
- const entry = entries.single();
15
- if (!entry)
14
+ if (entries.length === 0)
16
15
  return;
17
- handler({ entry });
16
+ handler({ entry: entries[entries.length - 1] });
18
17
  });
19
18
  observer.observe(element);
20
19
  return () => {
@@ -1,6 +1,7 @@
1
1
  import { EventManagerPlugin } from "@angular/platform-browser";
2
2
  import * as i0 from "@angular/core";
3
3
  export declare class SdOptionEventPlugin extends EventManagerPlugin {
4
+ private readonly _document;
4
5
  constructor();
5
6
  supports(eventName: string): boolean;
6
7
  addEventListener(element: HTMLElement, eventName: string, handler: (event: Event) => void): () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"sd-option-event.plugin.d.ts","sourceRoot":"","sources":["../../../../src/core/plugins/events/sd-option-event.plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;;AAG/D,qBACa,mBAAoB,SAAQ,kBAAkB;;IAKhD,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAYpC,gBAAgB,CACvB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAC9B,MAAM,IAAI;yCArBF,mBAAmB;6CAAnB,mBAAmB;CAqC/B"}
1
+ {"version":3,"file":"sd-option-event.plugin.d.ts","sourceRoot":"","sources":["../../../../src/core/plugins/events/sd-option-event.plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;;AAG/D,qBACa,mBAAoB,SAAQ,kBAAkB;IACzD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;;IAMrC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAYpC,gBAAgB,CACvB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAC9B,MAAM,IAAI;yCAvBF,mBAAmB;6CAAnB,mBAAmB;CAuC/B"}
@@ -3,6 +3,7 @@ import { EventManagerPlugin } from "@angular/platform-browser";
3
3
  import { DOCUMENT } from "@angular/common";
4
4
  import * as i0 from "@angular/core";
5
5
  export class SdOptionEventPlugin extends EventManagerPlugin {
6
+ _document = inject(DOCUMENT);
6
7
  constructor() {
7
8
  super(inject(DOCUMENT));
8
9
  }
@@ -11,7 +12,7 @@ export class SdOptionEventPlugin extends EventManagerPlugin {
11
12
  return false;
12
13
  const realEventName = eventName.replace(/\.(capture|passive|once)/g, "");
13
14
  return (`on${realEventName}` in window ||
14
- `on${realEventName}` in document ||
15
+ `on${realEventName}` in this._document ||
15
16
  `on${realEventName}` in HTMLElement.prototype);
16
17
  }
17
18
  addEventListener(element, eventName, handler) {
@@ -1 +1 @@
1
- {"version":3,"file":"sd-global-error-handler.plugin.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/sd-global-error-handler.plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EAIb,MAAM,eAAe,CAAC;;AAGvB,qBACa,0BAA2B,YAAW,YAAY;IAC7D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA+B;IAC5D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA+B;IAC1D,OAAO,CAAC,kBAAkB,CAAS;IAEnC,WAAW,CAAC,KAAK,EAAE,GAAG;IAoEtB,OAAO,CAAC,oBAAoB;yCAzEjB,0BAA0B;6CAA1B,0BAA0B;CAiHtC"}
1
+ {"version":3,"file":"sd-global-error-handler.plugin.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/sd-global-error-handler.plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EAIb,MAAM,eAAe,CAAC;;AAGvB,qBACa,0BAA2B,YAAW,YAAY;IAC7D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA+B;IAC5D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA+B;IAC1D,OAAO,CAAC,kBAAkB,CAAS;IAEnC,WAAW,CAAC,KAAK,EAAE,GAAG;IAuEtB,OAAO,CAAC,oBAAoB;yCA5EjB,0BAA0B;6CAA1B,0BAA0B;CAoHtC"}
@@ -27,7 +27,7 @@ export class SdGlobalErrorHandlerPlugin {
27
27
  }
28
28
  else {
29
29
  this._displayErrorMessage("처리되지 않은 Promise 거부", {
30
- Event: JSON.stringify(event, null, 2),
30
+ Reason: String(reason),
31
31
  });
32
32
  }
33
33
  }
@@ -65,6 +65,8 @@ export class SdGlobalErrorHandlerPlugin {
65
65
  catch (err) {
66
66
  // eslint-disable-next-line no-console
67
67
  console.error(err, event);
68
+ document.body.textContent =
69
+ `[에러 처리 실패]\n원본: ${String(event)}\n2차: ${String(err)}`;
68
70
  const appRef = this._envInjector.get(ApplicationRef);
69
71
  appRef.destroy();
70
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"provideSdAngular.d.ts","sourceRoot":"","sources":["../../src/core/provideSdAngular.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAoC1D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,oBAAoB,CAqHlF"}
1
+ {"version":3,"file":"provideSdAngular.d.ts","sourceRoot":"","sources":["../../src/core/provideSdAngular.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAoC1D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,oBAAoB,CAkIlF"}
@@ -36,8 +36,13 @@ export function provideSdAngular(opt) {
36
36
  if (savedDark != null) {
37
37
  sdTheme.dark.set(savedDark);
38
38
  }
39
+ let prevDark = sdTheme.dark();
39
40
  effect(() => {
40
- sdLocalStorage.set("sd-theme-dark", sdTheme.dark());
41
+ const dark = sdTheme.dark();
42
+ if (dark !== prevDark) {
43
+ sdLocalStorage.set("sd-theme-dark", dark);
44
+ prevDark = dark;
45
+ }
41
46
  });
42
47
  }),
43
48
  provideEnvironmentInitializer(() => {
@@ -79,6 +84,9 @@ export function provideSdAngular(opt) {
79
84
  const swUpdate = inject(SwUpdate, { optional: true });
80
85
  const destroyRef = inject(DestroyRef);
81
86
  let timerId;
87
+ let failCount = 0;
88
+ const BASE_INTERVAL = 5 * 60 * 1000;
89
+ const MAX_INTERVAL = 60 * 60 * 1000;
82
90
  const updateFn = async () => {
83
91
  try {
84
92
  if (swUpdate?.isEnabled) {
@@ -90,12 +98,14 @@ export function provideSdAngular(opt) {
90
98
  }
91
99
  }
92
100
  }
101
+ failCount = 0;
93
102
  }
94
103
  catch {
95
- // checkForUpdate 실패 시 무시하고 다음 폴링 주기에 재시도
104
+ failCount++;
96
105
  }
97
106
  finally {
98
- timerId = setTimeout(updateFn, 5 * 60 * 1000);
107
+ const interval = Math.min(BASE_INTERVAL * Math.pow(2, Math.max(0, failCount - 1)), MAX_INTERVAL);
108
+ timerId = setTimeout(updateFn, interval);
99
109
  }
100
110
  };
101
111
  void updateFn();
@@ -119,7 +129,7 @@ export function provideSdAngular(opt) {
119
129
  else if (event instanceof NavigationEnd ||
120
130
  event instanceof NavigationCancel ||
121
131
  event instanceof NavigationError) {
122
- sdBusy.globalBusyCount.update((v) => v - 1);
132
+ sdBusy.globalBusyCount.update((v) => Math.max(0, v - 1));
123
133
  }
124
134
  });
125
135
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"sd-app-structure.provider.d.ts","sourceRoot":"","sources":["../../../src/core/providers/sd-app-structure.provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;;AAE5C,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAG5F;AAID,8BACsB,sBAAsB,CAAC,OAAO,GAAG,OAAO;IAC5D,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,EAAE,CAAC;IAC/C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,CAAC;IACtD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;IAEjE,WAAW,6BAET;IACF,eAAe,iCAEb;IAEF,yBAAyB,CAAC,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,GAAE,MAAM,EAAO;IAIzF,kBAAkB,CAAC,QAAQ,EAAE,MAAM;IAInC,sBAAsB,CAAC,QAAQ,EAAE,MAAM;IAIvC,kBAAkB,CAAC,CAAC,SAAS,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE;yCAxBzD,sBAAsB;6CAAtB,sBAAsB;CAgC3C;AAED,8BAAsB,mBAAmB;IAGvC,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM;IAa1F,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,CAAC,SAAS,MAAM,EACjD,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,EAAE,EACrC,SAAS,EAAE,MAAM,EAAE,EACnB,QAAQ,EAAE,CAAC,EAAE,EACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC9C,CAAC,EAAE;IAqBN,MAAM,CAAC,sBAAsB,CAAC,OAAO,EACnC,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,EAAE,EACrC,QAAQ,EAAE,MAAM,GACf,mBAAmB,CAAC,OAAO,CAAC,EAAE;IAoBjC,MAAM,CAAC,QAAQ,CAAC,OAAO,EACrB,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,EAAE,EACrC,SAAS,EAAE,MAAM,EAAE,EACnB,aAAa,EAAE,OAAO,EAAE,GAAG,SAAS,EACpC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC9C,OAAO,CAAC,OAAO,CAAC,EAAE;IA6CrB,MAAM,CAAC,YAAY,CAAC,OAAO,EACzB,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,EAAE,EACrC,aAAa,EAAE,OAAO,EAAE,GAAG,SAAS,EACpC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC9C,WAAW,CAAC,OAAO,CAAC,EAAE;IA0DzB,MAAM,CAAC,cAAc,CAAC,OAAO,EAC3B,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,EAAE,EACrC,SAAS,EAAE,MAAM,EAAE,EACnB,aAAa,EAAE,OAAO,EAAE,GAAG,SAAS,GACnC,aAAa,CAAC,OAAO,CAAC,EAAE;IAyC3B,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAC/B,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,EAAE,EACrC,aAAa,EAAE,OAAO,EAAE,GAAG,SAAS;IAgFtC,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAsBpC,OAAO,CAAC,MAAM,CAAC,gBAAgB;CAiBhC;AAED,MAAM,MAAM,mBAAmB,CAAC,OAAO,GAAG,OAAO,IAC7C,wBAAwB,CAAC,OAAO,CAAC,GACjC,uBAAuB,CAAC,OAAO,CAAC,CAAC;AAErC,UAAU,wBAAwB,CAAC,OAAO;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,mBAAmB,CAAC,OAAO,CAAC,EAAE,CAAC;CAC1C;AAED,UAAU,uBAAuB,CAAC,OAAO;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,4BAA4B,CAAC,OAAO,CAAC,EAAE,CAAC;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,UAAU,4BAA4B,CAAC,OAAO;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B,KAAK,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,OAAO,CAAC,OAAO,GAAG,OAAO;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,OAAO,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC;IAC/B,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,SAAS,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW,CAAC,OAAO,GAAG,OAAO;IAC5C,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,OAAO,EAAE,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa,CAAC,OAAO,GAAG,OAAO;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC;IAC/B,KAAK,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,EAAE,GAAG,SAAS,CAAC;IACtC,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,SAAS,CAAC;CAChD;AAED,MAAM,WAAW,iBAAiB,CAAC,OAAO,GAAG,OAAO;IAClD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,OAAO,EAAE,EAAE,CAAC;CAC3B"}
1
+ {"version":3,"file":"sd-app-structure.provider.d.ts","sourceRoot":"","sources":["../../../src/core/providers/sd-app-structure.provider.ts"],"names":[],"mappings":"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"}
@@ -43,10 +43,12 @@ export class SdAppStructureUtils {
43
43
  return (parent ? `[${parent}] ` : "") + current;
44
44
  }
45
45
  static getPermsByFullCode(items, fullCodes, permKeys, permRecord) {
46
+ if (permRecord === undefined)
47
+ return [];
46
48
  const result = [];
47
49
  for (const permKey of permKeys) {
48
50
  // 해당 권한이 설정되어있거나
49
- if (fullCodes.some((fullCode) => permRecord?.[fullCode + "." + permKey])) {
51
+ if (fullCodes.some((fullCode) => permRecord[fullCode + "." + permKey])) {
50
52
  result.push(permKey);
51
53
  }
52
54
  // 권한이라는것이 아얘 존재하지 않거나
@@ -62,14 +64,13 @@ export class SdAppStructureUtils {
62
64
  static getItemChainByFullCode(items, fullCode) {
63
65
  const codeChain = fullCode.split(".");
64
66
  const result = [];
65
- let cursor;
66
67
  let cursorChildren = items;
67
68
  for (const currCode of codeChain) {
68
- cursor = cursorChildren.single((item) => item.code === currCode);
69
- cursorChildren = cursor != null && "children" in cursor ? cursor.children : [];
70
- if (cursor) {
71
- result.push(cursor);
72
- }
69
+ const cursor = cursorChildren.single((item) => item.code === currCode);
70
+ if (cursor == null)
71
+ return [];
72
+ cursorChildren = "children" in cursor ? cursor.children : [];
73
+ result.push(cursor);
73
74
  }
74
75
  return result;
75
76
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sd-file-dialog.provider.d.ts","sourceRoot":"","sources":["../../../src/core/providers/sd-file-dialog.provider.ts"],"names":[],"mappings":";AAGA,qBACa,oBAAoB;IACzB,SAAS,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IACvE,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,SAAS,CAAC;yCAFlE,oBAAoB;6CAApB,oBAAoB;CA4ChC"}
1
+ {"version":3,"file":"sd-file-dialog.provider.d.ts","sourceRoot":"","sources":["../../../src/core/providers/sd-file-dialog.provider.ts"],"names":[],"mappings":";AAGA,qBACa,oBAAoB;IACzB,SAAS,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IACvE,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,SAAS,CAAC;yCAFlE,oBAAoB;6CAApB,oBAAoB;CAqDhC"}
@@ -5,19 +5,27 @@ export class SdFileDialogProvider {
5
5
  async showAsync(multiple, accept) {
6
6
  return new Promise((resolve) => {
7
7
  let inputEl = document.createElement("input");
8
+ function cleanup() {
9
+ if (inputEl) {
10
+ document.body.removeChild(inputEl);
11
+ inputEl = undefined;
12
+ }
13
+ }
8
14
  inputEl.type = "file";
9
15
  inputEl.multiple = multiple ?? false;
10
16
  if (accept !== undefined) {
11
17
  inputEl.accept = accept;
12
18
  }
13
19
  inputEl.onchange = (event) => {
14
- if (inputEl) {
15
- document.body.removeChild(inputEl);
16
- inputEl = undefined;
17
- }
20
+ cleanup();
18
21
  const files = event.target.files;
19
22
  resolve(multiple ? Array.from(files) : files[0]);
20
23
  };
24
+ // cancel 이벤트 (Chrome 77+)
25
+ inputEl.addEventListener("cancel", () => {
26
+ cleanup();
27
+ resolve(undefined);
28
+ });
21
29
  inputEl.style.opacity = "0";
22
30
  inputEl.style.position = "fixed";
23
31
  inputEl.style.top = "0";
@@ -26,16 +34,16 @@ export class SdFileDialogProvider {
26
34
  document.body.appendChild(inputEl);
27
35
  inputEl.focus();
28
36
  inputEl.click();
37
+ // focus 폴백 (Chrome 61-76)
29
38
  setTimeout(() => {
30
39
  if (inputEl == null)
31
40
  return;
32
41
  inputEl.onfocus = async () => {
33
42
  await wait.time(1000);
34
43
  if (inputEl) {
35
- document.body.removeChild(inputEl);
36
- inputEl = undefined;
44
+ cleanup();
45
+ resolve(undefined);
37
46
  }
38
- resolve(undefined);
39
47
  };
40
48
  });
41
49
  });
@@ -1 +1 @@
1
- {"version":3,"file":"sd-local-storage.provider.d.ts","sourceRoot":"","sources":["../../../src/core/providers/sd-local-storage.provider.ts"],"names":[],"mappings":";AAGA,qBACa,sBAAsB,CAAC,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmC;IAE7D,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAInD,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS;IAMzD,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,MAAM;yCAbjB,sBAAsB;6CAAtB,sBAAsB;CAgBlC"}
1
+ {"version":3,"file":"sd-local-storage.provider.d.ts","sourceRoot":"","sources":["../../../src/core/providers/sd-local-storage.provider.ts"],"names":[],"mappings":";AAGA,qBACa,sBAAsB,CAAC,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmC;IAE7D,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAInD,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS;IAUzD,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,MAAM;yCAjBjB,sBAAsB;6CAAtB,sBAAsB;CAoBlC"}
@@ -10,7 +10,12 @@ export class SdLocalStorageProvider {
10
10
  const json = localStorage.getItem(`${this._sdNgConf.clientName}.${key}`);
11
11
  if (json == null)
12
12
  return undefined;
13
- return JSON.parse(json);
13
+ try {
14
+ return JSON.parse(json);
15
+ }
16
+ catch {
17
+ return undefined;
18
+ }
14
19
  }
15
20
  remove(key) {
16
21
  localStorage.removeItem(`${this._sdNgConf.clientName}.${key}`);
@@ -4,7 +4,10 @@ export class SdNavigateWindowProvider {
4
4
  _openedWindows = new Set();
5
5
  _beforeUnloadRegistered = false;
6
6
  get isWindow() {
7
- const urlSearchParams = new URLSearchParams(location.hash.slice(location.hash.indexOf(";") + 1));
7
+ const semicolonIdx = location.hash.indexOf(";");
8
+ if (semicolonIdx === -1)
9
+ return false;
10
+ const urlSearchParams = new URLSearchParams(location.hash.slice(semicolonIdx + 1));
8
11
  return urlSearchParams.get("window") === "true";
9
12
  }
10
13
  open(navigate, params, features) {
@@ -36,7 +36,7 @@ export class SdPrintProvider {
36
36
  document.head.appendChild(styleEl);
37
37
  try {
38
38
  this._appRef.tick();
39
- await wait.until(() => compRef.instance.initialized());
39
+ await wait.until(() => compRef.instance.initialized(), 100, 300);
40
40
  await this._waitForAllImagesLoadedAsync(compEl);
41
41
  window.print();
42
42
  }
@@ -69,7 +69,7 @@ export class SdPrintProvider {
69
69
  const headStylesBefore = new Set(document.head.querySelectorAll("style"));
70
70
  try {
71
71
  this._appRef.tick();
72
- await wait.until(() => compRef.instance.initialized());
72
+ await wait.until(() => compRef.instance.initialized(), 100, 300);
73
73
  await this._waitForAllImagesLoadedAsync(compEl);
74
74
  const pageSize = options?.pageSize ?? "a4";
75
75
  const orientation = options?.orientation ?? "p";
@@ -1 +1 @@
1
- {"version":3,"file":"sd-shared-data.provider.d.ts","sourceRoot":"","sources":["../../../src/core/providers/sd-shared-data.provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsD,KAAK,MAAM,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAIrH,OAAO,uBAAuB,CAAC;;AAE/B,MAAM,WAAW,eAAe,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM;IAC3D,UAAU,EAAE,IAAI,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,eAAe,CAAC,MAAM,GAAG,MAAM,CAAC;IACzE,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,eAAe,CAAC,MAAM,GAAG,MAAM,CAAC;IAC1E,KAAK,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;IACnB,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,SAAS,GAAG,CAAC,GAAG,SAAS,CAAC;CACtD;AAED,eAAO,MAAM,uBAAuB;UAC1B,MAAM;YAAU,OAAO;mCAEV,CAAC;AAUxB,8BACsB,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACnG,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA0C;IACzE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAwB;IAEtD,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC,MAAM,CAAC,CAAa;IAE1D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4C;IAErE,QAAQ,CAAC,UAAU,IAAI,IAAI;IAE3B,QAAQ,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAkChF,SAAS,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAchE,SAAS,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,EACxC,IAAI,EAAE,CAAC,EACP,UAAU,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAC/B,OAAO,CAAC,IAAI,CAAC;IAcV,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,OAAO,CAAC,cAAc;YA6BR,QAAQ;yCA5GF,oBAAoB;6CAApB,oBAAoB;CA8IzC"}
1
+ {"version":3,"file":"sd-shared-data.provider.d.ts","sourceRoot":"","sources":["../../../src/core/providers/sd-shared-data.provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsD,KAAK,MAAM,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAIrH,OAAO,uBAAuB,CAAC;;AAE/B,MAAM,WAAW,eAAe,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM;IAC3D,UAAU,EAAE,IAAI,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,eAAe,CAAC,MAAM,GAAG,MAAM,CAAC;IACzE,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,eAAe,CAAC,MAAM,GAAG,MAAM,CAAC;IAC1E,KAAK,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;IACnB,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,SAAS,GAAG,CAAC,GAAG,SAAS,CAAC;CACtD;AAED,eAAO,MAAM,uBAAuB;UAC1B,MAAM;YAAU,OAAO;mCAEV,CAAC;AAWxB,8BACsB,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACnG,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA0C;IACzE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAwB;IAEtD,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC,MAAM,CAAC,CAAa;IAE1D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4C;IAErE,QAAQ,CAAC,UAAU,IAAI,IAAI;IAE3B,QAAQ,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAmChF,SAAS,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAchE,SAAS,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,EACxC,IAAI,EAAE,CAAC,EACP,UAAU,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAC/B,OAAO,CAAC,IAAI,CAAC;IAcV,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,OAAO,CAAC,cAAc;YAmCR,QAAQ;yCAnHF,oBAAoB;6CAApB,oBAAoB;CAwJzC"}
@@ -38,6 +38,7 @@ export class SdSharedDataProvider {
38
38
  itemsSignal,
39
39
  handle,
40
40
  needsReload: true,
41
+ isLoading: false,
41
42
  });
42
43
  }
43
44
  }
@@ -46,7 +47,7 @@ export class SdSharedDataProvider {
46
47
  if (entry == null) {
47
48
  throw new Error(`등록되지 않은 공유 데이터: ${name}`);
48
49
  }
49
- if (entry.needsReload) {
50
+ if (entry.needsReload && !entry.isLoading) {
50
51
  entry.needsReload = false;
51
52
  this._loadAndListen(name, entry);
52
53
  }
@@ -64,6 +65,7 @@ export class SdSharedDataProvider {
64
65
  await waitUtil.until(() => this.loadingCount() <= 0);
65
66
  }
66
67
  _loadAndListen(name, entry) {
68
+ entry.isLoading = true;
67
69
  this.loadingCount.update((v) => v + 1);
68
70
  // 비동기 로드
69
71
  void entry.info
@@ -83,6 +85,11 @@ export class SdSharedDataProvider {
83
85
  })
84
86
  .finally(() => {
85
87
  this.loadingCount.update((v) => v - 1);
88
+ entry.isLoading = false;
89
+ if (entry.needsReload) {
90
+ entry.needsReload = false;
91
+ this._loadAndListen(name, entry);
92
+ }
86
93
  });
87
94
  }
88
95
  async _onEvent(name, entry, changeKeys) {
@@ -97,8 +104,9 @@ export class SdSharedDataProvider {
97
104
  // 부분 업데이트
98
105
  const newItems = await entry.info.getter(changeKeys);
99
106
  const currentItems = entry.itemsSignal();
100
- // 변경된 키를 제거하고 새 항목 추가
101
- const filtered = currentItems.filter((item) => !changeKeys.includes(item.__valueKey));
107
+ // 변경된 키를 제거하고 새 항목 추가 (String 변환으로 타입 혼재 방지)
108
+ const changeKeySet = new Set(changeKeys.map(String));
109
+ const filtered = currentItems.filter((item) => !changeKeySet.has(String(item.__valueKey)));
102
110
  const merged = [...filtered, ...newItems];
103
111
  // orderBy 적용
104
112
  if (entry.info.orderBy != null) {
@@ -107,6 +115,9 @@ export class SdSharedDataProvider {
107
115
  entry.itemsSignal.set(merged);
108
116
  }
109
117
  }
118
+ catch (err) {
119
+ this._errorHandler.handleError(err);
120
+ }
110
121
  finally {
111
122
  this.loadingCount.update((v) => v - 1);
112
123
  }