@dashadmin/dash-admin 1.3.24 → 1.3.26

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 (511) hide show
  1. package/dist/AppAsyncWrapper.js +30 -1
  2. package/dist/AppWrapper.js +35 -1
  3. package/dist/DASHAdmin.js +312 -1
  4. package/dist/RoutingWrapper.js +76 -1
  5. package/dist/classes/DASHStorageClass.js +15 -1
  6. package/dist/components/Input/RichTextField.js +26 -1
  7. package/dist/components/Redirect.js +56 -1
  8. package/dist/components/avatar/Avatar.js +72 -1
  9. package/dist/components/avatar/SingleImageUploader.js +46 -1
  10. package/dist/components/currency/Format.js +71 -1
  11. package/dist/components/custom/Redirect.js +20 -1
  12. package/dist/components/error/Error.js +161 -1
  13. package/dist/components/geocoding/GeocodingField.js +133 -1
  14. package/dist/components/i18n/BridgedLocalesMenuButton.js +126 -1
  15. package/dist/components/i18n/LangSwitcher.js +196 -1
  16. package/dist/components/loader/GlobalLoader.js +71 -1
  17. package/dist/components/logs/LogFile.js +99 -1
  18. package/dist/components/logs/LogFileById.js +75 -1
  19. package/dist/components/logs/LogViewer.js +33 -1
  20. package/dist/components/menu/AppMenu.js +11 -1
  21. package/dist/components/menu/CustomMenuItemLink.js +77 -1
  22. package/dist/components/menu/DarkToggleMode.js +47 -1
  23. package/dist/components/menu/LanguageToggleMode.js +99 -1
  24. package/dist/components/misc/CustomImageInput.js +54 -1
  25. package/dist/components/misc/DASHGlobalErrorHandler.js +159 -1
  26. package/dist/components/misc/DarkModeSwitcher.js +40 -1
  27. package/dist/components/misc/LanguageSwitcher.js +193 -1
  28. package/dist/components/misc/MUIHtmlToolTip.js +50 -1
  29. package/dist/components/misc/MuiSimpleJsonTable.js +178 -1
  30. package/dist/components/misc/MultiLevelTable.js +124 -1
  31. package/dist/components/misc/NoResults.js +17 -1
  32. package/dist/components/misc/PDFViewer.js +86 -1
  33. package/dist/components/navigation/Breadcrumbs.js +178 -1
  34. package/dist/components/navigation/BreadcrumbsManager.js +194 -1
  35. package/dist/components/navigation/index.js +8 -1
  36. package/dist/components/panel/Error.js +161 -1
  37. package/dist/components/permission/AvailablePermissionsContext.js +157 -1
  38. package/dist/components/permission/PermissionsSelector.js +719 -1
  39. package/dist/components/permission/PermissionsSelectorList.js +400 -1
  40. package/dist/components/racustombuttons/CustomRAButton.js +94 -1
  41. package/dist/components/racustombuttons/QuickButton.js +109 -1
  42. package/dist/components/racustombuttons/QuickEditButton.js +114 -1
  43. package/dist/components/racustombuttons/QuickIconButton.js +119 -1
  44. package/dist/components/scrollbar/Scrollbar.js +52 -1
  45. package/dist/components/selects/MultiSelect.js +42 -1
  46. package/dist/components/selects/RASearchableSelect.js +207 -1
  47. package/dist/components/selects/RASearchableSelectChips.js +225 -1
  48. package/dist/components/selects/SearchableSelect.js +128 -1
  49. package/dist/components/subscription/BillingCycleSelectInput.js +50 -1
  50. package/dist/components/subscription/PlanAddonsSettings.js +396 -1
  51. package/dist/components/subscription/PlanAuditLog.js +345 -1
  52. package/dist/components/subscription/PlanFeaturesSettings.js +151 -1
  53. package/dist/components/subscription/PlanLimitsSettings.js +168 -1
  54. package/dist/components/subscription/PlanMetadataSettings.js +219 -1
  55. package/dist/components/subscription/PlanPricesSettings.js +222 -1
  56. package/dist/components/subscription/index.js +12 -1
  57. package/dist/components/svgelements/SvgLoading.js +330 -1
  58. package/dist/components/svgelements/SvgLogo.js +70 -1
  59. package/dist/components/svgelements/SvgLogoMin.js +76 -1
  60. package/dist/components/svgelements/SvgShipping.js +1001 -1
  61. package/dist/components/tenant/TenantAttributes.js +107 -1
  62. package/dist/components/tenant/TenantAttributesContext.js +150 -1
  63. package/dist/components/tenant/TenantSelector.js +160 -1
  64. package/dist/components/tenant/TenantSettings.js +107 -1
  65. package/dist/components/tenant/TenantSettingsContext.js +152 -1
  66. package/dist/components/tenant/TenantTheme.js +112 -1
  67. package/dist/components/user/AvatarComponent.js +270 -1
  68. package/dist/components/user/TenantAvatarComponent.js +83 -1
  69. package/dist/components/user/UserPreferences.js +422 -1
  70. package/dist/config/ACTIONS.js +25 -1
  71. package/dist/config/ConstantsService.js +25 -1
  72. package/dist/config/DASHAdminSystemConstants.js +137 -1
  73. package/dist/config/PARSERS.js +9 -1
  74. package/dist/contexts/DashQueryClientContext.js +78 -1
  75. package/dist/contexts/DashResourceContext.js +21 -1
  76. package/dist/contexts/I18nBridgeContext.js +123 -1
  77. package/dist/contexts/I18nBridgeSetter.js +29 -1
  78. package/dist/contexts/I18nReduxSync.js +16 -1
  79. package/dist/contexts/SubscriptionPlanFormatsProvider.js +175 -1
  80. package/dist/contexts/SystemRequestsCache.js +194 -1
  81. package/dist/contexts/auth/AuthContext.js +396 -1
  82. package/dist/contexts/auth/AuthContextLocalStorage.js +118 -1
  83. package/dist/contexts/auth/DASHAuthenticationService.js +679 -1
  84. package/dist/contexts/auth/WindowContext.js +10 -1
  85. package/dist/contexts/auth/index.js +2 -1
  86. package/dist/contexts/com/FCMContext.js +378 -1
  87. package/dist/contexts/com/LaravelEchoContext.js +45 -1
  88. package/dist/contexts/com/LaravelEchoMgr.js +121 -1
  89. package/dist/contexts/com/components/DefaultNotificationComponent.js +31 -1
  90. package/dist/contexts/com/components/NotificationAttributesTable.js +28 -1
  91. package/dist/contexts/com/components/NotificationRenderer.js +36 -1
  92. package/dist/contexts/com/components/NotificationsWidget.js +142 -1
  93. package/dist/contexts/com/components/notificationFormats.js +15 -1
  94. package/dist/contexts/com/useLaravelEcho.js +340 -1
  95. package/dist/contexts/dictionary/DictionaryContext.js +43 -1
  96. package/dist/default-theme/DASHAppProviders.js +86 -1
  97. package/dist/default-theme/DashThemeContext.js +146 -1
  98. package/dist/default-theme/DashThemeHelperProvider.js +54 -1
  99. package/dist/default-theme/DomainAppLayout.js +126 -1
  100. package/dist/default-theme/DomainHeader.js +114 -1
  101. package/dist/default-theme/DomainTheme.js +60 -1
  102. package/dist/default-theme/FullLayoutMarkup.js +55 -1
  103. package/dist/default-theme/StaticLayout.js +36 -1
  104. package/dist/default-theme/index.js +19 -1
  105. package/dist/default-theme/menu/AppMaterialMenu.js +364 -1
  106. package/dist/default-theme/menu/AppMenuComponents/SubmenuPortal.js +33 -1
  107. package/dist/default-theme/menu/AppMenuComponents/collapsed/CollapsedSidebarItem.js +239 -1
  108. package/dist/default-theme/menu/AppMenuComponents/collapsed/CollapsedSidebarItems.js +22 -1
  109. package/dist/default-theme/menu/AppMenuComponents/expanded/CollapsableSidebarMenu.js +209 -1
  110. package/dist/default-theme/menu/AppMenuComponents/expanded/SidebarItem.js +71 -1
  111. package/dist/default-theme/menu/AppMenuComponents/getItem.js +7 -1
  112. package/dist/default-theme/menu/AppMenuComponents/submenuConstants.js +78 -1
  113. package/dist/default-theme/menu/AppSidebarMaterial.js +232 -1
  114. package/dist/default-theme/menu/SidebarActions.js +75 -1
  115. package/dist/default-theme/updateDomCssVariables.js +134 -1
  116. package/dist/helpers/checkRole.js +14 -1
  117. package/dist/helpers/parseAxiosError.js +28 -2
  118. package/dist/hooks/audio/useAudio.js +24 -1
  119. package/dist/hooks/axios.js +52 -1
  120. package/dist/hooks/data/useDashboardStats.js +88 -1
  121. package/dist/hooks/data/usePackageByClientsStats.js +51 -1
  122. package/dist/hooks/data/usePackageByCommunesStats.js +51 -1
  123. package/dist/hooks/data/usePackageStats.js +88 -1
  124. package/dist/hooks/data/usePackageWithdrawDetails.js +69 -1
  125. package/dist/hooks/data/useStats.js +94 -1
  126. package/dist/hooks/isCurrentPath.js +18 -1
  127. package/dist/hooks/notifications/WSMessagesManager.js +128 -1
  128. package/dist/hooks/notifications/WSPusherManager.js +70 -1
  129. package/dist/hooks/useBreadcrumbs.js +208 -1
  130. package/dist/hooks/useClickOutside.js +18 -1
  131. package/dist/hooks/useFormPersistance.js +129 -1
  132. package/dist/hooks/useGlobalErrorMediator.js +37 -1
  133. package/dist/hooks/useGlobalLoaderMgr.js +20 -1
  134. package/dist/hooks/useHash.js +24 -1
  135. package/dist/hooks/useLocalStorage.js +68 -1
  136. package/dist/hooks/usePolyglotTranslation.js +57 -1
  137. package/dist/hooks/usePrevious.js +12 -1
  138. package/dist/hooks/usePrintSelected.js +30 -1
  139. package/dist/hooks/useVirtualHash.js +28 -1
  140. package/dist/hooks/window/useWindowSize.js +23 -1
  141. package/dist/index.js +120 -97
  142. package/dist/interfaces.js +6 -1
  143. package/dist/layout/AppLayout.js +36 -1
  144. package/dist/layout/ApplicationLayout.js +110 -1
  145. package/dist/layout/MotionWrapper.js +182 -1
  146. package/dist/layout/MotionWrapper.original.js +182 -1
  147. package/dist/layout/ResourceMenu.js +87 -1
  148. package/dist/layout/ResoureLayout.js +47 -1
  149. package/dist/layout/TransitionWrapper.js +83 -2
  150. package/dist/pages/ChangePassword.js +198 -1
  151. package/dist/pages/DASHLanding.js +9 -1
  152. package/dist/pages/DASHLightWeightLogin.js +495 -1
  153. package/dist/pages/DASHSimpleLogin.js +231 -1
  154. package/dist/pages/Login.js +113 -1
  155. package/dist/pages/Profile.js +347 -1
  156. package/dist/pages/RecoverPassword.js +175 -1
  157. package/dist/pages/SingleImageUploader.js +40 -1
  158. package/dist/pages/VerifyAccount.js +129 -1
  159. package/dist/providers/authProvider.js +186 -1
  160. package/dist/providers/dataProvider.js +468 -1
  161. package/dist/providers/i18n/en.js +514 -1
  162. package/dist/providers/i18n/es.js +520 -1
  163. package/dist/providers/i18n/languages.js +8 -1
  164. package/dist/providers/i18nProvider.js +23 -1
  165. package/dist/react-admin-dash/RADashComponent.js +210 -1
  166. package/dist/react-admin-dash/Resource.js +62 -1
  167. package/dist/resources/Brand/BrandResource.js +106 -1
  168. package/dist/resources/DASHResourceLoader.js +104 -1
  169. package/dist/resources/Log/LogResource.js +59 -1
  170. package/dist/resources/Tenant/ImpersonateTenantResource.js +113 -1
  171. package/dist/resources/Trash/TrashTemplate.js +195 -1
  172. package/dist/resources.js +259 -1
  173. package/dist/schemas/log.js +45 -1
  174. package/dist/schemas/notification.js +39 -1
  175. package/dist/schemas/permissions.js +44 -1
  176. package/dist/schemas/roles.js +48 -1
  177. package/dist/schemas/rolesDataGrid.js +48 -1
  178. package/dist/schemas/subscription/components/SubscriptionActions.js +172 -1
  179. package/dist/schemas/subscription/components/SubscriptionPaymentHistory.js +101 -1
  180. package/dist/schemas/subscription/components/SubscriptionPlanFeatures.js +115 -1
  181. package/dist/schemas/subscription/components/SubscriptionPlanPreview.js +92 -1
  182. package/dist/schemas/subscription/components/SubscriptionPlanStats.js +181 -1
  183. package/dist/schemas/subscription/components/SubscriptionStatusIndicator.js +70 -1
  184. package/dist/schemas/subscription/subscriptionPlanSchema.js +184 -1
  185. package/dist/schemas/subscription/subscriptionSchema.js +147 -1
  186. package/dist/schemas/subscriptionPlan.js +397 -1
  187. package/dist/schemas/tenant.js +122 -1
  188. package/dist/schemas/tenantUser.js +94 -1
  189. package/dist/schemas/tenant_superadmin.js +118 -1
  190. package/dist/schemas/user.js +26 -1
  191. package/dist/systemResources.js +1039 -1
  192. package/dist/systemResources.old.js +668 -1
  193. package/dist/templates/ResourceTemplate.js +196 -1
  194. package/dist/templates/ResourceTemplateCreate.js +144 -1
  195. package/dist/templates/ResourceTemplateEdit.js +147 -1
  196. package/dist/templates/ResourceTemplateFull.js +518 -1
  197. package/dist/templates/ResourceTemplateList.js +295 -1
  198. package/dist/templates/ResourceTemplateShow.js +45 -1
  199. package/dist/templates/TrashTemplate.js +175 -1
  200. package/dist/tenantResources.js +206 -1
  201. package/dist/test_portal_bubbles.js +37 -1
  202. package/dist/theme/AppHeader.js +60 -1
  203. package/dist/theme/AppLayoutSetting.js +34 -1
  204. package/dist/theme/AppLogo.js +7 -1
  205. package/dist/theme/AppSidebar.js +30 -1
  206. package/dist/theme/AppSidebarContent.js +84 -1
  207. package/dist/theme/AppSidebarLogo.js +42 -1
  208. package/dist/theme/components/PageTitle.js +61 -1
  209. package/dist/utils/cache/CacheInvalidatorContext.js +100 -1
  210. package/dist/utils/cache/CacheInvalidatorListenerComponent.js +10 -1
  211. package/dist/utils/cache/useCacheInvalidatorListener.js +17 -1
  212. package/dist/utils/convertFileToBase64.js +10 -1
  213. package/dist/utils/convertToFile.js +12 -1
  214. package/dist/utils/cookies.js +45 -1
  215. package/dist/utils/dashDefaultQueryClient.js +15 -1
  216. package/dist/utils/dataUrlToBlob.js +23 -1
  217. package/dist/utils/deepReplace.js +17 -1
  218. package/dist/utils/getProfileMenu.js +31 -1
  219. package/dist/utils/getTenantSettings.js +9 -1
  220. package/dist/utils/getType.js +10 -1
  221. package/dist/utils/getUserSettings.js +9 -1
  222. package/dist/utils/hasCode.js +14 -1
  223. package/dist/utils/index.js +19 -1
  224. package/dist/utils/injectTenantStyles.js +19 -1
  225. package/dist/utils/isComponent.js +23 -1
  226. package/dist/utils/navEvents.js +75 -1
  227. package/dist/utils/prototypes.js +5 -1
  228. package/dist/utils/regexp.js +7 -1
  229. package/dist/utils/resolveObjectPath.js +5 -1
  230. package/dist/utils/setNativeValue.js +17 -1
  231. package/dist/utils/slugify.js +7 -1
  232. package/dist/utils/validators/emailValidator.js +8 -1
  233. package/dist/utils/validators/requiredValidator.js +7 -1
  234. package/dist/utils/validators/rutValidator.js +25 -1
  235. package/dist/utils/validators.js +57 -1
  236. package/package.json +153 -69
  237. package/src/AppAsyncWrapper.tsx +42 -0
  238. package/src/AppWrapper.tsx +45 -0
  239. package/src/DASHAdmin.tsx +501 -0
  240. package/src/RoutingWrapper.tsx +139 -0
  241. package/src/classes/DASHStorageClass.tsx +8 -0
  242. package/src/components/Input/RichTextField.tsx +27 -0
  243. package/src/components/Redirect.tsx +46 -0
  244. package/src/components/avatar/Avatar.tsx +67 -0
  245. package/src/components/avatar/SingleImageUploader.tsx +53 -0
  246. package/src/components/currency/Format.tsx +77 -0
  247. package/src/components/custom/Redirect.tsx +23 -0
  248. package/src/components/error/Error.tsx +168 -0
  249. package/src/components/geocoding/GeocodingField.tsx +167 -0
  250. package/src/components/i18n/BridgedLocalesMenuButton.tsx +159 -0
  251. package/src/components/i18n/LangSwitcher.tsx +204 -0
  252. package/src/components/loader/GlobalLoader.tsx +56 -0
  253. package/src/components/logs/LogFile.tsx +88 -0
  254. package/src/components/logs/LogFileById.tsx +68 -0
  255. package/src/components/logs/LogViewer.tsx +43 -0
  256. package/src/components/menu/AppMenu.tsx +22 -0
  257. package/src/components/menu/CustomMenuItemLink.tsx +61 -0
  258. package/src/components/menu/DarkToggleMode.tsx +65 -0
  259. package/src/components/menu/LanguageToggleMode.tsx +120 -0
  260. package/src/components/misc/CustomImageInput.tsx +62 -0
  261. package/src/components/misc/DASHGlobalErrorHandler.tsx +194 -0
  262. package/src/components/misc/DarkModeSwitcher.tsx +112 -0
  263. package/src/components/misc/LanguageSwitcher.tsx +199 -0
  264. package/src/components/misc/MUIHtmlToolTip.tsx +15 -0
  265. package/src/components/misc/MuiSimpleJsonTable.tsx +279 -0
  266. package/src/components/misc/MultiLevelTable.tsx +229 -0
  267. package/src/components/misc/NoResults.tsx +25 -0
  268. package/src/components/misc/PDFViewer.tsx +85 -0
  269. package/src/components/navigation/Breadcrumbs.tsx +220 -0
  270. package/src/components/navigation/BreadcrumbsManager.tsx +310 -0
  271. package/src/components/navigation/index.tsx +5 -0
  272. package/src/components/panel/Error.tsx +168 -0
  273. package/src/components/permission/AvailablePermissionsContext.tsx +173 -0
  274. package/src/components/permission/PermissionsSelector.tsx +819 -0
  275. package/src/components/permission/PermissionsSelectorList.tsx +468 -0
  276. package/src/components/permission/tsx +0 -0
  277. package/src/components/racustombuttons/CustomRAButton.tsx +87 -0
  278. package/src/components/racustombuttons/QuickButton.tsx +117 -0
  279. package/src/components/racustombuttons/QuickEditButton.tsx +115 -0
  280. package/src/components/racustombuttons/QuickIconButton.tsx +122 -0
  281. package/src/components/scrollbar/Scrollbar.tsx +31 -0
  282. package/src/components/selects/MultiSelect.tsx +53 -0
  283. package/src/components/selects/RASearchableSelect.tsx +279 -0
  284. package/src/components/selects/RASearchableSelectChips.tsx +304 -0
  285. package/src/components/selects/SearchableSelect.tsx +135 -0
  286. package/src/components/subscription/BillingCycleSelectInput.tsx +68 -0
  287. package/src/components/subscription/PlanAddonsSettings.tsx +522 -0
  288. package/src/components/subscription/PlanAuditLog.tsx +439 -0
  289. package/src/components/subscription/PlanFeaturesSettings.tsx +223 -0
  290. package/src/components/subscription/PlanLimitsSettings.tsx +230 -0
  291. package/src/components/subscription/PlanMetadataSettings.tsx +284 -0
  292. package/src/components/subscription/PlanPricesSettings.tsx +295 -0
  293. package/src/components/subscription/index.ts +7 -0
  294. package/src/components/svgelements/SvgLoading.tsx +229 -0
  295. package/src/components/svgelements/SvgLogo.tsx +53 -0
  296. package/src/components/svgelements/SvgLogoMin.tsx +64 -0
  297. package/src/components/svgelements/SvgShipping.tsx +673 -0
  298. package/src/components/tenant/AvailablePermissionsContext.tsx +0 -0
  299. package/src/components/tenant/TenantAttributes.tsx +153 -0
  300. package/src/components/tenant/TenantAttributesContext.tsx +163 -0
  301. package/src/components/tenant/TenantSelector.tsx +139 -0
  302. package/src/components/tenant/TenantSettings.tsx +172 -0
  303. package/src/components/tenant/TenantSettingsContext.tsx +165 -0
  304. package/src/components/tenant/TenantTheme.tsx +172 -0
  305. package/src/components/user/AvatarComponent.tsx +301 -0
  306. package/src/components/user/TenantAvatarComponent.tsx +99 -0
  307. package/src/components/user/UserPreferences.tsx +642 -0
  308. package/src/config/ACTIONS.tsx +26 -0
  309. package/src/config/ConstantsService.tsx +44 -0
  310. package/src/config/DASHAdminSystemConstants.tsx +182 -0
  311. package/src/config/PARSERS.tsx +9 -0
  312. package/src/contexts/DashQueryClientContext.tsx +113 -0
  313. package/src/contexts/DashResourceContext.tsx +34 -0
  314. package/src/contexts/I18nBridgeContext.tsx +156 -0
  315. package/src/contexts/I18nBridgeSetter.tsx +39 -0
  316. package/src/contexts/I18nReduxSync.tsx +27 -0
  317. package/src/contexts/SubscriptionPlanFormatsProvider.tsx +217 -0
  318. package/src/contexts/SystemRequestsCache.tsx +215 -0
  319. package/src/contexts/auth/AuthContext.tsx +553 -0
  320. package/src/contexts/auth/AuthContextLocalStorage.tsx +140 -0
  321. package/src/contexts/auth/DASHAuthenticationService.tsx +917 -0
  322. package/src/contexts/auth/WindowContext.tsx +15 -0
  323. package/src/contexts/auth/index.tsx +3 -0
  324. package/src/contexts/com/FCMContext.tsx +415 -0
  325. package/src/contexts/com/LaravelEchoContext.tsx +41 -0
  326. package/src/contexts/com/LaravelEchoMgr.tsx +155 -0
  327. package/src/contexts/com/components/DefaultNotificationComponent.tsx +20 -0
  328. package/src/contexts/com/components/NotificationAttributesTable.tsx +54 -0
  329. package/src/contexts/com/components/NotificationRenderer.tsx +42 -0
  330. package/src/contexts/com/components/NotificationsWidget.tsx +182 -0
  331. package/src/contexts/com/components/notificationFormats.tsx +50 -0
  332. package/src/contexts/com/useLaravelEcho.tsx +432 -0
  333. package/src/contexts/dictionary/DictionaryContext.tsx +94 -0
  334. package/src/default-theme/DASHAppProviders.tsx +117 -0
  335. package/src/default-theme/DashThemeContext.tsx +218 -0
  336. package/src/default-theme/DashThemeHelperProvider.tsx +98 -0
  337. package/src/default-theme/DomainAppLayout.tsx +166 -0
  338. package/src/default-theme/DomainHeader.tsx +162 -0
  339. package/src/default-theme/DomainTheme.tsx +59 -0
  340. package/src/default-theme/FullLayoutMarkup.tsx +250 -0
  341. package/src/default-theme/StaticLayout.tsx +47 -0
  342. package/src/default-theme/index.tsx +11 -0
  343. package/src/default-theme/menu/AppMaterialMenu.tsx +545 -0
  344. package/src/default-theme/menu/AppMenuComponents/SubmenuPortal.tsx +56 -0
  345. package/src/default-theme/menu/AppMenuComponents/collapsed/CollapsedSidebarItem.tsx +254 -0
  346. package/src/default-theme/menu/AppMenuComponents/collapsed/CollapsedSidebarItems.tsx +31 -0
  347. package/src/default-theme/menu/AppMenuComponents/expanded/CollapsableSidebarMenu.tsx +276 -0
  348. package/src/default-theme/menu/AppMenuComponents/expanded/SidebarItem.tsx +91 -0
  349. package/src/default-theme/menu/AppMenuComponents/getItem.tsx +17 -0
  350. package/src/default-theme/menu/AppMenuComponents/interfaces.tsx +41 -0
  351. package/src/default-theme/menu/AppMenuComponents/submenuConstants.ts +85 -0
  352. package/src/default-theme/menu/AppSidebarMaterial.tsx +339 -0
  353. package/src/default-theme/menu/SidebarActions.tsx +84 -0
  354. package/src/default-theme/updateDomCssVariables.tsx +176 -0
  355. package/src/helpers/checkRole.tsx +66 -0
  356. package/src/helpers/parseAxiosError.tsx +41 -0
  357. package/src/hooks/audio/useAudio.tsx +39 -0
  358. package/src/hooks/axios.tsx +62 -0
  359. package/src/hooks/data/useDashboardStats.tsx +65 -0
  360. package/src/hooks/data/usePackageByClientsStats.tsx +44 -0
  361. package/src/hooks/data/usePackageByCommunesStats.tsx +44 -0
  362. package/src/hooks/data/usePackageStats.tsx +69 -0
  363. package/src/hooks/data/usePackageWithdrawDetails.tsx +61 -0
  364. package/src/hooks/data/useStats.tsx +86 -0
  365. package/src/hooks/isCurrentPath.tsx +22 -0
  366. package/src/hooks/notifications/WSMessagesManager.tsx +152 -0
  367. package/src/hooks/notifications/WSPusherManager.tsx +92 -0
  368. package/src/hooks/useBreadcrumbs.tsx +329 -0
  369. package/src/hooks/useClickOutside.tsx +17 -0
  370. package/src/hooks/useFormPersistance.tsx +150 -0
  371. package/src/hooks/useGlobalErrorMediator.tsx +43 -0
  372. package/src/hooks/useGlobalLoaderMgr.tsx +21 -0
  373. package/src/hooks/useHash.tsx +27 -0
  374. package/src/hooks/useLocalStorage.tsx +196 -0
  375. package/src/hooks/usePolyglotTranslation.tsx +62 -0
  376. package/src/hooks/usePrevious.tsx +9 -0
  377. package/src/hooks/usePrintSelected.tsx +37 -0
  378. package/src/hooks/useVirtualHash.tsx +33 -0
  379. package/src/hooks/window/useWindowSize.tsx +36 -0
  380. package/src/index.tsx +110 -0
  381. package/src/interfaces/IAppResourceConfig.tsx +20 -0
  382. package/src/interfaces/Log.tsx +16 -0
  383. package/src/interfaces/Tenant.tsx +25 -0
  384. package/src/interfaces/communication/IActions.tsx +5 -0
  385. package/src/interfaces/communication/INotification.tsx +21 -0
  386. package/src/interfaces/communication/IPayload.tsx +3 -0
  387. package/src/interfaces/communication/IRequestAction.tsx +10 -0
  388. package/src/interfaces/communication/IRequestPayload.tsx +7 -0
  389. package/src/interfaces/communication/IResponseAction.tsx +7 -0
  390. package/src/interfaces/misc/IAny.tsx +3 -0
  391. package/src/interfaces/misc/IFlashMessage.tsx +10 -0
  392. package/src/interfaces/navigation/IAppMenu.ts +14 -0
  393. package/src/interfaces/navigation/ICollapsableSidebarMenu.ts +12 -0
  394. package/src/interfaces/navigation/IMenuItem.ts +16 -0
  395. package/src/interfaces/notifications/IModel.tsx +6 -0
  396. package/src/interfaces/notifications/IModelField.tsx +8 -0
  397. package/src/interfaces/notifications/IUserNotification.tsx +12 -0
  398. package/src/interfaces/notifications/IUserNotificationData.tsx +13 -0
  399. package/src/interfaces/notifications/IUserNotificationPayload.tsx +8 -0
  400. package/src/interfaces/user/IGetAuth.tsx +92 -0
  401. package/src/interfaces/user/ITenantSettings.tsx +3 -0
  402. package/src/interfaces/user/IUser.tsx +60 -0
  403. package/src/interfaces/user/IUserSettings.tsx +43 -0
  404. package/src/interfaces.tsx +6 -0
  405. package/src/layout/AppLayout.tsx +112 -0
  406. package/src/layout/ApplicationLayout.tsx +197 -0
  407. package/src/layout/MotionWrapper.original.tsx +236 -0
  408. package/src/layout/MotionWrapper.tsx +236 -0
  409. package/src/layout/ResourceMenu.tsx +164 -0
  410. package/src/layout/ResoureLayout.tsx +105 -0
  411. package/src/layout/TransitionWrapper.tsx +125 -0
  412. package/src/pages/ChangePassword.tsx +179 -0
  413. package/src/pages/DASHLanding.tsx +22 -0
  414. package/src/pages/DASHLightWeightLogin.tsx +610 -0
  415. package/src/pages/DASHSimpleLogin.tsx +260 -0
  416. package/src/pages/Login.tsx +111 -0
  417. package/src/pages/Profile.tsx +394 -0
  418. package/src/pages/RecoverPassword.tsx +166 -0
  419. package/src/pages/SingleImageUploader.tsx +55 -0
  420. package/src/pages/VerifyAccount.tsx +128 -0
  421. package/src/providers/authProvider.tsx +210 -0
  422. package/src/providers/dataProvider.tsx +672 -0
  423. package/src/providers/i18n/en.ts +533 -0
  424. package/src/providers/i18n/es.ts +539 -0
  425. package/src/providers/i18n/languages.tsx +5 -0
  426. package/src/providers/i18nProvider.tsx +23 -0
  427. package/src/react-admin-dash/RADashComponent.tsx +240 -0
  428. package/src/react-admin-dash/Resource.tsx +77 -0
  429. package/src/resources/Brand/BrandResource.tsx +130 -0
  430. package/src/resources/DASHResourceLoader.ts +180 -0
  431. package/src/resources/Log/LogResource.tsx +73 -0
  432. package/src/resources/Tenant/ImpersonateTenantResource.tsx +113 -0
  433. package/src/resources/Trash/TrashTemplate.tsx +180 -0
  434. package/src/resources.tsx +280 -0
  435. package/src/schemas/log.tsx +45 -0
  436. package/src/schemas/notification.tsx +42 -0
  437. package/src/schemas/permissions.tsx +44 -0
  438. package/src/schemas/roles.tsx +48 -0
  439. package/src/schemas/rolesDataGrid.tsx +48 -0
  440. package/src/schemas/subscription/components/SubscriptionActions.tsx +153 -0
  441. package/src/schemas/subscription/components/SubscriptionPaymentHistory.tsx +120 -0
  442. package/src/schemas/subscription/components/SubscriptionPlanFeatures.tsx +155 -0
  443. package/src/schemas/subscription/components/SubscriptionPlanPreview.tsx +128 -0
  444. package/src/schemas/subscription/components/SubscriptionPlanStats.tsx +268 -0
  445. package/src/schemas/subscription/components/SubscriptionStatusIndicator.tsx +72 -0
  446. package/src/schemas/subscription/subscriptionPlanSchema.tsx +185 -0
  447. package/src/schemas/subscription/subscriptionSchema.tsx +152 -0
  448. package/src/schemas/subscriptionPlan.ts +422 -0
  449. package/src/schemas/tenant.tsx +129 -0
  450. package/src/schemas/tenantUser.tsx +96 -0
  451. package/src/schemas/tenant_superadmin.tsx +119 -0
  452. package/src/schemas/user.tsx +26 -0
  453. package/src/systemResources.old.tsx +928 -0
  454. package/src/systemResources.tsx +1135 -0
  455. package/src/templates/ResourceTemplate.tsx +240 -0
  456. package/src/templates/ResourceTemplateCreate.tsx +167 -0
  457. package/src/templates/ResourceTemplateEdit.tsx +176 -0
  458. package/src/templates/ResourceTemplateFull.tsx +581 -0
  459. package/src/templates/ResourceTemplateList.tsx +340 -0
  460. package/src/templates/ResourceTemplateShow.tsx +88 -0
  461. package/src/templates/TrashTemplate.tsx +179 -0
  462. package/src/tenantResources.tsx +223 -0
  463. package/src/test_portal_bubbles.tsx +40 -0
  464. package/src/theme/AppHeader.tsx +52 -0
  465. package/src/theme/AppLayoutSetting.tsx +33 -0
  466. package/src/theme/AppLogo.tsx +13 -0
  467. package/src/theme/AppSidebar.tsx +12 -0
  468. package/src/theme/AppSidebarContent.tsx +105 -0
  469. package/src/theme/AppSidebarLogo.tsx +48 -0
  470. package/src/theme/components/PageTitle.tsx +37 -0
  471. package/src/utils/cache/CacheInvalidatorContext.tsx +125 -0
  472. package/src/utils/cache/CacheInvalidatorListenerComponent.tsx +10 -0
  473. package/src/utils/cache/useCacheInvalidatorListener.tsx +27 -0
  474. package/src/utils/convertFileToBase64.tsx +9 -0
  475. package/src/utils/convertToFile.tsx +14 -0
  476. package/src/utils/cookies.tsx +33 -0
  477. package/src/utils/dashDefaultQueryClient.tsx +34 -0
  478. package/src/utils/dataUrlToBlob.tsx +30 -0
  479. package/src/utils/deepReplace.tsx +19 -0
  480. package/src/utils/getProfileMenu.tsx +41 -0
  481. package/src/utils/getTenantSettings.tsx +9 -0
  482. package/src/utils/getType.tsx +8 -0
  483. package/src/utils/getUserSettings.tsx +8 -0
  484. package/src/utils/hasCode.tsx +14 -0
  485. package/src/utils/index.ts +19 -0
  486. package/src/utils/injectTenantStyles.ts +28 -0
  487. package/src/utils/isComponent.tsx +45 -0
  488. package/src/utils/navEvents.tsx +91 -0
  489. package/src/utils/prototypes.tsx +5 -0
  490. package/src/utils/regexp.tsx +4 -0
  491. package/src/utils/resolveObjectPath.tsx +4 -0
  492. package/src/utils/setNativeValue.tsx +24 -0
  493. package/src/utils/slugify.tsx +11 -0
  494. package/src/utils/validators/emailValidator.tsx +6 -0
  495. package/src/utils/validators/requiredValidator.tsx +5 -0
  496. package/src/utils/validators/rutValidator.tsx +31 -0
  497. package/src/utils/validators.tsx +96 -0
  498. package/dist/ChangePassword-DmWAQAX_.js +0 -152
  499. package/dist/Login-t41HMhVT.js +0 -101
  500. package/dist/Profile-By-gdPUd.js +0 -294
  501. package/dist/RecoverPassword-DzPdbkg2.js +0 -149
  502. package/dist/VerifyAccount-Bofaxe5w.js +0 -99
  503. package/dist/index-gfebuoyf.js +0 -21614
  504. /package/dist/{components/permission/tsx → declarations.d.js} +0 -0
  505. /package/{dist → src}/DASHAdmin.tsx.old +0 -0
  506. /package/{dist → src}/declarations.d.ts +0 -0
  507. /package/{dist → src}/default-theme/DashThemeContext.tsx.fast +0 -0
  508. /package/{dist → src}/default-theme/DashThemeContext.tsx.old +0 -0
  509. /package/{dist → src}/templates/ResourceTemplate.tsx.memoized_experiment +0 -0
  510. /package/{dist → src}/templates/ResourceTemplate.tsx.original +0 -0
  511. /package/{dist → src}/templates/ResourceTemplateOld.tsx.bkup +0 -0
