@asaleh37/ui-base 25.8.31 → 25.9.3-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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asaleh37/ui-base",
3
- "version": "25.8.31",
3
+ "version": "25.9.3-1",
4
4
  "description": "",
5
5
  "license": "ISC",
6
6
  "author": "Ahmed Saleh Mohamed",
@@ -113,7 +113,9 @@
113
113
  "stylis-plugin-rtl": "^2.1.1",
114
114
  "zod": "^3.24.2"
115
115
  },
116
- "dependencies": {
116
+ "dependencies": {
117
+ "@azure/msal-browser": "^4.21.1",
118
+ "@azure/msal-react": "^3.0.19",
117
119
  "@rollup/plugin-json": "^6.1.0",
118
120
  "rollup-plugin-terser": "^7.0.2"
119
121
  }
package/public/bg.jpg ADDED
Binary file
@@ -13,9 +13,18 @@ import {
13
13
  } from "../util";
14
14
  import { setStoresMetaData } from "../redux/features/common/CommonStoreSlice";
15
15
  import { ADMINISTRATION_STORES } from "../redux/features/administration/AdministrationStoresMetaData";
16
+ import { PublicClientApplication } from "@azure/msal-browser";
17
+ import { MsalProvider } from "@azure/msal-react";
16
18
 
17
19
  const App: React.FC<AppInfo> = (props: AppInfo) => {
18
20
  const dispatch = useDispatch();
21
+ const msalInstance = new PublicClientApplication({
22
+ auth: {
23
+ clientId: props?.azureConfiguration?.frontEndClientId,
24
+ authority: `https://login.microsoftonline.com/${props?.azureConfiguration?.tenantId}`,
25
+ redirectUri: props?.azureConfiguration?.redirectURL,
26
+ },
27
+ });
19
28
  LicenseInfo.setLicenseKey(props.muiPremiumKey);
20
29
  const LightThemeOptions: ThemeOptions = {
21
30
  components: {
@@ -115,7 +124,13 @@ const App: React.FC<AppInfo> = (props: AppInfo) => {
115
124
  }, [props]);
116
125
  return (
117
126
  <ThemeProvider theme={theme}>
118
- <Layout />
127
+ {props?.authenticationMethod === "AZURE" ? (
128
+ <MsalProvider instance={msalInstance}>
129
+ <Layout msalInstance={msalInstance} />
130
+ </MsalProvider>
131
+ ) : (
132
+ <Layout msalInstance={msalInstance} />
133
+ )}
119
134
  </ThemeProvider>
120
135
  );
121
136
  };
@@ -0,0 +1,222 @@
1
+ import { PublicClientApplication } from "@azure/msal-browser";
2
+ import {
3
+ Box,
4
+ Button,
5
+ CircularProgress,
6
+ createTheme,
7
+ Paper,
8
+ Typography,
9
+ } from "@mui/material";
10
+ import { useDispatch, useSelector } from "react-redux";
11
+ import { AppInfo } from "../../redux/features/common/AppInfoSlice";
12
+ import { useAxios } from "../../hooks";
13
+ import { UserSessionActions } from "../../redux/features/common/UserSessionSlice";
14
+ import { useEffect, useState } from "react";
15
+
16
+ import { ThemeProvider } from "@emotion/react";
17
+ import {
18
+ DARK_THEME_INITIAL_MAIN_COLOR,
19
+ DARK_THEME_INITIAL_SECANDARY_COLOR,
20
+ LIGHT_THEME_INITIAL_MAIN_COLOR,
21
+ LIGHT_THEME_INITIAL_SECANDARY_COLOR,
22
+ } from "../../util";
23
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
24
+ interface AzureLoginProps {
25
+ msalInstance: PublicClientApplication;
26
+ }
27
+
28
+ const AzureLogin: React.FC<AzureLoginProps> = ({ msalInstance }) => {
29
+ const appInfo: AppInfo = useSelector((state: any) => state.AppInfo.value);
30
+ const userSession = useSelector((state: any) => state.UserSession.value);
31
+ const [isLoginInProcess, setIsLoginInProcess] = useState(false);
32
+ const { handleGetRequest } = useAxios();
33
+ const dispatch = useDispatch();
34
+ const checkUserSession = async () => {
35
+ if (localStorage.getItem("TOKEN")) {
36
+ if (appInfo?.apiBaseUrl) {
37
+ handleGetRequest({
38
+ endPointURI: "api/auth/userInfo",
39
+ showMask: true,
40
+ successCallBkFn: (response) => {
41
+ setIsLoginInProcess(false);
42
+ if (response != null && response.data != null) {
43
+ const UserSession = {
44
+ ...response.data,
45
+ isAuthenticated: true,
46
+ };
47
+ dispatch(UserSessionActions.setAuthenticated(UserSession));
48
+ } else {
49
+ dispatch(UserSessionActions.setUnAuthenticated());
50
+ localStorage.removeItem("TOKEN");
51
+ }
52
+ },
53
+ failureCallBkFn: () => {
54
+ setIsLoginInProcess(false);
55
+ },
56
+ });
57
+ }
58
+ } else {
59
+ dispatch(UserSessionActions.setUnAuthenticated());
60
+ setIsLoginInProcess(false);
61
+ }
62
+ };
63
+ const handleLogin = async () => {
64
+ setIsLoginInProcess(true);
65
+ const response = await msalInstance.acquireTokenPopup({
66
+ scopes: appInfo?.azureConfiguration?.scopes,
67
+ });
68
+ if (response?.accessToken) {
69
+ localStorage.setItem("TOKEN", response.accessToken);
70
+ checkUserSession();
71
+ } else {
72
+ setIsLoginInProcess(false);
73
+ }
74
+ };
75
+ const UserSessionState = useSelector((state: any) => state.UserSession.value);
76
+
77
+ useEffect(() => {
78
+ checkUserSession();
79
+ }, [appInfo]);
80
+
81
+ const loginTheme = createTheme({
82
+ components: {
83
+ MuiCssBaseline: {
84
+ styleOverrides: `
85
+ /* Custom Scrollbar */
86
+ * {
87
+ scrollbar-width: thin;
88
+ scrollbar-color: ${
89
+ appInfo.appTheme?.dark?.primaryColor ||
90
+ DARK_THEME_INITIAL_MAIN_COLOR
91
+ } #121212;
92
+ }
93
+
94
+ /* Webkit Browsers */
95
+ *::-webkit-scrollbar {
96
+ width: 12px;
97
+ height: 10px;
98
+ }
99
+ `,
100
+ },
101
+ },
102
+ palette: {
103
+ mode: appInfo?.loginScreenStyle?.themeMode || "dark",
104
+ primary: {
105
+ main:
106
+ appInfo?.loginScreenStyle?.themeMode === "light"
107
+ ? appInfo.appTheme?.light?.primaryColor ||
108
+ LIGHT_THEME_INITIAL_MAIN_COLOR
109
+ : appInfo.appTheme?.dark?.primaryColor ||
110
+ DARK_THEME_INITIAL_MAIN_COLOR,
111
+ },
112
+ secondary: {
113
+ main:
114
+ appInfo?.loginScreenStyle?.themeMode === "light"
115
+ ? appInfo.appTheme?.light?.secondaryColor ||
116
+ LIGHT_THEME_INITIAL_SECANDARY_COLOR
117
+ : appInfo.appTheme?.dark?.secondaryColor ||
118
+ DARK_THEME_INITIAL_SECANDARY_COLOR,
119
+ },
120
+ },
121
+ });
122
+ return (
123
+ <ThemeProvider theme={loginTheme}>
124
+ {UserSessionState.isAuthenticated == false ? (
125
+ <Box
126
+ sx={{
127
+ // position: "relative",
128
+ display: "flex",
129
+ alignItems: "center",
130
+ justifyContent: "center",
131
+ minHeight: "100vh",
132
+ width: "100%",
133
+ backgroundImage: "url('/bg.jpg')",
134
+ backgroundRepeat: "no-repeat",
135
+ backgroundSize: "cover",
136
+ backgroundPosition: "center",
137
+ "&::before": {
138
+ content: '""',
139
+ position: "absolute",
140
+ top: 0,
141
+ left: 0,
142
+ right: 0,
143
+ bottom: 0,
144
+ backgroundColor: "rgba(0, 0, 0, 0.4)", // 👈 controls opacity
145
+ zIndex: 0,
146
+ },
147
+ }}
148
+ >
149
+ <Paper
150
+ sx={{
151
+ display: "flex",
152
+ width: "fit-content",
153
+ padding: 2,
154
+ height: "fit-content",
155
+ borderRadius: 5,
156
+ alignItems: "center",
157
+ justifyContent: "center",
158
+ textAlign: "center",
159
+ zIndex: 1,
160
+ p: 4,
161
+ }}
162
+ >
163
+ <Box
164
+ sx={{
165
+ display: "flex",
166
+ flexDirection: "column",
167
+ alignItems: "center",
168
+ justifyContent: "center",
169
+ }}
170
+ >
171
+ <img src={appInfo?.appLogo} width={150} height={150} />
172
+ <Typography sx={{ m: 1 }} variant="h4" color="textSecondary">
173
+ {appInfo?.appName}
174
+ </Typography>
175
+ <Typography
176
+ sx={{
177
+ paddingRight: 1,
178
+ width: "100%",
179
+ textAlign: "right",
180
+ fontSize: 10,
181
+ }}
182
+ variant="caption"
183
+ color="textSecondary"
184
+ >
185
+ V.{appInfo.appVersion}
186
+ </Typography>
187
+ <Button
188
+ loading={isLoginInProcess}
189
+ onClick={handleLogin}
190
+ variant="contained"
191
+ color="primary"
192
+ sx={{ m: 1 }}
193
+ startIcon={
194
+ <FontAwesomeIcon
195
+ icon={{ iconName: "microsoft", prefix: "fab" }}
196
+ />
197
+ }
198
+ >
199
+ login
200
+ </Button>
201
+ </Box>
202
+ </Paper>
203
+ </Box>
204
+ ) : (
205
+ <Paper
206
+ sx={{
207
+ width: "100%",
208
+ height: "100vh",
209
+ display: "flex",
210
+ alignItems: "center",
211
+ justifyContent: "center",
212
+ }}
213
+ >
214
+ <CircularProgress sx={{ marginRight: 1 }} />
215
+ <div>You will be redirected shortly ... please wait</div>
216
+ </Paper>
217
+ )}
218
+ </ThemeProvider>
219
+ );
220
+ };
221
+
222
+ export default AzureLogin;
@@ -16,10 +16,13 @@ import { UserSessionActions } from "../../redux/features/common/UserSessionSlice
16
16
  import {
17
17
  DARK_THEME_INITIAL_MAIN_COLOR,
18
18
  DARK_THEME_INITIAL_SECANDARY_COLOR,
19
+ LIGHT_THEME_INITIAL_MAIN_COLOR,
20
+ LIGHT_THEME_INITIAL_SECANDARY_COLOR,
19
21
  } from "../../util";
22
+ import { AppInfo } from "../../redux/features/common/AppInfoSlice";
20
23
 
21
24
  const Login: React.FC = () => {
22
- const appInfo = useSelector((state: any) => state.AppInfo.value);
25
+ const appInfo: AppInfo = useSelector((state: any) => state.AppInfo.value);
23
26
  const [username, setUsername] = useState("");
24
27
  const [password, setPassword] = useState("");
25
28
  const [isLoginInProcess, setIsLoginInProcess] = useState(false);
@@ -89,15 +92,22 @@ const Login: React.FC = () => {
89
92
  },
90
93
  },
91
94
  palette: {
92
- mode: "dark",
95
+ mode: appInfo?.loginScreenStyle?.themeMode || "dark",
93
96
  primary: {
94
97
  main:
95
- appInfo.appTheme?.dark?.primaryColor || DARK_THEME_INITIAL_MAIN_COLOR,
98
+ appInfo?.loginScreenStyle?.themeMode === "light"
99
+ ? appInfo.appTheme?.light?.primaryColor ||
100
+ LIGHT_THEME_INITIAL_MAIN_COLOR
101
+ : appInfo.appTheme?.dark?.primaryColor ||
102
+ DARK_THEME_INITIAL_MAIN_COLOR,
96
103
  },
97
104
  secondary: {
98
105
  main:
99
- appInfo.appTheme?.dark?.secondaryColor ||
100
- DARK_THEME_INITIAL_SECANDARY_COLOR,
106
+ appInfo?.loginScreenStyle?.themeMode === "light"
107
+ ? appInfo.appTheme?.light?.secondaryColor ||
108
+ LIGHT_THEME_INITIAL_SECANDARY_COLOR
109
+ : appInfo.appTheme?.dark?.secondaryColor ||
110
+ DARK_THEME_INITIAL_SECANDARY_COLOR,
101
111
  },
102
112
  },
103
113
  });
