@solidxai/core-ui 0.1.12-beta.7 → 0.1.12-beta.9

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 (233) hide show
  1. package/dist/components/auth/AuthLayout.d.ts.map +1 -1
  2. package/dist/components/auth/AuthLayout.js +19 -17
  3. package/dist/components/auth/AuthLayout.js.map +1 -1
  4. package/dist/components/auth/AuthLayout.tsx +59 -34
  5. package/dist/components/common/BackendReconnectIndicator.d.ts +6 -0
  6. package/dist/components/common/BackendReconnectIndicator.d.ts.map +1 -0
  7. package/dist/components/common/BackendReconnectIndicator.js +25 -0
  8. package/dist/components/common/BackendReconnectIndicator.js.map +1 -0
  9. package/dist/components/common/BackendReconnectIndicator.tsx +45 -0
  10. package/dist/components/common/SettingsComponent.d.ts.map +1 -1
  11. package/dist/components/common/SettingsComponent.js +7 -3
  12. package/dist/components/common/SettingsComponent.js.map +1 -1
  13. package/dist/components/common/SettingsComponent.module.css +144 -12
  14. package/dist/components/common/SettingsComponent.tsx +22 -3
  15. package/dist/components/common/SolidAdmin.d.ts.map +1 -1
  16. package/dist/components/common/SolidAdmin.js +7 -2
  17. package/dist/components/common/SolidAdmin.js.map +1 -1
  18. package/dist/components/common/SolidAdmin.tsx +7 -2
  19. package/dist/components/common/SolidBreadcrumb.d.ts.map +1 -1
  20. package/dist/components/common/SolidBreadcrumb.js +1 -6
  21. package/dist/components/common/SolidBreadcrumb.js.map +1 -1
  22. package/dist/components/common/SolidBreadcrumb.tsx +1 -8
  23. package/dist/components/common/SolidMaterialSymbol.d.ts +10 -0
  24. package/dist/components/common/SolidMaterialSymbol.d.ts.map +1 -0
  25. package/dist/components/common/SolidMaterialSymbol.js +69 -0
  26. package/dist/components/common/SolidMaterialSymbol.js.map +1 -0
  27. package/dist/components/common/SolidMaterialSymbol.tsx +96 -0
  28. package/dist/components/common/SolidToastProvider.d.ts.map +1 -1
  29. package/dist/components/common/SolidToastProvider.js +14 -1
  30. package/dist/components/common/SolidToastProvider.js.map +1 -1
  31. package/dist/components/common/SolidToastProvider.tsx +19 -1
  32. package/dist/components/core/common/SolidAccountSettings/SolidAccountSettings.module.css +3 -1
  33. package/dist/components/core/common/SolidGlobalSearchElement.d.ts.map +1 -1
  34. package/dist/components/core/common/SolidGlobalSearchElement.js +3 -2
  35. package/dist/components/core/common/SolidGlobalSearchElement.js.map +1 -1
  36. package/dist/components/core/common/SolidGlobalSearchElement.tsx +14 -18
  37. package/dist/components/core/extension/solid-core/modelMetadata/list/DeleteModelRowAction.d.ts.map +1 -1
  38. package/dist/components/core/extension/solid-core/modelMetadata/list/DeleteModelRowAction.js +43 -16
  39. package/dist/components/core/extension/solid-core/modelMetadata/list/DeleteModelRowAction.js.map +1 -1
  40. package/dist/components/core/extension/solid-core/modelMetadata/list/DeleteModelRowAction.tsx +24 -2
  41. package/dist/components/core/form/SolidFormFooter.js +1 -1
  42. package/dist/components/core/form/SolidFormFooter.js.map +1 -1
  43. package/dist/components/core/form/SolidFormFooter.tsx +1 -1
  44. package/dist/components/core/form/SolidFormLayouts.js +1 -1
  45. package/dist/components/core/form/SolidFormLayouts.js.map +1 -1
  46. package/dist/components/core/form/SolidFormLayouts.tsx +2 -2
  47. package/dist/components/core/form/fields/SolidMediaMultipleField.d.ts.map +1 -1
  48. package/dist/components/core/form/fields/SolidMediaMultipleField.js +120 -56
  49. package/dist/components/core/form/fields/SolidMediaMultipleField.js.map +1 -1
  50. package/dist/components/core/form/fields/SolidMediaMultipleField.tsx +63 -50
  51. package/dist/components/core/form/fields/SolidMediaSingleField.d.ts.map +1 -1
  52. package/dist/components/core/form/fields/SolidMediaSingleField.js +115 -37
  53. package/dist/components/core/form/fields/SolidMediaSingleField.js.map +1 -1
  54. package/dist/components/core/form/fields/SolidMediaSingleField.tsx +36 -35
  55. package/dist/components/core/form/fields/SolidRichTextField.d.ts.map +1 -1
  56. package/dist/components/core/form/fields/SolidRichTextField.js +54 -5
  57. package/dist/components/core/form/fields/SolidRichTextField.js.map +1 -1
  58. package/dist/components/core/form/fields/SolidRichTextField.tsx +71 -7
  59. package/dist/components/core/form/fields/mediaFieldUtils.d.ts +3 -0
  60. package/dist/components/core/form/fields/mediaFieldUtils.d.ts.map +1 -0
  61. package/dist/components/core/form/fields/mediaFieldUtils.js +30 -0
  62. package/dist/components/core/form/fields/mediaFieldUtils.js.map +1 -0
  63. package/dist/components/core/form/fields/mediaFieldUtils.ts +45 -0
  64. package/dist/components/core/form/fields/relations/RolesGroupedByModuleWidget.d.ts.map +1 -1
  65. package/dist/components/core/form/fields/relations/RolesGroupedByModuleWidget.js +1 -1
  66. package/dist/components/core/form/fields/relations/RolesGroupedByModuleWidget.js.map +1 -1
  67. package/dist/components/core/form/fields/relations/RolesGroupedByModuleWidget.tsx +3 -1
  68. package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.d.ts.map +1 -1
  69. package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.js +22 -23
  70. package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.js.map +1 -1
  71. package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.tsx +13 -7
  72. package/dist/components/core/form/fields/widgets/SolidIconEditWidget.d.ts.map +1 -1
  73. package/dist/components/core/form/fields/widgets/SolidIconEditWidget.js +16 -11
  74. package/dist/components/core/form/fields/widgets/SolidIconEditWidget.js.map +1 -1
  75. package/dist/components/core/form/fields/widgets/SolidIconEditWidget.tsx +32 -18
  76. package/dist/components/core/form/fields/widgets/SolidIconViewWidget.d.ts.map +1 -1
  77. package/dist/components/core/form/fields/widgets/SolidIconViewWidget.js +3 -1
  78. package/dist/components/core/form/fields/widgets/SolidIconViewWidget.js.map +1 -1
  79. package/dist/components/core/form/fields/widgets/SolidIconViewWidget.tsx +11 -5
  80. package/dist/components/core/list/SolidDataTable.d.ts.map +1 -1
  81. package/dist/components/core/list/SolidDataTable.js +3 -2
  82. package/dist/components/core/list/SolidDataTable.js.map +1 -1
  83. package/dist/components/core/list/SolidDataTable.tsx +3 -2
  84. package/dist/components/core/list/SolidListView.d.ts.map +1 -1
  85. package/dist/components/core/list/SolidListView.js +11 -5
  86. package/dist/components/core/list/SolidListView.js.map +1 -1
  87. package/dist/components/core/list/SolidListView.tsx +15 -8
  88. package/dist/components/core/list/SolidListViewColumn.d.ts.map +1 -1
  89. package/dist/components/core/list/SolidListViewColumn.js +1 -0
  90. package/dist/components/core/list/SolidListViewColumn.js.map +1 -1
  91. package/dist/components/core/list/SolidListViewColumn.tsx +1 -0
  92. package/dist/components/core/list/columns/SolidShortTextColumn.d.ts.map +1 -1
  93. package/dist/components/core/list/columns/SolidShortTextColumn.js +7 -2
  94. package/dist/components/core/list/columns/SolidShortTextColumn.js.map +1 -1
  95. package/dist/components/core/list/columns/SolidShortTextColumn.tsx +7 -2
  96. package/dist/components/core/list/columns/relations/SolidRelationManyToManyColumn.d.ts.map +1 -1
  97. package/dist/components/core/list/columns/relations/SolidRelationManyToManyColumn.js +4 -1
  98. package/dist/components/core/list/columns/relations/SolidRelationManyToManyColumn.js.map +1 -1
  99. package/dist/components/core/list/columns/relations/SolidRelationManyToManyColumn.tsx +5 -2
  100. package/dist/components/core/list/columns/relations/SolidRelationManyToOneColumn.d.ts.map +1 -1
  101. package/dist/components/core/list/columns/relations/SolidRelationManyToOneColumn.js +2 -1
  102. package/dist/components/core/list/columns/relations/SolidRelationManyToOneColumn.js.map +1 -1
  103. package/dist/components/core/list/columns/relations/SolidRelationManyToOneColumn.tsx +2 -1
  104. package/dist/components/core/list/columns/relations/SolidRelationOneToManyColumn.d.ts.map +1 -1
  105. package/dist/components/core/list/columns/relations/SolidRelationOneToManyColumn.js +4 -1
  106. package/dist/components/core/list/columns/relations/SolidRelationOneToManyColumn.js.map +1 -1
  107. package/dist/components/core/list/columns/relations/SolidRelationOneToManyColumn.tsx +5 -2
  108. package/dist/components/core/locales/SolidLocale.d.ts.map +1 -1
  109. package/dist/components/core/locales/SolidLocale.js +1 -1
  110. package/dist/components/core/locales/SolidLocale.js.map +1 -1
  111. package/dist/components/core/locales/SolidLocale.tsx +1 -0
  112. package/dist/components/core/model/CreateModel.css +26 -0
  113. package/dist/components/core/model/FieldMetaData.d.ts.map +1 -1
  114. package/dist/components/core/model/FieldMetaData.js +21 -3
  115. package/dist/components/core/model/FieldMetaData.js.map +1 -1
  116. package/dist/components/core/model/FieldMetaData.tsx +45 -4
  117. package/dist/components/core/model/FieldMetaDataForm.css +82 -0
  118. package/dist/components/core/model/FieldMetaDataForm.d.ts +1 -0
  119. package/dist/components/core/model/FieldMetaDataForm.d.ts.map +1 -1
  120. package/dist/components/core/model/FieldMetaDataForm.js +246 -235
  121. package/dist/components/core/model/FieldMetaDataForm.js.map +1 -1
  122. package/dist/components/core/model/FieldMetaDataForm.tsx +46 -34
  123. package/dist/components/core/model/FieldSelector.js +1 -1
  124. package/dist/components/core/model/FieldSelector.js.map +1 -1
  125. package/dist/components/core/model/FieldSelector.tsx +1 -1
  126. package/dist/components/core/model/ModelMetaData.js +1 -1
  127. package/dist/components/core/model/ModelMetaData.js.map +1 -1
  128. package/dist/components/core/model/ModelMetaData.tsx +1 -1
  129. package/dist/components/core/module/CreateModule.css +55 -2
  130. package/dist/components/core/module/CreateModule.d.ts.map +1 -1
  131. package/dist/components/core/module/CreateModule.js +2 -2
  132. package/dist/components/core/module/CreateModule.js.map +1 -1
  133. package/dist/components/core/module/CreateModule.tsx +3 -2
  134. package/dist/components/core/module/ModuleMetadataExplorer.css +27 -0
  135. package/dist/components/core/module/ModuleMetadataExplorer.d.ts.map +1 -1
  136. package/dist/components/core/module/ModuleMetadataExplorer.js +1 -1
  137. package/dist/components/core/module/ModuleMetadataExplorer.js.map +1 -1
  138. package/dist/components/core/module/ModuleMetadataExplorer.tsx +1 -0
  139. package/dist/components/core/tree/SolidTreeView.d.ts.map +1 -1
  140. package/dist/components/core/tree/SolidTreeView.js +6 -1
  141. package/dist/components/core/tree/SolidTreeView.js.map +1 -1
  142. package/dist/components/core/tree/SolidTreeView.tsx +7 -1
  143. package/dist/components/layout/AdminHeaderActions.d.ts.map +1 -1
  144. package/dist/components/layout/AdminHeaderActions.js +10 -9
  145. package/dist/components/layout/AdminHeaderActions.js.map +1 -1
  146. package/dist/components/layout/AdminHeaderActions.tsx +2 -0
  147. package/dist/components/layout/AppSidebar.d.ts.map +1 -1
  148. package/dist/components/layout/AppSidebar.js +2 -1
  149. package/dist/components/layout/AppSidebar.js.map +1 -1
  150. package/dist/components/layout/AppSidebar.tsx +12 -5
  151. package/dist/components/layout/SolidMenuItemIcon.d.ts +9 -0
  152. package/dist/components/layout/SolidMenuItemIcon.d.ts.map +1 -0
  153. package/dist/components/layout/SolidMenuItemIcon.js +20 -0
  154. package/dist/components/layout/SolidMenuItemIcon.js.map +1 -0
  155. package/dist/components/layout/SolidMenuItemIcon.tsx +45 -0
  156. package/dist/components/layout/navbar-two-menu.d.ts.map +1 -1
  157. package/dist/components/layout/navbar-two-menu.js +6 -7
  158. package/dist/components/layout/navbar-two-menu.js.map +1 -1
  159. package/dist/components/layout/navbar-two-menu.tsx +4 -12
  160. package/dist/components/shad-cn-ui/SolidCodeEditor.d.ts.map +1 -1
  161. package/dist/components/shad-cn-ui/SolidCodeEditor.js +30 -2
  162. package/dist/components/shad-cn-ui/SolidCodeEditor.js.map +1 -1
  163. package/dist/components/shad-cn-ui/SolidCodeEditor.tsx +38 -1
  164. package/dist/helpers/backendHealthMonitor.d.ts +39 -0
  165. package/dist/helpers/backendHealthMonitor.d.ts.map +1 -0
  166. package/dist/helpers/backendHealthMonitor.js +255 -0
  167. package/dist/helpers/backendHealthMonitor.js.map +1 -0
  168. package/dist/helpers/backendHealthMonitor.ts +177 -0
  169. package/dist/helpers/helpers.d.ts +1 -0
  170. package/dist/helpers/helpers.d.ts.map +1 -1
  171. package/dist/helpers/helpers.js +9 -0
  172. package/dist/helpers/helpers.js.map +1 -1
  173. package/dist/helpers/helpers.ts +11 -1
  174. package/dist/helpers/menuItemIcons.d.ts +34 -0
  175. package/dist/helpers/menuItemIcons.d.ts.map +1 -0
  176. package/dist/helpers/menuItemIcons.js +144 -0
  177. package/dist/helpers/menuItemIcons.js.map +1 -0
  178. package/dist/helpers/menuItemIcons.ts +191 -0
  179. package/dist/helpers/relationDisplay.d.ts +3 -0
  180. package/dist/helpers/relationDisplay.d.ts.map +1 -0
  181. package/dist/helpers/relationDisplay.js +92 -0
  182. package/dist/helpers/relationDisplay.js.map +1 -0
  183. package/dist/helpers/relationDisplay.ts +101 -0
  184. package/dist/helpers/settingsPayload.d.ts +1 -0
  185. package/dist/helpers/settingsPayload.d.ts.map +1 -1
  186. package/dist/helpers/settingsPayload.js.map +1 -1
  187. package/dist/helpers/settingsPayload.ts +1 -0
  188. package/dist/helpers/solidIcons.d.ts +2 -0
  189. package/dist/helpers/solidIcons.d.ts.map +1 -1
  190. package/dist/helpers/solidIcons.js +8 -0
  191. package/dist/helpers/solidIcons.js.map +1 -1
  192. package/dist/helpers/solidIcons.tsx +10 -1
  193. package/dist/helpers/waitForBackendAvailability.d.ts +1 -0
  194. package/dist/helpers/waitForBackendAvailability.d.ts.map +1 -1
  195. package/dist/helpers/waitForBackendAvailability.js +35 -22
  196. package/dist/helpers/waitForBackendAvailability.js.map +1 -1
  197. package/dist/helpers/waitForBackendAvailability.ts +18 -12
  198. package/dist/http/solidHttp.d.ts.map +1 -1
  199. package/dist/http/solidHttp.js +10 -4
  200. package/dist/http/solidHttp.js.map +1 -1
  201. package/dist/http/solidHttp.ts +9 -4
  202. package/dist/redux/api/datasourceIntrospectionApi.d.ts +4 -0
  203. package/dist/redux/api/datasourceIntrospectionApi.d.ts.map +1 -1
  204. package/dist/redux/api/datasourceIntrospectionApi.js.map +1 -1
  205. package/dist/redux/api/datasourceIntrospectionApi.ts +4 -0
  206. package/dist/redux/api/fetchBaseQuery.d.ts.map +1 -1
  207. package/dist/redux/api/fetchBaseQuery.js +9 -3
  208. package/dist/redux/api/fetchBaseQuery.js.map +1 -1
  209. package/dist/redux/api/fetchBaseQuery.tsx +9 -3
  210. package/dist/redux/store/StoreProvider.d.ts.map +1 -1
  211. package/dist/redux/store/StoreProvider.js +4 -3
  212. package/dist/redux/store/StoreProvider.js.map +1 -1
  213. package/dist/redux/store/StoreProvider.tsx +4 -3
  214. package/dist/resources/globals.css +341 -49
  215. package/dist/resources/solid-custom.css +410 -12
  216. package/dist/resources/solid-responsive.css +27 -16
  217. package/dist/resources/solid-tailwind-generated.css +1 -1
  218. package/dist/routes/AppEventListener.d.ts.map +1 -1
  219. package/dist/routes/AppEventListener.js +23 -0
  220. package/dist/routes/AppEventListener.js.map +1 -1
  221. package/dist/routes/AppEventListener.tsx +29 -0
  222. package/dist/routes/pages/admin/core/DashboardPage.module.css +12 -0
  223. package/dist/routes/pages/admin/core/DatasourceIntrospectionPage.css +306 -3
  224. package/dist/routes/pages/admin/core/DatasourceIntrospectionPage.d.ts.map +1 -1
  225. package/dist/routes/pages/admin/core/DatasourceIntrospectionPage.js +745 -393
  226. package/dist/routes/pages/admin/core/DatasourceIntrospectionPage.js.map +1 -1
  227. package/dist/routes/pages/admin/core/DatasourceIntrospectionPage.tsx +1074 -420
  228. package/dist/routes/pages/admin/core/DatasourcesPage.css +15 -0
  229. package/dist/routes/pages/admin/core/DatasourcesPage.d.ts.map +1 -1
  230. package/dist/routes/pages/admin/core/DatasourcesPage.js +7 -188
  231. package/dist/routes/pages/admin/core/DatasourcesPage.js.map +1 -1
  232. package/dist/routes/pages/admin/core/DatasourcesPage.tsx +3 -393
  233. package/package.json +3 -2
