@simplysm/angular 14.0.42 → 14.0.43

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 (241) hide show
  1. package/dist/controls/button/sd-additional-button.js +1 -1
  2. package/dist/controls/button/sd-anchor.js +1 -1
  3. package/dist/controls/button/sd-button.js +1 -1
  4. package/dist/controls/button/sd-modal-select-button.d.ts +1 -1
  5. package/dist/controls/button/sd-modal-select-button.d.ts.map +1 -1
  6. package/dist/controls/button/sd-modal-select-button.js +8 -6
  7. package/dist/controls/checkbox/sd-checkbox-group-item.js +1 -1
  8. package/dist/controls/checkbox/sd-checkbox-group.js +1 -1
  9. package/dist/controls/checkbox/sd-checkbox.js +1 -1
  10. package/dist/controls/checkbox/sd-switch.js +1 -1
  11. package/dist/controls/collapse/sd-collapse-icon.d.ts.map +1 -1
  12. package/dist/controls/collapse/sd-collapse-icon.js +3 -3
  13. package/dist/controls/collapse/sd-collapse.d.ts +1 -1
  14. package/dist/controls/collapse/sd-collapse.d.ts.map +1 -1
  15. package/dist/controls/collapse/sd-collapse.js +8 -7
  16. package/dist/controls/dropdown/sd-dropdown-popup.d.ts +2 -0
  17. package/dist/controls/dropdown/sd-dropdown-popup.d.ts.map +1 -1
  18. package/dist/controls/dropdown/sd-dropdown-popup.js +21 -8
  19. package/dist/controls/dropdown/sd-dropdown.d.ts.map +1 -1
  20. package/dist/controls/dropdown/sd-dropdown.js +5 -16
  21. package/dist/controls/form/sd-form.js +1 -1
  22. package/dist/controls/gap/sd-gap.js +5 -5
  23. package/dist/controls/input/sd-date-range-picker.d.ts +1 -0
  24. package/dist/controls/input/sd-date-range-picker.d.ts.map +1 -1
  25. package/dist/controls/input/sd-date-range-picker.js +14 -19
  26. package/dist/controls/input/sd-numpad.js +3 -3
  27. package/dist/controls/input/sd-range.js +1 -1
  28. package/dist/controls/input/sd-textarea.js +2 -2
  29. package/dist/controls/input/sd-textfield-type-handlers.js +2 -2
  30. package/dist/controls/input/sd-textfield.js +9 -9
  31. package/dist/controls/list/sd-list-item.d.ts +0 -1
  32. package/dist/controls/list/sd-list-item.d.ts.map +1 -1
  33. package/dist/controls/list/sd-list-item.js +38 -38
  34. package/dist/controls/list/sd-list.d.ts.map +1 -1
  35. package/dist/controls/list/sd-list.js +3 -3
  36. package/dist/controls/pagination/sd-pagination.js +1 -1
  37. package/dist/controls/select/sd-select-button.d.ts.map +1 -1
  38. package/dist/controls/select/sd-select-button.js +4 -8
  39. package/dist/controls/select/sd-select-item.d.ts +3 -3
  40. package/dist/controls/select/sd-select-item.d.ts.map +1 -1
  41. package/dist/controls/select/sd-select-item.js +27 -20
  42. package/dist/controls/select/sd-select.d.ts +5 -4
  43. package/dist/controls/select/sd-select.d.ts.map +1 -1
  44. package/dist/controls/select/sd-select.js +20 -17
  45. package/dist/controls/tab/sd-tab-item.js +1 -1
  46. package/dist/controls/tab/sd-tab.js +1 -1
  47. package/dist/core/app-structure/sd-app-structure.utils.js +1 -1
  48. package/dist/core/busy/sd-busy-container.d.ts.map +1 -1
  49. package/dist/core/busy/sd-busy-container.js +62 -68
  50. package/dist/core/busy/sd-busy.provider.js +1 -1
  51. package/dist/core/commands/sd-command.d.ts +13 -0
  52. package/dist/core/commands/sd-command.d.ts.map +1 -0
  53. package/dist/core/commands/sd-command.js +52 -0
  54. package/dist/core/error-handler/sd-global-error-handler.plugin.js +1 -1
  55. package/dist/core/events/sd-events.d.ts +1 -6
  56. package/dist/core/events/sd-events.d.ts.map +1 -1
  57. package/dist/core/events/sd-events.js +3 -11
  58. package/dist/core/events/sd-intersection.d.ts +13 -0
  59. package/dist/core/events/sd-intersection.d.ts.map +1 -0
  60. package/dist/core/events/sd-intersection.js +27 -0
  61. package/dist/core/events/sd-resize.d.ts +16 -0
  62. package/dist/core/events/sd-resize.d.ts.map +1 -0
  63. package/dist/core/events/{sd-resize-event.plugin.js → sd-resize.js} +18 -20
  64. package/dist/core/file-dialog/sd-file-dialog.provider.js +1 -1
  65. package/dist/core/modal/injectDragResize.js +9 -9
  66. package/dist/core/modal/injectFocusTrap.js +1 -1
  67. package/dist/core/modal/sd-confirm-modal.js +1 -1
  68. package/dist/core/modal/sd-modal.d.ts +8 -1
  69. package/dist/core/modal/sd-modal.d.ts.map +1 -1
  70. package/dist/core/modal/sd-modal.js +135 -39
  71. package/dist/core/modal/sd-modal.provider.js +5 -5
  72. package/dist/core/modal/sd-prompt-modal.js +1 -1
  73. package/dist/core/provideSdAngular.d.ts.map +1 -1
  74. package/dist/core/provideSdAngular.js +0 -10
  75. package/dist/core/ripple/setupRipple.js +5 -5
  76. package/dist/core/routing/menu-utils.js +1 -1
  77. package/dist/core/routing/sd-navigate-window.provider.js +1 -1
  78. package/dist/core/routing/sd-router-link.js +1 -1
  79. package/dist/core/selection/setupCumulateSelectedKeys.js +3 -3
  80. package/dist/core/setupModelHook.js +1 -1
  81. package/dist/core/toast/sd-toast-container.d.ts +1 -1
  82. package/dist/core/toast/sd-toast-container.js +3 -7
  83. package/dist/core/toast/sd-toast.d.ts.map +1 -1
  84. package/dist/core/toast/sd-toast.js +27 -24
  85. package/dist/core/toast/sd-toast.provider.js +6 -6
  86. package/dist/core/validation/setupInvalid.js +2 -1
  87. package/dist/data/data-detail/sd-data-detail.d.ts +2 -1
  88. package/dist/data/data-detail/sd-data-detail.d.ts.map +1 -1
  89. package/dist/data/data-detail/sd-data-detail.js +37 -33
  90. package/dist/data/data-select-button/sd-data-select-button.js +1 -1
  91. package/dist/data/data-sheet/sd-data-sheet.d.ts +2 -1
  92. package/dist/data/data-sheet/sd-data-sheet.d.ts.map +1 -1
  93. package/dist/data/data-sheet/sd-data-sheet.js +30 -22
  94. package/dist/data/kanban/sd-kanban-board.js +1 -1
  95. package/dist/data/kanban/sd-kanban-lane.js +1 -1
  96. package/dist/data/kanban/sd-kanban.d.ts +1 -1
  97. package/dist/data/kanban/sd-kanban.d.ts.map +1 -1
  98. package/dist/data/kanban/sd-kanban.js +4 -4
  99. package/dist/data/permission-table/sd-permission-table.js +6 -6
  100. package/dist/data/shared-data/sd-shared-data-select-button.js +1 -1
  101. package/dist/data/shared-data/sd-shared-data-select-list.js +3 -3
  102. package/dist/data/shared-data/sd-shared-data-select.d.ts +1 -1
  103. package/dist/data/shared-data/sd-shared-data-select.d.ts.map +1 -1
  104. package/dist/data/shared-data/sd-shared-data-select.js +29 -54
  105. package/dist/data/sheet/injectSheetDomAccessor.d.ts +6 -2
  106. package/dist/data/sheet/injectSheetDomAccessor.d.ts.map +1 -1
  107. package/dist/data/sheet/injectSheetDomAccessor.js +27 -22
  108. package/dist/data/sheet/injectSheetSelectRowIndicator.d.ts +10 -0
  109. package/dist/data/sheet/injectSheetSelectRowIndicator.d.ts.map +1 -0
  110. package/dist/data/sheet/injectSheetSelectRowIndicator.js +55 -0
  111. package/dist/data/sheet/sd-sheet-config.modal.d.ts +18 -19
  112. package/dist/data/sheet/sd-sheet-config.modal.d.ts.map +1 -1
  113. package/dist/data/sheet/sd-sheet-config.modal.js +357 -217
  114. package/dist/data/sheet/sd-sheet.d.ts +27 -13
  115. package/dist/data/sheet/sd-sheet.d.ts.map +1 -1
  116. package/dist/data/sheet/sd-sheet.js +609 -291
  117. package/dist/data/sheet/useSheetCellAgent.js +6 -6
  118. package/dist/data/sheet/useSheetCellStyling.d.ts.map +1 -1
  119. package/dist/data/sheet/useSheetCellStyling.js +4 -4
  120. package/dist/data/sheet/useSheetFocusIndicator.d.ts +7 -0
  121. package/dist/data/sheet/useSheetFocusIndicator.d.ts.map +1 -0
  122. package/dist/data/sheet/useSheetFocusIndicator.js +53 -0
  123. package/dist/data/sheet/useSheetLayoutEngine.js +1 -1
  124. package/dist/data/state-preset/sd-state-preset.d.ts.map +1 -1
  125. package/dist/data/state-preset/sd-state-preset.js +14 -14
  126. package/dist/features/address/sd-address-search.modal.js +3 -3
  127. package/dist/features/editor/sd-tiptap-editor.js +6 -6
  128. package/dist/features/editor/useTiptapToolbar.js +2 -2
  129. package/dist/features/theme/sd-theme-selector.js +1 -1
  130. package/dist/features/visual/sd-barcode.js +1 -1
  131. package/dist/features/visual/sd-calendar.js +2 -2
  132. package/dist/features/visual/sd-echarts.d.ts +2 -1
  133. package/dist/features/visual/sd-echarts.d.ts.map +1 -1
  134. package/dist/features/visual/sd-echarts.js +5 -3
  135. package/dist/features/visual/sd-label.js +1 -1
  136. package/dist/features/visual/sd-note.js +1 -1
  137. package/dist/features/visual/sd-progress.js +1 -1
  138. package/dist/index.d.ts +3 -5
  139. package/dist/index.d.ts.map +1 -1
  140. package/dist/index.js +3 -5
  141. package/dist/layout/base-container/sd-base-container.js +3 -3
  142. package/dist/layout/dock/sd-dock-container.js +1 -1
  143. package/dist/layout/dock/sd-dock.d.ts +3 -2
  144. package/dist/layout/dock/sd-dock.d.ts.map +1 -1
  145. package/dist/layout/dock/sd-dock.js +6 -4
  146. package/dist/layout/sidebar/sd-sidebar-container.js +5 -5
  147. package/dist/layout/sidebar/sd-sidebar-menu.d.ts.map +1 -1
  148. package/dist/layout/sidebar/sd-sidebar-menu.js +7 -6
  149. package/dist/layout/sidebar/sd-sidebar-user.js +1 -1
  150. package/dist/layout/sidebar/sd-sidebar.js +1 -1
  151. package/dist/layout/topbar/sd-topbar-container.js +1 -1
  152. package/dist/layout/topbar/sd-topbar-menu.d.ts.map +1 -1
  153. package/dist/layout/topbar/sd-topbar-menu.js +7 -7
  154. package/dist/layout/topbar/sd-topbar-user.js +1 -1
  155. package/dist/layout/topbar/sd-topbar.js +3 -3
  156. package/package.json +5 -5
  157. package/src/controls/button/sd-modal-select-button.ts +7 -2
  158. package/src/controls/collapse/sd-collapse-icon.ts +2 -2
  159. package/src/controls/collapse/sd-collapse.ts +4 -5
  160. package/src/controls/dropdown/sd-dropdown-popup.ts +15 -2
  161. package/src/controls/dropdown/sd-dropdown.ts +4 -16
  162. package/src/controls/gap/sd-gap.ts +4 -4
  163. package/src/controls/input/sd-date-range-picker.ts +13 -16
  164. package/src/controls/input/sd-numpad.ts +1 -1
  165. package/src/controls/input/sd-textarea.ts +1 -1
  166. package/src/controls/input/sd-textfield-type-handlers.ts +2 -2
  167. package/src/controls/input/sd-textfield.ts +6 -6
  168. package/src/controls/list/sd-list-item.ts +40 -26
  169. package/src/controls/list/sd-list.ts +2 -1
  170. package/src/controls/select/sd-select-button.ts +8 -11
  171. package/src/controls/select/sd-select-item.ts +35 -27
  172. package/src/controls/select/sd-select.ts +111 -41
  173. package/src/core/app-structure/sd-app-structure.utils.ts +1 -1
  174. package/src/core/busy/sd-busy-container.ts +235 -123
  175. package/src/core/busy/sd-busy.provider.ts +1 -1
  176. package/src/core/commands/sd-command.ts +46 -0
  177. package/src/core/error-handler/sd-global-error-handler.plugin.ts +1 -1
  178. package/src/core/events/sd-events.ts +1 -12
  179. package/src/core/events/sd-intersection.ts +29 -0
  180. package/src/core/events/{sd-resize-event.plugin.ts → sd-resize.ts} +17 -24
  181. package/src/core/file-dialog/sd-file-dialog.provider.ts +1 -1
  182. package/src/core/modal/injectDragResize.ts +9 -9
  183. package/src/core/modal/injectFocusTrap.ts +1 -1
  184. package/src/core/modal/sd-modal.provider.ts +5 -5
  185. package/src/core/modal/sd-modal.ts +119 -41
  186. package/src/core/provideSdAngular.ts +0 -10
  187. package/src/core/ripple/setupRipple.ts +5 -5
  188. package/src/core/routing/menu-utils.ts +1 -1
  189. package/src/core/routing/sd-navigate-window.provider.ts +1 -1
  190. package/src/core/routing/sd-router-link.ts +1 -1
  191. package/src/core/selection/setupCumulateSelectedKeys.ts +3 -3
  192. package/src/core/setupModelHook.ts +1 -1
  193. package/src/core/toast/sd-toast-container.ts +1 -1
  194. package/src/core/toast/sd-toast.provider.ts +6 -6
  195. package/src/core/toast/sd-toast.ts +25 -22
  196. package/src/core/validation/setupInvalid.ts +2 -1
  197. package/src/data/data-detail/sd-data-detail.ts +15 -11
  198. package/src/data/data-sheet/sd-data-sheet.ts +13 -15
  199. package/src/data/kanban/sd-kanban.ts +4 -5
  200. package/src/data/permission-table/sd-permission-table.ts +4 -4
  201. package/src/data/shared-data/sd-shared-data-select-list.ts +1 -1
  202. package/src/data/shared-data/sd-shared-data-select.ts +8 -27
  203. package/src/data/sheet/injectSheetDomAccessor.ts +37 -25
  204. package/src/data/sheet/injectSheetSelectRowIndicator.ts +69 -0
  205. package/src/data/sheet/sd-sheet-config.modal.ts +215 -191
  206. package/src/data/sheet/sd-sheet.ts +529 -209
  207. package/src/data/sheet/useSheetCellAgent.ts +8 -8
  208. package/src/data/sheet/useSheetCellStyling.ts +4 -8
  209. package/src/data/sheet/useSheetFocusIndicator.ts +66 -0
  210. package/src/data/sheet/useSheetLayoutEngine.ts +1 -1
  211. package/src/data/state-preset/sd-state-preset.ts +26 -13
  212. package/src/features/address/sd-address-search.modal.ts +1 -1
  213. package/src/features/editor/sd-tiptap-editor.ts +4 -4
  214. package/src/features/editor/useTiptapToolbar.ts +2 -2
  215. package/src/features/visual/sd-calendar.ts +1 -1
  216. package/src/features/visual/sd-echarts.ts +2 -0
  217. package/src/index.ts +4 -6
  218. package/src/layout/base-container/sd-base-container.ts +1 -1
  219. package/src/layout/dock/sd-dock.ts +3 -2
  220. package/src/layout/sidebar/sd-sidebar-container.ts +2 -2
  221. package/src/layout/sidebar/sd-sidebar-menu.ts +1 -3
  222. package/src/layout/topbar/sd-topbar-menu.ts +11 -15
  223. package/src/layout/topbar/sd-topbar.ts +1 -1
  224. package/dist/core/commands/sd-insert-command-event.plugin.d.ts +0 -11
  225. package/dist/core/commands/sd-insert-command-event.plugin.d.ts.map +0 -1
  226. package/dist/core/commands/sd-insert-command-event.plugin.js +0 -35
  227. package/dist/core/commands/sd-refresh-command-event.plugin.d.ts +0 -11
  228. package/dist/core/commands/sd-refresh-command-event.plugin.d.ts.map +0 -1
  229. package/dist/core/commands/sd-refresh-command-event.plugin.js +0 -38
  230. package/dist/core/commands/sd-save-command-event.plugin.d.ts +0 -11
  231. package/dist/core/commands/sd-save-command-event.plugin.d.ts.map +0 -1
  232. package/dist/core/commands/sd-save-command-event.plugin.js +0 -38
  233. package/dist/core/events/sd-intersection-event.plugin.d.ts +0 -13
  234. package/dist/core/events/sd-intersection-event.plugin.d.ts.map +0 -1
  235. package/dist/core/events/sd-intersection-event.plugin.js +0 -29
  236. package/dist/core/events/sd-resize-event.plugin.d.ts +0 -16
  237. package/dist/core/events/sd-resize-event.plugin.d.ts.map +0 -1
  238. package/src/core/commands/sd-insert-command-event.plugin.ts +0 -39
  239. package/src/core/commands/sd-refresh-command-event.plugin.ts +0 -44
  240. package/src/core/commands/sd-save-command-event.plugin.ts +0 -44
  241. package/src/core/events/sd-intersection-event.plugin.ts +0 -35
