src/app/main.ts   A
last analyzed

Complexity

Total Complexity 13
Complexity/F 0

Size

Lines of Code 187
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 13
eloc 112
mnd 13
bc 13
fnc 0
dl 0
loc 187
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
ccs 47
cts 47
cp 1
rs 10
1 1
import {
2
  Config,
3
  initStore,
4
  initi18n,
5
  requestRoute,
6
} from "@cianciarusocataldo/modular-engine";
7
8 1
import {
9
  defaultTheme,
10
  defaultAppConfig,
11
  defaultEngineConfig,
12
} from "./constants/default-configs";
13 1
import { uiProperties } from "./constants/ui-properties";
14
15
import { AppConfig, Init, Theme } from "./types";
16
17 1
import { addStyle, printDev } from "./utils";
18
19
/**
20
 * Init the modular main application, with given configs. If some configs are not given, will look for default config files:
21
 * - `app.config.js` for app setup
22
 * - `engine.config.js` for engine (state and localization) setup
23
 * - `theme.config.json` for app custom theme
24
 *
25
 * If these files are not present in the same folder where this function is called, default internal configs will be used instead.
26
 * Use the `onComplete` callback to render the final app component.
27
 *
28
 * @param {AppConfig} appConfig
29
 * @param {Config} engine engine config (to setup internal redux store and i18n system)
30
 * @param {(App: JSX.Element) => any} onComplete custom callback called at the end of the init process. Receives as input parameter the final application component, already configured
31
 * @param {()=>any} onStart custom callback called at the start of the init process, before any other action.
32
 * @param {Theme} theme app custom theme
33
 *
34
 * @author Cataldo Cianciaruso <https://github.com/CianciarusoCataldo>
35
 *
36
 * @copyright 2022 Cataldo Cianciaruso
37
 */
38 1
export const initApplication: Init = ({
39 3
  appConfig: inputAppConfig,
40 3
  engine: inputEngineConfig,
41 3
  onComplete,
42 3
  onStart,
43 3
  theme: inputTheme,
44
}) => {
45 3
  let theme: Theme = defaultTheme;
46 3
  let config: AppConfig = defaultAppConfig;
47 3
  let engineConfig: Config = defaultEngineConfig;
48
49 3
  onStart && onStart();
50
51 3
  if (inputTheme) {
52 2
    theme = inputTheme;
53
  } else {
54 1
    try {
55
      /*istanbul ignore next */
56
      theme = require("theme.config.json");
57
    } catch (e) {
58 1
      printDev("theme.config file not found, using default theme");
59
60 1
      theme = defaultTheme;
61
    }
62
  }
63
64 3
  const uiTheme = theme.ui || {};
65 3
  let uiStyle = "";
66 3
  if (uiTheme.dark) {
67 1
    if (uiTheme.default.background) {
68 1
      uiStyle += `${uiProperties.default.background}: ${uiTheme.default.background}; `;
69
    }
70 1
    if (uiTheme.dark.background) {
71 1
      uiStyle += `${uiProperties.dark.background}: ${uiTheme.dark.background}; `;
72
    }
73
  }
74
75 3
  const bodyTheme = theme.body || defaultTheme.body;
76
77 3
  let customStyle: string = `
78
  * {
79
    ${uiStyle}
80
  }
81
82
  body.light { background: ${
83
    bodyTheme.default || defaultTheme.body.default
84
  }; } body.dark { background: ${bodyTheme.dark || defaultTheme.body.dark}; }
85
  /* Works on Firefox */
86
* {
87
  scrollbar-width: thin;
88
  scrollbar-color: #c0c0c0;
89
}
90
91
/* Works on Chrome, Edge, and Safari */
92
*::-webkit-scrollbar {
93
  width: 12px;
94
}
95
96
*::-webkit-scrollbar-track {
97
  background: linear-gradient(to right, #2d3748, #1d232e);
98
}
99
100
*::-webkit-scrollbar-thumb {
101
  background-color: #c0c0c0;
102
  border-radius: 20px;
103
  border: 3px solid #c0c0c0;
104
}
105
`;
106
107 3
  addStyle(customStyle);
108
109 3
  if (inputEngineConfig) {
110 2
    engineConfig = inputEngineConfig;
111
  } else {
112 1
    try {
113
      /*istanbul ignore next */
114
      engineConfig = require("engine.config").default;
115
    } catch (e) {
116 1
      printDev("engine.config file not found, using default engine config");
117 1
      engineConfig = defaultEngineConfig;
118
    }
119
  }
120
121 3
  window.document.body.classList.add(
122
    engineConfig.redux.darkMode ? "dark" : "light"
123
  );
124
125 3
  initi18n(engineConfig);
126
127 3
  const { store, history } = initStore({
128
    config: engineConfig,
129
  });
130
131 3
  let initialRoute: string | null = null;
132
133 3
  return import("./components/MainApp").then(({ default: MainApp }) => {
134 3
    if (inputAppConfig) {
135 2
      config = inputAppConfig;
136
    } else {
137 1
      try {
138
        /*istanbul ignore next */
139
        config = require("app.config").default;
140
      } catch (e) {
141 1
        printDev("app.config file not found, using default app config");
142 1
        config = defaultAppConfig;
143
      }
144
    }
145
146 3
    const App = MainApp({
147
      store,
148
      history,
149
      config,
150
      engine: engineConfig.redux,
151
      theme,
152
    });
153
154 3
    onComplete && onComplete(App);
155
156
    /*istanbul ignore next */
157
    if (config.useQueryParams) {
158
      if (window.location.search) {
159
        const urlParams = new URLSearchParams(window.location.search);
160
        initialRoute = urlParams.get("to");
161
162
        if (
163
          initialRoute &&
164
          Object.values(store.getState().config.router.pages).includes(
165
            initialRoute
166
          )
167
        ) {
168
          store.dispatch(
169
            requestRoute(store.getState().config.router.basename + initialRoute)
170
          );
171
        } else {
172
          store.dispatch(
173
            requestRoute(
174
              store.getState().config.router.basename +
175
                store.getState().config.router.homePage
176
            )
177
          );
178
        }
179
      }
180
    }
181
182 3
    return {
183
      App,
184
    };
185
  });
186
};
187