@@ -0,0 +1,177 @@
1
+ import { env } from "../adapters/env";
2
+ import { pingBackendAvailability } from "./waitForBackendAvailability";
3
+
4
+ export type BackendHealthStatus = "online" | "checking" | "offline";
5
+
6
+ export type BackendHealthState = {
7
+ status: BackendHealthStatus;
8
+ firstFailureAt: number | null;
9
+ lastFailureAt: number | null;
10
+ unavailableToastDelayMs: number;
11
+ retryDelayMs: number;
12
+ message: string;
13
+ statusCode?: number | string;
14
+ error?: unknown;
15
+ };
16
+
17
+ type BackendHealthListener = (state: BackendHealthState) => void;
18
+
19
+ type BackendHealthConfig = {
20
+ unavailableToastDelayMs?: number;
21
+ retryDelayMs?: number;
22
+ };
23
+
24
+ const DEFAULT_UNAVAILABLE_TOAST_DELAY_MS = 60_000;
25
+ const DEFAULT_RETRY_DELAY_MS = 1_500;
26
+
27
+ function parsePositiveInteger(value: string, fallback: number) {
28
+ const parsed = Number.parseInt(value, 10);
29
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
30
+ }
31
+
32
+ class BackendHealthMonitor {
33
+ private listeners = new Set<BackendHealthListener>();
34
+ private pollingPromise: Promise<void> | null = null;
35
+ private offlineTimer: number | null = null;
36
+ private config: Required<BackendHealthConfig> = {
37
+ unavailableToastDelayMs: parsePositiveInteger(
38
+ env("BACKEND_UNAVAILABLE_TOAST_DELAY_MS", `${DEFAULT_UNAVAILABLE_TOAST_DELAY_MS}`),
39
+ DEFAULT_UNAVAILABLE_TOAST_DELAY_MS,
40
+ ),
41
+ retryDelayMs: parsePositiveInteger(
42
+ env("BACKEND_RETRY_DELAY_MS", `${DEFAULT_RETRY_DELAY_MS}`),
43
+ DEFAULT_RETRY_DELAY_MS,
44
+ ),
45
+ };
46
+
47
+ private state: BackendHealthState = {
48
+ status: "online",
49
+ firstFailureAt: null,
50
+ lastFailureAt: null,
51
+ unavailableToastDelayMs: this.config.unavailableToastDelayMs,
52
+ retryDelayMs: this.config.retryDelayMs,
53
+ message: "",
54
+ };
55
+
56
+ subscribe(listener: BackendHealthListener) {
57
+ this.listeners.add(listener);
58
+ listener(this.state);
59
+ return () => {
60
+ this.listeners.delete(listener);
61
+ };
62
+ }
63
+
64
+ getState() {
65
+ return this.state;
66
+ }
67
+
68
+ configure(nextConfig: BackendHealthConfig = {}) {
69
+ this.config = {
70
+ unavailableToastDelayMs: nextConfig.unavailableToastDelayMs ?? this.config.unavailableToastDelayMs,
71
+ retryDelayMs: nextConfig.retryDelayMs ?? this.config.retryDelayMs,
72
+ };
73
+
74
+ this.state = {
75
+ ...this.state,
76
+ unavailableToastDelayMs: this.config.unavailableToastDelayMs,
77
+ retryDelayMs: this.config.retryDelayMs,
78
+ };
79
+ this.emit();
80
+ }
81
+
82
+ reportFailure(payload?: { status?: number | string; message?: string; error?: unknown }) {
83
+ const now = Date.now();
84
+
85
+ this.state = {
86
+ ...this.state,
87
+ status: this.state.status === "offline" ? "offline" : "checking",
88
+ firstFailureAt: this.state.firstFailureAt ?? now,
89
+ lastFailureAt: now,
90
+ unavailableToastDelayMs: this.config.unavailableToastDelayMs,
91
+ retryDelayMs: this.config.retryDelayMs,
92
+ message: payload?.message || "Unable to reach the server. Reconnecting...",
93
+ statusCode: payload?.status,
94
+ error: payload?.error,
95
+ };
96
+ this.emit();
97
+
98
+ this.scheduleOfflineTimer();
99
+ void this.ensurePolling();
100
+ }
101
+
102
+ reportSuccess() {
103
+ if (this.state.status === "online") {
104
+ return;
105
+ }
106
+
107
+ this.clearOfflineTimer();
108
+ this.state = {
109
+ ...this.state,
110
+ status: "online",
111
+ firstFailureAt: null,
112
+ lastFailureAt: null,
113
+ message: "",
114
+ statusCode: undefined,
115
+ error: undefined,
116
+ };
117
+ this.emit();
118
+ }
119
+
120
+ private emit() {
121
+ for (const listener of Array.from(this.listeners)) {
122
+ listener(this.state);
123
+ }
124
+ }
125
+
126
+ private scheduleOfflineTimer() {
127
+ if (this.offlineTimer != null) {
128
+ return;
129
+ }
130
+
131
+ this.offlineTimer = window.setTimeout(() => {
132
+ this.offlineTimer = null;
133
+ if (this.state.status !== "online" && this.state.firstFailureAt != null) {
134
+ this.state = {
135
+ ...this.state,
136
+ status: "offline",
137
+ message: this.state.message || "Server unavailable.",
138
+ };
139
+ this.emit();
140
+ }
141
+ }, this.config.unavailableToastDelayMs);
142
+ }
143
+
144
+ private clearOfflineTimer() {
145
+ if (this.offlineTimer != null) {
146
+ window.clearTimeout(this.offlineTimer);
147
+ this.offlineTimer = null;
148
+ }
149
+ }
150
+
151
+ private async ensurePolling() {
152
+ if (this.pollingPromise) {
153
+ return this.pollingPromise;
154
+ }
155
+
156
+ this.pollingPromise = (async () => {
157
+ while (this.state.status !== "online") {
158
+ const reachable = await pingBackendAvailability();
159
+ if (reachable) {
160
+ this.reportSuccess();
161
+ break;
162
+ }
163
+
164
+ await new Promise((resolve) => window.setTimeout(resolve, this.config.retryDelayMs));
165
+ }
166
+ })();
167
+
168
+ try {
169
+ await this.pollingPromise;
170
+ } finally {
171
+ this.pollingPromise = null;
172
+ }
173
+ }
174
+ }
175
+
176
+ export const backendHealthMonitor = new BackendHealthMonitor();
177
+
@@ -1,5 +1,6 @@
1
1
  export declare const calculateDaysOfStay: (checkInDate: Date, checkOutDate: Date) => number;
