@dashadmin/dash-admin 1.3.73 → 1.3.74-srcfree.1

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 (289) hide show
  1. package/dist/components/tenant/TenancyPlan.js +307 -0
  2. package/dist/systemResources.js +18 -2
  3. package/package.json +25 -22
  4. package/src/AppAsyncWrapper.tsx +0 -42
  5. package/src/AppWrapper.tsx +0 -45
  6. package/src/DASHAdmin.tsx +0 -502
  7. package/src/DASHAdmin.tsx.old +0 -456
  8. package/src/RoutingWrapper.tsx +0 -143
  9. package/src/classes/DASHStorageClass.tsx +0 -8
  10. package/src/components/Input/RichTextField.tsx +0 -27
  11. package/src/components/Redirect.tsx +0 -46
  12. package/src/components/avatar/Avatar.tsx +0 -71
  13. package/src/components/avatar/SingleImageUploader.tsx +0 -107
  14. package/src/components/currency/Format.tsx +0 -79
  15. package/src/components/custom/Redirect.tsx +0 -23
  16. package/src/components/error/Error.tsx +0 -168
  17. package/src/components/geocoding/GeocodingField.tsx +0 -167
  18. package/src/components/i18n/BridgedLocalesMenuButton.tsx +0 -160
  19. package/src/components/i18n/LangSwitcher.tsx +0 -204
  20. package/src/components/loader/GlobalLoader.tsx +0 -49
  21. package/src/components/logs/LogFile.tsx +0 -88
  22. package/src/components/logs/LogFileById.tsx +0 -68
  23. package/src/components/logs/LogViewer.tsx +0 -43
  24. package/src/components/menu/AppMenu.tsx +0 -22
  25. package/src/components/menu/CustomMenuItemLink.tsx +0 -61
  26. package/src/components/menu/DarkToggleMode.tsx +0 -65
  27. package/src/components/menu/LanguageToggleMode.tsx +0 -120
  28. package/src/components/misc/CustomImageInput.tsx +0 -62
  29. package/src/components/misc/DASHGlobalErrorHandler.tsx +0 -194
  30. package/src/components/misc/DarkModeSwitcher.tsx +0 -112
  31. package/src/components/misc/HorizontalScroller.tsx +0 -225
  32. package/src/components/misc/LanguageSwitcher.tsx +0 -199
  33. package/src/components/misc/MUIHtmlToolTip.tsx +0 -15
  34. package/src/components/misc/MuiSimpleJsonTable.tsx +0 -279
  35. package/src/components/misc/MultiLevelTable.tsx +0 -229
  36. package/src/components/misc/NoResults.tsx +0 -28
  37. package/src/components/misc/PDFViewer.tsx +0 -85
  38. package/src/components/navigation/Breadcrumbs.tsx +0 -220
  39. package/src/components/navigation/BreadcrumbsManager.tsx +0 -310
  40. package/src/components/navigation/index.tsx +0 -5
  41. package/src/components/panel/Error.tsx +0 -168
  42. package/src/components/permission/AvailablePermissionsContext.tsx +0 -173
  43. package/src/components/permission/PermissionsSelector.tsx +0 -834
  44. package/src/components/permission/PermissionsSelectorList.tsx +0 -473
  45. package/src/components/permission/tsx +0 -0
  46. package/src/components/racustombuttons/CustomRAButton.tsx +0 -87
  47. package/src/components/racustombuttons/QuickButton.tsx +0 -117
  48. package/src/components/racustombuttons/QuickEditButton.tsx +0 -115
  49. package/src/components/racustombuttons/QuickIconButton.tsx +0 -122
  50. package/src/components/scrollbar/Scrollbar.tsx +0 -31
  51. package/src/components/selects/MultiSelect.tsx +0 -53
  52. package/src/components/selects/RASearchableSelect.tsx +0 -282
  53. package/src/components/selects/RASearchableSelectChips.tsx +0 -308
  54. package/src/components/selects/SearchableSelect.tsx +0 -139
  55. package/src/components/serviceAccount/ApiKeyRevealDialog.tsx +0 -129
  56. package/src/components/serviceAccount/ServiceAccountStatusSwitch.tsx +0 -99
  57. package/src/components/subscription/BillingCycleSelectInput.tsx +0 -68
  58. package/src/components/subscription/PlanAddonsSettings.tsx +0 -563
  59. package/src/components/subscription/PlanAuditLog.tsx +0 -453
  60. package/src/components/subscription/PlanFeaturesSettings.tsx +0 -243
  61. package/src/components/subscription/PlanLimitsSettings.tsx +0 -230
  62. package/src/components/subscription/PlanMetadataSettings.tsx +0 -306
  63. package/src/components/subscription/PlanPricesSettings.tsx +0 -307
  64. package/src/components/subscription/index.ts +0 -7
  65. package/src/components/svgelements/SvgLoading.tsx +0 -229
  66. package/src/components/svgelements/SvgLogo.tsx +0 -53
  67. package/src/components/svgelements/SvgLogoMin.tsx +0 -64
  68. package/src/components/svgelements/SvgShipping.tsx +0 -673
  69. package/src/components/tenancy/GlobalTenantWrapper.tsx +0 -84
  70. package/src/components/tenancy/TenantSwitcher.tsx +0 -514
  71. package/src/components/tenant/AvailablePermissionsContext.tsx +0 -0
  72. package/src/components/tenant/SettingsSections.tsx +0 -151
  73. package/src/components/tenant/TenancySettings.tsx +0 -122
  74. package/src/components/tenant/TenantAttributes.tsx +0 -153
  75. package/src/components/tenant/TenantAttributesContext.tsx +0 -163
  76. package/src/components/tenant/TenantSelector.tsx +0 -142
  77. package/src/components/tenant/TenantSettings.tsx +0 -184
  78. package/src/components/tenant/TenantSettingsContext.tsx +0 -165
  79. package/src/components/tenant/TenantTheme.tsx +0 -172
  80. package/src/components/user/AvatarComponent.tsx +0 -317
  81. package/src/components/user/TenantAvatarComponent.tsx +0 -99
  82. package/src/components/user/UserPreferences.tsx +0 -677
  83. package/src/config/ACTIONS.tsx +0 -26
  84. package/src/config/ConstantsService.tsx +0 -44
  85. package/src/config/DASHAdminSystemConstants.tsx +0 -183
  86. package/src/config/PARSERS.tsx +0 -9
  87. package/src/contexts/DashQueryClientContext.tsx +0 -113
  88. package/src/contexts/DashResourceContext.tsx +0 -34
  89. package/src/contexts/I18nBridgeContext.tsx +0 -156
  90. package/src/contexts/I18nBridgeSetter.tsx +0 -39
  91. package/src/contexts/I18nReduxSync.tsx +0 -27
  92. package/src/contexts/SubscriptionPlanFormatsProvider.tsx +0 -217
  93. package/src/contexts/SystemRequestsCache.tsx +0 -215
  94. package/src/contexts/auth/AuthContext.tsx +0 -567
  95. package/src/contexts/auth/AuthContextLocalStorage.tsx +0 -140
  96. package/src/contexts/auth/DASHAuthenticationService.tsx +0 -915
  97. package/src/contexts/auth/WindowContext.tsx +0 -15
  98. package/src/contexts/auth/index.tsx +0 -3
  99. package/src/contexts/com/FCMContext.tsx +0 -415
  100. package/src/contexts/com/LaravelEchoContext.tsx +0 -41
  101. package/src/contexts/com/LaravelEchoMgr.tsx +0 -155
  102. package/src/contexts/com/components/DefaultNotificationComponent.tsx +0 -20
  103. package/src/contexts/com/components/EchoNotificationsCenter.tsx +0 -65
  104. package/src/contexts/com/components/NotificationAttributesTable.tsx +0 -54
  105. package/src/contexts/com/components/NotificationRenderer.tsx +0 -42
  106. package/src/contexts/com/components/NotificationsWidget.tsx +0 -182
  107. package/src/contexts/com/components/notificationFormats.tsx +0 -50
  108. package/src/contexts/com/useLaravelEcho.tsx +0 -432
  109. package/src/contexts/dictionary/DictionaryContext.tsx +0 -94
  110. package/src/declarations.d.ts +0 -17
  111. package/src/default-theme/DASHAppProviders.tsx +0 -117
  112. package/src/default-theme/DashThemeContext.tsx +0 -209
  113. package/src/default-theme/DashThemeContext.tsx.fast +0 -143
  114. package/src/default-theme/DashThemeContext.tsx.old +0 -306
  115. package/src/default-theme/DashThemeHelperProvider.tsx +0 -98
  116. package/src/default-theme/DomainAppLayout.tsx +0 -166
  117. package/src/default-theme/DomainHeader.tsx +0 -162
  118. package/src/default-theme/DomainTheme.tsx +0 -59
  119. package/src/default-theme/FullLayoutMarkup.tsx +0 -231
  120. package/src/default-theme/StaticLayout.tsx +0 -47
  121. package/src/default-theme/index.tsx +0 -11
  122. package/src/default-theme/menu/AppDashboardGrid.tsx +0 -279
  123. package/src/default-theme/menu/AppMaterialMenu.tsx +0 -546
  124. package/src/default-theme/menu/AppMenuComponents/SubmenuPortal.tsx +0 -61
  125. package/src/default-theme/menu/AppMenuComponents/collapsed/CollapsedSidebarItem.tsx +0 -264
  126. package/src/default-theme/menu/AppMenuComponents/collapsed/CollapsedSidebarItems.tsx +0 -31
  127. package/src/default-theme/menu/AppMenuComponents/expanded/CollapsableSidebarMenu.tsx +0 -293
  128. package/src/default-theme/menu/AppMenuComponents/expanded/SidebarItem.tsx +0 -92
  129. package/src/default-theme/menu/AppMenuComponents/getItem.tsx +0 -17
  130. package/src/default-theme/menu/AppMenuComponents/interfaces.tsx +0 -41
  131. package/src/default-theme/menu/AppMenuComponents/submenuConstants.ts +0 -90
  132. package/src/default-theme/menu/AppSidebarMaterial.tsx +0 -339
  133. package/src/default-theme/menu/SidebarActions.tsx +0 -84
  134. package/src/default-theme/updateDomCssVariables.tsx +0 -176
  135. package/src/helpers/checkRole.tsx +0 -66
  136. package/src/helpers/parseAxiosError.tsx +0 -41
  137. package/src/hooks/audio/useAudio.tsx +0 -39
  138. package/src/hooks/axios.tsx +0 -165
  139. package/src/hooks/data/useDashboardStats.tsx +0 -65
  140. package/src/hooks/data/usePackageByClientsStats.tsx +0 -44
  141. package/src/hooks/data/usePackageByCommunesStats.tsx +0 -44
  142. package/src/hooks/data/usePackageStats.tsx +0 -69
  143. package/src/hooks/data/usePackageWithdrawDetails.tsx +0 -61
  144. package/src/hooks/data/useStats.tsx +0 -86
  145. package/src/hooks/isCurrentPath.tsx +0 -22
  146. package/src/hooks/notifications/WSMessagesManager.tsx +0 -152
  147. package/src/hooks/notifications/WSPusherManager.tsx +0 -92
  148. package/src/hooks/useBreadcrumbs.tsx +0 -329
  149. package/src/hooks/useClickOutside.tsx +0 -57
  150. package/src/hooks/useFormPersistance.tsx +0 -150
  151. package/src/hooks/useGlobalErrorMediator.tsx +0 -43
  152. package/src/hooks/useGlobalLoaderMgr.tsx +0 -21
  153. package/src/hooks/useHash.tsx +0 -27
  154. package/src/hooks/useLocalStorage.tsx +0 -196
  155. package/src/hooks/usePolyglotTranslation.tsx +0 -62
  156. package/src/hooks/usePrevious.tsx +0 -9
  157. package/src/hooks/usePrintSelected.tsx +0 -37
  158. package/src/hooks/useVirtualHash.tsx +0 -33
  159. package/src/hooks/window/useWindowSize.tsx +0 -36
  160. package/src/index.tsx +0 -134
  161. package/src/interfaces/IAppResourceConfig.tsx +0 -20
  162. package/src/interfaces/Log.tsx +0 -16
  163. package/src/interfaces/Tenant.tsx +0 -25
  164. package/src/interfaces/communication/IActions.tsx +0 -5
  165. package/src/interfaces/communication/INotification.tsx +0 -21
  166. package/src/interfaces/communication/IPayload.tsx +0 -3
  167. package/src/interfaces/communication/IRequestAction.tsx +0 -10
  168. package/src/interfaces/communication/IRequestPayload.tsx +0 -7
  169. package/src/interfaces/communication/IResponseAction.tsx +0 -7
  170. package/src/interfaces/misc/IAny.tsx +0 -3
  171. package/src/interfaces/misc/IFlashMessage.tsx +0 -10
  172. package/src/interfaces/navigation/IAppMenu.ts +0 -14
  173. package/src/interfaces/navigation/ICollapsableSidebarMenu.ts +0 -12
  174. package/src/interfaces/navigation/IMenuItem.ts +0 -16
  175. package/src/interfaces/notifications/IModel.tsx +0 -6
  176. package/src/interfaces/notifications/IModelField.tsx +0 -8
  177. package/src/interfaces/notifications/IUserNotification.tsx +0 -12
  178. package/src/interfaces/notifications/IUserNotificationData.tsx +0 -13
  179. package/src/interfaces/notifications/IUserNotificationPayload.tsx +0 -8
  180. package/src/interfaces/user/IGetAuth.tsx +0 -92
  181. package/src/interfaces/user/ITenantSettings.tsx +0 -3
  182. package/src/interfaces/user/IUser.tsx +0 -60
  183. package/src/interfaces/user/IUserSettings.tsx +0 -43
  184. package/src/interfaces.tsx +0 -6
  185. package/src/layout/AppLayout.tsx +0 -112
  186. package/src/layout/ApplicationLayout.tsx +0 -197
  187. package/src/layout/MotionWrapper.original.tsx +0 -236
  188. package/src/layout/MotionWrapper.tsx +0 -236
  189. package/src/layout/ResourceMenu.tsx +0 -164
  190. package/src/layout/ResoureLayout.tsx +0 -105
  191. package/src/layout/TransitionWrapper.tsx +0 -125
  192. package/src/pages/ChangePassword.tsx +0 -179
  193. package/src/pages/DASHLanding.tsx +0 -22
  194. package/src/pages/DASHLightWeightLogin.tsx +0 -611
  195. package/src/pages/DASHSimpleLogin.tsx +0 -260
  196. package/src/pages/Login.tsx +0 -111
  197. package/src/pages/Profile.tsx +0 -357
  198. package/src/pages/RecoverPassword.tsx +0 -175
  199. package/src/pages/SingleImageUploader.tsx +0 -55
  200. package/src/pages/VerifyAccount.tsx +0 -128
  201. package/src/providers/authProvider.tsx +0 -217
  202. package/src/providers/dataProvider.tsx +0 -672
  203. package/src/providers/i18n/en.ts +0 -646
  204. package/src/providers/i18n/es.ts +0 -652
  205. package/src/providers/i18n/languages.tsx +0 -8
  206. package/src/providers/i18n/mergeTranslations.ts +0 -53
  207. package/src/providers/i18nProvider.tsx +0 -23
  208. package/src/react-admin-dash/RADashComponent.tsx +0 -240
  209. package/src/react-admin-dash/Resource.tsx +0 -77
  210. package/src/resources/Brand/BrandResource.tsx +0 -130
  211. package/src/resources/DASHResourceLoader.ts +0 -180
  212. package/src/resources/Log/LogResource.tsx +0 -73
  213. package/src/resources/Tenant/ImpersonateTenantResource.tsx +0 -113
  214. package/src/resources/Trash/TrashTemplate.tsx +0 -180
  215. package/src/resources/User/components/AvatarUploadField.tsx +0 -57
  216. package/src/resources/User/components/PasswordFields.tsx +0 -73
  217. package/src/resources/User/getProfileMenu.ts +0 -57
  218. package/src/resources/User/profileResource.tsx +0 -51
  219. package/src/resources/User/userLayout.tsx +0 -62
  220. package/src/resources/User/userResource.tsx +0 -111
  221. package/src/resources/User/userSchema.tsx +0 -213
  222. package/src/resources/User/usersFilters.tsx +0 -21
  223. package/src/resources.tsx +0 -280
  224. package/src/schemas/log.tsx +0 -45
  225. package/src/schemas/notification.tsx +0 -42
  226. package/src/schemas/permissions.tsx +0 -44
  227. package/src/schemas/roles.tsx +0 -48
  228. package/src/schemas/rolesDataGrid.tsx +0 -48
  229. package/src/schemas/subscription/components/SubscriptionActions.tsx +0 -153
  230. package/src/schemas/subscription/components/SubscriptionPaymentHistory.tsx +0 -127
  231. package/src/schemas/subscription/components/SubscriptionPlanFeatures.tsx +0 -162
  232. package/src/schemas/subscription/components/SubscriptionPlanPreview.tsx +0 -141
  233. package/src/schemas/subscription/components/SubscriptionPlanStats.tsx +0 -318
  234. package/src/schemas/subscription/components/SubscriptionStatusIndicator.tsx +0 -72
  235. package/src/schemas/subscription/subscriptionPlanSchema.tsx +0 -185
  236. package/src/schemas/subscription/subscriptionSchema.tsx +0 -152
  237. package/src/schemas/subscriptionPlan.ts +0 -422
  238. package/src/schemas/tenant.tsx +0 -129
  239. package/src/schemas/tenantUser.tsx +0 -96
  240. package/src/schemas/tenant_superadmin.tsx +0 -119
  241. package/src/schemas/user.tsx +0 -26
  242. package/src/systemResources.old.tsx +0 -928
  243. package/src/systemResources.tsx +0 -1369
  244. package/src/templates/ResourceTemplate.tsx +0 -240
  245. package/src/templates/ResourceTemplate.tsx.memoized_experiment +0 -350
  246. package/src/templates/ResourceTemplate.tsx.original +0 -396
  247. package/src/templates/ResourceTemplateCreate.tsx +0 -182
  248. package/src/templates/ResourceTemplateEdit.tsx +0 -176
  249. package/src/templates/ResourceTemplateFull.tsx +0 -581
  250. package/src/templates/ResourceTemplateList.tsx +0 -340
  251. package/src/templates/ResourceTemplateOld.tsx.bkup +0 -567
  252. package/src/templates/ResourceTemplateShow.tsx +0 -88
  253. package/src/templates/TrashTemplate.tsx +0 -179
  254. package/src/tenantResources.tsx +0 -223
  255. package/src/test_portal_bubbles.tsx +0 -40
  256. package/src/theme/AppHeader.tsx +0 -52
  257. package/src/theme/AppLayoutSetting.tsx +0 -33
  258. package/src/theme/AppLogo.tsx +0 -13
  259. package/src/theme/AppSidebar.tsx +0 -12
  260. package/src/theme/AppSidebarContent.tsx +0 -105
  261. package/src/theme/AppSidebarLogo.tsx +0 -48
  262. package/src/theme/components/PageTitle.tsx +0 -37
  263. package/src/utils/cache/CacheInvalidatorContext.tsx +0 -125
  264. package/src/utils/cache/CacheInvalidatorListenerComponent.tsx +0 -10
  265. package/src/utils/cache/useCacheInvalidatorListener.tsx +0 -27
  266. package/src/utils/convertFileToBase64.tsx +0 -9
  267. package/src/utils/convertToFile.tsx +0 -14
  268. package/src/utils/cookies.tsx +0 -33
  269. package/src/utils/dashDefaultQueryClient.tsx +0 -34
  270. package/src/utils/dataUrlToBlob.tsx +0 -30
  271. package/src/utils/deepReplace.tsx +0 -19
  272. package/src/utils/getProfileMenu.tsx +0 -41
  273. package/src/utils/getTenantSettings.tsx +0 -9
  274. package/src/utils/getType.tsx +0 -8
  275. package/src/utils/getUserSettings.tsx +0 -8
  276. package/src/utils/hasCode.tsx +0 -14
  277. package/src/utils/index.ts +0 -19
  278. package/src/utils/injectTenantStyles.ts +0 -28
  279. package/src/utils/isComponent.tsx +0 -45
  280. package/src/utils/navEvents.tsx +0 -91
  281. package/src/utils/prototypes.tsx +0 -5
  282. package/src/utils/regexp.tsx +0 -4
  283. package/src/utils/resolveObjectPath.tsx +0 -4
  284. package/src/utils/setNativeValue.tsx +0 -24
  285. package/src/utils/slugify.tsx +0 -11
  286. package/src/utils/validators/emailValidator.tsx +0 -6
  287. package/src/utils/validators/requiredValidator.tsx +0 -5
  288. package/src/utils/validators/rutValidator.tsx +0 -31
  289. package/src/utils/validators.tsx +0 -96
