@fluxo-dev/shell 0.0.8

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.
Files changed (66) hide show
  1. package/.babelrc +12 -0
  2. package/.eslintrc.json +18 -0
  3. package/README.md +7 -0
  4. package/jest.config.ts +11 -0
  5. package/package.json +4 -0
  6. package/project.json +43 -0
  7. package/src/index.ts +1 -0
  8. package/src/lib/app.module.css +1 -0
  9. package/src/lib/app.spec.tsx +17 -0
  10. package/src/lib/app.tsx +374 -0
  11. package/src/lib/components/error-page/404.tsx +16 -0
  12. package/src/lib/components/routes/main-routes.tsx +26 -0
  13. package/src/lib/layouts/blank/blank-layout.tsx +10 -0
  14. package/src/lib/layouts/main/app-bar.tsx +192 -0
  15. package/src/lib/layouts/main/app-layout.tsx +52 -0
  16. package/src/lib/layouts/main/content.tsx +10 -0
  17. package/src/lib/layouts/main/footer-bar.tsx +76 -0
  18. package/src/lib/layouts/main/navbar-item.module.css +49 -0
  19. package/src/lib/layouts/main/navbar-item.tsx +129 -0
  20. package/src/lib/layouts/main/navbar.tsx +38 -0
  21. package/src/lib/layouts/main/search-bar.tsx +44 -0
  22. package/src/lib/layouts/main/shell-spotlight.tsx +58 -0
  23. package/src/lib/models/app-jit.ts +6 -0
  24. package/src/lib/pages/general/fluxo-plugin-loader.tsx +22 -0
  25. package/src/lib/pages/login/account-confirmation.tsx +86 -0
  26. package/src/lib/pages/login/change-password.tsx +58 -0
  27. package/src/lib/pages/login/forgot-password.tsx +53 -0
  28. package/src/lib/pages/login/login-page.tsx +70 -0
  29. package/src/lib/pages/login/reset-password.tsx +91 -0
  30. package/src/lib/pages/settings/apps/add-jit-app.tsx +79 -0
  31. package/src/lib/pages/settings/apps/app-item.tsx +157 -0
  32. package/src/lib/pages/settings/apps/app-jit-item.tsx +105 -0
  33. package/src/lib/pages/settings/apps/apps-list.tsx +171 -0
  34. package/src/lib/pages/settings/apps/embedded-module-item.tsx +66 -0
  35. package/src/lib/pages/settings/apps/install-or-upgrade-app.tsx +105 -0
  36. package/src/lib/pages/settings/menu-designer/custom-node.module.css +34 -0
  37. package/src/lib/pages/settings/menu-designer/custom-node.tsx +160 -0
  38. package/src/lib/pages/settings/menu-designer/menu-create-form.tsx +109 -0
  39. package/src/lib/pages/settings/menu-designer/menu-designer.module.css +19 -0
  40. package/src/lib/pages/settings/menu-designer/menu-designer.tsx +463 -0
  41. package/src/lib/pages/settings/menu-designer/menu-item-edit.tsx +115 -0
  42. package/src/lib/pages/settings/menu-designer/placeholder.module.css +8 -0
  43. package/src/lib/pages/settings/menu-designer/placeholder.tsx +13 -0
  44. package/src/lib/pages/settings/security/components/domani-role/domain-role-form.tsx +67 -0
  45. package/src/lib/pages/settings/security/components/domani-role/domain-role-grid.tsx +139 -0
  46. package/src/lib/pages/settings/security/components/permission/create-custom-permission-form.tsx +64 -0
  47. package/src/lib/pages/settings/security/components/permission/create-scope-form.tsx +158 -0
  48. package/src/lib/pages/settings/security/components/permission/permission-grid.tsx +304 -0
  49. package/src/lib/pages/settings/security/components/permission/permission-navigator.tsx +320 -0
  50. package/src/lib/pages/settings/security/components/permission/update-permission.tsx +54 -0
  51. package/src/lib/pages/settings/security/components/route-rule/route-rule-create-form.tsx +59 -0
  52. package/src/lib/pages/settings/security/components/route-rule/route-rule-grid.tsx +229 -0
  53. package/src/lib/pages/settings/security/components/user/user-form.tsx +123 -0
  54. package/src/lib/pages/settings/security/components/user/users-grid.tsx +127 -0
  55. package/src/lib/pages/settings/settings.tsx +298 -0
  56. package/src/lib/pages/settings/token/token-row.tsx +69 -0
  57. package/src/lib/pages/settings/token/tokens.tsx +73 -0
  58. package/src/lib/pages/settings/ui/ui.tsx +149 -0
  59. package/src/lib/services/app-jit-manager.ts +92 -0
  60. package/src/lib/services/app-menu.service.ts +35 -0
  61. package/src/lib/utils/icon-factory.tsx +25 -0
  62. package/src/lib/utils/security/only-not-logged-route.tsx +17 -0
  63. package/src/lib/utils/security/protected-route.tsx +47 -0
  64. package/tsconfig.json +20 -0
  65. package/tsconfig.lib.json +24 -0
  66. package/tsconfig.spec.json +20 -0
