@dashadmin/dash-utils 1.3.73 → 1.3.74-srcfree.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/LazyAppLoader.d.ts +17 -0
- package/dist/components/MinimalLayout.d.ts +6 -0
- package/dist/components/RouterComponent.d.ts +22 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/contexts/IPCMessageBrokerContext.d.ts +42 -0
- package/dist/hooks/useCapacitorAppStateRefresh.d.ts +2 -0
- package/dist/hooks/useCapacitorKeyboard.d.ts +19 -0
- package/dist/hooks/useDeviceStorageSync.d.ts +4 -0
- package/dist/hooks/useDraggable.d.ts +24 -0
- package/dist/hooks/useMenuStateInit.d.ts +10 -0
- package/dist/hooks/useMobileDetection.d.ts +20 -0
- package/dist/hooks/useNotifications.d.ts +51 -0
- package/dist/hooks/useQuickSearch.d.ts +6 -0
- package/dist/hooks/useWindowSize.d.ts +6 -0
- package/dist/index.d.ts +30 -0
- package/dist/utils/authProviderUtils.d.ts +37 -0
- package/dist/utils/dashBootstrapApp.d.ts +9 -0
- package/dist/utils/dashDtorage.d.ts +8 -0
- package/dist/utils/dashIPCService.d.ts +93 -0
- package/dist/utils/dataProviderUtils.d.ts +44 -0
- package/dist/utils/electronStoreSync.d.ts +3 -0
- package/dist/utils/envUtils.d.ts +1 -0
- package/dist/utils/environmentBodyClasses.d.ts +11 -0
- package/dist/utils/isDev.d.ts +5 -0
- package/dist/utils/notificationPermission.d.ts +5 -0
- package/dist/utils/platformDetection.d.ts +13 -0
- package/dist/utils/priceFormatter.d.ts +2 -0
- package/dist/utils/resourceLoader.d.ts +8 -0
- package/dist/utils/speechService.d.ts +7 -0
- package/dist/utils/storedTheme.d.ts +11 -0
- package/dist/utils/updateDomCssVariables.d.ts +6 -0
- package/dist/utils/validation.d.ts +12 -0
- package/package.json +13 -10
- package/src/components/LazyAppLoader.tsx +0 -143
- package/src/components/MinimalLayout.tsx +0 -22
- package/src/components/RouterComponent.tsx +0 -169
- package/src/components/index.ts +0 -16
- package/src/contexts/IPCMessageBrokerContext.tsx +0 -303
- package/src/hooks/useCapacitorAppStateRefresh.ts +0 -34
- package/src/hooks/useCapacitorKeyboard.ts +0 -213
- package/src/hooks/useDeviceStorageSync.ts +0 -70
- package/src/hooks/useDraggable.ts +0 -133
- package/src/hooks/useMenuStateInit.ts +0 -85
- package/src/hooks/useMobileDetection.ts +0 -165
- package/src/hooks/useNotifications.ts +0 -220
- package/src/hooks/useQuickSearch.ts +0 -42
- package/src/hooks/useWindowSize.tsx +0 -36
- package/src/index.ts +0 -202
- package/src/utils/authProviderUtils.ts +0 -170
- package/src/utils/dashBootstrapApp.ts +0 -104
- package/src/utils/dashDtorage.tsx +0 -51
- package/src/utils/dashDtorage.tsx.old +0 -78
- package/src/utils/dashIPCService.ts +0 -204
- package/src/utils/dataProviderUtils.ts +0 -221
- package/src/utils/electronStoreSync.ts +0 -34
- package/src/utils/envUtils.tsx +0 -27
- package/src/utils/environmentBodyClasses.ts +0 -72
- package/src/utils/isDev.ts +0 -65
- package/src/utils/notificationPermission.ts +0 -57
- package/src/utils/platformDetection.ts +0 -98
- package/src/utils/priceFormatter.ts +0 -36
- package/src/utils/resourceLoader.ts +0 -107
- package/src/utils/speechService.ts +0 -112
- package/src/utils/storedTheme.ts +0 -60
- package/src/utils/updateDomCssVariables.tsx +0 -181
- package/src/utils/validation.ts +0 -147
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dash Bootstrap Application Utilities
|
|
3
|
-
*
|
|
4
|
-
* Core bootstrap functions for initializing a Dash application.
|
|
5
|
-
* These utilities handle platform detection and environment setup before React renders.
|
|
6
|
-
*
|
|
7
|
-
* NOTE: For tenant styles injection, use injectTenantStyles from 'dash-admin' package.
|
|
8
|
-
*/
|
|
9
|
-
import { syncElectronStore } from './electronStoreSync';
|
|
10
|
-
import { applyPlatformBodyClasses } from './platformDetection';
|
|
11
|
-
import { requestNotificationPermission } from './notificationPermission';
|
|
12
|
-
|
|
13
|
-
export interface DashInitializeAppConfig {
|
|
14
|
-
/**
|
|
15
|
-
* Default theme to use for tenant styles
|
|
16
|
-
* @deprecated Use injectTenantStyles from 'dash-admin' instead
|
|
17
|
-
*/
|
|
18
|
-
defaultTheme?: string;
|
|
19
|
-
|
|
20
|
-
/** Whether to request notification permission (default: true) */
|
|
21
|
-
requestNotifications?: boolean;
|
|
22
|
-
|
|
23
|
-
/** Whether to sync Electron store (default: true) */
|
|
24
|
-
syncElectron?: boolean;
|
|
25
|
-
|
|
26
|
-
/** Whether to apply platform body classes (default: true) */
|
|
27
|
-
applyPlatformClasses?: boolean;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Initialize the Dash application asynchronously
|
|
32
|
-
* Called before React renders to set up the environment
|
|
33
|
-
*
|
|
34
|
-
* @param config - Optional configuration for initialization steps
|
|
35
|
-
*
|
|
36
|
-
* @example
|
|
37
|
-
* ```tsx
|
|
38
|
-
* // With default settings
|
|
39
|
-
* await dashInitializeApp();
|
|
40
|
-
*
|
|
41
|
-
* // With custom configuration
|
|
42
|
-
* await dashInitializeApp({
|
|
43
|
-
* defaultTheme: 'dark',
|
|
44
|
-
* requestNotifications: false
|
|
45
|
-
* });
|
|
46
|
-
* ```
|
|
47
|
-
*/
|
|
48
|
-
export const dashInitializeApp = async (config: DashInitializeAppConfig = {}): Promise<void> => {
|
|
49
|
-
const {
|
|
50
|
-
requestNotifications = true,
|
|
51
|
-
syncElectron = true,
|
|
52
|
-
applyPlatformClasses = true
|
|
53
|
-
} = config;
|
|
54
|
-
|
|
55
|
-
// Sync Electron store to localStorage first
|
|
56
|
-
if (syncElectron) {
|
|
57
|
-
await syncElectronStore();
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Apply platform-specific body classes
|
|
61
|
-
if (applyPlatformClasses) {
|
|
62
|
-
applyPlatformBodyClasses();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// NOTE: Tenant styles injection should be done by caller using injectTenantStyles from 'dash-admin'
|
|
66
|
-
|
|
67
|
-
// Request notification permission
|
|
68
|
-
if (requestNotifications) {
|
|
69
|
-
await requestNotificationPermission();
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Synchronous bootstrap sequence for immediate execution
|
|
75
|
-
* Use this when you don't need to await the electron store sync
|
|
76
|
-
*
|
|
77
|
-
* NOTE: For tenant styles injection, use injectTenantStyles from 'dash-admin' separately.
|
|
78
|
-
*
|
|
79
|
-
* @example
|
|
80
|
-
* ```tsx
|
|
81
|
-
* // In main.tsx before React renders
|
|
82
|
-
* import { injectTenantStyles } from 'dash-admin';
|
|
83
|
-
*
|
|
84
|
-
* dashBootstrapApp();
|
|
85
|
-
* injectTenantStyles('dark'); // Call separately
|
|
86
|
-
*
|
|
87
|
-
* // Then render React
|
|
88
|
-
* root.render(<App />);
|
|
89
|
-
* ```
|
|
90
|
-
*/
|
|
91
|
-
export const dashBootstrapApp = (): void => {
|
|
92
|
-
// Sync Electron store (async but non-blocking)
|
|
93
|
-
syncElectronStore();
|
|
94
|
-
|
|
95
|
-
// Apply platform-specific body classes
|
|
96
|
-
applyPlatformBodyClasses();
|
|
97
|
-
|
|
98
|
-
// NOTE: Tenant styles injection should be done by caller using injectTenantStyles from 'dash-admin'
|
|
99
|
-
|
|
100
|
-
// Request notification permission (non-blocking)
|
|
101
|
-
requestNotificationPermission();
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
export default dashBootstrapApp;
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { getEnv } from "./envUtils";
|
|
2
|
-
|
|
3
|
-
interface PersistanceLayer {
|
|
4
|
-
getItem<T = any>(key: string): T | null;
|
|
5
|
-
setItem<T = any>(key: string, value: T): void;
|
|
6
|
-
removeItem(key: string): void;
|
|
7
|
-
clear(): void;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
class LocalStorageLayer implements PersistanceLayer {
|
|
11
|
-
getItem<T = any>(key: string): T | null {
|
|
12
|
-
const item = window.localStorage.getItem(key);
|
|
13
|
-
if (!item) return null;
|
|
14
|
-
try {
|
|
15
|
-
return JSON.parse(item);
|
|
16
|
-
} catch {
|
|
17
|
-
// Return as string if not valid JSON
|
|
18
|
-
return item as any;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
setItem<T = any>(key: string, value: T): void {
|
|
22
|
-
window.localStorage.setItem(key, JSON.stringify(value));
|
|
23
|
-
}
|
|
24
|
-
removeItem(key: string): void {
|
|
25
|
-
window.localStorage.removeItem(key);
|
|
26
|
-
}
|
|
27
|
-
clear(): void {
|
|
28
|
-
window.localStorage.clear();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export class dashStorage {
|
|
33
|
-
private static localLayer = new LocalStorageLayer();
|
|
34
|
-
|
|
35
|
-
private static get layer(): PersistanceLayer {
|
|
36
|
-
return dashStorage.localLayer;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
static getItem<T = any>(key: string): T | null {
|
|
40
|
-
return this.layer.getItem<T>(key);
|
|
41
|
-
}
|
|
42
|
-
static setItem<T = any>(key: string, value: T): void {
|
|
43
|
-
this.layer.setItem<T>(key, value);
|
|
44
|
-
}
|
|
45
|
-
static removeItem(key: string): void {
|
|
46
|
-
this.layer.removeItem(key);
|
|
47
|
-
}
|
|
48
|
-
static clear(): void {
|
|
49
|
-
this.layer.clear();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { getEnv } from "./envUtils";
|
|
2
|
-
|
|
3
|
-
type StorageType = 'localStorage' | 'electronStore';
|
|
4
|
-
|
|
5
|
-
interface PersistanceLayer {
|
|
6
|
-
getItem<T = any>(key: string): T | null;
|
|
7
|
-
setItem<T = any>(key: string, value: T): void;
|
|
8
|
-
removeItem(key: string): void;
|
|
9
|
-
clear(): void;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
class LocalStorageLayer implements PersistanceLayer {
|
|
13
|
-
/*getItem<T = any>(key: string): T | null {
|
|
14
|
-
const item = window.localStorage.getItem(key);
|
|
15
|
-
return item ? JSON.parse(item) : null;
|
|
16
|
-
}*/
|
|
17
|
-
getItem<T = any>(key: string): T | null {
|
|
18
|
-
const item = window.localStorage.getItem(key);
|
|
19
|
-
if (!item) return null;
|
|
20
|
-
try {
|
|
21
|
-
return JSON.parse(item);
|
|
22
|
-
} catch {
|
|
23
|
-
// Return as string if not valid JSON
|
|
24
|
-
return item as any;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
setItem<T = any>(key: string, value: T): void {
|
|
28
|
-
window.localStorage.setItem(key, JSON.stringify(value));
|
|
29
|
-
}
|
|
30
|
-
removeItem(key: string): void {
|
|
31
|
-
window.localStorage.removeItem(key);
|
|
32
|
-
}
|
|
33
|
-
clear(): void {
|
|
34
|
-
window.localStorage.clear();
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
class ElectronStoreLayer implements PersistanceLayer {
|
|
39
|
-
getItem<T = any>(key: string): T | null {
|
|
40
|
-
return (window as any).electronStore?.get(key) ?? null;
|
|
41
|
-
}
|
|
42
|
-
setItem<T = any>(key: string, value: T): void {
|
|
43
|
-
(window as any).electronStore?.set(key, value);
|
|
44
|
-
}
|
|
45
|
-
removeItem(key: string): void {
|
|
46
|
-
(window as any).electronStore?.delete(key);
|
|
47
|
-
}
|
|
48
|
-
clear(): void {
|
|
49
|
-
(window as any).electronStore?.clear();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export class dashStorage {
|
|
54
|
-
private static get layer(): PersistanceLayer {
|
|
55
|
-
const storageType = (getEnv('APP_STORAGE_TYPE') as StorageType) || 'localStorage';
|
|
56
|
-
if (storageType === 'electronStore' && (window as any).electronStore) {
|
|
57
|
-
return dashStorage.electronLayer;
|
|
58
|
-
} else {
|
|
59
|
-
return dashStorage.localLayer;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
private static localLayer = new LocalStorageLayer();
|
|
64
|
-
private static electronLayer = new ElectronStoreLayer();
|
|
65
|
-
|
|
66
|
-
static getItem<T = any>(key: string): T | null {
|
|
67
|
-
return this.layer.getItem<T>(key);
|
|
68
|
-
}
|
|
69
|
-
static setItem<T = any>(key: string, value: T): void {
|
|
70
|
-
this.layer.setItem<T>(key, value);
|
|
71
|
-
}
|
|
72
|
-
static removeItem(key: string): void {
|
|
73
|
-
this.layer.removeItem(key);
|
|
74
|
-
}
|
|
75
|
-
static clear(): void {
|
|
76
|
-
this.layer.clear();
|
|
77
|
-
}
|
|
78
|
-
}
|
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
// Electron IPC Service Types
|
|
2
|
-
export interface SpeechPayload {
|
|
3
|
-
message: string;
|
|
4
|
-
lang?: string;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface SubprocessOutput {
|
|
8
|
-
type: 'stdout' | 'stderr' | 'exit' | 'error' | 'print-stdout' | 'print-stderr';
|
|
9
|
-
message: string;
|
|
10
|
-
timestamp: string;
|
|
11
|
-
pid?: number;
|
|
12
|
-
exitCode?: number;
|
|
13
|
-
error?: string;
|
|
14
|
-
code?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface ElectronLogData {
|
|
18
|
-
level: 'info' | 'error' | 'warn' | 'debug' | 'verbose';
|
|
19
|
-
message: string;
|
|
20
|
-
timestamp: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* DashIPCService
|
|
25
|
-
*
|
|
26
|
-
* Utility for interacting with Electron IPC (Inter-Process Communication).
|
|
27
|
-
* Provides a safe wrapper around the DashIPCService that may be injected
|
|
28
|
-
* by the Electron preload script.
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Extended Interface for the DashIPCService exposed by Electron
|
|
33
|
-
*/
|
|
34
|
-
export interface DashIPCServiceType {
|
|
35
|
-
runPythonScript: (filePath: string, scriptPath: string, args: string[]) => void;
|
|
36
|
-
action: (action: string, payload: any) => void;
|
|
37
|
-
speak: (payload: string | SpeechPayload) => void;
|
|
38
|
-
playSound: (soundName: string) => void;
|
|
39
|
-
stopSound: () => void;
|
|
40
|
-
notify: (title: string, message: string) => void;
|
|
41
|
-
onPythonOutput: (callback: (data: any) => void) => void;
|
|
42
|
-
onServiceMessage: (callback: (data: any) => void) => void;
|
|
43
|
-
onStdout: (callback: (data: string) => void) => void;
|
|
44
|
-
onElectronLog: (callback: (logData: ElectronLogData) => void) => void;
|
|
45
|
-
onSubprocessOutput: (callback: (data: SubprocessOutput) => void) => void;
|
|
46
|
-
windowControls: (action: 'minimize' | 'maximize' | 'close') => void;
|
|
47
|
-
startDrag: () => void;
|
|
48
|
-
// Print service - calls print_service directly
|
|
49
|
-
print: (urlOrTest: string) => Promise<any>;
|
|
50
|
-
// Legacy/optional methods
|
|
51
|
-
send?: (channel: string, data?: any) => void;
|
|
52
|
-
invoke?: (channel: string, data?: any) => Promise<any>;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Electron Store Type
|
|
57
|
-
*/
|
|
58
|
-
export interface ElectronStoreType {
|
|
59
|
-
get: (key: string) => Promise<any>;
|
|
60
|
-
set: (key: string, value: any) => Promise<void>;
|
|
61
|
-
delete: (key: string) => Promise<void>;
|
|
62
|
-
clear: () => Promise<void>;
|
|
63
|
-
getAll: () => Promise<Record<string, any>>;
|
|
64
|
-
syncToLocalStorage: () => Promise<Record<string, any>>;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Extend Window interface to include DashIPCService and ElectronStore
|
|
69
|
-
*/
|
|
70
|
-
declare global {
|
|
71
|
-
interface Window {
|
|
72
|
-
DashIPCService?: DashIPCServiceType;
|
|
73
|
-
electronStore?: ElectronStoreType;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Check if DashIPCService is available (running in Electron)
|
|
79
|
-
*/
|
|
80
|
-
export const isDashIPCServiceAvailable = (): boolean => {
|
|
81
|
-
return typeof window !== 'undefined' && !!window.DashIPCService;
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Check if running in Electron environment
|
|
86
|
-
*/
|
|
87
|
-
export const isElectron = (): boolean => {
|
|
88
|
-
return isDashIPCServiceAvailable();
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Get the DashIPCService instance
|
|
93
|
-
* Returns undefined if not running in Electron
|
|
94
|
-
*/
|
|
95
|
-
export const getDashIPCService = (): DashIPCServiceType | undefined => {
|
|
96
|
-
if (typeof window !== 'undefined') {
|
|
97
|
-
return window.DashIPCService;
|
|
98
|
-
}
|
|
99
|
-
return undefined;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Safe wrapper for window control actions
|
|
104
|
-
*/
|
|
105
|
-
export const windowControl = (action: 'minimize' | 'maximize' | 'close'): boolean => {
|
|
106
|
-
const ipc = getDashIPCService();
|
|
107
|
-
if (ipc) {
|
|
108
|
-
ipc.windowControls(action);
|
|
109
|
-
return true;
|
|
110
|
-
}
|
|
111
|
-
return false;
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Start window dragging (for custom title bars)
|
|
116
|
-
*/
|
|
117
|
-
export const startWindowDrag = (): boolean => {
|
|
118
|
-
const ipc = getDashIPCService();
|
|
119
|
-
if (ipc) {
|
|
120
|
-
ipc.startDrag();
|
|
121
|
-
return true;
|
|
122
|
-
}
|
|
123
|
-
return false;
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Execute an IPC action
|
|
128
|
-
*/
|
|
129
|
-
export const executeIPCAction = (action: string, payload: any): boolean => {
|
|
130
|
-
const ipc = getDashIPCService();
|
|
131
|
-
if (ipc) {
|
|
132
|
-
ipc.action(action, payload);
|
|
133
|
-
return true;
|
|
134
|
-
}
|
|
135
|
-
return false;
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Register a callback for stdout events
|
|
140
|
-
*/
|
|
141
|
-
export const onIPCStdout = (callback: (data: string) => void): boolean => {
|
|
142
|
-
const ipc = getDashIPCService();
|
|
143
|
-
if (ipc && ipc.onStdout) {
|
|
144
|
-
ipc.onStdout(callback);
|
|
145
|
-
return true;
|
|
146
|
-
}
|
|
147
|
-
return false;
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Register a callback for Electron log events
|
|
152
|
-
*/
|
|
153
|
-
export const onElectronLog = (callback: (logData: ElectronLogData) => void): boolean => {
|
|
154
|
-
const ipc = getDashIPCService();
|
|
155
|
-
if (ipc && ipc.onElectronLog) {
|
|
156
|
-
ipc.onElectronLog(callback);
|
|
157
|
-
return true;
|
|
158
|
-
}
|
|
159
|
-
return false;
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Register a callback for subprocess output events
|
|
164
|
-
*/
|
|
165
|
-
export const onSubprocessOutput = (callback: (data: SubprocessOutput) => void): boolean => {
|
|
166
|
-
const ipc = getDashIPCService();
|
|
167
|
-
if (ipc && ipc.onSubprocessOutput) {
|
|
168
|
-
ipc.onSubprocessOutput(callback);
|
|
169
|
-
return true;
|
|
170
|
-
}
|
|
171
|
-
return false;
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Hook for using DashIPCService in React components
|
|
176
|
-
*/
|
|
177
|
-
export const useDashIPCService = () => {
|
|
178
|
-
const ipcService = getDashIPCService();
|
|
179
|
-
|
|
180
|
-
return {
|
|
181
|
-
isAvailable: isDashIPCServiceAvailable(),
|
|
182
|
-
isElectron: isElectron(),
|
|
183
|
-
service: ipcService,
|
|
184
|
-
windowControl,
|
|
185
|
-
startWindowDrag,
|
|
186
|
-
executeAction: executeIPCAction,
|
|
187
|
-
onStdout: onIPCStdout,
|
|
188
|
-
onElectronLog,
|
|
189
|
-
onSubprocessOutput,
|
|
190
|
-
};
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
export default {
|
|
194
|
-
isDashIPCServiceAvailable,
|
|
195
|
-
isElectron,
|
|
196
|
-
getDashIPCService,
|
|
197
|
-
windowControl,
|
|
198
|
-
startWindowDrag,
|
|
199
|
-
executeIPCAction,
|
|
200
|
-
onIPCStdout,
|
|
201
|
-
onElectronLog,
|
|
202
|
-
onSubprocessOutput,
|
|
203
|
-
useDashIPCService,
|
|
204
|
-
};
|
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Data Provider Utilities
|
|
3
|
-
*
|
|
4
|
-
* Helper functions for data provider operations.
|
|
5
|
-
* These utilities are used by data providers across Dash applications.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Generic resource configuration interface
|
|
10
|
-
* Apps can extend this with their own properties
|
|
11
|
-
*/
|
|
12
|
-
export interface IResourceConfig {
|
|
13
|
-
model?: string;
|
|
14
|
-
isFormData?: boolean;
|
|
15
|
-
dataTransform?: (data: Record<string, any>, operation: string) => Record<string, any>;
|
|
16
|
-
[key: string]: any;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Resource configuration manager
|
|
21
|
-
* Manages resource configurations for data provider operations
|
|
22
|
-
*/
|
|
23
|
-
class ResourceConfigManager<T extends IResourceConfig = IResourceConfig> {
|
|
24
|
-
private configs: T[] = [];
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Set resource configurations
|
|
28
|
-
*/
|
|
29
|
-
setConfigs(configs: T[]): void {
|
|
30
|
-
this.configs = configs;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Get all resource configurations
|
|
35
|
-
*/
|
|
36
|
-
getConfigs(): T[] {
|
|
37
|
-
return this.configs;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Get resource configuration by resource path
|
|
42
|
-
*/
|
|
43
|
-
getConfig(resource: string): T | undefined {
|
|
44
|
-
// Try to find by model path (exact match)
|
|
45
|
-
const config = this.configs.find(r => r.model === resource);
|
|
46
|
-
if (config) return config;
|
|
47
|
-
|
|
48
|
-
// Try to find by matching the resource path (partial match)
|
|
49
|
-
return this.configs.find(r => {
|
|
50
|
-
const modelPath = r.model || '';
|
|
51
|
-
return resource.startsWith(modelPath) || modelPath.startsWith(resource);
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Clear all configurations
|
|
57
|
-
*/
|
|
58
|
-
clear(): void {
|
|
59
|
-
this.configs = [];
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Singleton instance
|
|
64
|
-
let resourceConfigManager: ResourceConfigManager | null = null;
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Get the resource config manager instance
|
|
68
|
-
*/
|
|
69
|
-
export const getResourceConfigManager = <T extends IResourceConfig = IResourceConfig>(): ResourceConfigManager<T> => {
|
|
70
|
-
if (!resourceConfigManager) {
|
|
71
|
-
resourceConfigManager = new ResourceConfigManager<T>();
|
|
72
|
-
}
|
|
73
|
-
return resourceConfigManager as ResourceConfigManager<T>;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Set resource configurations (convenience function)
|
|
78
|
-
*/
|
|
79
|
-
export const setResourceConfigs = <T extends IResourceConfig = IResourceConfig>(configs: T[]): void => {
|
|
80
|
-
getResourceConfigManager<T>().setConfigs(configs);
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Get resource configuration by resource path (convenience function)
|
|
85
|
-
*/
|
|
86
|
-
export const getResourceConfig = <T extends IResourceConfig = IResourceConfig>(resource: string): T | undefined => {
|
|
87
|
-
return getResourceConfigManager<T>().getConfig(resource);
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Process post data before sending to backend
|
|
92
|
-
* Applies resource-specific transformations
|
|
93
|
-
*/
|
|
94
|
-
export const processPostData = <T extends IResourceConfig = IResourceConfig>(
|
|
95
|
-
resource: string,
|
|
96
|
-
data: Record<string, any>,
|
|
97
|
-
operation: 'create' | 'update' | 'getList' | 'import' | string
|
|
98
|
-
): Record<string, any> => {
|
|
99
|
-
const config = getResourceConfig<T>(resource);
|
|
100
|
-
|
|
101
|
-
// Clone data to avoid mutations
|
|
102
|
-
let processedData = { ...data };
|
|
103
|
-
|
|
104
|
-
// Remove undefined values for cleaner payloads
|
|
105
|
-
Object.keys(processedData).forEach(key => {
|
|
106
|
-
if (processedData[key] === undefined) {
|
|
107
|
-
delete processedData[key];
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
// Apply resource-specific transformations if defined
|
|
112
|
-
if (config?.dataTransform) {
|
|
113
|
-
processedData = config.dataTransform(processedData, operation);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return processedData;
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Process data into FormData for file uploads
|
|
121
|
-
*/
|
|
122
|
-
export const processFormData = (
|
|
123
|
-
resource: string,
|
|
124
|
-
data: Record<string, any>
|
|
125
|
-
): FormData => {
|
|
126
|
-
const formData = new FormData();
|
|
127
|
-
|
|
128
|
-
const appendToFormData = (key: string, value: any, prefix = ''): void => {
|
|
129
|
-
const fieldName = prefix ? `${prefix}[${key}]` : key;
|
|
130
|
-
|
|
131
|
-
if (value === null || value === undefined) {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (value instanceof File) {
|
|
136
|
-
formData.append(fieldName, value);
|
|
137
|
-
} else if (typeof FileList !== 'undefined' && value instanceof FileList) {
|
|
138
|
-
Array.from(value).forEach((file, index) => {
|
|
139
|
-
formData.append(`${fieldName}[${index}]`, file);
|
|
140
|
-
});
|
|
141
|
-
} else if (Array.isArray(value)) {
|
|
142
|
-
value.forEach((item, index) => {
|
|
143
|
-
if (typeof item === 'object' && !(item instanceof File)) {
|
|
144
|
-
Object.keys(item).forEach(itemKey => {
|
|
145
|
-
appendToFormData(itemKey, item[itemKey], `${fieldName}[${index}]`);
|
|
146
|
-
});
|
|
147
|
-
} else {
|
|
148
|
-
formData.append(`${fieldName}[${index}]`, item);
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
} else if (typeof value === 'object' && !(value instanceof Date)) {
|
|
152
|
-
if (value.rawFile && value.rawFile instanceof File) {
|
|
153
|
-
formData.append(fieldName, value.rawFile);
|
|
154
|
-
} else {
|
|
155
|
-
Object.keys(value).forEach(objKey => {
|
|
156
|
-
appendToFormData(objKey, value[objKey], fieldName);
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
} else if (typeof value === 'boolean') {
|
|
160
|
-
formData.append(fieldName, value ? '1' : '0');
|
|
161
|
-
} else {
|
|
162
|
-
formData.append(fieldName, String(value));
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
Object.keys(data).forEach(key => {
|
|
167
|
-
appendToFormData(key, data[key]);
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
return formData;
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Build query string from params
|
|
175
|
-
* Supports arrays and nested objects
|
|
176
|
-
*/
|
|
177
|
-
export const buildQueryString = (params: Record<string, any>): string => {
|
|
178
|
-
const searchParams = new URLSearchParams();
|
|
179
|
-
|
|
180
|
-
Object.keys(params).forEach(key => {
|
|
181
|
-
const value = params[key];
|
|
182
|
-
if (value !== undefined && value !== null) {
|
|
183
|
-
if (Array.isArray(value)) {
|
|
184
|
-
value.forEach(item => {
|
|
185
|
-
searchParams.append(`${key}[]`, String(item));
|
|
186
|
-
});
|
|
187
|
-
} else if (typeof value === 'object') {
|
|
188
|
-
searchParams.append(key, JSON.stringify(value));
|
|
189
|
-
} else {
|
|
190
|
-
searchParams.append(key, String(value));
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
return searchParams.toString();
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Check if resource is configured for FormData uploads
|
|
200
|
-
*/
|
|
201
|
-
export const isFormDataResource = <T extends IResourceConfig = IResourceConfig>(
|
|
202
|
-
resource: string,
|
|
203
|
-
params?: { data?: { isFormData?: boolean }; meta?: { isFormData?: boolean } }
|
|
204
|
-
): boolean => {
|
|
205
|
-
const config = getResourceConfig<T>(resource);
|
|
206
|
-
return (
|
|
207
|
-
config?.isFormData === true ||
|
|
208
|
-
params?.data?.isFormData === true ||
|
|
209
|
-
params?.meta?.isFormData === true
|
|
210
|
-
);
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
export default {
|
|
214
|
-
getResourceConfigManager,
|
|
215
|
-
setResourceConfigs,
|
|
216
|
-
getResourceConfig,
|
|
217
|
-
processPostData,
|
|
218
|
-
processFormData,
|
|
219
|
-
buildQueryString,
|
|
220
|
-
isFormDataResource
|
|
221
|
-
};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Electron Store Sync Utility
|
|
3
|
-
*
|
|
4
|
-
* Synchronizes Electron store with localStorage on app startup.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Sync Electron store to localStorage
|
|
9
|
-
* Should be called early in app initialization
|
|
10
|
-
*/
|
|
11
|
-
export const syncElectronStore = async (): Promise<void> => {
|
|
12
|
-
if (typeof window === 'undefined' || !window.electronStore) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
const all = await window.electronStore.syncToLocalStorage();
|
|
18
|
-
Object.entries(all).forEach(([key, value]) => {
|
|
19
|
-
window.localStorage.setItem(key, JSON.stringify(value));
|
|
20
|
-
});
|
|
21
|
-
console.log('Electron store synced to localStorage');
|
|
22
|
-
} catch (error) {
|
|
23
|
-
console.error('Failed to sync Electron store:', error);
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Check if Electron store is available
|
|
29
|
-
*/
|
|
30
|
-
export const hasElectronStore = (): boolean => {
|
|
31
|
-
return typeof window !== 'undefined' && !!window.electronStore;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export default syncElectronStore;
|