@@ -1,329 +0,0 @@
1
- import { useCallback, useEffect, useMemo } from 'react';
2
- import { useLocation, useParams } from 'react-router-dom';
3
- import { useDispatch, useSelector } from 'react-redux';
4
- import { useStore } from 'react-admin';
5
- import { IBreadcrumbItem, IDASHAppState, DASH_REDUX_ACTIONS, IPageState } from 'dash-admin-state';
6
- import { IDashAutoAdminResourceConfig } from 'dash-auto-admin';
7
- import { DASHAdminSystemConstants } from 'dash-constants';
8
-
9
- // ============================================================================
10
- // TYPES & INTERFACES
11
- // ============================================================================
12
-
13
- export interface UseBreadcrumbsOptions {
14
- /** Whether to auto-update breadcrumbs on route change */
15
- autoUpdate?: boolean;
16
- /** Custom label map for route segments */
17
- labelMap?: Record<string, string>;
18
- /** Whether to include the home item */
19
- includeHome?: boolean;
20
- /** Home path */
21
- homePath?: string;
22
- /** Home label */
23
- homeLabel?: string;
24
- /** Custom breadcrumb generator function */
25
- customGenerator?: (pathname: string, resourceConfig?: IDashAutoAdminResourceConfig) => IBreadcrumbItem[];
26
- /** Whether to fetch record name for detail pages */
27
- fetchRecordName?: boolean;
28
- /** Field to use as record name (default: 'name') */
29
- recordNameField?: string;
30
- }
31
-
32
- export interface UseBreadcrumbsResult {
33
- /** Current breadcrumbs */
34
- breadcrumbs: IBreadcrumbItem[];
35
- /** Manually set breadcrumbs */
36
- setBreadcrumbs: (items: IBreadcrumbItem[]) => void;
37
- /** Add a breadcrumb item */
38
- addBreadcrumb: (item: IBreadcrumbItem) => void;
39
- /** Clear all breadcrumbs */
40
- clearBreadcrumbs: () => void;
41
- /** Current pathname */
42
- pathname: string;
43
- }
44
-
45
- // ============================================================================
46
- // DEFAULT LABEL MAPPINGS
47
- // ============================================================================
48
-
49
- const defaultLabelMap: Record<string, string> = {
50
- // Common actions
51
- 'create': 'Crear',
52
- 'edit': 'Editar',
53
- 'show': 'Ver',
54
- 'list': 'Lista',
55
- 'inline': 'Detalle',
56
- 'trash': 'Papelera',
57
-
58
- // Common routes
59
- 'admin': 'Admin',
60
- 'system': 'Sistema',
61
- 'settings': 'Configuración',
62
- 'users': 'Usuarios',
63
- 'roles': 'Roles',
64
- 'permissions': 'Permisos',
65
- 'tenants': 'Tenants',
66
- 'profile': 'Perfil',
67
- 'dashboard': 'Dashboard',
68
- };
69
-
70
- // ============================================================================
71
- // HELPER FUNCTIONS
72
- // ============================================================================
73
-
74
- /**
75
- * Parse a route segment into a readable label
76
- */
77
- const parseSegmentLabel = (
78
- segment: string,
79
- labelMap: Record<string, string>,
80
- resourceConfig?: IDashAutoAdminResourceConfig
81
- ): string => {
82
- // Check custom label map first
83
- if (labelMap[segment]) {
84
- return labelMap[segment];
85
- }
86
-
87
- // Check default label map
88
- if (defaultLabelMap[segment]) {
89
- return defaultLabelMap[segment];
90
- }
91
-
92
- // Check if segment matches resource model
93
- if (resourceConfig && resourceConfig.model?.includes(segment)) {
94
- return resourceConfig.label || segment;
95
- }
96
-
97
- // Convert kebab-case or snake_case to Title Case
98
- return segment
99
- .replace(/[-_]/g, ' ')
100
- .replace(/\b\w/g, char => char.toUpperCase());
101
- };
102
-
103
- /**
104
- * Check if a segment is an ID (numeric or UUID-like)
105
- */
106
- const isIdSegment = (segment: string): boolean => {
107
- // Check for numeric ID
108
- if (/^\d+$/.test(segment)) {
109
- return true;
110
- }
111
- // Check for UUID
112
- if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(segment)) {
113
- return true;
114
- }
115
- // Check for short hash-like IDs
116
- if (/^[a-z0-9]{20,}$/i.test(segment)) {
117
- return true;
118
- }
119
- return false;
120
- };
121
-
122
- /**
123
- * Generate breadcrumbs from pathname
124
- */
125
- const generateBreadcrumbsFromPath = (
126
- pathname: string,
127
- labelMap: Record<string, string>,
128
- resourceConfig?: IDashAutoAdminResourceConfig,
129
- includeHome?: boolean,
130
- homePath?: string,
131
- homeLabel?: string,
132
- recordName?: string
133
- ): IBreadcrumbItem[] => {
134
- const URL_PREFIX = DASHAdminSystemConstants.system.URL_PREFIX || '';
135
-
136
- // Remove URL prefix and clean path
137
- let cleanPath = pathname;
138
- if (URL_PREFIX && cleanPath.startsWith(URL_PREFIX)) {
139
- cleanPath = cleanPath.slice(URL_PREFIX.length);
140
- }
141
-
142
- // Split into segments and filter empty ones
143
- const segments = cleanPath.split('/').filter(Boolean);
144
-
145
- if (segments.length === 0) {
146
- return [];
147
- }
148
-
149
- const breadcrumbs: IBreadcrumbItem[] = [];
150
-
151
- // Add home item if requested
152
- if (includeHome) {
153
- breadcrumbs.push({
154
- label: homeLabel || 'Home',
155
- path: homePath || '/',
156
- });
157
- }
158
-
159
- let currentPath = URL_PREFIX;
160
-
161
- // Ensure path starts with slash if prefix doesn't have one
162
- if (currentPath && !currentPath.startsWith('/')) {
163
- currentPath = `/${currentPath}`;
164
- }
165
-
166
- let lastIdIndex = -1;
167
-
168
- segments.forEach((segment, index) => {
169
- currentPath += `/${segment}`;
170
- const isLast = index === segments.length - 1;
171
- const isId = isIdSegment(segment);
172
-
173
- // Skip adding ID segments directly, we'll handle them specially
174
- if (isId) {
175
- lastIdIndex = index;
176
- // If we have a record name and this is related to the last ID, use it
177
- if (recordName && isLast) {
178
- breadcrumbs.push({
179
- label: recordName,
180
- path: isLast ? undefined : currentPath,
181
- isActive: isLast,
182
- });
183
- } else {
184
- // Use a generic "Record #ID" label
185
- breadcrumbs.push({
186
- label: `#${segment.substring(0, 8)}${segment.length > 8 ? '...' : ''}`,
187
- path: isLast ? undefined : currentPath,
188
- isActive: isLast,
189
- data: { id: segment },
190
- });
191
- }
192
- return;
193
- }
194
-
195
- // Get the label for this segment
196
- const label = parseSegmentLabel(segment, labelMap, resourceConfig);
197
-
198
- breadcrumbs.push({
199
- label,
200
- path: isLast ? undefined : currentPath,
201
- isActive: isLast,
202
- });
203
- });
204
-
205
- return breadcrumbs;
206
- };
207
-
208
- // ============================================================================
209
- // HOOK
210
- // ============================================================================
211
-
212
- export const useBreadcrumbs = (options: UseBreadcrumbsOptions = {}): UseBreadcrumbsResult => {
213
- const {
214
- autoUpdate = true,
215
- labelMap = {},
216
- includeHome = false,
217
- homePath = '/',
218
- homeLabel = 'Home',
219
- customGenerator,
220
- fetchRecordName = true,
221
- recordNameField = 'name',
222
- } = options;
223
-
224
- const dispatch = useDispatch();
225
- const location = useLocation();
226
- const params = useParams();
227
-
228
- // Get resource config from store
229
- const [resourceConfig] = useStore<IDashAutoAdminResourceConfig>('resourceConfig');
230
-
231
- // Get current page state including existing breadcrumbs
232
- const pageState: IPageState = useSelector(
233
- (state: IDASHAppState<any, any, IDashAutoAdminResourceConfig>) => state.page
234
- );
235
-
236
- // Note: Record context is not available at the layout level
237
- // Use the record prop in options if you need to pass record data
238
- const record: any = null;
239
-
240
- // Merge label maps
241
- const mergedLabelMap = useMemo(() => ({
242
- ...defaultLabelMap,
243
- ...labelMap,
244
- }), [labelMap]);
245
-
246
- // Get record name from record context
247
- const recordName = useMemo(() => {
248
- if (!fetchRecordName || !record) return undefined;
249
-
250
- // Try common name fields
251
- const nameFields = [recordNameField, 'name', 'title', 'label', 'displayName', 'username'];
252
- for (const field of nameFields) {
253
- if (record[field]) {
254
- return String(record[field]);
255
- }
256
- }
257
-
258
- // Use recordRepresentation if available
259
- if (resourceConfig?.recordRepresentation) {
260
- const repr = resourceConfig.recordRepresentation;
261
- if (typeof repr === 'string' && record[repr]) {
262
- return String(record[repr]);
263
- }
264
- }
265
-
266
- return undefined;
267
- }, [record, fetchRecordName, recordNameField, resourceConfig]);
268
-
269
- // Generate breadcrumbs
270
- const breadcrumbs = useMemo(() => {
271
- if (customGenerator) {
272
- return customGenerator(location.pathname, resourceConfig);
273
- }
274
-
275
- return generateBreadcrumbsFromPath(
276
- location.pathname,
277
- mergedLabelMap,
278
- resourceConfig,
279
- includeHome,
280
- homePath,
281
- homeLabel,
282
- recordName
283
- );
284
- }, [
285
- location.pathname,
286
- mergedLabelMap,
287
- resourceConfig,
288
- includeHome,
289
- homePath,
290
- homeLabel,
291
- recordName,
292
- customGenerator,
293
- ]);
294
-
295
- // Set breadcrumbs action
296
- const setBreadcrumbs = useCallback((items: IBreadcrumbItem[]) => {
297
- dispatch(DASH_REDUX_ACTIONS.updatePage({ breadcrumbs: items }));
298
- }, [dispatch]);
299
-
300
- // Add breadcrumb action
301
- const addBreadcrumb = useCallback((item: IBreadcrumbItem) => {
302
- const currentBreadcrumbs = pageState.breadcrumbs || [];
303
- dispatch(DASH_REDUX_ACTIONS.updatePage({
304
- breadcrumbs: [...currentBreadcrumbs, item]
305
- }));
306
- }, [dispatch, pageState.breadcrumbs]);
307
-
308
- // Clear breadcrumbs action
309
- const clearBreadcrumbs = useCallback(() => {
310
- dispatch(DASH_REDUX_ACTIONS.updatePage({ breadcrumbs: [] }));
311
- }, [dispatch]);
312
-
313
- // Auto-update breadcrumbs on route change
314
- useEffect(() => {
315
- if (autoUpdate && breadcrumbs.length > 0) {
316
- setBreadcrumbs(breadcrumbs);
317
- }
318
- }, [autoUpdate, breadcrumbs, setBreadcrumbs]);
319
-
320
- return {
321
- breadcrumbs: pageState.breadcrumbs || breadcrumbs,
322
- setBreadcrumbs,
323
- addBreadcrumb,
324
- clearBreadcrumbs,
325
- pathname: location.pathname,
326
- };
327
- };
328
-
329
- export default useBreadcrumbs;
@@ -1,57 +0,0 @@
1
- import { useEffect, useRef } from 'react';
2
-
3
- /**
4
- * Closes a dropdown/menu when the user interacts outside of it.
5
- *
6
- * Takes an ARRAY of refs on purpose: these menus render their content via
7
- * `ReactDOM.createPortal(..., document.body)`, so the trigger (e.g. the
8
- * avatar) and the menu content are two separate DOM subtrees — a click
9
- * inside the portal is not a descendant of the trigger ref, so checking
10
- * only the trigger would treat every click inside the menu itself as
11
- * "outside" and close it immediately. Pass every root that should count as
12
- * "inside" (trigger + portal content).
13
- *
14
- * Listens on 'mousedown'/'touchstart' rather than 'click': the containment
15
- * check already excludes clicks on the trigger itself (so it never
16
- * self-closes the menu it just opened), and the earlier event avoids fights
17
- * with libraries that stopPropagation() on 'click'.
18
- *
19
- * `enabled` lets the caller skip attaching the listener entirely while the
20
- * menu is closed (pass the same `open` state driving the menu) instead of
21
- * registering a global document listener for the lifetime of the component.
22
- */
23
- const useClickOutside = (
24
- refs: React.RefObject<HTMLElement>[],
25
- onClickOutside: () => void,
26
- enabled: boolean = true,
27
- ) => {
28
- // Ref so the effect doesn't need to re-subscribe every time the caller
29
- // passes a new callback identity (common here since these callbacks
30
- // close over component state).
31
- const callbackRef = useRef(onClickOutside);
32
- callbackRef.current = onClickOutside;
33
-
34
- useEffect(() => {
35
- if (!enabled) return;
36
-
37
- const handlePointerDown = (e: MouseEvent | TouchEvent) => {
38
- const target = e.target as Node;
39
- const isInside = refs.some((ref) => ref.current && ref.current.contains(target));
40
- if (!isInside) {
41
- callbackRef.current();
42
- }
43
- };
44
-
45
- document.addEventListener('mousedown', handlePointerDown);
46
- document.addEventListener('touchstart', handlePointerDown);
47
- return () => {
48
- document.removeEventListener('mousedown', handlePointerDown);
49
- document.removeEventListener('touchstart', handlePointerDown);
50
- };
51
- // eslint-disable-next-line react-hooks/exhaustive-deps -- `refs` are
52
- // stable useRef objects from the caller; only `enabled` should
53
- // re-trigger (re)subscription.
54
- }, [enabled]);
55
- };
56
-
57
- export default useClickOutside;
@@ -1,150 +0,0 @@
1
- import { useEffect, useCallback, useRef } from 'react';
2
- import { useFormContext } from 'react-hook-form';
3
- import { useParams } from 'react-router-dom';
4
- import { dashStorage } from 'dash-utils';
5
- interface FormPersistenceOptions {
6
- persistState?: boolean;
7
- storageKey?: string;
8
- debounceMs?: number;
9
- excludeFields?: string[];
10
- }
11
-
12
- export const useFormPersistence = (options: FormPersistenceOptions = {}) => {
13
- const {
14
- persistState = false,
15
- storageKey,
16
- debounceMs = 1000,
17
- excludeFields = []
18
- } = options;
19
-
20
- const { watch, setValue, getValues } = useFormContext();
21
- const { id: tabId } = useParams();
22
- const debounceRef = useRef<ReturnType<typeof setTimeout>>(null);
23
-
24
- // Generate storage key
25
- const finalStorageKey = storageKey || `tab-form-${tabId}`;
26
-
27
- // Save form data to localStorage
28
- const saveFormData = useCallback((data: any) => {
29
- if (!persistState) return;
30
-
31
- try {
32
- // Filter out excluded fields
33
- const filteredData = { ...data };
34
- excludeFields.forEach(field => {
35
- delete filteredData[field];
36
- });
37
-
38
- const persistData = {
39
- formData: filteredData,
40
- timestamp: Date.now(),
41
- tabId
42
- };
43
-
44
- dashStorage.setItem(finalStorageKey, JSON.stringify(persistData));
45
- console.log('📦 Form data persisted:', finalStorageKey);
46
- } catch (error) {
47
- console.error('Failed to persist form data:', error);
48
- }
49
- }, [persistState, finalStorageKey, excludeFields, tabId]);
50
-
51
- // Load form data from localStorage
52
- const loadFormData = useCallback(() => {
53
- if (!persistState) return null;
54
-
55
- try {
56
- const stored = dashStorage.getItem(finalStorageKey);
57
- if (!stored) return null;
58
-
59
- const persistData = JSON.parse(stored);
60
-
61
- // Check if data is not too old (optional: 24 hours)
62
- const maxAge = 24 * 60 * 60 * 1000; // 24 hours
63
- if (Date.now() - persistData.timestamp > maxAge) {
64
- dashStorage.removeItem(finalStorageKey);
65
- return null;
66
- }
67
-
68
- console.log('📦 Form data loaded from storage:', finalStorageKey);
69
- return persistData.formData;
70
- } catch (error) {
71
- console.error('Failed to load form data:', error);
72
- return null;
73
- }
74
- }, [persistState, finalStorageKey]);
75
-
76
- // Restore form data
77
- const restoreFormData = useCallback(() => {
78
- const savedData = loadFormData();
79
- if (!savedData) return false;
80
-
81
- try {
82
- // Restore each field
83
- Object.keys(savedData).forEach(fieldName => {
84
- setValue(fieldName, savedData[fieldName], {
85
- shouldDirty: true,
86
- shouldTouch: true,
87
- shouldValidate: false
88
- });
89
- });
90
-
91
- console.log('✅ Form data restored successfully');
92
- return true;
93
- } catch (error) {
94
- console.error('Failed to restore form data:', error);
95
- return false;
96
- }
97
- }, [loadFormData, setValue]);
98
-
99
- // Clear persisted data
100
- const clearPersistedData = useCallback(() => {
101
- try {
102
- dashStorage.removeItem(finalStorageKey);
103
- console.log('🗑️ Persisted form data cleared:', finalStorageKey);
104
- } catch (error) {
105
- console.error('Failed to clear persisted data:', error);
106
- }
107
- }, [finalStorageKey]);
108
-
109
- // Watch for form changes and save with debouncing
110
- useEffect(() => {
111
- if (!persistState) return;
112
-
113
- const subscription = watch((data) => {
114
- // Clear existing timeout
115
- if (debounceRef.current) {
116
- clearTimeout(debounceRef.current);
117
- }
118
-
119
- // Set new timeout
120
- debounceRef.current = setTimeout(() => {
121
- saveFormData(data);
122
- }, debounceMs);
123
- });
124
-
125
- return () => {
126
- subscription.unsubscribe();
127
- if (debounceRef.current) {
128
- clearTimeout(debounceRef.current);
129
- }
130
- };
131
- }, [watch, persistState, saveFormData, debounceMs]);
132
-
133
- // Cleanup on unmount
134
- useEffect(() => {
135
- return () => {
136
- if (debounceRef.current) {
137
- clearTimeout(debounceRef.current);
138
- }
139
- };
140
- }, []);
141
-
142
- return {
143
- restoreFormData,
144
- clearPersistedData,
145
- loadFormData,
146
- saveFormData: () => saveFormData(getValues())
147
- };
148
- };
149
-
150
- export default useFormPersistence;
@@ -1,43 +0,0 @@
1
- import { random } from 'lodash';
2
- import React, { useState } from 'react';
3
- import { dashStorage } from 'dash-utils';
4
- const useGlobalErrorMediator = () => {
5
- const [error, setError] = React.useState<any>(null);
6
- const errorChangeHandler = React.useCallback((e) => {
7
- if (dashStorage.getItem('lastGlobalError') === JSON.stringify(e.data)) {
8
- return;
9
- }
10
-
11
- setError(e.data);
12
- dashStorage.setItem('lastGlobalError', JSON.stringify(e.data));
13
-
14
- setTimeout(() => {
15
- dashStorage.setItem('lastGlobalError', JSON.stringify({}));
16
- }, 1000);
17
- }, []);
18
-
19
- React.useEffect(() => {
20
- dashStorage.setItem('lastGlobalError', JSON.stringify({}));
21
-
22
- window.addEventListener('GlobalError', errorChangeHandler);
23
- return () => {
24
- dashStorage.setItem('lastGlobalError', JSON.stringify({}));
25
- window.removeEventListener('GlobalError', errorChangeHandler);
26
- };
27
- }, []);
28
-
29
- const _update = React.useCallback(
30
- (newError) => {
31
- window.dispatchEvent(new MessageEvent('GlobalError', { data: {error:newError} }));
32
- },
33
- [error],
34
- );
35
-
36
- const sendError = (error: any) => {
37
- _update(error);
38
- };
39
-
40
- return { error, sendError };
41
- };
42
-
43
- export default useGlobalErrorMediator;
@@ -1,21 +0,0 @@
1
- import React, { useState } from 'react';
2
- import { useDispatch, useSelector } from 'react-redux';
3
-
4
- const useGlobalLoaderMgr = () => {
5
- const useLoader = useState<boolean>(false);
6
- React.useEffect(() => {
7
-
8
- window.addEventListener('dash-global-loader', (e: any) => {
9
-
10
- return useLoader[1](e.data)
11
- });
12
- return () => {
13
- window.removeEventListener('dash-global-loader', (e: any) =>
14
- useLoader[1](e.data),
15
- );
16
- };
17
- }, []);
18
- return useLoader;
19
- };
20
-
21
- export default useGlobalLoaderMgr;
@@ -1,27 +0,0 @@
1
- import React from 'react';
2
-
3
- const useHash = () => {
4
- const [hash, setHash] = React.useState(() => window.location.hash);
5
-
6
- const hashChangeHandler = React.useCallback(() => {
7
- setHash(window.location.hash);
8
- }, []);
9
-
10
- React.useEffect(() => {
11
- window.addEventListener('hashchange', hashChangeHandler);
12
- return () => {
13
- window.removeEventListener('hashchange', hashChangeHandler);
14
- };
15
- }, []);
16
-
17
- const updateHash = React.useCallback(
18
- (newHash) => {
19
- /*if (newHash !== hash)*/ window.location.hash = newHash;
20
- },
21
- [hash],
22
- );
23
-
24
- return [hash, updateHash];
25
- };
26
-
27
- export default useHash;