@admin-layout/gluestack-ui-mobile 9.0.2-alpha.4 → 9.0.4-alpha.102
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/CHANGELOG.md +112 -0
- package/lib/components/AuthWrapper.d.ts +4 -1
- package/lib/components/AuthWrapper.js +6 -5
- package/lib/components/AuthWrapper.js.map +1 -1
- package/lib/components/Layout/components/Drawer.js +9 -9
- package/lib/components/Layout/components/Drawer.js.map +1 -1
- package/lib/components/Layout/components/Header.js +28 -15
- package/lib/components/Layout/components/Header.js.map +1 -1
- package/lib/components/Layout/components/SettingDrawer/LayoutButton.js +14 -6
- package/lib/components/Layout/components/SettingDrawer/LayoutButton.js.map +1 -1
- package/lib/components/Layout/components/SettingDrawer/SettingDrawer.d.ts +1 -1
- package/lib/components/Layout/components/SettingDrawer/SettingDrawer.js +55 -15
- package/lib/components/Layout/components/SettingDrawer/SettingDrawer.js.map +1 -1
- package/lib/components/Layout/components/SettingDrawer/ThemeColorButton.js +1 -1
- package/lib/components/NavigationComponent.js +11 -2
- package/lib/components/NavigationComponent.js.map +1 -1
- package/lib/components/WithConfiguration.d.ts +18 -0
- package/lib/components/WithConfiguration.js +42 -0
- package/lib/components/WithConfiguration.js.map +1 -0
- package/lib/components/WithPermission.d.ts +31 -0
- package/lib/components/WithPermission.js +53 -0
- package/lib/components/WithPermission.js.map +1 -0
- package/lib/components/WithPolicy.d.ts +13 -0
- package/lib/components/WithPolicy.js +18 -0
- package/lib/components/WithPolicy.js.map +1 -0
- package/lib/components/index.d.ts +5 -0
- package/lib/components/index.js +5 -0
- package/lib/components/index.js.map +1 -1
- package/lib/components/usePermissionAutoFetch.d.ts +75 -0
- package/lib/components/usePermissionAutoFetch.js +63 -0
- package/lib/components/usePermissionAutoFetch.js.map +1 -0
- package/lib/components/useSetting.d.ts +25 -0
- package/lib/components/useSetting.js +87 -0
- package/lib/components/useSetting.js.map +1 -0
- package/lib/components/with-interactions-lifecycle-managed.d.ts +3 -3
- package/lib/components/with-interactions-lifecycle-managed.js +23 -15
- package/lib/components/with-interactions-lifecycle-managed.js.map +1 -1
- package/lib/containers/layout/BasicLayout.d.ts +3 -3
- package/lib/containers/layout/DrawerBottomNavigationConfig.d.ts +393 -88
- package/lib/containers/layout/DrawerConfig.d.ts +266 -60
- package/lib/containers/layout/module.js +2 -2
- package/lib/containers/layout/module.js.map +1 -1
- package/lib/redux/settings.d.ts +8 -8
- package/lib/utils/ThemeColor.js +11 -1
- package/lib/utils/ThemeColor.js.map +1 -1
- package/lib/utils/generateMobileNavigations.d.ts +4 -10
- package/lib/utils/generateMobileNavigations.js +720 -310
- package/lib/utils/generateMobileNavigations.js.map +1 -1
- package/package.json +7 -7
- package/src/components/AuthWrapper.tsx +30 -17
- package/src/components/Layout/components/Drawer.tsx +19 -20
- package/src/components/Layout/components/Header.tsx +154 -93
- package/src/components/Layout/components/SettingDrawer/LayoutButton.tsx +27 -13
- package/src/components/Layout/components/SettingDrawer/SettingDrawer.tsx +151 -48
- package/src/components/Layout/components/SettingDrawer/ThemeColorButton.tsx +2 -2
- package/src/components/NavigationComponent.tsx +9 -2
- package/src/components/WithConfiguration.tsx +74 -0
- package/src/components/WithPermission.tsx +81 -0
- package/src/components/WithPolicy.tsx +32 -0
- package/src/components/index.ts +6 -1
- package/src/components/usePermissionAutoFetch.tsx +78 -0
- package/src/components/useSetting.tsx +137 -0
- package/src/components/with-interactions-lifecycle-managed.tsx +62 -26
- package/src/containers/layout/module.ts +2 -2
- package/src/utils/ThemeColor.ts +11 -1
- package/src/utils/generateMobileNavigations.ts +780 -290
- package/lib/components/Layout/components/util.d.ts +0 -1
- package/lib/components/Layout/components/util.js +0 -15
- package/lib/components/Layout/components/util.js.map +0 -1
- package/src/components/Layout/components/util.ts +0 -14
|
@@ -5,28 +5,25 @@ import { fileURLToPath } from 'url';
|
|
|
5
5
|
import { createRequire } from 'module';
|
|
6
6
|
import { exec as execCallback } from 'child_process';
|
|
7
7
|
import { getSortedNavigations } from '@common-stack/client-react/lib/route/react-navigation/get-navigation-utils.js';
|
|
8
|
+
import { performCopyOperations } from '@common-stack/rollup-vite-utils/lib/preStartup/configLoader/configLoader.js';
|
|
8
9
|
import { getReplacedRouteConfig } from './getReplacedRouteConfig.js';
|
|
9
10
|
const require = createRequire(import.meta.url);
|
|
10
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
12
|
const __dirname = path.dirname(__filename);
|
|
12
13
|
const configFilePath = path.join(__dirname, '../layout.json');
|
|
13
|
-
const appNavigationFileName = 'navigation.
|
|
14
|
+
const appNavigationFileName = 'navigation.js';
|
|
14
15
|
const mainRoutesFileName = 'main_routes.json';
|
|
15
16
|
const modulesFileName = 'modules.ts';
|
|
16
|
-
const stacksDirPath = 'stack/index.
|
|
17
|
-
const drawerFilePath = 'drawer/index.
|
|
18
|
-
const hostDrawerFilePath = 'host_drawer/index.
|
|
19
|
-
const bottomFilePath = 'bottom/index.
|
|
20
|
-
const hostBottomFilePath = 'host_bottom/index.
|
|
17
|
+
const stacksDirPath = 'stack/index.js';
|
|
18
|
+
const drawerFilePath = 'drawer/index.js';
|
|
19
|
+
const hostDrawerFilePath = 'host_drawer/index.js';
|
|
20
|
+
const bottomFilePath = 'bottom/index.js';
|
|
21
|
+
const hostBottomFilePath = 'host_bottom/index.js';
|
|
22
|
+
const mainRoutesJsFileName = 'mainRoutes.js';
|
|
23
|
+
const mainAppFileName = 'index.js';
|
|
21
24
|
|
|
22
25
|
type IGenerateMobileNavigationsProps = {
|
|
23
|
-
|
|
24
|
-
modules: any;
|
|
25
|
-
initialRouteName?: string;
|
|
26
|
-
unauthenticatedComponentPath?: string;
|
|
27
|
-
customTabBarPath?: string;
|
|
28
|
-
customDrawerPath?: string;
|
|
29
|
-
customHeaderPath?: string;
|
|
26
|
+
configFilePath: any;
|
|
30
27
|
};
|
|
31
28
|
|
|
32
29
|
export const readJsonFile = (filePath) => {
|
|
@@ -66,32 +63,46 @@ export const getLayoutConfig = async () => {
|
|
|
66
63
|
};
|
|
67
64
|
|
|
68
65
|
export class GenerateMobileNavigations {
|
|
69
|
-
#
|
|
70
|
-
#
|
|
66
|
+
#configFileData: any = {};
|
|
67
|
+
#configFilePath: any;
|
|
68
|
+
#appPath: string = 'app';
|
|
69
|
+
#isDefaultPackagePathMobileRoot: boolean;
|
|
70
|
+
#mobileStackPath: string = 'mobile-stack-react';
|
|
71
|
+
//#layoutSettings: any = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
|
|
72
|
+
#appDirPath: any;
|
|
71
73
|
#modules: any;
|
|
74
|
+
#initialRouteNameRootStack: string;
|
|
72
75
|
#initialRouteName: string;
|
|
73
76
|
#unauthenticatedComponentPath: string;
|
|
74
77
|
#customTabBarPath: string;
|
|
75
78
|
#customDrawerPath: string;
|
|
76
79
|
#customHeaderPath: string;
|
|
80
|
+
#i18Options: any;
|
|
81
|
+
#iconsRepository: string;
|
|
82
|
+
|
|
83
|
+
constructor({ configFilePath }: IGenerateMobileNavigationsProps) {
|
|
84
|
+
this.#configFilePath = configFilePath;
|
|
85
|
+
const config = this.#readConfigFile(configFilePath);
|
|
86
|
+
this.#configFileData = config;
|
|
87
|
+
// this.#layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
|
|
88
|
+
this.#appPath = config?.commonPaths?.appPath ?? 'app';
|
|
89
|
+
this.#isDefaultPackagePathMobileRoot = config?.mobileConfig?.isDefaultPackagePathMobileRoot ?? false;
|
|
90
|
+
this.#iconsRepository = config?.iconsRepository ?? '';
|
|
91
|
+
this.#mobileStackPath = config?.mobileStackPath ?? 'mobile-stack-react';
|
|
92
|
+
this.#appDirPath = path.join(path.dirname(configFilePath), this.#appPath);
|
|
93
|
+
this.#modules = config?.modules ?? [];
|
|
94
|
+
this.#initialRouteName = config?.mobileConfig?.initialRouteName ?? '';
|
|
95
|
+
this.#initialRouteNameRootStack = config?.mobileConfig?.initialRouteNameRootStack ?? 'MainStack';
|
|
96
|
+
this.#unauthenticatedComponentPath = config?.mobileConfig?.unauthenticatedComponentPath ?? '';
|
|
97
|
+
this.#customTabBarPath = config?.mobileConfig?.customTabBarPath ?? '';
|
|
98
|
+
this.#customDrawerPath = config?.mobileConfig?.customDrawerPath ?? '';
|
|
99
|
+
this.#customHeaderPath = config?.mobileConfig?.customHeaderPath ?? '';
|
|
100
|
+
this.#i18Options = config?.i18n ?? {};
|
|
101
|
+
}
|
|
77
102
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
initialRouteName = '',
|
|
82
|
-
unauthenticatedComponentPath = null,
|
|
83
|
-
customTabBarPath = null,
|
|
84
|
-
customDrawerPath = null,
|
|
85
|
-
customHeaderPath = null,
|
|
86
|
-
}: IGenerateMobileNavigationsProps) {
|
|
87
|
-
this.#layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
|
|
88
|
-
this.#appDirPath = appDirPath;
|
|
89
|
-
this.#modules = modules;
|
|
90
|
-
this.#initialRouteName = initialRouteName;
|
|
91
|
-
this.#unauthenticatedComponentPath = unauthenticatedComponentPath;
|
|
92
|
-
this.#customTabBarPath = customTabBarPath;
|
|
93
|
-
this.#customDrawerPath = customDrawerPath;
|
|
94
|
-
this.#customHeaderPath = customHeaderPath;
|
|
103
|
+
#readConfigFile(configFilePath: any) {
|
|
104
|
+
const jsonData = fs.readFileSync(configFilePath, 'utf-8');
|
|
105
|
+
return JSON.parse(jsonData);
|
|
95
106
|
}
|
|
96
107
|
|
|
97
108
|
async #readJsonFile(filePath) {
|
|
@@ -148,10 +159,20 @@ export class GenerateMobileNavigations {
|
|
|
148
159
|
|
|
149
160
|
async #getModulesRouteConfig({ modules }) {
|
|
150
161
|
const allFilteredRoutes = [];
|
|
162
|
+
let pkgFile;
|
|
151
163
|
for (const pkg of modules) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
164
|
+
if (this.#isDefaultPackagePathMobileRoot) {
|
|
165
|
+
const pkgRootFilePath = path.join(
|
|
166
|
+
path.join(path.dirname(this.#configFilePath), 'node_modules/lib'),
|
|
167
|
+
pkg,
|
|
168
|
+
);
|
|
169
|
+
pkgFile = path.join(pkgRootFilePath, 'routes.json');
|
|
170
|
+
} else {
|
|
171
|
+
const pkgPath = require.resolve(pkg);
|
|
172
|
+
const pkgDirPath = path.dirname(pkgPath);
|
|
173
|
+
pkgFile = path.join(pkgDirPath, 'routes.json');
|
|
174
|
+
}
|
|
175
|
+
|
|
155
176
|
if (fs.existsSync(pkgFile)) {
|
|
156
177
|
const fileModuleJSON: any = await readJsonFile(pkgFile);
|
|
157
178
|
if (fileModuleJSON) {
|
|
@@ -187,14 +208,16 @@ export class GenerateMobileNavigations {
|
|
|
187
208
|
return value;
|
|
188
209
|
}
|
|
189
210
|
|
|
190
|
-
async #generateAppRoutesJson(
|
|
191
|
-
const
|
|
211
|
+
async #generateAppRoutesJson() {
|
|
212
|
+
const appDirPath = this.#appDirPath;
|
|
213
|
+
const parentDirPath = path.dirname(this.#configFileData?.mobileConfig?.computeFilePath ?? this.#configFilePath);
|
|
192
214
|
const parentDirName = path.basename(parentDirPath);
|
|
193
215
|
const appDirName = path.basename(appDirPath);
|
|
194
216
|
// const tsFile = 'src/compute.ts';
|
|
195
217
|
// const outputDir = 'src/app';
|
|
196
218
|
const tsFile = `${parentDirName}/compute.ts`;
|
|
197
|
-
const outputDir = `${parentDirName}/${appDirName}`;
|
|
219
|
+
// const outputDir = `${parentDirName}/${appDirName}`;
|
|
220
|
+
const outputDir = `${appDirName}`;
|
|
198
221
|
const tscCommand = `tsc ${tsFile} --outDir ${outputDir} --target es6 --module esnext --jsx react --allowSyntheticDefaultImports true --moduleResolution node --esModuleInterop true --forceConsistentCasingInFileNames true --skipLibCheck true`;
|
|
199
222
|
const mainRoutesJsFile = path.join(appDirPath, '/compute.js');
|
|
200
223
|
const mainRoutesMjsFile = path.join(appDirPath, '/compute.mjs');
|
|
@@ -210,13 +233,12 @@ export class GenerateMobileNavigations {
|
|
|
210
233
|
const noWhitespaceJsData = noCommentsData.replace(/\s+/g, '');
|
|
211
234
|
if (noWhitespaceJsData?.length == 0) {
|
|
212
235
|
const outPutDirName = path.dirname(outputFile);
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
} else return false;
|
|
236
|
+
try {
|
|
237
|
+
await this.#makeDir(outPutDirName);
|
|
238
|
+
await this.#writeFile(outputFile, JSON.stringify(allFilteredRoutes));
|
|
239
|
+
} catch (error) {
|
|
240
|
+
console.log('Error directory/file create', error);
|
|
241
|
+
}
|
|
220
242
|
} else {
|
|
221
243
|
const newFilePath = mainRoutesJsFile.replace('.js', '.mjs');
|
|
222
244
|
const renameFileResponse = await this.#renameFile(mainRoutesJsFile, newFilePath);
|
|
@@ -236,46 +258,45 @@ export class GenerateMobileNavigations {
|
|
|
236
258
|
return { [routConfig.path]: routConfig };
|
|
237
259
|
}) ?? [];
|
|
238
260
|
allFilteredRoutes.push(...newRoutes);
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
fs.unlinkSync(mainRoutesMjsFile);
|
|
246
|
-
|
|
247
|
-
|
|
261
|
+
try {
|
|
262
|
+
const writeFileResponse = await this.#writeFile(
|
|
263
|
+
outputFile,
|
|
264
|
+
JSON.stringify(allFilteredRoutes, null, 2),
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
if (writeFileResponse) fs.unlinkSync(mainRoutesMjsFile);
|
|
268
|
+
} catch (error) {
|
|
269
|
+
console.log('Error creating main routes file', error);
|
|
270
|
+
}
|
|
248
271
|
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
251
274
|
}
|
|
252
275
|
} else {
|
|
253
276
|
const outPutDirName = path.dirname(outputFile);
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
} else return false;
|
|
277
|
+
try {
|
|
278
|
+
await this.#makeDir(outPutDirName);
|
|
279
|
+
await this.#writeFile(outputFile, JSON.stringify(allFilteredRoutes));
|
|
280
|
+
} catch (error) {
|
|
281
|
+
console.log('Error creating main routes file', error);
|
|
282
|
+
}
|
|
261
283
|
}
|
|
262
284
|
// return true;
|
|
263
285
|
} catch (error) {
|
|
264
286
|
console.error(`exec error: ${error.message}`);
|
|
265
287
|
const outPutDirName = path.dirname(outputFile);
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
} else return false;
|
|
288
|
+
try {
|
|
289
|
+
await this.#makeDir(outPutDirName);
|
|
290
|
+
await this.#writeFile(outputFile, JSON.stringify(allFilteredRoutes));
|
|
291
|
+
} catch (error) {
|
|
292
|
+
console.log('Error creating main routes file', error);
|
|
293
|
+
}
|
|
273
294
|
}
|
|
274
295
|
}
|
|
275
296
|
|
|
276
297
|
async #generateImportStatements({ modules, initialRouteName }) {
|
|
277
298
|
try {
|
|
278
|
-
const layoutSettings =
|
|
299
|
+
const layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
|
|
279
300
|
const layoutConfigFileData = await this.#getLayoutConfig();
|
|
280
301
|
const hostRouteConfig = layoutConfigFileData['host-bottom'];
|
|
281
302
|
const hostRouteKey = Object.keys(hostRouteConfig)[1];
|
|
@@ -393,10 +414,228 @@ export class GenerateMobileNavigations {
|
|
|
393
414
|
return false;
|
|
394
415
|
}
|
|
395
416
|
|
|
417
|
+
async #generateMainRoutesFile({ initialRouteName, i18Options }) {
|
|
418
|
+
try {
|
|
419
|
+
const layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
|
|
420
|
+
const layoutConfigFileData = await this.#getLayoutConfig();
|
|
421
|
+
const hostRouteConfig = layoutConfigFileData['host-bottom'];
|
|
422
|
+
const hostRouteKey = Object.keys(hostRouteConfig)[1];
|
|
423
|
+
const hostLayout = hostRouteConfig[hostRouteKey];
|
|
424
|
+
|
|
425
|
+
let importStatements = '';
|
|
426
|
+
importStatements += `import React from 'react';\n`;
|
|
427
|
+
importStatements += `import { InversifyProvider, PluginArea } from '@common-stack/client-react';\n`;
|
|
428
|
+
importStatements += `import { useSelector, useDispatch } from 'react-redux';\n`;
|
|
429
|
+
importStatements += `import { CHANGE_SETTINGS_ACTION } from '@admin-layout/client';\n`;
|
|
430
|
+
importStatements += `import {layoutRouteConfig,getReplacedRouteConfig,ErrorBoundary,NavigationContainerComponent,ApplicationErrorHandler,Box,Spinner,} from '@admin-layout/gluestack-ui-mobile';\n`;
|
|
431
|
+
importStatements += `import mainRouteConfig from './main_routes.json';\n`;
|
|
432
|
+
importStatements += `import features from './mobile-stack-react/modules.js';\n`;
|
|
433
|
+
importStatements += `import AppNavigations from './navigation';\n`;
|
|
434
|
+
importStatements += `import {loadContext} from './mobile-stack-react/load-context.mobile.js';\n`;
|
|
435
|
+
|
|
436
|
+
let classStructure = `
|
|
437
|
+
|
|
438
|
+
const mainAppRoutes = mainRouteConfig || [];
|
|
439
|
+
|
|
440
|
+
const appRoutes = [...[mainAppRoutes],features?.routeConfig];
|
|
441
|
+
|
|
442
|
+
const featureRouteConfig = appRoutes?.flat(1)??features?.routeConfig;
|
|
443
|
+
features.routeConfig = featureRouteConfig;
|
|
444
|
+
let appConfiguredRoutes = features?.getConfiguredRoutes2("/");
|
|
445
|
+
|
|
446
|
+
const DefaultProvider = ({children}) => <>{children}</>
|
|
447
|
+
|
|
448
|
+
export function MainRoute({ container,externalProvider: ExternalProvider = DefaultProvider,externalProviderProps={},linking = {} }){
|
|
449
|
+
const dispatch = useDispatch();
|
|
450
|
+
const defaultSettings = useSelector((state) => state.settings);
|
|
451
|
+
const initialRouteName = '${initialRouteName}';
|
|
452
|
+
const layoutSettings = ${JSON.stringify({ ...layoutSettings, hostLayout: hostLayout.key })}
|
|
453
|
+
const [mainFeatures, setMainFeatures] = React.useState(null);
|
|
454
|
+
|
|
455
|
+
React.useEffect(() => {
|
|
456
|
+
setDefalutSettings();
|
|
457
|
+
}, []);
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
const setDefalutSettings = React.useCallback(()=>{
|
|
461
|
+
const config = {
|
|
462
|
+
...defaultSettings,
|
|
463
|
+
...layoutSettings,
|
|
464
|
+
};
|
|
465
|
+
dispatch({
|
|
466
|
+
type: CHANGE_SETTINGS_ACTION,
|
|
467
|
+
payload: config,
|
|
468
|
+
});
|
|
469
|
+
},[]);
|
|
470
|
+
|
|
471
|
+
React.useEffect(() => {
|
|
472
|
+
if (defaultSettings) {
|
|
473
|
+
const settingObj = { ...defaultSettings };
|
|
474
|
+
const layoutType = settingObj.layout;
|
|
475
|
+
const {replacedConfiguredRouteConfig} = getReplacedRouteConfig({
|
|
476
|
+
layoutType: layoutType,
|
|
477
|
+
routeConfig: appRoutes,
|
|
478
|
+
layoutConfigData: layoutRouteConfig,
|
|
479
|
+
initialRouteName,
|
|
480
|
+
});
|
|
481
|
+
if(replacedConfiguredRouteConfig){
|
|
482
|
+
const moduleRouteConfigObject = Object.assign({}, ...replacedConfiguredRouteConfig?.flat(1)??[]);
|
|
483
|
+
const replacedRouteConfig = Object.fromEntries(Object.entries(moduleRouteConfigObject));
|
|
484
|
+
const appReplacedRouteConfig = replacedRouteConfig ? Object.keys(replacedRouteConfig)?.map((k)=>({[k]:replacedRouteConfig[k]})) : [];
|
|
485
|
+
|
|
486
|
+
if (appReplacedRouteConfig) {
|
|
487
|
+
const hostRouteConfig = appReplacedRouteConfig.filter(item => {
|
|
488
|
+
return Object.keys(item).some(key =>
|
|
489
|
+
key === "/" ||
|
|
490
|
+
(key.startsWith("//" + layoutSettings.hostLayout) || key.startsWith("//:orgName/" + layoutSettings.hostLayout))
|
|
491
|
+
);
|
|
492
|
+
})?.filter((value) => Object.keys(value).length !== 0) ?? [];
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
const layoutRouteConfig = appReplacedRouteConfig.filter(item => {
|
|
496
|
+
return Object.keys(item).some(key =>
|
|
497
|
+
key === "/" ||
|
|
498
|
+
(!key.startsWith("//" + layoutSettings.hostLayout) && !key.startsWith("//:orgName/" + layoutSettings.hostLayout))
|
|
499
|
+
);
|
|
500
|
+
})?.filter((value) => Object.keys(value).length !== 0) ?? [];
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
// const hostRouteConfig = appReplacedRouteConfig?.map((obj)=> Object.fromEntries(Object.entries(obj)?.filter(([key,val])=>key === '/' || key.startsWith('//'+layoutSettings.hostLayout))))?.filter(value => Object.keys(value).length !== 0)??[];
|
|
504
|
+
// const layoutRouteConfig = appReplacedRouteConfig?.map((obj)=> Object.fromEntries(Object.entries(obj)?.filter(([key,val])=>key === '/' || !key.startsWith('//'+layoutSettings.hostLayout))))?.filter(value => Object.keys(value).length !== 0)??[];
|
|
505
|
+
const featureRouteConfig = defaultSettings?.layout == 'host-bottom' ? hostRouteConfig:layoutRouteConfig;
|
|
506
|
+
features.routeConfig = featureRouteConfig;
|
|
507
|
+
setMainFeatures(features);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}, [defaultSettings]);
|
|
512
|
+
|
|
513
|
+
const loadingComponent = () => <Box flex={1}>{<Spinner />}</Box>;
|
|
514
|
+
|
|
515
|
+
if (!mainFeatures || mainFeatures?.routeConfig?.length == 0) return loadingComponent();
|
|
516
|
+
|
|
517
|
+
const plugins = mainFeatures?.getComponentFillPlugins();
|
|
518
|
+
const configuredRoutes = mainFeatures?.getConfiguredRoutes2('/');
|
|
519
|
+
appConfiguredRoutes = configuredRoutes;
|
|
520
|
+
|
|
521
|
+
return (
|
|
522
|
+
<InversifyProvider container={container} modules={mainFeatures}>
|
|
523
|
+
{mainFeatures?.getWrappedRoot(
|
|
524
|
+
<ErrorBoundary>
|
|
525
|
+
<NavigationContainerComponent configurableRoutes={configuredRoutes} independent={true} linking={linking}>
|
|
526
|
+
<ExternalProvider {...externalProviderProps}>
|
|
527
|
+
<AppNavigations />
|
|
528
|
+
</ExternalProvider>
|
|
529
|
+
<PluginArea />
|
|
530
|
+
<ApplicationErrorHandler plugins={plugins} />
|
|
531
|
+
</NavigationContainerComponent>
|
|
532
|
+
</ErrorBoundary>,
|
|
533
|
+
)}
|
|
534
|
+
</InversifyProvider>
|
|
535
|
+
);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
export { loadContext,appConfiguredRoutes };
|
|
539
|
+
|
|
540
|
+
export default features;
|
|
541
|
+
`.replace(/,(\s*)$/, ''); // Removes trailing comma
|
|
542
|
+
|
|
543
|
+
// Use Prettier to format the code
|
|
544
|
+
classStructure = prettier.format(classStructure, { parser: 'babel' });
|
|
545
|
+
|
|
546
|
+
const appFeatures = importStatements + '\n' + classStructure;
|
|
547
|
+
|
|
548
|
+
return { appFeatures };
|
|
549
|
+
} catch (err) {
|
|
550
|
+
console.error('Error:', err);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
async #generateMainRoutes({ appDirPath, i18Options, initialRouteName }) {
|
|
555
|
+
const mainRoutesFile = path.join(appDirPath, `/${mainRoutesJsFileName}`);
|
|
556
|
+
const imports: any = await this.#generateMainRoutesFile({ initialRouteName, i18Options });
|
|
557
|
+
const { appFeatures } = imports;
|
|
558
|
+
try {
|
|
559
|
+
await this.#writeFile(mainRoutesFile, appFeatures);
|
|
560
|
+
} catch (err) {
|
|
561
|
+
console.error('Error generating main routes:', err);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
async #generateAppFile({ initialRouteName, i18Options }) {
|
|
566
|
+
try {
|
|
567
|
+
let importStatements = '';
|
|
568
|
+
importStatements += `import 'reflect-metadata';\n`;
|
|
569
|
+
importStatements += `import React from 'react';\n`;
|
|
570
|
+
importStatements += `import { SlotFillProvider } from '@common-stack/components-pro';\n`;
|
|
571
|
+
importStatements += `import { ApolloProvider } from '@apollo/client';\n`;
|
|
572
|
+
importStatements += `import { Provider } from 'react-redux';\n`;
|
|
573
|
+
importStatements += `import { PersistGate } from 'redux-persist/integration/react';\n`;
|
|
574
|
+
importStatements += `import { SafeAreaProvider } from 'react-native-safe-area-context';\n`;
|
|
575
|
+
importStatements += `import {GluestackUIProvider,config,i18next,reactI18Next} from '@admin-layout/gluestack-ui-mobile';\n`;
|
|
576
|
+
importStatements += `import { enableScreens } from 'react-native-screens';\n`;
|
|
577
|
+
importStatements += `import {MainRoute,loadContext,appConfiguredRoutes} from './mainRoutes.js'\n`;
|
|
578
|
+
|
|
579
|
+
let classStructure = `
|
|
580
|
+
enableScreens(true);
|
|
581
|
+
const { I18nextProvider } = reactI18Next;
|
|
582
|
+
i18next.options ={...i18next?.options??{},...${JSON.stringify(i18Options)}};
|
|
583
|
+
|
|
584
|
+
const DefaultProvider = ({children}) => <>{children}</>
|
|
585
|
+
|
|
586
|
+
function App({externalProvider = DefaultProvider,externalProviderProps={},linking = {}}){
|
|
587
|
+
const {store,persistor,container,apolloClient: client} = loadContext();
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
return (
|
|
591
|
+
<SlotFillProvider>
|
|
592
|
+
<ApolloProvider client={client}>
|
|
593
|
+
<Provider store={store}>
|
|
594
|
+
<PersistGate persistor={persistor}>
|
|
595
|
+
<I18nextProvider i18n={i18next}>
|
|
596
|
+
<SafeAreaProvider>
|
|
597
|
+
<GluestackUIProvider config={config}>
|
|
598
|
+
<MainRoute container={container} externalProvider={externalProvider} linking={linking} externalProviderProps={externalProviderProps} />
|
|
599
|
+
</GluestackUIProvider>
|
|
600
|
+
</SafeAreaProvider>
|
|
601
|
+
</I18nextProvider>
|
|
602
|
+
</PersistGate>
|
|
603
|
+
</Provider>
|
|
604
|
+
</ApolloProvider>
|
|
605
|
+
</SlotFillProvider>
|
|
606
|
+
);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
export const configuredRoutes = appConfiguredRoutes;
|
|
610
|
+
export default App;
|
|
611
|
+
`.replace(/,(\s*)$/, ''); // Removes trailing comma
|
|
612
|
+
|
|
613
|
+
// Use Prettier to format the code
|
|
614
|
+
classStructure = prettier.format(classStructure, { parser: 'babel' });
|
|
615
|
+
|
|
616
|
+
const appFeatures = importStatements + '\n' + classStructure;
|
|
617
|
+
|
|
618
|
+
return { appFeatures };
|
|
619
|
+
} catch (err) {
|
|
620
|
+
console.error('Error:', err);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
async #generateApp({ appDirPath, i18Options, initialRouteName }) {
|
|
625
|
+
const mainRoutesFile = path.join(appDirPath, `/${mainAppFileName}`);
|
|
626
|
+
const imports: any = await this.#generateAppFile({ initialRouteName, i18Options });
|
|
627
|
+
const { appFeatures } = imports;
|
|
628
|
+
try {
|
|
629
|
+
await this.#writeFile(mainRoutesFile, appFeatures);
|
|
630
|
+
} catch (err) {
|
|
631
|
+
console.error('Error generating app:', err);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
396
635
|
async #generateStackNavigations({ appDirPath, modules, initialRouteName, unauthenticatedComponentPath }) {
|
|
397
636
|
const mainRoutes = path.join(appDirPath, `/${mainRoutesFileName}`);
|
|
398
637
|
const stackDirPath = path.join(appDirPath, `/${stacksDirPath}`);
|
|
399
|
-
const layoutSettings =
|
|
638
|
+
const layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
|
|
400
639
|
const layoutConfigFileData = await this.#getLayoutConfig();
|
|
401
640
|
const layoutType = layoutSettings?.layout || 'bottom';
|
|
402
641
|
const layoutRouteConfig = layoutConfigFileData[layoutType];
|
|
@@ -445,7 +684,7 @@ export class GenerateMobileNavigations {
|
|
|
445
684
|
const regex = /\.(tsx|ts|jsx|js)$/i;
|
|
446
685
|
|
|
447
686
|
importStatements += `import * as React from 'react';\n`;
|
|
448
|
-
importStatements += `import
|
|
687
|
+
importStatements += `import AuthWrapper from '@admin-layout/gluestack-ui-mobile/lib/components/AuthWrapper.js';\n`;
|
|
449
688
|
|
|
450
689
|
if (unauthenticatedComponentPath)
|
|
451
690
|
importStatements += `import UnauthenticatedComponent from '${unauthenticatedComponentPath}';\n`;
|
|
@@ -492,14 +731,19 @@ export class GenerateMobileNavigations {
|
|
|
492
731
|
pkgRouteConfig?.customHeader &&
|
|
493
732
|
Object.keys(pkgRouteConfig.customHeader)?.length &&
|
|
494
733
|
customHeaderComponentPath
|
|
495
|
-
? `header: (props
|
|
734
|
+
? `header: (props) => <${customHeaderName} {...props} {...${JSON.stringify(
|
|
496
735
|
pkgRouteConfig?.customHeader?.props ?? '',
|
|
497
736
|
)}} />`
|
|
498
737
|
: ''
|
|
499
738
|
}}}}
|
|
500
|
-
>{(props
|
|
739
|
+
>{(props) => <AuthWrapper
|
|
501
740
|
auth={${pkgRouteConfig?.props?.initialParams?.auth ?? false}}
|
|
502
|
-
|
|
741
|
+
authority={${JSON.stringify(pkgRouteConfig?.authority) ?? null}}
|
|
742
|
+
extraPermissions={${JSON.stringify(pkgRouteConfig?.extraPermissions) ?? null}}
|
|
743
|
+
component={<Component${moduleNumber} {...props}
|
|
744
|
+
permissions={${JSON.stringify(pkgRouteConfig?.authority) ?? null}}
|
|
745
|
+
extraPermissions={${JSON.stringify(pkgRouteConfig?.extraPermissions) ?? null}}
|
|
746
|
+
/>}
|
|
503
747
|
${
|
|
504
748
|
pkgRouteConfig?.unauthenticatedComponent && customUnauthenticatedComponentPath
|
|
505
749
|
? `unauthenticatedComponent={<${customUnauthenticatedComponentName}/>}`
|
|
@@ -550,20 +794,20 @@ export class GenerateMobileNavigations {
|
|
|
550
794
|
}
|
|
551
795
|
|
|
552
796
|
moduleContent += `</Stack.Group>`;
|
|
553
|
-
moduleRender = `export default ({Stack,...rest}
|
|
797
|
+
moduleRender = `export default ({Stack,...rest}) => { return (<>${moduleContent}</>)}`;
|
|
554
798
|
}
|
|
555
799
|
stackNavigator = importStatements + '\n' + moduleRender;
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
800
|
+
let stackNavigation = stackNavigator;
|
|
801
|
+
stackNavigation = prettier.format(stackNavigation, { parser: 'babel' });
|
|
802
|
+
const stackDirName = path.dirname(stackDirPath);
|
|
803
|
+
try {
|
|
560
804
|
const isDirCreated = await this.#makeDir(stackDirName);
|
|
561
805
|
if (isDirCreated) {
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
}
|
|
806
|
+
await this.#writeFile(stackDirPath, stackNavigation);
|
|
807
|
+
}
|
|
808
|
+
} catch (error) {
|
|
809
|
+
console.log('Error generating stack navigation', error);
|
|
810
|
+
}
|
|
567
811
|
}
|
|
568
812
|
|
|
569
813
|
async #generateDrawerNavigationsFile({ drawerConfig, unauthenticatedComponentPath, drawerDirPath }) {
|
|
@@ -580,7 +824,8 @@ export class GenerateMobileNavigations {
|
|
|
580
824
|
const regex = /\.(tsx|ts|jsx|js)$/i;
|
|
581
825
|
|
|
582
826
|
importStatements += `import * as React from 'react';\n`;
|
|
583
|
-
importStatements += `import
|
|
827
|
+
importStatements += `import AuthWrapper from '@admin-layout/gluestack-ui-mobile/lib/components/AuthWrapper.js';\n`;
|
|
828
|
+
importStatements += `import DynamicIcons from '@app/selectiveIcons';\n`;
|
|
584
829
|
|
|
585
830
|
if (unauthenticatedComponentPath)
|
|
586
831
|
importStatements += `import UnauthenticatedComponent from '${unauthenticatedComponentPath}';\n`;
|
|
@@ -626,25 +871,55 @@ export class GenerateMobileNavigations {
|
|
|
626
871
|
initialParams={${JSON.stringify(pkgRouteConfig?.props?.initialParams || {})}}
|
|
627
872
|
options={{...${options},...{${
|
|
628
873
|
pkgRouteConfig?.icon && Object.keys(pkgRouteConfig.icon)?.length && pkgRouteConfig?.icon?.name
|
|
629
|
-
? `drawerIcon: ({ color
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
874
|
+
? `drawerIcon: ({ color }) => {
|
|
875
|
+
const focused = color === '${pkgRouteConfig?.props?.options?.tabBarActiveTintColor}' ? true : false;
|
|
876
|
+
const SelectedIcon = DynamicIcons('${pkgRouteConfig?.icon?.name}');
|
|
877
|
+
return (<SelectedIcon
|
|
878
|
+
{...{
|
|
879
|
+
...${JSON.stringify({ ...(pkgRouteConfig?.icon?.props || {}) })},
|
|
880
|
+
...{
|
|
881
|
+
color:focused ? ${
|
|
882
|
+
JSON.stringify(
|
|
883
|
+
pkgRouteConfig?.icon?.props?.color ??
|
|
884
|
+
pkgRouteConfig?.props?.options?.tabBarActiveTintColor,
|
|
885
|
+
) ?? 'black'
|
|
886
|
+
}
|
|
887
|
+
:${
|
|
888
|
+
JSON.stringify(pkgRouteConfig?.props?.options?.tabBarInactiveTintColor) ??
|
|
889
|
+
'grey'
|
|
890
|
+
},
|
|
891
|
+
stroke:focused ? ${
|
|
892
|
+
JSON.stringify(
|
|
893
|
+
pkgRouteConfig?.icon?.props?.color ??
|
|
894
|
+
pkgRouteConfig?.props?.options?.tabBarActiveTintColor,
|
|
895
|
+
) ?? 'black'
|
|
896
|
+
}
|
|
897
|
+
:${
|
|
898
|
+
JSON.stringify(pkgRouteConfig?.props?.options?.tabBarInactiveTintColor) ??
|
|
899
|
+
'grey'
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
}}
|
|
903
|
+
/>)},`
|
|
634
904
|
: ''
|
|
635
905
|
}
|
|
636
906
|
${
|
|
637
907
|
pkgRouteConfig?.customHeader &&
|
|
638
908
|
Object.keys(pkgRouteConfig.customHeader)?.length &&
|
|
639
909
|
customHeaderComponentPath
|
|
640
|
-
? `header: (props
|
|
910
|
+
? `header: (props) => <${customHeaderName} {...props} {...${JSON.stringify(
|
|
641
911
|
pkgRouteConfig?.customHeader?.props ?? '',
|
|
642
912
|
)}} />`
|
|
643
913
|
: ''
|
|
644
914
|
}}}}
|
|
645
|
-
>{(props
|
|
915
|
+
>{(props) => <AuthWrapper
|
|
646
916
|
auth={${pkgRouteConfig?.props?.initialParams?.auth ?? false}}
|
|
647
|
-
|
|
917
|
+
authority={${JSON.stringify(pkgRouteConfig?.authority) ?? null}}
|
|
918
|
+
extraPermissions={${JSON.stringify(pkgRouteConfig?.extraPermissions) ?? null}}
|
|
919
|
+
component={<Component${moduleNumber} {...props}
|
|
920
|
+
permissions={${JSON.stringify(pkgRouteConfig?.authority) ?? null}}
|
|
921
|
+
extraPermissions={${JSON.stringify(pkgRouteConfig?.extraPermissions) ?? null}}
|
|
922
|
+
/>}
|
|
648
923
|
${
|
|
649
924
|
pkgRouteConfig?.unauthenticatedComponent && customUnauthenticatedComponentPath
|
|
650
925
|
? `unauthenticatedComponent={<${customUnauthenticatedComponentName}/>}`
|
|
@@ -671,10 +946,10 @@ export class GenerateMobileNavigations {
|
|
|
671
946
|
}
|
|
672
947
|
/>}</Drawer.Screen>`;
|
|
673
948
|
}
|
|
674
|
-
if (icons && icons?.length) {
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
}
|
|
949
|
+
// if (icons && icons?.length) {
|
|
950
|
+
// const uniqueIcons = [...new Set(icons.split(','))].join(',');
|
|
951
|
+
// importStatements += `import Icons from '@expo/vector-icons';\n`;
|
|
952
|
+
// }
|
|
678
953
|
|
|
679
954
|
if (customHeaderPaths && customHeaderPaths?.length) {
|
|
680
955
|
const uniqueHeaderNames = [...new Set(customHeaderNames.split(','))]?.filter((str) => str?.length);
|
|
@@ -699,22 +974,20 @@ export class GenerateMobileNavigations {
|
|
|
699
974
|
});
|
|
700
975
|
}
|
|
701
976
|
|
|
702
|
-
moduleRender = `export default ({Drawer,...rest}
|
|
977
|
+
moduleRender = `export default ({Drawer,...rest}) => { return (<>${moduleContent}</>)}`;
|
|
703
978
|
moduleNavigation = importStatements + '\n' + moduleRender;
|
|
704
|
-
|
|
705
979
|
const drawerNavigator = moduleNavigation;
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
980
|
+
let drawerNavigation = drawerNavigator;
|
|
981
|
+
drawerNavigation = prettier.format(drawerNavigation, { parser: 'babel' });
|
|
982
|
+
const drawerDirName = path.dirname(drawerDirPath);
|
|
983
|
+
try {
|
|
710
984
|
const isDirCreated = await this.#makeDir(drawerDirName);
|
|
711
985
|
if (isDirCreated) {
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
986
|
+
await this.#writeFile(drawerDirPath, drawerNavigation);
|
|
987
|
+
}
|
|
988
|
+
} catch (error) {
|
|
989
|
+
console.log('Error generating drawer navigation file', error);
|
|
716
990
|
}
|
|
717
|
-
return false;
|
|
718
991
|
}
|
|
719
992
|
|
|
720
993
|
async #generateDrawerNavigations({ appDirPath, modules, initialRouteName, unauthenticatedComponentPath }) {
|
|
@@ -722,7 +995,7 @@ export class GenerateMobileNavigations {
|
|
|
722
995
|
const drawerDirPath = path.join(appDirPath, `/${drawerFilePath}`);
|
|
723
996
|
const hostDirPath = path.join(appDirPath, `/${hostDrawerFilePath}`);
|
|
724
997
|
|
|
725
|
-
const layoutSettings =
|
|
998
|
+
const layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
|
|
726
999
|
const layoutConfigFileData = await this.#getLayoutConfig();
|
|
727
1000
|
const layoutType = 'side';
|
|
728
1001
|
const layoutRouteConfig = layoutConfigFileData[layoutType];
|
|
@@ -760,31 +1033,32 @@ export class GenerateMobileNavigations {
|
|
|
760
1033
|
return a?.props?.options?.priority - b?.props?.options?.priority;
|
|
761
1034
|
}) ?? [];
|
|
762
1035
|
|
|
763
|
-
|
|
764
|
-
if (
|
|
765
|
-
|
|
766
|
-
drawerConfig: drawerConfig,
|
|
767
|
-
unauthenticatedComponentPath,
|
|
768
|
-
drawerDirPath: drawerDirPath,
|
|
769
|
-
});
|
|
770
|
-
if (drawerNavigation)
|
|
1036
|
+
try {
|
|
1037
|
+
if (layoutSettings?.layout == 'side') {
|
|
1038
|
+
if (drawerConfig) {
|
|
771
1039
|
await this.#generateDrawerNavigationsFile({
|
|
772
|
-
drawerConfig:
|
|
1040
|
+
drawerConfig: drawerConfig,
|
|
773
1041
|
unauthenticatedComponentPath,
|
|
774
|
-
drawerDirPath:
|
|
1042
|
+
drawerDirPath: drawerDirPath,
|
|
775
1043
|
});
|
|
776
|
-
|
|
777
|
-
} else {
|
|
778
|
-
if (hostDrawerConfig) {
|
|
779
|
-
const isDrawerGenerated = await this.#generateDrawerNavigationsFile({
|
|
1044
|
+
await this.#generateDrawerNavigationsFile({
|
|
780
1045
|
drawerConfig: hostDrawerConfig,
|
|
781
1046
|
unauthenticatedComponentPath,
|
|
782
1047
|
drawerDirPath: hostDirPath,
|
|
783
1048
|
});
|
|
784
|
-
|
|
785
|
-
|
|
1049
|
+
} else {
|
|
1050
|
+
if (hostDrawerConfig) {
|
|
1051
|
+
await this.#generateDrawerNavigationsFile({
|
|
1052
|
+
drawerConfig: hostDrawerConfig,
|
|
1053
|
+
unauthenticatedComponentPath,
|
|
1054
|
+
drawerDirPath: hostDirPath,
|
|
1055
|
+
});
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
786
1058
|
}
|
|
787
|
-
}
|
|
1059
|
+
} catch (error) {
|
|
1060
|
+
console.log('Error generating drawer navigation', error);
|
|
1061
|
+
}
|
|
788
1062
|
}
|
|
789
1063
|
|
|
790
1064
|
async #generateBottomTabNavigationsFile({
|
|
@@ -807,7 +1081,8 @@ export class GenerateMobileNavigations {
|
|
|
807
1081
|
const regex = /\.(tsx|ts|jsx|js)$/i;
|
|
808
1082
|
|
|
809
1083
|
importStatements += `import * as React from 'react';\n`;
|
|
810
|
-
importStatements += `import
|
|
1084
|
+
importStatements += `import AuthWrapper from '@admin-layout/gluestack-ui-mobile/lib/components/AuthWrapper.js';\n`;
|
|
1085
|
+
importStatements += `import DynamicIcons from '@app/selectiveIcons';\n`;
|
|
811
1086
|
|
|
812
1087
|
if (unauthenticatedComponentPath)
|
|
813
1088
|
importStatements += `import UnauthenticatedComponent from '${unauthenticatedComponentPath}';\n`;
|
|
@@ -847,10 +1122,12 @@ export class GenerateMobileNavigations {
|
|
|
847
1122
|
}
|
|
848
1123
|
|
|
849
1124
|
const options = JSON.stringify(
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
1125
|
+
pkgRouteConfig?.props?.options
|
|
1126
|
+
? {
|
|
1127
|
+
...pkgRouteConfig.props.options,
|
|
1128
|
+
headerShown: mixLayout ? false : pkgRouteConfig.props.options.headerShown,
|
|
1129
|
+
}
|
|
1130
|
+
: { headerShown: mixLayout ? false : true },
|
|
854
1131
|
);
|
|
855
1132
|
importStatements += `import Component${moduleNumber} from '${pkgRouteConfig.componentPath}';\n`;
|
|
856
1133
|
moduleContent += `<Tab.Screen
|
|
@@ -860,26 +1137,57 @@ export class GenerateMobileNavigations {
|
|
|
860
1137
|
initialParams={${JSON.stringify(pkgRouteConfig?.props?.initialParams || {})}}
|
|
861
1138
|
options={{...${options},...{${
|
|
862
1139
|
pkgRouteConfig?.icon && Object.keys(pkgRouteConfig.icon)?.length && pkgRouteConfig?.icon?.name
|
|
863
|
-
? `tabBarIcon: ({ color }
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
1140
|
+
? `tabBarIcon: ({ color }) => {
|
|
1141
|
+
const focused = color === '${pkgRouteConfig?.props?.options?.tabBarActiveTintColor}' ? true : false;
|
|
1142
|
+
const SelectedIcon = DynamicIcons('${pkgRouteConfig?.icon?.name}');
|
|
1143
|
+
return (<SelectedIcon
|
|
1144
|
+
{...{
|
|
1145
|
+
...${JSON.stringify({ ...(pkgRouteConfig?.icon?.props || {}) })},
|
|
1146
|
+
...{
|
|
1147
|
+
color:focused ? ${
|
|
1148
|
+
JSON.stringify(
|
|
1149
|
+
pkgRouteConfig?.icon?.props?.color ??
|
|
1150
|
+
pkgRouteConfig?.props?.options?.tabBarActiveTintColor,
|
|
1151
|
+
) ?? 'black'
|
|
1152
|
+
}
|
|
1153
|
+
:${
|
|
1154
|
+
JSON.stringify(pkgRouteConfig?.props?.options?.tabBarInactiveTintColor) ??
|
|
1155
|
+
'grey'
|
|
1156
|
+
},
|
|
1157
|
+
stroke:focused ? ${
|
|
1158
|
+
JSON.stringify(
|
|
1159
|
+
pkgRouteConfig?.icon?.props?.color ??
|
|
1160
|
+
pkgRouteConfig?.props?.options?.tabBarActiveTintColor,
|
|
1161
|
+
) ?? 'black'
|
|
1162
|
+
}
|
|
1163
|
+
:${
|
|
1164
|
+
JSON.stringify(pkgRouteConfig?.props?.options?.tabBarInactiveTintColor) ??
|
|
1165
|
+
'grey'
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
}}
|
|
1169
|
+
|
|
1170
|
+
/>)}`
|
|
868
1171
|
: ''
|
|
869
1172
|
}
|
|
870
1173
|
${
|
|
871
1174
|
pkgRouteConfig?.customHeader &&
|
|
872
1175
|
Object.keys(pkgRouteConfig.customHeader)?.length &&
|
|
873
1176
|
customHeaderComponentPath
|
|
874
|
-
? `,header: (props
|
|
1177
|
+
? `,header: (props) => <${customHeaderName} {...props} {...${JSON.stringify(
|
|
875
1178
|
pkgRouteConfig?.customHeader?.props ?? '',
|
|
876
1179
|
)}} />`
|
|
877
1180
|
: ''
|
|
878
1181
|
}
|
|
879
1182
|
}}}
|
|
880
|
-
>{(props
|
|
1183
|
+
>{(props) => <AuthWrapper
|
|
881
1184
|
auth={${pkgRouteConfig?.props?.initialParams?.auth ?? false}}
|
|
882
|
-
|
|
1185
|
+
authority={${JSON.stringify(pkgRouteConfig?.authority) ?? null}}
|
|
1186
|
+
extraPermissions={${JSON.stringify(pkgRouteConfig?.extraPermissions) ?? null}}
|
|
1187
|
+
component={<Component${moduleNumber} {...props}
|
|
1188
|
+
permissions={${JSON.stringify(pkgRouteConfig?.authority) ?? null}}
|
|
1189
|
+
extraPermissions={${JSON.stringify(pkgRouteConfig?.extraPermissions) ?? null}}
|
|
1190
|
+
/>}
|
|
883
1191
|
${
|
|
884
1192
|
pkgRouteConfig?.unauthenticatedComponent && customUnauthenticatedComponentPath
|
|
885
1193
|
? `unauthenticatedComponent={<${customUnauthenticatedComponentName}/>}`
|
|
@@ -908,10 +1216,10 @@ export class GenerateMobileNavigations {
|
|
|
908
1216
|
</Tab.Screen>`;
|
|
909
1217
|
}
|
|
910
1218
|
|
|
911
|
-
if (icons && icons?.length) {
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
}
|
|
1219
|
+
// if (icons && icons?.length) {
|
|
1220
|
+
// const uniqueIcons = [...new Set(icons.split(','))].join(',');
|
|
1221
|
+
// importStatements += `import { ${uniqueIcons} } from '@expo/vector-icons';\n`;
|
|
1222
|
+
// }
|
|
915
1223
|
|
|
916
1224
|
if (customHeaderPaths && customHeaderPaths?.length) {
|
|
917
1225
|
const uniqueHeaderNames = [...new Set(customHeaderNames.split(','))]?.filter((str) => str?.length);
|
|
@@ -936,21 +1244,20 @@ export class GenerateMobileNavigations {
|
|
|
936
1244
|
});
|
|
937
1245
|
}
|
|
938
1246
|
|
|
939
|
-
moduleRender = `export default ({Tab,...rest}
|
|
1247
|
+
moduleRender = `export default ({Tab,...rest}) => { return (<>${moduleContent}</>)}`;
|
|
940
1248
|
moduleNavigation = importStatements + '\n' + moduleRender;
|
|
941
1249
|
const bottomTabNavigator = moduleNavigation;
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
1250
|
+
let bottomTabNavigation = bottomTabNavigator;
|
|
1251
|
+
bottomTabNavigation = prettier.format(bottomTabNavigation, { parser: 'babel' });
|
|
1252
|
+
const bottomDirName = path.dirname(bottomDirPath);
|
|
1253
|
+
try {
|
|
946
1254
|
const isDirCreated = await this.#makeDir(bottomDirName);
|
|
947
1255
|
if (isDirCreated) {
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
1256
|
+
await this.#writeFile(bottomDirPath, bottomTabNavigation);
|
|
1257
|
+
}
|
|
1258
|
+
} catch (error) {
|
|
1259
|
+
console.log('Error generating bottom tab navigation file', error);
|
|
952
1260
|
}
|
|
953
|
-
return false;
|
|
954
1261
|
}
|
|
955
1262
|
|
|
956
1263
|
async #generateBottomTabNavigations({ appDirPath, modules, initialRouteName, unauthenticatedComponentPath }) {
|
|
@@ -958,7 +1265,7 @@ export class GenerateMobileNavigations {
|
|
|
958
1265
|
const bottomDirPath = path.join(appDirPath, `/${bottomFilePath}`);
|
|
959
1266
|
const hostBottomDirPath = path.join(appDirPath, `/${hostBottomFilePath}`);
|
|
960
1267
|
|
|
961
|
-
const layoutSettings =
|
|
1268
|
+
const layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
|
|
962
1269
|
const layoutConfigFileData = await this.#getLayoutConfig();
|
|
963
1270
|
const layoutType = layoutSettings?.layout ?? 'bottom';
|
|
964
1271
|
const layoutRouteConfig = layoutConfigFileData[layoutType];
|
|
@@ -998,34 +1305,35 @@ export class GenerateMobileNavigations {
|
|
|
998
1305
|
if (b?.props?.options?.priority === undefined) return -1;
|
|
999
1306
|
return a?.props?.options?.priority - b?.props?.options?.priority;
|
|
1000
1307
|
}) ?? [];
|
|
1001
|
-
|
|
1002
|
-
if (
|
|
1003
|
-
|
|
1004
|
-
bottomTabConfig: bottomTabConfig,
|
|
1005
|
-
unauthenticatedComponentPath,
|
|
1006
|
-
bottomDirPath: bottomDirPath,
|
|
1007
|
-
mixLayout,
|
|
1008
|
-
});
|
|
1009
|
-
if (drawerNavigation)
|
|
1308
|
+
try {
|
|
1309
|
+
if (layoutType == 'bottom' || layoutType == 'mixSide') {
|
|
1310
|
+
if (bottomTabConfig) {
|
|
1010
1311
|
await this.#generateBottomTabNavigationsFile({
|
|
1011
|
-
bottomTabConfig:
|
|
1312
|
+
bottomTabConfig: bottomTabConfig,
|
|
1012
1313
|
unauthenticatedComponentPath,
|
|
1013
|
-
bottomDirPath:
|
|
1314
|
+
bottomDirPath: bottomDirPath,
|
|
1014
1315
|
mixLayout,
|
|
1015
1316
|
});
|
|
1016
|
-
|
|
1017
|
-
} else {
|
|
1018
|
-
if (hostBottomTabConfig) {
|
|
1019
|
-
const isHostGenerated = await this.#generateBottomTabNavigationsFile({
|
|
1317
|
+
await this.#generateBottomTabNavigationsFile({
|
|
1020
1318
|
bottomTabConfig: hostBottomTabConfig,
|
|
1021
1319
|
unauthenticatedComponentPath,
|
|
1022
1320
|
bottomDirPath: hostBottomDirPath,
|
|
1023
1321
|
mixLayout,
|
|
1024
1322
|
});
|
|
1025
|
-
|
|
1026
|
-
|
|
1323
|
+
} else {
|
|
1324
|
+
if (hostBottomTabConfig) {
|
|
1325
|
+
await this.#generateBottomTabNavigationsFile({
|
|
1326
|
+
bottomTabConfig: hostBottomTabConfig,
|
|
1327
|
+
unauthenticatedComponentPath,
|
|
1328
|
+
bottomDirPath: hostBottomDirPath,
|
|
1329
|
+
mixLayout,
|
|
1330
|
+
});
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1027
1333
|
}
|
|
1028
|
-
}
|
|
1334
|
+
} catch (error) {
|
|
1335
|
+
console.log('Error generating bottom tab navigation', error);
|
|
1336
|
+
}
|
|
1029
1337
|
}
|
|
1030
1338
|
|
|
1031
1339
|
async #generateBottomTabDrawerNavigations({ appDirPath, modules, initialRouteName, unauthenticatedComponentPath }) {
|
|
@@ -1035,7 +1343,7 @@ export class GenerateMobileNavigations {
|
|
|
1035
1343
|
const drawerDirPath = path.join(appDirPath, `/${drawerFilePath}`);
|
|
1036
1344
|
const hostDirPath = path.join(appDirPath, `/${hostDrawerFilePath}`);
|
|
1037
1345
|
|
|
1038
|
-
const layoutSettings =
|
|
1346
|
+
const layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
|
|
1039
1347
|
const layoutConfigFileData = await this.#getLayoutConfig();
|
|
1040
1348
|
const layoutType = layoutSettings?.layout ?? 'bottom';
|
|
1041
1349
|
const layoutRouteConfig = layoutConfigFileData[layoutType];
|
|
@@ -1098,52 +1406,57 @@ export class GenerateMobileNavigations {
|
|
|
1098
1406
|
}) ?? [];
|
|
1099
1407
|
|
|
1100
1408
|
if (bottomTabConfig) {
|
|
1101
|
-
|
|
1102
|
-
bottomTabConfig: bottomTabConfig,
|
|
1103
|
-
unauthenticatedComponentPath,
|
|
1104
|
-
bottomDirPath: bottomDirPath,
|
|
1105
|
-
mixLayout,
|
|
1106
|
-
});
|
|
1107
|
-
if (drawerNavigation)
|
|
1409
|
+
try {
|
|
1108
1410
|
await this.#generateBottomTabNavigationsFile({
|
|
1109
|
-
bottomTabConfig:
|
|
1411
|
+
bottomTabConfig: bottomTabConfig,
|
|
1110
1412
|
unauthenticatedComponentPath,
|
|
1111
|
-
bottomDirPath:
|
|
1413
|
+
bottomDirPath: bottomDirPath,
|
|
1112
1414
|
mixLayout,
|
|
1113
1415
|
});
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1416
|
+
|
|
1417
|
+
await this.#generateBottomTabNavigationsFile({
|
|
1418
|
+
bottomTabConfig: hostBottomTabConfig,
|
|
1117
1419
|
unauthenticatedComponentPath,
|
|
1118
|
-
|
|
1420
|
+
bottomDirPath: hostBottomDirPath,
|
|
1421
|
+
mixLayout,
|
|
1119
1422
|
});
|
|
1120
|
-
if (
|
|
1423
|
+
if (drawerConfig) {
|
|
1424
|
+
await this.#generateDrawerNavigationsFile({
|
|
1425
|
+
drawerConfig: drawerConfig,
|
|
1426
|
+
unauthenticatedComponentPath,
|
|
1427
|
+
drawerDirPath: drawerDirPath,
|
|
1428
|
+
});
|
|
1121
1429
|
await this.#generateDrawerNavigationsFile({
|
|
1122
1430
|
drawerConfig: hostDrawerConfig,
|
|
1123
1431
|
unauthenticatedComponentPath,
|
|
1124
1432
|
drawerDirPath: hostDirPath,
|
|
1125
1433
|
});
|
|
1126
|
-
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1434
|
+
}
|
|
1435
|
+
} catch (error) {
|
|
1436
|
+
console.log('Error in generating drawer bottom tab navigation', error);
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1129
1439
|
}
|
|
1130
1440
|
|
|
1131
1441
|
async #generateAppNavigationFile({ appDirPath, customTabBarPath, customDrawerPath, customHeaderPath }) {
|
|
1132
1442
|
const navigationDirPath = path.join(appDirPath, `/${appNavigationFileName}`);
|
|
1133
|
-
const layoutSettings =
|
|
1443
|
+
const layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
|
|
1134
1444
|
const layoutConfigFileData = await this.#getLayoutConfig();
|
|
1135
1445
|
const layoutType = layoutSettings?.layout || 'bottom';
|
|
1136
1446
|
const layoutRouteConfig = layoutConfigFileData[layoutType];
|
|
1137
1447
|
const layoutRouteKey = Object.keys(layoutRouteConfig)[1];
|
|
1138
1448
|
const appLayout = layoutRouteConfig[layoutRouteKey];
|
|
1139
|
-
|
|
1140
|
-
const
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1449
|
+
const initialRouteNameRootStack = this.#initialRouteNameRootStack;
|
|
1450
|
+
const layoutInitialRouteName = this.#initialRouteName;
|
|
1451
|
+
const initialRouteName = layoutInitialRouteName
|
|
1452
|
+
? layoutInitialRouteName
|
|
1453
|
+
: layoutType === 'mixSide'
|
|
1454
|
+
? appLayout?.[appLayout?.key]?.props?.initialRouteName ?? 'MainStack.Layout.Home'
|
|
1455
|
+
: appLayout?.props?.initialRouteName || 'MainStack.Home';
|
|
1144
1456
|
const isShowTabs = layoutType === 'mixSide' || layoutType === 'bottom' ? true : false;
|
|
1145
1457
|
const isShowDefalutHeader = layoutType === 'mixSide' ? true : false;
|
|
1146
1458
|
const defaultHeaderProps = {
|
|
1459
|
+
...(layoutSettings || {}),
|
|
1147
1460
|
showToggle: layoutSettings?.topLeftToggle || false,
|
|
1148
1461
|
right: layoutSettings?.topRightSettingToggle || false,
|
|
1149
1462
|
};
|
|
@@ -1178,8 +1491,8 @@ export class GenerateMobileNavigations {
|
|
|
1178
1491
|
const Drawer = createDrawerNavigator();
|
|
1179
1492
|
`;
|
|
1180
1493
|
rootComponent += `
|
|
1181
|
-
const RootComponent = (props
|
|
1182
|
-
const settings = useSelector((state
|
|
1494
|
+
const RootComponent = (props) => {
|
|
1495
|
+
const settings = useSelector((state) => state.settings);
|
|
1183
1496
|
const defaultHeaderProps = ${JSON.stringify(defaultHeaderProps || {})};
|
|
1184
1497
|
return (
|
|
1185
1498
|
<Drawer.Navigator
|
|
@@ -1188,14 +1501,18 @@ export class GenerateMobileNavigations {
|
|
|
1188
1501
|
screenOptions={({ route }) => ({ ...${JSON.stringify(screenOptions)} ,...{
|
|
1189
1502
|
${
|
|
1190
1503
|
customHeaderPath
|
|
1191
|
-
? `header: (props
|
|
1504
|
+
? `header: (props) => {
|
|
1192
1505
|
const title = getHeaderTitle(props.options, props.route.name);
|
|
1193
1506
|
return <CustomHeader {...defaultHeaderProps} {...props} title={title} style={props.options.headerStyle} />;
|
|
1194
1507
|
}`
|
|
1195
1508
|
: ''
|
|
1196
1509
|
}
|
|
1197
1510
|
}})}
|
|
1198
|
-
${
|
|
1511
|
+
${
|
|
1512
|
+
customDrawerPath
|
|
1513
|
+
? 'drawerContent={(props) => <CustomDrawerContent {...props} {...defaultHeaderProps || {}} />}'
|
|
1514
|
+
: ''
|
|
1515
|
+
}
|
|
1199
1516
|
>
|
|
1200
1517
|
{settings?.layout == 'host-bottom' ? hostDrawerNavigations({ Drawer }) : drawerNavigations({ Drawer })}
|
|
1201
1518
|
</Drawer.Navigator>
|
|
@@ -1219,20 +1536,20 @@ export class GenerateMobileNavigations {
|
|
|
1219
1536
|
const Tab = createBottomTabNavigator();
|
|
1220
1537
|
`;
|
|
1221
1538
|
rootComponent += `
|
|
1222
|
-
const RootComponent = (props
|
|
1223
|
-
const settings = useSelector((state
|
|
1539
|
+
const RootComponent = (props) => {
|
|
1540
|
+
const settings = useSelector((state) => state.settings);
|
|
1224
1541
|
const initialRouteName = ${JSON.stringify(initialRouteName)};
|
|
1225
1542
|
let defaultScreenOptions = ${JSON.stringify(screenOptionsTab)};
|
|
1226
1543
|
const defaultHeaderProps = ${JSON.stringify(defaultHeaderProps || {})};
|
|
1227
1544
|
const defaultHeader = {${
|
|
1228
|
-
isShowDefalutHeader ? `header:(props
|
|
1545
|
+
isShowDefalutHeader ? `header:(props)=><Header {...defaultHeaderProps} {...props} />` : ''
|
|
1229
1546
|
}};
|
|
1230
1547
|
return (
|
|
1231
1548
|
<Tab.Navigator
|
|
1232
1549
|
initialRouteName={initialRouteName}
|
|
1233
|
-
screenOptions={(props
|
|
1550
|
+
screenOptions={(props)=>({...props,...defaultScreenOptions,...{${
|
|
1234
1551
|
customHeaderPath
|
|
1235
|
-
? `header: (props
|
|
1552
|
+
? `header: (props) => {
|
|
1236
1553
|
const title = getHeaderTitle(props.options, props.route.name);
|
|
1237
1554
|
return <CustomHeader {...defaultHeaderProps} {...props} title={title} style={props.options.headerStyle} />;
|
|
1238
1555
|
}`
|
|
@@ -1240,7 +1557,7 @@ export class GenerateMobileNavigations {
|
|
|
1240
1557
|
}}})}
|
|
1241
1558
|
${
|
|
1242
1559
|
customTabBarPath
|
|
1243
|
-
? 'tabBar={(props
|
|
1560
|
+
? 'tabBar={(props) => <CustomTabBar key={props?.key??"customTabBarKey"} {...props} />}'
|
|
1244
1561
|
: ''
|
|
1245
1562
|
}
|
|
1246
1563
|
>
|
|
@@ -1274,21 +1591,21 @@ export class GenerateMobileNavigations {
|
|
|
1274
1591
|
`;
|
|
1275
1592
|
rootComponent += `
|
|
1276
1593
|
const TabNavigator = () => {
|
|
1277
|
-
const settings = useSelector((state
|
|
1594
|
+
const settings = useSelector((state) => state.settings);
|
|
1278
1595
|
const initialRouteName = ${JSON.stringify(initialRouteName)};
|
|
1279
1596
|
let defaultScreenOptions = ${JSON.stringify(screenOptionsTab)};
|
|
1280
1597
|
const defaultHeaderProps = ${JSON.stringify(defaultHeaderProps || {})};
|
|
1281
1598
|
const defaultHeader = {${
|
|
1282
|
-
isShowDefalutHeader ? `header:(props
|
|
1599
|
+
isShowDefalutHeader ? `header:(props)=><Header {...defaultHeaderProps} {...props} />` : ''
|
|
1283
1600
|
}};
|
|
1284
1601
|
|
|
1285
1602
|
return (
|
|
1286
1603
|
<Tab.Navigator
|
|
1287
1604
|
initialRouteName={initialRouteName}
|
|
1288
|
-
screenOptions={(props
|
|
1605
|
+
screenOptions={(props)=>({...props,...defaultScreenOptions,...{headerShown: false,header:()=>null},})}
|
|
1289
1606
|
${
|
|
1290
1607
|
customTabBarPath
|
|
1291
|
-
? 'tabBar={(props
|
|
1608
|
+
? 'tabBar={(props) => <CustomTabBar key={props?.key??"customTabBarKey"} {...props} />}'
|
|
1292
1609
|
: ''
|
|
1293
1610
|
}
|
|
1294
1611
|
>
|
|
@@ -1296,13 +1613,13 @@ export class GenerateMobileNavigations {
|
|
|
1296
1613
|
</Tab.Navigator>
|
|
1297
1614
|
)
|
|
1298
1615
|
}
|
|
1299
|
-
const RootComponent = (props
|
|
1616
|
+
const RootComponent = (props) => {
|
|
1300
1617
|
const initialRouteName = ${JSON.stringify(initialRouteName)};
|
|
1301
|
-
const settings = useSelector((state
|
|
1618
|
+
const settings = useSelector((state) => state.settings);
|
|
1302
1619
|
let defaultScreenOptions = ${JSON.stringify(screenOptionsTab)};
|
|
1303
1620
|
const defaultHeaderProps = ${JSON.stringify(defaultHeaderProps || {})};
|
|
1304
1621
|
const defaultHeader = {${
|
|
1305
|
-
isShowDefalutHeader ? `header:(props
|
|
1622
|
+
isShowDefalutHeader ? `header:(props)=><Header {...defaultHeaderProps} {...props} />` : ''
|
|
1306
1623
|
}};
|
|
1307
1624
|
return (
|
|
1308
1625
|
<Drawer.Navigator
|
|
@@ -1317,7 +1634,7 @@ export class GenerateMobileNavigations {
|
|
|
1317
1634
|
: "Home",
|
|
1318
1635
|
${
|
|
1319
1636
|
customHeaderPath
|
|
1320
|
-
? `header: (props
|
|
1637
|
+
? `header: (props) => {
|
|
1321
1638
|
const title = getHeaderTitle(props.options, props.route.name);
|
|
1322
1639
|
return <CustomHeader {...defaultHeaderProps} {...props} title={title} isMixedLayout={true} style={props.options.headerStyle} />;
|
|
1323
1640
|
}`
|
|
@@ -1327,11 +1644,11 @@ export class GenerateMobileNavigations {
|
|
|
1327
1644
|
}})}
|
|
1328
1645
|
${
|
|
1329
1646
|
customDrawerPath
|
|
1330
|
-
? 'drawerContent={((props
|
|
1647
|
+
? 'drawerContent={((props)) => <CustomDrawerContent {...props} showDefaultRoutes={true} />}'
|
|
1331
1648
|
: ''
|
|
1332
1649
|
}
|
|
1333
1650
|
>
|
|
1334
|
-
<Drawer.Screen name="Layout" options={{title:"Home", drawerIcon: ({ color, size }
|
|
1651
|
+
<Drawer.Screen name="Layout" options={{title:"Home", drawerIcon: ({ color, size }) => (
|
|
1335
1652
|
<MaterialIcons name="home" size={24} color={color} />
|
|
1336
1653
|
),}}
|
|
1337
1654
|
component={TabNavigator} />
|
|
@@ -1344,7 +1661,7 @@ export class GenerateMobileNavigations {
|
|
|
1344
1661
|
appComponent += `
|
|
1345
1662
|
const AppNavigations = () => {
|
|
1346
1663
|
return (
|
|
1347
|
-
<Stack.Navigator initialRouteName="${
|
|
1664
|
+
<Stack.Navigator initialRouteName="${initialRouteNameRootStack}">
|
|
1348
1665
|
<Stack.Screen
|
|
1349
1666
|
name="MainStack"
|
|
1350
1667
|
options={{ headerShown: false }}
|
|
@@ -1359,9 +1676,110 @@ export class GenerateMobileNavigations {
|
|
|
1359
1676
|
`;
|
|
1360
1677
|
appNavigation = importStatements + '\n' + rootComponent + '\n' + appComponent;
|
|
1361
1678
|
appNavigation = prettier.format(appNavigation, { parser: 'babel' });
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1679
|
+
try {
|
|
1680
|
+
await this.#writeFile(navigationDirPath, appNavigation);
|
|
1681
|
+
} catch (error) {
|
|
1682
|
+
console.log('Error in generating app navigationfile', error);
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
async #generateSelectiveIconsFile({ appDirPath, modules }) {
|
|
1687
|
+
const mainRoutes = path.join(appDirPath, `/${mainRoutesFileName}`);
|
|
1688
|
+
const modulesRouteConfig = await this.#getModulesRouteConfig({ modules: modules });
|
|
1689
|
+
const mainRouteConfig = await this.#readJsonFile(mainRoutes);
|
|
1690
|
+
const allRoutes = [...[mainRouteConfig ?? []], ...(modulesRouteConfig ?? [])];
|
|
1691
|
+
let iconNames = [];
|
|
1692
|
+
allRoutes?.flat(1)?.forEach((route) => {
|
|
1693
|
+
const key = Object.keys(route)[0];
|
|
1694
|
+
const value = route[key];
|
|
1695
|
+
if (value?.icon && typeof value.icon === 'object') {
|
|
1696
|
+
if (typeof value.icon.name === 'string') {
|
|
1697
|
+
if (!iconNames.includes(value.icon.name)) iconNames.push(value.icon.name);
|
|
1698
|
+
}
|
|
1699
|
+
} else if (value?.icon && typeof value.icon === 'string') {
|
|
1700
|
+
if (!iconNames.includes(value.icon)) iconNames.push(value.icon);
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
if (value?.extraIcons && Array.isArray(value.extraIcons) && value?.extraIcons?.length > 0) {
|
|
1704
|
+
value?.extraIcons?.map((icon) => {
|
|
1705
|
+
if (typeof icon === 'string') {
|
|
1706
|
+
if (!iconNames.includes(icon)) iconNames.push(icon);
|
|
1707
|
+
} else {
|
|
1708
|
+
console.warn(`Invalid icon type: ${typeof icon}`);
|
|
1709
|
+
}
|
|
1710
|
+
});
|
|
1711
|
+
} else if (value?.extraIcons && typeof value.extraIcons === 'string') {
|
|
1712
|
+
if (!iconNames.includes(value.extraIcons)) iconNames.push(value.extraIcons);
|
|
1713
|
+
}
|
|
1714
|
+
});
|
|
1715
|
+
|
|
1716
|
+
const iconsRepository = this.#iconsRepository;
|
|
1717
|
+
const expoIcons = [
|
|
1718
|
+
'AntDesign',
|
|
1719
|
+
'Entypo',
|
|
1720
|
+
'EvilIcons',
|
|
1721
|
+
'Feather',
|
|
1722
|
+
'FontAwesome',
|
|
1723
|
+
'FontAwesome5',
|
|
1724
|
+
'Fontisto',
|
|
1725
|
+
'Foundation',
|
|
1726
|
+
'Ionicons',
|
|
1727
|
+
'MaterialCommunityIcons',
|
|
1728
|
+
'MaterialIcons',
|
|
1729
|
+
'Octicons',
|
|
1730
|
+
'SimpleLineIcons',
|
|
1731
|
+
'Zocial',
|
|
1732
|
+
];
|
|
1733
|
+
|
|
1734
|
+
let content = `
|
|
1735
|
+
function __variableDynamicIcon(icon) {
|
|
1736
|
+
switch (icon) {
|
|
1737
|
+
`;
|
|
1738
|
+
iconNames.forEach((name) => {
|
|
1739
|
+
let prefix, iconName;
|
|
1740
|
+
if (name.includes('.')) {
|
|
1741
|
+
[prefix, iconName] = name.split('.');
|
|
1742
|
+
}
|
|
1743
|
+
if (prefix && iconsRepository[prefix]) {
|
|
1744
|
+
const importPath = iconsRepository[prefix].replace(
|
|
1745
|
+
'{iconName}',
|
|
1746
|
+
prefix === 'expo' ? iconName : iconName + '.native',
|
|
1747
|
+
);
|
|
1748
|
+
// prefix = prefix.charAt(0).toUpperCase() + prefix.slice(1).toLowerCase();
|
|
1749
|
+
content += `
|
|
1750
|
+
case '${prefix + '.' + iconName}':
|
|
1751
|
+
return require('${importPath}')?.default;
|
|
1752
|
+
`;
|
|
1753
|
+
} else {
|
|
1754
|
+
content += `
|
|
1755
|
+
case '${name}':
|
|
1756
|
+
return ${
|
|
1757
|
+
expoIcons.includes(name)
|
|
1758
|
+
? `require('@expo/vector-icons/${name}.js')?.default`
|
|
1759
|
+
: `require('@expo/vector-icons/FontAwesome.js')?.default;`
|
|
1760
|
+
};
|
|
1761
|
+
`;
|
|
1762
|
+
}
|
|
1763
|
+
});
|
|
1764
|
+
|
|
1765
|
+
content += `
|
|
1766
|
+
default:
|
|
1767
|
+
console.warn('Sorry, the icon named "', icon, '" could not be found in "@react-icon/all-files" and "@app/icons". Please check again.');
|
|
1768
|
+
return require('@expo/vector-icons/FontAwesome.js')?.default;
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
export default function(icon) {
|
|
1772
|
+
return __variableDynamicIcon(icon);
|
|
1773
|
+
}
|
|
1774
|
+
`;
|
|
1775
|
+
const rootPath = process.cwd();
|
|
1776
|
+
const fileName = `selectiveIcons.js`;
|
|
1777
|
+
const newFilePath = path.join(rootPath, 'app', fileName);
|
|
1778
|
+
// Ensure the directory exists
|
|
1779
|
+
if (!fs.existsSync(path.dirname(newFilePath))) {
|
|
1780
|
+
fs.mkdirSync(path.dirname(newFilePath), { recursive: true });
|
|
1781
|
+
}
|
|
1782
|
+
fs.writeFileSync(newFilePath, content, 'utf8');
|
|
1365
1783
|
}
|
|
1366
1784
|
|
|
1367
1785
|
async #setLayoutAndGenerateNavigation() {
|
|
@@ -1372,83 +1790,155 @@ export class GenerateMobileNavigations {
|
|
|
1372
1790
|
const customTabBarPath = this.#customTabBarPath;
|
|
1373
1791
|
const customDrawerPath = this.#customDrawerPath;
|
|
1374
1792
|
const customHeaderPath = this.#customHeaderPath;
|
|
1793
|
+
const i18Options = this.#i18Options;
|
|
1375
1794
|
|
|
1376
|
-
const layoutSettings =
|
|
1795
|
+
const layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
|
|
1377
1796
|
const layoutConfigFileData = await this.#getLayoutConfig();
|
|
1378
1797
|
const layoutType = layoutSettings?.layout || 'bottom';
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1798
|
+
try {
|
|
1799
|
+
await this.#generateAppRoutesJson();
|
|
1800
|
+
await this.#generateSelectiveIconsFile({ appDirPath, modules });
|
|
1801
|
+
await this.#generateMainRoutes({
|
|
1802
|
+
appDirPath,
|
|
1803
|
+
i18Options,
|
|
1804
|
+
initialRouteName,
|
|
1805
|
+
});
|
|
1806
|
+
await this.#generateApp({
|
|
1807
|
+
appDirPath,
|
|
1808
|
+
i18Options,
|
|
1809
|
+
initialRouteName,
|
|
1810
|
+
});
|
|
1811
|
+
|
|
1812
|
+
await this.#generateStackNavigations({
|
|
1382
1813
|
appDirPath,
|
|
1383
1814
|
modules,
|
|
1384
1815
|
initialRouteName,
|
|
1816
|
+
unauthenticatedComponentPath,
|
|
1385
1817
|
});
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
}
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
}
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1818
|
+
|
|
1819
|
+
if (layoutType == 'side') {
|
|
1820
|
+
try {
|
|
1821
|
+
await this.#generateDrawerNavigations({
|
|
1822
|
+
appDirPath,
|
|
1823
|
+
modules,
|
|
1824
|
+
initialRouteName,
|
|
1825
|
+
unauthenticatedComponentPath,
|
|
1826
|
+
});
|
|
1827
|
+
await this.#generateAppNavigationFile({
|
|
1828
|
+
appDirPath,
|
|
1829
|
+
customTabBarPath,
|
|
1830
|
+
customDrawerPath,
|
|
1831
|
+
customHeaderPath,
|
|
1832
|
+
});
|
|
1833
|
+
} catch (error) {
|
|
1834
|
+
console.log('Error in generating side navigation', error);
|
|
1835
|
+
}
|
|
1836
|
+
} else if (layoutType == 'bottom' || layoutType == 'host-bottom') {
|
|
1837
|
+
try {
|
|
1838
|
+
await this.#generateBottomTabNavigations({
|
|
1839
|
+
appDirPath,
|
|
1840
|
+
modules,
|
|
1841
|
+
initialRouteName,
|
|
1842
|
+
unauthenticatedComponentPath,
|
|
1843
|
+
});
|
|
1844
|
+
await this.#generateAppNavigationFile({
|
|
1845
|
+
appDirPath,
|
|
1846
|
+
customTabBarPath,
|
|
1847
|
+
customDrawerPath,
|
|
1848
|
+
customHeaderPath,
|
|
1849
|
+
});
|
|
1850
|
+
} catch (error) {
|
|
1851
|
+
console.log('Error in generating bottom navigation', error);
|
|
1852
|
+
}
|
|
1853
|
+
} else {
|
|
1854
|
+
try {
|
|
1855
|
+
await this.#generateBottomTabDrawerNavigations({
|
|
1856
|
+
appDirPath,
|
|
1857
|
+
modules,
|
|
1858
|
+
initialRouteName,
|
|
1859
|
+
unauthenticatedComponentPath,
|
|
1860
|
+
});
|
|
1861
|
+
|
|
1862
|
+
await this.#generateAppNavigationFile({
|
|
1863
|
+
appDirPath,
|
|
1864
|
+
customTabBarPath,
|
|
1865
|
+
customDrawerPath,
|
|
1866
|
+
customHeaderPath,
|
|
1867
|
+
});
|
|
1868
|
+
} catch (error) {
|
|
1869
|
+
console.log('Error in generating drawer bottom navigation', error);
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
} catch (error) {
|
|
1873
|
+
console.log('Error generating app navigations', error);
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
|
|
1877
|
+
async #performCopyOperations() {
|
|
1878
|
+
const config = this.#configFileData;
|
|
1879
|
+
try {
|
|
1880
|
+
await performCopyOperations(config);
|
|
1881
|
+
await this.#setLayoutAndGenerateNavigation();
|
|
1882
|
+
} catch (error) {
|
|
1883
|
+
console.error('PerformCopyOperations error:', error);
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1887
|
+
async #deleteDirectoryRecursive(dirPath: any) {
|
|
1888
|
+
if (fs.existsSync(dirPath)) {
|
|
1889
|
+
const files = fs.readdirSync(dirPath);
|
|
1890
|
+
for (const file of files) {
|
|
1891
|
+
const curPath = path.join(dirPath, file);
|
|
1892
|
+
if (fs.lstatSync(curPath).isDirectory()) {
|
|
1893
|
+
// Recursively delete subdirectories
|
|
1894
|
+
await this.#deleteDirectoryRecursive(curPath);
|
|
1895
|
+
} else {
|
|
1896
|
+
// Delete files
|
|
1897
|
+
fs.unlinkSync(curPath);
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
// Delete the directory itself
|
|
1901
|
+
fs.rmdirSync(dirPath);
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1904
|
+
|
|
1905
|
+
async #createAppDirectory() {
|
|
1906
|
+
const appDir = this.#appDirPath;
|
|
1907
|
+
|
|
1908
|
+
try {
|
|
1909
|
+
// Check if the directory exists
|
|
1910
|
+
if (fs.existsSync(appDir)) {
|
|
1911
|
+
console.log('Directory exists. Recreating it...');
|
|
1912
|
+
// Delete the directory and its contents
|
|
1913
|
+
await this.#deleteDirectoryRecursive(appDir);
|
|
1914
|
+
}
|
|
1915
|
+
|
|
1916
|
+
// Create the directory
|
|
1917
|
+
fs.mkdirSync(appDir);
|
|
1918
|
+
console.log('Directory created');
|
|
1919
|
+
// Add 'app' to .gitignore if not already present
|
|
1920
|
+
const gitignorePath = path.resolve(appDir, '.gitignore');
|
|
1921
|
+
let gitignoreContent = '';
|
|
1922
|
+
if (fs.existsSync(gitignorePath)) {
|
|
1923
|
+
gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
|
|
1924
|
+
} else {
|
|
1925
|
+
fs.writeFileSync(gitignorePath, '');
|
|
1926
|
+
console.log('Created .gitignore file');
|
|
1927
|
+
}
|
|
1928
|
+
|
|
1929
|
+
if (!gitignoreContent.includes('*')) {
|
|
1930
|
+
fs.appendFileSync(gitignorePath, '*\n');
|
|
1931
|
+
console.log('Added "*" to .gitignore');
|
|
1932
|
+
}
|
|
1933
|
+
await this.#performCopyOperations();
|
|
1934
|
+
} catch (error) {
|
|
1935
|
+
console.error('Error creating app directory:', error);
|
|
1936
|
+
}
|
|
1449
1937
|
}
|
|
1450
1938
|
|
|
1451
1939
|
async generateAppNavigations() {
|
|
1452
|
-
return this.#
|
|
1940
|
+
return this.#createAppDirectory();
|
|
1453
1941
|
}
|
|
1454
1942
|
}
|
|
1943
|
+
|
|
1944
|
+
export default GenerateMobileNavigations;
|