Skip to content

Commit

Permalink
refactor: start of work
Browse files Browse the repository at this point in the history
  • Loading branch information
lme-axelor committed Sep 6, 2024
1 parent cc82c7e commit be4da2b
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 139 deletions.
22 changes: 14 additions & 8 deletions packages/core/src/app/Application.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import React, {useEffect, useRef} from 'react';
import React, {useEffect, useMemo, useRef} from 'react';
import {
Theme,
ThemeColors,
Expand Down Expand Up @@ -78,19 +78,24 @@ const Application = ({
}: ApplicationProps) => {
const modules: Module[] = useRef([authModule, ...modulesProvided]).current;

RouterProvider.enableRetrocompatibilityWithAOSv6(
configuration?.retrocompatibilityAOS6,
);

RouterProvider.addRoutes(configuration?.additionalRoutes);
RouterProvider.init({
retrocompatibility: configuration?.retrocompatibilityAOS6,
routesDefinition: configuration?.additionalRoutes,
});

ApiProviderConfig.allowConnectionBlock =
configuration.allowInternetConnectionBlock;

useEffect(() => {
modulesProvider.init(modules);
const moduleRegisters = useMemo(() => {
return modules
.filter(_module => _module.moduleRegister)
.flatMap(_module => _module.moduleRegister);
}, [modules]);

useEffect(() => {
modulesProvider.init(modules, moduleRegisters);
}, [modules, moduleRegisters]);

useEffect(() => {
sessionStorage.init(
configuration?.isDemoSession,
Expand All @@ -100,6 +105,7 @@ const Application = ({

return (
<ContextsProvider
modules={modules}
additionalsReducers={additionalsReducers}
defaultTheme={defaultTheme}
themes={themes}
Expand Down
144 changes: 45 additions & 99 deletions packages/core/src/app/ContextsProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import React, {createContext, useEffect, useMemo, useState} from 'react';
import React, {useEffect, useMemo, useState} from 'react';
import {Provider} from 'react-redux';
import {
ConfigProvider,
Expand All @@ -28,24 +28,16 @@ import {
ThemeColors,
WritingStyles,
} from '@axelor/aos-mobile-ui';
import {Models, useModules} from './modules';
import {configI18n} from '../i18n/i18n';
import enTranslation from '../i18n/translations/en.json';
import frTranslation from '../i18n/translations/fr.json';
import {configGlobalStore} from '../redux/store';
import {useBackgroundFunction} from '../hooks/use-background-function';
import {addModuleModels} from './context.helper';
import {objectFieldsProvider} from '../apiProviders';
import {requestBuilder} from '../apiProviders/Standard/requests.helper';
import {core_modelAPI, core_searchFields, core_sortFields} from '../models';
import {HeaderBandProvider} from '../header';
import {addModuleForms, formConfigsProvider} from '../forms';
import {initSelections} from '../selections';
import {processProvider} from '../loader';

const ApplicationContext = createContext(null);
import {Module} from './modules';

interface ContextsProviderProps {
modules: Module[];
additionalsReducers?: any;
themes?: Theme[];
defaultTheme?: Theme;
Expand All @@ -60,6 +52,7 @@ interface ContextsProviderProps {
}

const ContextsProvider = ({
modules: _staticModules,
additionalsReducers,
themes,
defaultTheme,
Expand All @@ -72,121 +65,74 @@ const ContextsProvider = ({
writingStylesConfig,
showModulesSubtitle = false,
}: ContextsProviderProps) => {
const {modules} = useModules();

const [loading, setLoading] = useState(true);
const [moduleLoaded, setModuleLoaded] = useState(0);

const appTranslations = useMemo(
() =>
modules
.filter(_module => _module.translations)
.reduce(
(translations, _module) => {
setModuleLoaded(_current => _current + 1);
return {
en: {...translations.en, ..._module.translations?.en},
fr: {...translations.fr, ..._module.translations?.fr},
};
},
{en: enTranslation, fr: frTranslation},
),
[modules],
);

useEffect(() => {
if (moduleLoaded === modules?.length) {
configI18n({
resources: [
{lng: 'en', translationsObject: appTranslations.en},
{lng: 'fr', translationsObject: appTranslations.fr},
],
defaultLanguage: defaultLanguage,
});
setLoading(false);
}
const appTranslations = _staticModules
.filter(_module => _module.translations)
.reduce(
(translations, _module) => {
return {
en: {...translations.en, ..._module.translations?.en},
fr: {...translations.fr, ..._module.translations?.fr},
};
},
{en: enTranslation, fr: frTranslation},
);

configI18n({
resources: [
{lng: 'en', translationsObject: appTranslations.en},
{lng: 'fr', translationsObject: appTranslations.fr},
],
defaultLanguage: defaultLanguage,
});
setLoading(false);
// NOTE: I18n should be initialize only once
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [moduleLoaded, modules]);
}, []);

const externalsReducers = useMemo(
() =>
modules
_staticModules
.filter(_module => _module.reducers)
.reduce((reducers, _module) => ({...reducers, ..._module.reducers}), {
...additionalsReducers,
}),
[additionalsReducers, modules],
[additionalsReducers, _staticModules],
);

const modulesBackgroundFunctions = useMemo(() => {
const backgroundFunctions = modules
.filter(_module => _module.backgroundFunctions)
.flatMap(_module => _module.backgroundFunctions);

backgroundFunctions.push(processProvider.removeOldProcesses);

return backgroundFunctions;
}, [modules]);

const store = useMemo(
() => configGlobalStore(externalsReducers),
[externalsReducers],
);

useBackgroundFunction(modulesBackgroundFunctions);

const modulesObjectFields: Models = useMemo(
() =>
modules
.filter(_module => _module.models)
.reduce(addModuleModels, {
objectFields: {...core_modelAPI},
sortFields: {...core_sortFields},
searchFields: {...core_searchFields},
typeObjects: [],
}),
[modules],
);

const modulesFormsRegisters = useMemo(() => {
return modules
.filter(_module => _module.models?.formsRegister)
.map(_module => _module.models.formsRegister)
.reduce((forms, _moduleForms) => addModuleForms(forms, _moduleForms), {});
}, [modules]);

useEffect(() => {
objectFieldsProvider.init(modulesObjectFields);
initSelections(modulesObjectFields.typeObjects);
requestBuilder.init(defaultRequestLimit);
formConfigsProvider.init(modulesFormsRegisters);
}, [defaultRequestLimit, modulesObjectFields, modulesFormsRegisters]);
}, [defaultRequestLimit]);

if (loading) {
return null;
}

return (
<ApplicationContext.Provider value={{}}>
<Provider store={store} identityFunctionCheck="never">
<OutsideAlerterProvider>
<ThemeProvider
themes={themes}
defaultTheme={defaultTheme}
themeColorsConfig={themeColorsConfig}>
<WritingThemeProvider
themes={writingThemes}
defaultTheme={defaultWritingTheme}
writingStylesConfig={writingStylesConfig}>
<ConfigProvider showModulesSubtitle={showModulesSubtitle}>
<HeaderBandProvider>{children}</HeaderBandProvider>
</ConfigProvider>
</WritingThemeProvider>
</ThemeProvider>
</OutsideAlerterProvider>
</Provider>
</ApplicationContext.Provider>
<Provider store={store} identityFunctionCheck="never">
<OutsideAlerterProvider>
<ThemeProvider
themes={themes}
defaultTheme={defaultTheme}
themeColorsConfig={themeColorsConfig}>
<WritingThemeProvider
themes={writingThemes}
defaultTheme={defaultWritingTheme}
writingStylesConfig={writingStylesConfig}>
<ConfigProvider showModulesSubtitle={showModulesSubtitle}>
<HeaderBandProvider>{children}</HeaderBandProvider>
</ConfigProvider>
</WritingThemeProvider>
</ThemeProvider>
</OutsideAlerterProvider>
</Provider>
);
};

Expand Down
13 changes: 1 addition & 12 deletions packages/core/src/app/RootNavigator.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,23 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import React, {useCallback, useEffect, useMemo, useRef} from 'react';
import React, {useCallback, useEffect, useRef} from 'react';
import {useDispatch, useSelector} from 'react-redux';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {useThemeColor} from '@axelor/aos-mobile-ui';
import {default as CoreNavigator} from '../navigator/Navigator';
import {getNetInfo, getTokenInfo} from '../api/net-info-utils';
import {useHeaderRegisters} from '../hooks/use-header-registers';
import LoginScreen from '../screens/LoginScreen';
import SessionManagementScreen from '../screens/SessionManagementScreen';
import {useHeaderBand} from '../header';
import {useTranslator} from '../i18n';
import {showToastMessage} from '../utils';
import {logout} from '../features/authSlice';
import {useSessionExpired} from '../apiProviders/config';
import {useModules} from './modules';

const {Navigator, Screen} = createNativeStackNavigator();

const RootNavigator = ({mainMenu, onRefresh, configuration}) => {
const {modules} = useModules();
const Colors = useThemeColor();
const I18n = useTranslator();
const dispatch = useDispatch();
Expand All @@ -48,14 +45,6 @@ const RootNavigator = ({mainMenu, onRefresh, configuration}) => {

const {logged} = useSelector(state => state.auth);

const modulesHeaderRegisters = useMemo(() => {
return modules
.filter(_module => _module.models?.headerRegisters)
.map(_module => _module.models.headerRegisters);
}, [modules]);

useHeaderRegisters(modulesHeaderRegisters);

const AppNavigator = useCallback(
() => (
<CoreNavigator
Expand Down
42 changes: 27 additions & 15 deletions packages/core/src/app/modules/ModuleProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,23 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import {useEffect, useMemo, useState} from 'react';
import {useCallback, useEffect, useMemo, useState} from 'react';
import {Module} from './types';

class ModuleProvider {
private modules: Module[];
private moduleRegisters: Function[];
private refreshCallBack: Function[];

constructor() {
this.modules = [];
this.moduleRegisters = [];
this.refreshCallBack = [];
}

init(_modules: Module[]) {
init(_modules: Module[], _moduleRegisters: Function[]) {
this.modules = _modules ?? [];
this.moduleRegisters = _moduleRegisters ?? [];
this.updateState();
}

Expand All @@ -44,23 +47,27 @@ class ModuleProvider {
registerModule(_module: Module) {
if (this.modules.find(({name}) => name === _module.name) == null) {
this.modules = [...this.modules, _module];
} else {
this.modules = this.modules.map(_m => {
if (_m.name === _module.name) {
return _module;
} else {
return _m;
}
});
this.updateState();
}

this.updateState();
// } else {
// this.modules = this.modules.map(_m => {
// if (_m.name === _module.name) {
// return _module;
// } else {
// return _m;
// }
// });
// }
}

getModules() {
return this.modules;
}

getModuleRegisters(): Function[] {
return this.moduleRegisters;
}

private updateState() {
this.refreshCallBack.forEach(_f => _f(this.modules));
}
Expand All @@ -76,13 +83,18 @@ export const useModules = (): {
modulesProvider.getModules(),
);

const refreshData = useCallback(
(data: Module[]) => setModules([...data]),
[],
);

useEffect(() => {
modulesProvider.registerCallback(data => setModules([...data]));
modulesProvider.registerCallback(refreshData);

return () => {
modulesProvider.unregisterCallback(setModules);
modulesProvider.unregisterCallback(refreshData);
};
}, []);
}, [refreshData]);

return useMemo(
() => ({
Expand Down
Loading

0 comments on commit be4da2b

Please sign in to comment.