@dashadmin/dash-app-common 1.3.24 → 1.3.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DashApp.js +176 -1
- package/dist/DashAppLoader.js +348 -3
- package/dist/DashDefaultResources.js +10 -1
- package/dist/components/DashDefaultPrivateApp.js +150 -1
- package/dist/components/DashDefaultPrivateResources.js +10 -1
- package/dist/components/DashDefaultPublicApp.js +20 -1
- package/dist/components/DashResourceLoader.js +245 -1
- package/dist/defaults/extensions/bootstrap/DashDefaultErrorBoundary.js +78 -1
- package/dist/defaults/extensions/bootstrap/dashDefaultInitializeApp.js +59 -1
- package/dist/defaults/extensions/bootstrap/index.js +24 -1
- package/dist/defaults/extensions/components/DashDefaultLoader.js +43 -2
- package/dist/defaults/extensions/components/dashDefaultAutoAdminComponents.js +67 -1
- package/dist/defaults/extensions/components/dashDefaultNotification.js +28 -1
- package/dist/defaults/extensions/components/dashDefaultStaticComponents.js +15 -1
- package/dist/defaults/extensions/components/index.js +13 -1
- package/dist/defaults/extensions/electron/dashDefaultIpcListeners.js +38 -1
- package/dist/defaults/extensions/electron/index.js +5 -1
- package/dist/defaults/extensions/hooks/index.js +12 -1
- package/dist/defaults/extensions/hooks/useDashDefaultLazyAutoAdminComponents.js +17 -1
- package/dist/defaults/extensions/hooks/useDashDefaultLazyI18nProvider.js +51 -1
- package/dist/defaults/extensions/hooks/useDashDefaultLazyResources.js +19 -1
- package/dist/defaults/extensions/hooks/useDashDefaultMountTracker.js +22 -1
- package/dist/defaults/extensions/hooks/useDashDefaultRoutePath.js +17 -1
- package/dist/defaults/extensions/i18n/dashDefaultI18nProvider.js +44 -1
- package/dist/defaults/extensions/i18n/dashDefaultTranslations.js +87 -1
- package/dist/defaults/extensions/i18n/index.js +24 -1
- package/dist/defaults/extensions/index.js +190 -1
- package/dist/defaults/extensions/layout/dashDefaultDomainAppLayout.js +58 -1
- package/dist/defaults/extensions/layout/index.js +12 -1
- package/dist/defaults/extensions/managers/DashDefaultWSMessagesManager.js +84 -1
- package/dist/defaults/extensions/managers/index.js +5 -1
- package/dist/defaults/extensions/providers/dashDefaultAuthProvider.js +220 -1
- package/dist/defaults/extensions/providers/dashDefaultDataProvider.js +395 -1
- package/dist/defaults/extensions/providers/index.js +24 -1
- package/dist/defaults/extensions/router/DashDefaultLanding.js +46 -1
- package/dist/defaults/extensions/router/dashDefaultPrivateRoutes.js +38 -1
- package/dist/defaults/extensions/router/dashDefaultPublicRoutes.js +65 -1
- package/dist/defaults/extensions/router/dashDefaultRouter.js +39 -1
- package/dist/defaults/extensions/router/dashDefaultSharedRoutes.js +40 -1
- package/dist/defaults/extensions/router/index.js +12 -1
- package/dist/defaults/extensions/state/dashDefaultAppCommon.js +57 -1
- package/dist/defaults/extensions/state/dashDefaultAppSettings.js +38 -1
- package/dist/defaults/extensions/state/dashDefaultInitialAppState.js +31 -1
- package/dist/defaults/extensions/state/dashDefaultLayoutSettings.js +48 -1
- package/dist/defaults/extensions/state/dashDefaultQueryClient.js +58 -1
- package/dist/defaults/extensions/state/dashDefaultResourcesIcons.js +24 -1
- package/dist/defaults/extensions/state/index.js +29 -1
- package/dist/defaults/extensions/styles/index.js +2 -1
- package/dist/defaults/extensions/theme/dashDefaultThemeOptions.js +74 -1
- package/dist/defaults/extensions/theme/index.js +6 -1
- package/dist/defaults/extensions/utils/IPCMessageBrokerContext.js +12 -1
- package/dist/defaults/extensions/utils/dashDefaultAuthProviderUtils.js +29 -1
- package/dist/defaults/extensions/utils/dashDefaultDataProviderUtils.js +37 -1
- package/dist/defaults/extensions/utils/dashDefaultNotificationsProcessor.js +149 -1
- package/dist/defaults/extensions/utils/index.js +44 -1
- package/dist/defaults/filters/demo/dashDefaultDemoFilters.js +36 -1
- package/dist/defaults/filters/demo/index.js +4 -1
- package/dist/defaults/filters/index.js +5 -1
- package/dist/defaults/index.js +14 -1
- package/dist/defaults/pages/Account/DashDefaultRegister.js +282 -1
- package/dist/defaults/pages/Account/DashDefaultSignUp.js +420 -1
- package/dist/defaults/pages/Account/DashDefaultSignUpSuccess.js +101 -1
- package/dist/defaults/pages/Account/index.js +8 -1
- package/dist/defaults/pages/DashDefaultLogin.js +218 -1
- package/dist/defaults/pages/Misc/DashDefaultNotFound.js +74 -1
- package/dist/defaults/pages/Misc/DashDefaultServerError.js +79 -1
- package/dist/defaults/pages/Misc/DashDefaultUnauthorized.js +90 -1
- package/dist/defaults/pages/Misc/index.js +8 -1
- package/dist/defaults/pages/Static/DashDefaultPrivacyPage.js +48 -1
- package/dist/defaults/pages/Static/DashDefaultStaticPage.js +55 -1
- package/dist/defaults/pages/Static/DashDefaultTermsPage.js +52 -1
- package/dist/defaults/pages/Static/index.js +8 -1
- package/dist/defaults/pages/index.js +25 -1
- package/dist/defaults/schemas/dashDefaultSchema.js +14 -1
- package/dist/defaults/schemas/demo/dashDefaultTodoSchema.js +24 -1
- package/dist/defaults/schemas/demo/index.js +4 -1
- package/dist/defaults/schemas/index.js +7 -1
- package/dist/filters/demo/todoFilters.js +36 -1
- package/dist/index.js +56 -5975
- package/dist/resources/demo/todoResource.js +58 -1
- package/dist/schemas/defaultSchema.js +14 -1
- package/dist/schemas/demo/todoSchema.js +24 -1
- package/package.json +132 -77
- package/src/DashApp.tsx +294 -0
- package/src/DashAppLoader.tsx +717 -0
- package/src/DashDefaultResources.tsx +10 -0
- package/src/components/DashDefaultPrivateApp.tsx +358 -0
- package/src/components/DashDefaultPrivateResources.tsx +10 -0
- package/src/components/DashDefaultPublicApp.tsx +40 -0
- package/src/components/DashResourceLoader.tsx +564 -0
- package/src/defaults/extensions/bootstrap/DashDefaultErrorBoundary.tsx +113 -0
- package/src/defaults/extensions/bootstrap/dashDefaultInitializeApp.ts +81 -0
- package/src/defaults/extensions/bootstrap/index.ts +32 -0
- package/src/defaults/extensions/components/DashDefaultLoader.tsx +59 -0
- package/src/defaults/extensions/components/dashDefaultAutoAdminComponents.tsx +49 -0
- package/src/defaults/extensions/components/dashDefaultNotification.tsx +37 -0
- package/src/defaults/extensions/components/dashDefaultStaticComponents.tsx +34 -0
- package/src/defaults/extensions/components/index.ts +17 -0
- package/src/defaults/extensions/electron/dashDefaultIpcListeners.ts +62 -0
- package/src/defaults/extensions/electron/index.ts +7 -0
- package/src/defaults/extensions/hooks/index.ts +11 -0
- package/src/defaults/extensions/hooks/useDashDefaultLazyAutoAdminComponents.ts +25 -0
- package/src/defaults/extensions/hooks/useDashDefaultLazyI18nProvider.ts +38 -0
- package/src/defaults/extensions/hooks/useDashDefaultLazyResources.ts +29 -0
- package/src/defaults/extensions/hooks/useDashDefaultMountTracker.ts +28 -0
- package/src/defaults/extensions/hooks/useDashDefaultRoutePath.ts +27 -0
- package/src/defaults/extensions/i18n/dashDefaultI18nProvider.ts +66 -0
- package/src/defaults/extensions/i18n/dashDefaultTranslations.ts +82 -0
- package/src/defaults/extensions/i18n/index.ts +22 -0
- package/src/defaults/extensions/index.ts +177 -0
- package/src/defaults/extensions/layout/dashDefaultDomainAppLayout.tsx +126 -0
- package/src/defaults/extensions/layout/index.ts +12 -0
- package/src/defaults/extensions/managers/DashDefaultWSMessagesManager.tsx +99 -0
- package/src/defaults/extensions/managers/index.ts +7 -0
- package/src/defaults/extensions/providers/dashDefaultAuthProvider.ts +256 -0
- package/src/defaults/extensions/providers/dashDefaultDataProvider.ts +513 -0
- package/src/defaults/extensions/providers/index.ts +25 -0
- package/src/defaults/extensions/router/DashDefaultLanding.tsx +51 -0
- package/src/defaults/extensions/router/dashDefaultPrivateRoutes.tsx +50 -0
- package/src/defaults/extensions/router/dashDefaultPublicRoutes.tsx +86 -0
- package/src/defaults/extensions/router/dashDefaultRouter.tsx +54 -0
- package/src/defaults/extensions/router/dashDefaultSharedRoutes.tsx +56 -0
- package/src/defaults/extensions/router/index.ts +13 -0
- package/src/defaults/extensions/state/dashDefaultAppCommon.ts +54 -0
- package/src/defaults/extensions/state/dashDefaultAppSettings.ts +29 -0
- package/src/defaults/extensions/state/dashDefaultInitialAppState.ts +75 -0
- package/src/defaults/extensions/state/dashDefaultLayoutSettings.ts +59 -0
- package/src/defaults/extensions/state/dashDefaultQueryClient.ts +59 -0
- package/src/defaults/extensions/state/dashDefaultResourcesIcons.tsx +23 -0
- package/src/defaults/extensions/state/index.ts +29 -0
- package/src/defaults/extensions/styles/index.ts +17 -0
- package/src/defaults/extensions/theme/dashDefaultThemeOptions.ts +89 -0
- package/src/defaults/extensions/theme/index.ts +7 -0
- package/src/defaults/extensions/utils/IPCMessageBrokerContext.tsx +22 -0
- package/src/defaults/extensions/utils/dashDefaultAuthProviderUtils.ts +36 -0
- package/src/defaults/extensions/utils/dashDefaultDataProviderUtils.ts +46 -0
- package/src/defaults/extensions/utils/dashDefaultNotificationsProcessor.tsx +208 -0
- package/src/defaults/extensions/utils/index.ts +42 -0
- package/src/defaults/filters/demo/dashDefaultDemoFilters.tsx +50 -0
- package/src/defaults/filters/demo/index.ts +6 -0
- package/src/defaults/filters/index.ts +11 -0
- package/src/defaults/index.ts +27 -0
- package/src/defaults/pages/Account/DashDefaultRegister.tsx +281 -0
- package/src/defaults/pages/Account/DashDefaultSignUp.tsx +492 -0
- package/src/defaults/pages/Account/DashDefaultSignUpSuccess.tsx +113 -0
- package/src/defaults/pages/Account/index.ts +8 -0
- package/src/defaults/pages/DashDefaultLogin.tsx +224 -0
- package/src/defaults/pages/Misc/DashDefaultNotFound.tsx +96 -0
- package/src/defaults/pages/Misc/DashDefaultServerError.tsx +102 -0
- package/src/defaults/pages/Misc/DashDefaultUnauthorized.tsx +116 -0
- package/src/defaults/pages/Misc/index.ts +8 -0
- package/src/defaults/pages/Static/DashDefaultPrivacyPage.tsx +85 -0
- package/src/defaults/pages/Static/DashDefaultStaticPage.tsx +75 -0
- package/src/defaults/pages/Static/DashDefaultTermsPage.tsx +69 -0
- package/src/defaults/pages/Static/index.ts +8 -0
- package/src/defaults/pages/index.ts +28 -0
- package/src/defaults/schemas/dashDefaultSchema.tsx +25 -0
- package/src/defaults/schemas/demo/dashDefaultTodoSchema.tsx +39 -0
- package/src/defaults/schemas/demo/index.ts +6 -0
- package/src/defaults/schemas/index.ts +14 -0
- package/src/filters/demo/todoFilters.tsx +39 -0
- package/src/index.ts +131 -0
- package/src/resources/demo/todoResource.tsx +68 -0
- package/src/schemas/defaultSchema.tsx +14 -0
- package/src/schemas/demo/todoSchema.tsx +27 -0
|
@@ -0,0 +1,717 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DashAppLoader
|
|
3
|
+
*
|
|
4
|
+
* The core authentication-aware application loader for Dash Framework.
|
|
5
|
+
* Handles auth state management, Redux session restoration, and conditional
|
|
6
|
+
* rendering of public/private apps based on authentication status.
|
|
7
|
+
*
|
|
8
|
+
* This component consolidates all app bootstrapping logic:
|
|
9
|
+
* - Auth state detection and initialization
|
|
10
|
+
* - Redux state restoration from localStorage
|
|
11
|
+
* - Device storage synchronization
|
|
12
|
+
* - Lazy loading of public/private app components
|
|
13
|
+
* - Loading and error state management
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* ```tsx
|
|
17
|
+
* import { DashAppLoader, createDashAppLoader } from 'dash-app-common';
|
|
18
|
+
*
|
|
19
|
+
* // Option 1: Minimal usage with all defaults (zero-config)
|
|
20
|
+
* <DashAppLoader />
|
|
21
|
+
*
|
|
22
|
+
* // Option 2: Direct usage with custom apps
|
|
23
|
+
* <DashAppLoader
|
|
24
|
+
* publicAppImport={() => import('./PublicApp')}
|
|
25
|
+
* privateAppImport={() => import('./AdminApp')}
|
|
26
|
+
* />
|
|
27
|
+
*
|
|
28
|
+
* // Option 3: Factory function for reusable loader
|
|
29
|
+
* const AppLoader = createDashAppLoader({
|
|
30
|
+
* publicAppImport: () => import('./PublicApp'),
|
|
31
|
+
* privateAppImport: () => import('./AdminApp'),
|
|
32
|
+
* AdminHookComponent: MainAppHook,
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* <AppLoader />
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
import React, { ComponentType, Suspense, useEffect, useState, useCallback, lazy, useMemo } from 'react';
|
|
39
|
+
import { useSelector, useDispatch } from 'react-redux';
|
|
40
|
+
import { useDeviceStorageSync } from 'dash-utils';
|
|
41
|
+
|
|
42
|
+
// Import framework defaults that can't be imported in dash-utils due to circular deps
|
|
43
|
+
import DASHAuthenticationService from 'dash-admin/src/contexts/auth/DASHAuthenticationService';
|
|
44
|
+
import { DASH_REDUX_ACTIONS } from 'dash-admin-state';
|
|
45
|
+
import { ACTION_UPDATE_AUTH } from 'dash-admin-state/src/redux/reducers/Auth';
|
|
46
|
+
import AppLoadingFallback from 'dash-components/src/components/theme/AppLoadingFallback';
|
|
47
|
+
import DashDefaultPublicApp from './components/DashDefaultPublicApp';
|
|
48
|
+
import DashDefaultPrivateApp from './components/DashDefaultPrivateApp';
|
|
49
|
+
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// TYPES & INTERFACES
|
|
52
|
+
// ============================================================================
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Interface for Redux auth state
|
|
56
|
+
* Represents the authentication state in Redux store
|
|
57
|
+
*/
|
|
58
|
+
export interface IDashAuthState {
|
|
59
|
+
isLogged: boolean;
|
|
60
|
+
isLoading: boolean;
|
|
61
|
+
token: string | null;
|
|
62
|
+
user: Record<string, any> | null;
|
|
63
|
+
[key: string]: any;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Interface for Redux app state with auth
|
|
68
|
+
* Represents the full Redux state structure
|
|
69
|
+
*/
|
|
70
|
+
export interface IDashAppState {
|
|
71
|
+
auth: IDashAuthState;
|
|
72
|
+
[key: string]: any;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Interface for auth service (like DASHAuthenticationService)
|
|
77
|
+
* Defines the contract for authentication services
|
|
78
|
+
*/
|
|
79
|
+
export interface IDashAuthService {
|
|
80
|
+
/** Initialize app authentication - checks for existing tokens and restores session */
|
|
81
|
+
initializeApp?: (forceGetAuth?: boolean) => Promise<{ success: boolean; user?: any; token?: string; error?: string }>;
|
|
82
|
+
/** Alternative init method for simpler auth services */
|
|
83
|
+
init?: () => Promise<{ success: boolean; user?: any }>;
|
|
84
|
+
login?: (credentials: any) => Promise<any>;
|
|
85
|
+
logout?: () => Promise<void>;
|
|
86
|
+
checkAuth?: () => Promise<boolean>;
|
|
87
|
+
getToken?: () => string | null;
|
|
88
|
+
getUser?: () => any;
|
|
89
|
+
getInitialAuthState?: () => { authenticated: boolean; user: any; auth: any };
|
|
90
|
+
[key: string]: any;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Interface for Redux actions
|
|
95
|
+
* Defines the contract for Redux action creators
|
|
96
|
+
*/
|
|
97
|
+
export interface IDashReduxActions {
|
|
98
|
+
loginSuccess?: (user: any, token?: string) => { type: string; payload: any };
|
|
99
|
+
logout?: () => { type: string };
|
|
100
|
+
setLoading?: (loading: boolean) => { type: string; payload: boolean };
|
|
101
|
+
updateAuth?: (type: any, auth: any) => { type: string; payload: any };
|
|
102
|
+
[key: string]: any;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Configuration for DashAppLoader
|
|
107
|
+
* All props are optional - sensible defaults are provided
|
|
108
|
+
*/
|
|
109
|
+
export interface DashAppLoaderConfig {
|
|
110
|
+
/**
|
|
111
|
+
* Function to import the public app component (lazy loaded)
|
|
112
|
+
* If not provided, uses DefaultPublicApp with basic login/auth routes
|
|
113
|
+
* @optional
|
|
114
|
+
* @example () => import('./DASHPublicApp')
|
|
115
|
+
*/
|
|
116
|
+
publicAppImport?: () => Promise<{ default: ComponentType<any> }>;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Function to import the private/admin app component (lazy loaded)
|
|
120
|
+
* If not provided, uses DefaultPrivateApp with minimal admin shell
|
|
121
|
+
* @optional
|
|
122
|
+
* @example () => import('./DASHLazyAdminApp')
|
|
123
|
+
*/
|
|
124
|
+
privateAppImport?: () => Promise<{ default: ComponentType<any> }>;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* The authentication service for checking auth status
|
|
128
|
+
* If not provided, uses DASHAuthenticationService from dash-admin
|
|
129
|
+
* @optional
|
|
130
|
+
*/
|
|
131
|
+
authService?: IDashAuthService;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Redux actions for auth state management
|
|
135
|
+
* If not provided, uses DASH_REDUX_ACTIONS from dash-admin-state
|
|
136
|
+
* @optional
|
|
137
|
+
*/
|
|
138
|
+
reduxActions?: IDashReduxActions;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* The Redux action type for updating auth state
|
|
142
|
+
* Used to dispatch auth restoration from localStorage
|
|
143
|
+
* @default ACTION_UPDATE_AUTH
|
|
144
|
+
*/
|
|
145
|
+
updateAuthActionType?: string;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Optional admin hook component to inject into the private app
|
|
149
|
+
* This is rendered as the AdminHook prop of the private app
|
|
150
|
+
* @optional
|
|
151
|
+
*/
|
|
152
|
+
AdminHookComponent?: ComponentType<any>;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Optional custom loading fallback component
|
|
156
|
+
* If not provided, uses AppLoadingFallback from dash-components
|
|
157
|
+
* @optional
|
|
158
|
+
*/
|
|
159
|
+
LoadingFallback?: ComponentType<{ message?: string }>;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Optional custom error fallback component
|
|
163
|
+
* If not provided, uses the default error UI
|
|
164
|
+
* @optional
|
|
165
|
+
*/
|
|
166
|
+
ErrorFallback?: ComponentType<{ error: string; onRetry: () => void }>;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Additional props to pass to the private app
|
|
170
|
+
* @optional
|
|
171
|
+
*/
|
|
172
|
+
privateAppProps?: Record<string, any>;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Additional props to pass to the public app
|
|
176
|
+
* @optional
|
|
177
|
+
*/
|
|
178
|
+
publicAppProps?: Record<string, any>;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Enable debug logging
|
|
182
|
+
* @default false
|
|
183
|
+
*/
|
|
184
|
+
debug?: boolean;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Props for DashAppLoader - extends DashAppLoaderConfig
|
|
189
|
+
*/
|
|
190
|
+
export interface DashAppLoaderProps extends DashAppLoaderConfig {}
|
|
191
|
+
|
|
192
|
+
// ============================================================================
|
|
193
|
+
// HELPER FUNCTIONS
|
|
194
|
+
// ============================================================================
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Debug logging helper
|
|
198
|
+
* Only logs when debug mode is enabled
|
|
199
|
+
*/
|
|
200
|
+
const log = (debug: boolean, ...args: any[]) => {
|
|
201
|
+
if (debug) {
|
|
202
|
+
console.log(...args);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
// ============================================================================
|
|
207
|
+
// DEFAULT FALLBACK COMPONENTS
|
|
208
|
+
// ============================================================================
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Default loading fallback component
|
|
212
|
+
* Shows a simple loading message with spinner
|
|
213
|
+
*/
|
|
214
|
+
const DefaultLoadingFallback: React.FC<{ message?: string }> = ({ message }) => (
|
|
215
|
+
<div style={{
|
|
216
|
+
display: 'flex',
|
|
217
|
+
flexDirection: 'column',
|
|
218
|
+
justifyContent: 'center',
|
|
219
|
+
alignItems: 'center',
|
|
220
|
+
height: '100vh',
|
|
221
|
+
width: '100%',
|
|
222
|
+
backgroundColor: 'var(--dash-background, #121212)',
|
|
223
|
+
color: 'var(--dash-text, #ffffff)'
|
|
224
|
+
}}>
|
|
225
|
+
<div style={{
|
|
226
|
+
width: '40px',
|
|
227
|
+
height: '40px',
|
|
228
|
+
border: '3px solid rgba(255,255,255,0.3)',
|
|
229
|
+
borderTop: '3px solid var(--dash-primary, #90caf9)',
|
|
230
|
+
borderRadius: '50%',
|
|
231
|
+
animation: 'spin 1s linear infinite',
|
|
232
|
+
marginBottom: '16px'
|
|
233
|
+
}} />
|
|
234
|
+
<p style={{ margin: 0, fontSize: '14px', opacity: 0.8 }}>
|
|
235
|
+
{message || 'Loading application...'}
|
|
236
|
+
</p>
|
|
237
|
+
<style>{`
|
|
238
|
+
@keyframes spin {
|
|
239
|
+
0% { transform: rotate(0deg); }
|
|
240
|
+
100% { transform: rotate(360deg); }
|
|
241
|
+
}
|
|
242
|
+
`}</style>
|
|
243
|
+
</div>
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Default error fallback component
|
|
248
|
+
* Shows error message with retry button
|
|
249
|
+
*/
|
|
250
|
+
const DefaultErrorFallback: React.FC<{ error: string; onRetry: () => void }> = ({
|
|
251
|
+
error,
|
|
252
|
+
onRetry
|
|
253
|
+
}) => (
|
|
254
|
+
<div style={{
|
|
255
|
+
display: 'flex',
|
|
256
|
+
flexDirection: 'column',
|
|
257
|
+
justifyContent: 'center',
|
|
258
|
+
alignItems: 'center',
|
|
259
|
+
height: '100vh',
|
|
260
|
+
width: '100%',
|
|
261
|
+
backgroundColor: 'var(--dash-background, #121212)',
|
|
262
|
+
color: 'var(--dash-text, #ffffff)',
|
|
263
|
+
padding: '20px'
|
|
264
|
+
}}>
|
|
265
|
+
<h2 style={{ color: '#f44336', marginBottom: '16px' }}>Application Error</h2>
|
|
266
|
+
<p style={{
|
|
267
|
+
maxWidth: '500px',
|
|
268
|
+
textAlign: 'center',
|
|
269
|
+
marginBottom: '24px',
|
|
270
|
+
opacity: 0.8
|
|
271
|
+
}}>
|
|
272
|
+
{error}
|
|
273
|
+
</p>
|
|
274
|
+
<button
|
|
275
|
+
onClick={onRetry}
|
|
276
|
+
style={{
|
|
277
|
+
backgroundColor: 'var(--dash-primary, #90caf9)',
|
|
278
|
+
color: '#000',
|
|
279
|
+
border: 'none',
|
|
280
|
+
padding: '12px 24px',
|
|
281
|
+
borderRadius: '4px',
|
|
282
|
+
cursor: 'pointer',
|
|
283
|
+
fontSize: '14px',
|
|
284
|
+
fontWeight: 500
|
|
285
|
+
}}
|
|
286
|
+
>
|
|
287
|
+
Retry
|
|
288
|
+
</button>
|
|
289
|
+
</div>
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Configuration error component
|
|
294
|
+
* Shows detailed error for missing required configuration
|
|
295
|
+
*/
|
|
296
|
+
const ConfigurationError: React.FC<{ missingProps: string[] }> = ({ missingProps }) => (
|
|
297
|
+
<div style={{
|
|
298
|
+
display: 'flex',
|
|
299
|
+
flexDirection: 'column',
|
|
300
|
+
justifyContent: 'center',
|
|
301
|
+
alignItems: 'center',
|
|
302
|
+
height: '100vh',
|
|
303
|
+
width: '100%',
|
|
304
|
+
backgroundColor: '#1a1a1a',
|
|
305
|
+
color: '#ffffff',
|
|
306
|
+
padding: '40px',
|
|
307
|
+
boxSizing: 'border-box'
|
|
308
|
+
}}>
|
|
309
|
+
<h2 style={{ color: '#f44336', marginBottom: '16px' }}>DashAppLoader Configuration Error</h2>
|
|
310
|
+
<p style={{ marginBottom: '16px' }}>The following required props are missing:</p>
|
|
311
|
+
<ul style={{ textAlign: 'left', marginBottom: '24px' }}>
|
|
312
|
+
{missingProps.map(prop => (
|
|
313
|
+
<li key={prop} style={{ color: '#ff9800' }}>{prop}</li>
|
|
314
|
+
))}
|
|
315
|
+
</ul>
|
|
316
|
+
<div style={{
|
|
317
|
+
backgroundColor: '#2d2d2d',
|
|
318
|
+
padding: '16px',
|
|
319
|
+
borderRadius: '8px',
|
|
320
|
+
maxWidth: '600px',
|
|
321
|
+
width: '100%'
|
|
322
|
+
}}>
|
|
323
|
+
<p style={{ marginBottom: '8px', color: '#90caf9' }}>Example usage:</p>
|
|
324
|
+
<pre style={{
|
|
325
|
+
backgroundColor: '#1e1e1e',
|
|
326
|
+
padding: '12px',
|
|
327
|
+
borderRadius: '4px',
|
|
328
|
+
overflow: 'auto',
|
|
329
|
+
fontSize: '12px'
|
|
330
|
+
}}>
|
|
331
|
+
{`import { DashAppLoader } from 'dash-app-common';
|
|
332
|
+
|
|
333
|
+
<DashAppLoader
|
|
334
|
+
publicAppImport={() => import('./DASHPublicApp')}
|
|
335
|
+
privateAppImport={() => import('./DASHLazyAdminApp')}
|
|
336
|
+
/>`}
|
|
337
|
+
</pre>
|
|
338
|
+
</div>
|
|
339
|
+
</div>
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
// ============================================================================
|
|
343
|
+
// DEFAULT APP IMPORTS
|
|
344
|
+
// ============================================================================
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Default public app import function
|
|
348
|
+
* Returns the DashDefaultPublicApp component which provides basic login/auth routes
|
|
349
|
+
*/
|
|
350
|
+
const dashDefaultPublicAppImport = (): Promise<{ default: ComponentType<any> }> =>
|
|
351
|
+
Promise.resolve({ default: DashDefaultPublicApp });
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Default private app import function
|
|
355
|
+
* Returns the DashDefaultPrivateApp component which provides a minimal admin shell
|
|
356
|
+
*/
|
|
357
|
+
const dashDefaultPrivateAppImport = (): Promise<{ default: ComponentType<any> }> =>
|
|
358
|
+
Promise.resolve({ default: DashDefaultPrivateApp });
|
|
359
|
+
|
|
360
|
+
// ============================================================================
|
|
361
|
+
// INTERNAL COMPONENT - DashAppLoaderInner
|
|
362
|
+
// ============================================================================
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Internal component that handles the auth initialization and app loading
|
|
366
|
+
* This is wrapped by DashAppLoader which handles validation
|
|
367
|
+
*/
|
|
368
|
+
interface DashAppLoaderInnerProps {
|
|
369
|
+
publicAppImport: () => Promise<{ default: ComponentType<any> }>;
|
|
370
|
+
privateAppImport: () => Promise<{ default: ComponentType<any> }>;
|
|
371
|
+
authService: IDashAuthService;
|
|
372
|
+
reduxActions: IDashReduxActions;
|
|
373
|
+
updateAuthActionType: string;
|
|
374
|
+
AdminHookComponent?: ComponentType<any>;
|
|
375
|
+
LoadingFallback: ComponentType<{ message?: string }>;
|
|
376
|
+
ErrorFallback: ComponentType<{ error: string; onRetry: () => void }>;
|
|
377
|
+
privateAppProps: Record<string, any>;
|
|
378
|
+
publicAppProps: Record<string, any>;
|
|
379
|
+
debug: boolean;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const DashAppLoaderInner: React.FC<DashAppLoaderInnerProps> = ({
|
|
383
|
+
publicAppImport,
|
|
384
|
+
privateAppImport,
|
|
385
|
+
authService,
|
|
386
|
+
reduxActions,
|
|
387
|
+
updateAuthActionType,
|
|
388
|
+
AdminHookComponent,
|
|
389
|
+
LoadingFallback,
|
|
390
|
+
ErrorFallback,
|
|
391
|
+
privateAppProps,
|
|
392
|
+
publicAppProps,
|
|
393
|
+
debug
|
|
394
|
+
}) => {
|
|
395
|
+
const dispatch = useDispatch();
|
|
396
|
+
const auth = useSelector((state: IDashAppState) => state.auth);
|
|
397
|
+
|
|
398
|
+
// State for initialization
|
|
399
|
+
const [isInitializing, setIsInitializing] = useState(true);
|
|
400
|
+
const [initError, setInitError] = useState<string | null>(null);
|
|
401
|
+
const [hasRestoredFromStorage, setHasRestoredFromStorage] = useState(false);
|
|
402
|
+
|
|
403
|
+
// Use device storage sync hook for Capacitor/Electron environments
|
|
404
|
+
useDeviceStorageSync();
|
|
405
|
+
|
|
406
|
+
// Log current auth state in debug mode
|
|
407
|
+
log(debug, '🔍 DashAppLoader: Redux auth state:', {
|
|
408
|
+
isLogged: auth?.isLogged,
|
|
409
|
+
hasUser: !!auth?.user,
|
|
410
|
+
hasToken: !!auth?.token,
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
// Effect to restore auth from localStorage to Redux if needed
|
|
414
|
+
useEffect(() => {
|
|
415
|
+
if (!hasRestoredFromStorage && !auth?.isLogged) {
|
|
416
|
+
log(debug, '🔍 DashAppLoader: Checking for persisted auth data...');
|
|
417
|
+
|
|
418
|
+
// Check localStorage for persisted auth data
|
|
419
|
+
const storedToken = localStorage.getItem('token');
|
|
420
|
+
const storedUserRaw = localStorage.getItem('user');
|
|
421
|
+
const storedTenantRaw = localStorage.getItem('tenant');
|
|
422
|
+
|
|
423
|
+
log(debug, '🔍 DashAppLoader: Persisted data check:', {
|
|
424
|
+
hasToken: !!storedToken,
|
|
425
|
+
hasUser: !!storedUserRaw,
|
|
426
|
+
hasTenant: !!storedTenantRaw
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
// If we have persisted auth data but Redux is empty, restore it
|
|
430
|
+
if (storedToken && storedUserRaw && !auth?.isLogged) {
|
|
431
|
+
log(debug, '🔄 DashAppLoader: Restoring auth session to Redux from localStorage');
|
|
432
|
+
|
|
433
|
+
let parsedUser: any = null;
|
|
434
|
+
try {
|
|
435
|
+
// User is stored as JSON string in localStorage
|
|
436
|
+
parsedUser = JSON.parse(storedUserRaw);
|
|
437
|
+
|
|
438
|
+
// Handle double-stringified case (JSON inside JSON)
|
|
439
|
+
if (typeof parsedUser === 'string') {
|
|
440
|
+
log(debug, '🔄 DashAppLoader: User was double-stringified, parsing again...');
|
|
441
|
+
parsedUser = JSON.parse(parsedUser);
|
|
442
|
+
}
|
|
443
|
+
} catch (e) {
|
|
444
|
+
console.error('❌ DashAppLoader: Cannot parse user from localStorage, clearing auth data');
|
|
445
|
+
localStorage.removeItem('token');
|
|
446
|
+
localStorage.removeItem('user');
|
|
447
|
+
localStorage.removeItem('tenant');
|
|
448
|
+
localStorage.removeItem('authenticated');
|
|
449
|
+
setHasRestoredFromStorage(true);
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
let parsedTenant: any = null;
|
|
454
|
+
if (storedTenantRaw) {
|
|
455
|
+
try {
|
|
456
|
+
parsedTenant = JSON.parse(storedTenantRaw);
|
|
457
|
+
if (typeof parsedTenant === 'string') {
|
|
458
|
+
parsedTenant = JSON.parse(parsedTenant);
|
|
459
|
+
}
|
|
460
|
+
} catch {
|
|
461
|
+
// Tenant parsing failed, continue without it
|
|
462
|
+
log(debug, '⚠️ DashAppLoader: Could not parse tenant, continuing without it');
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// Dispatch auth restoration action directly to Redux
|
|
467
|
+
dispatch({
|
|
468
|
+
type: updateAuthActionType,
|
|
469
|
+
payload: {
|
|
470
|
+
isLogged: true,
|
|
471
|
+
token: storedToken,
|
|
472
|
+
user: parsedUser,
|
|
473
|
+
tenant: parsedTenant
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
log(debug, '✅ DashAppLoader: Redux state restored from persisted data');
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
setHasRestoredFromStorage(true);
|
|
480
|
+
}
|
|
481
|
+
}, [auth?.isLogged, hasRestoredFromStorage, dispatch, updateAuthActionType, debug]);
|
|
482
|
+
|
|
483
|
+
// Effect to initialize auth service
|
|
484
|
+
useEffect(() => {
|
|
485
|
+
let mounted = true;
|
|
486
|
+
|
|
487
|
+
const initializeAuth = async () => {
|
|
488
|
+
if (!hasRestoredFromStorage) {
|
|
489
|
+
// Wait for storage restoration to complete first
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
try {
|
|
494
|
+
log(debug, '🚀 DashAppLoader: Starting app initialization...');
|
|
495
|
+
|
|
496
|
+
// Call auth service initialization method
|
|
497
|
+
// DASHAuthenticationService uses initializeApp(), fallback to init() for other implementations
|
|
498
|
+
let initResult: { success: boolean; user?: any; error?: string };
|
|
499
|
+
|
|
500
|
+
if (authService.initializeApp) {
|
|
501
|
+
initResult = await authService.initializeApp();
|
|
502
|
+
} else if (authService.init) {
|
|
503
|
+
initResult = await authService.init();
|
|
504
|
+
} else {
|
|
505
|
+
// No init method available, just continue
|
|
506
|
+
log(debug, '⚠️ DashAppLoader: No init method on authService, skipping initialization');
|
|
507
|
+
setIsInitializing(false);
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
if (!mounted) return;
|
|
512
|
+
|
|
513
|
+
log(debug, '🔍 DashAppLoader: Initialization result:', initResult);
|
|
514
|
+
|
|
515
|
+
if (initResult.success && initResult.user) {
|
|
516
|
+
log(debug, '✅ DashAppLoader: Auto-login successful');
|
|
517
|
+
// Auth service should have updated Redux via its own dispatch
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
setIsInitializing(false);
|
|
521
|
+
} catch (error) {
|
|
522
|
+
if (!mounted) return;
|
|
523
|
+
console.error('❌ DashAppLoader initialization error:', error);
|
|
524
|
+
setInitError(error instanceof Error ? error.message : 'Unknown error during initialization');
|
|
525
|
+
setIsInitializing(false);
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
|
|
529
|
+
initializeAuth();
|
|
530
|
+
|
|
531
|
+
return () => {
|
|
532
|
+
mounted = false;
|
|
533
|
+
};
|
|
534
|
+
}, [authService, hasRestoredFromStorage, debug]);
|
|
535
|
+
|
|
536
|
+
// Create lazy loaded components - memoized to prevent recreating on each render
|
|
537
|
+
const PublicApp = useMemo(() => lazy(publicAppImport), [publicAppImport]);
|
|
538
|
+
const PrivateApp = useMemo(() => lazy(privateAppImport), [privateAppImport]);
|
|
539
|
+
|
|
540
|
+
// Retry handler for errors
|
|
541
|
+
const handleRetry = useCallback(() => {
|
|
542
|
+
setInitError(null);
|
|
543
|
+
setIsInitializing(true);
|
|
544
|
+
setHasRestoredFromStorage(false);
|
|
545
|
+
}, []);
|
|
546
|
+
|
|
547
|
+
// Show error state
|
|
548
|
+
if (initError) {
|
|
549
|
+
return <ErrorFallback error={initError} onRetry={handleRetry} />;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// Show loading state during initialization
|
|
553
|
+
if (isInitializing || !hasRestoredFromStorage) {
|
|
554
|
+
return <LoadingFallback message="Initializing application..." />;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// Determine which app to show based on auth state
|
|
558
|
+
const isAuthenticated = auth?.isLogged === true;
|
|
559
|
+
|
|
560
|
+
log(debug, '🎯 DashAppLoader: Rendering app:', {
|
|
561
|
+
isAuthenticated,
|
|
562
|
+
appType: isAuthenticated ? 'Private' : 'Public'
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
// Render the appropriate app
|
|
566
|
+
return (
|
|
567
|
+
<Suspense fallback={<LoadingFallback message={isAuthenticated ? 'Loading admin...' : 'Loading...'} />}>
|
|
568
|
+
{isAuthenticated ? (
|
|
569
|
+
<PrivateApp
|
|
570
|
+
AdminHookComponent={AdminHookComponent}
|
|
571
|
+
{...privateAppProps}
|
|
572
|
+
/>
|
|
573
|
+
) : (
|
|
574
|
+
<PublicApp {...publicAppProps} />
|
|
575
|
+
)}
|
|
576
|
+
</Suspense>
|
|
577
|
+
);
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
// ============================================================================
|
|
581
|
+
// MAIN COMPONENT - DashAppLoader
|
|
582
|
+
// ============================================================================
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* DashAppLoader - Authentication-aware application loader
|
|
586
|
+
*
|
|
587
|
+
* This component provides all the required framework dependencies:
|
|
588
|
+
* - DASHAuthenticationService from dash-admin
|
|
589
|
+
* - DASH_REDUX_ACTIONS from dash-admin-state
|
|
590
|
+
* - ACTION_UPDATE_AUTH from dash-admin-state
|
|
591
|
+
* - AppLoadingFallback from dash-components
|
|
592
|
+
* - DashDefaultPublicApp for unauthenticated users (if no publicAppImport provided)
|
|
593
|
+
* - DashDefaultPrivateApp for authenticated users (if no privateAppImport provided)
|
|
594
|
+
*
|
|
595
|
+
* Key features:
|
|
596
|
+
* - Auth state management and initialization
|
|
597
|
+
* - Redux state restoration from localStorage
|
|
598
|
+
* - Device storage synchronization (Capacitor/Electron)
|
|
599
|
+
* - Lazy loading of public/private apps
|
|
600
|
+
* - Loading and error state handling
|
|
601
|
+
*
|
|
602
|
+
* Can be used with zero configuration for a basic working app:
|
|
603
|
+
* ```tsx
|
|
604
|
+
* <DashAppLoader />
|
|
605
|
+
* ```
|
|
606
|
+
*
|
|
607
|
+
* Or with custom apps:
|
|
608
|
+
* ```tsx
|
|
609
|
+
* <DashAppLoader
|
|
610
|
+
* publicAppImport={() => import('./DASHPublicApp')}
|
|
611
|
+
* privateAppImport={() => import('./DASHLazyAdminApp')}
|
|
612
|
+
* AdminHookComponent={MainAppHookComponent}
|
|
613
|
+
* debug={import.meta.env.DEV}
|
|
614
|
+
* />
|
|
615
|
+
* ```
|
|
616
|
+
*/
|
|
617
|
+
export const DashAppLoader: React.FC<DashAppLoaderProps> = ({
|
|
618
|
+
publicAppImport,
|
|
619
|
+
privateAppImport,
|
|
620
|
+
AdminHookComponent,
|
|
621
|
+
LoadingFallback = AppLoadingFallback,
|
|
622
|
+
ErrorFallback = DefaultErrorFallback,
|
|
623
|
+
privateAppProps = {},
|
|
624
|
+
publicAppProps = {},
|
|
625
|
+
debug = false,
|
|
626
|
+
// Allow overrides but provide defaults
|
|
627
|
+
authService = DASHAuthenticationService,
|
|
628
|
+
reduxActions = DASH_REDUX_ACTIONS,
|
|
629
|
+
updateAuthActionType = ACTION_UPDATE_AUTH,
|
|
630
|
+
}) => {
|
|
631
|
+
// Use default app imports if not provided
|
|
632
|
+
const resolvedPublicAppImport = publicAppImport || dashDefaultPublicAppImport;
|
|
633
|
+
const resolvedPrivateAppImport = privateAppImport || dashDefaultPrivateAppImport;
|
|
634
|
+
|
|
635
|
+
// Validate that we have the framework dependencies
|
|
636
|
+
// These should always be available since we provide defaults
|
|
637
|
+
const missingProps: string[] = [];
|
|
638
|
+
if (!authService) missingProps.push('authService');
|
|
639
|
+
if (!reduxActions) missingProps.push('reduxActions');
|
|
640
|
+
if (!updateAuthActionType) missingProps.push('updateAuthActionType');
|
|
641
|
+
|
|
642
|
+
if (missingProps.length > 0) {
|
|
643
|
+
return <ConfigurationError missingProps={missingProps} />;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
return (
|
|
647
|
+
<DashAppLoaderInner
|
|
648
|
+
publicAppImport={resolvedPublicAppImport}
|
|
649
|
+
privateAppImport={resolvedPrivateAppImport}
|
|
650
|
+
authService={authService}
|
|
651
|
+
reduxActions={reduxActions}
|
|
652
|
+
updateAuthActionType={updateAuthActionType}
|
|
653
|
+
AdminHookComponent={AdminHookComponent}
|
|
654
|
+
LoadingFallback={LoadingFallback}
|
|
655
|
+
ErrorFallback={ErrorFallback}
|
|
656
|
+
privateAppProps={privateAppProps}
|
|
657
|
+
publicAppProps={publicAppProps}
|
|
658
|
+
debug={debug}
|
|
659
|
+
/>
|
|
660
|
+
);
|
|
661
|
+
};
|
|
662
|
+
|
|
663
|
+
// ============================================================================
|
|
664
|
+
// FACTORY FUNCTION
|
|
665
|
+
// ============================================================================
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Create a configured DashAppLoader component with framework defaults
|
|
669
|
+
*
|
|
670
|
+
* This factory function creates a component with all configuration baked in,
|
|
671
|
+
* perfect for use in your app's entry point.
|
|
672
|
+
*
|
|
673
|
+
* @param config - Configuration for the app loader (all optional)
|
|
674
|
+
* @returns A configured React component
|
|
675
|
+
*
|
|
676
|
+
* @example
|
|
677
|
+
* ```tsx
|
|
678
|
+
* import { createDashAppLoader } from 'dash-app-common';
|
|
679
|
+
* import MainAppHook from './components/MainAppHookComponent';
|
|
680
|
+
*
|
|
681
|
+
* // Minimal - uses all defaults
|
|
682
|
+
* const AppLoader = createDashAppLoader({});
|
|
683
|
+
*
|
|
684
|
+
* // With custom apps
|
|
685
|
+
* const AppLoader = createDashAppLoader({
|
|
686
|
+
* publicAppImport: () => import('./DASHPublicApp'),
|
|
687
|
+
* privateAppImport: () => import('./DASHLazyAdminApp'),
|
|
688
|
+
* AdminHookComponent: MainAppHook,
|
|
689
|
+
* debug: import.meta.env.DEV,
|
|
690
|
+
* });
|
|
691
|
+
*
|
|
692
|
+
* // In your component:
|
|
693
|
+
* export const DASHAppLoader = () => <AppLoader />;
|
|
694
|
+
* ```
|
|
695
|
+
*/
|
|
696
|
+
export const createDashAppLoader = (
|
|
697
|
+
config: DashAppLoaderProps = {}
|
|
698
|
+
): React.FC => {
|
|
699
|
+
return () => <DashAppLoader {...config} />;
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
// ============================================================================
|
|
703
|
+
// RE-EXPORTS FOR CONVENIENCE
|
|
704
|
+
// ============================================================================
|
|
705
|
+
|
|
706
|
+
// Re-export framework services for advanced customization
|
|
707
|
+
export { DASHAuthenticationService, DASH_REDUX_ACTIONS, ACTION_UPDATE_AUTH, AppLoadingFallback };
|
|
708
|
+
|
|
709
|
+
// Re-export default apps and routes
|
|
710
|
+
export { DashDefaultPublicApp, DashDefaultPrivateApp };
|
|
711
|
+
export { dashDefaultPublicRoutes } from './defaults/extensions/router/dashDefaultPublicRoutes';
|
|
712
|
+
export { dashDefaultPrivateRoutes } from './defaults/extensions/router/dashDefaultPrivateRoutes';
|
|
713
|
+
|
|
714
|
+
// Re-export default fallback components
|
|
715
|
+
export { DefaultLoadingFallback, DefaultErrorFallback };
|
|
716
|
+
|
|
717
|
+
export default DashAppLoader;
|