@@ -121,6 +131,7 @@ const Login: React.FC = () => {
121
131
  dispatch(UserSessionActions.setAuthenticated(UserSession));
122
132
  } else {
123
133
  dispatch(UserSessionActions.setUnAuthenticated());
134
+ localStorage.removeItem("TOKEN");
124
135
  }
125
136
  } catch (error) {
126
137
  dispatch(UserSessionActions.setUnAuthenticated());
@@ -129,92 +140,127 @@ const Login: React.FC = () => {
129
140
  }
130
141
  };
131
142
  useEffect(() => {
132
- console.log("checking usersession on reload", userSession);
133
- console.log("checking usersession app info", appInfo);
134
143
  checkUserSession();
135
144
  }, [appInfo, userSession.isAuthenticated]);
136
145
 
137
146
  return (
138
147
  <ThemeProvider theme={loginTheme}>
139
- <Paper
140
- sx={{
141
- display: "flex",
142
- height: "100vh",
143
- width: "100%",
144
- borderRadius: 0,
145
- alignItems: "center",
146
- justifyContent: "center",
147
- }}
148
- >
149
- {UserSessionState.isAuthenticated == false ? (
150
- <Box
148
+ {UserSessionState.isAuthenticated == false ? (
149
+ <Box
150
+ sx={{
151
+ // position: "relative",
152
+ display: "flex",
153
+ alignItems: "center",
154
+ justifyContent: "center",
155
+ minHeight: "100vh",
156
+ width: "100%",
157
+ backgroundImage: "url('/bg.jpg')",
158
+ backgroundRepeat: "no-repeat",
159
+ backgroundSize: "cover",
160
+ backgroundPosition: "center",
161
+ "&::before": {
162
+ content: '""',
163
+ position: "absolute",
164
+ top: 0,
165
+ left: 0,
166
+ right: 0,
167
+ bottom: 0,
168
+ backgroundColor: "rgba(0, 0, 0, 0.4)", // 👈 controls opacity
169
+ zIndex: 0,
170
+ },
171
+ }}
172
+ >
173
+ <Paper
151
174
  sx={{
152
175
  display: "flex",
153
- flexDirection: "column",
176
+ width: "fit-content",
177
+ padding: 2,
178
+ height: "fit-content",
179
+ borderRadius: 5,
154
180
  alignItems: "center",
155
181
  justifyContent: "center",
182
+ textAlign: "center",
183
+ zIndex: 1,
184
+ p: 4,
156
185
  }}
157
186
  >
158
- <img src={appInfo?.appLogo} width={150} height={150} />
159
- <Typography sx={{ m: 1 }} variant="h4" color="textSecondary">
160
- {appInfo?.appName}
161
- </Typography>
162
- <Typography
187
+ <Box
163
188
  sx={{
164
- paddingRight: 1,
165
- width: "100%",
166
- textAlign: "right",
167
- fontSize: 10,
189
+ display: "flex",
190
+ flexDirection: "column",
191
+ alignItems: "center",
192
+ justifyContent: "center",
168
193
  }}
169
- variant="caption"
170
- color="textSecondary"
171
194
  >
172
- V.{appInfo.appVersion}
173
- </Typography>
174
- <TextField
175
- label="username"
176
- sx={{ width: 300, m: 1 }}
177
- value={username}
178
- onChange={(event) => {
179
- setUsername(event.target.value);
180
- }}
181
- onKeyDown={(event) => {
182
- if (event.key === "Enter") {
183
- handleLogin();
184
- }
185
- }}
186
- />
187
- <TextField
188
- label="password"
189
- sx={{ width: 300, m: 1 }}
190
- value={password}
191
- type="password"
192
- onChange={(event) => {
193
- setPassword(event.target.value);
194
- }}
195
- onKeyDown={(event) => {
196
- if (event.key === "Enter") {
197
- handleLogin();
198
- }
199
- }}
200
- />
201
- <Button
202
- loading={isLoginInProcess}
203
- onClick={handleLogin}
204
- variant="contained"
205
- color="primary"
206
- sx={{ m: 1 }}
207
- >
208
- login
209
- </Button>
210
- </Box>
211
- ) : (
212
- <>
213
- <CircularProgress sx={{ marginRight: 1 }} />
214
- <div>You will be redirected shortly ... please wait</div>
215
- </>
216
- )}
217
- </Paper>
195
+ <img src={appInfo?.appLogo} width={150} height={150} />
196
+ <Typography sx={{ m: 1 }} variant="h4" color="textSecondary">
197
+ {appInfo?.appName}
198
+ </Typography>
199
+ <Typography
200
+ sx={{
201
+ paddingRight: 1,
202
+ width: "100%",
203
+ textAlign: "right",
204
+ fontSize: 10,
205
+ }}
206
+ variant="caption"
207
+ color="textSecondary"
208
+ >
209
+ V.{appInfo.appVersion}
210
+ </Typography>
211
+ <TextField
212
+ label="username"
213
+ sx={{ width: 300, m: 1 }}
214
+ value={username}
215
+ onChange={(event) => {
216
+ setUsername(event.target.value);
217
+ }}
218
+ onKeyDown={(event) => {
219
+ if (event.key === "Enter") {
220
+ handleLogin();
221
+ }
222
+ }}
223
+ />
224
+ <TextField
225
+ label="password"
226
+ sx={{ width: 300, m: 1 }}
227
+ value={password}
228
+ type="password"
229
+ onChange={(event) => {
230
+ setPassword(event.target.value);
231
+ }}
232
+ onKeyDown={(event) => {
233
+ if (event.key === "Enter") {
234
+ handleLogin();
235
+ }
236
+ }}
237
+ />
238
+ <Button
239
+ loading={isLoginInProcess}
240
+ onClick={handleLogin}
241
+ variant="contained"
242
+ color="primary"
243
+ sx={{ m: 1 }}
244
+ >
245
+ login
246
+ </Button>
247
+ </Box>
248
+ </Paper>
249
+ </Box>
250
+ ) : (
251
+ <Paper
252
+ sx={{
253
+ width: "100%",
254
+ height: "100vh",
255
+ display: "flex",
256
+ alignItems: "center",
257
+ justifyContent: "center",
258
+ }}
259
+ >
260
+ <CircularProgress sx={{ marginRight: 1 }} />
261
+ <div>You will be redirected shortly ... please wait</div>
262
+ </Paper>
263
+ )}
218
264
  </ThemeProvider>
219
265
  );