2
2
  export declare const addCommasToAmount: (amount: string) => string;
3
+ export declare const toTitleCase: (value: any) => string;
3
4
  export declare const getSingularAndPlural: (displayName: any) => {
4
5
  toKebabCase: any;
5
6
  toSnakeCase: any;
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/helpers/helpers.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,mBAAmB,gBAAiB,IAAI,gBAAgB,IAAI,WAKxE,CAAC;AAEF,eAAO,MAAM,iBAAiB,WAAY,MAAM,WAQ/C,CAAC;AAGF,eAAO,MAAM,oBAAoB,gBAAiB,GAAG;;;;;;;;CAmBpD,CAAC;AAYF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,GAAG,UAQpD"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/helpers/helpers.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,mBAAmB,gBAAiB,IAAI,gBAAgB,IAAI,WAKxE,CAAC;AAEF,eAAO,MAAM,iBAAiB,WAAY,MAAM,WAQ/C,CAAC;AAEF,eAAO,MAAM,WAAW,UAAW,GAAG,WAQrC,CAAC;AAGF,eAAO,MAAM,oBAAoB,gBAAiB,GAAG;;;;;;;;CAmBpD,CAAC;AAYF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,GAAG,UAQpD"}
@@ -13,6 +13,15 @@ export var addCommasToAmount = function (amount) {
13
13
  parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
14
14
  return parts.join(".");
15
15
  };
