sprintify-ui 0.10.65 → 0.10.67

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 (416) hide show
  1. package/README.md +266 -266
  2. package/dist/{BaseCkeditor-D6D4FPEb.js → BaseCkeditor-B4PbYw6a.js} +2 -2
  3. package/dist/sprintify-ui.es.js +4435 -4557
  4. package/dist/style.css +3 -3
  5. package/dist/tailwindcss/button.js +260 -260
  6. package/dist/tailwindcss/index.js +21 -21
  7. package/dist/tailwindcss/input.js +22 -22
  8. package/dist/tailwindcss/overlay.js +12 -12
  9. package/dist/tailwindcss/table.js +91 -91
  10. package/dist/tailwindcss/theme.js +52 -52
  11. package/dist/types/components/BaseActionButtons.vue.d.ts +1 -1
  12. package/dist/types/components/BaseActionItem.vue.d.ts +7 -10
  13. package/dist/types/components/BaseAddressForm.vue.d.ts +1 -1
  14. package/dist/types/components/BaseAlert.vue.d.ts +24 -11
  15. package/dist/types/components/BaseApp.vue.d.ts +14 -12
  16. package/dist/types/components/BaseAssign.vue.d.ts +1 -1
  17. package/dist/types/components/BaseAutocomplete.vue.d.ts +665 -455
  18. package/dist/types/components/BaseAutocompleteDrawer.vue.d.ts +119 -24
  19. package/dist/types/components/BaseAutocompleteFetch.vue.d.ts +1033 -412
  20. package/dist/types/components/BaseAvatarGroup.vue.d.ts +1 -1
  21. package/dist/types/components/BaseBadge.vue.d.ts +23 -11
  22. package/dist/types/components/BaseBelongsTo.vue.d.ts +998 -411
  23. package/dist/types/components/BaseBelongsToFetch.vue.d.ts +754 -371
  24. package/dist/types/components/BaseBoolean.vue.d.ts +1 -1
  25. package/dist/types/components/BaseBreadcrumbs.vue.d.ts +1 -1
  26. package/dist/types/components/BaseButton.vue.d.ts +78 -16
  27. package/dist/types/components/BaseButtonGroup.vue.d.ts +166 -15
  28. package/dist/types/components/BaseCard.vue.d.ts +26 -12
  29. package/dist/types/components/BaseCardRow.vue.d.ts +20 -11
  30. package/dist/types/components/BaseCharacterCounter.vue.d.ts +1 -1
  31. package/dist/types/components/BaseClipboard.vue.d.ts +45 -13
  32. package/dist/types/components/BaseCollapse.vue.d.ts +41 -20
  33. package/dist/types/components/BaseContainer.vue.d.ts +16 -11
  34. package/dist/types/components/BaseCounter.vue.d.ts +1 -1
  35. package/dist/types/components/BaseCropper.vue.d.ts +55 -30
  36. package/dist/types/components/BaseDataIterator.vue.d.ts +43 -42
  37. package/dist/types/components/BaseDataIteratorSectionBox.vue.d.ts +15 -12
  38. package/dist/types/components/BaseDataIteratorSectionColumns.vue.d.ts +1 -1
  39. package/dist/types/components/BaseDataIteratorSectionModal.vue.d.ts +19 -10
  40. package/dist/types/components/BaseDataTable.vue.d.ts +2090 -738
  41. package/dist/types/components/BaseDataTableTemplate.vue.d.ts +576 -100
  42. package/dist/types/components/BaseDatePicker.vue.d.ts +1 -1
  43. package/dist/types/components/BaseDateSelect.vue.d.ts +1 -1
  44. package/dist/types/components/BaseDescriptionList.vue.d.ts +12 -12
  45. package/dist/types/components/BaseDescriptionListItem.vue.d.ts +16 -15
  46. package/dist/types/components/BaseDialog.vue.d.ts +114 -413
  47. package/dist/types/components/BaseDisplayRelativeTime.vue.d.ts +55 -13
  48. package/dist/types/components/BaseDraggable.vue.d.ts +25 -16
  49. package/dist/types/components/BaseDropdown.vue.d.ts +155 -17
  50. package/dist/types/components/BaseDropdownAutocomplete.vue.d.ts +131 -16
  51. package/dist/types/components/BaseField.vue.d.ts +103 -12
  52. package/dist/types/components/BaseFieldI18n.vue.d.ts +1 -1
  53. package/dist/types/components/BaseFilePicker.vue.d.ts +35 -16
  54. package/dist/types/components/BaseFilePickerCrop.vue.d.ts +87 -42
  55. package/dist/types/components/BaseFileUploader.vue.d.ts +195 -29
  56. package/dist/types/components/BaseForm.vue.d.ts +161 -20
  57. package/dist/types/components/BaseGantt.vue.d.ts +1130 -409
  58. package/dist/types/components/BaseHasMany.vue.d.ts +590 -347
  59. package/dist/types/components/BaseHasManyFetch.vue.d.ts +602 -251
  60. package/dist/types/components/BaseHeader.vue.d.ts +1 -1
  61. package/dist/types/components/BaseIconPicker.vue.d.ts +1 -1
  62. package/dist/types/components/BaseInputError.vue.d.ts +23 -11
  63. package/dist/types/components/BaseJsonReaderItem.vue.d.ts +1 -1
  64. package/dist/types/components/BaseLayoutNotificationItemContent.vue.d.ts +1 -1
  65. package/dist/types/components/BaseLayoutSidebar.vue.d.ts +124 -16
  66. package/dist/types/components/BaseLayoutSidebarConfigurable.vue.d.ts +115 -13
  67. package/dist/types/components/BaseLayoutStacked.vue.d.ts +69 -22
  68. package/dist/types/components/BaseLayoutStackedConfigurable.vue.d.ts +120 -10
  69. package/dist/types/components/BaseLazy.vue.d.ts +20 -15
  70. package/dist/types/components/BaseMediaGallery.vue.d.ts +1 -1
  71. package/dist/types/components/BaseMediaGalleryItem.vue.d.ts +1 -1
  72. package/dist/types/components/BaseMediaItem.vue.d.ts +1 -1
  73. package/dist/types/components/BaseMediaLibrary.vue.d.ts +234 -34
  74. package/dist/types/components/BaseMediaListItem.vue.d.ts +1 -1
  75. package/dist/types/components/BaseMediaPicturesItem.vue.d.ts +1 -1
  76. package/dist/types/components/BaseMenu.vue.d.ts +233 -30
  77. package/dist/types/components/BaseMenuItem.vue.d.ts +1 -1
  78. package/dist/types/components/BaseModalCenter.vue.d.ts +88 -12
  79. package/dist/types/components/BaseModalSide.vue.d.ts +85 -12
  80. package/dist/types/components/BaseNavbar.vue.d.ts +88 -22
  81. package/dist/types/components/BaseNavbarItem.vue.d.ts +1 -1
  82. package/dist/types/components/BaseNavbarItemContent.vue.d.ts +1 -1
  83. package/dist/types/components/BaseNavbarSideItem.vue.d.ts +1 -1
  84. package/dist/types/components/BaseNavbarSideItemContent.vue.d.ts +1 -1
  85. package/dist/types/components/BasePagination.vue.d.ts +1 -1
  86. package/dist/types/components/BaseRadioGroup.vue.d.ts +113 -13
  87. package/dist/types/components/BaseReadMore.vue.d.ts +31 -12
  88. package/dist/types/components/BaseRichText.vue.d.ts +1 -1
  89. package/dist/types/components/BaseSelect.vue.d.ts +149 -12
  90. package/dist/types/components/BaseShortcut.vue.d.ts +1 -1
  91. package/dist/types/components/BaseSideNavigation.vue.d.ts +11 -12
  92. package/dist/types/components/BaseSideNavigationItem.vue.d.ts +22 -13
  93. package/dist/types/components/BaseSkeleton.vue.d.ts +3 -3
  94. package/dist/types/components/BaseStepper.vue.d.ts +1 -1
  95. package/dist/types/components/BaseSwitch.vue.d.ts +122 -13
  96. package/dist/types/components/BaseSystemAlert.vue.d.ts +58 -11
  97. package/dist/types/components/BaseTabItem.vue.d.ts +35 -18
  98. package/dist/types/components/BaseTable.vue.d.ts +29 -14
  99. package/dist/types/components/BaseTableBody.vue.d.ts +9 -12
  100. package/dist/types/components/BaseTableCell.vue.d.ts +40 -15
  101. package/dist/types/components/BaseTableColumn.vue.d.ts +3 -3
  102. package/dist/types/components/BaseTableHead.vue.d.ts +14 -12
  103. package/dist/types/components/BaseTableHeader.vue.d.ts +46 -17
  104. package/dist/types/components/BaseTableRow.vue.d.ts +40 -13
  105. package/dist/types/components/BaseTabs.vue.d.ts +21 -15
  106. package/dist/types/components/BaseTagAutocomplete.vue.d.ts +602 -203
  107. package/dist/types/components/BaseTagAutocompleteFetch.vue.d.ts +807 -348
  108. package/dist/types/components/BaseTextareaAutoresize.vue.d.ts +1 -1
  109. package/dist/types/components/BaseTimeline.vue.d.ts +1 -1
  110. package/dist/types/components/BaseTimelineItem.vue.d.ts +1 -1
  111. package/dist/types/components/BaseToast.vue.d.ts +1 -1
  112. package/dist/types/components/BaseTooltip.vue.d.ts +41 -15
  113. package/dist/types/components/BaseUniqueCode.vue.d.ts +1 -1
  114. package/dist/types/stories/PageInputSizes.vue.d.ts +1 -1
  115. package/dist/types/stories/PageShow.vue.d.ts +1 -1
  116. package/dist/types/svg/BaseEmptyState.vue.d.ts +1 -1
  117. package/dist/types/svg/BaseSpinnerSmall.vue.d.ts +1 -1
  118. package/package.json +135 -135
  119. package/src/assets/base-cropper.css +61 -61
  120. package/src/assets/base-date-picker.css +4 -4
  121. package/src/assets/base-rich-text.css +270 -270
  122. package/src/assets/base-spinner.css +18 -18
  123. package/src/assets/base-tabs.css +4 -4
  124. package/src/assets/base-time-picker.css +9 -9
  125. package/src/assets/flatpickr.css +247 -247
  126. package/src/assets/form.css +6 -6
  127. package/src/assets/google-pac.css +25 -25
  128. package/src/assets/main.css +56 -56
  129. package/src/assets/tailwind.css +2 -2
  130. package/src/changelog.mdx +6 -6
  131. package/src/components/BaseActionButtons.vue +76 -76
  132. package/src/components/BaseActionItem.vue +80 -80
  133. package/src/components/BaseActionItemButton.vue +75 -75
  134. package/src/components/BaseAddressForm.stories.js +114 -114
  135. package/src/components/BaseAddressForm.vue +382 -382
  136. package/src/components/BaseAlert.stories.js +75 -75
  137. package/src/components/BaseAlert.vue +101 -101
  138. package/src/components/BaseApp.vue +16 -16
  139. package/src/components/BaseAppDialogs.vue +126 -126
  140. package/src/components/BaseAppSnackbars.vue +40 -40
  141. package/src/components/BaseAssign.mdx +98 -98
  142. package/src/components/BaseAssign.stories.js +78 -78
  143. package/src/components/BaseAssign.vue +366 -366
  144. package/src/components/BaseAutocomplete.stories.js +243 -243
  145. package/src/components/BaseAutocomplete.vue +603 -603
  146. package/src/components/BaseAutocompleteDrawer.vue +386 -386
  147. package/src/components/BaseAutocompleteFetch.stories.js +224 -224
  148. package/src/components/BaseAutocompleteFetch.vue +314 -314
  149. package/src/components/BaseAvatar.stories.js +39 -39
  150. package/src/components/BaseAvatar.vue +164 -164
  151. package/src/components/BaseAvatarGroup.stories.js +71 -71
  152. package/src/components/BaseAvatarGroup.vue +148 -148
  153. package/src/components/BaseBadge.stories.js +132 -130
  154. package/src/components/BaseBadge.vue +118 -97
  155. package/src/components/BaseBelongsTo.stories.js +220 -220
  156. package/src/components/BaseBelongsTo.vue +164 -164
  157. package/src/components/BaseBelongsToFetch.stories.js +223 -223
  158. package/src/components/BaseBelongsToFetch.vue +213 -213
  159. package/src/components/BaseBoolean.stories.js +35 -35
  160. package/src/components/BaseBoolean.vue +26 -26
  161. package/src/components/BaseBreadcrumbs.stories.js +50 -50
  162. package/src/components/BaseBreadcrumbs.vue +109 -109
  163. package/src/components/BaseButton.stories.js +126 -126
  164. package/src/components/BaseButton.vue +279 -279
  165. package/src/components/BaseButtonGroup.stories.js +114 -114
  166. package/src/components/BaseButtonGroup.vue +193 -193
  167. package/src/components/BaseCard.stories.js +63 -63
  168. package/src/components/BaseCard.vue +49 -49
  169. package/src/components/BaseCardRow.vue +53 -53
  170. package/src/components/BaseCharacterCounter.stories.js +30 -30
  171. package/src/components/BaseCharacterCounter.vue +64 -64
  172. package/src/components/BaseCkeditor.vue +154 -154
  173. package/src/components/BaseClipboard.stories.js +55 -55
  174. package/src/components/BaseClipboard.vue +105 -105
  175. package/src/components/BaseCollapse.stories.js +168 -168
  176. package/src/components/BaseCollapse.vue +98 -98
  177. package/src/components/BaseColor.stories.js +66 -66
  178. package/src/components/BaseColor.vue +155 -155
  179. package/src/components/BaseContainer.stories.js +34 -34
  180. package/src/components/BaseContainer.vue +64 -64
  181. package/src/components/BaseCounter.stories.js +47 -47
  182. package/src/components/BaseCounter.vue +83 -83
  183. package/src/components/BaseCropper.stories.js +113 -113
  184. package/src/components/BaseCropper.vue +390 -390
  185. package/src/components/BaseCropperModal.stories.js +54 -54
  186. package/src/components/BaseCropperModal.vue +143 -143
  187. package/src/components/BaseDataIterator.stories.js +292 -292
  188. package/src/components/BaseDataIterator.vue +986 -986
  189. package/src/components/BaseDataIteratorSectionBox.vue +36 -36
  190. package/src/components/BaseDataIteratorSectionButton.vue +42 -42
  191. package/src/components/BaseDataIteratorSectionColumns.vue +150 -150
  192. package/src/components/BaseDataIteratorSectionModal.vue +41 -41
  193. package/src/components/BaseDataTable.stories.js +393 -393
  194. package/src/components/BaseDataTable.vue +966 -966
  195. package/src/components/BaseDataTableRowAction.vue +70 -70
  196. package/src/components/BaseDataTableTemplate.vue +831 -838
  197. package/src/components/BaseDatePicker.stories.js +166 -166
  198. package/src/components/BaseDatePicker.vue +372 -372
  199. package/src/components/BaseDateSelect.stories.js +68 -68
  200. package/src/components/BaseDateSelect.vue +222 -222
  201. package/src/components/BaseDescriptionList.stories.js +35 -35
  202. package/src/components/BaseDescriptionList.vue +13 -13
  203. package/src/components/BaseDescriptionListItem.vue +47 -47
  204. package/src/components/BaseDialog.stories.js +95 -95
  205. package/src/components/BaseDialog.vue +221 -221
  206. package/src/components/BaseDisplayRelativeTime.stories.js +47 -47
  207. package/src/components/BaseDisplayRelativeTime.vue +126 -126
  208. package/src/components/BaseDraggable.stories.js +34 -34
  209. package/src/components/BaseDraggable.vue +111 -111
  210. package/src/components/BaseDropdown.stories.js +164 -164
  211. package/src/components/BaseDropdown.vue +74 -74
  212. package/src/components/BaseDropdownAutocomplete.stories.js +208 -208
  213. package/src/components/BaseDropdownAutocomplete.vue +203 -203
  214. package/src/components/BaseField.vue +151 -151
  215. package/src/components/BaseFieldI18n.stories.js +37 -37
  216. package/src/components/BaseFieldI18n.vue +170 -170
  217. package/src/components/BaseFilePicker.stories.js +84 -84
  218. package/src/components/BaseFilePicker.vue +163 -163
  219. package/src/components/BaseFilePickerCrop.stories.js +135 -135
  220. package/src/components/BaseFilePickerCrop.vue +130 -130
  221. package/src/components/BaseFileUploader.stories.js +101 -101
  222. package/src/components/BaseFileUploader.vue +185 -185
  223. package/src/components/BaseForm.mdx +87 -87
  224. package/src/components/BaseForm.stories.js +133 -133
  225. package/src/components/BaseForm.vue +372 -372
  226. package/src/components/BaseGantt.stories.js +145 -145
  227. package/src/components/BaseGantt.vue +384 -384
  228. package/src/components/BaseHasMany.stories.js +211 -211
  229. package/src/components/BaseHasMany.vue +135 -135
  230. package/src/components/BaseHasManyFetch.stories.js +278 -278
  231. package/src/components/BaseHasManyFetch.vue +222 -222
  232. package/src/components/BaseHeader.stories.js +137 -137
  233. package/src/components/BaseHeader.vue +141 -141
  234. package/src/components/BaseIconPicker.stories.js +22 -22
  235. package/src/components/BaseIconPicker.vue +225 -225
  236. package/src/components/BaseInput.stories.js +202 -202
  237. package/src/components/BaseInput.vue +402 -402
  238. package/src/components/BaseInputError.vue +39 -39
  239. package/src/components/BaseInputLabel.stories.js +36 -36
  240. package/src/components/BaseInputLabel.vue +83 -83
  241. package/src/components/BaseInputPercent.stories.js +66 -66
  242. package/src/components/BaseInputPercent.vue +139 -139
  243. package/src/components/BaseJsonReader.stories.js +120 -120
  244. package/src/components/BaseJsonReader.vue +51 -51
  245. package/src/components/BaseJsonReaderItem.vue +119 -119
  246. package/src/components/BaseLayoutNotificationDropdown.vue +153 -153
  247. package/src/components/BaseLayoutNotificationItem.vue +53 -53
  248. package/src/components/BaseLayoutNotificationItemContent.vue +41 -41
  249. package/src/components/BaseLayoutSidebar.vue +300 -300
  250. package/src/components/BaseLayoutSidebarConfigurable.stories.js +217 -217
  251. package/src/components/BaseLayoutSidebarConfigurable.vue +202 -202
  252. package/src/components/BaseLayoutStacked.vue +78 -78
  253. package/src/components/BaseLayoutStackedConfigurable.stories.js +181 -181
  254. package/src/components/BaseLayoutStackedConfigurable.vue +196 -196
  255. package/src/components/BaseLazy.stories.js +59 -59
  256. package/src/components/BaseLazy.vue +80 -80
  257. package/src/components/BaseLoadingCover.stories.js +55 -55
  258. package/src/components/BaseLoadingCover.vue +101 -101
  259. package/src/components/BaseMediaGallery.vue +96 -96
  260. package/src/components/BaseMediaGalleryItem.vue +101 -101
  261. package/src/components/BaseMediaItem.stories.js +41 -41
  262. package/src/components/BaseMediaItem.vue +80 -80
  263. package/src/components/BaseMediaLibrary.stories.js +267 -267
  264. package/src/components/BaseMediaLibrary.vue +357 -357
  265. package/src/components/BaseMediaList.vue +67 -67
  266. package/src/components/BaseMediaListItem.vue +213 -213
  267. package/src/components/BaseMediaPictures.vue +64 -64
  268. package/src/components/BaseMediaPicturesItem.vue +100 -100
  269. package/src/components/BaseMediaPreview.stories.js +72 -72
  270. package/src/components/BaseMediaPreview.vue +106 -106
  271. package/src/components/BaseMenu.stories.js +134 -134
  272. package/src/components/BaseMenu.vue +187 -187
  273. package/src/components/BaseMenuItem.vue +177 -177
  274. package/src/components/BaseModalCenter.stories.js +68 -68
  275. package/src/components/BaseModalCenter.vue +128 -128
  276. package/src/components/BaseModalSide.stories.js +61 -61
  277. package/src/components/BaseModalSide.vue +130 -130
  278. package/src/components/BaseNavbar.stories.js +152 -152
  279. package/src/components/BaseNavbar.vue +191 -191
  280. package/src/components/BaseNavbarItem.vue +108 -108
  281. package/src/components/BaseNavbarItemContent.vue +124 -124
  282. package/src/components/BaseNavbarSideItem.vue +187 -187
  283. package/src/components/BaseNavbarSideItemContent.vue +126 -126
  284. package/src/components/BasePagination.stories.js +35 -35
  285. package/src/components/BasePagination.vue +266 -266
  286. package/src/components/BasePanel.stories.js +56 -56
  287. package/src/components/BasePanel.vue +42 -42
  288. package/src/components/BasePassword.stories.js +80 -80
  289. package/src/components/BasePassword.vue +87 -87
  290. package/src/components/BaseProgressCircle.stories.js +27 -27
  291. package/src/components/BaseProgressCircle.vue +80 -80
  292. package/src/components/BaseRadioGroup.stories.js +87 -87
  293. package/src/components/BaseRadioGroup.vue +124 -124
  294. package/src/components/BaseReadMore.stories.js +30 -30
  295. package/src/components/BaseReadMore.vue +73 -73
  296. package/src/components/BaseRichText.stories.js +90 -90
  297. package/src/components/BaseRichText.vue +87 -87
  298. package/src/components/BaseScrollColumn.vue +128 -128
  299. package/src/components/BaseSelect.stories.js +151 -151
  300. package/src/components/BaseSelect.vue +241 -241
  301. package/src/components/BaseShortcut.stories.js +100 -100
  302. package/src/components/BaseShortcut.vue +114 -114
  303. package/src/components/BaseSideNavigation.stories.js +85 -85
  304. package/src/components/BaseSideNavigation.vue +32 -32
  305. package/src/components/BaseSideNavigationItem.vue +99 -99
  306. package/src/components/BaseSkeleton.stories.js +36 -36
  307. package/src/components/BaseSkeleton.vue +40 -40
  308. package/src/components/BaseStatistic.stories.js +51 -51
  309. package/src/components/BaseStatistic.vue +98 -98
  310. package/src/components/BaseStepper.stories.js +94 -94
  311. package/src/components/BaseStepper.vue +72 -72
  312. package/src/components/BaseStepperItem.stories.js +65 -65
  313. package/src/components/BaseStepperItem.vue +149 -149
  314. package/src/components/BaseSwitch.stories.js +133 -133
  315. package/src/components/BaseSwitch.vue +228 -226
  316. package/src/components/BaseSystemAlert.stories.js +63 -63
  317. package/src/components/BaseSystemAlert.vue +89 -89
  318. package/src/components/BaseTabItem.vue +192 -192
  319. package/src/components/BaseTable.stories.js +214 -214
  320. package/src/components/BaseTable.vue +111 -111
  321. package/src/components/BaseTableBody.vue +14 -14
  322. package/src/components/BaseTableCell.vue +204 -204
  323. package/src/components/BaseTableColumn.vue +140 -140
  324. package/src/components/BaseTableHead.vue +38 -38
  325. package/src/components/BaseTableHeader.vue +139 -139
  326. package/src/components/BaseTableRow.vue +197 -197
  327. package/src/components/BaseTabs.stories.js +165 -165
  328. package/src/components/BaseTabs.vue +203 -203
  329. package/src/components/BaseTagAutocomplete.stories.js +271 -271
  330. package/src/components/BaseTagAutocomplete.vue +565 -565
  331. package/src/components/BaseTagAutocompleteFetch.stories.js +211 -211
  332. package/src/components/BaseTagAutocompleteFetch.vue +237 -237
  333. package/src/components/BaseTextarea.stories.js +81 -81
  334. package/src/components/BaseTextarea.vue +138 -138
  335. package/src/components/BaseTextareaAutoresize.stories.js +125 -125
  336. package/src/components/BaseTextareaAutoresize.vue +187 -187
  337. package/src/components/BaseTimePicker.stories.js +68 -68
  338. package/src/components/BaseTimePicker.vue +379 -379
  339. package/src/components/BaseTimeline.stories.js +55 -55
  340. package/src/components/BaseTimeline.vue +38 -38
  341. package/src/components/BaseTimelineItem.stories.js +77 -77
  342. package/src/components/BaseTimelineItem.vue +90 -90
  343. package/src/components/BaseToast.stories.js +50 -50
  344. package/src/components/BaseToast.vue +43 -43
  345. package/src/components/BaseTooltip.stories.js +65 -65
  346. package/src/components/BaseTooltip.vue +93 -93
  347. package/src/components/BaseUniqueCode.stories.js +36 -36
  348. package/src/components/BaseUniqueCode.vue +183 -183
  349. package/src/components/SlotComponent.ts +37 -37
  350. package/src/components/index.ts +222 -222
  351. package/src/composables/breakpoints.ts +94 -94
  352. package/src/composables/clickOutside.ts +80 -80
  353. package/src/composables/field.ts +156 -156
  354. package/src/composables/hasOptions.ts +86 -86
  355. package/src/composables/inputSize.ts +35 -35
  356. package/src/composables/isLastColumn.ts +30 -30
  357. package/src/composables/mediaQuery.ts +42 -42
  358. package/src/composables/modal.ts +73 -73
  359. package/src/composables/paginatedData.ts +76 -76
  360. package/src/composables/tooltip.ts +84 -84
  361. package/src/constants/MyConstants.ts +1 -1
  362. package/src/constants/index.ts +5 -5
  363. package/src/env.d.ts +15 -15
  364. package/src/i18n/index.ts +60 -60
  365. package/src/index.ts +138 -138
  366. package/src/lang/en.json +101 -101
  367. package/src/lang/fr.json +101 -101
  368. package/src/services/gantt/format.ts +133 -133
  369. package/src/services/gantt/timescale.ts +250 -250
  370. package/src/services/gantt/types.ts +81 -81
  371. package/src/services/table/classes.ts +37 -37
  372. package/src/services/table/customKeyActions.ts +2 -2
  373. package/src/services/table/types.ts +27 -27
  374. package/src/stores/dialogs.ts +48 -48
  375. package/src/stores/i18n.ts +14 -14
  376. package/src/stores/snackbars.ts +47 -47
  377. package/src/stores/systemAlerts.ts +32 -32
  378. package/src/stories/InputSizes.stories.js +21 -21
  379. package/src/stories/List.stories.js +136 -136
  380. package/src/stories/PageInputSizes.vue +228 -228
  381. package/src/stories/PageShow.vue +423 -423
  382. package/src/stories/Show.stories.js +21 -21
  383. package/src/svg/BaseEmptyState.vue +38 -38
  384. package/src/svg/BaseSpinnerLarge.vue +40 -40
  385. package/src/svg/BaseSpinnerSmall.vue +13 -13
  386. package/src/types/Color.ts +9 -9
  387. package/src/types/Country.ts +4 -4
  388. package/src/types/ImagePickerResult.ts +5 -5
  389. package/src/types/Media.ts +10 -10
  390. package/src/types/Notification.ts +11 -11
  391. package/src/types/Region.ts +5 -5
  392. package/src/types/Status.ts +5 -5
  393. package/src/types/StepperItem.ts +8 -8
  394. package/src/types/ToolbarOption.ts +1 -1
  395. package/src/types/UploadedFile.ts +11 -11
  396. package/src/types/User.ts +7 -7
  397. package/src/types/index.ts +302 -302
  398. package/src/utils/blob.ts +30 -30
  399. package/src/utils/colors.ts +239 -239
  400. package/src/utils/cropper/avatar.ts +33 -33
  401. package/src/utils/cropper/cover.ts +41 -41
  402. package/src/utils/cropper/presetInterface.ts +16 -16
  403. package/src/utils/cropper/presets.ts +7 -7
  404. package/src/utils/deepIncludes.ts +76 -76
  405. package/src/utils/fileSizeFormat.ts +15 -15
  406. package/src/utils/fileValidations.ts +26 -26
  407. package/src/utils/getApiData.ts +11 -11
  408. package/src/utils/index.ts +18 -18
  409. package/src/utils/resizeImageFromURI.ts +118 -118
  410. package/src/utils/scrollPreventer.ts +11 -11
  411. package/src/utils/sizeBehaviors.ts +3 -3
  412. package/src/utils/sizes.ts +38 -38
  413. package/src/utils/slots.ts +12 -12
  414. package/src/utils/storage.ts +36 -36
  415. package/src/utils/toHumanList.ts +20 -20
  416. package/src/utils/uuid.ts +7 -7