@@ -24,14 +24,17 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
24
24
  "[attr.aria-live]": "ariaLive()",
25
25
  },
26
26
  template: `
27
- <div class="_block">
28
- @if (message() !== undefined) {
29
- <div class="_message">{{ message() }}</div>
30
- }
31
- <ng-content />
27
+ <div class="_sd-toast-block">
28
+ <div class="_sd-toast-message">
29
+ @if (message() != undefined) {
30
+ {{ message() }}
31
+ } @else {
32
+ <ng-content />
33
+ }
34
+ </div>
32
35
  @if (useProgress()) {
33
- <div class="_progress">
34
- <div class="_progress-bar" [style.width.%]="progress()"></div>
36
+ <div class="_sd-toast-progress">
37
+ <div class="_sd-toast-progress-bar" [style.width.%]="progress()"></div>
35
38
  </div>
36
39
  }
37
40
  </div>
@@ -49,7 +52,7 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
49
52
  width: 100%;
50
53
  pointer-events: none;
51
54
 
52
- > ._block {
55
+ > ._sd-toast-block {
53
56
  display: inline-block;
54
57
  text-align: left;
55
58
  color: var(--text-trans-rev-default);
@@ -59,19 +62,19 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
59
62
  @include mixins.elevation(12);
60
63
  pointer-events: auto;
61
64
 
62
- > ._message {
65
+ > ._sd-toast-message {
63
66
  padding: var(--gap-default) var(--gap-lg);
64
67
  word-break: break-all;
65
68
  white-space: pre-wrap;
66
69
  }
67
70
 
68
- > ._progress {
71
+ > ._sd-toast-progress {
69
72
  background: var(--theme-gray-default);
70
73
  height: 4px;
71
74
  border-radius: var(--border-radius-xl);
72
75
  margin: 0 4px 4px 4px;
73
76
 
74
- > ._progress-bar {
77
+ > ._sd-toast-progress-bar {
75
78
  border-radius: var(--border-radius-xl);
76
79
  height: 4px;
77
80
  transition: width 1s ease-out;
@@ -81,14 +84,14 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
81
84
 
82
85
  @each $theme-name, $theme-map in map.get(variables.$vars, theme) {
83
86
  &[data-sd-theme="#{$theme-name}"] {
84
- > ._block {
85
- background: map.get($theme-map, default);
87
+ > ._sd-toast-block {
88
+ background: var(--theme-#{$theme-name}-default);
86
89
 
87
- > ._progress {
88
- background: map.get($theme-map, darker);
90
+ > ._sd-toast-progress {
91
+ background: var(--theme-#{$theme-name}-darker);
89
92
 
90
- > ._progress-bar {
91
- background: map.get($theme-map, lighter);
93
+ > ._sd-toast-progress-bar {
94
+ background: var(--theme-#{$theme-name}-lighter);
92
95
  }
93
96
  }
94
97
  }
@@ -96,7 +99,7 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
96
99
  }
97
100
 
98
101
  &[data-sd-open="true"] {
99
- > ._block {
102
+ > ._sd-toast-block {
100
103
  transform: none;
101
104
  transition: var(--animation-duration) ease-out;
102
105
  transition-property: transform, opacity;
@@ -105,7 +108,7 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
105
108
  }
106
109
 
107
110
  &[data-sd-open="false"] {
108
- > ._block {
111
+ > ._sd-toast-block {
109
112
  transform: translateY(-100%);
110
113
  transition: var(--animation-duration) ease-in;
111
114
  transition-property: transform, opacity;
@@ -114,17 +117,17 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
114
117
  }
115
118
 
116
119
  @media all and (max-width: variables.$breakpoint-mobile) {
117
- > ._block {
120
+ > ._sd-toast-block {
118
121
  border-radius: calc(var(--line-height) / 2);
119
122
  transform: translateY(100%);
120
123
 
121
- > ._message {
124
+ > ._sd-toast-message {
122
125
  padding: var(--gap-xs) var(--gap-default);
123
126
  }
124
127
  }
125
128
 
126
129
  &[data-sd-open="false"] {
127
- > ._block {
130
+ > ._sd-toast-block {
128
131
  transform: translateY(100%);
129
132
  }
130
133
  }
@@ -66,6 +66,7 @@ function createInputHiddenEl(renderer: Renderer2, hostEl: HTMLElement): HTMLInpu
66
66
  newEl.name = Uuid.generate().toString();
67
67
  newEl.className = "sd-invalid-input";
68
68
  newEl.tabIndex = -1;
69
+ newEl.autocomplete = "off";
69
70
  setSafeStyle(renderer, newEl, {
70
71
  position: "absolute",
71
72
  left: "2px",
@@ -83,7 +84,7 @@ function createInputHiddenEl(renderer: Renderer2, hostEl: HTMLElement): HTMLInpu
83
84
  const tabbableElement =
84
85
  (isTabbable(hostEl) ? hostEl : hostEl.findFirstTabbableChild()) ??
85
86
  hostEl.findTabbableParent();
86
- if (tabbableElement !== undefined) {
87
+ if (tabbableElement != null) {
87
88
  tabbableElement.focus();
88
89
  }
89
90
  });
@@ -22,6 +22,7 @@ import {
22
22
  tablerRestore,
23
23
  } from "@ng-icons/tabler-icons";
24
24
  import { SdDataDetailBase } from "./sd-data-detail.base";
25
+ import { SdCommandDirective } from "../../core/commands/sd-command";
25
26
 
26
27
  export type { SdDataDetailDataInfo } from "./sd-data-detail.base";
27
28
 
@@ -41,6 +42,9 @@ export type { SdDataDetailDataInfo } from "./sd-data-detail.base";
41
42
  SdAnchor,
42
43
  NgIcon,
43
44
  ],
45
+ hostDirectives: [
46
+ { directive: SdCommandDirective, outputs: ["sdRefreshCommand", "sdSaveCommand"] },
47
+ ],
44
48
  host: {
45
49
  "(sdRefreshCommand)": "onRefreshButtonClick()",
46
50
  "(sdSaveCommand)": "onSubmitButtonClick()",
@@ -169,18 +173,18 @@ export type { SdDataDetailDataInfo } from "./sd-data-detail.base";
169
173
  </div>
170
174
  </div>
171
175
  </ng-template>
172
- }
173
176
 
174
- <ng-template #modalActionTpl>
175
- <sd-anchor
176
- [theme]="'gray'"
177
- class="p-sm-default"
178
- (click)="onRefreshButtonClick()"
179
- title="새로고침(CTRL+ALT+L)"
180
- >
181
- <ng-icon [svg]="icons.tablerRefresh" />
182
- </sd-anchor>
183
- </ng-template>
177
+ <ng-template #modalActionTpl>
178
+ <sd-anchor
179
+ [theme]="'gray'"
180
+ class="p-sm-default"
181
+ (click)="onRefreshButtonClick()"
182
+ title="새로고침(CTRL+ALT+L)"
183
+ >
184
+ <ng-icon [svg]="icons.tablerRefresh" />
185
+ </sd-anchor>
186
+ </ng-template>
187
+ }
184
188
  </sd-base-container>
185
189
  `,