220
266
  };
@@ -0,0 +1,11 @@
1
+ import { PublicClientApplication } from "@azure/msal-browser";
2
+
3
+ export const msalConfig = {
4
+ auth: {
5
+ clientId: "your-frontend-client-id",
6
+ authority: "https://login.microsoftonline.com/<tenant-id>",
7
+ redirectUri: "http://localhost:3000"
8
+ }
9
+ };
10
+
11
+ export const msalInstance = new PublicClientApplication(msalConfig);
@@ -64,6 +64,7 @@ const useAxios = () => {
64
64
  : false
65
65
  ) {
66
66
  dispatch(UserSessionActions.setUnAuthenticated());
67
+ localStorage.removeItem("TOKEN");
67
68
  toast.error("your session is now expired, you need to login again", {
68
69
  autoClose: false,
69
70
  });
@@ -14,6 +14,9 @@ import { UserSessionProps } from "../redux/features/common/UserSessionSlice";
14
14
  import LoadingMask from "../components/common/LoadingMask";
15
15
  import Login from "../components/common/Login";
16
16
  import NoLicenseComponent from "../components/common/NoLicenseComponent";
17
+ import { msalInstance } from "../components/msalConfig";
18
+ import { PublicClientApplication } from "@azure/msal-browser";
19
+ import AzureLogin from "../components/common/AzureLogin";
17
20
 
18
21
  const Main = styled("main", {
19
22
  shouldForwardProp: (prop) => prop !== "open",
@@ -53,9 +56,13 @@ const Main = styled("main", {
53
56
  };
54
57
  });
55
58
 
56
- export default function Layout() {
57
- const SideBarState = useSelector((state: any) => state.SideBar);
59
+ interface LayoutProps {
60
+ msalInstance: PublicClientApplication;
61
+ }
58
62
 
63
+ const Layout: React.FC<LayoutProps> = ({ msalInstance }) => {
64
+ const SideBarState = useSelector((state: any) => state.SideBar);
65
+ const appInfo = useSelector((state: any) => state.AppInfo.value);
59
66
  const isMobile = useIsMobile();
60
67
  const UserSession: UserSessionProps = useSelector(
61
68
  (state: any) => state.UserSession
@@ -80,9 +87,13 @@ export default function Layout() {
80
87
  <MainContent />
81
88
  <NoLicenseComponent />
82
89
  </Main>
90
+ ) : appInfo.authenticationMethod === "AZURE" ? (
91
+ <AzureLogin msalInstance={msalInstance} />
83
92
  ) : (
84
93
  <Login />
85
94
  )}
86
95
  </BrowserRouter>
87
96
  );
88
- }
97
+ };
98
+
99
+ export default Layout;
@@ -107,11 +107,6 @@ const MainContent: React.FC = () => {
107
107
  })}