@@ -1,838 +1,831 @@
1
- <template>
2
- <div
3
- class="relative w-full overflow-hidden"
4
- :style="{
5
- minHeight: maxHeight ? maxHeight + 'px' : '200px',
6
- }"
7
- >
8
- <div
9
- ref="slot"
10
- style="display: none"
11
- >
12
- <slot />
13
- </div>
14
-
15
- <BaseTable
16
- ref="baseTableRef"
17
- class="min-w-full"
18
- :size="size"
19
- :fixed-header="(maxHeight && maxHeight > 0) == true"
20
- :fixed-column="true"
21
- :max-height="maxHeight"
22
- :loading="loading"
23
- :virtual-scrolling="virtualScrolling"
24
- >
25
- <BaseTableHead v-if="newColumns.length">
26
- <BaseTableRow>
27
- <BaseTableHeader
28
- v-for="(column, index) in visibleColumnsInternal"
29
- :key="column.newKey + ':' + index + 'header'"
30
- :style="column.style"
31
- :tooltip="column.tooltip"
32
- class="bg-slate-50"
33
- >
34
- <div class="flex gap-4">
35
- <template v-if="index == 0">
36
- <div
37
- v-if="showDetailRowIcon"
38
- class="flex h-5 w-5 shrink-0 grow-0"
39
- />
40
-
41
- <div
42
- v-if="checkable"
43
- class="flex items-center cursor-pointer"
44
- @click="checkAll"
45
- >
46
- <input
47
- type="checkbox"
48
- autocomplete="off"
49
- :checked="isAllChecked"
50
- :disabled="isAllUncheckable"
51
- :class="checkboxStyle"
52
- >
53
- </div>
54
- </template>
55
-
56
- <button
57
- type="button"
58
- class="flex gap-2 w-full items-start bg-transparent text-left text-sm font-medium leading-tight text-slate-900"
59
- :class="[
60
- column.sortable ? 'cursor-pointer' : '',
61
- column.align == 'right' ? 'justify-start flex-row-reverse text-right' : ''
62
- ]"
63
- @click="sort(column, undefined, $event as any)"
64
- >
65
- <div
66
- class="whitespace-nowrap text-slate-600"
67
- :class="{
68
- 'text-[12px]': size == 'sm',
69
- 'text-xs': size == 'md',
70
- }"
71
- v-html="column.label"
72
- />
73
- <!-- h-4 is used to make sure the tooltip icon is always smaller than label and avoid alignment issues when icon is not present -->
74
- <div
75
- v-if="column.sortable"
76
- class="h-4 relative top-0.5"
77
- :class="[
78
- currentSortColumn === column
79
- ? ''
80
- : 'opacity-0 duration-200 group-hover:opacity-100',
81
- ]"
82
- >
83
- <svg
84
- width="11"
85
- height="11"
86
- viewBox="0 0 11 11"
87
- fill="none"
88
- class="block"
89
- xmlns="http://www.w3.org/2000/svg"
90
- >
91
- <path
92
- :opacity="!isAsc ? '0.5' : '1'"
93
- d="M4.88471 0.366233C5.00079 0.250125 5.1386 0.158021 5.29028 0.0951819C5.44196 0.0323429 5.60453 0 5.76871 0C5.93289 0 6.09546 0.0323429 6.24714 0.0951819C6.39882 0.158021 6.53663 0.250125 6.65271 0.366233L9.29871 3.01323C9.43119 3.15541 9.50331 3.34345 9.49988 3.53776C9.49646 3.73206 9.41774 3.91744 9.28033 4.05485C9.14292 4.19227 8.95753 4.27098 8.76323 4.27441C8.56893 4.27784 8.38088 4.20571 8.23871 4.07323L5.76871 1.60323L3.29871 4.07323C3.23005 4.14692 3.14725 4.20602 3.05525 4.24701C2.96325 4.28801 2.86393 4.31005 2.76323 4.31182C2.66253 4.3136 2.5625 4.29508 2.46911 4.25736C2.37572 4.21963 2.29089 4.16349 2.21967 4.09227C2.14845 4.02105 2.09231 3.93622 2.05459 3.84283C2.01686 3.74944 1.99834 3.64941 2.00012 3.54871C2.00189 3.44801 2.02394 3.34869 2.06493 3.25669C2.10592 3.1647 2.16502 3.08189 2.23871 3.01323L4.88471 0.366233Z"
94
- fill="black"
95
- ></path>
96
- <path
97
- :opacity="isAsc ? '0.5' : '1'"
98
-
99
- d="M4.84729 10.6083C4.96337 10.7244 5.10118 10.8165 5.25286 10.8793C5.40454 10.9422 5.56711 10.9745 5.73129 10.9745C5.89547 10.9745 6.05804 10.9422 6.20972 10.8793C6.3614 10.8165 6.49921 10.7244 6.61529 10.6083L9.26129 7.96129C9.39377 7.81912 9.4659 7.63107 9.46247 7.43677C9.45904 7.24247 9.38033 7.05708 9.24291 6.91967C9.1055 6.78226 8.92011 6.70354 8.72581 6.70012C8.53151 6.69669 8.34347 6.76881 8.20129 6.90129L5.73129 9.37129L3.26129 6.90129C3.11912 6.76881 2.93107 6.69669 2.73677 6.70012C2.54247 6.70354 2.35708 6.78226 2.21967 6.91967C2.08226 7.05708 2.00355 7.24247 2.00012 7.43677C1.99669 7.63107 2.06881 7.81912 2.20129 7.96129L4.84729 10.6083Z"
100
- fill="black"
101
- ></path>
102
- </svg>
103
- </div>
104
- </button>
105
- </div>
106
- </BaseTableHeader>
107
- </BaseTableRow>
108
- </BaseTableHead>
109
-
110
- <BaseTableBody
111
- class="bg-white"
112
- >
113
- <template
114
- v-for="(row, index) in data"
115
- :key="getRowKey(row)"
116
- >
117
- <BaseTableRow
118
- :to="rowTo ? rowTo(row) : undefined"
119
- :selected="rowSelected ? rowSelected(row) : false"
120
- v-bind="rowBindings(row, index)"
121
- >
122
- <BaseTableCell
123
- v-for="(column, columnIndex) in visibleColumnsInternal"
124
- :key="column.newKey + index + ':' + columnIndex"
125
- :class="[column.class, column.numeric ? 'tabular-nums' : '']"
126
- :align="column.align"
127
- :style="column.style"
128
- :to="column.to ? column.to(row) : undefined"
129
- :href="column.href ? column.href(row) : undefined"
130
- :target="column.target"
131
- :ignore-row-interactions="column.ignoreRowInteractions"
132
- :on-click="onCellClick(row, index, column, columnIndex)"
133
- >
134
- <div :class="[columnIndex == 0 ? 'flex items-center gap-4' : '']">
135
- <template v-if="columnIndex == 0">
136
- <button
137
- v-if="showDetailRowIcon"
138
- type="button"
139
- class="relative z-[1] || flex h-5 w-5 shrink-0 grow-0 appearance-none items-center justify-center rounded-full border border-slate-300 bg-white text-slate-400 shadow duration-100 hover:text-slate-600 hover:shadow-md"
140
- @click.stop="toggleDetails(row)"
141
- >
142
- <BaseIcon
143
- v-if="hasDetailedVisible(row)"
144
- icon="mdi:chevron-down"
145
- class="h-5 w-5 duration-300"
146
- :class="{
147
- 'rotate-180': isVisibleDetailRow(row)
148
- }"
149
- />
150
- </button>
151
-
152
- <div
153
- v-if="checkable"
154
- class="relative z-[1] || flex items-center group cursor-pointer bg-white"
155
- @click.stop="checkRow(row, index, $event as MouseEvent)"
156
- >
157
- <input
158
- type="checkbox"
159
- autocomplete="off"
160
- :disabled="!isRowCheckable(row)"
161
- :checked="isRowChecked(row)"
162
- :class="checkboxStyle"
163
- >
164
- </div>
165
- </template>
166
-
167
- <SlotComponent
168
- :component="column"
169
- scoped
170
- name="default"
171
- tag="div"
172
- class="text-sm grow"
173
- :data-label="column.label"
174
- :props="{ row, column, index, columnIndex, toggleDetails }"
175
- />
176
- </div>
177
- </BaseTableCell>
178
- </BaseTableRow>
179
-
180
- <BaseTableRow
181
- v-if="isActiveDetailRow(row)"
182
- :key="getRowKey(row) + 'detail'"
183
- >
184
- <BaseTableCell
185
- :colspan="columnCount"
186
- >
187
- <slot
188
- name="detail"
189
- :row="row"
190
- :index="index"
191
- />
192
- </BaseTableCell>
193
- </BaseTableRow>
194
- </template>
195
-
196
- <BaseTableRow v-if="data.length == 0">
197
- <BaseTableCell :colspan="columnCount">
198
- <slot name="empty" />
199
- </BaseTableCell>
200
- </BaseTableRow>
201
- </BaseTableBody>
202
- </BaseTable>
203
- </div>
204
- </template>
205
-
206
- <script lang="ts" setup>
207
- import { PropType, ref } from 'vue';
208
- import { BaseTableColumnData, CollectionItem, Row } from '@/types';
209
- import SlotComponent from './SlotComponent';
210
- import { isArray } from 'lodash';
211
- import { Size } from '@/utils/sizes';
212
- import objectHash from 'object-hash';
213
- import BaseTable from './BaseTable.vue';
214
- import BaseTableHead from './BaseTableHead.vue';
215
- import BaseTableHeader from './BaseTableHeader.vue';
216
- import BaseTableBody from './BaseTableBody.vue';
217
- import BaseTableRow from './BaseTableRow.vue';
218
- import BaseTableCell from './BaseTableCell.vue';
219
- import { RouteLocationRaw } from 'vue-router';
220
- import { customKeyActions } from '@/services/table/customKeyActions';
221
-
222
- const checkboxStyle =
223
- 'disabled:bg-slate-100 group-hover:shadow-md disabled:border-slate-300 disabled:cursor-not-allowed duration-300 cursor-pointer focus:ring-blue-300 border border-slate-300 shadow h-[18px] w-[18px] rounded';
224
-
225
- defineOptions({
226
- name: 'BaseDataTableTemplate',
227
- inheritAttrs: false,
228
- });
229
-
230
- provide('table', getCurrentInstance());
231
-
232
- const props = defineProps({
233
- /** Table data */
234
- data: {
235
- type: Array as PropType<Row[]>,
236
- default: () => [],
237
- },
238
- /** Loading state */
239
- loading: {
240
- default: false,
241
- type: Boolean,
242
- },
243
- visibleColumns: {
244
- default: undefined,
245
- type: Array as PropType<string[]>,
246
- },
247
- columnOrder: {
248
- default: undefined,
249
- type: Array as PropType<string[]>,
250
- },
251
- /** Allow row details */
252
- detailed: {
253
- default: false,
254
- type: Boolean,
255
- },
256
- /** Rows can be checked (multiple) */
257
- checkable: {
258
- default: false,
259
- type: Boolean,
260
- },
261
- /** Custom method to verify if a row is checkable, works when is checkable */
262
- isRowCheckable: {
263
- type: Function,
264
- default: () => true,
265
- },
266
- /** Set which rows are checked, use v-model:checkedRows to make it two-way binding */
267
- checkedRows: {
268
- default: () => [],
269
- type: Array as PropType<Row[]>,
270
- },
271
- /** Sets the default sort column field */
272
- sortField: {
273
- type: String,
274
- default: '',
275
- },
276
- /**
277
- * Sets the default sort column direction
278
- * @values asc, desc
279
- */
280
- sortDirection: {
281
- type: String,
282
- default: 'asc',
283
- },
284
- /** Controls the visibility of the trigger that toggles the detailed rows. */
285
- hasDetailedVisible: {
286
- type: Function,
287
- default: () => true,
288
- },
289
- /* Max height (in px) */
290
- maxHeight: {
291
- default: undefined,
292
- type: Number,
293
- },
294
- size: {
295
- type: String as PropType<Size>,
296
- default: 'md',
297
- },
298
- rowTo: {
299
- default: undefined,
300
- type: Function as PropType<((row: CollectionItem) => RouteLocationRaw) | undefined>,
301
- },
302
- rowHref: {
303
- default: undefined,
304
- type: Function as PropType<((row: CollectionItem) => string) | undefined>,
305
- },
306
- onRowClick: {
307
- default: undefined,
308
- type: Function as PropType<((row: CollectionItem, index: number, event: MouseEvent) => void) | undefined>,
309
- },
310
- rowKey: {
311
- default: undefined,
312
- type: Function as PropType<((row: CollectionItem) => string | number) | undefined>,
313
- },
314
- rowSelected: {
315
- default: undefined,
316
- type: Function as PropType<((row: CollectionItem) => boolean) | undefined>,
317
- },
318
- virtualScrolling: {
319
- default: false,
320
- type: Boolean,
321
- },
322
- });
323
-
324
- const emit = defineEmits([
325
- 'check',
326
- 'check-all',
327
- 'update:checkedRows',
328
- 'details-open',
329
- 'details-close',
330
- 'update:openedDetailed',
331
- 'sort',
332
- 'cell-click',
333
- 'row-click',
334
- ]);
335
-
336
- const visibleDetailRows = ref<string[]>([]);
337
- // eslint-disable-next-line vue/no-setup-props-destructure
338
- const newCheckedRows = ref<Row[]>([...props.checkedRows]);
339
- const lastCheckedRowIndex = ref<number | null>(null);
340
- const currentSortColumn = ref<BaseTableColumnData | null>(null);
341
- const isAsc = ref(true);
342
- const defaultSlots = ref<BaseTableColumnData[]>([]);
343
-
344
- const slot = ref<HTMLElement | null>(null);
345
-
346
- const newColumns = computed(() => {
347
- const cols = defaultSlots.value;
348
-
349
- if (props.columnOrder && props.columnOrder.length) {
350
-
351
- const colOrder = props.columnOrder;
352
-
353
- return cols
354
- .sort((a, b) => {
355
-
356
- // Always put actions column at the end
357
-
358
- if (a.newKey === customKeyActions) {
359
- return 1;
360
- }
361
-
362
- if (b.newKey === customKeyActions) {
363
- return -1;
364
- }
365
-
366
- // If not found, put it at the end
367
-
368
- const existsA = colOrder.includes(a.newKey);
369
- const existsB = colOrder.includes(b.newKey);
370
-
371
- if (!existsA && !existsB) {
372
- return 0;
373
- }
374
-
375
- if (!existsA) {
376
- return 1;
377
- }
378
-
379
- if (!existsB) {
380
- return -1;
381
- }
382
-
383
- // Sort based on the order
384
-
385
- return colOrder.indexOf(a.newKey) - colOrder.indexOf(b.newKey);
386
- });
387
- }
388
-
389
- return cols;
390
- });
391
-
392
-
393
- const visibleColumnsInternal = computed(() => {
394
-
395
- if (!newColumns.value) {
396
- return [];
397
- }
398
-
399
- return newColumns.value
400
- .filter((column: BaseTableColumnData) => {
401
- if (column.toggle === false) {
402
- return true;
403
- }
404
-
405
- if (!isArray(props.visibleColumns)) {
406
- return true;
407
- }
408
-
409
- if (props.visibleColumns.includes(column.newKey)) {
410
- return true;
411
- }
412
-
413
- return false;
414
- });
415
- });
416
-
417
- /**
418
- * Return total column count based if it's checkable or expanded
419
- */
420
- const columnCount = computed(() => {
421
- let count = visibleColumnsInternal.value.length;
422
- count += props.checkable ? 1 : 0;
423
- count += props.detailed ? 1 : 0;
424
-
425
- return count;
426
- });
427
-
428
- /**
429
- * Return if detailed row tabled
430
- * will be with chevron column & icon or not
431
- */
432
- const showDetailRowIcon = computed(() => {
433
- return props.detailed;
434
- });
435
-
436
- /**
437
- * When checkedRows prop change, update internal value without
438
- * mutating original data.
439
- */
440
- watch(
441
- () => props.checkedRows,
442
- (rows) => {
443
- newCheckedRows.value = [...rows];
444
- },
445
- { deep: true }
446
- );
447
-
448
- watch(
449
- () => props.sortField,
450
- () => {
451
- updateSortState();
452
- }
453
- );
454
-
455
- watch(
456
- () => props.sortDirection,
457
- () => {
458
- updateSortState();
459
- }
460
- );
461
-
462
- onMounted(() => {
463
- nextTick(() => {
464
- updateSortState();
465
- });
466
- });
467
-
468
- /**
469
- * Sort the column.
470
- * Toggle current direction on column if it's sortable
471
- * and not just updating the prop.
472
- */
473
- function sort(column: BaseTableColumnData, updatingData = false, event = null) {
474
- if (!column || !column.sortable) {
475
- return;
476
- }
477
-
478
- if (!updatingData) {
479
- isAsc.value =
480
- column === currentSortColumn.value
481
- ? !isAsc.value
482
- : props.sortDirection.toLowerCase() !== 'desc';
483
- }
484
-
485
- /**
486
- * @property {string} field column field
487
- * @property {boolean} direction 'asc' or 'desc'
488
- * @property {Event} event native event
489
- */
490
- emit('sort', column.field, isAsc.value ? 'asc' : 'desc', event);
491
-
492
- currentSortColumn.value = column;
493
- }
494
-
495
- /**
496
- * Check if the row is checked (is added to the array).
497
- */
498
- function isRowChecked(row: Row): boolean {
499
- const found = newCheckedRows.value.find((r) => {
500
- const key1 = getRowKey(r);
501
- const key2 = getRowKey(row);
502
- return key1 == key2
503
- });
504
-
505
- return found !== undefined;
506
- }
507
-
508
- /**
509
- * Check if all rows in the page are checkable.
510
- */
511
- const isAllUncheckable = computed(() => {
512
- const validData = props.data.filter((row) => props.isRowCheckable(row));
513
- return validData.length === 0;
514
- });
515
-
516
- /**
517
- * Check if all rows in the page are checked.
518
- */
519
- const isAllChecked = computed(() => {
520
- const validData = props.data.filter((row) => {
521
- return props.isRowCheckable(row);
522
- });
523
-
524
- if (validData.length === 0) {
525
- return false;
526
- }
527
-
528
- const missingChecked = validData.some((currentRow) => {
529
- return !isRowChecked(currentRow);
530
- });
531
-
532
- return !missingChecked;
533
- });
534
-
535
- function getCheckedRowIndex(row: Row) {
536
- const foundIndex = newCheckedRows.value.findIndex((r) => {
537
- const key1 = getRowKey(r);
538
- const key2 = getRowKey(row);
539
- return key1 == key2
540
- });
541
-
542
- return foundIndex;
543
- }
544
-
545
- /**
546
- * Remove a checked row from the array.
547
- */
548
- function removeCheckedRow(row: Row) {
549
- const index = getCheckedRowIndex(row);
550
- if (index >= 0) {
551
- newCheckedRows.value.splice(index, 1);
552
- }
553
- }
554
-
555
- /**
556
- * Header checkbox click listener.
557
- * Add or remove all rows in current page.
558
- */
559
- function checkAll() {
560
- if (isAllChecked.value) {
561
- newCheckedRows.value = [];
562
- } else {
563
- props.data.forEach((currentRow) => {
564
- if (props.isRowCheckable(currentRow) && !isRowChecked(currentRow)) {
565
- newCheckedRows.value.push(currentRow);
566
- }
567
- });
568
- }
569
-
570
- sendCheckUpdate();
571
- }
572
-
573
- /**
574
- * Remove all rows in current page.
575
- */
576
- function uncheckAll() {
577
- newCheckedRows.value = [];
578
-
579
- sendCheckUpdate();
580
- }
581
-
582
- function sendCheckUpdate() {
583
- emit('check', newCheckedRows.value);
584
- emit('check-all', newCheckedRows.value);
585
- emit('update:checkedRows', newCheckedRows.value);
586
- }
587
-
588
- /**
589
- * Row checkbox click listener.
590
- */
591
- function checkRow(row: Row, index: number, event: MouseEvent) {
592
- if (!props.isRowCheckable(row)) {
593
- return;
594
- }
595
-
596
- const lastIndex = lastCheckedRowIndex.value;
597
- lastCheckedRowIndex.value = index;
598
-
599
- if (event.shiftKey && lastIndex !== null && index !== lastIndex) {
600
- shiftCheckRow(row, index, lastIndex);
601
- } else if (!isRowChecked(row)) {
602
- newCheckedRows.value.push(row);
603
- } else {
604
- removeCheckedRow(row);
605
- }
606
-
607
- emit('check', newCheckedRows.value, row);
608
-
609
- // Emit checked rows to update user variable
610
- emit('update:checkedRows', newCheckedRows.value);
611
- }
612
-
613
- /**
614
- * Check row when shift is pressed.
615
- */
616
- function shiftCheckRow(row: Row, index: number, lastCheckedRowIndex: number) {
617
- // Get the subset of the list between the two indices
618
- const subset = props.data.slice(
619
- Math.min(index, lastCheckedRowIndex),
620
- Math.max(index, lastCheckedRowIndex) + 1
621
- );
622
-
623
- // Determine the operation based on the state of the clicked checkbox
624
- const shouldCheck = !isRowChecked(row);
625
-
626
- subset.forEach((item) => {
627
- removeCheckedRow(item);
628
- if (shouldCheck && props.isRowCheckable(item)) {
629
- newCheckedRows.value.push(item);
630
- }
631
- });
632
- }
633
-
634
- /**
635
- * Toggle to show/hide details slot
636
- */
637
- function toggleDetails(row: Row) {
638
- const found = isVisibleDetailRow(row);
639
-
640
- if (found) {
641
- closeDetailRow(row);
642
- emit('details-close', row);
643
- } else {
644
- openDetailRow(row);
645
- emit('details-open', row);
646
- }
647
-
648
- // Syncs the detailed rows with the parent component
649
- emit('update:openedDetailed', visibleDetailRows.value);
650
- }
651
-
652
- function openDetailRow(row: Row) {
653
- const key = getRowKey(row);
654
- visibleDetailRows.value.push(key);
655
- }
656
-
657
- function closeDetailRow(row: Row) {
658
- const key = getRowKey(row);
659
- const i = visibleDetailRows.value.indexOf(key);
660
- if (i >= 0) {
661
- visibleDetailRows.value.splice(i, 1);
662
- }
663
- }
664
-
665
- function isVisibleDetailRow(row: Row) {
666
- const key = getRowKey(row);
667
- return visibleDetailRows.value.indexOf(key) >= 0;
668
- }
669
-
670
- function isActiveDetailRow(row: Row) {
671
- return props.detailed && isVisibleDetailRow(row);
672
- }
673
-
674
- /**
675
- * Update sort state
676
- */
677
- function updateSortState() {
678
- const sortField = props.sortField;
679
-
680
- const sortDirection = props.sortDirection;
681
-
682
- const sortColumn = newColumns.value.filter(
683
- (column) => column.field === sortField
684
- )[0];
685
-
686
- // Set sort state
687
-
688
- if (sortColumn) {
689
- currentSortColumn.value = sortColumn;
690
- isAsc.value = sortDirection.toLowerCase() !== 'desc';
691
- } else {
692
- currentSortColumn.value = null;
693
- return;
694
- }
695
- }
696
-
697
- /*
698
- |--------------------------------------------------------------------------
699
- | BaseTableColumns functions
700
- |--------------------------------------------------------------------------
701
- */
702
-
703
- function addColumn(column: BaseTableColumnData) {
704
- defaultSlots.value.push(column);
705
-
706
- const slotHTMLElement = slot.value as HTMLElement;
707
-
708
- if (slotHTMLElement && slotHTMLElement.children) {
709
- nextTick(() => {
710
- const ids = defaultSlots.value
711
- .map((it) => `[data-id="${it.newKey}"]`)
712
- .join(',');
713
-
714
- const sortedIds = Array.from(slotHTMLElement.querySelectorAll(ids)).map(
715
- (el: Element) => el.getAttribute('data-id')
716
- );
717
-
718
- defaultSlots.value = defaultSlots.value.sort((a, b) => {
719
- return (
720
- sortedIds.indexOf(`${a.newKey}`) - sortedIds.indexOf(`${b.newKey}`)
721
- );
722
- });
723
- });
724
- }
725
- }
726
-
727
- function removeColumn(column: BaseTableColumnData) {
728
- defaultSlots.value = defaultSlots.value.filter(
729
- (d) => d.newKey !== column.newKey
730
- );
731
- }
732
-
733
- function rowBindings(row: CollectionItem, index: number) {
734
- return {
735
- onClick: props.onRowClick ? (event: MouseEvent) => props.onRowClick && props.onRowClick(row, index, event) : undefined,
736
- }
737
- }
738
-
739
- function onCellClick(row: CollectionItem, index: number, column: BaseTableColumnData, columnIndex: number) {
740
- if (!column.onClick) {
741
- return undefined;
742
- }
743
-
744
- return (event: MouseEvent) => {
745
- if (!column.onClick) {
746
- return;
747
- }
748
-
749
- column.onClick(row, index, column, columnIndex, event);
750
- };
751
- }
752
-
753
- let warningNoRowKeyFoundShown = false;
754
-
755
- function getRowKey(row: Row): string {
756
-
757
- if (props.rowKey) {
758
- return props.rowKey(row) + '';
759
- }
760
-
761
- if (row.id) {
762
- return row.id;
763
- }
764
-
765
- if (row.key) {
766
- return row.key;
767
- }
768
-
769
- if (row.uuid) {
770
- return row.uuid;
771
- }
772
-
773
- if (!warningNoRowKeyFoundShown) {
774
- console.warn('%cNo unique key found for items provided to BaseDataTable.%cPlease provide a unique key for each row (id, key or uuid) or use the row-key props to specify a unique key.', 'font-weight: bold', 'font-weight: normal');
775
- warningNoRowKeyFoundShown = true;
776
- }
777
-
778
- // if no key is found, hash a simplified version of the row object
779
- // We use a simplified version to avoid hashing functions, objects, etc. for performance reasons
780
-
781
- const simpleRow = {} as Record<string, string | number | boolean>;
782
-
783
- for (const key in row) {
784
- const value = row[key];
785
- if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
786
- simpleRow[key] = value;
787
- }
788
- }
789
-
790
- return objectHash(simpleRow);
791
- }
792
-
793
- provide('addColumn', addColumn);
794
- provide('removeColumn', removeColumn);
795
-
796
- const baseTableRef = ref<InstanceType<typeof BaseTable> | null>(null);
797
-
798
-
799
- /*
800
- |--------------------------------------------------------------------------
801
- | Checks
802
- |--------------------------------------------------------------------------
803
- */
804
-
805
- watch(
806
- () => newColumns.value.map((item) => item.newKey),
807
- (keys: string[]) => {
808
-
809
- // check duplicates
810
-
811
- const duplicates = keys.reduce((acc, key, index) => {
812
- if (keys.indexOf(key) !== index && !acc.includes(key)) {
813
- acc.push(key);
814
- }
815
-
816
- return acc;
817
- }, [] as string[]);
818
-
819
- if (duplicates.length) {
820
- throw new Error(`Duplicate BaseTableColumn keys found: ${duplicates.join(', ')}`);
821
- }
822
- }
823
- )
824
-
825
- /*
826
- |--------------------------------------------------------------------------
827
- | Expose
828
- |--------------------------------------------------------------------------
829
- */
830
-
831
- defineExpose({
832
- newColumns,
833
- uncheckAll,
834
- scrollTop: () => {
835
- baseTableRef.value?.scrollTop();
836
- },
837
- });
838
- </script>
1
+ <template>
2
+ <div
3
+ class="relative w-full overflow-hidden"
4
+ :style="{
5
+ minHeight: maxHeight ? maxHeight + 'px' : '200px',
6
+ }"
7
+ >
8
+ <div
9
+ ref="slot"
10
+ style="display: none"
11
+ >
12
+ <slot />
13
+ </div>
14
+
15
+ <BaseTable
16
+ ref="baseTableRef"
17
+ class="min-w-full"
18
+ :size="size"
19
+ :fixed-header="(maxHeight && maxHeight > 0) == true"
20
+ :fixed-column="true"
21
+ :max-height="maxHeight"
22
+ :loading="loading"
23
+ :virtual-scrolling="virtualScrolling"
24
+ >
25
+ <BaseTableHead v-if="newColumns.length">
26
+ <BaseTableRow>
27
+ <BaseTableHeader
28
+ v-for="(column, index) in visibleColumnsInternal"
29
+ :key="column.newKey + ':' + index + 'header'"
30
+ :style="column.style"
31
+ :tooltip="column.tooltip"
32
+ class="bg-slate-50"
33
+ >
34
+ <div class="flex gap-4">
35
+ <template v-if="index == 0">
36
+ <div
37
+ v-if="checkable"
38
+ class="flex items-center cursor-pointer"
39
+ @click="checkAll"
40
+ >
41
+ <input
42
+ type="checkbox"
43
+ autocomplete="off"
44
+ :checked="isAllChecked"
45
+ :disabled="isAllUncheckable"
46
+ :class="checkboxStyle"
47
+ >
48
+ </div>
49
+ </template>
50
+
51
+ <button
52
+ type="button"
53
+ class="flex gap-2 w-full items-start bg-transparent text-left text-sm font-medium leading-tight text-slate-900"
54
+ :class="[
55
+ column.sortable ? 'cursor-pointer' : '',
56
+ column.align == 'right' ? 'justify-start flex-row-reverse text-right' : ''
57
+ ]"
58
+ @click="sort(column, undefined, $event as any)"
59
+ >
60
+ <div
61
+ class="whitespace-nowrap text-slate-600"
62
+ :class="{
63
+ 'text-[12px]': size == 'sm',
64
+ 'text-xs': size == 'md',
65
+ }"
66
+ v-html="column.label"
67
+ />
68
+ <!-- h-4 is used to make sure the tooltip icon is always smaller than label and avoid alignment issues when icon is not present -->
69
+ <div
70
+ v-if="column.sortable"
71
+ class="h-4 relative top-0.5"
72
+ :class="[
73
+ currentSortColumn === column
74
+ ? ''
75
+ : 'opacity-0 duration-200 group-hover:opacity-100',
76
+ ]"
77
+ >
78
+ <svg
79
+ width="11"
80
+ height="11"
81
+ viewBox="0 0 11 11"
82
+ fill="none"
83
+ class="block"
84
+ xmlns="http://www.w3.org/2000/svg"
85
+ >
86
+ <path
87
+ :opacity="!isAsc ? '0.5' : '1'"
88
+ d="M4.88471 0.366233C5.00079 0.250125 5.1386 0.158021 5.29028 0.0951819C5.44196 0.0323429 5.60453 0 5.76871 0C5.93289 0 6.09546 0.0323429 6.24714 0.0951819C6.39882 0.158021 6.53663 0.250125 6.65271 0.366233L9.29871 3.01323C9.43119 3.15541 9.50331 3.34345 9.49988 3.53776C9.49646 3.73206 9.41774 3.91744 9.28033 4.05485C9.14292 4.19227 8.95753 4.27098 8.76323 4.27441C8.56893 4.27784 8.38088 4.20571 8.23871 4.07323L5.76871 1.60323L3.29871 4.07323C3.23005 4.14692 3.14725 4.20602 3.05525 4.24701C2.96325 4.28801 2.86393 4.31005 2.76323 4.31182C2.66253 4.3136 2.5625 4.29508 2.46911 4.25736C2.37572 4.21963 2.29089 4.16349 2.21967 4.09227C2.14845 4.02105 2.09231 3.93622 2.05459 3.84283C2.01686 3.74944 1.99834 3.64941 2.00012 3.54871C2.00189 3.44801 2.02394 3.34869 2.06493 3.25669C2.10592 3.1647 2.16502 3.08189 2.23871 3.01323L4.88471 0.366233Z"
89
+ fill="black"
90
+ ></path>
91
+ <path
92
+ :opacity="isAsc ? '0.5' : '1'"
93
+
94
+ d="M4.84729 10.6083C4.96337 10.7244 5.10118 10.8165 5.25286 10.8793C5.40454 10.9422 5.56711 10.9745 5.73129 10.9745C5.89547 10.9745 6.05804 10.9422 6.20972 10.8793C6.3614 10.8165 6.49921 10.7244 6.61529 10.6083L9.26129 7.96129C9.39377 7.81912 9.4659 7.63107 9.46247 7.43677C9.45904 7.24247 9.38033 7.05708 9.24291 6.91967C9.1055 6.78226 8.92011 6.70354 8.72581 6.70012C8.53151 6.69669 8.34347 6.76881 8.20129 6.90129L5.73129 9.37129L3.26129 6.90129C3.11912 6.76881 2.93107 6.69669 2.73677 6.70012C2.54247 6.70354 2.35708 6.78226 2.21967 6.91967C2.08226 7.05708 2.00355 7.24247 2.00012 7.43677C1.99669 7.63107 2.06881 7.81912 2.20129 7.96129L4.84729 10.6083Z"
95
+ fill="black"
96
+ ></path>
97
+ </svg>
98
+ </div>
99
+ </button>
100
+ </div>
101
+ </BaseTableHeader>
102
+ </BaseTableRow>
103
+ </BaseTableHead>
104
+
105
+ <BaseTableBody
106
+ class="bg-white"
107
+ >
108
+ <template
109
+ v-for="(row, index) in data"
110
+ :key="getRowKey(row)"
111
+ >
112
+ <BaseTableRow
113
+ :to="rowTo ? rowTo(row) : undefined"
114
+ :selected="rowSelected ? rowSelected(row) : false"
115
+ v-bind="rowBindings(row, index)"
116
+ >
117
+ <BaseTableCell
118
+ v-for="(column, columnIndex) in visibleColumnsInternal"
119
+ :key="column.newKey + index + ':' + columnIndex"
120
+ :class="[column.class, column.numeric ? 'tabular-nums' : '']"
121
+ :align="column.align"
122
+ :style="column.style"
123
+ :to="column.to ? column.to(row) : undefined"
124
+ :href="column.href ? column.href(row) : undefined"
125
+ :target="column.target"
126
+ :ignore-row-interactions="column.ignoreRowInteractions"
127
+ :on-click="onCellClick(row, index, column, columnIndex)"
128
+ >
129
+ <div :class="[columnIndex == 0 ? 'flex items-center gap-4' : '']">
130
+ <template v-if="columnIndex == 0">
131
+ <div
132
+ v-if="checkable"
133
+ class="relative z-[1] || flex items-center group cursor-pointer bg-white"
134
+ @click.stop="checkRow(row, index, $event as MouseEvent)"
135
+ >
136
+ <input
137
+ type="checkbox"
138
+ autocomplete="off"
139
+ :disabled="!isRowCheckable(row)"
140
+ :checked="isRowChecked(row)"
141
+ :class="checkboxStyle"
142
+ >
143
+ </div>
144
+ <button
145
+ v-if="showDetailRowIcon && hasDetailedVisible(row)"
146
+ type="button"
147
+ class="relative z-[1] || flex h-5 w-5 shrink-0 grow-0 appearance-none items-center justify-center rounded-full border border-slate-300 bg-white text-slate-400 shadow duration-100 hover:text-slate-600 hover:shadow-md"
148
+ @click.stop="toggleDetails(row)"
149
+ >
150
+ <BaseIcon
151
+ icon="mdi:chevron-down"
152
+ class="h-5 w-5 duration-300"
153
+ :class="{
154
+ 'rotate-180': isVisibleDetailRow(row)
155
+ }"
156
+ />
157
+ </button>
158
+ </template>
159
+
160
+ <SlotComponent
161
+ :component="column"
162
+ scoped
163
+ name="default"
164
+ tag="div"
165
+ class="text-sm grow"
166
+ :data-label="column.label"
167
+ :props="{ row, column, index, columnIndex, toggleDetails }"
168
+ />
169
+ </div>
170
+ </BaseTableCell>
171
+ </BaseTableRow>
172
+
173
+ <BaseTableRow
174
+ v-if="isActiveDetailRow(row)"
175
+ :key="getRowKey(row) + 'detail'"
176
+ >
177
+ <BaseTableCell
178
+ :colspan="columnCount"
179
+ >
180
+ <slot
181
+ name="detail"
182
+ :row="row"
183
+ :index="index"
184
+ />
185
+ </BaseTableCell>
186
+ </BaseTableRow>
187
+ </template>
188
+
189
+ <BaseTableRow v-if="data.length == 0">
190
+ <BaseTableCell :colspan="columnCount">
191
+ <slot name="empty" />
192
+ </BaseTableCell>
193
+ </BaseTableRow>
194
+ </BaseTableBody>
195
+ </BaseTable>
196
+ </div>
197
+ </template>
198
+
199
+ <script lang="ts" setup>
200
+ import { PropType, ref } from 'vue';
201
+ import { BaseTableColumnData, CollectionItem, Row } from '@/types';
202
+ import SlotComponent from './SlotComponent';
203
+ import { isArray } from 'lodash';
204
+ import { Size } from '@/utils/sizes';
205
+ import objectHash from 'object-hash';
206
+ import BaseTable from './BaseTable.vue';
207
+ import BaseTableHead from './BaseTableHead.vue';
208
+ import BaseTableHeader from './BaseTableHeader.vue';
209
+ import BaseTableBody from './BaseTableBody.vue';
210
+ import BaseTableRow from './BaseTableRow.vue';
211
+ import BaseTableCell from './BaseTableCell.vue';
212
+ import { RouteLocationRaw } from 'vue-router';
213
+ import { customKeyActions } from '@/services/table/customKeyActions';
214
+
215
+ const checkboxStyle =
216
+ 'disabled:bg-slate-100 group-hover:shadow-md disabled:border-slate-300 disabled:cursor-not-allowed duration-300 cursor-pointer focus:ring-blue-300 border border-slate-300 shadow h-[18px] w-[18px] rounded';
217
+
218
+ defineOptions({
219
+ name: 'BaseDataTableTemplate',
220
+ inheritAttrs: false,
221
+ });
222
+
223
+ provide('table', getCurrentInstance());
224
+
225
+ const props = defineProps({
226
+ /** Table data */
227
+ data: {
228
+ type: Array as PropType<Row[]>,
229
+ default: () => [],
230
+ },
231
+ /** Loading state */
232
+ loading: {
233
+ default: false,
234
+ type: Boolean,
235
+ },
236
+ visibleColumns: {
237
+ default: undefined,
238
+ type: Array as PropType<string[]>,
239
+ },
240
+ columnOrder: {
241
+ default: undefined,
242
+ type: Array as PropType<string[]>,
243
+ },
244
+ /** Allow row details */
245
+ detailed: {
246
+ default: false,
247
+ type: Boolean,
248
+ },
249
+ /** Rows can be checked (multiple) */
250
+ checkable: {
251
+ default: false,
252
+ type: Boolean,
253
+ },
254
+ /** Custom method to verify if a row is checkable, works when is checkable */
255
+ isRowCheckable: {
256
+ type: Function,
257
+ default: () => true,
258
+ },
259
+ /** Set which rows are checked, use v-model:checkedRows to make it two-way binding */
260
+ checkedRows: {
261
+ default: () => [],
262
+ type: Array as PropType<Row[]>,
263
+ },
264
+ /** Sets the default sort column field */
265
+ sortField: {
266
+ type: String,
267
+ default: '',
268
+ },
269
+ /**
270
+ * Sets the default sort column direction
271
+ * @values asc, desc
272
+ */
273
+ sortDirection: {
274
+ type: String,
275
+ default: 'asc',
276
+ },
277
+ /** Controls the visibility of the trigger that toggles the detailed rows. */
278
+ hasDetailedVisible: {
279
+ type: Function,
280
+ default: () => true,
281
+ },
282
+ /* Max height (in px) */
283
+ maxHeight: {
284
+ default: undefined,
285
+ type: Number,
286
+ },
287
+ size: {
288
+ type: String as PropType<Size>,
289
+ default: 'md',
290
+ },
291
+ rowTo: {
292
+ default: undefined,
293
+ type: Function as PropType<((row: CollectionItem) => RouteLocationRaw) | undefined>,
294
+ },
295
+ rowHref: {
296
+ default: undefined,
297
+ type: Function as PropType<((row: CollectionItem) => string) | undefined>,
298
+ },
299
+ onRowClick: {
300
+ default: undefined,
301
+ type: Function as PropType<((row: CollectionItem, index: number, event: MouseEvent) => void) | undefined>,
302
+ },
303
+ rowKey: {
304
+ default: undefined,
305
+ type: Function as PropType<((row: CollectionItem) => string | number) | undefined>,
306
+ },
307
+ rowSelected: {
308
+ default: undefined,
309
+ type: Function as PropType<((row: CollectionItem) => boolean) | undefined>,
310
+ },
311
+ virtualScrolling: {
312
+ default: false,
313
+ type: Boolean,
314
+ },
315
+ });
316
+
317
+ const emit = defineEmits([
318
+ 'check',
319
+ 'check-all',
320
+ 'update:checkedRows',
321
+ 'details-open',
322
+ 'details-close',
323
+ 'update:openedDetailed',
324
+ 'sort',
325
+ 'cell-click',
326
+ 'row-click',
327
+ ]);
328
+
329
+ const visibleDetailRows = ref<string[]>([]);
330
+ // eslint-disable-next-line vue/no-setup-props-destructure
331
+ const newCheckedRows = ref<Row[]>([...props.checkedRows]);
332
+ const lastCheckedRowIndex = ref<number | null>(null);
333
+ const currentSortColumn = ref<BaseTableColumnData | null>(null);
334
+ const isAsc = ref(true);
335
+ const defaultSlots = ref<BaseTableColumnData[]>([]);
336
+
337
+ const slot = ref<HTMLElement | null>(null);
338
+
339
+ const newColumns = computed(() => {
340
+ const cols = defaultSlots.value;
341
+
342
+ if (props.columnOrder && props.columnOrder.length) {
343
+
344
+ const colOrder = props.columnOrder;
345
+
346
+ return cols
347
+ .sort((a, b) => {
348
+
349
+ // Always put actions column at the end
350
+
351
+ if (a.newKey === customKeyActions) {
352
+ return 1;
353
+ }
354
+
355
+ if (b.newKey === customKeyActions) {
356
+ return -1;
357
+ }
358
+
359
+ // If not found, put it at the end
360
+
361
+ const existsA = colOrder.includes(a.newKey);
362
+ const existsB = colOrder.includes(b.newKey);
363
+
364
+ if (!existsA && !existsB) {
365
+ return 0;
366
+ }
367
+
368
+ if (!existsA) {
369
+ return 1;
370
+ }
371
+
372
+ if (!existsB) {
373
+ return -1;
374
+ }
375
+
376
+ // Sort based on the order
377
+
378
+ return colOrder.indexOf(a.newKey) - colOrder.indexOf(b.newKey);
379
+ });
380
+ }
381
+
382
+ return cols;
383
+ });
384
+
385
+
386
+ const visibleColumnsInternal = computed(() => {
387
+
388
+ if (!newColumns.value) {
389
+ return [];
390
+ }
391
+
392
+ return newColumns.value
393
+ .filter((column: BaseTableColumnData) => {
394
+ if (column.toggle === false) {
395
+ return true;
396
+ }
397
+
398
+ if (!isArray(props.visibleColumns)) {
399
+ return true;
400
+ }
401
+
402
+ if (props.visibleColumns.includes(column.newKey)) {
403
+ return true;
404
+ }
405
+
406
+ return false;
407
+ });
408
+ });
409
+
410
+ /**
411
+ * Return total column count based if it's checkable or expanded
412
+ */
413
+ const columnCount = computed(() => {
414
+ let count = visibleColumnsInternal.value.length;
415
+ count += props.checkable ? 1 : 0;
416
+ count += props.detailed ? 1 : 0;
417
+
418
+ return count;
419
+ });
420
+
421
+ /**
422
+ * Return if detailed row tabled
423
+ * will be with chevron column & icon or not
424
+ */
425
+ const showDetailRowIcon = computed(() => {
426
+ return props.detailed;
427
+ });
428
+
429
+ /**
430
+ * When checkedRows prop change, update internal value without
431
+ * mutating original data.
432
+ */
433
+ watch(
434
+ () => props.checkedRows,
435
+ (rows) => {
436
+ newCheckedRows.value = [...rows];
437
+ },
438
+ { deep: true }
439
+ );
440
+
441
+ watch(
442
+ () => props.sortField,
443
+ () => {
444
+ updateSortState();
445
+ }
446
+ );
447
+
448
+ watch(
449
+ () => props.sortDirection,
450
+ () => {
451
+ updateSortState();
452
+ }
453
+ );
454
+
455
+ onMounted(() => {
456
+ nextTick(() => {
457
+ updateSortState();
458
+ });
459
+ });
460
+
461
+ /**
462
+ * Sort the column.
463
+ * Toggle current direction on column if it's sortable
464
+ * and not just updating the prop.
465
+ */
466
+ function sort(column: BaseTableColumnData, updatingData = false, event = null) {
467
+ if (!column || !column.sortable) {
468
+ return;
469
+ }
470
+
471
+ if (!updatingData) {
472
+ isAsc.value =
473
+ column === currentSortColumn.value
474
+ ? !isAsc.value
475
+ : props.sortDirection.toLowerCase() !== 'desc';
476
+ }
477
+
478
+ /**
479
+ * @property {string} field column field
480
+ * @property {boolean} direction 'asc' or 'desc'
481
+ * @property {Event} event native event
482
+ */
483
+ emit('sort', column.field, isAsc.value ? 'asc' : 'desc', event);
484
+
485
+ currentSortColumn.value = column;
486
+ }
487
+
488
+ /**
489
+ * Check if the row is checked (is added to the array).
490
+ */
491
+ function isRowChecked(row: Row): boolean {
492
+ const found = newCheckedRows.value.find((r) => {
493
+ const key1 = getRowKey(r);
494
+ const key2 = getRowKey(row);
495
+ return key1 == key2
496
+ });
497
+
498
+ return found !== undefined;
499
+ }
500
+
501
+ /**
502
+ * Check if all rows in the page are checkable.
503
+ */
504
+ const isAllUncheckable = computed(() => {
505
+ const validData = props.data.filter((row) => props.isRowCheckable(row));
506
+ return validData.length === 0;
507
+ });
508
+
509
+ /**
510
+ * Check if all rows in the page are checked.
511
+ */
512
+ const isAllChecked = computed(() => {
513
+ const validData = props.data.filter((row) => {
514
+ return props.isRowCheckable(row);
515
+ });
516
+
517
+ if (validData.length === 0) {
518
+ return false;
519
+ }
520
+
521
+ const missingChecked = validData.some((currentRow) => {
522
+ return !isRowChecked(currentRow);
523
+ });
524
+
525
+ return !missingChecked;
526
+ });
527
+
528
+ function getCheckedRowIndex(row: Row) {
529
+ const foundIndex = newCheckedRows.value.findIndex((r) => {
530
+ const key1 = getRowKey(r);
531
+ const key2 = getRowKey(row);
532
+ return key1 == key2
533
+ });
534
+
535
+ return foundIndex;
536
+ }
537
+
538
+ /**
539
+ * Remove a checked row from the array.
540
+ */
541
+ function removeCheckedRow(row: Row) {
542
+ const index = getCheckedRowIndex(row);
543
+ if (index >= 0) {
544
+ newCheckedRows.value.splice(index, 1);
545
+ }
546
+ }
547
+
548
+ /**
549
+ * Header checkbox click listener.
550
+ * Add or remove all rows in current page.
551
+ */
552
+ function checkAll() {
553
+ if (isAllChecked.value) {
554
+ newCheckedRows.value = [];
555
+ } else {
556
+ props.data.forEach((currentRow) => {
557
+ if (props.isRowCheckable(currentRow) && !isRowChecked(currentRow)) {
558
+ newCheckedRows.value.push(currentRow);
559
+ }
560
+ });
561
+ }
562
+
563
+ sendCheckUpdate();
564
+ }
565
+
566
+ /**
567
+ * Remove all rows in current page.
568
+ */
569
+ function uncheckAll() {
570
+ newCheckedRows.value = [];
571
+
572
+ sendCheckUpdate();
573
+ }
574
+
575
+ function sendCheckUpdate() {
576
+ emit('check', newCheckedRows.value);
577
+ emit('check-all', newCheckedRows.value);
578
+ emit('update:checkedRows', newCheckedRows.value);
579
+ }
580
+
581
+ /**
582
+ * Row checkbox click listener.
583
+ */
584
+ function checkRow(row: Row, index: number, event: MouseEvent) {
585
+ if (!props.isRowCheckable(row)) {
586
+ return;
587
+ }
588
+
589
+ const lastIndex = lastCheckedRowIndex.value;
590
+ lastCheckedRowIndex.value = index;
591
+
592
+ if (event.shiftKey && lastIndex !== null && index !== lastIndex) {
593
+ shiftCheckRow(row, index, lastIndex);
594
+ } else if (!isRowChecked(row)) {
595
+ newCheckedRows.value.push(row);
596
+ } else {
597
+ removeCheckedRow(row);
598
+ }
599
+
600
+ emit('check', newCheckedRows.value, row);
601
+
602
+ // Emit checked rows to update user variable
603
+ emit('update:checkedRows', newCheckedRows.value);
604
+ }
605
+
606
+ /**
607
+ * Check row when shift is pressed.
608
+ */
609
+ function shiftCheckRow(row: Row, index: number, lastCheckedRowIndex: number) {
610
+ // Get the subset of the list between the two indices
611
+ const subset = props.data.slice(
612
+ Math.min(index, lastCheckedRowIndex),
613
+ Math.max(index, lastCheckedRowIndex) + 1
614
+ );
615
+
616
+ // Determine the operation based on the state of the clicked checkbox
617
+ const shouldCheck = !isRowChecked(row);
618
+
619
+ subset.forEach((item) => {
620
+ removeCheckedRow(item);
621
+ if (shouldCheck && props.isRowCheckable(item)) {
622
+ newCheckedRows.value.push(item);
623
+ }
624
+ });
625
+ }
626
+
627
+ /**
628
+ * Toggle to show/hide details slot
629
+ */
630
+ function toggleDetails(row: Row) {
631
+ const found = isVisibleDetailRow(row);
632
+
633
+ if (found) {
634
+ closeDetailRow(row);
635
+ emit('details-close', row);
636
+ } else {
637
+ openDetailRow(row);
638
+ emit('details-open', row);
639
+ }
640
+
641
+ // Syncs the detailed rows with the parent component
642
+ emit('update:openedDetailed', visibleDetailRows.value);
643
+ }
644
+
645
+ function openDetailRow(row: Row) {
646
+ const key = getRowKey(row);
647
+ visibleDetailRows.value.push(key);
648
+ }
649
+
650
+ function closeDetailRow(row: Row) {
651
+ const key = getRowKey(row);
652
+ const i = visibleDetailRows.value.indexOf(key);
653
+ if (i >= 0) {
654
+ visibleDetailRows.value.splice(i, 1);
655
+ }
656
+ }
657
+
658
+ function isVisibleDetailRow(row: Row) {
659
+ const key = getRowKey(row);
660
+ return visibleDetailRows.value.indexOf(key) >= 0;
661
+ }
662
+
663
+ function isActiveDetailRow(row: Row) {
664
+ return props.detailed && isVisibleDetailRow(row);
665
+ }
666
+
667
+ /**
668
+ * Update sort state
669
+ */
670
+ function updateSortState() {
671
+ const sortField = props.sortField;
672
+
673
+ const sortDirection = props.sortDirection;
674
+
675
+ const sortColumn = newColumns.value.filter(
676
+ (column) => column.field === sortField
677
+ )[0];
678
+
679
+ // Set sort state
680
+
681
+ if (sortColumn) {
682
+ currentSortColumn.value = sortColumn;
683
+ isAsc.value = sortDirection.toLowerCase() !== 'desc';
684
+ } else {
685
+ currentSortColumn.value = null;
686
+ return;
687
+ }
688
+ }
689
+
690
+ /*
691
+ |--------------------------------------------------------------------------
692
+ | BaseTableColumns functions
693
+ |--------------------------------------------------------------------------
694
+ */
695
+
696
+ function addColumn(column: BaseTableColumnData) {
697
+ defaultSlots.value.push(column);
698
+
699
+ const slotHTMLElement = slot.value as HTMLElement;
700
+
701
+ if (slotHTMLElement && slotHTMLElement.children) {
702
+ nextTick(() => {
703
+ const ids = defaultSlots.value
704
+ .map((it) => `[data-id="${it.newKey}"]`)
705
+ .join(',');
706
+
707
+ const sortedIds = Array.from(slotHTMLElement.querySelectorAll(ids)).map(
708
+ (el: Element) => el.getAttribute('data-id')
709
+ );
710
+
711
+ defaultSlots.value = defaultSlots.value.sort((a, b) => {
712
+ return (
713
+ sortedIds.indexOf(`${a.newKey}`) - sortedIds.indexOf(`${b.newKey}`)
714
+ );
715
+ });
716
+ });
717
+ }
718
+ }
719
+
720
+ function removeColumn(column: BaseTableColumnData) {
721
+ defaultSlots.value = defaultSlots.value.filter(
722
+ (d) => d.newKey !== column.newKey
723
+ );
724
+ }
725
+
726
+ function rowBindings(row: CollectionItem, index: number) {
727
+ return {
728
+ onClick: props.onRowClick ? (event: MouseEvent) => props.onRowClick && props.onRowClick(row, index, event) : undefined,
729
+ }
730
+ }
731
+
732
+ function onCellClick(row: CollectionItem, index: number, column: BaseTableColumnData, columnIndex: number) {
733
+ if (!column.onClick) {
734
+ return undefined;
735
+ }
736
+
737
+ return (event: MouseEvent) => {
738
+ if (!column.onClick) {
739
+ return;
740
+ }
741
+
742
+ column.onClick(row, index, column, columnIndex, event);
743
+ };
744
+ }
745
+
746
+ let warningNoRowKeyFoundShown = false;
747
+
748
+ function getRowKey(row: Row): string {
749
+
750
+ if (props.rowKey) {
751
+ return props.rowKey(row) + '';
752
+ }
753
+
754
+ if (row.id) {
755
+ return row.id;
756
+ }
757
+
758
+ if (row.key) {
759
+ return row.key;
760
+ }
761
+
762
+ if (row.uuid) {
763
+ return row.uuid;
764
+ }
765
+
766
+ if (!warningNoRowKeyFoundShown) {
767
+ console.warn('%cNo unique key found for items provided to BaseDataTable.%cPlease provide a unique key for each row (id, key or uuid) or use the row-key props to specify a unique key.', 'font-weight: bold', 'font-weight: normal');
768
+ warningNoRowKeyFoundShown = true;
769
+ }
770
+
771
+ // if no key is found, hash a simplified version of the row object
772
+ // We use a simplified version to avoid hashing functions, objects, etc. for performance reasons
773
+
774
+ const simpleRow = {} as Record<string, string | number | boolean>;
775
+
776
+ for (const key in row) {
777
+ const value = row[key];
778
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
779
+ simpleRow[key] = value;
780
+ }
781
+ }
782
+
783
+ return objectHash(simpleRow);
784
+ }
785
+
786
+ provide('addColumn', addColumn);
787
+ provide('removeColumn', removeColumn);
788
+
789
+ const baseTableRef = ref<InstanceType<typeof BaseTable> | null>(null);
790
+
791
+
792
+ /*
793
+ |--------------------------------------------------------------------------
794
+ | Checks
795
+ |--------------------------------------------------------------------------
796
+ */
797
+
798
+ watch(
799
+ () => newColumns.value.map((item) => item.newKey),
800
+ (keys: string[]) => {
801
+
802
+ // check duplicates
803
+
804
+ const duplicates = keys.reduce((acc, key, index) => {
805
+ if (keys.indexOf(key) !== index && !acc.includes(key)) {
806
+ acc.push(key);
807
+ }
808
+
809
+ return acc;
810
+ }, [] as string[]);
811
+
812
+ if (duplicates.length) {
813
+ throw new Error(`Duplicate BaseTableColumn keys found: ${duplicates.join(', ')}`);
814
+ }
815
+ }
816
+ )
817
+
818
+ /*
819
+ |--------------------------------------------------------------------------
820
+ | Expose
821
+ |--------------------------------------------------------------------------
822
+ */
823
+
824
+ defineExpose({
825
+ newColumns,
826
+ uncheckAll,
827
+ scrollTop: () => {
828
+ baseTableRef.value?.scrollTop();
829
+ },
830
+ });
831
+ </script>