sprintify-ui 0.1.17 → 0.1.18

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 (395) hide show
  1. package/README.md +229 -229
  2. package/dist/sprintify-ui.es.js +97 -92
  3. package/dist/style.css +1 -1
  4. package/dist/tailwindcss/index.js +306 -306
  5. package/dist/types/src/components/BaseActionItem.vue.d.ts +33 -33
  6. package/dist/types/src/components/BaseActionItemButton.vue.d.ts +29 -29
  7. package/dist/types/src/components/BaseAddressForm.vue.d.ts +81 -81
  8. package/dist/types/src/components/BaseAlert.vue.d.ts +51 -51
  9. package/dist/types/src/components/BaseApp.vue.d.ts +9 -9
  10. package/dist/types/src/components/BaseAppDialogs.vue.d.ts +14 -14
  11. package/dist/types/src/components/BaseAppNotifications.vue.d.ts +2 -2
  12. package/dist/types/src/components/BaseAutocomplete.vue.d.ts +232 -232
  13. package/dist/types/src/components/BaseAutocompleteDrawer.vue.d.ts +90 -90
  14. package/dist/types/src/components/BaseAutocompleteFetch.vue.d.ts +213 -213
  15. package/dist/types/src/components/BaseAvatar.vue.d.ts +52 -52
  16. package/dist/types/src/components/BaseAvatarGroup.vue.d.ts +43 -43
  17. package/dist/types/src/components/BaseBadge.vue.d.ts +50 -50
  18. package/dist/types/src/components/BaseBelongsTo.vue.d.ts +219 -219
  19. package/dist/types/src/components/BaseBoolean.vue.d.ts +15 -15
  20. package/dist/types/src/components/BaseBreadcrumbs.vue.d.ts +14 -14
  21. package/dist/types/src/components/BaseButton.vue.d.ts +23 -23
  22. package/dist/types/src/components/BaseButtonGroup.vue.d.ts +143 -143
  23. package/dist/types/src/components/BaseCard.vue.d.ts +21 -21
  24. package/dist/types/src/components/BaseCardRow.vue.d.ts +16 -16
  25. package/dist/types/src/components/BaseCharacterCounter.vue.d.ts +49 -49
  26. package/dist/types/src/components/BaseClickOutside.vue.d.ts +26 -26
  27. package/dist/types/src/components/BaseClipboard.vue.d.ts +21 -21
  28. package/dist/types/src/components/BaseColor.vue.d.ts +80 -80
  29. package/dist/types/src/components/BaseContainer.vue.d.ts +34 -34
  30. package/dist/types/src/components/BaseCounter.vue.d.ts +42 -42
  31. package/dist/types/src/components/BaseCropper.vue.d.ts +57 -57
  32. package/dist/types/src/components/BaseCropperModal.vue.d.ts +27 -27
  33. package/dist/types/src/components/BaseDataIterator.vue.d.ts +212 -212
  34. package/dist/types/src/components/BaseDataIteratorSectionBox.vue.d.ts +23 -23
  35. package/dist/types/src/components/BaseDataIteratorSectionButton.vue.d.ts +20 -20
  36. package/dist/types/src/components/BaseDataIteratorSectionColumns.vue.d.ts +665 -665
  37. package/dist/types/src/components/BaseDataIteratorSectionModal.vue.d.ts +29 -29
  38. package/dist/types/src/components/BaseDataTable.vue.d.ts +383 -383
  39. package/dist/types/src/components/BaseDataTableRowAction.vue.d.ts +18 -18
  40. package/dist/types/src/components/BaseDatePicker.vue.d.ts +84 -84
  41. package/dist/types/src/components/BaseDateSelect.vue.d.ts +70 -70
  42. package/dist/types/src/components/BaseDescriptionList.vue.d.ts +9 -9
  43. package/dist/types/src/components/BaseDescriptionListItem.vue.d.ts +10 -10
  44. package/dist/types/src/components/BaseDialog.vue.d.ts +60 -60
  45. package/dist/types/src/components/BaseDisplayRelativeTime.vue.d.ts +68 -68
  46. package/dist/types/src/components/BaseDraggable.vue.d.ts +34 -34
  47. package/dist/types/src/components/BaseDropdown.vue.d.ts +62 -62
  48. package/dist/types/src/components/BaseDropdownAutocomplete.vue.d.ts +132 -132
  49. package/dist/types/src/components/BaseField.vue.d.ts +58 -58
  50. package/dist/types/src/components/BaseFieldI18n.vue.d.ts +96 -96
  51. package/dist/types/src/components/BaseFilePicker.vue.d.ts +59 -59
  52. package/dist/types/src/components/BaseFilePickerCrop.vue.d.ts +57 -57
  53. package/dist/types/src/components/BaseFileUploader.vue.d.ts +85 -85
  54. package/dist/types/src/components/BaseForm.vue.d.ts +131 -131
  55. package/dist/types/src/components/BaseHasMany.vue.d.ts +152 -152
  56. package/dist/types/src/components/BaseHeader.vue.d.ts +80 -80
  57. package/dist/types/src/components/BaseIconPicker.vue.d.ts +38 -38
  58. package/dist/types/src/components/BaseInput.vue.d.ts +169 -169
  59. package/dist/types/src/components/BaseInputError.vue.d.ts +9 -9
  60. package/dist/types/src/components/BaseInputLabel.vue.d.ts +43 -43
  61. package/dist/types/src/components/BaseInputPercent.vue.d.ts +133 -133
  62. package/dist/types/src/components/BaseLayoutNotificationDropdown.vue.d.ts +36 -36
  63. package/dist/types/src/components/BaseLayoutNotificationItem.vue.d.ts +16 -16
  64. package/dist/types/src/components/BaseLayoutNotificationItemContent.vue.d.ts +18 -18
  65. package/dist/types/src/components/BaseLayoutSidebar.vue.d.ts +51 -51
  66. package/dist/types/src/components/BaseLayoutSidebarConfigurable.vue.d.ts +87 -87
  67. package/dist/types/src/components/BaseLayoutStacked.vue.d.ts +23 -23
  68. package/dist/types/src/components/BaseLayoutStackedConfigurable.vue.d.ts +78 -78
  69. package/dist/types/src/components/BaseLoadingCover.vue.d.ts +96 -96
  70. package/dist/types/src/components/BaseMediaGallery.vue.d.ts +64 -64
  71. package/dist/types/src/components/BaseMediaGalleryItem.vue.d.ts +45 -45
  72. package/dist/types/src/components/BaseMediaItem.vue.d.ts +27 -27
  73. package/dist/types/src/components/BaseMediaLibrary.vue.d.ts +172 -172
  74. package/dist/types/src/components/BaseMediaList.vue.d.ts +47 -47
  75. package/dist/types/src/components/BaseMediaListItem.vue.d.ts +47 -47
  76. package/dist/types/src/components/BaseMediaPictures.vue.d.ts +55 -55
  77. package/dist/types/src/components/BaseMediaPicturesItem.vue.d.ts +54 -54
  78. package/dist/types/src/components/BaseMediaPreview.vue.d.ts +36 -36
  79. package/dist/types/src/components/BaseMenu.vue.d.ts +68 -68
  80. package/dist/types/src/components/BaseMenuItem.vue.d.ts +61 -61
  81. package/dist/types/src/components/BaseModalCenter.vue.d.ts +79 -79
  82. package/dist/types/src/components/BaseModalSide.vue.d.ts +61 -61
  83. package/dist/types/src/components/BaseNavbar.vue.d.ts +35 -35
  84. package/dist/types/src/components/BaseNavbarItem.vue.d.ts +26 -26
  85. package/dist/types/src/components/BaseNavbarItemContent.vue.d.ts +60 -60
  86. package/dist/types/src/components/BaseNavbarSideItem.vue.d.ts +44 -44
  87. package/dist/types/src/components/BaseNavbarSideItemContent.vue.d.ts +60 -60
  88. package/dist/types/src/components/BaseNumber.vue.d.ts +125 -125
  89. package/dist/types/src/components/BasePagination.vue.d.ts +35 -35
  90. package/dist/types/src/components/BasePanel.vue.d.ts +31 -31
  91. package/dist/types/src/components/BasePassword.vue.d.ts +62 -62
  92. package/dist/types/src/components/BaseProgressCircle.vue.d.ts +37 -37
  93. package/dist/types/src/components/BaseRadioGroup.vue.d.ts +105 -105
  94. package/dist/types/src/components/BaseReadMore.vue.d.ts +21 -21
  95. package/dist/types/src/components/BaseRichText.vue.d.ts +92 -92
  96. package/dist/types/src/components/BaseSelect.vue.d.ts +97 -97
  97. package/dist/types/src/components/BaseShortcut.vue.d.ts +86 -86
  98. package/dist/types/src/components/BaseSideNavigation.vue.d.ts +33 -33
  99. package/dist/types/src/components/BaseSideNavigationItem.vue.d.ts +43 -43
  100. package/dist/types/src/components/BaseSkeleton.vue.d.ts +30 -30
  101. package/dist/types/src/components/BaseStatistic.vue.d.ts +56 -56
  102. package/dist/types/src/components/BaseStepper.vue.d.ts +16 -16
  103. package/dist/types/src/components/BaseStepperItem.vue.d.ts +51 -51
  104. package/dist/types/src/components/BaseSwitch.vue.d.ts +87 -87
  105. package/dist/types/src/components/BaseSystemAlert.vue.d.ts +52 -52
  106. package/dist/types/src/components/BaseTabItem.vue.d.ts +43 -43
  107. package/dist/types/src/components/BaseTable.vue.d.ts +212 -212
  108. package/dist/types/src/components/BaseTableColumn.vue.d.ts +174 -174
  109. package/dist/types/src/components/BaseTabs.vue.d.ts +33 -33
  110. package/dist/types/src/components/BaseTagAutocomplete.vue.d.ts +204 -204
  111. package/dist/types/src/components/BaseTagAutocompleteFetch.vue.d.ts +144 -144
  112. package/dist/types/src/components/BaseTextarea.vue.d.ts +98 -98
  113. package/dist/types/src/components/BaseTextareaAutoresize.vue.d.ts +98 -98
  114. package/dist/types/src/components/BaseTimeline.vue.d.ts +14 -14
  115. package/dist/types/src/components/BaseTimelineItem.vue.d.ts +14 -14
  116. package/dist/types/src/components/SlotComponent.d.ts +43 -43
  117. package/dist/types/src/components/index.d.ts +93 -93
  118. package/dist/types/src/composables/breakpoints.d.ts +27 -27
  119. package/dist/types/src/composables/clickOutside.d.ts +8 -8
  120. package/dist/types/src/composables/field.d.ts +19 -19
  121. package/dist/types/src/composables/hasOptions.d.ts +7 -7
  122. package/dist/types/src/composables/mediaQuery.d.ts +2 -2
  123. package/dist/types/src/composables/modal.d.ts +6 -6
  124. package/dist/types/src/composables/paginatedData.d.ts +7 -7
  125. package/dist/types/src/constants/MyConstants.d.ts +1 -1
  126. package/dist/types/src/constants/index.d.ts +2 -2
  127. package/dist/types/src/i18n/index.d.ts +1 -1
  128. package/dist/types/src/index.d.ts +220 -220
  129. package/dist/types/src/stores/dialogs.d.ts +9 -9
  130. package/dist/types/src/stores/i18n.d.ts +5 -5
  131. package/dist/types/src/stores/notifications.d.ts +10 -10
  132. package/dist/types/src/stores/systemAlerts.d.ts +9 -9
  133. package/dist/types/src/svg/BaseEmptyState.vue.d.ts +2 -2
  134. package/dist/types/src/svg/BaseSpinnerLarge.vue.d.ts +2 -2
  135. package/dist/types/src/svg/BaseSpinnerSmall.vue.d.ts +2 -2
  136. package/dist/types/src/types/Color.d.ts +9 -9
  137. package/dist/types/src/types/Country.d.ts +4 -4
  138. package/dist/types/src/types/ImagePickerResult.d.ts +5 -5
  139. package/dist/types/src/types/Media.d.ts +9 -9
  140. package/dist/types/src/types/Notification.d.ts +8 -8
  141. package/dist/types/src/types/Region.d.ts +5 -5
  142. package/dist/types/src/types/Status.d.ts +5 -5
  143. package/dist/types/src/types/StepperItem.d.ts +7 -7
  144. package/dist/types/src/types/TimelineItem.d.ts +8 -8
  145. package/dist/types/src/types/UploadedFile.d.ts +10 -10
  146. package/dist/types/src/types/User.d.ts +6 -6
  147. package/dist/types/src/types/index.d.ts +218 -218
  148. package/dist/types/src/utils/blob.d.ts +3 -3
  149. package/dist/types/src/utils/colors.d.ts +13 -13
  150. package/dist/types/src/utils/cropper/avatar.d.ts +5 -5
  151. package/dist/types/src/utils/cropper/cover.d.ts +5 -5
  152. package/dist/types/src/utils/cropper/presetInterface.d.ts +7 -7
  153. package/dist/types/src/utils/cropper/presets.d.ts +6 -6
  154. package/dist/types/src/utils/fileSizeFormat.d.ts +1 -1
  155. package/dist/types/src/utils/fileValidations.d.ts +2 -2
  156. package/dist/types/src/utils/index.d.ts +6 -6
  157. package/dist/types/src/utils/resizeImageFromURI.d.ts +1 -1
  158. package/dist/types/src/utils/scrollPreventer.d.ts +3 -3
  159. package/dist/types/src/utils/toHumanList.d.ts +1 -1
  160. package/package.json +139 -139
  161. package/src/assets/form.css +6 -6
  162. package/src/assets/main.css +35 -35
  163. package/src/assets/tailwind.css +2 -2
  164. package/src/components/BaseActionItem.vue +63 -63
  165. package/src/components/BaseActionItemButton.vue +75 -75
  166. package/src/components/BaseAddressForm.stories.js +103 -103
  167. package/src/components/BaseAddressForm.vue +353 -353
  168. package/src/components/BaseAlert.stories.js +52 -52
  169. package/src/components/BaseAlert.vue +152 -152
  170. package/src/components/BaseApp.vue +16 -16
  171. package/src/components/BaseAppDialogs.vue +124 -124
  172. package/src/components/BaseAppNotifications.vue +73 -73
  173. package/src/components/BaseAutocomplete.stories.js +236 -236
  174. package/src/components/BaseAutocomplete.vue +514 -514
  175. package/src/components/BaseAutocompleteDrawer.vue +354 -354
  176. package/src/components/BaseAutocompleteFetch.stories.js +224 -224
  177. package/src/components/BaseAutocompleteFetch.vue +277 -277
  178. package/src/components/BaseAvatar.stories.js +39 -39
  179. package/src/components/BaseAvatar.vue +120 -120
  180. package/src/components/BaseAvatarGroup.stories.js +71 -71
  181. package/src/components/BaseAvatarGroup.vue +148 -148
  182. package/src/components/BaseBadge.stories.js +124 -124
  183. package/src/components/BaseBadge.vue +79 -79
  184. package/src/components/BaseBelongsTo.stories.js +223 -223
  185. package/src/components/BaseBelongsTo.vue +184 -184
  186. package/src/components/BaseBoolean.stories.js +35 -35
  187. package/src/components/BaseBoolean.vue +26 -26
  188. package/src/components/BaseBreadcrumbs.stories.js +45 -45
  189. package/src/components/BaseBreadcrumbs.vue +98 -98
  190. package/src/components/BaseButton.stories.js +88 -88
  191. package/src/components/BaseButton.vue +39 -39
  192. package/src/components/BaseButtonGroup.stories.js +85 -85
  193. package/src/components/BaseButtonGroup.vue +147 -147
  194. package/src/components/BaseCard.stories.js +61 -61
  195. package/src/components/BaseCard.vue +49 -49
  196. package/src/components/BaseCardRow.vue +34 -34
  197. package/src/components/BaseCharacterCounter.stories.js +30 -30
  198. package/src/components/BaseCharacterCounter.vue +61 -61
  199. package/src/components/BaseClickOutside.vue +37 -37
  200. package/src/components/BaseClipboard.stories.js +31 -31
  201. package/src/components/BaseClipboard.vue +96 -96
  202. package/src/components/BaseColor.stories.js +46 -46
  203. package/src/components/BaseColor.vue +151 -151
  204. package/src/components/BaseContainer.stories.js +34 -34
  205. package/src/components/BaseContainer.vue +50 -50
  206. package/src/components/BaseCounter.stories.js +47 -47
  207. package/src/components/BaseCounter.vue +82 -82
  208. package/src/components/BaseCropper.stories.js +113 -113
  209. package/src/components/BaseCropper.vue +446 -446
  210. package/src/components/BaseCropperModal.stories.js +54 -54
  211. package/src/components/BaseCropperModal.vue +140 -140
  212. package/src/components/BaseDataIterator.stories.js +197 -197
  213. package/src/components/BaseDataIterator.vue +784 -777
  214. package/src/components/BaseDataIteratorSectionBox.vue +33 -33
  215. package/src/components/BaseDataIteratorSectionButton.vue +40 -40
  216. package/src/components/BaseDataIteratorSectionColumns.vue +67 -67
  217. package/src/components/BaseDataIteratorSectionModal.vue +41 -41
  218. package/src/components/BaseDataTable.stories.js +341 -341
  219. package/src/components/BaseDataTable.vue +724 -724
  220. package/src/components/BaseDataTableRowAction.vue +28 -28
  221. package/src/components/BaseDatePicker.stories.js +130 -130
  222. package/src/components/BaseDatePicker.vue +374 -374
  223. package/src/components/BaseDateSelect.stories.js +47 -47
  224. package/src/components/BaseDateSelect.vue +209 -209
  225. package/src/components/BaseDescriptionList.stories.js +35 -35
  226. package/src/components/BaseDescriptionList.vue +13 -13
  227. package/src/components/BaseDescriptionListItem.vue +47 -47
  228. package/src/components/BaseDialog.stories.js +51 -51
  229. package/src/components/BaseDialog.vue +119 -119
  230. package/src/components/BaseDisplayRelativeTime.stories.js +59 -59
  231. package/src/components/BaseDisplayRelativeTime.vue +120 -120
  232. package/src/components/BaseDraggable.vue +71 -71
  233. package/src/components/BaseDropdown.stories.js +210 -210
  234. package/src/components/BaseDropdown.vue +269 -269
  235. package/src/components/BaseDropdownAutocomplete.stories.js +187 -187
  236. package/src/components/BaseDropdownAutocomplete.vue +230 -230
  237. package/src/components/BaseField.vue +109 -109
  238. package/src/components/BaseFieldI18n.stories.js +38 -38
  239. package/src/components/BaseFieldI18n.vue +162 -162
  240. package/src/components/BaseFilePicker.stories.js +78 -78
  241. package/src/components/BaseFilePicker.vue +132 -132
  242. package/src/components/BaseFilePickerCrop.stories.js +134 -134
  243. package/src/components/BaseFilePickerCrop.vue +127 -127
  244. package/src/components/BaseFileUploader.stories.js +84 -84
  245. package/src/components/BaseFileUploader.vue +163 -163
  246. package/src/components/BaseForm.stories.js +48 -48
  247. package/src/components/BaseForm.vue +323 -323
  248. package/src/components/BaseHasMany.stories.js +189 -189
  249. package/src/components/BaseHasMany.vue +125 -125
  250. package/src/components/BaseHeader.stories.js +127 -127
  251. package/src/components/BaseHeader.vue +188 -188
  252. package/src/components/BaseIconPicker.stories.js +22 -22
  253. package/src/components/BaseIconPicker.vue +215 -215
  254. package/src/components/BaseInput.stories.js +151 -151
  255. package/src/components/BaseInput.vue +266 -266
  256. package/src/components/BaseInputError.vue +7 -7
  257. package/src/components/BaseInputLabel.stories.js +36 -36
  258. package/src/components/BaseInputLabel.vue +72 -72
  259. package/src/components/BaseInputPercent.stories.js +50 -50
  260. package/src/components/BaseInputPercent.vue +123 -123
  261. package/src/components/BaseLayoutNotificationDropdown.vue +144 -144
  262. package/src/components/BaseLayoutNotificationItem.vue +43 -43
  263. package/src/components/BaseLayoutNotificationItemContent.vue +27 -27
  264. package/src/components/BaseLayoutSidebar.vue +219 -219
  265. package/src/components/BaseLayoutSidebarConfigurable.stories.js +166 -166
  266. package/src/components/BaseLayoutSidebarConfigurable.vue +167 -167
  267. package/src/components/BaseLayoutStacked.vue +52 -52
  268. package/src/components/BaseLayoutStackedConfigurable.stories.js +109 -109
  269. package/src/components/BaseLayoutStackedConfigurable.vue +141 -141
  270. package/src/components/BaseLoadingCover.stories.js +55 -55
  271. package/src/components/BaseLoadingCover.vue +94 -94
  272. package/src/components/BaseMediaGallery.vue +93 -93
  273. package/src/components/BaseMediaGalleryItem.vue +92 -92
  274. package/src/components/BaseMediaItem.stories.js +41 -41
  275. package/src/components/BaseMediaItem.vue +71 -71
  276. package/src/components/BaseMediaLibrary.stories.js +262 -262
  277. package/src/components/BaseMediaLibrary.vue +313 -313
  278. package/src/components/BaseMediaList.vue +68 -68
  279. package/src/components/BaseMediaListItem.vue +172 -172
  280. package/src/components/BaseMediaPictures.vue +64 -64
  281. package/src/components/BaseMediaPicturesItem.vue +94 -94
  282. package/src/components/BaseMediaPreview.stories.js +72 -72
  283. package/src/components/BaseMediaPreview.vue +106 -106
  284. package/src/components/BaseMenu.stories.js +125 -125
  285. package/src/components/BaseMenu.vue +129 -129
  286. package/src/components/BaseMenuItem.vue +107 -107
  287. package/src/components/BaseModalCenter.stories.js +68 -68
  288. package/src/components/BaseModalCenter.vue +125 -125
  289. package/src/components/BaseModalSide.stories.js +55 -55
  290. package/src/components/BaseModalSide.vue +116 -116
  291. package/src/components/BaseNavbar.stories.js +151 -151
  292. package/src/components/BaseNavbar.vue +91 -91
  293. package/src/components/BaseNavbarItem.vue +49 -49
  294. package/src/components/BaseNavbarItemContent.vue +86 -86
  295. package/src/components/BaseNavbarSideItem.vue +111 -111
  296. package/src/components/BaseNavbarSideItemContent.vue +104 -104
  297. package/src/components/BaseNumber.stories.js +66 -66
  298. package/src/components/BaseNumber.vue +366 -366
  299. package/src/components/BasePagination.stories.js +35 -35
  300. package/src/components/BasePagination.vue +266 -266
  301. package/src/components/BasePanel.stories.js +56 -56
  302. package/src/components/BasePanel.vue +39 -39
  303. package/src/components/BasePassword.stories.js +41 -41
  304. package/src/components/BasePassword.vue +88 -88
  305. package/src/components/BaseProgressCircle.stories.js +27 -27
  306. package/src/components/BaseProgressCircle.vue +77 -77
  307. package/src/components/BaseRadioGroup.stories.js +88 -88
  308. package/src/components/BaseRadioGroup.vue +122 -122
  309. package/src/components/BaseReadMore.stories.js +30 -30
  310. package/src/components/BaseReadMore.vue +73 -73
  311. package/src/components/BaseRichText.stories.js +102 -102
  312. package/src/components/BaseRichText.vue +183 -183
  313. package/src/components/BaseSelect.stories.js +118 -118
  314. package/src/components/BaseSelect.vue +220 -220
  315. package/src/components/BaseShortcut.stories.js +102 -102
  316. package/src/components/BaseShortcut.vue +105 -105
  317. package/src/components/BaseSideNavigation.stories.js +80 -80
  318. package/src/components/BaseSideNavigation.vue +29 -29
  319. package/src/components/BaseSideNavigationItem.vue +92 -92
  320. package/src/components/BaseSkeleton.stories.js +36 -36
  321. package/src/components/BaseSkeleton.vue +24 -24
  322. package/src/components/BaseStatistic.stories.js +51 -51
  323. package/src/components/BaseStatistic.vue +98 -98
  324. package/src/components/BaseStepper.stories.js +94 -94
  325. package/src/components/BaseStepper.vue +69 -69
  326. package/src/components/BaseStepperItem.stories.js +65 -65
  327. package/src/components/BaseStepperItem.vue +149 -149
  328. package/src/components/BaseSwitch.stories.js +131 -131
  329. package/src/components/BaseSwitch.vue +209 -209
  330. package/src/components/BaseSystemAlert.stories.js +63 -63
  331. package/src/components/BaseSystemAlert.vue +86 -86
  332. package/src/components/BaseTabItem.vue +93 -93
  333. package/src/components/BaseTable.vue +880 -880
  334. package/src/components/BaseTableColumn.vue +124 -124
  335. package/src/components/BaseTabs.stories.js +85 -85
  336. package/src/components/BaseTabs.vue +73 -73
  337. package/src/components/BaseTagAutocomplete.stories.js +258 -258
  338. package/src/components/BaseTagAutocomplete.vue +428 -428
  339. package/src/components/BaseTagAutocompleteFetch.stories.js +185 -185
  340. package/src/components/BaseTagAutocompleteFetch.vue +206 -206
  341. package/src/components/BaseTextarea.stories.js +43 -43
  342. package/src/components/BaseTextarea.vue +87 -87
  343. package/src/components/BaseTextareaAutoresize.stories.js +58 -58
  344. package/src/components/BaseTextareaAutoresize.vue +140 -140
  345. package/src/components/BaseTimeline.stories.js +53 -53
  346. package/src/components/BaseTimeline.vue +29 -29
  347. package/src/components/BaseTimelineItem.stories.js +78 -78
  348. package/src/components/BaseTimelineItem.vue +79 -79
  349. package/src/components/SlotComponent.ts +37 -37
  350. package/src/components/index.ts +188 -188
  351. package/src/composables/breakpoints.ts +94 -94
  352. package/src/composables/clickOutside.ts +80 -80
  353. package/src/composables/field.ts +117 -117
  354. package/src/composables/hasOptions.ts +68 -68
  355. package/src/composables/mediaQuery.ts +42 -42
  356. package/src/composables/modal.ts +73 -73
  357. package/src/composables/paginatedData.ts +65 -65
  358. package/src/constants/MyConstants.ts +1 -1
  359. package/src/constants/index.ts +5 -5
  360. package/src/env.d.ts +15 -15
  361. package/src/i18n/index.ts +60 -60
  362. package/src/index.ts +111 -111
  363. package/src/lang/en.json +87 -87
  364. package/src/lang/fr.json +87 -87
  365. package/src/stores/dialogs.ts +45 -45
  366. package/src/stores/i18n.ts +14 -14
  367. package/src/stores/notifications.ts +47 -47
  368. package/src/stores/systemAlerts.ts +33 -33
  369. package/src/svg/BaseEmptyState.vue +34 -34
  370. package/src/svg/BaseSpinnerLarge.vue +47 -47
  371. package/src/svg/BaseSpinnerSmall.vue +9 -9
  372. package/src/types/Color.ts +9 -9
  373. package/src/types/Country.ts +4 -4
  374. package/src/types/ImagePickerResult.ts +5 -5
  375. package/src/types/Media.ts +10 -10
  376. package/src/types/Notification.ts +10 -10
  377. package/src/types/Region.ts +5 -5
  378. package/src/types/Status.ts +5 -5
  379. package/src/types/StepperItem.ts +8 -8
  380. package/src/types/TimelineItem.ts +8 -8
  381. package/src/types/UploadedFile.ts +11 -11
  382. package/src/types/User.ts +7 -7
  383. package/src/types/index.ts +267 -267
  384. package/src/utils/blob.ts +30 -30
  385. package/src/utils/colors.ts +200 -200
  386. package/src/utils/cropper/avatar.ts +33 -33
  387. package/src/utils/cropper/cover.ts +41 -41
  388. package/src/utils/cropper/presetInterface.ts +16 -16
  389. package/src/utils/cropper/presets.ts +7 -7
  390. package/src/utils/fileSizeFormat.ts +15 -15
  391. package/src/utils/fileValidations.ts +26 -26
  392. package/src/utils/index.ts +16 -16
  393. package/src/utils/resizeImageFromURI.ts +118 -118
  394. package/src/utils/scrollPreventer.ts +11 -11
  395. package/src/utils/toHumanList.ts +20 -20