@@ -0,0 +1,819 @@
1
+ import React, { useCallback, useEffect, useState, useMemo, useRef } from 'react';
2
+ import { useRecordContext, useRefresh, CheckboxGroupInput, Loading, useEditContext, useGetOne } from 'react-admin';
3
+ import { useController, useFormContext, useFormState } from 'react-hook-form';
4
+ import { IDashAutoAdminCustomFieldComponent } from 'dash-auto-admin';
5
+ import { useAxios } from 'dash-axios-hook';
6
+ import {
7
+ Grid,
8
+ Card,
9
+ CardContent,
10
+ Typography,
11
+ Button,
12
+ Box,
13
+ Chip,
14
+ Divider,
15
+ Stack,
16
+ Toolbar,
17
+ Paper,
18
+ TextField,
19
+ InputAdornment,
20
+ CircularProgress,
21
+ IconButton
22
+ } from '@mui/material';
23
+ import {
24
+ SelectAll as SelectAllIcon,
25
+ DeselectOutlined as DeselectAllIcon,
26
+ Search as SearchIcon,
27
+ Clear as ClearIcon,
28
+ FilterList as FilterIcon
29
+ } from '@mui/icons-material';
30
+
31
+ import {useAvailablePermissionsFormats} from "./AvailablePermissionsContext";
32
+ import { useSystemRequestsCache } from '../../contexts/SystemRequestsCache';
33
+ import { NotFound } from 'dash-components';
34
+
35
+
36
+ interface IPermissionItem {
37
+ group: string;
38
+ name: string;
39
+ route_name: string;
40
+ checked?: boolean;
41
+ }
42
+
43
+ // Styles for HTML checkboxes
44
+ const checkboxStyles = {
45
+ checkbox: {
46
+ marginRight: '8px',
47
+ cursor: 'pointer',
48
+ accentColor: '#1976d2'
49
+ },
50
+ checkboxLabel: {
51
+ display: 'flex',
52
+ alignItems: 'center',
53
+ fontSize: '14px',
54
+ cursor: 'pointer',
55
+ padding: '4px 0',
56
+ margin: 0,
57
+ userSelect: 'none' as const
58
+ },
59
+ selectAllLabel: {
60
+ display: 'flex',
61
+ alignItems: 'center',
62
+ fontSize: '14px',
63
+ fontWeight: 'bold',
64
+ cursor: 'pointer',
65
+ margin: 0,
66
+ userSelect: 'none' as const
67
+ }
68
+ };
69
+
70
+ const PermissionsSelectorView: React.FC<IDashAutoAdminCustomFieldComponent> = ({
71
+ method,
72
+ attribute,
73
+ }) => {
74
+ const record = useRecordContext();
75
+ const [permissions, setPermissions] = useState<IPermissionItem[][]>([]);
76
+
77
+ useEffect(() => {
78
+
79
+ if (record?.permissions) {
80
+
81
+ const groupedPermissions = record.permissions.reduce((acc, permission) => {
82
+ const group = acc.find(g => g[0]?.group === permission.group);
83
+ if (group) {
84
+ group.push(permission);
85
+ } else {
86
+ acc.push([permission]);
87
+ }
88
+ return acc;
89
+ }, [] as any[]);
90
+ setPermissions(groupedPermissions);
91
+ }
92
+ }, [record?.permissions]);
93
+
94
+ if (!record?.permissions || record.permissions.length === 0) {
95
+ return (
96
+ <Box sx={{ p: 2, textAlign: 'center' }}>
97
+ <Typography variant="body2" color="text.secondary">
98
+ No permissions assigned
99
+ </Typography>
100
+ </Box>
101
+ );
102
+ }
103
+
104
+ return (
105
+ <Box sx={{ p: 2 }}>
106
+ <Typography variant="h6" sx={{ mb: 3 }}>
107
+ Assigned Permissions ({record.permissions.length})
108
+ </Typography>
109
+ <Grid container spacing={3}>
110
+ {permissions?.map((tab, index) => (
111
+ /* @ts-ignore */
112
+ <Grid item xs={12} sm={6} md={4} lg={3} key={index}>
113
+ <Card
114
+ variant="outlined"
115
+ sx={{
116
+ height: '100%',
117
+ display: 'flex',
118
+ flexDirection: 'column'
119
+ }}
120
+ >
121
+ <CardContent sx={{ flexGrow: 1 }}>
122
+ <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 2 }}>
123
+ <Typography variant="subtitle1" sx={{ fontWeight: 600, fontSize: '1rem' }}>
124
+ {tab[0]?.group.charAt(0).toUpperCase() + tab[0]?.group.slice(1)}
125
+ </Typography>
126
+ <Chip
127
+ label={tab.length}
128
+ size="small"
129
+ color="primary"
130
+ />
131
+ </Box>
132
+ <Stack spacing={0.5}>
133
+ {tab.map((item, i) => (
134
+ <Typography key={i} variant="body2" sx={{ color: 'text.secondary', fontSize: '0.875rem' }}>
135
+ • {item.name.split('.').pop()}
136
+ </Typography>
137
+ ))}
138
+ </Stack>
139
+ </CardContent>
140
+ </Card>
141
+ </Grid>
142
+ ))}
143
+ </Grid>
144
+ </Box>
145
+ );
146
+ };
147
+
148
+ // Utility for deep equality check (comparing by route_name instead of name)
149
+ function arePermissionsEqual(a: IPermissionItem[], b: IPermissionItem[]) {
150
+ if (!Array.isArray(a) || !Array.isArray(b)) return false;
151
+ if (a.length !== b.length) return false;
152
+ const aRouteNames = a.map(p => p.route_name).sort();
153
+ const bRouteNames = b.map(p => p.route_name).sort();
154
+ return aRouteNames.every((routeName, idx) => routeName === bRouteNames[idx]);
155
+ }
156
+
157
+ const INITIAL_ITEMS_COUNT = 6;
158
+
159
+ const PermissionsSelectorBase: React.FC<IDashAutoAdminCustomFieldComponent & { record: any }> = ({
160
+ method,
161
+ attribute,
162
+ resourceConfig,
163
+ record = null
164
+ }) => {
165
+ const [permissionsData, setPermissionsData] = useState<IPermissionItem[][]>([]);
166
+ const [parsedValues, setParsedValues] = useState<IPermissionItem[]>([]);
167
+ const [expandedCards, setExpandedCards] = useState<{ [key: string]: boolean }>({});
168
+ const [isInitialized, setIsInitialized] = useState(false);
169
+ const [groupSearchTerm, setGroupSearchTerm] = useState<string>('');
170
+ const [itemSearchTerm, setItemSearchTerm] = useState<string>('');
171
+ const [debouncedGroupSearch, setDebouncedGroupSearch] = useState<string>('');
172
+ const [debouncedItemSearch, setDebouncedItemSearch] = useState<string>('');
173
+
174
+ const groupSearchTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
175
+ const itemSearchTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
176
+
177
+ const axios = useAxios();
178
+ const refresh = useRefresh();
179
+ const form = useFormContext();
180
+ const formState = useFormState();
181
+
182
+ // Controllers for both permission_objects and permissions fields
183
+ const permissionObjectsController = useController({ name: 'permission_objects' });
184
+ const permissionsController = useController({ name: 'permissions' });
185
+
186
+ // Local state for selected permissions (array of permission objects)
187
+ const [statePermissions, setStatePermissions] = useState<IPermissionItem[]>([]);
188
+
189
+ const { formats: availablePermissions, loading } = useSystemRequestsCache();
190
+
191
+ // Group permissions by their group
192
+ const groupPermissions = useCallback((permissions: IPermissionItem[]) => {
193
+ return permissions.reduce((acc, permission) => {
194
+ const group = acc.find(g => g[0]?.group === permission.group);
195
+ if (group) {
196
+ group.push(permission);
197
+ } else {
198
+ acc.push([permission]);
199
+ }
200
+ return acc;
201
+ }, [] as IPermissionItem[][]);
202
+ }, []);
203
+
204
+ // --- Debounced search logic (improved for UX) ---
205
+ useEffect(() => {
206
+ if (groupSearchTimeoutRef.current) clearTimeout(groupSearchTimeoutRef.current);
207
+ groupSearchTimeoutRef.current = setTimeout(() => {
208
+ setDebouncedGroupSearch(groupSearchTerm);
209
+ }, 500);
210
+ return () => { if (groupSearchTimeoutRef.current) clearTimeout(groupSearchTimeoutRef.current); };
211
+ }, [groupSearchTerm]);
212
+ useEffect(() => {
213
+ if (itemSearchTimeoutRef.current) clearTimeout(itemSearchTimeoutRef.current);
214
+ itemSearchTimeoutRef.current = setTimeout(() => {
215
+ setDebouncedItemSearch(itemSearchTerm);
216
+ }, 500);
217
+ return () => { if (itemSearchTimeoutRef.current) clearTimeout(itemSearchTimeoutRef.current); };
218
+ }, [itemSearchTerm]);
219
+
220
+ // Initialize permissions from available permissions
221
+ useEffect(() => {
222
+ if (!isInitialized && availablePermissions) {
223
+ const perms = Array.isArray(availablePermissions.data)
224
+ ? availablePermissions.data
225
+ : Array.isArray(availablePermissions)
226
+ ? availablePermissions
227
+ : [];
228
+ if (perms.length > 0) {
229
+ const groupedPerms = groupPermissions(perms);
230
+ setPermissionsData(groupedPerms);
231
+ // Initialize all cards as collapsed by default using group name as key
232
+ const initialExpandedState = groupedPerms.reduce((acc, group) => {
233
+ const groupKey = group[0]?.group || 'Other';
234
+ acc[groupKey] = false;
235
+ return acc;
236
+ }, {} as { [key: string]: boolean });
237
+ setExpandedCards(initialExpandedState);
238
+ }
239
+ setIsInitialized(true);
240
+ }
241
+ }, [availablePermissions, isInitialized, groupPermissions]);
242
+
243
+ // --- FIX: Remove field.onChange from useEffect that watches parsedValues ---
244
+ // Only set parsedValues and call field.onChange when the record changes (external update)
245
+ useEffect(() => {
246
+ if (!loading && record && record.id && permissionsData.length > 0) {
247
+ const initialPermissionObjects = record.permission_objects || [];
248
+ // Only update if different
249
+ if (!arePermissionsEqual(initialPermissionObjects, statePermissions)) {
250
+ setStatePermissions(initialPermissionObjects);
251
+ }
252
+ }
253
+ // Only run when record or permissionsData changes
254
+ }, [permissionsData, record?.permissions, record?.permission_objects, record?.id, loading]);
255
+
256
+ // When initializing statePermissions from backend, only consider a permission checked if it is present in permission_objects
257
+ useEffect(() => {
258
+ if (!loading && record && record.id && permissionsData.length > 0) {
259
+ const initialPermissionObjects = record.permission_objects || [];
260
+ // Only permissions present in permission_objects are checked
261
+ // Compare by route_name since that's the unique identifier
262
+ const checkedRouteNames = new Set(initialPermissionObjects.map(obj => obj.route_name));
263
+ const initialChecked = permissionsData.flat().map(p => ({
264
+ ...p,
265
+ checked: checkedRouteNames.has(p.route_name)
266
+ }));
267
+ // Only update if different
268
+ if (
269
+ statePermissions.length !== initialChecked.length ||
270
+ statePermissions.some((p, i) => p.route_name !== initialChecked[i].route_name || p.checked !== initialChecked[i].checked)
271
+ ) {
272
+ setStatePermissions(initialChecked);
273
+ }
274
+ }
275
+ // Only run when record or permissionsData changes
276
+ }, [permissionsData, record?.permissions, record?.permission_objects, record?.id, loading]);
277
+
278
+ // Sync statePermissions to form fields
279
+ useEffect(() => {
280
+ if (!statePermissions) return;
281
+ // Always update permission_objects with the array of permission objects (with checked: true)
282
+ permissionObjectsController.field.onChange(statePermissions.map(p => ({ ...p, checked: true })));
283
+ // Optionally update permissions with just the route_names
284
+ permissionsController.field.onChange(statePermissions.map(p => p.route_name));
285
+ // eslint-disable-next-line react-hooks/exhaustive-deps
286
+ }, [statePermissions]);
287
+
288
+ // Update the handleTogglePermission function to be more explicit about checked status
289
+ const handleTogglePermission = useCallback((permission: IPermissionItem) => {
290
+ setStatePermissions(prev => prev.map(p =>
291
+ p.route_name === permission.route_name ? { ...p, checked: !p.checked } : p
292
+ ));
293
+ }, []);
294
+
295
+ // Handle toggling all permissions in a group
296
+ const handleToggleGroup = useCallback((groupPermissions: IPermissionItem[]) => {
297
+ setStatePermissions(prev => {
298
+ const allSelected = groupPermissions.every(p => prev.find(sel => sel.route_name === p.route_name && sel.checked));
299
+ return prev.map(p =>
300
+ groupPermissions.some(gp => gp.route_name === p.route_name)
301
+ ? { ...p, checked: !allSelected }
302
+ : p
303
+ );
304
+ });
305
+ }, []);
306
+
307
+ // Select all: set checked: true for all
308
+ const handleSelectAll = useCallback(() => {
309
+ console.log('Selecting all permissions', permissionsData.flat().length);
310
+ setStatePermissions(prev =>
311
+ prev.map(p => ({ ...p, checked: true }))
312
+ );
313
+ }, []);
314
+
315
+ // Deselect all: set checked: false for all
316
+ const handleDeselectAll = useCallback(() => {
317
+ setStatePermissions(prev => prev.map(p => ({ ...p, checked: false })));
318
+ }, []);
319
+
320
+ // When syncing to form fields, make sure we're only sending checked permissions
321
+ useEffect(() => {
322
+ if (!statePermissions) return;
323
+
324
+ // CHANGED: Only include permissions that have checked=true
325
+ const checkedPermissions = statePermissions.filter(p => p.checked);
326
+
327
+ // Update permission_objects with ONLY the checked permissions
328
+ permissionObjectsController.field.onChange(checkedPermissions);
329
+
330
+ // Update permissions field with just the route_names of checked permissions
331
+ permissionsController.field.onChange(
332
+ checkedPermissions.map(p => p.route_name)
333
+ );
334
+
335
+ // Log what we're sending to the form (for debugging)
336
+ console.log('Syncing permissions to form:', {
337
+ totalPermissions: statePermissions.length,
338
+ checkedPermissions: checkedPermissions.length,
339
+ selectedCount: statePermissions.filter(p => p.checked).length,
340
+ firstFew: checkedPermissions.slice(0, 3).map(p => p.name)
341
+ });
342
+
343
+ // eslint-disable-next-line react-hooks/exhaustive-deps
344
+ }, [statePermissions]);
345
+
346
+ // --- Filtered permissions with search summary ---
347
+ const filteredPermissions = useMemo(() => {
348
+ let filtered = permissionsData;
349
+ if (debouncedGroupSearch.trim()) {
350
+ const groupSearchLower = debouncedGroupSearch.toLowerCase().trim();
351
+ filtered = filtered.filter(tab => tab[0]?.group.toLowerCase().includes(groupSearchLower));
352
+ }
353
+ if (debouncedItemSearch.trim()) {
354
+ const itemSearchLower = debouncedItemSearch.toLowerCase().trim();
355
+ filtered = filtered.map(tab => tab.filter(item =>
356
+ item.name.toLowerCase().includes(itemSearchLower) ||
357
+ item.name.split('.').pop()?.toLowerCase().includes(itemSearchLower)
358
+ )).filter(tab => tab.length > 0);
359
+ }
360
+ return filtered;
361
+ }, [permissionsData, debouncedGroupSearch, debouncedItemSearch]);
362
+
363
+ // Select all from current filtered page: set checked: true only for filtered permissions
364
+ const handleSelectAllFiltered = useCallback(() => {
365
+ const filteredRouteNames = new Set(filteredPermissions.flat().map(p => p.route_name));
366
+ console.log('Selecting all filtered permissions', filteredRouteNames.size);
367
+ setStatePermissions(prev =>
368
+ prev.map(p => filteredRouteNames.has(p.route_name) ? { ...p, checked: true } : p)
369
+ );
370
+ }, [filteredPermissions]);
371
+
372
+ // Deselect all from current filtered page: set checked: false only for filtered permissions
373
+ const handleDeselectAllFiltered = useCallback(() => {
374
+ const filteredRouteNames = new Set(filteredPermissions.flat().map(p => p.route_name));
375
+ setStatePermissions(prev =>
376
+ prev.map(p => filteredRouteNames.has(p.route_name) ? { ...p, checked: false } : p)
377
+ );
378
+ }, [filteredPermissions]);
379
+
380
+ // --- UI statistics ---
381
+ const totalPermissions = permissionsData.flat().length;
382
+ const selectedPermissions = statePermissions.filter(p => p.checked).length;
383
+ const isAllSelected = selectedPermissions === totalPermissions;
384
+ const isNoneSelected = selectedPermissions === 0;
385
+ const hasActiveSearch = !!debouncedGroupSearch.trim() || !!debouncedItemSearch.trim();
386
+ const filteredGroupsCount = filteredPermissions.length;
387
+ const totalFilteredItems = filteredPermissions.reduce((sum, group) => sum + group.length, 0);
388
+
389
+ // Statistics for filtered permissions
390
+ const filteredSelectedCount = useMemo(() => {
391
+ const filteredRouteNames = new Set(filteredPermissions.flat().map(p => p.route_name));
392
+ return statePermissions.filter(p => p.checked && filteredRouteNames.has(p.route_name)).length;
393
+ }, [filteredPermissions, statePermissions]);
394
+ const isAllFilteredSelected = filteredSelectedCount === totalFilteredItems;
395
+ const isNoneFilteredSelected = filteredSelectedCount === 0;
396
+
397
+ // --- Clear search handlers ---
398
+ const handleClearGroupSearch = useCallback(() => setGroupSearchTerm(''), []);
399
+ const handleClearItemSearch = useCallback(() => setItemSearchTerm(''), []);
400
+ const handleClearAllSearches = useCallback(() => {
401
+ setGroupSearchTerm('');
402
+ setItemSearchTerm('');
403
+ setDebouncedGroupSearch('');
404
+ setDebouncedItemSearch('');
405
+ }, []);
406
+
407
+ // --- Utility: Check if all permissions in a group are selected ---
408
+ const isGroupSelected = useCallback((groupPermissions: IPermissionItem[]) => {
409
+ return groupPermissions.every(p =>
410
+ statePermissions.find(sel => sel.name === p.name && sel.checked)
411
+ );
412
+ }, [statePermissions]);
413
+
414
+ // --- Utility: Count selected permissions in a group ---
415
+ const getSelectedCount = useCallback((groupPermissions: IPermissionItem[]) => {
416
+ return groupPermissions.filter(p =>
417
+ statePermissions.find(sel => sel.name === p.name && sel.checked)
418
+ ).length;
419
+ }, [statePermissions]);
420
+
421
+ // --- Utility: Check if a single permission is selected ---
422
+ const isPermissionSelected = useCallback((permission: IPermissionItem) => {
423
+ const found = statePermissions.find(p => p.name === permission.name);
424
+ return !!found?.checked;
425
+ }, [statePermissions]);
426
+
427
+ if(!statePermissions) return <CircularProgress />;
428
+ if (!permissionsData || !permissionsData.length) return <CircularProgress />;
429
+ if (!record) return <CircularProgress />;
430
+
431
+ return (
432
+ <Box sx={{ p: 2 }}>
433
+ {/* --- Global Toolbar --- */}
434
+ <Paper elevation={1} sx={{ mb: 3, borderRadius: 2, overflow: 'hidden' }}>
435
+ <Toolbar sx={{
436
+ display: 'flex',
437
+ justifyContent: 'space-between',
438
+ alignItems: 'center',
439
+ minHeight: '64px !important',
440
+ px: 3,
441
+ bgcolor: 'background.default'
442
+ }}>
443
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
444
+ <Typography variant="h6" sx={{ fontWeight: 600 }}>
445
+ Permissions Selection
446
+ </Typography>
447
+ <Chip
448
+ label={`${selectedPermissions} / ${totalPermissions} selected`}
449
+ color={isAllSelected ? 'success' : selectedPermissions > 0 ? 'warning' : 'default'}
450
+ variant="outlined"
451
+ />
452
+ </Box>
453
+ <Box sx={{ display: 'flex', gap: 1 }}>
454
+ {hasActiveSearch && (
455
+ <>
456
+ <Button
457
+ variant="contained"
458
+ startIcon={<SelectAllIcon />}
459
+ onClick={handleSelectAllFiltered}
460
+ disabled={isAllFilteredSelected}
461
+ size="small"
462
+ color="primary"
463
+ sx={{ textTransform: 'none' }}
464
+ >
465
+ Select Filtered ({totalFilteredItems})
466
+ </Button>
467
+ <Button
468
+ variant="contained"
469
+ startIcon={<DeselectAllIcon />}
470
+ onClick={handleDeselectAllFiltered}
471
+ disabled={isNoneFilteredSelected}
472
+ size="small"
473
+ color="secondary"
474
+ sx={{ textTransform: 'none' }}
475
+ >
476
+ Deselect Filtered
477
+ </Button>
478
+ <Divider orientation="vertical" flexItem sx={{ mx: 1 }} />
479
+ </>
480
+ )}
481
+ <Button
482
+ variant="outlined"
483
+ startIcon={<SelectAllIcon />}
484
+ onClick={handleSelectAll}
485
+ disabled={isAllSelected}
486
+ size="small"
487
+ sx={{ textTransform: 'none' }}
488
+ >
489
+ Select All
490
+ </Button>
491
+ <Button
492
+ variant="outlined"
493
+ startIcon={<DeselectAllIcon />}
494
+ onClick={handleDeselectAll}
495
+ disabled={isNoneSelected}
496
+ size="small"
497
+ color="secondary"
498
+ sx={{ textTransform: 'none' }}
499
+ >
500
+ Deselect All
501
+ </Button>
502
+ </Box>
503
+ </Toolbar>
504
+ </Paper>
505
+
506
+ {/* --- Search & Filter Panel --- */}
507
+ <Paper elevation={1} sx={{ mb: 3, p: 3, borderRadius: 2, bgcolor: 'background.paper' }}>
508
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 2, mb: 2 }}>
509
+ <FilterIcon color="primary" />
510
+ <Typography variant="h6" sx={{ fontWeight: 600 }}>
511
+ Search & Filter
512
+ </Typography>
513
+ {hasActiveSearch && (
514
+ <Button
515
+ size="small"
516
+ variant="outlined"
517
+ color="secondary"
518
+ onClick={handleClearAllSearches}
519
+ startIcon={<ClearIcon />}
520
+ sx={{ textTransform: 'none' }}
521
+ >
522
+ Clear All Filters
523
+ </Button>
524
+ )}
525
+ </Box>
526
+ <Grid container spacing={2}>
527
+ { /* @ts-ignore */ }
528
+ <Grid item xs={12} md={6}>
529
+ <TextField
530
+ fullWidth
531
+ variant="outlined"
532
+ label="Search by Group Name"
533
+ placeholder="e.g., user, admin, system..."
534
+ value={groupSearchTerm}
535
+ onChange={e => setGroupSearchTerm(e.target.value)}
536
+ InputProps={{
537
+ startAdornment: (
538
+ <InputAdornment position="start">
539
+ <SearchIcon color="action" />
540
+ </InputAdornment>
541
+ ),
542
+ endAdornment: groupSearchTerm && (
543
+ <InputAdornment position="end">
544
+ <IconButton size="small" onClick={handleClearGroupSearch}>
545
+ <ClearIcon fontSize="small" />
546
+ </IconButton>
547
+ </InputAdornment>
548
+ )
549
+ }}
550
+ />
551
+ </Grid>
552
+ { /* @ts-ignore */ }
553
+ <Grid item xs={12} md={6}>
554
+ <TextField
555
+ fullWidth
556
+ variant="outlined"
557
+ label="Search by Permission Name"
558
+ placeholder="e.g., create, edit, delete, view..."
559
+ value={itemSearchTerm}
560
+ onChange={e => setItemSearchTerm(e.target.value)}
561
+ InputProps={{
562
+ startAdornment: (
563
+ <InputAdornment position="start">
564
+ <SearchIcon color="action" />
565
+ </InputAdornment>
566
+ ),
567
+ endAdornment: itemSearchTerm && (
568
+ <InputAdornment position="end">
569
+ <IconButton size="small" onClick={handleClearItemSearch}>
570
+ <ClearIcon fontSize="small" />
571
+ </IconButton>
572
+ </InputAdornment>
573
+ )
574
+ }}
575
+ />
576
+ </Grid>
577
+ </Grid>
578
+ {hasActiveSearch && (
579
+ <Box sx={{ mt: 2, p: 2, bgcolor: 'action.hover', borderRadius: 1 }}>
580
+ <Typography variant="body2" color="text.secondary">
581
+ <strong>Search Results:</strong> {filteredGroupsCount} group{filteredGroupsCount !== 1 ? 's' : ''}
582
+ {' '}({totalFilteredItems} permission{totalFilteredItems !== 1 ? 's' : ''})
583
+ {' '}of {permissionsData.length} total groups ({totalPermissions} total permissions)
584
+ </Typography>
585
+ {debouncedGroupSearch && (
586
+ <Typography variant="caption" color="primary" sx={{ display: 'block', mt: 0.5 }}>
587
+ • Group filter: "{debouncedGroupSearch}"
588
+ </Typography>
589
+ )}
590
+ {debouncedItemSearch && (
591
+ <Typography variant="caption" color="primary" sx={{ display: 'block', mt: 0.5 }}>
592
+ • Permission filter: "{debouncedItemSearch}"
593
+ </Typography>
594
+ )}
595
+ </Box>
596
+ )}
597
+ </Paper>
598
+
599
+ {/* --- No Results Message --- */}
600
+ {hasActiveSearch && filteredPermissions.length === 0 && (
601
+ <Paper sx={{
602
+ p: 4,
603
+ textAlign: 'center',
604
+ bgcolor: 'background.default',
605
+ border: '1px dashed',
606
+ borderColor: 'divider'
607
+ }}>
608
+ <SearchIcon sx={{ fontSize: 48, color: 'text.disabled', mb: 2 }} />
609
+ <Typography variant="h6" color="text.secondary" gutterBottom>
610
+ No permissions found
611
+ </Typography>
612
+ <Typography variant="body2" color="text.disabled" sx={{ mb: 2 }}>
613
+ No permissions match your search criteria
614
+ {debouncedGroupSearch && ` for group "${debouncedGroupSearch}"`}
615
+ {debouncedItemSearch && ` for permission "${debouncedItemSearch}"`}
616
+ </Typography>
617
+ <Button
618
+ variant="outlined"
619
+ size="small"
620
+ onClick={handleClearAllSearches}
621
+ startIcon={<ClearIcon />}
622
+ >
623
+ Clear All Filters
624
+ </Button>
625
+ </Paper>
626
+ )}
627
+
628
+ {/* --- Permissions Grid --- */}
629
+ {filteredPermissions.length > 0 && (
630
+ <Grid container spacing={3}>
631
+ {filteredPermissions.map((group, groupIndex) => {
632
+ const groupLabel = group[0]?.group || 'Other';
633
+ const groupKey = groupLabel; // Use group name as stable key
634
+ const isExpanded = expandedCards[groupKey] || false;
635
+ const groupSelectedCount = getSelectedCount(group);
636
+ const isAllSelectedInGroup = isGroupSelected(group);
637
+ const hasMoreItems = group.length > INITIAL_ITEMS_COUNT;
638
+ const visibleItems = isExpanded ? group : group.slice(0, INITIAL_ITEMS_COUNT);
639
+ const remainingCount = group.length - INITIAL_ITEMS_COUNT;
640
+ return (
641
+ /* @ts-ignore */
642
+ <Grid item xs={12} md={4} key={groupIndex}>
643
+ <Card variant="outlined" sx={{
644
+ height: '100%',
645
+ display: 'flex',
646
+ flexDirection: 'column',
647
+ transition: 'all 0.2s ease-in-out',
648
+ '&:hover': {
649
+ boxShadow: 3,
650
+ borderColor: 'primary.main'
651
+ },
652
+ ...(hasActiveSearch && {
653
+ border: '2px solid',
654
+ borderColor: 'primary.light',
655
+ bgcolor: 'primary.50'
656
+ })
657
+ }}>
658
+ <CardContent sx={{
659
+ flexGrow: 1,
660
+ display: 'flex',
661
+ flexDirection: 'column',
662
+ p: 2,
663
+ '&:last-child': { pb: 2 }
664
+ }}>
665
+ <Box sx={{
666
+ display: 'flex',
667
+ alignItems: 'center',
668
+ justifyContent: 'space-between',
669
+ mb: 2,
670
+ minHeight: '32px'
671
+ }}>
672
+ <Typography variant="subtitle1" sx={{ fontWeight: 600, fontSize: '1rem', lineHeight: 1.2 }}>
673
+ {groupLabel}
674
+ </Typography>
675
+ <Chip
676
+ label={`${groupSelectedCount}/${group.length}`}
677
+ size="small"
678
+ color={isAllSelectedInGroup ? "primary" : groupSelectedCount > 0 ? "warning" : "default"}
679
+ sx={{ fontSize: '0.75rem', height: 24, mr: 1 }}
680
+ />
681
+ </Box>
682
+ <Box sx={{ mb: 2 }}>
683
+ <label style={checkboxStyles.selectAllLabel}>
684
+ <input
685
+ type="checkbox"
686
+ style={checkboxStyles.checkbox}
687
+ checked={isAllSelectedInGroup}
688
+ onChange={() => handleToggleGroup(group)}
689
+ />
690
+ Select all {groupLabel} permissions
691
+ </label>
692
+ <Divider sx={{ mt: 1 }} />
693
+ </Box>
694
+ <Box sx={{ flexGrow: 1, mb: hasMoreItems ? 2 : 0 }}>
695
+ <Stack spacing={0.5}>
696
+ {visibleItems.map((permission, permIndex) => {
697
+ const displayName = permission.name.split('.').pop();
698
+ const isChecked = isPermissionSelected(permission);
699
+ const shouldHighlight = debouncedItemSearch &&
700
+ (permission.name.toLowerCase().includes(debouncedItemSearch.toLowerCase()) ||
701
+ displayName?.toLowerCase().includes(debouncedItemSearch.toLowerCase()));
702
+ return (
703
+ <Box key={permIndex}>
704
+ <label style={checkboxStyles.checkboxLabel}>
705
+ <input
706
+ type="checkbox"
707
+ style={checkboxStyles.checkbox}
708
+ checked={isChecked}
709
+ onChange={() => handleTogglePermission(permission)}
710
+ />
711
+ <Box>
712
+ <Typography
713
+ variant="caption"
714
+ sx={{
715
+ fontSize: '0.8rem',
716
+ lineHeight: 1.3,
717
+ ...(shouldHighlight && {
718
+ bgcolor: 'warning.light',
719
+ color: 'warning.contrastText',
720
+ px: 0.5,
721
+ borderRadius: 0.5,
722
+ fontWeight: 600
723
+ })
724
+ }}
725
+ >
726
+ {displayName}
727
+ </Typography>
728
+ <Typography
729
+ variant="caption"
730
+ sx={{
731
+ color: 'text.disabled',
732
+ fontSize: '0.7rem',
733
+ ml: 0,
734
+ display: 'block',
735
+ maxWidth: '100%',
736
+ overflow: 'hidden',
737
+ textOverflow: 'ellipsis',
738
+ whiteSpace: 'nowrap'
739
+ }}
740
+ >
741
+ {permission.name}
742
+ </Typography>
743
+ </Box>
744
+ </label>
745
+ </Box>
746
+ );
747
+ })}
748
+ </Stack>
749
+ </Box>
750
+ {hasMoreItems && (
751
+ <Box sx={{
752
+ display: 'flex',
753
+ justifyContent: 'center',
754
+ mt: 'auto',
755
+ pt: 1,
756
+ borderTop: '1px solid',
757
+ borderColor: 'divider'
758
+ }}>
759
+ <Button
760
+ size="small"
761
+ variant="text"
762
+ onClick={() => setExpandedCards(prev => ({
763
+ ...prev,
764
+ [groupKey]: !isExpanded
765
+ }))}
766
+ sx={{
767
+ fontSize: '0.75rem',
768
+ minHeight: '28px',
769
+ textTransform: 'none'
770
+ }}
771
+ >
772
+ {isExpanded
773
+ ? 'Show Less ▲'
774
+ : `Show ${remainingCount} More ▼`
775
+ }
776
+ </Button>
777
+ </Box>
778
+ )}
779
+ </CardContent>
780
+ </Card>
781
+ </Grid>
782
+ );
783
+ })}
784
+ </Grid>
785
+ )}
786
+ </Box>
787
+ );
788
+ };
789
+
790
+ const PermissionsSelectorEdit: React.FC<IDashAutoAdminCustomFieldComponent> = (props) => {
791
+ const { record: contextRecord, resource, isPending,isLoading} = useEditContext();
792
+ if (isPending || isLoading) return <CircularProgress />;
793
+ return <PermissionsSelectorBase {...props} record={contextRecord} />;
794
+ };
795
+
796
+ const PermissionsSelectorCreate: React.FC<IDashAutoAdminCustomFieldComponent> = (props) => {
797
+ return <PermissionsSelectorBase {...props} record={{}} />;
798
+ };
799
+
800
+ const PermissionsSelector = ({
801
+ method,
802
+ attribute,
803
+ resourceConfig
804
+ }: IDashAutoAdminCustomFieldComponent) => {
805
+
806
+ switch (method) {
807
+ case 'edit':
808
+ return <PermissionsSelectorEdit attribute={attribute} method={method} resourceConfig={resourceConfig} />;
809
+ case 'create':
810
+ return <PermissionsSelectorCreate attribute={attribute} method={method} resourceConfig={resourceConfig} />;
811
+ case 'view':
812
+ return <><NotFound/></>
813
+ //<PermissionsSelectorView attribute={attribute} method={method} resourceConfig={resourceConfig} />;
814
+ default:
815
+ return null;
816
+ }
817
+ };
818
+
819
+ export default PermissionsSelector;