@schukai/monster 3.51.5 → 3.52.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (360) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +15 -12
  3. package/example/components/form/button.mjs +10 -0
  4. package/example/components/form/select.mjs +25 -0
  5. package/example/components/form/tree-select.mjs +27 -0
  6. package/example/components/host/host.mjs +0 -0
  7. package/example/components/notify/message.mjs +4 -0
  8. package/example/components/notify/notify.mjs +4 -0
  9. package/example/components/state/log.mjs +0 -0
  10. package/example/components/state/state.mjs +0 -0
  11. package/package.json +6 -2
  12. package/source/components/constants.mjs +132 -0
  13. package/source/components/datatable/columnbar.mjs +310 -0
  14. package/source/components/datatable/constants.mjs +121 -0
  15. package/source/components/datatable/dataset.mjs +219 -0
  16. package/source/components/datatable/datasource/dom.mjs +186 -0
  17. package/source/components/datatable/datasource/namespace.mjs +13 -0
  18. package/source/components/datatable/datasource/rest.mjs +400 -0
  19. package/source/components/datatable/datasource.mjs +102 -0
  20. package/source/components/datatable/datatable/header.mjs +268 -0
  21. package/source/components/datatable/datatable/namespace.mjs +13 -0
  22. package/source/components/datatable/datatable.mjs +789 -0
  23. package/source/components/datatable/embedded-pagination.mjs +113 -0
  24. package/source/components/datatable/filter/abstract-base.mjs +31 -0
  25. package/source/components/datatable/filter/date-range.mjs +1041 -0
  26. package/source/components/datatable/filter/input.mjs +175 -0
  27. package/source/components/datatable/filter/namespace.mjs +13 -0
  28. package/source/components/datatable/filter/range.mjs +671 -0
  29. package/source/components/datatable/filter/select.mjs +65 -0
  30. package/source/components/datatable/filter/settings.mjs +116 -0
  31. package/source/components/datatable/filter-button.mjs +98 -0
  32. package/source/components/datatable/filter.mjs +929 -0
  33. package/source/components/datatable/namespace.mjs +11 -0
  34. package/source/components/datatable/pagination.mjs +456 -0
  35. package/source/components/datatable/style/column-bar.pcss +123 -0
  36. package/source/components/datatable/style/dataset.pcss +13 -0
  37. package/source/components/datatable/style/datasource.pcss +16 -0
  38. package/source/components/datatable/style/datatable.pcss +239 -0
  39. package/source/components/datatable/style/embedded-pagination.pcss +101 -0
  40. package/source/components/datatable/style/filter-button.pcss +22 -0
  41. package/source/components/datatable/style/filter-controls-defaults.pcss +46 -0
  42. package/source/components/datatable/style/filter-date-range.pcss +9 -0
  43. package/source/components/datatable/style/filter-range.pcss +5 -0
  44. package/source/components/datatable/style/filter.pcss +156 -0
  45. package/source/components/datatable/style/pagination.pcss +59 -0
  46. package/source/components/datatable/style/select-filter.pcss +27 -0
  47. package/source/components/datatable/stylesheet/column-bar.mjs +33 -0
  48. package/source/components/datatable/stylesheet/dataset.mjs +33 -0
  49. package/source/components/datatable/stylesheet/datasource.mjs +33 -0
  50. package/source/components/datatable/stylesheet/datatable.mjs +33 -0
  51. package/source/components/datatable/stylesheet/embedded-pagination.mjs +33 -0
  52. package/source/components/datatable/stylesheet/filter-button.mjs +33 -0
  53. package/source/components/datatable/stylesheet/filter-controls-defaults.mjs +33 -0
  54. package/source/components/datatable/stylesheet/filter-date-range.mjs +33 -0
  55. package/source/components/datatable/stylesheet/filter-range.mjs +33 -0
  56. package/source/components/datatable/stylesheet/filter.mjs +33 -0
  57. package/source/components/datatable/stylesheet/namespace.mjs +13 -0
  58. package/source/components/datatable/stylesheet/pagination.mjs +33 -0
  59. package/source/components/datatable/stylesheet/select-filter.mjs +33 -0
  60. package/source/components/datatable/util.mjs +60 -0
  61. package/source/components/form/action-button.mjs +262 -0
  62. package/source/components/form/api-button.mjs +515 -0
  63. package/source/components/form/button-bar.mjs +739 -0
  64. package/source/components/form/button.mjs +350 -0
  65. package/source/components/form/confirm-button.mjs +330 -0
  66. package/source/components/form/constants.mjs +111 -0
  67. package/source/components/form/context-help.mjs +123 -0
  68. package/source/components/form/events.mjs +84 -0
  69. package/source/components/form/form.mjs +601 -0
  70. package/source/components/form/message-state-button.mjs +396 -0
  71. package/source/components/form/namespace.mjs +13 -0
  72. package/source/components/form/popper-button.mjs +435 -0
  73. package/source/components/form/popper.mjs +487 -0
  74. package/source/components/form/reload.mjs +360 -0
  75. package/source/components/form/select.mjs +2314 -0
  76. package/source/components/form/shadow-reload.mjs +137 -0
  77. package/source/components/form/state-button.mjs +182 -0
  78. package/source/components/form/style/action-button.pcss +41 -0
  79. package/source/components/form/style/api-button.pcss +0 -0
  80. package/source/components/form/style/button-bar.pcss +51 -0
  81. package/source/components/form/style/button.pcss +8 -0
  82. package/source/components/form/style/confirm-button.pcss +17 -0
  83. package/source/components/form/style/context-help.pcss +16 -0
  84. package/source/components/form/style/form.pcss +10 -0
  85. package/source/components/form/style/message-state-button.pcss +10 -0
  86. package/source/components/form/style/popper-button.pcss +16 -0
  87. package/source/components/form/style/popper.pcss +8 -0
  88. package/source/components/form/style/select.pcss +265 -0
  89. package/source/components/form/style/state-button.pcss +116 -0
  90. package/source/components/form/style/tabs.pcss +170 -0
  91. package/source/components/form/style/tree-select.pcss +81 -0
  92. package/source/components/form/stylesheet/action-button.mjs +33 -0
  93. package/source/components/form/stylesheet/api-button.mjs +33 -0
  94. package/source/components/form/stylesheet/button-bar.mjs +33 -0
  95. package/source/components/form/stylesheet/button.mjs +33 -0
  96. package/source/components/form/stylesheet/confirm-button.mjs +33 -0
  97. package/source/components/form/stylesheet/context-help.mjs +33 -0
  98. package/source/components/form/stylesheet/form.mjs +33 -0
  99. package/source/components/form/stylesheet/message-state-button.mjs +33 -0
  100. package/source/components/form/stylesheet/namespace.mjs +13 -0
  101. package/source/components/form/stylesheet/popper-button.mjs +33 -0
  102. package/source/components/form/stylesheet/popper.mjs +33 -0
  103. package/source/components/form/stylesheet/select.mjs +33 -0
  104. package/source/components/form/stylesheet/state-button.mjs +33 -0
  105. package/source/components/form/stylesheet/tabs.mjs +33 -0
  106. package/source/components/form/stylesheet/tree-select.mjs +33 -0
  107. package/source/components/form/tabs.mjs +1011 -0
  108. package/source/components/form/template.mjs +373 -0
  109. package/source/components/form/tree-select.mjs +527 -0
  110. package/source/components/form/types/namespace.mjs +13 -0
  111. package/source/components/form/types/state.mjs +93 -0
  112. package/source/components/form/util/fetch.mjs +133 -0
  113. package/source/components/form/util/floating-ui.mjs +245 -0
  114. package/source/components/form/util/namespace.mjs +13 -0
  115. package/source/components/form/util/popper.mjs +49 -0
  116. package/source/components/host/call-button.mjs +236 -0
  117. package/source/components/host/collapse.mjs +526 -0
  118. package/source/components/host/config-manager.mjs +304 -0
  119. package/source/components/host/constants.mjs +18 -0
  120. package/source/components/host/details.mjs +268 -0
  121. package/source/components/host/events.mjs +131 -0
  122. package/source/components/host/host.mjs +420 -0
  123. package/source/components/host/namespace.mjs +13 -0
  124. package/source/components/host/overlay.mjs +339 -0
  125. package/source/components/host/style/call-button.pcss +36 -0
  126. package/source/components/host/style/collapse.pcss +67 -0
  127. package/source/components/host/style/config-manager.pcss +5 -0
  128. package/source/components/host/style/details.pcss +68 -0
  129. package/source/components/host/style/host.pcss +43 -0
  130. package/source/components/host/style/overlay.pcss +73 -0
  131. package/source/components/host/style/toggle-button.pcss +36 -0
  132. package/source/components/host/style/viewer.pcss +13 -0
  133. package/source/components/host/stylesheet/call-button.mjs +33 -0
  134. package/source/components/host/stylesheet/collapse.mjs +33 -0
  135. package/source/components/host/stylesheet/config-manager.mjs +33 -0
  136. package/source/components/host/stylesheet/details.mjs +33 -0
  137. package/source/components/host/stylesheet/host.mjs +33 -0
  138. package/source/components/host/stylesheet/namespace.mjs +13 -0
  139. package/source/components/host/stylesheet/overlay.mjs +33 -0
  140. package/source/components/host/stylesheet/toggle-button.mjs +33 -0
  141. package/source/components/host/stylesheet/viewer.mjs +33 -0
  142. package/source/components/host/toggle-button.mjs +88 -0
  143. package/source/components/host/util.mjs +23 -0
  144. package/source/components/host/viewer.mjs +309 -0
  145. package/source/components/namespace.mjs +14 -0
  146. package/source/components/notify/constants.mjs +15 -0
  147. package/source/components/notify/events.mjs +15 -0
  148. package/source/components/notify/message.mjs +374 -0
  149. package/source/components/notify/namespace.mjs +15 -0
  150. package/source/components/notify/notify.mjs +236 -0
  151. package/source/components/notify/style/message.pcss +57 -0
  152. package/source/components/notify/style/notify.pcss +118 -0
  153. package/source/components/notify/stylesheet/message.mjs +33 -0
  154. package/source/components/notify/stylesheet/namespace.mjs +15 -0
  155. package/source/components/notify/stylesheet/notify.mjs +33 -0
  156. package/source/components/state/log/entry.mjs +126 -0
  157. package/source/components/state/log/namespace.mjs +13 -0
  158. package/source/components/state/log.mjs +275 -0
  159. package/source/components/state/namespace.mjs +13 -0
  160. package/source/components/state/state.mjs +131 -0
  161. package/source/components/state/style/log.pcss +111 -0
  162. package/source/components/state/style/state.pcss +113 -0
  163. package/source/components/state/stylesheet/log.mjs +33 -0
  164. package/source/components/state/stylesheet/state.mjs +33 -0
  165. package/source/components/style/badge.pcss +92 -0
  166. package/source/components/style/border.pcss +77 -0
  167. package/source/components/style/button.pcss +105 -0
  168. package/source/components/style/card.pcss +108 -0
  169. package/source/components/style/color.pcss +257 -0
  170. package/source/components/style/common.pcss +103 -0
  171. package/source/components/style/control.pcss +11 -0
  172. package/source/components/style/data-grid.pcss +43 -0
  173. package/source/components/style/display.pcss +42 -0
  174. package/source/components/style/floating-ui.pcss +33 -0
  175. package/source/components/style/form.pcss +5 -0
  176. package/source/components/style/host.pcss +15 -0
  177. package/source/components/style/link.pcss +63 -0
  178. package/source/components/style/mixin/badge.pcss +18 -0
  179. package/source/components/style/mixin/button.pcss +54 -0
  180. package/source/components/style/mixin/form.pcss +247 -0
  181. package/source/components/style/mixin/hover.pcss +8 -0
  182. package/source/components/style/mixin/media.pcss +107 -0
  183. package/source/components/style/mixin/property.pcss +288 -0
  184. package/source/components/style/mixin/skeleton.pcss +26 -0
  185. package/source/components/style/mixin/spinner.pcss +24 -0
  186. package/source/components/style/mixin/typography.pcss +52 -0
  187. package/source/components/style/normalize.pcss +14 -0
  188. package/source/components/style/popper.pcss +78 -0
  189. package/source/components/style/property.pcss +17 -0
  190. package/source/components/style/ripple.pcss +14 -0
  191. package/source/components/style/skeleton.pcss +28 -0
  192. package/source/components/style/space.pcss +47 -0
  193. package/source/components/style/spinner.pcss +6 -0
  194. package/source/components/style/table.pcss +46 -0
  195. package/source/components/style/theme.pcss +119 -0
  196. package/source/components/style/typography.pcss +131 -0
  197. package/source/components/stylesheet/badge.mjs +33 -0
  198. package/source/components/stylesheet/border.mjs +33 -0
  199. package/source/components/stylesheet/button.mjs +33 -0
  200. package/source/components/stylesheet/card.mjs +33 -0
  201. package/source/components/stylesheet/color.mjs +33 -0
  202. package/source/components/stylesheet/common.mjs +33 -0
  203. package/source/components/stylesheet/control.mjs +33 -0
  204. package/source/components/stylesheet/data-grid.mjs +33 -0
  205. package/source/components/stylesheet/display.mjs +33 -0
  206. package/source/components/stylesheet/floating-ui.mjs +33 -0
  207. package/source/components/stylesheet/form.mjs +33 -0
  208. package/source/components/stylesheet/host.mjs +33 -0
  209. package/source/components/stylesheet/link.mjs +33 -0
  210. package/source/components/stylesheet/namespace.mjs +13 -0
  211. package/source/components/stylesheet/normalize.mjs +33 -0
  212. package/source/components/stylesheet/popper.mjs +33 -0
  213. package/source/components/stylesheet/property.mjs +33 -0
  214. package/source/components/stylesheet/ripple.mjs +33 -0
  215. package/source/components/stylesheet/skeleton.mjs +33 -0
  216. package/source/components/stylesheet/space.mjs +33 -0
  217. package/source/components/stylesheet/spinner.mjs +33 -0
  218. package/source/components/stylesheet/table.mjs +33 -0
  219. package/source/components/stylesheet/theme.mjs +33 -0
  220. package/source/components/stylesheet/tree-menu.mjs +33 -0
  221. package/source/components/stylesheet/typography.mjs +33 -0
  222. package/source/components/tree-menu/namespace.mjs +13 -0
  223. package/source/components/tree-menu/style/tree-menu.pcss +107 -0
  224. package/source/components/tree-menu/stylesheet/namespace.mjs +13 -0
  225. package/source/components/tree-menu/stylesheet/tree-menu.mjs +33 -0
  226. package/source/components/tree-menu/tree-menu.mjs +660 -0
  227. package/source/constraints/abstract.mjs +17 -24
  228. package/source/constraints/abstractoperator.mjs +27 -22
  229. package/source/constraints/andoperator.mjs +20 -17
  230. package/source/constraints/invalid.mjs +17 -17
  231. package/source/constraints/isarray.mjs +20 -20
  232. package/source/constraints/isobject.mjs +20 -20
  233. package/source/constraints/oroperator.mjs +45 -45
  234. package/source/constraints/valid.mjs +17 -17
  235. package/source/data/buildmap.mjs +108 -103
  236. package/source/data/buildtree.mjs +59 -57
  237. package/source/data/datasource/dom.mjs +80 -84
  238. package/source/data/datasource/namespace.mjs +1 -1
  239. package/source/data/datasource/server/restapi/data-fetch-error.mjs +27 -25
  240. package/source/data/datasource/server/restapi/writeerror.mjs +34 -32
  241. package/source/data/datasource/server/restapi.mjs +176 -177
  242. package/source/data/datasource/server/webconnect.mjs +150 -156
  243. package/source/data/datasource/server.mjs +58 -59
  244. package/source/data/datasource/storage/localstorage.mjs +25 -24
  245. package/source/data/datasource/storage/sessionstorage.mjs +28 -25
  246. package/source/data/datasource/storage.mjs +74 -73
  247. package/source/data/datasource.mjs +176 -167
  248. package/source/data/diff.mjs +98 -97
  249. package/source/data/extend.mjs +42 -42
  250. package/source/data/pathfinder.mjs +301 -288
  251. package/source/data/pipe.mjs +36 -36
  252. package/source/data/transformer.mjs +742 -726
  253. package/source/dom/assembler.mjs +44 -44
  254. package/source/dom/attributes.mjs +142 -122
  255. package/source/dom/constants.mjs +62 -58
  256. package/source/dom/customcontrol.mjs +299 -299
  257. package/source/dom/customelement.mjs +843 -806
  258. package/source/dom/dimension.mjs +56 -46
  259. package/source/dom/events.mjs +74 -69
  260. package/source/dom/focusmanager.mjs +175 -175
  261. package/source/dom/locale.mjs +28 -28
  262. package/source/dom/ready.mjs +13 -13
  263. package/source/dom/resource/data.mjs +117 -111
  264. package/source/dom/resource/link/stylesheet.mjs +16 -16
  265. package/source/dom/resource/link.mjs +94 -96
  266. package/source/dom/resource/script.mjs +72 -74
  267. package/source/dom/resource.mjs +174 -172
  268. package/source/dom/resourcemanager.mjs +152 -156
  269. package/source/dom/slotted.mjs +78 -80
  270. package/source/dom/template.mjs +126 -112
  271. package/source/dom/theme.mjs +35 -35
  272. package/source/dom/updater.mjs +673 -651
  273. package/source/dom/util/extract-keys.mjs +34 -22
  274. package/source/dom/util/init-options-from-attributes.mjs +46 -38
  275. package/source/dom/util/namespace.mjs +13 -0
  276. package/source/dom/util/set-option-from-attribute.mjs +35 -29
  277. package/source/dom/util.mjs +112 -81
  278. package/source/dom/worker/factory.mjs +83 -83
  279. package/source/i18n/formatter.mjs +75 -73
  280. package/source/i18n/locale.mjs +146 -144
  281. package/source/i18n/provider.mjs +70 -64
  282. package/source/i18n/providers/embed.mjs +136 -127
  283. package/source/i18n/providers/fetch.mjs +84 -76
  284. package/source/i18n/translations.mjs +205 -195
  285. package/source/logging/handler/console.mjs +36 -36
  286. package/source/logging/handler.mjs +140 -140
  287. package/source/logging/logentry.mjs +25 -25
  288. package/source/logging/logger.mjs +177 -175
  289. package/source/math/random.mjs +63 -59
  290. package/source/monster.mjs +223 -103
  291. package/source/net/webconnect/message.mjs +31 -31
  292. package/source/net/webconnect.mjs +278 -271
  293. package/source/text/bracketed-key-value-hash.mjs +182 -179
  294. package/source/text/formatter.mjs +235 -210
  295. package/source/text/generate-range-comparison-expression.mjs +56 -34
  296. package/source/text/namespace.mjs +1 -1
  297. package/source/types/base.mjs +69 -61
  298. package/source/types/basewithoptions.mjs +46 -46
  299. package/source/types/binary.mjs +20 -20
  300. package/source/types/dataurl.mjs +96 -90
  301. package/source/types/global.mjs +45 -39
  302. package/source/types/id.mjs +25 -25
  303. package/source/types/internal.mjs +115 -114
  304. package/source/types/is.mjs +56 -40
  305. package/source/types/mediatype.mjs +119 -119
  306. package/source/types/namespace.mjs +1 -1
  307. package/source/types/node.mjs +160 -150
  308. package/source/types/nodelist.mjs +94 -96
  309. package/source/types/noderecursiveiterator.mjs +50 -50
  310. package/source/types/observablequeue.mjs +73 -73
  311. package/source/types/observer.mjs +104 -104
  312. package/source/types/observerlist.mjs +66 -66
  313. package/source/types/proxyobserver.mjs +210 -210
  314. package/source/types/queue.mjs +63 -63
  315. package/source/types/randomid.mjs +13 -13
  316. package/source/types/regex.mjs +3 -1
  317. package/source/types/stack.mjs +64 -64
  318. package/source/types/tokenlist.mjs +206 -205
  319. package/source/types/typeof.mjs +12 -10
  320. package/source/types/uniquequeue.mjs +48 -48
  321. package/source/types/uuid.mjs +32 -32
  322. package/source/types/validate.mjs +67 -67
  323. package/source/types/version.mjs +115 -105
  324. package/source/util/clone.mjs +103 -91
  325. package/source/util/comparator.mjs +97 -97
  326. package/source/util/deadmansswitch.mjs +40 -44
  327. package/source/util/freeze.mjs +10 -9
  328. package/source/util/namespace.mjs +1 -1
  329. package/source/util/processing.mjs +104 -105
  330. package/source/util/runtime.mjs +56 -44
  331. package/source/util/trimspaces.mjs +24 -24
  332. package/test/cases/components/form/button.mjs +122 -0
  333. package/test/cases/components/form/confirm-button.mjs +127 -0
  334. package/test/cases/components/form/form.mjs +317 -0
  335. package/test/cases/components/form/reload.mjs +188 -0
  336. package/test/cases/components/form/select.mjs +229 -0
  337. package/test/cases/components/form/state-button.mjs +130 -0
  338. package/test/cases/components/form/tabs.mjs +98 -0
  339. package/test/cases/components/form/template.mjs +189 -0
  340. package/test/cases/components/form/tree-select.mjs +216 -0
  341. package/test/cases/components/host/details.mjs +68 -0
  342. package/test/cases/components/host/host.mjs +70 -0
  343. package/test/cases/components/host/overlay.mjs +60 -0
  344. package/test/cases/components/host/util.mjs +79 -0
  345. package/test/cases/components/notify/message.mjs +39 -0
  346. package/test/cases/components/notify/notify.mjs +89 -0
  347. package/test/cases/dom/customcontrol.mjs +5 -4
  348. package/test/cases/math/random.mjs +0 -1
  349. package/test/cases/monster.mjs +1 -1
  350. package/test/cases/net/webconnect/message.mjs +0 -1
  351. package/test/cases/types/node.mjs +1 -1
  352. package/test/util/chai-dom.mjs +2 -2
  353. package/test/util/intersection-mock.mjs +69 -0
  354. package/test/util/jsdom.mjs +41 -25
  355. package/test/util/localstorage.mjs +1 -0
  356. package/test/util/resize-observer.mjs +29 -0
  357. package/test/util/websocket.mjs +4 -1
  358. package/test/web/import.js +16 -1
  359. package/test/web/test.html +28 -5
  360. package/test/web/tests.js +30398 -17879