package/.babelrc ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "presets": [
3
+ [
4
+ "@nx/react/babel",
5
+ {
6
+ "runtime": "automatic",
7
+ "useBuiltIns": "usage"
8
+ }
9
+ ]
10
+ ],
11
+ "plugins": []
12
+ }
package/.eslintrc.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "extends": ["plugin:@nx/react", "../../../.eslintrc.json"],
3
+ "ignorePatterns": ["!**/*"],
4
+ "overrides": [
5
+ {
6
+ "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7
+ "rules": {}
8
+ },
9
+ {
10
+ "files": ["*.ts", "*.tsx"],
11
+ "rules": {}
12
+ },
13
+ {
14
+ "files": ["*.js", "*.jsx"],
15
+ "rules": {}
16
+ }
17
+ ]
18
+ }
package/README.md ADDED
@@ -0,0 +1,7 @@
1
+ # libs/shell/shell
2
+
3
+ This library was generated with [Nx](https://nx.dev).
4
+
5
+ ## Running unit tests
6
+
7
+ Run `nx test libs/shell/shell` to execute the unit tests via [Jest](https://jestjs.io).
package/jest.config.ts ADDED
@@ -0,0 +1,11 @@
1
+ /* eslint-disable */
2
+ export default {
3
+ displayName: 'libs/shell/shell',
4
+ preset: '../../../jest.preset.js',
5
+ transform: {
6
+ '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nx/react/plugins/jest',
7
+ '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nx/react/babel'] }],
8
+ },
9
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
10
+ coverageDirectory: '../../../coverage/libs/shell/shell',
11
+ };
package/package.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "@fluxo-dev/shell",
3
+ "version": "0.0.8"
4
+ }
package/project.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "libs/shell/shell",
3
+ "$schema": "../../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "libs/shell/shell/src",
5
+ "projectType": "library",
6
+ "tags": [],
7
+ "targets": {
8
+ "lint": {
9
+ "executor": "@nx/eslint:lint",
10
+ "outputs": ["{options.outputFile}"],
11
+ "options": {
12
+ "lintFilePatterns": ["libs/shell/shell/**/*.{ts,tsx,js,jsx}"]
13
+ }
14
+ },
15
+ "build": {
16
+ "executor": "@nx/rollup:rollup",
17
+ "outputs": ["{options.outputPath}"],
18
+ "options": {
19
+ "outputPath": "dist/libs/shell/shell",
20
+ "tsConfig": "libs/shell/shell/tsconfig.lib.json",
21
+ "project": "libs/shell/shell/package.json",
22
+ "entryFile": "libs/shell/shell/src/index.ts",
23
+ "external": ["react", "react-dom", "react/jsx-runtime"],
24
+ "rollupConfig": "@nx/react/plugins/bundle-rollup",
25
+ "compiler": "babel",
26
+ "assets": [
27
+ {
28
+ "glob": "libs/shell/shell/README.md",
29
+ "input": ".",
30
+ "output": "."
31
+ }
32
+ ]
33
+ }
34
+ },
35
+ "test": {
36
+ "executor": "@nx/jest:jest",
37
+ "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
38
+ "options": {
39
+ "jestConfig": "libs/shell/shell/jest.config.ts"
40
+ }
41
+ }
42
+ }
43
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export {FluxoShell, FluxoShellProps} from './lib/app';
@@ -0,0 +1 @@
1
+ /* Your styles goes here. */
@@ -0,0 +1,17 @@
1
+ import { render } from '@testing-library/react';
2
+
3
+ import App from './app';
4
+
5
+ describe('App', () => {
6
+ it('should render successfully', () => {
7
+ const { baseElement } = render(<App />);
8
+
9
+ expect(baseElement).toBeTruthy();
10
+ });
11
+
12
+ it('should have a greeting as the title', () => {
13
+ const { getByText } = render(<App />);
14
+
15
+ expect(getByText(/Welcome shell/gi)).toBeTruthy();
16
+ });
17
+ });
@@ -0,0 +1,374 @@
1
+ import React, {useEffect, useState} from "react";
2
+ import {Provider} from "react-redux";
3
+ import {createBrowserRouter, RouteObject, RouterProvider} from "react-router-dom";
4
+ import ErrorPage from "./components/error-page/404";
5
+ import ProtectedRoute from "./utils/security/protected-route";
6
+
7
+ import FluxoPluginLoader from "./pages/general/fluxo-plugin-loader";
8
+ import OnlyNotLoggedRoute from "./utils/security/only-not-logged-route";
9
+ import BlankLayout from "./layouts/blank/blank-layout";
10
+ import AppLayout from "./layouts/main/app-layout";
11
+ import LoginPage from "./pages/login/login-page";
12
+
13
+ import {store} from "@fluxo-dev/state";
14
+ import {MantineProvider} from "@mantine/core";
15
+ import {Notifications} from "@mantine/notifications";
16
+ import {MainRoutes} from "./components/routes/main-routes";
17
+ import {
18
+ AppState,
19
+ EmbeddedModule,
20
+ FeatureList,
21
+ FluxoApp,
22
+ FluxoClientSys,
23
+ FluxoStateDispatcher
24
+ } from "@fluxo-dev/api-client-base";
25
+ import {WaitData} from "@fluxo-dev/ui-components";
26
+ import ForgotPassword from "./pages/login/forgot-password";
27
+ import ResetPassword from "./pages/login/reset-password";
28
+ import AccountConfirmation from "./pages/login/account-confirmation";
29
+ import {AppJitManager} from "./services/app-jit-manager";
30
+ import {DatesProvider} from "@mantine/dates";
31
+ import {reportsModule} from "@fluxo-fe/shell/reporting";
32
+ import {workflowModule} from "@fluxo-fe/shell/workflow";
33
+ import './app.module.css';
34
+ import 'dayjs/locale/it';
35
+
36
+ export interface FluxoShellProps {
37
+ pluginEndpoint: string,
38
+ appVersion: string,
39
+ dashboardComponent: React.ReactNode,
40
+ modules: EmbeddedModule[]
41
+ }
42
+
43
+ export function FluxoShell(props: FluxoShellProps) {
44
+
45
+
46
+ const [initialOperationsFinished, setInitialOperationsFinished] = useState<boolean>(false);
47
+ const [router, setRouter] = useState<any>();
48
+ const [brandColors, setBrandColors] = useState<any>(["#e9f4ff","#c2d8ef","#9bbae1","#749ad6","#4d7aca","#355db2","#29458a","#1d2e63","#101b3d","#030a18"]);
49
+
50
+ const generateRoutesFromEmbeddedModules = (): RouteObject[] => {
51
+ const embeddedModules: EmbeddedModule[] = [
52
+ ...props.modules,
53
+ reportsModule,
54
+ workflowModule
55
+ ];
56
+
57
+ const rObjs: RouteObject[] = [];
58
+
59
+ embeddedModules.forEach((eModule) => {
60
+ rObjs.push({
61
+ path: `/${eModule.scope}/${eModule.name}/*`,
62
+ children: eModule.getRouteObject()
63
+ });
64
+ })
65
+
66
+ return rObjs;
67
+ }
68
+
69
+ const generateRoutesFromJitApps = (): RouteObject[] => {
70
+ const jitAppManager = new AppJitManager();
71
+
72
+ const jitApps = jitAppManager.loadAppConfigurations();
73
+
74
+ const rObjs: RouteObject[] = [];
75
+
76
+ jitApps.filter(a => a.state == AppState.Active).map((app) => {
77
+ rObjs.push({
78
+ path: `/${app.developmentRoute}`,
79
+ children: [
80
+ {
81
+ path: `*`,
82
+ element: <FluxoPluginLoader module={`./${app.scope}`} scope={app.name} url={`${app.developmentUrl}/remoteEntry.js`} />
83
+ }
84
+ ]
85
+ });
86
+ });
87
+
88
+ const jitAppsFeatures: FeatureList = {
89
+ features: [],
90
+ modules: []
91
+ };
92
+
93
+ jitApps.filter(a => a.state == AppState.Active).map((app) => {
94
+
95
+ jitAppsFeatures.modules.push(
96
+ {key: app.scope, name: app.name, description: app.description}
97
+ );
98
+
99
+ app.menu.map((f) => {
100
+
101
+ f.items?.map((ff) => {
102
+ jitAppsFeatures.features.push({
103
+ name: ff.name,
104
+ description: ff.name,
105
+ routerLink: `${app.developmentRoute}/${ff.route}`,
106
+ identifier: app.scope + '.' + f.name + '.' + ff.name,
107
+ groupName: f.name,
108
+ groupKey: f.name,
109
+ moduleKey: app.scope,
110
+ moduleName: app.name
111
+ });
112
+ });
113
+
114
+ });
115
+ });
116
+
117
+ FluxoStateDispatcher.dispatchSetJitAppsFeatures(jitAppsFeatures);
118
+
119
+ return rObjs;
120
+ }
121
+
122
+ const generateRoutesFromDeployedApps = (apps: FluxoApp[]): RouteObject[] => {
123
+
124
+ const rObjs: RouteObject[] = [];
125
+
126
+ apps.map((app) => {
127
+ rObjs.push({
128
+ path: `/${app.scope}/${app.name}`,
129
+ children: [
130
+ {
131
+ path: `*`,
132
+ element: <FluxoPluginLoader module={`./${app.scope}`} scope={app.name} url={`${props.pluginEndpoint}/${app.scope}/${app.name}/remoteEntry.js`} />
133
+ }
134
+ ]
135
+ });
136
+ });
137
+
138
+ return rObjs;
139
+ }
140
+
141
+ const generateAuthRoutes = (): RouteObject => {
142
+ return {
143
+ path: "/auth",
144
+ element: <OnlyNotLoggedRoute><BlankLayout/></OnlyNotLoggedRoute>,
145
+ children: [
146
+ {
147
+ path: "login",
148
+ element: <LoginPage/>
149
+ },
150
+ {
151
+ path: "forgot-password",
152
+ element: <ForgotPassword/>
153
+ },
154
+ {
155
+ path: "reset-password",
156
+ element: <ResetPassword/>
157
+ },
158
+ {
159
+ path: "account-confirmation",
160
+ element: <AccountConfirmation/>
161
+ }
162
+ ]
163
+ };
164
+ }
165
+
166
+ useEffect(() => {
167
+ FluxoClientSys.Instance.configuration.getInitialConfiguration()
168
+ .then((res) => {
169
+
170
+ FluxoStateDispatcher.dispatchSetConfiguration(res.ui);
171
+ FluxoStateDispatcher.dispatchSetAppMenu(res.menu);
172
+ FluxoStateDispatcher.dispatchSetSysFeatures(res.features);
173
+ FluxoStateDispatcher.dispatchSetUserPermissions(res.permissions.map(a => a.fullIdentifier))
174
+ FluxoStateDispatcher.dispatchSetRouteRules(res.routeRules);
175
+
176
+ const rObjs: RouteObject[] = [
177
+ generateAuthRoutes(),
178
+ {
179
+ element: <ProtectedRoute><AppLayout appVersion={props.appVersion} /></ProtectedRoute>,
180
+ errorElement: <ErrorPage />,
181
+ children: [
182
+ {
183
+ index: true,
184
+ element: props.dashboardComponent
185
+ },
186
+ {
187
+ path: '/*',
188
+ element: <MainRoutes pluginEndpoint={props.pluginEndpoint} modules={props.modules} />,
189
+ },
190
+ ...generateRoutesFromEmbeddedModules(),
191
+ ...generateRoutesFromDeployedApps(res.apps),
192
+ ...generateRoutesFromJitApps(),
193
+ ],
194
+ },
195
+ {
196
+ path: '*',
197
+ element: <ErrorPage />,
198
+ }
199
+ ];
200
+
201
+ const router1 = createBrowserRouter(rObjs, { basename: '/' });
202
+
203
+ setRouter(router1);
204
+ setBrandColors(res.ui.colors);
205
+ })
206
+ .finally(() => {
207
+ setInitialOperationsFinished(true);
208
+ });
209
+ }, [])
210
+
211
+ return (
212
+ <MantineProvider theme={{
213
+ defaultRadius: 0,
214
+ components: {
215
+ ActionIcon: {
216
+ defaultProps: {
217
+ variant: 'transparent'
218
+ }
219
+ },
220
+ Text: {
221
+ defaultProps: {
222
+ size: 'xs',
223
+ fontSize: '10.5pt'
224
+ },
225
+ },
226
+ Button: {
227
+ defaultProps: {
228
+ size: 'xs',
229
+ fontSize: '10.5pt'
230
+ },
231
+ },
232
+ NumberInput: {
233
+ defaultProps: {
234
+ size: 'xs',
235
+ fontSize: '10.5pt'
236
+ },
237
+ },
238
+ DateInput: {
239
+ defaultProps: {
240
+ size: 'xs',
241
+ fontSize: '10.5pt'
242
+ },
243
+ },
244
+ Select: {
245
+ defaultProps: {
246
+ size: 'xs',
247
+ fontSize: '10.5pt'
248
+ },
249
+ },
250
+ Switch: {
251
+ defaultProps: {
252
+ size: 'xs',
253
+ fontSize: '10.5pt'
254
+ },
255
+ },
256
+ DatePickerInput: {
257
+ defaultProps: {
258
+ size: 'xs',
259
+ fontSize: '10.5pt',
260
+ popoverProps: {withinPortal: true}
261
+ },
262
+ },
263
+ TextInput: {
264
+ defaultProps: {
265
+ size: 'xs',
266
+ fontSize: '10.5pt'
267
+ }
268
+ },
269
+ Textarea: {
270
+ defaultProps: {
271
+ size: 'xs',
272
+ fontSize: '10.5pt'
273
+ }
274
+ },
275
+ MultiSelect: {
276
+ defaultProps: {
277
+ size: 'xs',
278
+ fontSize: '10.5pt'
279
+ }
280
+ },
281
+ Pill: {
282
+ defaultProps: {
283
+ size: 'xs',
284
+ fontSize: '10.5pt'
285
+ }
286
+ },
287
+ PillsInput: {
288
+ defaultProps: {
289
+ size: 'xs',
290
+ fontSize: '10.5pt'
291
+ }
292
+ },
293
+ Modal: {
294
+ defaultProps: {
295
+ shadow: '0 0 200px rgba(16,16,16,.4)',
296
+ styles: {
297
+ close: {color: 'black'},
298
+ header: {
299
+ background: '#fff',
300
+ padding: 8,
301
+ marginBottom: 16,
302
+ color: 'black',
303
+ boxShadow: 'rgba(33, 33, 33, 0.1) 2px 1px 1px'
304
+ }
305
+ },
306
+ overlayProps: {
307
+ color: 'rgba(153,153,153)',
308
+ opacity: 0.44,
309
+ blur: 0,
310
+ }
311
+ }
312
+ },
313
+ Pagination: {
314
+ styles: {
315
+ root: {
316
+ borderRadius: 0,
317
+ }
318
+ }
319
+ },
320
+ Loader: {
321
+ defaultProps: {
322
+ type: 'bars'
323
+ }
324
+ }
325
+ },
326
+ colors: {
327
+ darkGreen: ['#dcf6ff','#b3e8fc','#86ddf8','#5ad5f4','#37d1f2','#26bfd8','#1799a8','#077179','#004049','#00151a'],
328
+ darkBlue: [
329
+ '#e9f4ff',
330
+ '#c2d8ef',
331
+ '#9bbae1',
332
+ '#749ad6',
333
+ '#4d7aca',
334
+ '#355db2',
335
+ '#29458a',
336
+ '#1d2e63',
337
+ '#101b3d',
338
+ '#030a18',
339
+ ],
340
+ //brand: ['#000','#111','#222','#333','#444','#555','#666','#777'],
341
+ // DIA brand: ['#dcf6ff','#b3e8fc','#86ddf8','#5ad5f4','#37d1f2','#26bfd8','#1799a8','#077179','#004049','#00151a'],
342
+ brand: brandColors,
343
+ },
344
+ fontFamily: 'Roboto', primaryColor: 'brand'
345
+ }}>
346
+ <React.Fragment>
347
+ {initialOperationsFinished && (((router && brandColors))) ?
348
+ <React.Fragment>
349
+ <DatesProvider settings={{ locale: 'it', firstDayOfWeek: 1, weekendDays: [0,6] }}>
350
+ <Provider store={store}>
351
+ <Notifications />
352
+ <AppInner router={router} />
353
+ </Provider>
354
+ </DatesProvider>
355
+ </React.Fragment> : <WaitData />
356
+ }
357
+ </React.Fragment>
358
+ </MantineProvider>
359
+ );
360
+ }
361
+
362
+ export default FluxoShell;
363
+
364
+ export interface AppInnerProps {
365
+ router: any;
366
+ }
367
+ export function AppInner(props: AppInnerProps) {
368
+
369
+ return (
370
+ <React.Suspense fallback={<>...</>}>
371
+ <RouterProvider router={props.router} />
372
+ </React.Suspense>
373
+ )
374
+ }
@@ -0,0 +1,16 @@
1
+ import { useRouteError } from "react-router-dom";
2
+
3
+ export default function ErrorPage() {
4
+ //const error: any = useRouteError();
5
+ //console.error(error);
6
+
7
+ return (
8
+ <div id="error-page">
9
+ <h1>Oops!</h1>
10
+ <p>Sorry, an unexpected error has occurred.</p>
11
+ {/*<p>
12
+ <i>{error.statusText || error.message}</i>
13
+ </p>*/}
14
+ </div>
15
+ );
16
+ }
@@ -0,0 +1,26 @@
1
+ import { FlxRoutes } from "@fluxo-dev/ui-components";
2
+ import { Route } from "react-router-dom";
3
+ import ChangePassword from "../../pages/login/change-password";
4
+ import { Settings } from "../../pages/settings/settings";
5
+ import React, {lazy, Suspense} from "react";
6
+ import {EmbeddedModule, UserService} from "@fluxo-dev/api-client-base";
7
+
8
+ export interface MainRoutesProps {
9
+ pluginEndpoint: string;
10
+ modules: EmbeddedModule[];
11
+ }
12
+ export function MainRoutes(props: MainRoutesProps) {
13
+
14
+ const KIde = lazy(() => import('@fluxo-fe/shell/korebi').then(({KorebiIde}) => ({default: KorebiIde})));
15
+ const user = new UserService();
16
+
17
+
18
+
19
+ return (
20
+ <FlxRoutes>
21
+ <Route path={'settings'} element={<Settings pluginEndpoint={props.pluginEndpoint} modules={props.modules} />} />
22
+ <Route path={'change-password'} element={<ChangePassword />} />
23
+ <Route path={'korebi-ide'} element={<Suspense><KIde /></Suspense>} />
24
+ </FlxRoutes>
25
+ )
26
+ }
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import {Outlet} from "react-router-dom";
3
+
4
+ function BlankLayout() {
5
+ return (
6
+ <Outlet />
7
+ )
8
+ }
9
+
10
+ export default BlankLayout;