@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.
- package/dist/components/auth/AuthLayout.d.ts.map +1 -1
- package/dist/components/auth/AuthLayout.js +19 -17
- package/dist/components/auth/AuthLayout.js.map +1 -1
- package/dist/components/auth/AuthLayout.tsx +59 -34
- package/dist/components/common/BackendReconnectIndicator.d.ts +6 -0
- package/dist/components/common/BackendReconnectIndicator.d.ts.map +1 -0
- package/dist/components/common/BackendReconnectIndicator.js +25 -0
- package/dist/components/common/BackendReconnectIndicator.js.map +1 -0
- package/dist/components/common/BackendReconnectIndicator.tsx +45 -0
- package/dist/components/common/SettingsComponent.d.ts.map +1 -1
- package/dist/components/common/SettingsComponent.js +7 -3
- package/dist/components/common/SettingsComponent.js.map +1 -1
- package/dist/components/common/SettingsComponent.module.css +144 -12
- package/dist/components/common/SettingsComponent.tsx +22 -3
- package/dist/components/common/SolidAdmin.d.ts.map +1 -1
- package/dist/components/common/SolidAdmin.js +7 -2
- package/dist/components/common/SolidAdmin.js.map +1 -1
- package/dist/components/common/SolidAdmin.tsx +7 -2
- package/dist/components/common/SolidBreadcrumb.d.ts.map +1 -1
- package/dist/components/common/SolidBreadcrumb.js +1 -6
- package/dist/components/common/SolidBreadcrumb.js.map +1 -1
- package/dist/components/common/SolidBreadcrumb.tsx +1 -8
- package/dist/components/common/SolidMaterialSymbol.d.ts +10 -0
- package/dist/components/common/SolidMaterialSymbol.d.ts.map +1 -0
- package/dist/components/common/SolidMaterialSymbol.js +69 -0
- package/dist/components/common/SolidMaterialSymbol.js.map +1 -0
- package/dist/components/common/SolidMaterialSymbol.tsx +96 -0
- package/dist/components/common/SolidToastProvider.d.ts.map +1 -1
- package/dist/components/common/SolidToastProvider.js +14 -1
- package/dist/components/common/SolidToastProvider.js.map +1 -1
- package/dist/components/common/SolidToastProvider.tsx +19 -1
- package/dist/components/core/common/SolidAccountSettings/SolidAccountSettings.module.css +3 -1
- package/dist/components/core/common/SolidGlobalSearchElement.d.ts.map +1 -1
- package/dist/components/core/common/SolidGlobalSearchElement.js +3 -2
- package/dist/components/core/common/SolidGlobalSearchElement.js.map +1 -1
- package/dist/components/core/common/SolidGlobalSearchElement.tsx +14 -18
- package/dist/components/core/extension/solid-core/modelMetadata/list/DeleteModelRowAction.d.ts.map +1 -1
- package/dist/components/core/extension/solid-core/modelMetadata/list/DeleteModelRowAction.js +43 -16
- package/dist/components/core/extension/solid-core/modelMetadata/list/DeleteModelRowAction.js.map +1 -1
- package/dist/components/core/extension/solid-core/modelMetadata/list/DeleteModelRowAction.tsx +24 -2
- package/dist/components/core/form/SolidFormFooter.js +1 -1
- package/dist/components/core/form/SolidFormFooter.js.map +1 -1
- package/dist/components/core/form/SolidFormFooter.tsx +1 -1
- package/dist/components/core/form/SolidFormLayouts.js +1 -1
- package/dist/components/core/form/SolidFormLayouts.js.map +1 -1
- package/dist/components/core/form/SolidFormLayouts.tsx +2 -2
- package/dist/components/core/form/fields/SolidMediaMultipleField.d.ts.map +1 -1
- package/dist/components/core/form/fields/SolidMediaMultipleField.js +120 -56
- package/dist/components/core/form/fields/SolidMediaMultipleField.js.map +1 -1
- package/dist/components/core/form/fields/SolidMediaMultipleField.tsx +63 -50
- package/dist/components/core/form/fields/SolidMediaSingleField.d.ts.map +1 -1
- package/dist/components/core/form/fields/SolidMediaSingleField.js +115 -37
- package/dist/components/core/form/fields/SolidMediaSingleField.js.map +1 -1
- package/dist/components/core/form/fields/SolidMediaSingleField.tsx +36 -35
- package/dist/components/core/form/fields/SolidRichTextField.d.ts.map +1 -1
- package/dist/components/core/form/fields/SolidRichTextField.js +54 -5
- package/dist/components/core/form/fields/SolidRichTextField.js.map +1 -1
- package/dist/components/core/form/fields/SolidRichTextField.tsx +71 -7
- package/dist/components/core/form/fields/mediaFieldUtils.d.ts +3 -0
- package/dist/components/core/form/fields/mediaFieldUtils.d.ts.map +1 -0
- package/dist/components/core/form/fields/mediaFieldUtils.js +30 -0
- package/dist/components/core/form/fields/mediaFieldUtils.js.map +1 -0
- package/dist/components/core/form/fields/mediaFieldUtils.ts +45 -0
- package/dist/components/core/form/fields/relations/RolesGroupedByModuleWidget.d.ts.map +1 -1
- package/dist/components/core/form/fields/relations/RolesGroupedByModuleWidget.js +1 -1
- package/dist/components/core/form/fields/relations/RolesGroupedByModuleWidget.js.map +1 -1
- package/dist/components/core/form/fields/relations/RolesGroupedByModuleWidget.tsx +3 -1
- package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.d.ts.map +1 -1
- package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.js +22 -23
- package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.js.map +1 -1
- package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.tsx +13 -7
- package/dist/components/core/form/fields/widgets/SolidIconEditWidget.d.ts.map +1 -1
- package/dist/components/core/form/fields/widgets/SolidIconEditWidget.js +16 -11
- package/dist/components/core/form/fields/widgets/SolidIconEditWidget.js.map +1 -1
- package/dist/components/core/form/fields/widgets/SolidIconEditWidget.tsx +32 -18
- package/dist/components/core/form/fields/widgets/SolidIconViewWidget.d.ts.map +1 -1
- package/dist/components/core/form/fields/widgets/SolidIconViewWidget.js +3 -1
- package/dist/components/core/form/fields/widgets/SolidIconViewWidget.js.map +1 -1
- package/dist/components/core/form/fields/widgets/SolidIconViewWidget.tsx +11 -5
- package/dist/components/core/list/SolidDataTable.d.ts.map +1 -1
- package/dist/components/core/list/SolidDataTable.js +3 -2
- package/dist/components/core/list/SolidDataTable.js.map +1 -1
- package/dist/components/core/list/SolidDataTable.tsx +3 -2
- package/dist/components/core/list/SolidListView.d.ts.map +1 -1
- package/dist/components/core/list/SolidListView.js +11 -5
- package/dist/components/core/list/SolidListView.js.map +1 -1
- package/dist/components/core/list/SolidListView.tsx +15 -8
- package/dist/components/core/list/SolidListViewColumn.d.ts.map +1 -1
- package/dist/components/core/list/SolidListViewColumn.js +1 -0
- package/dist/components/core/list/SolidListViewColumn.js.map +1 -1
- package/dist/components/core/list/SolidListViewColumn.tsx +1 -0
- package/dist/components/core/list/columns/SolidShortTextColumn.d.ts.map +1 -1
- package/dist/components/core/list/columns/SolidShortTextColumn.js +7 -2
- package/dist/components/core/list/columns/SolidShortTextColumn.js.map +1 -1
- package/dist/components/core/list/columns/SolidShortTextColumn.tsx +7 -2
- package/dist/components/core/list/columns/relations/SolidRelationManyToManyColumn.d.ts.map +1 -1
- package/dist/components/core/list/columns/relations/SolidRelationManyToManyColumn.js +4 -1
- package/dist/components/core/list/columns/relations/SolidRelationManyToManyColumn.js.map +1 -1
- package/dist/components/core/list/columns/relations/SolidRelationManyToManyColumn.tsx +5 -2
- package/dist/components/core/list/columns/relations/SolidRelationManyToOneColumn.d.ts.map +1 -1
- package/dist/components/core/list/columns/relations/SolidRelationManyToOneColumn.js +2 -1
- package/dist/components/core/list/columns/relations/SolidRelationManyToOneColumn.js.map +1 -1
- package/dist/components/core/list/columns/relations/SolidRelationManyToOneColumn.tsx +2 -1
- package/dist/components/core/list/columns/relations/SolidRelationOneToManyColumn.d.ts.map +1 -1
- package/dist/components/core/list/columns/relations/SolidRelationOneToManyColumn.js +4 -1
- package/dist/components/core/list/columns/relations/SolidRelationOneToManyColumn.js.map +1 -1
- package/dist/components/core/list/columns/relations/SolidRelationOneToManyColumn.tsx +5 -2
- package/dist/components/core/locales/SolidLocale.d.ts.map +1 -1
- package/dist/components/core/locales/SolidLocale.js +1 -1
- package/dist/components/core/locales/SolidLocale.js.map +1 -1
- package/dist/components/core/locales/SolidLocale.tsx +1 -0
- package/dist/components/core/model/CreateModel.css +26 -0
- package/dist/components/core/model/FieldMetaData.d.ts.map +1 -1
- package/dist/components/core/model/FieldMetaData.js +21 -3
- package/dist/components/core/model/FieldMetaData.js.map +1 -1
- package/dist/components/core/model/FieldMetaData.tsx +45 -4
- package/dist/components/core/model/FieldMetaDataForm.css +82 -0
- package/dist/components/core/model/FieldMetaDataForm.d.ts +1 -0
- package/dist/components/core/model/FieldMetaDataForm.d.ts.map +1 -1
- package/dist/components/core/model/FieldMetaDataForm.js +246 -235
- package/dist/components/core/model/FieldMetaDataForm.js.map +1 -1
- package/dist/components/core/model/FieldMetaDataForm.tsx +46 -34
- package/dist/components/core/model/FieldSelector.js +1 -1
- package/dist/components/core/model/FieldSelector.js.map +1 -1
- package/dist/components/core/model/FieldSelector.tsx +1 -1
- package/dist/components/core/model/ModelMetaData.js +1 -1
- package/dist/components/core/model/ModelMetaData.js.map +1 -1
- package/dist/components/core/model/ModelMetaData.tsx +1 -1
- package/dist/components/core/module/CreateModule.css +55 -2
- package/dist/components/core/module/CreateModule.d.ts.map +1 -1
- package/dist/components/core/module/CreateModule.js +2 -2
- package/dist/components/core/module/CreateModule.js.map +1 -1
- package/dist/components/core/module/CreateModule.tsx +3 -2
- package/dist/components/core/module/ModuleMetadataExplorer.css +27 -0
- package/dist/components/core/module/ModuleMetadataExplorer.d.ts.map +1 -1
- package/dist/components/core/module/ModuleMetadataExplorer.js +1 -1
- package/dist/components/core/module/ModuleMetadataExplorer.js.map +1 -1
- package/dist/components/core/module/ModuleMetadataExplorer.tsx +1 -0
- package/dist/components/core/tree/SolidTreeView.d.ts.map +1 -1
- package/dist/components/core/tree/SolidTreeView.js +6 -1
- package/dist/components/core/tree/SolidTreeView.js.map +1 -1
- package/dist/components/core/tree/SolidTreeView.tsx +7 -1
- package/dist/components/layout/AdminHeaderActions.d.ts.map +1 -1
- package/dist/components/layout/AdminHeaderActions.js +10 -9
- package/dist/components/layout/AdminHeaderActions.js.map +1 -1
- package/dist/components/layout/AdminHeaderActions.tsx +2 -0
- package/dist/components/layout/AppSidebar.d.ts.map +1 -1
- package/dist/components/layout/AppSidebar.js +2 -1
- package/dist/components/layout/AppSidebar.js.map +1 -1
- package/dist/components/layout/AppSidebar.tsx +12 -5
- package/dist/components/layout/SolidMenuItemIcon.d.ts +9 -0
- package/dist/components/layout/SolidMenuItemIcon.d.ts.map +1 -0
- package/dist/components/layout/SolidMenuItemIcon.js +20 -0
- package/dist/components/layout/SolidMenuItemIcon.js.map +1 -0
- package/dist/components/layout/SolidMenuItemIcon.tsx +45 -0
- package/dist/components/layout/navbar-two-menu.d.ts.map +1 -1
- package/dist/components/layout/navbar-two-menu.js +6 -7
- package/dist/components/layout/navbar-two-menu.js.map +1 -1
- package/dist/components/layout/navbar-two-menu.tsx +4 -12
- package/dist/components/shad-cn-ui/SolidCodeEditor.d.ts.map +1 -1
- package/dist/components/shad-cn-ui/SolidCodeEditor.js +30 -2
- package/dist/components/shad-cn-ui/SolidCodeEditor.js.map +1 -1
- package/dist/components/shad-cn-ui/SolidCodeEditor.tsx +38 -1
- package/dist/helpers/backendHealthMonitor.d.ts +39 -0
- package/dist/helpers/backendHealthMonitor.d.ts.map +1 -0
- package/dist/helpers/backendHealthMonitor.js +255 -0
- package/dist/helpers/backendHealthMonitor.js.map +1 -0
- package/dist/helpers/backendHealthMonitor.ts +177 -0
- package/dist/helpers/helpers.d.ts +1 -0
- package/dist/helpers/helpers.d.ts.map +1 -1
- package/dist/helpers/helpers.js +9 -0
- package/dist/helpers/helpers.js.map +1 -1
- package/dist/helpers/helpers.ts +11 -1
- package/dist/helpers/menuItemIcons.d.ts +34 -0
- package/dist/helpers/menuItemIcons.d.ts.map +1 -0
- package/dist/helpers/menuItemIcons.js +144 -0
- package/dist/helpers/menuItemIcons.js.map +1 -0
- package/dist/helpers/menuItemIcons.ts +191 -0
- package/dist/helpers/relationDisplay.d.ts +3 -0
- package/dist/helpers/relationDisplay.d.ts.map +1 -0
- package/dist/helpers/relationDisplay.js +92 -0
- package/dist/helpers/relationDisplay.js.map +1 -0
- package/dist/helpers/relationDisplay.ts +101 -0
- package/dist/helpers/settingsPayload.d.ts +1 -0
- package/dist/helpers/settingsPayload.d.ts.map +1 -1
- package/dist/helpers/settingsPayload.js.map +1 -1
- package/dist/helpers/settingsPayload.ts +1 -0
- package/dist/helpers/solidIcons.d.ts +2 -0
- package/dist/helpers/solidIcons.d.ts.map +1 -1
- package/dist/helpers/solidIcons.js +8 -0
- package/dist/helpers/solidIcons.js.map +1 -1
- package/dist/helpers/solidIcons.tsx +10 -1
- package/dist/helpers/waitForBackendAvailability.d.ts +1 -0
- package/dist/helpers/waitForBackendAvailability.d.ts.map +1 -1
- package/dist/helpers/waitForBackendAvailability.js +35 -22
- package/dist/helpers/waitForBackendAvailability.js.map +1 -1
- package/dist/helpers/waitForBackendAvailability.ts +18 -12
- package/dist/http/solidHttp.d.ts.map +1 -1
- package/dist/http/solidHttp.js +10 -4
- package/dist/http/solidHttp.js.map +1 -1
- package/dist/http/solidHttp.ts +9 -4
- package/dist/redux/api/datasourceIntrospectionApi.d.ts +4 -0
- package/dist/redux/api/datasourceIntrospectionApi.d.ts.map +1 -1
- package/dist/redux/api/datasourceIntrospectionApi.js.map +1 -1
- package/dist/redux/api/datasourceIntrospectionApi.ts +4 -0
- package/dist/redux/api/fetchBaseQuery.d.ts.map +1 -1
- package/dist/redux/api/fetchBaseQuery.js +9 -3
- package/dist/redux/api/fetchBaseQuery.js.map +1 -1
- package/dist/redux/api/fetchBaseQuery.tsx +9 -3
- package/dist/redux/store/StoreProvider.d.ts.map +1 -1
- package/dist/redux/store/StoreProvider.js +4 -3
- package/dist/redux/store/StoreProvider.js.map +1 -1
- package/dist/redux/store/StoreProvider.tsx +4 -3
- package/dist/resources/globals.css +341 -49
- package/dist/resources/solid-custom.css +410 -12
- package/dist/resources/solid-responsive.css +27 -16
- package/dist/resources/solid-tailwind-generated.css +1 -1
- package/dist/routes/AppEventListener.d.ts.map +1 -1
- package/dist/routes/AppEventListener.js +23 -0
- package/dist/routes/AppEventListener.js.map +1 -1
- package/dist/routes/AppEventListener.tsx +29 -0
- package/dist/routes/pages/admin/core/DashboardPage.module.css +12 -0
- package/dist/routes/pages/admin/core/DatasourceIntrospectionPage.css +306 -3
- package/dist/routes/pages/admin/core/DatasourceIntrospectionPage.d.ts.map +1 -1
- package/dist/routes/pages/admin/core/DatasourceIntrospectionPage.js +745 -393
- package/dist/routes/pages/admin/core/DatasourceIntrospectionPage.js.map +1 -1
- package/dist/routes/pages/admin/core/DatasourceIntrospectionPage.tsx +1074 -420
- package/dist/routes/pages/admin/core/DatasourcesPage.css +15 -0
- package/dist/routes/pages/admin/core/DatasourcesPage.d.ts.map +1 -1
- package/dist/routes/pages/admin/core/DatasourcesPage.js +7 -188
- package/dist/routes/pages/admin/core/DatasourcesPage.js.map +1 -1
- package/dist/routes/pages/admin/core/DatasourcesPage.tsx +3 -393
- 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"}
|
package/dist/helpers/helpers.js
CHANGED
|
@@ -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"]}
|
package/dist/helpers/helpers.ts
CHANGED
|
@@ -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 @@
|
|
|
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"}
|