@@ -0,0 +1,789 @@
1
+ /**
2
+ * Copyright 2023 schukai GmbH
3
+ * SPDX-License-Identifier: AGPL-3.0
4
+ */
5
+
6
+ import { Datasource } from "./datasource.mjs";
7
+ import {
8
+ assembleMethodSymbol,
9
+ CustomElement,
10
+ registerCustomElement,
11
+ getSlottedElements,
12
+ } from "../../dom/customelement.mjs";
13
+ import { findTargetElementFromEvent } from "../../dom/events.mjs";
14
+ import {
15
+ isString,
16
+ isFunction,
17
+ isInstance,
18
+ isObject,
19
+ isArray,
20
+ } from "../../types/is.mjs";
21
+ import { Observer } from "../../types/observer.mjs";
22
+ import {
23
+ ATTRIBUTE_DATATABLE_HEAD,
24
+ ATTRIBUTE_DATATABLE_GRID_TEMPLATE,
25
+ ATTRIBUTE_DATASOURCE_SELECTOR,
26
+ ATTRIBUTE_DATATABLE_ALIGN,
27
+ ATTRIBUTE_DATATABLE_SORTABLE,
28
+ ATTRIBUTE_DATATABLE_MODE,
29
+ ATTRIBUTE_DATATABLE_INDEX,
30
+ ATTRIBUTE_DATATABLE_MODE_HIDDEN,
31
+ ATTRIBUTE_DATATABLE_MODE_VISIBLE,
32
+ ATTRIBUTE_DATATABLE_RESPONSIVE_BREAKPOINT,
33
+ ATTRIBUTE_DATATABLE_MODE_FIXED,
34
+ } from "./constants.mjs";
35
+ import { instanceSymbol } from "../../constants.mjs";
36
+ import {
37
+ Header,
38
+ createOrderStatement,
39
+ DIRECTION_ASC,
40
+ DIRECTION_DESC,
41
+ DIRECTION_NONE,
42
+ } from "./datatable/header.mjs";
43
+ import { DatatableStyleSheet } from "./stylesheet/datatable.mjs";
44
+ import {
45
+ handleDataSourceChanges,
46
+ datasourceLinkedElementSymbol,
47
+ } from "./util.mjs";
48
+ import "./columnbar.mjs";
49
+ import "./filter-button.mjs";
50
+ import { getDocument, getWindow } from "../../dom/util.mjs";
51
+ import { addAttributeToken } from "../../dom/attributes.mjs";
52
+ import { ATTRIBUTE_ERRORMESSAGE } from "../../dom/constants.mjs";
53
+ import { getDocumentTranslations } from "../../i18n/translations.mjs";
54
+ import "../state/state.mjs";
55
+ import "../host/collapse.mjs";
56
+ import { generateUniqueConfigKey } from "../host/util.mjs";
57
+
58
+ import "./datasource/dom.mjs";
59
+ import "./datasource/rest.mjs";
60
+
61
+ export { DataTable };
62
+
63
+ /**
64
+ * @private
65
+ * @type {symbol}
66
+ */
67
+ const gridElementSymbol = Symbol("gridElement");
68
+
69
+ /**
70
+ * @private
71
+ * @type {symbol}
72
+ */
73
+ const gridHeadersElementSymbol = Symbol("gridHeadersElement");
74
+
75
+ /**
76
+ * @private
77
+ * @type {symbol}
78
+ */
79
+ const columnBarElementSymbol = Symbol("columnBarElement");
80
+
81
+ /**
82
+ * The DataTable component is used to show the data from a data source.
83
+ *
84
+ * <img src="./images/datatable.png">
85
+ *
86
+ * Dependencies: the system uses functions of the [monsterjs](https://monsterjs.org/) library
87
+ *
88
+ * You can create this control either by specifying the HTML tag <monster-datatable />` directly in the HTML or using
89
+ * Javascript via the `document.createElement('monster-datatable');` method.
90
+ *
91
+ * ```html
92
+ * <monster-datatable></monster-datatable>
93
+ * ```
94
+ *
95
+ * Or you can create this CustomControl directly in Javascript:
96
+ *
97
+ * ```js
98
+ * import '@schukai/component-datatable/source/datatable.mjs';
99
+ * document.createElement('monster-datatable');
100
+ * ```
101
+ *
102
+ * The Body should have a class "hidden" to ensure that the styles are applied correctly.
103
+ *
104
+ * ```css
105
+ * body.hidden {
106
+ * visibility: hidden;
107
+ * }
108
+ * ```
109
+ *
110
+ * @startuml datatable.png
111
+ * skinparam monochrome true
112
+ * skinparam shadowing false
113
+ * HTMLElement <|-- CustomElement
114
+ * CustomElement <|-- Datatable
115
+ * @enduml
116
+ *
117
+ * @copyright schukai GmbH
118
+ * @memberOf Monster.Components.Datatable
119
+ * @summary A data table
120
+ */
121
+ class DataTable extends CustomElement {
122
+ /**
123
+ * This method is called by the `instanceof` operator.
124
+ * @returns {symbol}
125
+ */
126
+ static get [instanceSymbol]() {
127
+ return Symbol.for("@schukai/monster/components/datatable@@instance");
128
+ }
129
+
130
+ /**
131
+ * To set the options via the html tag the attribute `data-monster-options` must be used.
132
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
133
+ *
134
+ * The individual configuration values can be found in the table.
135
+ *
136
+ * @property {Object} templates Template definitions
137
+ * @property {string} templates.main Main template
138
+ * @property {Object} datasource Datasource configuration
139
+ * @property {string} datasource.selector Selector for the datasource
140
+ * @property {Object} mapping Mapping configuration
141
+ * @property {string} mapping.data Data mapping
142
+ * @property {Array} data Data
143
+ * @property {Array} headers Headers
144
+ * @property {Object} responsive Responsive configuration
145
+ * @property {number} responsive.breakpoint Breakpoint for responsive mode
146
+ * @property {Object} labels Labels
147
+ * @property {string} labels.theListContainsNoEntries Label for empty state
148
+ * @property {Object} features Features
149
+ * @property {boolean} features.settings Settings feature
150
+ * @property {boolean} features.footer Footer feature
151
+ * @property {boolean} features.autoInit Auto init feature (init datasource automatically)
152
+ * @property {Object} templateMapping Template mapping
153
+ * @property {string} templateMapping.row-key Row key
154
+ * @property {string} templateMapping.filter-id Filter id
155
+ **/
156
+ get defaults() {
157
+ return Object.assign(
158
+ {},
159
+ super.defaults,
160
+ {
161
+ templates: {
162
+ main: getTemplate(),
163
+ emptyState: getEmptyTemplate(),
164
+ },
165
+
166
+ datasource: {
167
+ selector: null,
168
+ },
169
+
170
+ mapping: {
171
+ data: "dataset",
172
+ },
173
+
174
+ data: [],
175
+ headers: [],
176
+
177
+ responsive: {
178
+ breakpoint: 800,
179
+ },
180
+
181
+ labels: {
182
+ theListContainsNoEntries: "The list contains no entries",
183
+ },
184
+
185
+ features: {
186
+ settings: true,
187
+ footer: true,
188
+ autoInit: true,
189
+ },
190
+
191
+ templateMapping: {
192
+ "row-key": null,
193
+ "filter-id": null,
194
+ },
195
+ },
196
+ initOptionsFromArguments.call(this),
197
+ );
198
+ }
199
+
200
+ /**
201
+ *
202
+ * @param {string} selector
203
+ * @returns {NodeListOf<*>}
204
+ */
205
+ getGridElements(selector) {
206
+ return this[gridElementSymbol].querySelectorAll(selector);
207
+ }
208
+
209
+ /**
210
+ *
211
+ * @return {string}
212
+ */
213
+ static getTag() {
214
+ return "monster-datatable";
215
+ }
216
+
217
+ /**
218
+ *
219
+ * @return {Monster.Components.Form.Form}
220
+ */
221
+ [assembleMethodSymbol]() {;
222
+
223
+ const rawKey = this.getOption("templateMapping.row-key");
224
+
225
+ if (rawKey === null) {
226
+ if (this.id !== null && this.id !== "") {
227
+ const rawKey = this.getOption("templateMapping.row-key");
228
+ if (rawKey === null) {
229
+ this.setOption("templateMapping.row-key", this.id + "-row");
230
+ }
231
+ } else {
232
+ this.setOption("templateMapping.row-key", "row");
233
+ }
234
+ }
235
+
236
+ if (this.id !== null && this.id !== "") {
237
+ this.setOption("templateMapping.filter-id", "" + this.id + "-filter");
238
+ } else {
239
+ this.setOption("templateMapping.filter-id", "filter");
240
+ }
241
+
242
+ super[assembleMethodSymbol]();
243
+
244
+ initControlReferences.call(this);
245
+ initEventHandler.call(this);
246
+
247
+ const selector = this.getOption("datasource.selector");
248
+
249
+ if (isString(selector)) {
250
+ const elements = document.querySelectorAll(selector);
251
+ if (elements.length !== 1) {
252
+ throw new Error("the selector must match exactly one element");
253
+ }
254
+
255
+ const element = elements[0];
256
+
257
+ if (!isInstance(element, Datasource)) {
258
+ throw new TypeError("the element must be a datasource");
259
+ }
260
+
261
+ this[datasourceLinkedElementSymbol] = element;
262
+
263
+ setTimeout(() => {
264
+ handleDataSourceChanges.call(this);
265
+ element.datasource.attachObserver(
266
+ new Observer(handleDataSourceChanges.bind(this)),
267
+ );
268
+ }, 0);
269
+ }
270
+
271
+ getHostConfig
272
+ .call(this, getColumnVisibilityConfigKey)
273
+ .then((config) => {
274
+ try {
275
+ initGridAndStructs.call(this, config);
276
+ } catch (error) {
277
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, String(error));
278
+ }
279
+
280
+ updateColumnBar.call(this);
281
+ })
282
+ .catch((error) => {
283
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, String(error));
284
+ });
285
+
286
+ getHostConfig
287
+ .call(this, getFilterConfigKey)
288
+ .then((config) => {
289
+ try {
290
+ // initGridAndStructs.call(self, config);
291
+ } catch (error) {
292
+ // addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, String(error));
293
+ }
294
+
295
+ //updateColumnBar.call(self);
296
+ })
297
+ .catch((error) => {
298
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, String(error));
299
+ });
300
+ }
301
+
302
+ /**
303
+ *
304
+ * @return {CSSStyleSheet[]}
305
+ */
306
+ static getCSSStyleSheet() {
307
+ return [DatatableStyleSheet];
308
+ }
309
+ }
310
+
311
+ /**
312
+ * @private
313
+ * @returns {string}
314
+ */
315
+ function getColumnVisibilityConfigKey() {
316
+ return generateUniqueConfigKey("datatable", this?.id, "columns-visibility");
317
+ }
318
+
319
+ /**
320
+ * @private
321
+ * @returns {string}
322
+ */
323
+ function getFilterConfigKey() {
324
+ return generateUniqueConfigKey("datatable", this?.id, "filter");
325
+ }
326
+
327
+ /**
328
+ * @private
329
+ * @returns {Promise}
330
+ */
331
+ function getHostConfig(callback) {;
332
+ const document = getDocument();
333
+ const host = document.querySelector("monster-host");
334
+
335
+ if (!(host && this.id)) {
336
+ return Promise.resolve({});
337
+ }
338
+
339
+ if (!host || !isFunction(host?.getConfig)) {
340
+ throw new TypeError("the host must be a monster-host");
341
+ }
342
+
343
+ const configKey = callback.call(this);
344
+ return host
345
+ .getConfig(configKey)
346
+ .then((config) => {
347
+ return config;
348
+ })
349
+ .catch(() => {
350
+ return {};
351
+ });
352
+ }
353
+
354
+ /**
355
+ * @private
356
+ */
357
+ function updateColumnBar() {;
358
+ if (!this[columnBarElementSymbol]) {
359
+ return;
360
+ }
361
+
362
+ const columns = [];
363
+ for (const header of this.getOption("headers")) {
364
+ const mode = header.getInternal("mode");
365
+
366
+ if (mode === ATTRIBUTE_DATATABLE_MODE_FIXED) {
367
+ continue;
368
+ }
369
+
370
+ columns.push({
371
+ visible: mode === ATTRIBUTE_DATATABLE_MODE_HIDDEN ? false : true,
372
+ name: header.label,
373
+ index: header.index,
374
+ });
375
+ }
376
+
377
+ this[columnBarElementSymbol].setOption("columns", columns);
378
+ }
379
+
380
+ /**
381
+ * @private
382
+ */
383
+ function updateHeaderFromColumnBar() {;
384
+
385
+ if (!this[columnBarElementSymbol]) {
386
+ return;
387
+ }
388
+
389
+ const options = this[columnBarElementSymbol].getOption("columns");
390
+ if (!isArray(options)) return;
391
+
392
+ const invisibleMap = {};
393
+
394
+ for (let i = 0; i < options.length; i++) {
395
+ const option = options[i];
396
+ invisibleMap[option.index] = option.visible;
397
+ }
398
+
399
+ for (const header of this.getOption("headers")) {
400
+ const mode = header.getInternal("mode");
401
+
402
+ if (mode === ATTRIBUTE_DATATABLE_MODE_FIXED) {
403
+ continue;
404
+ }
405
+
406
+ if (invisibleMap[header.index] === false) {
407
+ header.setInternal("mode", ATTRIBUTE_DATATABLE_MODE_HIDDEN);
408
+ } else {
409
+ header.setInternal("mode", ATTRIBUTE_DATATABLE_MODE_VISIBLE);
410
+ }
411
+ }
412
+ }
413
+
414
+ /**
415
+ * @private
416
+ */
417
+ function updateConfigColumnBar() {;
418
+
419
+ if (!this[columnBarElementSymbol]) {
420
+ return;
421
+ }
422
+
423
+ const options = this[columnBarElementSymbol].getOption("columns");
424
+ if (!isArray(options)) return;
425
+
426
+ const map = {};
427
+ for (let i = 0; i < options.length; i++) {
428
+ const option = options[i];
429
+ map[option.name] = option.visible;
430
+ }
431
+
432
+ const document = getDocument();
433
+ const host = document.querySelector("monster-host");
434
+ if (!(host && this.id)) {
435
+ return;
436
+ }
437
+ const configKey = getColumnVisibilityConfigKey.call(this);
438
+
439
+ try {
440
+ host.setConfig(configKey, map);
441
+ } catch (error) {
442
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, String(error));
443
+ }
444
+ }
445
+
446
+ /**
447
+ * @private
448
+ */
449
+ function initEventHandler() {
450
+ const self = this;
451
+
452
+ getWindow().addEventListener("resize", (event) => {
453
+ updateGrid.call(self);
454
+ });
455
+
456
+ self[columnBarElementSymbol].attachObserver(
457
+ new Observer((e) => {
458
+ updateHeaderFromColumnBar.call(self);
459
+ updateGrid.call(self);
460
+ updateConfigColumnBar.call(self);
461
+ }),
462
+ );
463
+
464
+ self[gridHeadersElementSymbol].addEventListener("click", function (event) {
465
+ let element = null;
466
+ const datasource = self[datasourceLinkedElementSymbol];
467
+ if (!datasource) {
468
+ return;
469
+ }
470
+
471
+ element = findTargetElementFromEvent(event, ATTRIBUTE_DATATABLE_SORTABLE);
472
+ if (element) {
473
+ const index = element.parentNode.getAttribute(ATTRIBUTE_DATATABLE_INDEX);
474
+ const headers = self.getOption("headers");
475
+
476
+ event.preventDefault();
477
+
478
+ headers[index].changeDirection();
479
+
480
+ setTimeout(function () {
481
+ /** hotfix, normally this should be done via the updater, no idea why this is not possible. */
482
+ element.setAttribute(
483
+ ATTRIBUTE_DATATABLE_SORTABLE,
484
+ `${headers[index].field} ${headers[index].direction}`,
485
+ );
486
+ setDataSource.call(
487
+ self,
488
+ { orderBy: createOrderStatement(headers) },
489
+ true,
490
+ );
491
+ }, 0);
492
+ }
493
+ });
494
+ }
495
+
496
+ /**
497
+ * @private
498
+ */
499
+ function initGridAndStructs(hostConfig) {;
500
+
501
+ const rowID = this.getOption("templateMapping.row-key");
502
+
503
+ if (!this[gridElementSymbol]) {
504
+ throw new Error("no grid element is defined");
505
+ }
506
+
507
+ let template;
508
+ getSlottedElements.call(this).forEach((e) => {
509
+ if (e instanceof HTMLTemplateElement && e.id === rowID) {
510
+ template = e;
511
+ }
512
+ });
513
+
514
+ if (!template) {
515
+ throw new Error("no template is defined");
516
+ }
517
+
518
+ const rowCount = template.content.children.length;
519
+
520
+ const headers = [];
521
+
522
+ for (let i = 0; i < rowCount; i++) {
523
+ let hClass = "";
524
+ const row = template.content.children[i];
525
+
526
+ let mode = "";
527
+ if (row.hasAttribute(ATTRIBUTE_DATATABLE_MODE)) {
528
+ mode = row.getAttribute(ATTRIBUTE_DATATABLE_MODE);
529
+ }
530
+
531
+ let grid = row.getAttribute(ATTRIBUTE_DATATABLE_GRID_TEMPLATE);
532
+ if (!grid || grid === "" || grid === "auto") {
533
+ grid = "minmax(0, 1fr)";
534
+ }
535
+
536
+ let label = "";
537
+ let labelKey = "";
538
+
539
+ if (row.hasAttribute(ATTRIBUTE_DATATABLE_HEAD)) {
540
+ label = row.getAttribute(ATTRIBUTE_DATATABLE_HEAD);
541
+ labelKey = label;
542
+
543
+ try {
544
+ if (label.startsWith("i18n:")) {
545
+ label = label.substring(5, label.length);
546
+ label = getDocumentTranslations().getText(label, label);
547
+ }
548
+ } catch (e) {
549
+ label = "i18n error " + label;
550
+ }
551
+ }
552
+
553
+ if (!label) {
554
+ label = i + 1 + "";
555
+ mode = ATTRIBUTE_DATATABLE_MODE_FIXED;
556
+ labelKey = label;
557
+ }
558
+
559
+ if (isObject(hostConfig) && hostConfig.hasOwnProperty(label)) {
560
+ if (hostConfig[label] === false) {
561
+ mode = ATTRIBUTE_DATATABLE_MODE_HIDDEN;
562
+ } else {
563
+ mode = ATTRIBUTE_DATATABLE_MODE_VISIBLE;
564
+ }
565
+ }
566
+
567
+ let align = "";
568
+ if (row.hasAttribute(ATTRIBUTE_DATATABLE_ALIGN)) {
569
+ align = row.getAttribute(ATTRIBUTE_DATATABLE_ALIGN);
570
+ }
571
+
572
+ switch (align) {
573
+ case "center":
574
+ hClass = "flex-center";
575
+ break;
576
+ case "end":
577
+ hClass = "flex-end";
578
+ break;
579
+ case "start":
580
+ hClass = "flex-start";
581
+ break;
582
+ default:
583
+ hClass = "flex-start";
584
+ }
585
+
586
+ let field = "";
587
+ if (row.hasAttribute(ATTRIBUTE_DATATABLE_SORTABLE)) {
588
+ field = row.getAttribute(ATTRIBUTE_DATATABLE_SORTABLE);
589
+ }
590
+
591
+ if (mode === ATTRIBUTE_DATATABLE_MODE_HIDDEN) {
592
+ hClass += " hidden";
593
+ }
594
+
595
+ const header = new Header();
596
+ header.setInternals({
597
+ field: field,
598
+ label: label,
599
+ classes: hClass,
600
+ index: i,
601
+ mode: mode,
602
+ grid: grid,
603
+ labelKey: labelKey,
604
+ });
605
+
606
+ headers.push(header);
607
+ }
608
+
609
+ const statement = createOrderStatement(headers);
610
+ setDataSource.call(
611
+ this,
612
+ { orderBy: statement },
613
+ this.getOption("features.autoInit"),
614
+ );
615
+ this.setOption("headers", headers);
616
+ }
617
+
618
+ /**
619
+ * @private
620
+ */
621
+ function updateGrid() {;
622
+
623
+ if (!this[gridElementSymbol]) {
624
+ throw new Error("no grid element is defined");
625
+ }
626
+
627
+ let gridTemplateColumns = "";
628
+
629
+ const headers = this.getOption("headers");
630
+
631
+ let styles = "";
632
+
633
+ for (let i = 0; i < headers.length; i++) {
634
+ const header = headers[i];
635
+
636
+ if (header.mode === ATTRIBUTE_DATATABLE_MODE_HIDDEN) {
637
+ styles += `[data-monster-role=datatable]>[data-monster-head="${header.labelKey}"] { display: none; }\n`;
638
+ styles += `[data-monster-role=datatable-headers]>[data-monster-index="${header.index}"] { display: none; }\n`;
639
+ } else {
640
+ gridTemplateColumns += `${header.grid} `;
641
+ }
642
+ }
643
+
644
+ const sheet = new CSSStyleSheet();
645
+ if (styles !== "") sheet.replaceSync(styles);
646
+ this.shadowRoot.adoptedStyleSheets = [...DataTable.getCSSStyleSheet(), sheet];
647
+
648
+ const bodyWidth = getDocument().body.getBoundingClientRect().width;
649
+
650
+ const breakpoint = this.getOption("responsive.breakpoint");
651
+
652
+ if (bodyWidth > breakpoint) {
653
+ this[
654
+ gridElementSymbol
655
+ ].style.gridTemplateColumns = `${gridTemplateColumns}`;
656
+ this[
657
+ gridHeadersElementSymbol
658
+ ].style.gridTemplateColumns = `${gridTemplateColumns}`;
659
+ } else {
660
+ this[gridElementSymbol].style.gridTemplateColumns = "auto";
661
+ this[gridHeadersElementSymbol].style.gridTemplateColumns = "auto";
662
+ }
663
+ }
664
+
665
+ /**
666
+ * @private
667
+ * @param {Monster.Components.Datatable.Header[]} headers
668
+ * @param {bool} doFetch
669
+ */
670
+ function setDataSource({ orderBy }, doFetch) {;
671
+ const datasource = this[datasourceLinkedElementSymbol];
672
+
673
+ if (!datasource) {
674
+ return;
675
+ }
676
+
677
+ if (isFunction(datasource?.setParameters)) {
678
+ datasource.setParameters({ orderBy });
679
+ }
680
+
681
+ if (doFetch !== false && isFunction(datasource?.fetch)) {
682
+ datasource.fetch();
683
+ }
684
+ }
685
+
686
+ /**
687
+ * @private
688
+ * @return {Monster.Components.Datatable.Form}
689
+ */
690
+ function initControlReferences() {;
691
+
692
+ if (!this.shadowRoot) {
693
+ throw new Error("no shadow-root is defined");
694
+ }
695
+
696
+ this[gridElementSymbol] = this.shadowRoot.querySelector(
697
+ "[data-monster-role=datatable]",
698
+ );
699
+ this[gridHeadersElementSymbol] = this.shadowRoot.querySelector(
700
+ "[data-monster-role=datatable-headers]",
701
+ );
702
+ this[columnBarElementSymbol] =
703
+ this.shadowRoot.querySelector("monster-column-bar");
704
+
705
+ return this;
706
+ }
707
+
708
+ /**
709
+ * @private
710
+ * @return {object}
711
+ * @throws {TypeError} incorrect arguments passed for the datasource
712
+ * @throws {Error} the datasource could not be initialized
713
+ */
714
+ function initOptionsFromArguments() {;
715
+
716
+ const options = {};
717
+ const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR);
718
+
719
+ if (selector) {
720
+ options.datasource = { selector: selector };
721
+ }
722
+
723
+ const breakpoint = this.getAttribute(ATTRIBUTE_DATATABLE_RESPONSIVE_BREAKPOINT);
724
+ if (breakpoint) {
725
+ options.responsive = {};
726
+ options.responsive.breakpoint = parseInt(breakpoint);
727
+ }
728
+
729
+ return options;
730
+ }
731
+
732
+ /**
733
+ * @private
734
+ * @return {string}
735
+ */
736
+ function getEmptyTemplate() {
737
+ return `<monster-state data-monster-role="empty-without-action">
738
+ <div part="visual">
739
+ <svg width="4rem" height="4rem" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
740
+ <path d="m21.5 22h-19c-1.378 0-2.5-1.121-2.5-2.5v-7c0-.07.015-.141.044-.205l3.969-8.82c.404-.896 1.299-1.475 2.28-1.475h11.414c.981 0 1.876.579 2.28 1.475l3.969 8.82c.029.064.044.135.044.205v7c0 1.379-1.122 2.5-2.5 2.5zm-20.5-9.393v6.893c0 .827.673 1.5 1.5 1.5h19c.827 0 1.5-.673 1.5-1.5v-6.893l-3.925-8.723c-.242-.536-.779-.884-1.368-.884h-11.414c-.589 0-1.126.348-1.368.885z"/>
741
+ <path d="m16.807 17h-9.614c-.622 0-1.186-.391-1.404-.973l-1.014-2.703c-.072-.194-.26-.324-.468-.324h-3.557c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h3.557c.622 0 1.186.391 1.405.973l1.013 2.703c.073.194.261.324.468.324h9.613c.208 0 .396-.13.468-.324l1.013-2.703c.22-.582.784-.973 1.406-.973h3.807c.276 0 .5.224.5.5s-.224.5-.5.5h-3.807c-.208 0-.396.13-.468.324l-1.013 2.703c-.219.582-.784.973-1.405.973z"/>
742
+ </svg>
743
+ </div>
744
+ <div part="content" monster-replace="path:labels.theListContainsNoEntries">
745
+ The list contains no entries.
746
+ </div>
747
+ </monster-state>`;
748
+ }
749
+
750
+ /**
751
+ * @private
752
+ * @return {string}
753
+ */
754
+ function getTemplate() {
755
+ // language=HTML
756
+ return `
757
+ <div data-monster-role="control" part="control">
758
+ <template id="headers-row">
759
+ <div data-monster-attributes="class path:headers-row.classname,
760
+ data-monster-index path:headers-row.index"
761
+ data-monster-replace="path:headers-row.html"></div>
762
+ </template>
763
+ <slot></slot>
764
+ <div class="table-container" part="table-container">
765
+ <div class="filter">
766
+ <slot name="filter"></slot>
767
+ </div>
768
+ <div class="bar">
769
+ <monster-column-bar
770
+ data-monster-attributes="class path:features.settings | ?::hidden"></monster-column-bar>
771
+ <slot name="bar"></slot>
772
+
773
+ </div>
774
+ <div data-monster-role="datatable-headers" data-monster-insert="headers-row path:headers"></div>
775
+ <div data-monster-replace="path:templates.emptyState"
776
+ data-monster-attributes="class path:data | has-entries | ?:hidden:empty-state-container"></div>
777
+ <div data-monster-role="datatable" data-monster-insert="\${row-key} path:data">
778
+ </div>
779
+ </div>
780
+ <div data-monster-role="footer" data-monster-select-this="true"
781
+ data-monster-attributes="class path:data | has-entries | ?::hidden">
782
+ <slot name="footer" data-monster-attributes="class path:features.footer | ?::hidden"></slot>
783
+ </div>
784
+
785
+ </div>
786
+ `;
787
+ }
788
+
789
+ registerCustomElement(DataTable);