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,966 +1,966 @@
1
- <template>
2
- <BaseDataIterator
3
- ref="dataIteratorRef"
4
- :items="items"
5
- :per-page="perPage"
6
- :url="url"
7
- :url-query="urlQuery"
8
- :default-query="defaultQuery"
9
- :searchable="searchable"
10
- :actions="actions"
11
- :history-mode="historyMode"
12
- :layout="layout"
13
- :size="sizeInternal.size.value"
14
- :sections="sectionsInternal"
15
- :scroll-top-on-fetch="maxHeight ? false : scrollTopOnFetch"
16
- :filters-position="filtersPosition"
17
- :search="search"
18
- @fetch="onFetch"
19
- @will-scroll-top="onWillScrollTop"
20
- >
21
- <template #default="dataIteratorProps">
22
- <BaseCard
23
- clipped
24
- class="w-full overflow-hidden"
25
- >
26
- <div v-if="newCheckedRows.length">
27
- <div
28
- class="flex items-center justify-between border-b border-slate-200 bg-slate-50 py-2 pl-3 pr-2 text-sm"
29
- >
30
- <div>
31
- <span class="mr-3 text-slate-500">{{
32
- t('sui.x_rows_selected', {
33
- count: newCheckedRows.length,
34
- })
35
- }}.</span>
36
- <button
37
- type="button"
38
- class="mr-3 inline text-slate-800 underline underline-offset-1 decoration-slate-400 decoration-2 decoration-dashed"
39
- @click="uncheckAll()"
40
- >
41
- {{ t('sui.deselect_all') }}
42
- </button>
43
- </div>
44
- <BaseActionButtons
45
- v-if="checkableActions?.length"
46
- :actions="checkableActions"
47
- :max-actions="2"
48
- variant="button-group"
49
- />
50
- </div>
51
- </div>
52
-
53
- <BaseDataTableTemplate
54
- ref="table"
55
- :checked-rows="newCheckedRows"
56
- :data="dataIteratorProps.items"
57
- :loading="dataIteratorProps.loading"
58
- :detailed="detailed"
59
- :has-detailed-visible="hasDetailedVisible"
60
- :checkable="checkable"
61
- :is-row-checkable="isRowCheckable"
62
- :sort-field="dataIteratorProps.sortField"
63
- :sort-direction="dataIteratorProps.sortDirection"
64
- :max-height="maxHeight"
65
- :visible-columns="visibleColumns"
66
- :column-order="columnOrder"
67
- :size="sizeInternal.size.value"
68
- :row-to="rowToInternal"
69
- :row-href="rowHref"
70
- :row-key="rowKey"
71
- :row-selected="rowSelected"
72
- :virtual-scrolling="virtualScrolling"
73
- @update:checked-rows="onCheckedRowsUpdate"
74
- @sort="dataIteratorProps.onSortChange"
75
- @row-click="onRowClick"
76
- >
77
- <template #default>
78
- <slot :data="dataIteratorProps.data" />
79
-
80
- <BaseTableColumn
81
- v-slot="{ row }"
82
- :visible="rowActionsInternal.length > 0"
83
- :toggle="false"
84
- ignore-row-interactions
85
- :custom-key="customKeyActions"
86
- class="overflow-hidden"
87
- >
88
- <div class="flex justify-end gap-1 text-right w-full">
89
- <div class="btn-group">
90
- <template
91
- v-for="rowAction in visibleRowActions"
92
- :key="rowAction.icon"
93
- >
94
- <BaseDataTableRowAction
95
- :row="row"
96
- :row-action="rowAction"
97
- :size="sizeInternal.size.value"
98
- />
99
- </template>
100
- <BaseMenu
101
- v-if="showRowActionMenu"
102
- :items="rowActionMenuItems(row)"
103
- :size="menuSize"
104
- >
105
- <template #button>
106
- <BaseButton
107
- as="div"
108
- :size="menuSize"
109
- icon="heroicons-solid:dots-vertical"
110
- />
111
- </template>
112
- </BaseMenu>
113
- </div>
114
- </div>
115
- </BaseTableColumn>
116
- </template>
117
-
118
- <template #detail="propsDetail">
119
- <slot
120
- name="detail"
121
- v-bind="propsDetail"
122
- />
123
- </template>
124
-
125
- <template #checkedHeader="propsCheckHeader">
126
- <slot
127
- name="checkedHeader"
128
- v-bind="propsCheckHeader"
129
- />
130
- </template>
131
-
132
- <template #empty>
133
- <div
134
- v-if="dataIteratorProps.error"
135
- class="flex items-center justify-center py-16"
136
- >
137
- <div class="flex flex-col items-center justify-center">
138
- <BaseIcon
139
- icon="heroicons:x-circle"
140
- class="h-10 w-10 text-red-600"
141
- />
142
- <p class="mt-3 text-center text-sm text-slate-600">
143
- {{ t('sui.whoops') }}
144
- </p>
145
- </div>
146
- </div>
147
- <div
148
- v-else-if="dataIteratorProps.firstLoad"
149
- >
150
- <slot name="empty">
151
- <div class="flex items-center justify-center py-16">
152
- <div class="flex flex-col items-center">
153
- <BaseEmptyState class="w-24" />
154
-
155
- <p class="mt-3 text-center text-sm text-slate-600">
156
- {{ t('sui.nothing_found') }}
157
- </p>
158
- </div>
159
- </div>
160
- </slot>
161
- </div>
162
- </template>
163
- </BaseDataTableTemplate>
164
- </BaseCard>
165
- </template>
166
-
167
- <template
168
- v-if="$slots.filters"
169
- #filters="{ query, updateQuery, updateQueryValue, updateQueryValueDebounce }"
170
- >
171
- <slot
172
- name="filters"
173
- :query="query"
174
- :update-query="updateQuery"
175
- :update-query-value="updateQueryValue"
176
- :update-query-value-debounce="updateQueryValueDebounce"
177
- />
178
- </template>
179
-
180
- <template #sidebarTop="sidebarProps">
181
- <slot
182
- name="sidebarTop"
183
- v-bind="sidebarProps"
184
- />
185
- </template>
186
-
187
- <template #sidebarBottom="sidebarProps">
188
- <slot
189
- name="sidebarBottom"
190
- v-bind="sidebarProps"
191
- />
192
- </template>
193
-
194
- <template
195
- v-if="toggleable"
196
- #columns
197
- >
198
- <BaseDataIteratorSectionColumns
199
- :table="table"
200
- :visible-columns="visibleColumns"
201
- :column-order="columnOrder"
202
- @update:visible-columns="onUpdateVisibleColumn"
203
- @update:column-order="onUpdateColumnOrder"
204
- />
205
- </template>
206
-
207
- <template
208
- v-for="section in sections"
209
- :key="section.name"
210
- #[section.name]
211
- >
212
- <slot :name="section.name" />
213
- </template>
214
- </BaseDataIterator>
215
- </template>
216
-
217
- <script lang="ts" setup>
218
- import { PropType } from 'vue';
219
- import { t } from '@/i18n';
220
- import {
221
- Collection,
222
- CollectionItem,
223
- DataIteratorSection,
224
- DataTableQuery,
225
- PaginatedCollection,
226
- ResourceCollection,
227
- RowAction,
228
- } from '@/types';
229
- import { useDialogsStore } from '@/stores/dialogs';
230
- import { useSnackbarsStore } from '../stores/snackbars';
231
- import BaseDataIterator from './BaseDataIterator.vue';
232
- import { cloneDeep, isArray } from 'lodash';
233
-
234
- import BaseCard from './BaseCard.vue';
235
- import BaseTableColumn from './BaseTableColumn.vue';
236
- import BaseDataIteratorSectionColumns from './BaseDataIteratorSectionColumns.vue';
237
- import { BaseIcon, config } from '@/index';
238
- import BaseEmptyState from '../svg/BaseEmptyState.vue';
239
- import { RouteLocationRaw } from 'vue-router';
240
- import BaseMenu from './BaseMenu.vue';
241
- import BaseDataTableRowAction from './BaseDataTableRowAction.vue';
242
- import { ActionItem } from '@/types';
243
- import { Size } from '@/utils/sizes';
244
- import { useInputSize } from '@/composables/inputSize';
245
- import BaseButton from './BaseButton.vue';
246
- import BaseDataTableTemplate from './BaseDataTableTemplate.vue';
247
- import { customKeyActions } from '@/services/table/customKeyActions';
248
- import BaseActionButtons from './BaseActionButtons.vue';
249
-
250
- const http = config.http;
251
-
252
- const dialogs = useDialogsStore();
253
- const snackbars = useSnackbarsStore();
254
-
255
- const table = ref<null | InstanceType<typeof BaseDataTableTemplate>>(null);
256
-
257
- const props = defineProps({
258
-
259
- /**
260
- * Data table items
261
- */
262
- items: {
263
- default: undefined,
264
- type: Array as PropType<CollectionItem[] | undefined>,
265
- },
266
-
267
- /**
268
- * Per page (only when using local data)
269
- */
270
- perPage: {
271
- default: undefined,
272
- type: Number,
273
- },
274
-
275
- /**
276
- * Base URL from which to make requests
277
- */
278
- url: {
279
- default: undefined,
280
- type: String as PropType<string | undefined>,
281
- },
282
-
283
- /**
284
- * Query params that always get applied
285
- */
286
- urlQuery: {
287
- default: undefined,
288
- type: Object as PropType<Record<string, any>>,
289
- },
290
-
291
- /**
292
- * Query params that gets applied by default
293
- * These may be overwritten by URL params generated by the data-table or filters
294
- */
295
- defaultQuery: {
296
- default: undefined,
297
- type: Object as PropType<DataTableQuery>,
298
- },
299
-
300
- /**
301
- * Show url for router link
302
- */
303
- showUrl: {
304
- default: undefined,
305
- type: Function as PropType<
306
- ((row: CollectionItem) => RouteLocationRaw) | undefined
307
- >,
308
- },
309
-
310
- rowTo: {
311
- default: undefined,
312
- type: Function as PropType<
313
- ((row: CollectionItem) => RouteLocationRaw) | undefined
314
- >,
315
- },
316
-
317
- rowHref: {
318
- default: undefined,
319
- type: Function as PropType<
320
- ((row: CollectionItem) => string) | undefined
321
- >,
322
- },
323
-
324
- rowSelected: {
325
- default: undefined,
326
- type: Function as PropType<
327
- ((row: CollectionItem) => boolean) | undefined
328
- >,
329
- },
330
-
331
- onRowClick: {
332
- default: undefined,
333
- type: Function as PropType<(row: CollectionItem, index: number, event: MouseEvent) => void>,
334
- },
335
-
336
- /**
337
- * Show/Hide edit button
338
- */
339
- editButton: {
340
- default: true,
341
- type: Boolean,
342
- },
343
-
344
- /**
345
- * Edit url for router link
346
- */
347
- editUrl: {
348
- default: undefined,
349
- type: Function as PropType<
350
- ((row: CollectionItem) => RouteLocationRaw) | undefined
351
- >,
352
- },
353
-
354
- /**
355
- * Show/Hide delete button
356
- */
357
- deleteButton: {
358
- default: true,
359
- type: Boolean,
360
- },
361
-
362
- /**
363
- * Delete endpoint to delete an item
364
- */
365
- deleteUrl: {
366
- default: undefined,
367
- type: Function as PropType<((row: CollectionItem) => string) | undefined>,
368
- },
369
-
370
- /**
371
- * Delete label
372
- */
373
- deleteLabel: {
374
- default: '',
375
- type: String,
376
- },
377
-
378
- /**
379
- * Delete message
380
- */
381
- deleteMessage: {
382
- default: '',
383
- type: String,
384
- },
385
-
386
- /**
387
- * Show toggle-able details on each row
388
- */
389
- detailed: {
390
- default: false,
391
- type: Boolean,
392
- },
393
-
394
- /**
395
- * Check is a given row has details
396
- */
397
- hasDetailedVisible: {
398
- default() {
399
- return true;
400
- },
401
- type: Function as PropType<(row: any) => boolean>,
402
- },
403
-
404
- /**
405
- * Makes row checkable
406
- */
407
- checkable: {
408
- default: false,
409
- type: Boolean,
410
- },
411
-
412
- /**
413
- * Actions on each row
414
- */
415
- checkableActions: {
416
- default: undefined,
417
- type: Array as PropType<ActionItem[]>,
418
- },
419
-
420
- /**
421
- * Checked rows array
422
- */
423
- checkedRows: {
424
- default() {
425
- return [];
426
- },
427
- type: Array as PropType<Record<string, any>[]>,
428
- },
429
-
430
- /**
431
- * Check is a given row is checkable
432
- */
433
- isRowCheckable: {
434
- default() {
435
- return () => true;
436
- },
437
- type: Function,
438
- },
439
-
440
- /**
441
- * Adds a search bar
442
- */
443
- searchable: {
444
- default: true,
445
- type: Boolean,
446
- },
447
-
448
- /**
449
- * Shows the column toggle utility
450
- */
451
- toggleable: {
452
- default: true,
453
- type: Boolean,
454
- },
455
-
456
- /**
457
- * Actions
458
- */
459
- actions: {
460
- default: undefined,
461
- type: Array as PropType<ActionItem[]>,
462
- },
463
-
464
- /**
465
- * Save data table state in URL
466
- */
467
- historyMode: {
468
- default: false,
469
- type: Boolean,
470
- },
471
-
472
- /*
473
- * Max height (in px)
474
- */
475
- maxHeight: {
476
- default: undefined,
477
- type: Number,
478
- },
479
-
480
- /**
481
- * Layout type
482
- *
483
- * default: Layout with a sidebar
484
- * compact: Layout without a sidebar, this is the default layout for mobile, even if you don't specify it
485
- */
486
- layout: {
487
- default: 'default',
488
- type: String as PropType<'default' | 'compact'>,
489
- },
490
-
491
- /**
492
- * Overall size and spacing of the component
493
- */
494
- size: {
495
- default: 'md',
496
- type: String as PropType<Size>,
497
- },
498
-
499
- /**
500
- * Data iterator sections
501
- */
502
- sections: {
503
- default: undefined,
504
- type: Array as PropType<DataIteratorSection[]>,
505
- },
506
-
507
- /**
508
- * Row actions
509
- */
510
- rowActions: {
511
- default: undefined,
512
- type: Array as PropType<RowAction[]>,
513
- },
514
-
515
- /**
516
- * Number of visible row actions
517
- */
518
- numberOfVisibleRowActions: {
519
- default: 2,
520
- type: Number,
521
- },
522
-
523
- /**
524
- * Scroll to top when fetching new data
525
- */
526
- scrollTopOnFetch: {
527
- default: true,
528
- type: Boolean,
529
- },
530
-
531
- /**
532
- * Filters position
533
- */
534
- filtersPosition: {
535
- default: 'section',
536
- type: String as PropType<'top' | 'section'>,
537
- },
538
-
539
- /**
540
- * Row key. Used to identify rows for faster rendering.
541
- * If not provided, it will use the id, key or uuid, or create a hash from the row object.
542
- */
543
- rowKey: {
544
- default: undefined,
545
- type: Function as PropType<(row: CollectionItem) => string | number>,
546
- },
547
-
548
- /**
549
- * Virtual scrolling
550
- */
551
- virtualScrolling: {
552
- default: false,
553
- type: Boolean,
554
- },
555
-
556
- /**
557
- * Storage key to save visible columns and order settings.
558
- * By default, it uses the current URL path, without query params.
559
- */
560
- storageKey: {
561
- type: String,
562
- default() {
563
- return window.location.pathname;
564
- },
565
- },
566
-
567
- /**
568
- * Function to search local data
569
- */
570
- search: {
571
- default: undefined,
572
- type: Function as PropType<(items: Collection, search: string | null) => Collection>,
573
- }
574
- });
575
-
576
- const sizeInternal = useInputSize(props.size);
577
-
578
- const menuSize = computed(() => {
579
- if (sizeInternal.size.value == 'md') {
580
- return 'sm';
581
- }
582
- if (sizeInternal.size.value == 'sm') {
583
- return 'xs';
584
- }
585
- return 'xs';
586
- })
587
-
588
- const emit = defineEmits([
589
- 'delete',
590
- 'update:checked-rows',
591
- 'fetch',
592
- ]);
593
-
594
- const dataIteratorRef = ref<null | InstanceType<typeof BaseDataIterator>>(null);
595
-
596
- const rowToInternal = computed(() => {
597
- if (props.showUrl) {
598
- console.warn('showUrl is deprecated, use rowTo instead');
599
- return props.showUrl;
600
- }
601
-
602
- return props.rowTo;
603
- });
604
-
605
- /*
606
- |--------------------------------------------------------------------------
607
- | Gate helpers
608
- |--------------------------------------------------------------------------
609
- */
610
-
611
- const gate = (row: CollectionItem, action: string): boolean => {
612
- if (row.can && Object.prototype.hasOwnProperty.call(row.can, action)) {
613
- return row.can[action];
614
- }
615
- return true;
616
- };
617
-
618
- const canUpdate = (row: CollectionItem): boolean => {
619
- return gate(row, 'update');
620
- };
621
-
622
- const canDelete = (row: CollectionItem): boolean => {
623
- return gate(row, 'delete');
624
- };
625
-
626
- function onDeleteClick(row: CollectionItem) {
627
- return new Promise<void>((resolve) => {
628
- dialogs.push({
629
- title: props.deleteLabel ? props.deleteLabel : (t('sui.delete_record') + '?'),
630
- message: props.deleteMessage ? props.deleteMessage : t('sui.delete_record_description'),
631
- color: 'danger',
632
- closeOnOutsideClick: true,
633
- confirmText: t('sui.yes_delete'),
634
- onConfirm: async () => {
635
- await onDelete(row),
636
- resolve();
637
- },
638
- onCancel: () => {
639
- resolve();
640
- },
641
- });
642
- });
643
- }
644
-
645
- async function onDelete(row: CollectionItem) {
646
- if (!props.deleteUrl) {
647
- return;
648
- }
649
-
650
- try {
651
-
652
- const response = await http.delete(props.deleteUrl(row));
653
-
654
- if (response.data && response.data.message) {
655
- snackbars.push({
656
- title: t('sui.success'),
657
- text: response.data.message,
658
- color: 'success',
659
- });
660
- }
661
-
662
- emit('delete', row);
663
-
664
- // Refetch even if URL is the same
665
- fetch();
666
-
667
- } catch (error: any) {
668
- snackbars.push({
669
- title: t('sui.error'),
670
- text: error.response.data?.message ?? 'Unknown error',
671
- color: 'danger',
672
- });
673
- }
674
- }
675
-
676
- const componentStorageKey = 'base_data_table.';
677
- const settingsStorage = config.settingsStorage;
678
-
679
- /*
680
- |--------------------------------------------------------------------------
681
- | Toggle columns
682
- |--------------------------------------------------------------------------
683
- */
684
-
685
- const visibleColumns = ref<string[]>([]);
686
- const visibleColumnsKey = componentStorageKey + props.storageKey + '.visible_columns';
687
-
688
- onMounted(async () => {
689
-
690
- const value = await settingsStorage.get(visibleColumnsKey);
691
-
692
- let visibleColumnsFromStorage = [];
693
-
694
- if (typeof value === 'string') {
695
- try {
696
- visibleColumnsFromStorage.push(...JSON.parse(value));
697
- } catch (e) {
698
- console.error('Error parsing visible columns from storage', e);
699
- }
700
- }
701
-
702
- if (typeof value === 'object' && value !== null) {
703
- visibleColumnsFromStorage.push(Object.values(value));
704
- }
705
-
706
- if (Array.isArray(value)) {
707
- visibleColumnsFromStorage = value;
708
- }
709
-
710
- // If found, set visibleColumns
711
- if (
712
- visibleColumnsFromStorage &&
713
- isArray(visibleColumnsFromStorage) &&
714
- visibleColumnsFromStorage.length > 0
715
- ) {
716
- visibleColumns.value = visibleColumnsFromStorage;
717
- }
718
-
719
- if (
720
- table.value &&
721
- table.value.newColumns.length &&
722
- visibleColumns.value.length == 0
723
- ) {
724
- visibleColumns.value = table.value.newColumns
725
- .filter((c) => c.toggle)
726
- .filter((c) => c.toggleDefault ?? true)
727
- .map((c) => c.newKey);
728
- }
729
- });
730
-
731
- /**
732
- * Update local storage when check input update
733
- */
734
- function onUpdateVisibleColumn(columns: string[]) {
735
-
736
- visibleColumns.value = columns;
737
-
738
- settingsStorage.set(
739
- visibleColumnsKey,
740
- JSON.stringify(visibleColumns.value)
741
- );
742
- }
743
-
744
- /*
745
- |--------------------------------------------------------------------------
746
- | Order columns
747
- |--------------------------------------------------------------------------
748
- */
749
-
750
- const columnOrder = ref<string[]>([]);
751
-
752
- const columnOrderKey = componentStorageKey + props.storageKey + '.column_order';
753
-
754
- onMounted(async () => {
755
-
756
- const value = await settingsStorage.get(columnOrderKey);
757
-
758
- let columnOrderFromStorage = [];
759
-
760
- if (typeof value === 'string') {
761
- try {
762
- columnOrderFromStorage.push(...JSON.parse(value));
763
- } catch (e) {
764
- console.error('Error parsing visible columns from storage', e);
765
- }
766
- }
767
-
768
- if (typeof value === 'object' && value !== null) {
769
- columnOrderFromStorage.push(Object.values(value));
770
- }
771
-
772
- if (Array.isArray(value)) {
773
- columnOrderFromStorage = value;
774
- }
775
-
776
- // If found, set columnOrder
777
- if (
778
- columnOrderFromStorage &&
779
- isArray(columnOrderFromStorage) &&
780
- columnOrderFromStorage.length > 0
781
- ) {
782
-
783
- const colKeys = table.value?.newColumns.map((c) => c.newKey) ?? [];
784
-
785
- columnOrder.value = columnOrderFromStorage.filter((c) => {
786
- return colKeys.includes(c);
787
- });
788
- }
789
- });
790
-
791
- function onUpdateColumnOrder(value: string[]) {
792
-
793
- columnOrder.value = value;
794
-
795
- settingsStorage.set(
796
- columnOrderKey,
797
- JSON.stringify(value)
798
- );
799
-
800
- }
801
-
802
- /*
803
- |--------------------------------------------------------------------------
804
- | Row Actions
805
- |--------------------------------------------------------------------------
806
- */
807
-
808
- const rowActionsInternal = computed<RowAction[]>(() => {
809
- const actions = [];
810
-
811
- if (props.editUrl && props.editButton) {
812
- actions.push({
813
- label: t('sui.edit'),
814
- icon: 'heroicons:cog-6-tooth-solid',
815
- to: (row: CollectionItem) => (props.editUrl ? props.editUrl(row) : ''),
816
- disabled: (row: CollectionItem) => !canUpdate(row),
817
- });
818
- }
819
-
820
- actions.push(...cloneDeep(props.rowActions) ?? []);
821
-
822
- if (props.deleteUrl && props.deleteButton) {
823
- actions.push({
824
- label: t('sui.delete'),
825
- icon: 'heroicons:trash-20-solid',
826
- action: onDeleteClick,
827
- disabled: (row: CollectionItem) => !canDelete(row),
828
- });
829
- }
830
-
831
- return actions;
832
- });
833
-
834
- const visibleRowActions = computed<RowAction[]>(() => {
835
- return rowActionsInternal.value.slice(0, props.numberOfVisibleRowActions);
836
- });
837
-
838
- const showRowActionMenu = computed<boolean>(() => {
839
- return rowActionsInternal.value.length > props.numberOfVisibleRowActions;
840
- });
841
-
842
- function rowActionMenuItems(row: CollectionItem): ActionItem[] {
843
- return rowActionsInternal.value.map((action) => {
844
- return {
845
- label: action.label,
846
- icon: action.icon,
847
- disabled: action.disabled && action.disabled(row),
848
- action: action.action
849
- ? () => {
850
- if (action.action) action.action(row);
851
- }
852
- : undefined,
853
- to: action.to ? action.to(row) : undefined,
854
- href: action.href ? action.href(row) : undefined,
855
- };
856
- });
857
- }
858
-
859
- /*
860
- |--------------------------------------------------------------------------
861
- | Checkable
862
- |--------------------------------------------------------------------------
863
- */
864
-
865
- const newCheckedRows = ref<Record<string, any>[]>([]);
866
-
867
- watch(
868
- () => props.checkedRows,
869
- (checkedRows) => {
870
- newCheckedRows.value = checkedRows;
871
- }
872
- );
873
-
874
- function uncheckAll() {
875
- table.value?.uncheckAll();
876
- }
877
-
878
- const sectionsInternal = computed<DataIteratorSection[]>(() => {
879
- const sections = props.sections ?? [];
880
-
881
- if (props.toggleable) {
882
- return [
883
- ...sections,
884
- {
885
- name: 'columns',
886
- icon: 'heroicons:view-columns',
887
- title: t('sui.columns'),
888
- closeText: t('sui.apply'),
889
- opened: false,
890
- },
891
- ];
892
- }
893
-
894
- return sections;
895
- });
896
-
897
- function onCheckedRowsUpdate(checkedRows: Record<string, any>[]) {
898
- newCheckedRows.value = checkedRows;
899
- emit('update:checked-rows', checkedRows);
900
- }
901
-
902
- /*
903
- |--------------------------------------------------------------------------
904
- | Scrolling behavior
905
- |--------------------------------------------------------------------------
906
- */
907
-
908
- function onWillScrollTop() {
909
- if (!props.scrollTopOnFetch) {
910
- return;
911
- }
912
-
913
- if (props.maxHeight) {
914
- table.value?.scrollTop();
915
-
916
- const top = dataIteratorRef.value?.$el?.getBoundingClientRect()?.top ?? 0;
917
-
918
- if (top < 0) {
919
- dataIteratorRef.value?.scrollIntoView();
920
- }
921
- }
922
- }
923
-
924
- /*
925
- |--------------------------------------------------------------------------
926
- | On fetch
927
- |--------------------------------------------------------------------------
928
- */
929
-
930
- function onFetch(
931
- payload: null | ResourceCollection | PaginatedCollection | Collection
932
- ) {
933
- emit('fetch', payload);
934
- }
935
-
936
- /*
937
- |--------------------------------------------------------------------------
938
- | Exposed functions
939
- |--------------------------------------------------------------------------
940
- */
941
-
942
- function fetch() {
943
- if (!dataIteratorRef.value) {
944
- return;
945
- }
946
- dataIteratorRef.value.fetch();
947
- }
948
-
949
- function fetchWithoutLoading() {
950
- if (!dataIteratorRef.value) {
951
- return;
952
- }
953
- dataIteratorRef.value.fetchWithoutLoading();
954
- }
955
-
956
- const dataIteratorQuery = computed((): DataTableQuery | null => {
957
- return dataIteratorRef.value?.query ?? null;
958
- });
959
-
960
- defineExpose({
961
- fetch,
962
- fetchWithoutLoading,
963
- query: dataIteratorQuery,
964
- data: computed(() => dataIteratorRef.value?.data ?? undefined),
965
- });
966
- </script>
1
+ <template>
2
+ <BaseDataIterator
3
+ ref="dataIteratorRef"
4
+ :items="items"
5
+ :per-page="perPage"
6
+ :url="url"
7
+ :url-query="urlQuery"
8
+ :default-query="defaultQuery"
9
+ :searchable="searchable"
10
+ :actions="actions"
11
+ :history-mode="historyMode"
12
+ :layout="layout"
13
+ :size="sizeInternal.size.value"
14
+ :sections="sectionsInternal"
15
+ :scroll-top-on-fetch="maxHeight ? false : scrollTopOnFetch"
16
+ :filters-position="filtersPosition"
17
+ :search="search"
18
+ @fetch="onFetch"
19
+ @will-scroll-top="onWillScrollTop"
20
+ >
21
+ <template #default="dataIteratorProps">
22
+ <BaseCard
23
+ clipped
24
+ class="w-full overflow-hidden"
25
+ >
26
+ <div v-if="newCheckedRows.length">
27
+ <div
28
+ class="flex items-center justify-between border-b border-slate-200 bg-slate-50 py-2 pl-3 pr-2 text-sm"
29
+ >
30
+ <div>
31
+ <span class="mr-3 text-slate-500">{{
32
+ t('sui.x_rows_selected', {
33
+ count: newCheckedRows.length,
34
+ })
35
+ }}.</span>
36
+ <button
37
+ type="button"
38
+ class="mr-3 inline text-slate-800 underline underline-offset-1 decoration-slate-400 decoration-2 decoration-dashed"
39
+ @click="uncheckAll()"
40
+ >
41
+ {{ t('sui.deselect_all') }}
42
+ </button>
43
+ </div>
44
+ <BaseActionButtons
45
+ v-if="checkableActions?.length"
46
+ :actions="checkableActions"
47
+ :max-actions="2"
48
+ variant="button-group"
49
+ />
50
+ </div>
51
+ </div>
52
+
53
+ <BaseDataTableTemplate
54
+ ref="table"
55
+ :checked-rows="newCheckedRows"
56
+ :data="dataIteratorProps.items"
57
+ :loading="dataIteratorProps.loading"
58
+ :detailed="detailed"
59
+ :has-detailed-visible="hasDetailedVisible"
60
+ :checkable="checkable"
61
+ :is-row-checkable="isRowCheckable"
62
+ :sort-field="dataIteratorProps.sortField"
63
+ :sort-direction="dataIteratorProps.sortDirection"
64
+ :max-height="maxHeight"
65
+ :visible-columns="visibleColumns"
66
+ :column-order="columnOrder"
67
+ :size="sizeInternal.size.value"
68
+ :row-to="rowToInternal"
69
+ :row-href="rowHref"
70
+ :row-key="rowKey"
71
+ :row-selected="rowSelected"
72
+ :virtual-scrolling="virtualScrolling"
73
+ @update:checked-rows="onCheckedRowsUpdate"
74
+ @sort="dataIteratorProps.onSortChange"
75
+ @row-click="onRowClick"
76
+ >
77
+ <template #default>
78
+ <slot :data="dataIteratorProps.data" />
79
+
80
+ <BaseTableColumn
81
+ v-slot="{ row }"
82
+ :visible="rowActionsInternal.length > 0"
83
+ :toggle="false"
84
+ ignore-row-interactions
85
+ :custom-key="customKeyActions"
86
+ class="overflow-hidden"
87
+ >
88
+ <div class="flex justify-end gap-1 text-right w-full">
89
+ <div class="btn-group">
90
+ <template
91
+ v-for="rowAction in visibleRowActions"
92
+ :key="rowAction.icon"
93
+ >
94
+ <BaseDataTableRowAction
95
+ :row="row"
96
+ :row-action="rowAction"
97
+ :size="sizeInternal.size.value"
98
+ />
99
+ </template>
100
+ <BaseMenu
101
+ v-if="showRowActionMenu"
102
+ :items="rowActionMenuItems(row)"
103
+ :size="menuSize"
104
+ >
105
+ <template #button>
106
+ <BaseButton
107
+ as="div"
108
+ :size="menuSize"
109
+ icon="heroicons-solid:dots-vertical"
110
+ />
111
+ </template>
112
+ </BaseMenu>
113
+ </div>
114
+ </div>
115
+ </BaseTableColumn>
116
+ </template>
117
+
118
+ <template #detail="propsDetail">
119
+ <slot
120
+ name="detail"
121
+ v-bind="propsDetail"
122
+ />
123
+ </template>
124
+
125
+ <template #checkedHeader="propsCheckHeader">
126
+ <slot
127
+ name="checkedHeader"
128
+ v-bind="propsCheckHeader"
129
+ />
130
+ </template>
131
+
132
+ <template #empty>
133
+ <div
134
+ v-if="dataIteratorProps.error"
135
+ class="flex items-center justify-center py-16"
136
+ >
137
+ <div class="flex flex-col items-center justify-center">
138
+ <BaseIcon
139
+ icon="heroicons:x-circle"
140
+ class="h-10 w-10 text-red-600"
141
+ />
142
+ <p class="mt-3 text-center text-sm text-slate-600">
143
+ {{ t('sui.whoops') }}
144
+ </p>
145
+ </div>
146
+ </div>
147
+ <div
148
+ v-else-if="dataIteratorProps.firstLoad"
149
+ >
150
+ <slot name="empty">
151
+ <div class="flex items-center justify-center py-16">
152
+ <div class="flex flex-col items-center">
153
+ <BaseEmptyState class="w-24" />
154
+
155
+ <p class="mt-3 text-center text-sm text-slate-600">
156
+ {{ t('sui.nothing_found') }}
157
+ </p>
158
+ </div>
159
+ </div>
160
+ </slot>
161
+ </div>
162
+ </template>
163
+ </BaseDataTableTemplate>
164
+ </BaseCard>
165
+ </template>
166
+
167
+ <template
168
+ v-if="$slots.filters"
169
+ #filters="{ query, updateQuery, updateQueryValue, updateQueryValueDebounce }"
170
+ >
171
+ <slot
172
+ name="filters"
173
+ :query="query"
174
+ :update-query="updateQuery"
175
+ :update-query-value="updateQueryValue"
176
+ :update-query-value-debounce="updateQueryValueDebounce"
177
+ />
178
+ </template>
179
+
180
+ <template #sidebarTop="sidebarProps">
181
+ <slot
182
+ name="sidebarTop"
183
+ v-bind="sidebarProps"
184
+ />
185
+ </template>
186
+
187
+ <template #sidebarBottom="sidebarProps">
188
+ <slot
189
+ name="sidebarBottom"
190
+ v-bind="sidebarProps"
191
+ />
192
+ </template>
193
+
194
+ <template
195
+ v-if="toggleable"
196
+ #columns
197
+ >
198
+ <BaseDataIteratorSectionColumns
199
+ :table="table"
200
+ :visible-columns="visibleColumns"
201
+ :column-order="columnOrder"
202
+ @update:visible-columns="onUpdateVisibleColumn"
203
+ @update:column-order="onUpdateColumnOrder"
204
+ />
205
+ </template>
206
+
207
+ <template
208
+ v-for="section in sections"
209
+ :key="section.name"
210
+ #[section.name]
211
+ >
212
+ <slot :name="section.name" />
213
+ </template>
214
+ </BaseDataIterator>
215
+ </template>
216
+
217
+ <script lang="ts" setup>
218
+ import { PropType } from 'vue';
219
+ import { t } from '@/i18n';
220
+ import {
221
+ Collection,
222
+ CollectionItem,
223
+ DataIteratorSection,
224
+ DataTableQuery,
225
+ PaginatedCollection,
226
+ ResourceCollection,
227
+ RowAction,
228
+ } from '@/types';
229
+ import { useDialogsStore } from '@/stores/dialogs';
230
+ import { useSnackbarsStore } from '../stores/snackbars';
231
+ import BaseDataIterator from './BaseDataIterator.vue';
232
+ import { cloneDeep, isArray } from 'lodash';
233
+
234
+ import BaseCard from './BaseCard.vue';
235
+ import BaseTableColumn from './BaseTableColumn.vue';
236
+ import BaseDataIteratorSectionColumns from './BaseDataIteratorSectionColumns.vue';
237
+ import { BaseIcon, config } from '@/index';
238
+ import BaseEmptyState from '../svg/BaseEmptyState.vue';
239
+ import { RouteLocationRaw } from 'vue-router';
240
+ import BaseMenu from './BaseMenu.vue';
241
+ import BaseDataTableRowAction from './BaseDataTableRowAction.vue';
242
+ import { ActionItem } from '@/types';
243
+ import { Size } from '@/utils/sizes';
244
+ import { useInputSize } from '@/composables/inputSize';
245
+ import BaseButton from './BaseButton.vue';
246
+ import BaseDataTableTemplate from './BaseDataTableTemplate.vue';
247
+ import { customKeyActions } from '@/services/table/customKeyActions';
248
+ import BaseActionButtons from './BaseActionButtons.vue';
249
+
250
+ const http = config.http;
251
+
252
+ const dialogs = useDialogsStore();
253
+ const snackbars = useSnackbarsStore();
254
+
255
+ const table = ref<null | InstanceType<typeof BaseDataTableTemplate>>(null);
256
+
257
+ const props = defineProps({
258
+
259
+ /**
260
+ * Data table items
261
+ */
262
+ items: {
263
+ default: undefined,
264
+ type: Array as PropType<CollectionItem[] | undefined>,
265
+ },
266
+
267
+ /**
268
+ * Per page (only when using local data)
269
+ */
270
+ perPage: {
271
+ default: undefined,
272
+ type: Number,
273
+ },
274
+
275
+ /**
276
+ * Base URL from which to make requests
277
+ */
278
+ url: {
279
+ default: undefined,
280
+ type: String as PropType<string | undefined>,
281
+ },
282
+
283
+ /**
284
+ * Query params that always get applied
285
+ */
286
+ urlQuery: {
287
+ default: undefined,
288
+ type: Object as PropType<Record<string, any>>,
289
+ },
290
+
291
+ /**
292
+ * Query params that gets applied by default
293
+ * These may be overwritten by URL params generated by the data-table or filters
294
+ */
295
+ defaultQuery: {
296
+ default: undefined,
297
+ type: Object as PropType<DataTableQuery>,
298
+ },
299
+
300
+ /**
301
+ * Show url for router link
302
+ */
303
+ showUrl: {
304
+ default: undefined,
305
+ type: Function as PropType<
306
+ ((row: CollectionItem) => RouteLocationRaw) | undefined
307
+ >,
308
+ },
309
+
310
+ rowTo: {
311
+ default: undefined,
312
+ type: Function as PropType<
313
+ ((row: CollectionItem) => RouteLocationRaw) | undefined
314
+ >,
315
+ },
316
+
317
+ rowHref: {
318
+ default: undefined,
319
+ type: Function as PropType<
320
+ ((row: CollectionItem) => string) | undefined
321
+ >,
322
+ },
323
+
324
+ rowSelected: {
325
+ default: undefined,
326
+ type: Function as PropType<
327
+ ((row: CollectionItem) => boolean) | undefined
328
+ >,
329
+ },
330
+
331
+ onRowClick: {
332
+ default: undefined,
333
+ type: Function as PropType<(row: CollectionItem, index: number, event: MouseEvent) => void>,
334
+ },
335
+
336
+ /**
337
+ * Show/Hide edit button
338
+ */
339
+ editButton: {
340
+ default: true,
341
+ type: Boolean,
342
+ },
343
+
344
+ /**
345
+ * Edit url for router link
346
+ */
347
+ editUrl: {
348
+ default: undefined,
349
+ type: Function as PropType<
350
+ ((row: CollectionItem) => RouteLocationRaw) | undefined
351
+ >,
352
+ },
353
+
354
+ /**
355
+ * Show/Hide delete button
356
+ */
357
+ deleteButton: {
358
+ default: true,
359
+ type: Boolean,
360
+ },
361
+
362
+ /**
363
+ * Delete endpoint to delete an item
364
+ */
365
+ deleteUrl: {
366
+ default: undefined,
367
+ type: Function as PropType<((row: CollectionItem) => string) | undefined>,
368
+ },
369
+
370
+ /**
371
+ * Delete label
372
+ */
373
+ deleteLabel: {
374
+ default: '',
375
+ type: String,
376
+ },
377
+
378
+ /**
379
+ * Delete message
380
+ */
381
+ deleteMessage: {
382
+ default: '',
383
+ type: String,
384
+ },
385
+
386
+ /**
387
+ * Show toggle-able details on each row
388
+ */
389
+ detailed: {
390
+ default: false,
391
+ type: Boolean,
392
+ },
393
+
394
+ /**
395
+ * Check is a given row has details
396
+ */
397
+ hasDetailedVisible: {
398
+ default() {
399
+ return true;
400
+ },
401
+ type: Function as PropType<(row: any) => boolean>,
402
+ },
403
+
404
+ /**
405
+ * Makes row checkable
406
+ */
407
+ checkable: {
408
+ default: false,
409
+ type: Boolean,
410
+ },
411
+
412
+ /**
413
+ * Actions on each row
414
+ */
415
+ checkableActions: {
416
+ default: undefined,
417
+ type: Array as PropType<ActionItem[]>,
418
+ },
419
+
420
+ /**
421
+ * Checked rows array
422
+ */
423
+ checkedRows: {
424
+ default() {
425
+ return [];
426
+ },
427
+ type: Array as PropType<Record<string, any>[]>,
428
+ },
429
+
430
+ /**
431
+ * Check is a given row is checkable
432
+ */
433
+ isRowCheckable: {
434
+ default() {
435
+ return () => true;
436
+ },
437
+ type: Function,
438
+ },
439
+
440
+ /**
441
+ * Adds a search bar
442
+ */
443
+ searchable: {
444
+ default: true,
445
+ type: Boolean,
446
+ },
447
+
448
+ /**
449
+ * Shows the column toggle utility
450
+ */
451
+ toggleable: {
452
+ default: true,
453
+ type: Boolean,
454
+ },
455
+
456
+ /**
457
+ * Actions
458
+ */
459
+ actions: {
460
+ default: undefined,
461
+ type: Array as PropType<ActionItem[]>,
462
+ },
463
+
464
+ /**
465
+ * Save data table state in URL
466
+ */
467
+ historyMode: {
468
+ default: false,
469
+ type: Boolean,
470
+ },
471
+
472
+ /*
473
+ * Max height (in px)
474
+ */
475
+ maxHeight: {
476
+ default: undefined,
477
+ type: Number,
478
+ },
479
+
480
+ /**
481
+ * Layout type
482
+ *
483
+ * default: Layout with a sidebar
484
+ * compact: Layout without a sidebar, this is the default layout for mobile, even if you don't specify it
485
+ */
486
+ layout: {
487
+ default: 'default',
488
+ type: String as PropType<'default' | 'compact'>,
489
+ },
490
+
491
+ /**
492
+ * Overall size and spacing of the component
493
+ */
494
+ size: {
495
+ default: 'md',
496
+ type: String as PropType<Size>,
497
+ },
498
+
499
+ /**
500
+ * Data iterator sections
501
+ */
502
+ sections: {
503
+ default: undefined,
504
+ type: Array as PropType<DataIteratorSection[]>,
505
+ },
506
+
507
+ /**
508
+ * Row actions
509
+ */
510
+ rowActions: {
511
+ default: undefined,
512
+ type: Array as PropType<RowAction[]>,
513
+ },
514
+
515
+ /**
516
+ * Number of visible row actions
517
+ */
518
+ numberOfVisibleRowActions: {
519
+ default: 2,
520
+ type: Number,
521
+ },
522
+
523
+ /**
524
+ * Scroll to top when fetching new data
525
+ */
526
+ scrollTopOnFetch: {
527
+ default: true,
528
+ type: Boolean,
529
+ },
530
+
531
+ /**
532
+ * Filters position
533
+ */
534
+ filtersPosition: {
535
+ default: 'section',
536
+ type: String as PropType<'top' | 'section'>,
537
+ },
538
+
539
+ /**
540
+ * Row key. Used to identify rows for faster rendering.
541
+ * If not provided, it will use the id, key or uuid, or create a hash from the row object.
542
+ */
543
+ rowKey: {
544
+ default: undefined,
545
+ type: Function as PropType<(row: CollectionItem) => string | number>,
546
+ },
547
+
548
+ /**
549
+ * Virtual scrolling
550
+ */
551
+ virtualScrolling: {
552
+ default: false,
553
+ type: Boolean,
554
+ },
555
+
556
+ /**
557
+ * Storage key to save visible columns and order settings.
558
+ * By default, it uses the current URL path, without query params.
559
+ */
560
+ storageKey: {
561
+ type: String,
562
+ default() {
563
+ return window.location.pathname;
564
+ },
565
+ },
566
+
567
+ /**
568
+ * Function to search local data
569
+ */
570
+ search: {
571
+ default: undefined,
572
+ type: Function as PropType<(items: Collection, search: string | null) => Collection>,
573
+ }
574
+ });
575
+
576
+ const sizeInternal = useInputSize(props.size);
577
+
578
+ const menuSize = computed(() => {
579
+ if (sizeInternal.size.value == 'md') {
580
+ return 'sm';
581
+ }
582
+ if (sizeInternal.size.value == 'sm') {
583
+ return 'xs';
584
+ }
585
+ return 'xs';
586
+ })
587
+
588
+ const emit = defineEmits([
589
+ 'delete',
590
+ 'update:checked-rows',
591
+ 'fetch',
592
+ ]);
593
+
594
+ const dataIteratorRef = ref<null | InstanceType<typeof BaseDataIterator>>(null);
595
+
596
+ const rowToInternal = computed(() => {
597
+ if (props.showUrl) {
598
+ console.warn('showUrl is deprecated, use rowTo instead');
599
+ return props.showUrl;
600
+ }
601
+
602
+ return props.rowTo;
603
+ });
604
+
605
+ /*
606
+ |--------------------------------------------------------------------------
607
+ | Gate helpers
608
+ |--------------------------------------------------------------------------
609
+ */
610
+
611
+ const gate = (row: CollectionItem, action: string): boolean => {
612
+ if (row.can && Object.prototype.hasOwnProperty.call(row.can, action)) {
613
+ return row.can[action];
614
+ }
615
+ return true;
616
+ };
617
+
618
+ const canUpdate = (row: CollectionItem): boolean => {
619
+ return gate(row, 'update');
620
+ };
621
+
622
+ const canDelete = (row: CollectionItem): boolean => {
623
+ return gate(row, 'delete');
624
+ };
625
+
626
+ function onDeleteClick(row: CollectionItem) {
627
+ return new Promise<void>((resolve) => {
628
+ dialogs.push({
629
+ title: props.deleteLabel ? props.deleteLabel : (t('sui.delete_record') + '?'),
630
+ message: props.deleteMessage ? props.deleteMessage : t('sui.delete_record_description'),
631
+ color: 'danger',
632
+ closeOnOutsideClick: true,
633
+ confirmText: t('sui.yes_delete'),
634
+ onConfirm: async () => {
635
+ await onDelete(row),
636
+ resolve();
637
+ },
638
+ onCancel: () => {
639
+ resolve();
640
+ },
641
+ });
642
+ });
643
+ }
644
+
645
+ async function onDelete(row: CollectionItem) {
646
+ if (!props.deleteUrl) {
647
+ return;
648
+ }
649
+
650
+ try {
651
+
652
+ const response = await http.delete(props.deleteUrl(row));
653
+
654
+ if (response.data && response.data.message) {
655
+ snackbars.push({
656
+ title: t('sui.success'),
657
+ text: response.data.message,
658
+ color: 'success',
659
+ });
660
+ }
661
+
662
+ emit('delete', row);
663
+
664
+ // Refetch even if URL is the same
665
+ fetch();
666
+
667
+ } catch (error: any) {
668
+ snackbars.push({
669
+ title: t('sui.error'),
670
+ text: error.response.data?.message ?? 'Unknown error',
671
+ color: 'danger',
672
+ });
673
+ }
674
+ }
675
+
676
+ const componentStorageKey = 'base_data_table.';
677
+ const settingsStorage = config.settingsStorage;
678
+
679
+ /*
680
+ |--------------------------------------------------------------------------
681
+ | Toggle columns
682
+ |--------------------------------------------------------------------------
683
+ */
684
+
685
+ const visibleColumns = ref<string[]>([]);
686
+ const visibleColumnsKey = componentStorageKey + props.storageKey + '.visible_columns';
687
+
688
+ onMounted(async () => {
689
+
690
+ const value = await settingsStorage.get(visibleColumnsKey);
691
+
692
+ let visibleColumnsFromStorage = [];
693
+
694
+ if (typeof value === 'string') {
695
+ try {
696
+ visibleColumnsFromStorage.push(...JSON.parse(value));
697
+ } catch (e) {
698
+ console.error('Error parsing visible columns from storage', e);
699
+ }
700
+ }
701
+
702
+ if (typeof value === 'object' && value !== null) {
703
+ visibleColumnsFromStorage.push(Object.values(value));
704
+ }
705
+
706
+ if (Array.isArray(value)) {
707
+ visibleColumnsFromStorage = value;
708
+ }
709
+
710
+ // If found, set visibleColumns
711
+ if (
712
+ visibleColumnsFromStorage &&
713
+ isArray(visibleColumnsFromStorage) &&
714
+ visibleColumnsFromStorage.length > 0
715
+ ) {
716
+ visibleColumns.value = visibleColumnsFromStorage;
717
+ }
718
+
719
+ if (
720
+ table.value &&
721
+ table.value.newColumns.length &&
722
+ visibleColumns.value.length == 0
723
+ ) {
724
+ visibleColumns.value = table.value.newColumns
725
+ .filter((c) => c.toggle)
726
+ .filter((c) => c.toggleDefault ?? true)
727
+ .map((c) => c.newKey);
728
+ }
729
+ });
730
+
731
+ /**
732
+ * Update local storage when check input update
733
+ */
734
+ function onUpdateVisibleColumn(columns: string[]) {
735
+
736
+ visibleColumns.value = columns;
737
+
738
+ settingsStorage.set(
739
+ visibleColumnsKey,
740
+ JSON.stringify(visibleColumns.value)
741
+ );
742
+ }
743
+
744
+ /*
745
+ |--------------------------------------------------------------------------
746
+ | Order columns
747
+ |--------------------------------------------------------------------------
748
+ */
749
+
750
+ const columnOrder = ref<string[]>([]);
751
+
752
+ const columnOrderKey = componentStorageKey + props.storageKey + '.column_order';
753
+
754
+ onMounted(async () => {
755
+
756
+ const value = await settingsStorage.get(columnOrderKey);
757
+
758
+ let columnOrderFromStorage = [];
759
+
760
+ if (typeof value === 'string') {
761
+ try {
762
+ columnOrderFromStorage.push(...JSON.parse(value));
763
+ } catch (e) {
764
+ console.error('Error parsing visible columns from storage', e);
765
+ }
766
+ }
767
+
768
+ if (typeof value === 'object' && value !== null) {
769
+ columnOrderFromStorage.push(Object.values(value));
770
+ }
771
+
772
+ if (Array.isArray(value)) {
773
+ columnOrderFromStorage = value;
774
+ }
775
+
776
+ // If found, set columnOrder
777
+ if (
778
+ columnOrderFromStorage &&
779
+ isArray(columnOrderFromStorage) &&
780
+ columnOrderFromStorage.length > 0
781
+ ) {
782
+
783
+ const colKeys = table.value?.newColumns.map((c) => c.newKey) ?? [];
784
+
785
+ columnOrder.value = columnOrderFromStorage.filter((c) => {
786
+ return colKeys.includes(c);
787
+ });
788
+ }
789
+ });
790
+
791
+ function onUpdateColumnOrder(value: string[]) {
792
+
793
+ columnOrder.value = value;
794
+
795
+ settingsStorage.set(
796
+ columnOrderKey,
797
+ JSON.stringify(value)
798
+ );
799
+
800
+ }
801
+
802
+ /*
803
+ |--------------------------------------------------------------------------
804
+ | Row Actions
805
+ |--------------------------------------------------------------------------
806
+ */
807
+
808
+ const rowActionsInternal = computed<RowAction[]>(() => {
809
+ const actions = [];
810
+
811
+ if (props.editUrl && props.editButton) {
812
+ actions.push({
813
+ label: t('sui.edit'),
814
+ icon: 'heroicons:cog-6-tooth-solid',
815
+ to: (row: CollectionItem) => (props.editUrl ? props.editUrl(row) : ''),
816
+ disabled: (row: CollectionItem) => !canUpdate(row),
817
+ });
818
+ }
819
+
820
+ actions.push(...cloneDeep(props.rowActions) ?? []);
821
+
822
+ if (props.deleteUrl && props.deleteButton) {
823
+ actions.push({
824
+ label: t('sui.delete'),
825
+ icon: 'heroicons:trash-20-solid',
826
+ action: onDeleteClick,
827
+ disabled: (row: CollectionItem) => !canDelete(row),
828
+ });
829
+ }
830
+
831
+ return actions;
832
+ });
833
+
834
+ const visibleRowActions = computed<RowAction[]>(() => {
835
+ return rowActionsInternal.value.slice(0, props.numberOfVisibleRowActions);
836
+ });
837
+
838
+ const showRowActionMenu = computed<boolean>(() => {
839
+ return rowActionsInternal.value.length > props.numberOfVisibleRowActions;
840
+ });
841
+
842
+ function rowActionMenuItems(row: CollectionItem): ActionItem[] {
843
+ return rowActionsInternal.value.map((action) => {
844
+ return {
845
+ label: action.label,
846
+ icon: action.icon,
847
+ disabled: action.disabled && action.disabled(row),
848
+ action: action.action
849
+ ? () => {
850
+ if (action.action) action.action(row);
851
+ }
852
+ : undefined,
853
+ to: action.to ? action.to(row) : undefined,
854
+ href: action.href ? action.href(row) : undefined,
855
+ };
856
+ });
857
+ }
858
+
859
+ /*
860
+ |--------------------------------------------------------------------------
861
+ | Checkable
862
+ |--------------------------------------------------------------------------
863
+ */
864
+
865
+ const newCheckedRows = ref<Record<string, any>[]>([]);
866
+
867
+ watch(
868
+ () => props.checkedRows,
869
+ (checkedRows) => {
870
+ newCheckedRows.value = checkedRows;
871
+ }
872
+ );
873
+
874
+ function uncheckAll() {
875
+ table.value?.uncheckAll();
876
+ }
877
+
878
+ const sectionsInternal = computed<DataIteratorSection[]>(() => {
879
+ const sections = props.sections ?? [];
880
+
881
+ if (props.toggleable) {
882
+ return [
883
+ ...sections,
884
+ {
885
+ name: 'columns',
886
+ icon: 'heroicons:view-columns',
887
+ title: t('sui.columns'),
888
+ closeText: t('sui.apply'),
889
+ opened: false,
890
+ },
891
+ ];
892
+ }
893
+
894
+ return sections;
895
+ });
896
+
897
+ function onCheckedRowsUpdate(checkedRows: Record<string, any>[]) {
898
+ newCheckedRows.value = checkedRows;
899
+ emit('update:checked-rows', checkedRows);
900
+ }
901
+
902
+ /*
903
+ |--------------------------------------------------------------------------
904
+ | Scrolling behavior
905
+ |--------------------------------------------------------------------------
906
+ */
907
+
908
+ function onWillScrollTop() {
909
+ if (!props.scrollTopOnFetch) {
910
+ return;
911
+ }
912
+
913
+ if (props.maxHeight) {
914
+ table.value?.scrollTop();
915
+
916
+ const top = dataIteratorRef.value?.$el?.getBoundingClientRect()?.top ?? 0;
917
+
918
+ if (top < 0) {
919
+ dataIteratorRef.value?.scrollIntoView();
920
+ }
921
+ }
922
+ }
923
+
924
+ /*
925
+ |--------------------------------------------------------------------------
926
+ | On fetch
927
+ |--------------------------------------------------------------------------
928
+ */
929
+
930
+ function onFetch(
931
+ payload: null | ResourceCollection | PaginatedCollection | Collection
932
+ ) {
933
+ emit('fetch', payload);
934
+ }
935
+
936
+ /*
937
+ |--------------------------------------------------------------------------
938
+ | Exposed functions
939
+ |--------------------------------------------------------------------------
940
+ */
941
+
942
+ function fetch() {
943
+ if (!dataIteratorRef.value) {
944
+ return;
945
+ }
946
+ dataIteratorRef.value.fetch();
947
+ }
948
+
949
+ function fetchWithoutLoading() {
950
+ if (!dataIteratorRef.value) {
951
+ return;
952
+ }
953
+ dataIteratorRef.value.fetchWithoutLoading();
954
+ }
955
+
956
+ const dataIteratorQuery = computed((): DataTableQuery | null => {
957
+ return dataIteratorRef.value?.query ?? null;
958
+ });
959
+
960
+ defineExpose({
961
+ fetch,
962
+ fetchWithoutLoading,
963
+ query: dataIteratorQuery,
964
+ data: computed(() => dataIteratorRef.value?.data ?? undefined),
965
+ });
966
+ </script>