108
108
  </Routes>
109
109
  </Box>
110
- )
111
- {/* : (
112
- <></>
113
- )
114
- } */}
115
110
  </CacheProvider>
116
111
  );
117
112
  };
@@ -102,6 +102,7 @@ const TopBar: React.FC = () => {
102
102
  await handleGetRequest({ endPointURI: "api/auth/logout" });
103
103
  } catch (error) {}
104
104
  dispatch(UserSessionActions.setUnAuthenticated());
105
+ localStorage.removeItem("TOKEN");
105
106
  };
106
107
  const toggleSideBar = () => {
107
108
  dispatch(toggleSideBarState());
@@ -169,7 +170,7 @@ const TopBar: React.FC = () => {
169
170
  <AttachmentImageViewer
170
171
  showAsAvatar={true}
171
172
  attachmentCode="ORGANIZATION_LOGOS"
172
- refKey={UserSession.value.currentOrganization.id + ""}
173
+ refKey={UserSession?.value?.currentOrganization?.id + ""}
173
174
  onErrorImage="/logo.png"
174
175
  style={{
175
176
  marginRight: 1,
package/src/main.tsx CHANGED
@@ -7,7 +7,18 @@ createRoot(document.getElementById("root")!).render(
7
7
  enableUINotifications={false}
8
8
  appLogo={"/logo.png"}
9
9
  appName="UI Base Library"
10
+ loginScreenStyle={{
11
+ themeMode: "dark",
12
+ backgroundImageNameInPublicFolder: "bg.jpg",
13
+ }}
10
14
  appVersion="0.0"
15
+ authenticationMethod="AZURE"
16
+ azureConfiguration={{
17
+ frontEndClientId: "c3bbbdbd-f392-4459-b3dd-2351cb07f924",
18
+ tenantId: "9f136fef-4529-475f-98e6-d271eb04eb00",
19
+ redirectURL: "http://localhost:3000",
20
+ scopes: ["api://6008a934-2a32-4776-a3df-1842ac9371da/access_as_user"],
21
+ }}
11
22
  businessCommonStoresMetaData={{}}
12
23
  businessNavigationItems={[]}
13
24
  businessReduxReducers={{}}
@@ -31,12 +31,5 @@ export const findNavigationItemById = (
31
31
  };
32
32
 
33
33
  export const NavigationItems: TreeViewBaseItem<ExtendedTreeItemProps>[] = [
34
- ...AdministrationItems,
35
- {
36
- icon: "user",
37
- label: "Example Grid",
38
- id: "example",
39
- action: "NAVIGATION",
40
- actionPayload: { path: "example" },
41
- },
34
+ ...AdministrationItems
42
35
  ];
@@ -19,6 +19,18 @@ export type AppInfo = {
19
19
  ar: { [key: string]: string };
20
20
  en: { [key: string]: string };
21
21
  };
22
+ loginScreenStyle?: {
23
+ themeMode: "dark" | "light";
24
+ backgroundImageNameInPublicFolder?: string;
25
+ backgroundColor?: string;
26
+ };
27
+ authenticationMethod: "AZURE" | "APP";
28
+ azureConfiguration?: {
29
+ frontEndClientId: string;
30
+ tenantId: string;
31
+ redirectURL: string;
32
+ scopes: Array<string>;
33
+ };
22
34
  businessRoutes?: Array<SystemRoute>;
23
35
  businessNavigationItems?: Array<ExtendedTreeItemProps>;
24
36
  businessReduxReducers?: { [key: string]: Reducer<any> };
@@ -41,6 +53,7 @@ const initialState: AppInfoProp = {
41
53
  value: {
42
54
  documentTitle: null,
43
55
  apiBaseUrl: null,
56
+ authenticationMethod: "APP",
44
57
  appName: null,
45
58
  appVersion: null,
46
59
  appLogo: null,