186
190
  })
@@ -33,6 +33,7 @@ import {
33
33
  tablerUpload,
34
34
  } from "@ng-icons/tabler-icons";
35
35
  import { SdDataSheetBase } from "./sd-data-sheet.base";
36
+ import { SdCommandDirective } from "../../core/commands/sd-command";
36
37
 
37
38
  //#region SdDataSheet
38
39
 
@@ -53,6 +54,9 @@ import { SdDataSheetBase } from "./sd-data-sheet.base";
53
54
  SdAnchor,
54
55
  NgIcon,
55
56
  ],
57
+ hostDirectives: [
58
+ { directive: SdCommandDirective, outputs: ["sdRefreshCommand", "sdSaveCommand"] },
59
+ ],
56
60
  host: {
57
61
  "(sdRefreshCommand)": "onRefreshButtonClick()",
58
62
  "(sdSaveCommand)": "onSubmitButtonClick()",
@@ -211,11 +215,14 @@ import { SdDataSheetBase } from "./sd-data-sheet.base";
211
215
  [getItemSelectableFn]="parent.getItemSelectableFn"
212
216
  >
213
217
  @if (
214
- parent.editMode === "inline" &&
215
- parent.canEdit() &&
216
- parent.itemPropInfo.isDeleted
218
+ parent.editMode === "inline" && parent.canEdit() && parent.itemPropInfo.isDeleted
217
219
  ) {
218
220
  <sd-sheet-column [fixed]="true" [key]="parent.itemPropInfo.isDeleted!">
221
+ <ng-template #headerTpl>
222
+ <div class="p-xs-sm tx-center">
223
+ <ng-icon [svg]="deleteIcon()" />
224
+ </div>
225
+ </ng-template>
219
226
  <ng-template [cell]="parent.items()" let-item="item">
220
227
  <div class="p-xs-sm tx-center">
221
228
  <sd-anchor
@@ -225,16 +232,10 @@ import { SdDataSheetBase } from "./sd-data-sheet.base";
225
232
  >
226
233
  <ng-icon
227
234
  [svg]="
228
- item[parent.itemPropInfo.isDeleted!]
229
- ? restoreIcon()
230
- : deleteIcon()
235
+ item[parent.itemPropInfo.isDeleted!] ? restoreIcon() : deleteIcon()
231
236
  "
232
237
  />
233
- {{
234
- item[parent.itemPropInfo.isDeleted!]
235
- ? (restoreText() ?? "복구")
236
- : (deleteText() ?? "삭제")
237
- }}
238
+ {{ item[parent.itemPropInfo.isDeleted!] ? restoreText() : deleteText() }}
238
239
  </sd-anchor>
239
240
  </div>
240
241
  </ng-template>
@@ -322,10 +323,7 @@ import { SdDataSheetBase } from "./sd-data-sheet.base";
322
323
  >
323
324
  <ng-template [cell]="parent.items()" let-item="item">
324
325
  <div class="p-xs-sm tx-center">
325
- {{
326
- item[parent.itemPropInfo.lastModifiedAt!]
327
- | format: "yyyy-MM-dd HH:mm"
328
- }}
326
+ {{ item[parent.itemPropInfo.lastModifiedAt!] | format: "yyyy-MM-dd HH:mm" }}
329
327
  </div>
330
328
  </ng-template>
331
329
  </sd-sheet-column>
@@ -17,15 +17,14 @@ import {
17
17
  type SdKanbanDropTarget,
18
18
  } from "./sd-kanban-board";
19
19
  import { SdKanbanLane } from "./sd-kanban-lane";
20
- import { SdEvents } from "../../core/events/sd-events";
21
- import type { SdResizeEvent } from "../../core/events/sd-resize-event.plugin";
20
+ import { SdResizeDirective, type SdResizeEvent } from "../../core/events/sd-resize";
22
21
 
23
22
  @Component({
24
23
  selector: "sd-kanban",
25
24
  changeDetection: ChangeDetectionStrategy.OnPush,
26
25
  encapsulation: ViewEncapsulation.None,
27
26
  standalone: true,
28
- imports: [SdEvents],
27
+ imports: [SdResizeDirective],
29
28
  host: {
30
29
  "[attr.data-sd-dragging-this]": "dragKanban() === thisRef",
31
30
  "[attr.data-sd-dragging]": "dragKanban() != null",
@@ -186,9 +185,9 @@ export class SdKanban<L, T> implements SdKanbanDragRef<L, T>, SdKanbanDropTarget
186
185
  }
187
186
 
188
187
  onCardResize(event: SdResizeEvent) {
189
- const marginBottom = getComputedStyle(event.target as HTMLElement).marginBottom;
188
+ const marginBottom = getComputedStyle(event.target).marginBottom;
190
189
  this.cardHeight.set(
191
- (event.target as HTMLElement).clientHeight + (parseInt(marginBottom) || 0),
190
+ event.target.clientHeight + (parseInt(marginBottom) || 0),
192
191
  );
193
192
  }
194
193
 
@@ -152,7 +152,7 @@ import { SdAnchor } from "../../controls/button/sd-anchor";
152
152
  <td class="_title">
153
153
  @if (item.children && item.children.length > 0) {
154
154
  <sd-anchor (click)="onPermCollapseToggle(item)">
155
- <sd-collapse-icon [open]="!getIsPermCollapsed(item)" />
155
+ <sd-collapse-icon [open]="getIsPermCollapsed(item)" />
156
156
  {{ item.title }}
157
157
  </sd-anchor>
158
158
  } @else {
@@ -226,7 +226,7 @@ export class SdPermissionTable<TModule> {
226
226
  const walk = (item: SdPermission<TModule>, type: "use" | "edit"): boolean => {
227
227
  const key = item.codeChain.join(".") + "." + type;
228
228
  const cached = cache.get(key);
229
- if (cached !== undefined) return cached;
229
+ if (cached != null) return cached;
230
230
 
231
231
  if (item.perms) {
232
232
  const result = item.perms.includes(type);
@@ -259,7 +259,7 @@ export class SdPermissionTable<TModule> {
259
259
  const walk = (item: SdPermission<TModule>, type: "use" | "edit"): boolean => {
260
260
  const key = item.codeChain.join(".") + "." + type;
261
261
  const cached = cache.get(key);
262
- if (cached !== undefined) return cached;
262
+ if (cached != null) return cached;
263
263
 
264
264
  if (item.perms) {
265
265
  const permCode = item.codeChain.join(".");
@@ -295,7 +295,7 @@ export class SdPermissionTable<TModule> {
295
295
  const walk = (item: SdPermission<TModule>): boolean => {
296
296
  const key = item.codeChain.join(".");
297
297
  const cached = cache.get(key);
298
- if (cached !== undefined) return cached;
298
+ if (cached != null) return cached;
299
299
 
300
300
  if (isDisabled) {
301
301
  cache.set(key, true);
@@ -93,7 +93,7 @@ import { tablerExternalLink } from "@ng-icons/tabler-icons";
93
93
  <sd-list [inset]="true" class="flex-fill">
94
94
  @if (useUndefined()) {
95
95
  <sd-list-item
96
- [selected]="selectedItem() === undefined"
96
+ [selected]="selectedItem() == null"
97
97
  (click)="select(undefined)"
98
98
  [selectedIcon]="selectedIcon()"
99
99
  >
@@ -61,6 +61,7 @@ import { matchesSearchText } from "./matchesSearchText";
61
61
  [inline]="inline()"
62
62
  [size]="size()"
63
63
  [items]="rootDisplayItems()"
64
+ [trackByFn]="trackByFn"
64
65
  [selectMode]="selectMode()"
65
66
  [contentClass]="selectClass()"
66
67
  [multiSelectionDisplayDirection]="multiSelectionDisplayDirection()"
@@ -93,19 +94,13 @@ import { matchesSearchText } from "./matchesSearchText";
93
94
  (!required() && selectMode() === "single") ||
94
95
  (useUndefined() && selectMode() === "multi")
95
96
  ) {
96
- <div
97
- class="_sd-shared-data-select-undefined"
98
- tabindex="0"
99
- (click)="onUndefinedClick()"
100
- (keydown.enter)="onUndefinedClick()"
101
- (keydown.space)="onUndefinedClick(); $event.preventDefault()"
102
- >
97
+ <sd-select-item>
103
98
  @if (undefinedTplRef()) {
104
99
  <ng-template [ngTemplateOutlet]="undefinedTplRef()!" />
105
100
  } @else {
106
101
  <span class="tx-theme-gray-default">미지정</span>
107
102
  }
108
- </div>
103
+ </sd-select-item>
109
104
  }
110
105
  </ng-template>
111
106
 
@@ -185,6 +180,8 @@ export class SdSharedDataSelect<
185
180
  read: TemplateRef,
186
181
  });
187
182
 
183
+ trackByFn = (item: TItem): TItem["__valueKey"] => item.__valueKey;
184
+
188
185
  searchText = signal<string | undefined>(undefined);
189
186
 
190
187
  isDropdownOpen = computed(() => this._selectCtrl()?.dropdownOpen() ?? false);
@@ -224,13 +221,7 @@ export class SdSharedDataSelect<
224
221
 
225
222
  const orderProp = this.displayOrderKeyProp();
226
223
  if (orderProp != null) {
227
- result = [...result].sort((a, b) => {
228
- const aVal = (a as any)[orderProp];
229
- const bVal = (b as any)[orderProp];
230
- if (aVal < bVal) return -1;
231
- if (aVal > bVal) return 1;
232
- return 0;
233
- });
224
+ result = result.orderBy((item) => (item as any)[orderProp]);
234
225
  }
235
226
 
236
227
  return result;
@@ -247,7 +238,7 @@ export class SdSharedDataSelect<
247
238
  const check = (item: TItem, index: number): boolean => {
248
239
  const key = item.__valueKey;
249
240
  const cached = cache.get(key);
250
- if (cached !== undefined) return cached;
241
+ if (cached != null) return cached;
251
242
 
252
243
  const itemText = getSearchTextFn(item, index);
253
244
  if (matchesSearchText(itemText, searchText)) {
@@ -332,13 +323,7 @@ export class SdSharedDataSelect<
332
323
  for (const [key, children] of parentMap) {
333
324
  sorted.set(
334
325
  key,
335
- [...children].sort((a, b) => {
336
- const aVal = (a as any)[orderProp];
337
- const bVal = (b as any)[orderProp];
338
- if (aVal < bVal) return -1;
339
- if (aVal > bVal) return 1;
340
- return 0;
341
- }),
326
+ children.orderBy((item) => (item as any)[orderProp]),
342
327
  );
343
328
  }
344
329
  return sorted;
@@ -351,10 +336,6 @@ export class SdSharedDataSelect<
351
336
  );
352
337
  };
353
338
 
354
- onUndefinedClick(): void {
355
- this.value.set(undefined as any);
356
- }
357
-
358
339
  async onModalButtonClick(event: MouseEvent): Promise<void> {
359
340
  event.preventDefault();
360
341
  event.stopPropagation();
@@ -8,45 +8,53 @@ export function injectSheetDomAccessor() {
8
8
  }
9
9
 
10
10
  function getContainer(): HTMLElement {
11
- return elRef.nativeElement.querySelector("._container")!;
11
+ return elRef.nativeElement.querySelector<HTMLElement>("._sheet-container")!;
12
12
  }
13
13
 
14
14
  function getTable(): HTMLTableElement {
15
- return elRef.nativeElement.querySelector("table")!;
15
+ return elRef.nativeElement.querySelector<HTMLTableElement>("table")!;
16
16
  }
17
17
 
18
18
  function getTHead(): HTMLTableSectionElement {
19
- return getTable().querySelector("thead")!;
19
+ return getTable().querySelector<HTMLTableSectionElement>("thead")!;
20
+ }
21
+
22
+ function getLastDepthFixedHeaders(): HTMLElement[] {
23
+ return Array.from(getTHead().querySelectorAll<HTMLElement>("tr > th._last-depth._fixed"));
24
+ }
25
+
26
+ function getFocusRowIndicator(): HTMLElement {
27
+ return getContainer().querySelector<HTMLElement>("._focus-row-indicator")!;
28
+ }
29
+
30
+ function getFocusCellIndicator(): HTMLElement {
31
+ return getFocusRowIndicator().firstElementChild as HTMLElement;
32
+ }
33
+
34
+ function getSelectRowIndicatorContainer(): HTMLElement {
35
+ return getContainer().querySelector<HTMLElement>("._select-row-indicator-container")!;
36
+ }
37
+
38
+ function getSelectRowIndicators(): HTMLElement[] {
39
+ return Array.from(
40
+ getSelectRowIndicatorContainer().querySelectorAll<HTMLElement>("._select-row-indicator"),
41
+ );
42
+ }
43
+
44
+ function getColumnResizeIndicator(): HTMLElement {
45
+ return getContainer().querySelector<HTMLElement>("._resize-indicator")!;
20
46
  }
21
47
 
22
48
  function getRow(r: number): HTMLTableRowElement | null {
23
49
  const tbody = getTable().querySelector("tbody");
24
50
  if (tbody == null) return null;
25
- const rows = tbody.querySelectorAll<HTMLTableRowElement>("tr");
26
- return rows[r] ?? null;
51
+ return tbody.querySelector<HTMLTableRowElement>(`tr[data-r='${r}']`);
27
52
  }
28
53
 
29
54
  function getCell(r: number, c: number): HTMLTableCellElement | null {
30
55
  const row = getRow(r);
31
56
  if (row == null) return null;
32
- const cells = row.querySelectorAll<HTMLTableCellElement>("td[data-c]");
33
- for (const cell of cells) {
34
- if (cell.getAttribute("data-c") === String(c)) {
35
- return cell;
36
- }
37
- }
38
- return null;
39
- }
40
-
41
- function getColumnResizeIndicator(): HTMLElement {
42
- return elRef.nativeElement.querySelector("._resize-indicator")!;
43
- }
44
-
45
- function getLastDepthFixedHeaders(): HTMLElement[] {
46
- const thead = getTHead();
47
- const lastRow = thead.querySelector("tr:last-child");
48
- if (lastRow == null) return [];
49
- return Array.from(lastRow.querySelectorAll<HTMLElement>("th[style*='sticky']"));
57
+ return row.querySelector<HTMLTableCellElement>(`td[data-c='${c}']`);
50
58
  }
51
59
 
52
60
  return {
@@ -54,9 +62,13 @@ export function injectSheetDomAccessor() {
54
62
  getContainer,
55
63
  getTable,
56
64
  getTHead,
65
+ getLastDepthFixedHeaders,
66
+ getFocusRowIndicator,
67
+ getFocusCellIndicator,
68
+ getSelectRowIndicatorContainer,
69
+ getSelectRowIndicators,
70
+ getColumnResizeIndicator,
57
71
  getRow,
58
72
  getCell,
59
- getColumnResizeIndicator,
60
- getLastDepthFixedHeaders,
61
73
  };
62
74
  }
@@ -0,0 +1,69 @@
1
+ import { afterEveryRender, type Signal } from "@angular/core";
2
+ import type { injectSheetDomAccessor } from "./injectSheetDomAccessor";
3
+
4
+ export function injectSheetSelectRowIndicator<T>(options: {
5
+ domAccessor: ReturnType<typeof injectSheetDomAccessor>;
6
+ selectedItems: Signal<T[]>;
7
+ displayItems: Signal<T[]>;
8
+ }) {
9
+ afterEveryRender(() => {
10
+ const containerEl = options.domAccessor.getSelectRowIndicatorContainer();
11
+
12
+ if (options.selectedItems().length <= 0) {
13
+ containerEl.innerHTML = "";
14
+ containerEl.style.display = "none";
15
+ return;
16
+ }
17
+
18
+ const selectedTrInfos = options.selectedItems()
19
+ .map((item) => {
20
+ const r = options.displayItems().indexOf(item);
21
+ return getTrInfo(r);
22
+ })
23
+ .filter((info): info is NonNullable<typeof info> => info != null);
24
+
25
+ let indicatorHtml = "";
26
+ for (const info of selectedTrInfos) {
27
+ const style = `top: ${info.top}px; height: ${info.height - 1}px; width: ${info.width - 1}px;`;
28
+ indicatorHtml += `<div class="_select-row-indicator" style="${style}" data-r="${info.r}"></div>`;
29
+ }
30
+ containerEl.innerHTML = indicatorHtml;
31
+ containerEl.style.display = "block";
32
+ });
33
+
34
+ function getTrInfo(
35
+ r: number,
36
+ ): { r: number; top: number; width: number; height: number } | undefined {
37
+ const trEl = options.domAccessor.getRow(r);
38
+ if (trEl == null) return undefined;
39
+
40
+ return {
41
+ r,
42
+ top: trEl.offsetTop,
43
+ width: trEl.offsetWidth,
44
+ height: trEl.offsetHeight,
45
+ };
46
+ }
47
+
48
+ function redraw(): void {
49
+ const selectRowIndicatorEls = options.domAccessor.getSelectRowIndicators();
50
+
51
+ for (const el of selectRowIndicatorEls) {
52
+ const rAttr = el.getAttribute("data-r");
53
+ if (rAttr == null) continue;
54
+ const r = parseInt(rAttr, 10);
55
+ if (Number.isNaN(r)) continue;
56
+
57
+ const trInfo = getTrInfo(r);
58
+ if (trInfo == null) continue;
59
+
60
+ Object.assign(el.style, {
61
+ top: trInfo.top + "px",
62
+ width: trInfo.width + "px",
63
+ height: trInfo.height + "px",
64
+ });
65
+ }
66
+ }
67
+
68
+ return { redraw };
69
+ }