@@ -1,724 +1,724 @@
1
- <template>
2
- <BaseDataIterator
3
- ref="dataIterator"
4
- :url="url"
5
- :url-query="urlQuery"
6
- :default-query="defaultQuery"
7
- :searchable="searchable"
8
- :actions="actions"
9
- :history-mode="historyMode"
10
- :layout="layout"
11
- :sections="sectionsInternal"
12
- :scroll-top-on-fetch="maxHeight ? false : scrollTopOnFetch"
13
- @fetch="onFetch"
14
- @will-scroll-top="onWillScrollTop"
15
- >
16
- <template
17
- #default="{
18
- items,
19
- loading,
20
- sortField,
21
- sortDirection,
22
- onSortChange,
23
- error,
24
- firstLoad,
25
- }"
26
- >
27
- <BaseCard clipped class="w-full overflow-hidden">
28
- <div v-if="newCheckedRows.length">
29
- <div
30
- class="flex items-center justify-between border-b border-slate-200 bg-slate-50 py-2 pl-3 pr-2 text-sm"
31
- >
32
- <div>
33
- <span class="mr-3 text-slate-500"
34
- >{{
35
- t('sui.x_rows_selected', {
36
- count: newCheckedRows.length,
37
- })
38
- }}.</span
39
- >
40
- <button
41
- type="button"
42
- class="mr-3 inline text-slate-700 underline"
43
- @click="uncheckAll()"
44
- >
45
- {{ t('sui.deselect_all') }}
46
- </button>
47
- </div>
48
- <BaseMenu
49
- v-if="checkableActions?.length"
50
- menu-class="w-52"
51
- :items="checkableActions"
52
- >
53
- <template #button="{ open }">
54
- <div
55
- class="flex h-10 w-10 items-center justify-center rounded-full border border-slate-300 bg-white duration-150 hover:bg-slate-50"
56
- :class="[
57
- open ? 'ring-2 ring-primary-500 ring-offset-2' : false,
58
- ]"
59
- >
60
- <BaseIcon icon="heroicons-solid:dots-vertical" />
61
- </div>
62
- </template>
63
- </BaseMenu>
64
- </div>
65
- </div>
66
-
67
- <BaseTable
68
- ref="table"
69
- :checked-rows="newCheckedRows"
70
- :data="items"
71
- :loading="loading"
72
- :detailed="detailed"
73
- :has-detailed-visible="hasDetailedVisible"
74
- :checkable="checkable"
75
- :is-row-checkable="isRowCheckable"
76
- checkbox-position="left"
77
- :sort-field="sortField"
78
- :sort-direction="sortDirection"
79
- :max-height="maxHeight"
80
- :visible-columns="visibleColumns"
81
- @update:checked-rows="onCheckedRowsUpdate"
82
- @sort="onSortChange"
83
- @cell-click="onCellClick"
84
- >
85
- <template #default>
86
- <slot />
87
-
88
- <BaseTableColumn
89
- v-slot="{ row }"
90
- :visible="rowActionsInternal.length"
91
- :toggle="false"
92
- :clickable="false"
93
- custom-key="actions"
94
- class="overflow-hidden"
95
- >
96
- <div class="flex justify-end gap-1 pr-2 text-right">
97
- <div class="btn-group">
98
- <template
99
- v-for="rowAction in visibleRowActions"
100
- :key="rowAction.icon"
101
- >
102
- <BaseDataTableRowAction
103
- :row="row"
104
- :row-action="rowAction"
105
- ></BaseDataTableRowAction>
106
- </template>
107
- <BaseMenu
108
- v-if="showRowActionMenu"
109
- :items="rowActionMenuItems(row)"
110
- size="sm"
111
- button-class="btn flex h-8 w-8 p-0 items-center justify-center"
112
- >
113
- <template #button>
114
- <BaseIcon icon="heroicons-solid:dots-vertical" />
115
- </template>
116
- </BaseMenu>
117
- </div>
118
- </div>
119
- </BaseTableColumn>
120
- </template>
121
-
122
- <template #detail="propsDetail">
123
- <slot name="detail" v-bind="propsDetail" />
124
- </template>
125
-
126
- <template #checkedHeader="propsCheckHeader">
127
- <slot name="checkedHeader" v-bind="propsCheckHeader" />
128
- </template>
129
-
130
- <template #empty>
131
- <div v-if="error" class="flex items-center justify-center py-16">
132
- <div class="flex flex-col items-center justify-center">
133
- <BaseIcon
134
- icon="heroicons:x-circle"
135
- class="h-10 w-10 text-red-600"
136
- />
137
- <p class="mt-3 text-center text-sm text-slate-600">
138
- {{ t('sui.whoops') }}
139
- </p>
140
- </div>
141
- </div>
142
- <div
143
- v-else-if="firstLoad"
144
- class="flex items-center justify-center py-16"
145
- >
146
- <div class="flex flex-col items-center">
147
- <BaseEmptyState class="w-32"></BaseEmptyState>
148
-
149
- <p class="mt-3 text-center text-sm text-slate-600">
150
- {{ t('sui.nothing_found') }}
151
- </p>
152
- </div>
153
- </div>
154
- </template>
155
- </BaseTable>
156
- </BaseCard>
157
- </template>
158
-
159
- <template
160
- v-if="$slots.filters"
161
- #filters="{ query, updateQuery, updateQueryValue }"
162
- >
163
- <slot
164
- name="filters"
165
- :query="query"
166
- :update-query="updateQuery"
167
- :update-query-value="updateQueryValue"
168
- />
169
- </template>
170
-
171
- <template #sidebarTop="sidebarProps">
172
- <slot name="sidebarTop" v-bind="sidebarProps"></slot>
173
- </template>
174
-
175
- <template #sidebarBottom="sidebarProps">
176
- <slot name="sidebarBottom" v-bind="sidebarProps"></slot>
177
- </template>
178
-
179
- <template v-if="toggleable" #columns>
180
- <BaseDataIteratorSectionColumns
181
- v-model:visibleColumns="visibleColumns"
182
- :table="table"
183
- @update:visible-columns="onUpdateVisibleColumn"
184
- ></BaseDataIteratorSectionColumns>
185
- </template>
186
-
187
- <template v-for="section in sections" :key="section.name" #[section.name]>
188
- <slot :name="section.name" />
189
- </template>
190
- </BaseDataIterator>
191
- </template>
192
-
193
- <script lang="ts" setup>
194
- import { PropType } from 'vue';
195
- import { t } from '@/i18n';
196
- import {
197
- Collection,
198
- CollectionItem,
199
- DataIteratorSection,
200
- DataTableQuery,
201
- MenuItemInterface,
202
- PaginatedCollection,
203
- ResourceCollection,
204
- RowAction,
205
- } from '@/types';
206
- import { useDialogsStore } from '@/stores/dialogs';
207
- import { useNotificationsStore } from '../stores/notifications';
208
- import BaseDataIterator from './BaseDataIterator.vue';
209
- import { cloneDeep, isArray } from 'lodash';
210
-
211
- import BaseCard from './BaseCard.vue';
212
- import BaseTable from './BaseTable.vue';
213
- import BaseTableColumn from './BaseTableColumn.vue';
214
- import BaseDataIteratorSectionColumns from './BaseDataIteratorSectionColumns.vue';
215
- import { BaseIcon, config } from '@/index';
216
- import BaseEmptyState from '../svg/BaseEmptyState.vue';
217
- import { RouteLocationRaw } from 'vue-router';
218
- import BaseMenu from './BaseMenu.vue';
219
- import BaseDataTableRowAction from './BaseDataTableRowAction.vue';
220
-
221
- const router = useRouter();
222
-
223
- const http = config.http;
224
-
225
- const dialogs = useDialogsStore();
226
- const notifications = useNotificationsStore();
227
-
228
- const table = ref<null | InstanceType<typeof BaseTable>>(null);
229
-
230
- const props = defineProps({
231
- /**
232
- * Base URL from which to make requests
233
- */
234
- url: {
235
- required: true,
236
- type: String,
237
- },
238
-
239
- /**
240
- * Query params that always get applied
241
- */
242
- urlQuery: {
243
- default: undefined,
244
- type: Object as PropType<Record<string, any>>,
245
- },
246
-
247
- /**
248
- * Query params that gets applied by default
249
- * These may be overwritten by URL params generated by the data-table or filters
250
- */
251
- defaultQuery: {
252
- default: undefined,
253
- type: Object as PropType<DataTableQuery>,
254
- },
255
-
256
- /**
257
- * Show url for router link
258
- */
259
- showUrl: {
260
- default: undefined,
261
- type: Function as PropType<
262
- ((row: CollectionItem) => RouteLocationRaw) | undefined
263
- >,
264
- },
265
-
266
- /**
267
- * Show/Hide edit button
268
- */
269
- editButton: {
270
- default: true,
271
- type: Boolean,
272
- },
273
-
274
- /**
275
- * Edit url for router link
276
- */
277
- editUrl: {
278
- default: undefined,
279
- type: Function as PropType<
280
- ((row: CollectionItem) => RouteLocationRaw) | undefined
281
- >,
282
- },
283
-
284
- /**
285
- * Show/Hide delete button
286
- */
287
- deleteButton: {
288
- default: true,
289
- type: Boolean,
290
- },
291
-
292
- /**
293
- * Delete endpoint to delete an item
294
- */
295
- deleteUrl: {
296
- default: undefined,
297
- type: Function as PropType<((row: CollectionItem) => string) | undefined>,
298
- },
299
-
300
- /**
301
- * Show toggle-able details on each row
302
- */
303
- detailed: {
304
- default: false,
305
- type: Boolean,
306
- },
307
-
308
- /**
309
- * Check is a given row has details
310
- */
311
- hasDetailedVisible: {
312
- default() {
313
- return true;
314
- },
315
- type: Function as PropType<(row: any) => boolean>,
316
- },
317
-
318
- /**
319
- * Makes row checkable
320
- */
321
- checkable: {
322
- default: false,
323
- type: Boolean,
324
- },
325
-
326
- /**
327
- * Actions on each row
328
- */
329
- checkableActions: {
330
- default: undefined,
331
- type: Array as PropType<MenuItemInterface[]>,
332
- },
333
-
334
- /**
335
- * Checked rows array
336
- */
337
- checkedRows: {
338
- default() {
339
- return [];
340
- },
341
- type: Array as PropType<Record<string, any>[]>,
342
- },
343
-
344
- /**
345
- * Check is a given row is checkable
346
- */
347
- isRowCheckable: {
348
- default() {
349
- return () => true;
350
- },
351
- type: Function,
352
- },
353
-
354
- /**
355
- * Adds a search bar
356
- */
357
- searchable: {
358
- default: true,
359
- type: Boolean,
360
- },
361
-
362
- /**
363
- * Shows the column toggle utility
364
- */
365
- toggleable: {
366
- default: true,
367
- type: Boolean,
368
- },
369
-
370
- /**
371
- * Actions
372
- */
373
- actions: {
374
- default: undefined,
375
- type: Array as PropType<MenuItemInterface[]>,
376
- },
377
-
378
- /**
379
- * Save data table state in URL
380
- */
381
- historyMode: {
382
- default: false,
383
- type: Boolean,
384
- },
385
-
386
- /*
387
- * Max height (in px)
388
- */
389
- maxHeight: {
390
- default: undefined,
391
- type: Number,
392
- },
393
-
394
- /**
395
- * Layout type
396
- */
397
- layout: {
398
- default: 'default',
399
- type: String as PropType<'default' | 'compact'>,
400
- },
401
-
402
- sections: {
403
- default: undefined,
404
- type: Array as PropType<DataIteratorSection[]>,
405
- },
406
-
407
- rowActions: {
408
- default: undefined,
409
- type: Array as PropType<RowAction[]>,
410
- },
411
-
412
- numberOfVisibleRowActions: {
413
- default: 2,
414
- type: Number,
415
- },
416
-
417
- /**
418
- * Scroll to top when fetching new data
419
- */
420
- scrollTopOnFetch: {
421
- default: true,
422
- type: Boolean,
423
- },
424
- });
425
-
426
- const emit = defineEmits([
427
- 'cell-click',
428
- 'delete',
429
- 'update:checked-rows',
430
- 'fetch',
431
- ]);
432
-
433
- const dataIterator = ref<null | InstanceType<typeof BaseDataIterator>>(null);
434
-
435
- /*
436
- |--------------------------------------------------------------------------
437
- | Handlers
438
- |--------------------------------------------------------------------------
439
- */
440
-
441
- function onCellClick(payload: CollectionItem) {
442
- if (props.showUrl) {
443
- router.push(props.showUrl(payload));
444
- }
445
- emit('cell-click', payload);
446
- }
447
-
448
- /*
449
- |--------------------------------------------------------------------------
450
- | Gate helpers
451
- |--------------------------------------------------------------------------
452
- */
453
-
454
- const gate = (row: CollectionItem, action: string): boolean => {
455
- if (row.can && Object.prototype.hasOwnProperty.call(row.can, action)) {
456
- return row.can[action];
457
- }
458
- return true;
459
- };
460
-
461
- const canUpdate = (row: CollectionItem): boolean => {
462
- return gate(row, 'update');
463
- };
464
-
465
- const canDelete = (row: CollectionItem): boolean => {
466
- return gate(row, 'delete');
467
- };
468
-
469
- function onDeleteClick(row: CollectionItem) {
470
- dialogs.push({
471
- title: t('sui.delete_record') + '?',
472
- message: t('sui.delete_record_description'),
473
- color: 'danger',
474
- closeOnOutsideClick: true,
475
- confirmText: t('sui.yes_delete'),
476
- onConfirm: () => onDelete(row),
477
- });
478
- }
479
-
480
- const onDelete = (row: CollectionItem) => {
481
- if (!props.deleteUrl) {
482
- return;
483
- }
484
-
485
- http
486
- .delete(props.deleteUrl(row))
487
- .then((response) => {
488
- if (response.data && response.data.message) {
489
- notifications.push({
490
- title: t('sui.success'),
491
- text: response.data.message,
492
- color: 'success',
493
- });
494
- }
495
- emit('delete', row);
496
-
497
- // Refetch even if URL is the same
498
- fetch();
499
- })
500
- .catch((error) => {
501
- notifications.push({
502
- title: t('sui.error'),
503
- text: error.response.data?.message ?? 'Unknown error',
504
- color: 'danger',
505
- });
506
- });
507
- };
508
-
509
- /*
510
- |--------------------------------------------------------------------------
511
- | Toggle columns
512
- |--------------------------------------------------------------------------
513
- */
514
-
515
- const visibleColumns = ref<number[]>([]);
516
-
517
- // Find visible columns in local storage
518
- const VISIBLE_COLUMNS_LOCAL_STORAGE = 'sprintify.visible_columns.';
519
- const VISIBLE_COLUMNS_LOCAL_STORAGE_KEY =
520
- VISIBLE_COLUMNS_LOCAL_STORAGE + window.location.pathname;
521
-
522
- const visibleColumnsFromStorage = JSON.parse(
523
- localStorage.getItem(VISIBLE_COLUMNS_LOCAL_STORAGE_KEY) + ''
524
- ) as number[];
525
-
526
- // If found, set visibleColumns
527
- if (
528
- visibleColumnsFromStorage &&
529
- isArray(visibleColumnsFromStorage) &&
530
- visibleColumnsFromStorage.length > 0
531
- ) {
532
- visibleColumns.value = visibleColumnsFromStorage;
533
- }
534
-
535
- // If nothing is found, set visibleColumns to all columns from table
536
- const unWatchTable = watch(
537
- () => table.value,
538
- () => {
539
- if (
540
- table.value &&
541
- table.value.newColumns.length &&
542
- visibleColumns.value.length == 0
543
- ) {
544
- visibleColumns.value = table.value.newColumns
545
- .filter((c) => c.toggle)
546
- .filter((c) => c.toggleDefault ?? true)
547
- .map((c) => c.newKey);
548
-
549
- unWatchTable();
550
- }
551
- }
552
- );
553
-
554
- /**
555
- * Update local storage when check input update
556
- */
557
- function onUpdateVisibleColumn() {
558
- localStorage.setItem(
559
- VISIBLE_COLUMNS_LOCAL_STORAGE_KEY,
560
- JSON.stringify(visibleColumns.value)
561
- );
562
- }
563
-
564
- /*
565
- |--------------------------------------------------------------------------
566
- | Row Actions
567
- |--------------------------------------------------------------------------
568
- */
569
-
570
- const rowActionsInternal = computed<RowAction[]>(() => {
571
- const actions = cloneDeep(props.rowActions) ?? [];
572
-
573
- if (props.editUrl && props.editButton) {
574
- actions.push({
575
- label: t('sui.edit'),
576
- icon: 'heroicons:cog-6-tooth-solid',
577
- to: (row: CollectionItem) => (props.editUrl ? props.editUrl(row) : ''),
578
- disabled: (row: CollectionItem) => !canUpdate(row),
579
- });
580
- }
581
-
582
- if (props.deleteUrl && props.deleteButton) {
583
- actions.push({
584
- label: t('sui.delete'),
585
- icon: 'heroicons:trash-20-solid',
586
- action: onDeleteClick,
587
- disabled: (row: CollectionItem) => !canDelete(row),
588
- });
589
- }
590
-
591
- return actions;
592
- });
593
-
594
- const visibleRowActions = computed<RowAction[]>(() => {
595
- return rowActionsInternal.value.slice(0, props.numberOfVisibleRowActions);
596
- });
597
-
598
- const showRowActionMenu = computed<boolean>(() => {
599
- return rowActionsInternal.value.length > props.numberOfVisibleRowActions;
600
- });
601
-
602
- function rowActionMenuItems(row: CollectionItem): MenuItemInterface[] {
603
- return rowActionsInternal.value.map((action) => {
604
- return {
605
- label: action.label,
606
- icon: action.icon,
607
- disabled: action.disabled && action.disabled(row),
608
- action: action.action
609
- ? () => {
610
- if (action.action) action.action(row);
611
- }
612
- : undefined,
613
- to: action.to ? action.to(row) : undefined,
614
- };
615
- });
616
- }
617
-
618
- /*
619
- |--------------------------------------------------------------------------
620
- | Checkable
621
- |--------------------------------------------------------------------------
622
- */
623
-
624
- const newCheckedRows = ref<Record<string, any>[]>([]);
625
-
626
- watch(
627
- () => props.checkedRows,
628
- (checkedRows) => {
629
- newCheckedRows.value = checkedRows;
630
- }
631
- );
632
-
633
- function uncheckAll() {
634
- table.value?.uncheckAll();
635
- }
636
-
637
- const sectionsInternal = computed<DataIteratorSection[]>(() => {
638
- const sections = props.sections ?? [];
639
-
640
- if (props.toggleable) {
641
- return [
642
- ...sections,
643
- {
644
- name: 'columns',
645
- icon: 'heroicons:table-cells-20-solid',
646
- title: t('sui.columns'),
647
- closeText: t('sui.apply'),
648
- opened: false,
649
- },
650
- ];
651
- }
652
-
653
- return sections;
654
- });
655
-
656
- function onCheckedRowsUpdate(checkedRows: Record<string, any>[]) {
657
- newCheckedRows.value = checkedRows;
658
- emit('update:checked-rows', checkedRows);
659
- }
660
-
661
- /*
662
- |--------------------------------------------------------------------------
663
- | Scrolling behavior
664
- |--------------------------------------------------------------------------
665
- */
666
-
667
- function onWillScrollTop() {
668
- if (!props.scrollTopOnFetch) {
669
- return;
670
- }
671
-
672
- if (props.maxHeight) {
673
- table.value?.scrollTop();
674
-
675
- const top = dataIterator.value?.$el?.getBoundingClientRect()?.top ?? 0;
676
-
677
- if (top < 0) {
678
- dataIterator.value?.scrollIntoView();
679
- }
680
- }
681
- }
682
-
683
- /*
684
- |--------------------------------------------------------------------------
685
- | On fetch
686
- |--------------------------------------------------------------------------
687
- */
688
-
689
- function onFetch(
690
- payload: null | ResourceCollection | PaginatedCollection | Collection
691
- ) {
692
- emit('fetch', payload);
693
- }
694
-
695
- /*
696
- |--------------------------------------------------------------------------
697
- | Exposed functions
698
- |--------------------------------------------------------------------------
699
- */
700
-
701
- function fetch() {
702
- if (!dataIterator.value) {
703
- return;
704
- }
705
- dataIterator.value.fetch();
706
- }
707
-
708
- function fetchWithoutLoading() {
709
- if (!dataIterator.value) {
710
- return;
711
- }
712
- dataIterator.value.fetchWithoutLoading();
713
- }
714
-
715
- const dataIteratorQuery = computed((): DataTableQuery | null => {
716
- return dataIterator.value?.query ?? null;
717
- });
718
-
719
- defineExpose({
720
- fetch,
721
- fetchWithoutLoading,
722
- query: dataIteratorQuery,
723
- });
724
- </script>
1
+ <template>
2
+ <BaseDataIterator
3
+ ref="dataIterator"
4
+ :url="url"
5
+ :url-query="urlQuery"
6
+ :default-query="defaultQuery"
7
+ :searchable="searchable"
8
+ :actions="actions"
9
+ :history-mode="historyMode"
10
+ :layout="layout"
11
+ :sections="sectionsInternal"
12
+ :scroll-top-on-fetch="maxHeight ? false : scrollTopOnFetch"
13
+ @fetch="onFetch"
14
+ @will-scroll-top="onWillScrollTop"
15
+ >
16
+ <template
17
+ #default="{
18
+ items,
19
+ loading,
20
+ sortField,
21
+ sortDirection,
22
+ onSortChange,
23
+ error,
24
+ firstLoad,
25
+ }"
26
+ >
27
+ <BaseCard clipped class="w-full overflow-hidden">
28
+ <div v-if="newCheckedRows.length">
29
+ <div
30
+ class="flex items-center justify-between border-b border-slate-200 bg-slate-50 py-2 pl-3 pr-2 text-sm"
31
+ >
32
+ <div>
33
+ <span class="mr-3 text-slate-500"
34
+ >{{
35
+ t('sui.x_rows_selected', {
36
+ count: newCheckedRows.length,
37
+ })
38
+ }}.</span
39
+ >
40
+ <button
41
+ type="button"
42
+ class="mr-3 inline text-slate-700 underline"
43
+ @click="uncheckAll()"
44
+ >
45
+ {{ t('sui.deselect_all') }}
46
+ </button>
47
+ </div>
48
+ <BaseMenu
49
+ v-if="checkableActions?.length"
50
+ menu-class="w-52"
51
+ :items="checkableActions"
52
+ >
53
+ <template #button="{ open }">
54
+ <div
55
+ class="flex h-10 w-10 items-center justify-center rounded-full border border-slate-300 bg-white duration-150 hover:bg-slate-50"
56
+ :class="[
57
+ open ? 'ring-2 ring-primary-500 ring-offset-2' : false,
58
+ ]"
59
+ >
60
+ <BaseIcon icon="heroicons-solid:dots-vertical" />
61
+ </div>
62
+ </template>
63
+ </BaseMenu>
64
+ </div>
65
+ </div>
66
+
67
+ <BaseTable
68
+ ref="table"
69
+ :checked-rows="newCheckedRows"
70
+ :data="items"
71
+ :loading="loading"
72
+ :detailed="detailed"
73
+ :has-detailed-visible="hasDetailedVisible"
74
+ :checkable="checkable"
75
+ :is-row-checkable="isRowCheckable"
76
+ checkbox-position="left"
77
+ :sort-field="sortField"
78
+ :sort-direction="sortDirection"
79
+ :max-height="maxHeight"
80
+ :visible-columns="visibleColumns"
81
+ @update:checked-rows="onCheckedRowsUpdate"
82
+ @sort="onSortChange"
83
+ @cell-click="onCellClick"
84
+ >
85
+ <template #default>
86
+ <slot />
87
+
88
+ <BaseTableColumn
89
+ v-slot="{ row }"
90
+ :visible="rowActionsInternal.length"
91
+ :toggle="false"
92
+ :clickable="false"
93
+ custom-key="actions"
94
+ class="overflow-hidden"
95
+ >
96
+ <div class="flex justify-end gap-1 pr-2 text-right">
97
+ <div class="btn-group">
98
+ <template
99
+ v-for="rowAction in visibleRowActions"
100
+ :key="rowAction.icon"
101
+ >
102
+ <BaseDataTableRowAction
103
+ :row="row"
104
+ :row-action="rowAction"
105
+ ></BaseDataTableRowAction>
106
+ </template>
107
+ <BaseMenu
108
+ v-if="showRowActionMenu"
109
+ :items="rowActionMenuItems(row)"
110
+ size="sm"
111
+ button-class="btn flex h-8 w-8 p-0 items-center justify-center"
112
+ >
113
+ <template #button>
114
+ <BaseIcon icon="heroicons-solid:dots-vertical" />
115
+ </template>
116
+ </BaseMenu>
117
+ </div>
118
+ </div>
119
+ </BaseTableColumn>
120
+ </template>
121
+
122
+ <template #detail="propsDetail">
123
+ <slot name="detail" v-bind="propsDetail" />
124
+ </template>
125
+
126
+ <template #checkedHeader="propsCheckHeader">
127
+ <slot name="checkedHeader" v-bind="propsCheckHeader" />
128
+ </template>
129
+
130
+ <template #empty>
131
+ <div v-if="error" class="flex items-center justify-center py-16">
132
+ <div class="flex flex-col items-center justify-center">
133
+ <BaseIcon
134
+ icon="heroicons:x-circle"
135
+ class="h-10 w-10 text-red-600"
136
+ />
137
+ <p class="mt-3 text-center text-sm text-slate-600">
138
+ {{ t('sui.whoops') }}
139
+ </p>
140
+ </div>
141
+ </div>
142
+ <div
143
+ v-else-if="firstLoad"
144
+ class="flex items-center justify-center py-16"
145
+ >
146
+ <div class="flex flex-col items-center">
147
+ <BaseEmptyState class="w-32"></BaseEmptyState>
148
+
149
+ <p class="mt-3 text-center text-sm text-slate-600">
150
+ {{ t('sui.nothing_found') }}
151
+ </p>
152
+ </div>
153
+ </div>
154
+ </template>
155
+ </BaseTable>
156
+ </BaseCard>
157
+ </template>
158
+
159
+ <template
160
+ v-if="$slots.filters"
161
+ #filters="{ query, updateQuery, updateQueryValue }"
162
+ >
163
+ <slot
164
+ name="filters"
165
+ :query="query"
166
+ :update-query="updateQuery"
167
+ :update-query-value="updateQueryValue"
168
+ />
169
+ </template>
170
+
171
+ <template #sidebarTop="sidebarProps">
172
+ <slot name="sidebarTop" v-bind="sidebarProps"></slot>
173
+ </template>
174
+
175
+ <template #sidebarBottom="sidebarProps">
176
+ <slot name="sidebarBottom" v-bind="sidebarProps"></slot>
177
+ </template>
178
+
179
+ <template v-if="toggleable" #columns>
180
+ <BaseDataIteratorSectionColumns
181
+ v-model:visibleColumns="visibleColumns"
182
+ :table="table"
183
+ @update:visible-columns="onUpdateVisibleColumn"
184
+ ></BaseDataIteratorSectionColumns>
185
+ </template>
186
+
187
+ <template v-for="section in sections" :key="section.name" #[section.name]>
188
+ <slot :name="section.name" />
189
+ </template>
190
+ </BaseDataIterator>
191
+ </template>
192
+
193
+ <script lang="ts" setup>
194
+ import { PropType } from 'vue';
195
+ import { t } from '@/i18n';
196
+ import {
197
+ Collection,
198
+ CollectionItem,
199
+ DataIteratorSection,
200
+ DataTableQuery,
201
+ MenuItemInterface,
202
+ PaginatedCollection,
203
+ ResourceCollection,
204
+ RowAction,
205
+ } from '@/types';
206
+ import { useDialogsStore } from '@/stores/dialogs';
207
+ import { useNotificationsStore } from '../stores/notifications';
208
+ import BaseDataIterator from './BaseDataIterator.vue';
209
+ import { cloneDeep, isArray } from 'lodash';
210
+
211
+ import BaseCard from './BaseCard.vue';
212
+ import BaseTable from './BaseTable.vue';
213
+ import BaseTableColumn from './BaseTableColumn.vue';
214
+ import BaseDataIteratorSectionColumns from './BaseDataIteratorSectionColumns.vue';
215
+ import { BaseIcon, config } from '@/index';
216
+ import BaseEmptyState from '../svg/BaseEmptyState.vue';
217
+ import { RouteLocationRaw } from 'vue-router';
218
+ import BaseMenu from './BaseMenu.vue';
219
+ import BaseDataTableRowAction from './BaseDataTableRowAction.vue';
220
+
221
+ const router = useRouter();
222
+
223
+ const http = config.http;
224
+
225
+ const dialogs = useDialogsStore();
226
+ const notifications = useNotificationsStore();
227
+
228
+ const table = ref<null | InstanceType<typeof BaseTable>>(null);
229
+
230
+ const props = defineProps({
231
+ /**
232
+ * Base URL from which to make requests
233
+ */
234
+ url: {
235
+ required: true,
236
+ type: String,
237
+ },
238
+
239
+ /**
240
+ * Query params that always get applied
241
+ */
242
+ urlQuery: {
243
+ default: undefined,
244
+ type: Object as PropType<Record<string, any>>,
245
+ },
246
+
247
+ /**
248
+ * Query params that gets applied by default
249
+ * These may be overwritten by URL params generated by the data-table or filters
250
+ */
251
+ defaultQuery: {
252
+ default: undefined,
253
+ type: Object as PropType<DataTableQuery>,
254
+ },
255
+
256
+ /**
257
+ * Show url for router link
258
+ */
259
+ showUrl: {
260
+ default: undefined,
261
+ type: Function as PropType<
262
+ ((row: CollectionItem) => RouteLocationRaw) | undefined
263
+ >,
264
+ },
265
+
266
+ /**
267
+ * Show/Hide edit button
268
+ */
269
+ editButton: {
270
+ default: true,
271
+ type: Boolean,
272
+ },
273
+
274
+ /**
275
+ * Edit url for router link
276
+ */
277
+ editUrl: {
278
+ default: undefined,
279
+ type: Function as PropType<
280
+ ((row: CollectionItem) => RouteLocationRaw) | undefined
281
+ >,
282
+ },
283
+
284
+ /**
285
+ * Show/Hide delete button
286
+ */
287
+ deleteButton: {
288
+ default: true,
289
+ type: Boolean,
290
+ },
291
+
292
+ /**
293
+ * Delete endpoint to delete an item
294
+ */
295
+ deleteUrl: {
296
+ default: undefined,
297
+ type: Function as PropType<((row: CollectionItem) => string) | undefined>,
298
+ },
299
+
300
+ /**
301
+ * Show toggle-able details on each row
302
+ */
303
+ detailed: {
304
+ default: false,
305
+ type: Boolean,
306
+ },
307
+
308
+ /**
309
+ * Check is a given row has details
310
+ */
311
+ hasDetailedVisible: {
312
+ default() {
313
+ return true;
314
+ },
315
+ type: Function as PropType<(row: any) => boolean>,
316
+ },
317
+
318
+ /**
319
+ * Makes row checkable
320
+ */
321
+ checkable: {
322
+ default: false,
323
+ type: Boolean,
324
+ },
325
+
326
+ /**
327
+ * Actions on each row
328
+ */
329
+ checkableActions: {
330
+ default: undefined,
331
+ type: Array as PropType<MenuItemInterface[]>,
332
+ },
333
+
334
+ /**
335
+ * Checked rows array
336
+ */
337
+ checkedRows: {
338
+ default() {
339
+ return [];
340
+ },
341
+ type: Array as PropType<Record<string, any>[]>,
342
+ },
343
+
344
+ /**
345
+ * Check is a given row is checkable
346
+ */
347
+ isRowCheckable: {
348
+ default() {
349
+ return () => true;
350
+ },
351
+ type: Function,
352
+ },
353
+
354
+ /**
355
+ * Adds a search bar
356
+ */
357
+ searchable: {
358
+ default: true,
359
+ type: Boolean,
360
+ },
361
+
362
+ /**
363
+ * Shows the column toggle utility
364
+ */
365
+ toggleable: {
366
+ default: true,
367
+ type: Boolean,
368
+ },
369
+
370
+ /**
371
+ * Actions
372
+ */
373
+ actions: {
374
+ default: undefined,
375
+ type: Array as PropType<MenuItemInterface[]>,
376
+ },
377
+
378
+ /**
379
+ * Save data table state in URL
380
+ */
381
+ historyMode: {
382
+ default: false,
383
+ type: Boolean,
384
+ },
385
+
386
+ /*
387
+ * Max height (in px)
388
+ */
389
+ maxHeight: {
390
+ default: undefined,
391
+ type: Number,
392
+ },
393
+
394
+ /**
395
+ * Layout type
396
+ */
397
+ layout: {
398
+ default: 'default',
399
+ type: String as PropType<'default' | 'compact'>,
400
+ },
401
+
402
+ sections: {
403
+ default: undefined,
404
+ type: Array as PropType<DataIteratorSection[]>,
405
+ },
406
+
407
+ rowActions: {
408
+ default: undefined,
409
+ type: Array as PropType<RowAction[]>,
410
+ },
411
+
412
+ numberOfVisibleRowActions: {
413
+ default: 2,
414
+ type: Number,
415
+ },
416
+
417
+ /**
418
+ * Scroll to top when fetching new data
419
+ */
420
+ scrollTopOnFetch: {
421
+ default: true,
422
+ type: Boolean,
423
+ },
424
+ });
425
+
426
+ const emit = defineEmits([
427
+ 'cell-click',
428
+ 'delete',
429
+ 'update:checked-rows',
430
+ 'fetch',
431
+ ]);
432
+
433
+ const dataIterator = ref<null | InstanceType<typeof BaseDataIterator>>(null);
434
+
435
+ /*
436
+ |--------------------------------------------------------------------------
437
+ | Handlers
438
+ |--------------------------------------------------------------------------
439
+ */
440
+
441
+ function onCellClick(payload: CollectionItem) {
442
+ if (props.showUrl) {
443
+ router.push(props.showUrl(payload));
444
+ }
445
+ emit('cell-click', payload);
446
+ }
447
+
448
+ /*
449
+ |--------------------------------------------------------------------------
450
+ | Gate helpers
451
+ |--------------------------------------------------------------------------
452
+ */
453
+
454
+ const gate = (row: CollectionItem, action: string): boolean => {
455
+ if (row.can && Object.prototype.hasOwnProperty.call(row.can, action)) {
456
+ return row.can[action];
457
+ }
458
+ return true;
459
+ };
460
+
461
+ const canUpdate = (row: CollectionItem): boolean => {
462
+ return gate(row, 'update');
463
+ };
464
+
465
+ const canDelete = (row: CollectionItem): boolean => {
466
+ return gate(row, 'delete');
467
+ };
468
+
469
+ function onDeleteClick(row: CollectionItem) {
470
+ dialogs.push({
471
+ title: t('sui.delete_record') + '?',
472
+ message: t('sui.delete_record_description'),
473
+ color: 'danger',
474
+ closeOnOutsideClick: true,
475
+ confirmText: t('sui.yes_delete'),
476
+ onConfirm: () => onDelete(row),
477
+ });
478
+ }
479
+
480
+ const onDelete = (row: CollectionItem) => {
481
+ if (!props.deleteUrl) {
482
+ return;
483
+ }
484
+
485
+ http
486
+ .delete(props.deleteUrl(row))
487
+ .then((response) => {
488
+ if (response.data && response.data.message) {
489
+ notifications.push({
490
+ title: t('sui.success'),
491
+ text: response.data.message,
492
+ color: 'success',
493
+ });
494
+ }
495
+ emit('delete', row);
496
+
497
+ // Refetch even if URL is the same
498
+ fetch();
499
+ })
500
+ .catch((error) => {
501
+ notifications.push({
502
+ title: t('sui.error'),
503
+ text: error.response.data?.message ?? 'Unknown error',
504
+ color: 'danger',
505
+ });
506
+ });
507
+ };
508
+
509
+ /*
510
+ |--------------------------------------------------------------------------
511
+ | Toggle columns
512
+ |--------------------------------------------------------------------------
513
+ */
514
+
515
+ const visibleColumns = ref<number[]>([]);
516
+
517
+ // Find visible columns in local storage
518
+ const VISIBLE_COLUMNS_LOCAL_STORAGE = 'sprintify.visible_columns.';
519
+ const VISIBLE_COLUMNS_LOCAL_STORAGE_KEY =
520
+ VISIBLE_COLUMNS_LOCAL_STORAGE + window.location.pathname;
521
+
522
+ const visibleColumnsFromStorage = JSON.parse(
523
+ localStorage.getItem(VISIBLE_COLUMNS_LOCAL_STORAGE_KEY) + ''
524
+ ) as number[];
525
+
526
+ // If found, set visibleColumns
527
+ if (
528
+ visibleColumnsFromStorage &&
529
+ isArray(visibleColumnsFromStorage) &&
530
+ visibleColumnsFromStorage.length > 0
531
+ ) {
532
+ visibleColumns.value = visibleColumnsFromStorage;
533
+ }
534
+
535
+ // If nothing is found, set visibleColumns to all columns from table
536
+ const unWatchTable = watch(
537
+ () => table.value,
538
+ () => {
539
+ if (
540
+ table.value &&
541
+ table.value.newColumns.length &&
542
+ visibleColumns.value.length == 0
543
+ ) {
544
+ visibleColumns.value = table.value.newColumns
545
+ .filter((c) => c.toggle)
546
+ .filter((c) => c.toggleDefault ?? true)
547
+ .map((c) => c.newKey);
548
+
549
+ unWatchTable();
550
+ }
551
+ }
552
+ );
553
+
554
+ /**
555
+ * Update local storage when check input update
556
+ */
557
+ function onUpdateVisibleColumn() {
558
+ localStorage.setItem(
559
+ VISIBLE_COLUMNS_LOCAL_STORAGE_KEY,
560
+ JSON.stringify(visibleColumns.value)
561
+ );
562
+ }
563
+
564
+ /*
565
+ |--------------------------------------------------------------------------
566
+ | Row Actions
567
+ |--------------------------------------------------------------------------
568
+ */
569
+
570
+ const rowActionsInternal = computed<RowAction[]>(() => {
571
+ const actions = cloneDeep(props.rowActions) ?? [];
572
+
573
+ if (props.editUrl && props.editButton) {
574
+ actions.push({
575
+ label: t('sui.edit'),
576
+ icon: 'heroicons:cog-6-tooth-solid',
577
+ to: (row: CollectionItem) => (props.editUrl ? props.editUrl(row) : ''),
578
+ disabled: (row: CollectionItem) => !canUpdate(row),
579
+ });
580
+ }
581
+
582
+ if (props.deleteUrl && props.deleteButton) {
583
+ actions.push({
584
+ label: t('sui.delete'),
585
+ icon: 'heroicons:trash-20-solid',
586
+ action: onDeleteClick,
587
+ disabled: (row: CollectionItem) => !canDelete(row),
588
+ });
589
+ }
590
+
591
+ return actions;
592
+ });
593
+
594
+ const visibleRowActions = computed<RowAction[]>(() => {
595
+ return rowActionsInternal.value.slice(0, props.numberOfVisibleRowActions);
596
+ });
597
+
598
+ const showRowActionMenu = computed<boolean>(() => {
599
+ return rowActionsInternal.value.length > props.numberOfVisibleRowActions;
600
+ });
601
+
602
+ function rowActionMenuItems(row: CollectionItem): MenuItemInterface[] {
603
+ return rowActionsInternal.value.map((action) => {
604
+ return {
605
+ label: action.label,
606
+ icon: action.icon,
607
+ disabled: action.disabled && action.disabled(row),
608
+ action: action.action
609
+ ? () => {
610
+ if (action.action) action.action(row);
611
+ }
612
+ : undefined,
613
+ to: action.to ? action.to(row) : undefined,
614
+ };
615
+ });
616
+ }
617
+
618
+ /*
619
+ |--------------------------------------------------------------------------
620
+ | Checkable
621
+ |--------------------------------------------------------------------------
622
+ */
623
+
624
+ const newCheckedRows = ref<Record<string, any>[]>([]);
625
+
626
+ watch(
627
+ () => props.checkedRows,
628
+ (checkedRows) => {
629
+ newCheckedRows.value = checkedRows;
630
+ }
631
+ );
632
+
633
+ function uncheckAll() {
634
+ table.value?.uncheckAll();
635
+ }
636
+
637
+ const sectionsInternal = computed<DataIteratorSection[]>(() => {
638
+ const sections = props.sections ?? [];
639
+
640
+ if (props.toggleable) {
641
+ return [
642
+ ...sections,
643
+ {
644
+ name: 'columns',
645
+ icon: 'heroicons:table-cells-20-solid',
646
+ title: t('sui.columns'),
647
+ closeText: t('sui.apply'),
648
+ opened: false,
649
+ },
650
+ ];
651
+ }
652
+
653
+ return sections;
654
+ });
655
+
656
+ function onCheckedRowsUpdate(checkedRows: Record<string, any>[]) {
657
+ newCheckedRows.value = checkedRows;
658
+ emit('update:checked-rows', checkedRows);
659
+ }
660
+
661
+ /*
662
+ |--------------------------------------------------------------------------
663
+ | Scrolling behavior
664
+ |--------------------------------------------------------------------------
665
+ */
666
+
667
+ function onWillScrollTop() {
668
+ if (!props.scrollTopOnFetch) {
669
+ return;
670
+ }
671
+
672
+ if (props.maxHeight) {
673
+ table.value?.scrollTop();
674
+
675
+ const top = dataIterator.value?.$el?.getBoundingClientRect()?.top ?? 0;
676
+
677
+ if (top < 0) {
678
+ dataIterator.value?.scrollIntoView();
679
+ }
680
+ }
681
+ }
682
+
683
+ /*
684
+ |--------------------------------------------------------------------------
685
+ | On fetch
686
+ |--------------------------------------------------------------------------
687
+ */
688
+
689
+ function onFetch(
690
+ payload: null | ResourceCollection | PaginatedCollection | Collection
691
+ ) {
692
+ emit('fetch', payload);
693
+ }
694
+
695
+ /*
696
+ |--------------------------------------------------------------------------
697
+ | Exposed functions
698
+ |--------------------------------------------------------------------------
699
+ */
700
+
701
+ function fetch() {
702
+ if (!dataIterator.value) {
703
+ return;
704
+ }
705
+ dataIterator.value.fetch();
706
+ }
707
+
708
+ function fetchWithoutLoading() {
709
+ if (!dataIterator.value) {
710
+ return;
711
+ }
712
+ dataIterator.value.fetchWithoutLoading();
713
+ }
714
+
715
+ const dataIteratorQuery = computed((): DataTableQuery | null => {
716
+ return dataIterator.value?.query ?? null;
717
+ });
718
+
719
+ defineExpose({
720
+ fetch,
721
+ fetchWithoutLoading,
722
+ query: dataIteratorQuery,
723
+ });
724
+ </script>