16
+ export var toTitleCase = function (value) {
17
+ var text = String(value !== null && value !== void 0 ? value : "").trim();
18
+ if (!text)
19
+ return "";
20
+ return text
21
+ .replace(/[-_]/g, " ")
22
+ .replace(/([a-z])([A-Z])/g, "$1 $2")
23
+ .replace(/\b\w/g, function (char) { return char.toUpperCase(); });
24
+ };
16
25
  export var getSingularAndPlural = function (displayName) {
17
26
  // Convert display name to kebab-case (lowercase with hyphens)
18
27
  var toKebabCase = kebabCase(displayName);
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/helpers/helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,CAAC,IAAM,mBAAmB,GAAG,UAAC,WAAiB,EAAE,YAAkB;IACvE,IAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IACtC,IAAM,OAAO,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;IAErC,OAAO,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;AAC7C,CAAC,CAAC;AAEF,MAAM,CAAC,IAAM,iBAAiB,GAAG,UAAC,MAAc;IAC9C,MAAM,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;IAE3B,IAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEhC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;IAE1D,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC,CAAC;AAGF,MAAM,CAAC,IAAM,oBAAoB,GAAG,UAAC,WAAgB;IACnD,8DAA8D;IAC9D,IAAM,WAAW,GAAQ,SAAS,CAAC,WAAW,CAAC,CAAC;IAEhD,IAAM,WAAW,GAAQ,SAAS,CAAC,WAAW,CAAC,CAAC;IAEhD,IAAM,WAAW,GAAQ,SAAS,CAAC,WAAW,CAAC,CAAC;IAGhD,sCAAsC;IACtC,IAAM,iBAAiB,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;IAEjD,IAAM,iBAAiB,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;IAEjD,IAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;IAExC,IAAM,UAAU,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAE7C,OAAO,EAAE,WAAW,aAAA,EAAE,WAAW,aAAA,EAAE,iBAAiB,mBAAA,EAAE,iBAAiB,mBAAA,EAAE,WAAW,aAAA,EAAE,QAAQ,UAAA,EAAE,UAAU,YAAA,EAAE,CAAC;AAC/G,CAAC,CAAC;AAEF,SAAS,aAAa,CAAC,MAAW;IAChC,kDAAkD;IAClD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,UAAC,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACpD,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,IAAI;YAAE,OAAO,SAAS,CAAC;QAC7D,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,OAAO,SAAS,CAAC;QACrE,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAW;IACnD,IAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACvC,OAAO,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE;QAC5B,MAAM,EAAE,IAAI;QACZ,WAAW,EAAE,UAAU;QACvB,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;AACL,CAAC","sourcesContent":["\nimport { camelCase, kebabCase, snakeCase } from \"lodash\";\nimport moment from \"moment\";\nimport pluralize from \"pluralize\";\nimport qs from \"qs\";\n\nexport const calculateDaysOfStay = (checkInDate: Date, checkOutDate: Date) => {\n const startDate = moment(checkInDate);\n const endDate = moment(checkOutDate);\n\n return endDate.diff(startDate, \"days\") + 1;\n};\n\nexport const addCommasToAmount = (amount: string) => {\n amount = amount.toString();\n\n const parts = amount.split(\".\");\n\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n\n return parts.join(\".\");\n};\n\n\nexport const getSingularAndPlural = (displayName: any) => {\n // Convert display name to kebab-case (lowercase with hyphens)\n const toKebabCase: any = kebabCase(displayName);\n\n const toSnakeCase: any = snakeCase(displayName);\n\n const toCamelCase: any = camelCase(displayName);\n\n\n // Get the plural form using pluralize\n const toPluralKebabCase = pluralize(toKebabCase);\n\n const toPluralCamelCase = pluralize(toCamelCase);\n\n const toPlural = pluralize(displayName);\n\n const toSingular = pluralize(displayName, 1);\n\n return { toKebabCase, toSnakeCase, toPluralKebabCase, toPluralCamelCase, toCamelCase, toPlural, toSingular };\n};\n\nfunction cleanForQuery(values: any) {\n // remove files, blobs, data: URIs, null/undefined\n return JSON.parse(JSON.stringify(values, (k, v) => {\n if (v === null || v === undefined) return undefined;\n if (v instanceof File || v instanceof Blob) return undefined;\n if (typeof v === \"string\" && v.startsWith(\"data:\")) return undefined;\n return v;\n }));\n}\n\nexport function formikValuestoQueryString(values: any) {\n const filtered = cleanForQuery(values);\n return qs.stringify(filtered, {\n encode: true,\n arrayFormat: \"brackets\",\n allowDots: true,\n skipNulls: true,\n });\n}"]}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/helpers/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport { camelCase, kebabCase, snakeCase } from \"lodash\";\nimport moment from \"moment\";\nimport pluralize from \"pluralize\";\nimport qs from \"qs\";\n\nexport const calculateDaysOfStay = (checkInDate: Date, checkOutDate: Date) => {\n const startDate = moment(checkInDate);\n const endDate = moment(checkOutDate);\n\n return endDate.diff(startDate, \"days\") + 1;\n};\n\nexport const addCommasToAmount = (amount: string) => {\n amount = amount.toString();\n\n const parts = amount.split(\".\");\n\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n\n return parts.join(\".\");\n};\n\nexport const toTitleCase = (value: any) => {\n const text = String(value ?? \"\").trim();\n if (!text) return \"\";\n\n return text\n .replace(/[-_]/g, \" \")\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\n};\n\n\nexport const getSingularAndPlural = (displayName: any) => {\n // Convert display name to kebab-case (lowercase with hyphens)\n const toKebabCase: any = kebabCase(displayName);\n\n const toSnakeCase: any = snakeCase(displayName);\n\n const toCamelCase: any = camelCase(displayName);\n\n\n // Get the plural form using pluralize\n const toPluralKebabCase = pluralize(toKebabCase);\n\n const toPluralCamelCase = pluralize(toCamelCase);\n\n const toPlural = pluralize(displayName);\n\n const toSingular = pluralize(displayName, 1);\n\n return { toKebabCase, toSnakeCase, toPluralKebabCase, toPluralCamelCase, toCamelCase, toPlural, toSingular };\n};\n\nfunction cleanForQuery(values: any) {\n // remove files, blobs, data: URIs, null/undefined\n return JSON.parse(JSON.stringify(values, (k, v) => {\n if (v === null || v === undefined) return undefined;\n if (v instanceof File || v instanceof Blob) return undefined;\n if (typeof v === \"string\" && v.startsWith(\"data:\")) return undefined;\n return v;\n }));\n}\n\nexport function formikValuestoQueryString(values: any) {\n const filtered = cleanForQuery(values);\n return qs.stringify(filtered, {\n encode: true,\n arrayFormat: \"brackets\",\n allowDots: true,\n skipNulls: true,\n });\n}\n"]}
@@ -21,6 +21,16 @@ export const addCommasToAmount = (amount: string) => {
21
21
  return parts.join(".");
22
22
  };
23
23
 
24
+ export const toTitleCase = (value: any) => {
25
+ const text = String(value ?? "").trim();
26
+ if (!text) return "";
27
+
28
+ return text
29
+ .replace(/[-_]/g, " ")
30
+ .replace(/([a-z])([A-Z])/g, "$1 $2")
31
+ .replace(/\b\w/g, (char) => char.toUpperCase());
32
+ };
33
+
24
34
 
25
35
  export const getSingularAndPlural = (displayName: any) => {
26
36
  // Convert display name to kebab-case (lowercase with hyphens)
@@ -61,4 +71,4 @@ export function formikValuestoQueryString(values: any) {
61
71
  allowDots: true,
62
72
  skipNulls: true,
63
73
  });
64
- }
74
+ }
@@ -0,0 +1,34 @@
1
+ import type { SolidIconName } from "../components/shad-cn-ui/SolidIcon";
2
+ type MenuItemModelMeta = {
3
+ displayName?: string | null;
4
+ icon?: string | null;
5
+ pluralName?: string | null;
6
+ singularName?: string | null;
7
+ title?: string | null;
8
+ };
9
+ export type MenuItemIconSource = {
10
+ children?: MenuItemIconSource[] | null;
11
+ icon?: string | {
12
+ src?: string;
13
+ } | null;
14
+ isSystem?: boolean | null;
15
+ label?: string | null;
16
+ model?: MenuItemModelMeta | null;
17
+ modelMetadata?: MenuItemModelMeta | null;
18
+ path?: string | null;
19
+ solidView?: {
20
+ model?: MenuItemModelMeta | null;
21
+ } | null;
22
+ title?: string | null;
23
+ };
24
+ export type ResolvedMenuItemIcon = {
25
+ kind: "material";
26
+ name: string;
27
+ } | {
28
+ kind: "solid";
29
+ name: SolidIconName;
30
+ spin?: boolean;
31
+ };
32
+ export declare function resolveMenuItemIcon(item?: MenuItemIconSource | null): ResolvedMenuItemIcon | undefined;
33
+ export {};
34
+ //# sourceMappingURL=menuItemIcons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menuItemIcons.d.ts","sourceRoot":"","sources":["../../src/helpers/menuItemIcons.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAIxE,KAAK,iBAAiB,GAAG;IACvB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAAC;IACvC,IAAI,CAAC,EAAE,MAAM,GAAG;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACjC,aAAa,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACzC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACxD,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAC5B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AA8H3D,wBAAgB,mBAAmB,CAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,IAAI,GAAI,oBAAoB,GAAG,SAAS,CAsCxG"}
@@ -0,0 +1,144 @@
1
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
2
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
3
+ if (ar || !(i in from)) {
4
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
5
+ ar[i] = from[i];
6
+ }
7
+ }
8
+ return to.concat(ar || Array.prototype.slice.call(from));
9
+ };
10
+ import { parseSolidIconMeta } from "../components/shad-cn-ui/SolidIcon";
11
+ import { hasSolidMaterialIconName } from "./solidIcons";
12
+ var TITLE_ALIAS_RULES = [
13
+ { pattern: /\bwhats?\s?app\b/i, icon: { kind: "material", name: "whatsapp" } },
14
+ { pattern: /\b(user|profile|account|contact)\b/i, icon: { kind: "material", name: "person" } },
15
+ { pattern: /\b(users|profiles|accounts|contacts|members?|people|teams?|groups?)\b/i, icon: { kind: "material", name: "group" } },
16
+ { pattern: /\b(roles?|permissions?|access)\b/i, icon: { kind: "material", name: "admin_panel_settings" } },
17
+ { pattern: /\b(emails?|mail|inbox)\b/i, icon: { kind: "material", name: "email" } },
18
+ { pattern: /\b(messages?|chats?|conversations?)\b/i, icon: { kind: "material", name: "message" } },
19
+ { pattern: /\b(forms?|submissions?)\b/i, icon: { kind: "material", name: "dynamic_form" } },
20
+ { pattern: /\b(reports?|analytics|dashboards?)\b/i, icon: { kind: "material", name: "analytics" } },
21
+ { pattern: /\b(settings?|configs?|configuration|preferences?)\b/i, icon: { kind: "material", name: "settings" } },
22
+ { pattern: /\b(files?|documents?|templates?)\b/i, icon: { kind: "material", name: "article" } },
23
+ ];
24
+ function normalizeTextValue(value) {
25
+ return typeof value === "string" ? value.trim() : "";
26
+ }
27
+ function buildMaterialIconCandidates(value) {
28
+ var trimmed = normalizeTextValue(value);
29
+ if (!trimmed) {
30
+ return [];
31
+ }
32
+ var camelSeparated = trimmed.replace(/([a-z0-9])([A-Z])/g, "$1 $2");
33
+ var snakeCase = camelSeparated
34
+ .toLowerCase()
35
+ .replace(/[^a-z0-9]+/g, "_")
36
+ .replace(/^_+|_+$/g, "");
37
+ var compact = snakeCase.replace(/_/g, "");
38
+ return Array.from(new Set([trimmed, trimmed.toLowerCase(), snakeCase, compact].filter(Boolean)));
39
+ }
40
+ function resolveMaterialIconName(value) {
41
+ for (var _i = 0, _a = buildMaterialIconCandidates(value); _i < _a.length; _i++) {
42
+ var candidate = _a[_i];
43
+ if (hasSolidMaterialIconName(candidate)) {
44
+ return candidate;
45
+ }
46
+ }
47
+ return undefined;
48
+ }
49
+ function cloneResolvedIcon(icon) {
50
+ if (icon.kind === "solid") {
51
+ return {
52
+ kind: "solid",
53
+ name: icon.name,
54
+ spin: icon.spin,
55
+ };
56
+ }
57
+ return {
58
+ kind: "material",
59
+ name: icon.name,
60
+ };
61
+ }
62
+ function getRawIconCandidates(item) {
63
+ var _a, _b, _c, _d;
64
+ if (!item) {
65
+ return [];
66
+ }
67
+ var candidates = [
68
+ typeof item.icon === "string" ? item.icon : "",
69
+ (_a = item.model) === null || _a === void 0 ? void 0 : _a.icon,
70
+ (_b = item.modelMetadata) === null || _b === void 0 ? void 0 : _b.icon,
71
+ (_d = (_c = item.solidView) === null || _c === void 0 ? void 0 : _c.model) === null || _d === void 0 ? void 0 : _d.icon,
72
+ ];
73
+ return Array.from(new Set(candidates.map(normalizeTextValue).filter(Boolean)));
74
+ }
75
+ function getAliasTextCandidates(item) {
76
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
77
+ if (!item) {
78
+ return [];
79
+ }
80
+ var candidates = __spreadArray([
81
+ item.title,
82
+ item.label,
83
+ (_a = item.model) === null || _a === void 0 ? void 0 : _a.displayName,
84
+ (_b = item.model) === null || _b === void 0 ? void 0 : _b.pluralName,
85
+ (_c = item.model) === null || _c === void 0 ? void 0 : _c.singularName,
86
+ (_d = item.model) === null || _d === void 0 ? void 0 : _d.title,
87
+ (_e = item.modelMetadata) === null || _e === void 0 ? void 0 : _e.displayName,
88
+ (_f = item.modelMetadata) === null || _f === void 0 ? void 0 : _f.pluralName,
89
+ (_g = item.modelMetadata) === null || _g === void 0 ? void 0 : _g.singularName,
90
+ (_h = item.modelMetadata) === null || _h === void 0 ? void 0 : _h.title,
91
+ (_k = (_j = item.solidView) === null || _j === void 0 ? void 0 : _j.model) === null || _k === void 0 ? void 0 : _k.displayName,
92
+ (_m = (_l = item.solidView) === null || _l === void 0 ? void 0 : _l.model) === null || _m === void 0 ? void 0 : _m.pluralName,
93
+ (_p = (_o = item.solidView) === null || _o === void 0 ? void 0 : _o.model) === null || _p === void 0 ? void 0 : _p.singularName,
94
+ (_r = (_q = item.solidView) === null || _q === void 0 ? void 0 : _q.model) === null || _r === void 0 ? void 0 : _r.title
95
+ ], getRawIconCandidates(item), true);
96
+ return Array.from(new Set(candidates.map(normalizeTextValue).filter(Boolean)));
97
+ }
98
+ function resolveAliasedIcon(item) {
99
+ var joinedText = getAliasTextCandidates(item).join(" ");
100
+ if (!joinedText) {
101
+ return undefined;
102
+ }
103
+ for (var _i = 0, TITLE_ALIAS_RULES_1 = TITLE_ALIAS_RULES; _i < TITLE_ALIAS_RULES_1.length; _i++) {
104
+ var rule = TITLE_ALIAS_RULES_1[_i];
105
+ if (rule.pattern.test(joinedText)) {
106
+ return cloneResolvedIcon(rule.icon);
107
+ }
108
+ }
109
+ return undefined;
110
+ }
111
+ export function resolveMenuItemIcon(item) {
112
+ if (!item) {
113
+ return undefined;
114
+ }
115
+ for (var _i = 0, _a = getRawIconCandidates(item); _i < _a.length; _i++) {
116
+ var rawIcon = _a[_i];
117
+ var solidIcon = parseSolidIconMeta(rawIcon);
118
+ if (solidIcon) {
119
+ return {
120
+ kind: "solid",
121
+ name: solidIcon.name,
122
+ spin: solidIcon.spin,
123
+ };
124
+ }
125
+ var materialIcon = resolveMaterialIconName(rawIcon);
126
+ if (materialIcon) {
127
+ return {
128
+ kind: "material",
129
+ name: materialIcon,
130
+ };
131
+ }
132
+ }
133
+ var derivedMaterialIcon = getAliasTextCandidates(item)
134
+ .map(resolveMaterialIconName)
135
+ .find(Boolean);
136
+ if (derivedMaterialIcon) {
137
+ return {
138
+ kind: "material",
139
+ name: derivedMaterialIcon,
140
+ };
141
+ }
142
+ return resolveAliasedIcon(item);
143
+ }
144
+ //# sourceMappingURL=menuItemIcons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menuItemIcons.js","sourceRoot":"","sources":["../../src/helpers/menuItemIcons.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SolidIconName } from \"../components/shad-cn-ui/SolidIcon\";\nimport { parseSolidIconMeta } from \"../components/shad-cn-ui/SolidIcon\";\nimport { hasSolidMaterialIconName } from \"./solidIcons\";\n\ntype MenuItemModelMeta = {\n displayName?: string | null;\n icon?: string | null;\n pluralName?: string | null;\n singularName?: string | null;\n title?: string | null;\n};\n\nexport type MenuItemIconSource = {\n children?: MenuItemIconSource[] | null;\n icon?: string | { src?: string } | null;\n isSystem?: boolean | null;\n label?: string | null;\n model?: MenuItemModelMeta | null;\n modelMetadata?: MenuItemModelMeta | null;\n path?: string | null;\n solidView?: { model?: MenuItemModelMeta | null } | null;\n title?: string | null;\n};\n\nexport type ResolvedMenuItemIcon =\n | { kind: \"material\"; name: string }\n | { kind: \"solid\"; name: SolidIconName; spin?: boolean };\n\nconst TITLE_ALIAS_RULES: Array<{pattern: RegExp;icon: ResolvedMenuItemIcon;}> = [\n { pattern: /\\bwhats?\\s?app\\b/i, icon: { kind: \"material\", name: \"whatsapp\" } },\n { pattern: /\\b(user|profile|account|contact)\\b/i, icon: { kind: \"material\", name: \"person\" } },\n { pattern: /\\b(users|profiles|accounts|contacts|members?|people|teams?|groups?)\\b/i, icon: { kind: \"material\", name: \"group\" } },\n { pattern: /\\b(roles?|permissions?|access)\\b/i, icon: { kind: \"material\", name: \"admin_panel_settings\" } },\n { pattern: /\\b(emails?|mail|inbox)\\b/i, icon: { kind: \"material\", name: \"email\" } },\n { pattern: /\\b(messages?|chats?|conversations?)\\b/i, icon: { kind: \"material\", name: \"message\" } },\n { pattern: /\\b(forms?|submissions?)\\b/i, icon: { kind: \"material\", name: \"dynamic_form\" } },\n { pattern: /\\b(reports?|analytics|dashboards?)\\b/i, icon: { kind: \"material\", name: \"analytics\" } },\n { pattern: /\\b(settings?|configs?|configuration|preferences?)\\b/i, icon: { kind: \"material\", name: \"settings\" } },\n { pattern: /\\b(files?|documents?|templates?)\\b/i, icon: { kind: \"material\", name: \"article\" } },\n];\n\nfunction normalizeTextValue(value?: string | null): string {\n return typeof value === \"string\" ? value.trim() : \"\";\n}\n\nfunction buildMaterialIconCandidates(value?: string | null): string[] {\n const trimmed = normalizeTextValue(value);\n\n if (!trimmed) {\n return [];\n }\n\n const camelSeparated = trimmed.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\");\n\n const snakeCase = camelSeparated\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\");\n\n const compact = snakeCase.replace(/_/g, \"\");\n\n return Array.from(\n new Set([trimmed, trimmed.toLowerCase(), snakeCase, compact].filter(Boolean))\n );\n}\n\nfunction resolveMaterialIconName(value?: string | null): string | undefined {\n for (const candidate of buildMaterialIconCandidates(value)) {\n if (hasSolidMaterialIconName(candidate)) {\n return candidate;\n }\n }\n\n return undefined;\n}\n\nfunction cloneResolvedIcon(icon: ResolvedMenuItemIcon): ResolvedMenuItemIcon {\n if (icon.kind === \"solid\") {\n return {\n kind: \"solid\",\n name: icon.name,\n spin: icon.spin,\n };\n }\n\n return {\n kind: \"material\",\n name: icon.name,\n };\n}\n\nfunction getRawIconCandidates(item?: MenuItemIconSource | null): string[] {\n if (!item) {\n return [];\n }\n\n const candidates = [\n typeof item.icon === \"string\" ? item.icon : \"\",\n item.model?.icon,\n item.modelMetadata?.icon,\n item.solidView?.model?.icon,\n ];\n\n return Array.from(\n new Set(candidates.map(normalizeTextValue).filter(Boolean))\n );\n}\n\nfunction getAliasTextCandidates(item?: MenuItemIconSource | null): string[] {\n if (!item) {\n return [];\n }\n\n const candidates = [\n item.title,\n item.label,\n item.model?.displayName,\n item.model?.pluralName,\n item.model?.singularName,\n item.model?.title,\n item.modelMetadata?.displayName,\n item.modelMetadata?.pluralName,\n item.modelMetadata?.singularName,\n item.modelMetadata?.title,\n item.solidView?.model?.displayName,\n item.solidView?.model?.pluralName,\n item.solidView?.model?.singularName,\n item.solidView?.model?.title,\n ...getRawIconCandidates(item),\n ];\n\n return Array.from(\n new Set(candidates.map(normalizeTextValue).filter(Boolean))\n );\n}\n\nfunction resolveAliasedIcon(item?: MenuItemIconSource | null): ResolvedMenuItemIcon | undefined {\n const joinedText = getAliasTextCandidates(item).join(\" \");\n\n if (!joinedText) {\n return undefined;\n }\n\n for (const rule of TITLE_ALIAS_RULES) {\n if (rule.pattern.test(joinedText)) {\n return cloneResolvedIcon(rule.icon);\n }\n }\n\n return undefined;\n}\n\nexport function resolveMenuItemIcon( item?: MenuItemIconSource | null ): ResolvedMenuItemIcon | undefined {\n if (!item) {\n return undefined;\n }\n\n for (const rawIcon of getRawIconCandidates(item)) {\n const solidIcon = parseSolidIconMeta(rawIcon);\n\n if (solidIcon) {\n return {\n kind: \"solid\",\n name: solidIcon.name,\n spin: solidIcon.spin,\n };\n }\n\n const materialIcon = resolveMaterialIconName(rawIcon);\n\n if (materialIcon) {\n return {\n kind: \"material\",\n name: materialIcon,\n };\n }\n }\n\n const derivedMaterialIcon = getAliasTextCandidates(item)\n .map(resolveMaterialIconName)\n .find(Boolean);\n\n if (derivedMaterialIcon) {\n return {\n kind: \"material\",\n name: derivedMaterialIcon,\n };\n }\n\n return resolveAliasedIcon(item);\n}"]}
@@ -0,0 +1,191 @@
1
+ import type { SolidIconName } from "../components/shad-cn-ui/SolidIcon";
2
+ import { parseSolidIconMeta } from "../components/shad-cn-ui/SolidIcon";
3
+ import { hasSolidMaterialIconName } from "./solidIcons";
4
+
5
+ type MenuItemModelMeta = {
6
+ displayName?: string | null;
7
+ icon?: string | null;
8
+ pluralName?: string | null;
9
+ singularName?: string | null;
10
+ title?: string | null;
11
+ };
12
+
13
+ export type MenuItemIconSource = {
14
+ children?: MenuItemIconSource[] | null;
15
+ icon?: string | { src?: string } | null;
16
+ isSystem?: boolean | null;
17
+ label?: string | null;
18
+ model?: MenuItemModelMeta | null;
19
+ modelMetadata?: MenuItemModelMeta | null;
20
+ path?: string | null;
21
+ solidView?: { model?: MenuItemModelMeta | null } | null;
22
+ title?: string | null;
23
+ };
24
+
25
+ export type ResolvedMenuItemIcon =
26
+ | { kind: "material"; name: string }
27
+ | { kind: "solid"; name: SolidIconName; spin?: boolean };
28
+
29
+ const TITLE_ALIAS_RULES: Array<{pattern: RegExp;icon: ResolvedMenuItemIcon;}> = [
30
+ { pattern: /\bwhats?\s?app\b/i, icon: { kind: "material", name: "whatsapp" } },
31
+ { pattern: /\b(user|profile|account|contact)\b/i, icon: { kind: "material", name: "person" } },
32
+ { pattern: /\b(users|profiles|accounts|contacts|members?|people|teams?|groups?)\b/i, icon: { kind: "material", name: "group" } },
33
+ { pattern: /\b(roles?|permissions?|access)\b/i, icon: { kind: "material", name: "admin_panel_settings" } },
34
+ { pattern: /\b(emails?|mail|inbox)\b/i, icon: { kind: "material", name: "email" } },
35
+ { pattern: /\b(messages?|chats?|conversations?)\b/i, icon: { kind: "material", name: "message" } },
36
+ { pattern: /\b(forms?|submissions?)\b/i, icon: { kind: "material", name: "dynamic_form" } },
37
+ { pattern: /\b(reports?|analytics|dashboards?)\b/i, icon: { kind: "material", name: "analytics" } },
38
+ { pattern: /\b(settings?|configs?|configuration|preferences?)\b/i, icon: { kind: "material", name: "settings" } },
39
+ { pattern: /\b(files?|documents?|templates?)\b/i, icon: { kind: "material", name: "article" } },
40
+ ];
41
+
42
+ function normalizeTextValue(value?: string | null): string {
43
+ return typeof value === "string" ? value.trim() : "";
44
+ }
45
+
46
+ function buildMaterialIconCandidates(value?: string | null): string[] {
47
+ const trimmed = normalizeTextValue(value);
48
+
49
+ if (!trimmed) {
50
+ return [];
51
+ }
52
+
53
+ const camelSeparated = trimmed.replace(/([a-z0-9])([A-Z])/g, "$1 $2");
54
+
55
+ const snakeCase = camelSeparated
56
+ .toLowerCase()
57
+ .replace(/[^a-z0-9]+/g, "_")
58
+ .replace(/^_+|_+$/g, "");
59
+
60
+ const compact = snakeCase.replace(/_/g, "");
61
+
62
+ return Array.from(
63
+ new Set([trimmed, trimmed.toLowerCase(), snakeCase, compact].filter(Boolean))
64
+ );
65
+ }
66
+
67
+ function resolveMaterialIconName(value?: string | null): string | undefined {
68
+ for (const candidate of buildMaterialIconCandidates(value)) {
69
+ if (hasSolidMaterialIconName(candidate)) {
70
+ return candidate;
71
+ }
72
+ }
73
+
74
+ return undefined;
75
+ }
76
+
77
+ function cloneResolvedIcon(icon: ResolvedMenuItemIcon): ResolvedMenuItemIcon {
78
+ if (icon.kind === "solid") {
79
+ return {
80
+ kind: "solid",
81
+ name: icon.name,
82
+ spin: icon.spin,
83
+ };
84
+ }
85
+
86
+ return {
87
+ kind: "material",
88
+ name: icon.name,
89
+ };
90
+ }
91
+
92
+ function getRawIconCandidates(item?: MenuItemIconSource | null): string[] {
93
+ if (!item) {
94
+ return [];
95
+ }
96
+
97
+ const candidates = [
98
+ typeof item.icon === "string" ? item.icon : "",
99
+ item.model?.icon,
100
+ item.modelMetadata?.icon,
101
+ item.solidView?.model?.icon,
102
+ ];
103
+
104
+ return Array.from(
105
+ new Set(candidates.map(normalizeTextValue).filter(Boolean))
106
+ );
107
+ }
108
+
109
+ function getAliasTextCandidates(item?: MenuItemIconSource | null): string[] {
110
+ if (!item) {
111
+ return [];
112
+ }
113
+
114
+ const candidates = [
115
+ item.title,
116
+ item.label,
117
+ item.model?.displayName,
118
+ item.model?.pluralName,
119
+ item.model?.singularName,
120
+ item.model?.title,
121
+ item.modelMetadata?.displayName,
122
+ item.modelMetadata?.pluralName,
123
+ item.modelMetadata?.singularName,
124
+ item.modelMetadata?.title,
125
+ item.solidView?.model?.displayName,
126
+ item.solidView?.model?.pluralName,
127
+ item.solidView?.model?.singularName,
128
+ item.solidView?.model?.title,
129
+ ...getRawIconCandidates(item),
130
+ ];
131
+
132
+ return Array.from(
133
+ new Set(candidates.map(normalizeTextValue).filter(Boolean))
134
+ );
135
+ }
136
+
137
+ function resolveAliasedIcon(item?: MenuItemIconSource | null): ResolvedMenuItemIcon | undefined {
138
+ const joinedText = getAliasTextCandidates(item).join(" ");
139
+
140
+ if (!joinedText) {
141
+ return undefined;
142
+ }
143
+
144
+ for (const rule of TITLE_ALIAS_RULES) {
145
+ if (rule.pattern.test(joinedText)) {
146
+ return cloneResolvedIcon(rule.icon);
147
+ }
148
+ }
149
+
150
+ return undefined;
151
+ }
152
+
153
+ export function resolveMenuItemIcon( item?: MenuItemIconSource | null ): ResolvedMenuItemIcon | undefined {
154
+ if (!item) {
155
+ return undefined;
156
+ }
157
+
158
+ for (const rawIcon of getRawIconCandidates(item)) {
159
+ const solidIcon = parseSolidIconMeta(rawIcon);
160
+
161
+ if (solidIcon) {
162
+ return {
163
+ kind: "solid",
164
+ name: solidIcon.name,
165
+ spin: solidIcon.spin,
166
+ };
167
+ }
168
+
169
+ const materialIcon = resolveMaterialIconName(rawIcon);
170
+
171
+ if (materialIcon) {
172
+ return {
173
+ kind: "material",
174
+ name: materialIcon,
175
+ };
176
+ }
177
+ }
178
+
179
+ const derivedMaterialIcon = getAliasTextCandidates(item)
180
+ .map(resolveMaterialIconName)
181
+ .find(Boolean);
182
+
183
+ if (derivedMaterialIcon) {
184
+ return {
185
+ kind: "material",
186
+ name: derivedMaterialIcon,
187
+ };
188
+ }
189
+
190
+ return resolveAliasedIcon(item);
191
+ }
@@ -0,0 +1,3 @@
1
+ export declare const getRelationDisplayText: (value: unknown) => string;
2
+ export declare const getRelatedRecordDisplayText: (record: Record<string, unknown> | null | undefined, userKeyField?: string) => string;
3
+ //# sourceMappingURL=relationDisplay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relationDisplay.d.ts","sourceRoot":"","sources":["../../src/helpers/relationDisplay.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,sBAAsB,UAAW,OAAO,KAAG,MA8CvD,CAAC;AAEF,eAAO,MAAM,2BAA2B,WAAY,OAAO,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,iBAAiB,MAAM,KAAG,MAUvH,CAAC"}