@genesislcap/blank-app-seed 5.1.2-prerelease.2 → 5.1.2-prerelease.3
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/.genx/package.json +1 -1
- package/CHANGELOG.md +8 -0
- package/client-tmp/react/package.json +2 -1
- package/client-tmp/react/src/App.tsx +9 -50
- package/client-tmp/react/src/components/routes/AppRoutes.tsx +35 -0
- package/client-tmp/react/src/components/routes/ProtectedRoute.tsx +17 -0
- package/client-tmp/react/src/layouts/default/DefaultLayout.tsx +10 -8
- package/client-tmp/react/src/pages/AuthPage/AuthPage.tsx +3 -2
- package/client-tmp/react/src/pbc/container.tsx +2 -2
- package/client-tmp/react/src/share/foundation-login.ts +10 -5
- package/client-tmp/react/src/share/genesis-components.ts +0 -7
- package/client-tmp/react/src/store/RoutesContext.tsx +1 -1
- package/client-tmp/react/webpack.config.js +1 -0
- package/package.json +1 -1
- package/client-tmp/react/src/guards/ProtectedGuard.tsx +0 -61
package/.genx/package.json
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [5.1.2-prerelease.3](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v5.1.2-prerelease.2...v5.1.2-prerelease.3) (2025-05-30)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* react router fixes b6d4754
|
|
9
|
+
* react router fixes (#469) 12e9d1e
|
|
10
|
+
|
|
3
11
|
## [5.1.2-prerelease.2](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v5.1.2-prerelease.1...v5.1.2-prerelease.2) (2025-05-26)
|
|
4
12
|
|
|
5
13
|
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"@genesislcap/foundation-shell": "{{versions.UI}}",
|
|
52
52
|
"@genesislcap/foundation-ui": "{{versions.UI}}",
|
|
53
53
|
"@genesislcap/foundation-utils": "{{versions.UI}}",
|
|
54
|
+
"@genesislcap/foundation-zero-grid-tabulator": "{{versions.UI}}",
|
|
54
55
|
"@genesislcap/rapid-design-system": "{{versions.UI}}",
|
|
55
56
|
"@genesislcap/rapid-grid-pro": "{{versions.UI}}",
|
|
56
57
|
"@genesislcap/rapid-grid-tabulator": "{{versions.UI}}",
|
|
@@ -61,7 +62,7 @@
|
|
|
61
62
|
"history": "^5.3.0",
|
|
62
63
|
"react": "^19.0.0",
|
|
63
64
|
"react-dom": "^19.0.0",
|
|
64
|
-
"react-router": "^7.1.3",
|
|
65
|
+
"react-router-dom": "^7.1.3",
|
|
65
66
|
"web-vitals": "^2.1.4"
|
|
66
67
|
},
|
|
67
68
|
"devDependencies": {
|
|
@@ -1,56 +1,19 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { BrowserRouter as Router } from 'react-router-dom';
|
|
3
3
|
import {
|
|
4
4
|
setApiHost,
|
|
5
|
-
getLayoutNameByRoute,
|
|
6
5
|
{{#if FDC3.channels.length~}}
|
|
7
6
|
listenToChannel,
|
|
8
7
|
onFDC3Ready,
|
|
9
8
|
{{/if}}
|
|
10
9
|
} from './utils';
|
|
11
10
|
import { customEventFactory, registerStylesTarget } from '@/pbc/utils';
|
|
12
|
-
import
|
|
13
|
-
import LayoutName from '@/types/LayoutName';
|
|
14
|
-
import { AUTH_PATH, routeLayouts } from './config';
|
|
15
|
-
import { AuthProvider } from './store/AuthContext';
|
|
16
|
-
import { RoutesProvider, useRoutesContext } from './store/RoutesContext';
|
|
17
|
-
import AuthPage from './pages/AuthPage/AuthPage';
|
|
11
|
+
import { RoutesProvider } from './store/RoutesContext';
|
|
18
12
|
import { registerComponents as genesisRegisterComponents } from './share/genesis-components';
|
|
19
|
-
import ProtectedGuard from './guards/ProtectedGuard';
|
|
20
13
|
import { storeService } from '@/services/store.service';
|
|
14
|
+
import AppRoutes from './components/routes/AppRoutes';
|
|
15
|
+
import NotFoundPage from "@/pages/NotFoundPage/NotFoundPage.tsx";
|
|
21
16
|
|
|
22
|
-
const DynamicLayout = () => {
|
|
23
|
-
const location = useLocation();
|
|
24
|
-
const [layoutName, setLayoutName] = useState<LayoutName>(routeLayouts[location.pathname] || 'default');
|
|
25
|
-
const handleRouteChange = (location: any) => {
|
|
26
|
-
setLayoutName(getLayoutNameByRoute(location.pathname));
|
|
27
|
-
};
|
|
28
|
-
const route = useRoutesContext().find((r) => r.path === location.pathname);
|
|
29
|
-
let pageComponent;
|
|
30
|
-
let content;
|
|
31
|
-
|
|
32
|
-
useEffect(() => {
|
|
33
|
-
handleRouteChange(location);
|
|
34
|
-
|
|
35
|
-
return () => {
|
|
36
|
-
}
|
|
37
|
-
}, [location]);
|
|
38
|
-
|
|
39
|
-
if (route) {
|
|
40
|
-
pageComponent = route.element;
|
|
41
|
-
} else {
|
|
42
|
-
pageComponent = <AuthPage />;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (location.pathname === `/${AUTH_PATH}` || location.pathname === '/') {
|
|
46
|
-
content = pageComponent;
|
|
47
|
-
} else {
|
|
48
|
-
content = <ProtectedGuard>{pageComponent}</ProtectedGuard>
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return <LayoutWrapper layout={layoutName}>{content}</LayoutWrapper>
|
|
52
|
-
|
|
53
|
-
};
|
|
54
17
|
|
|
55
18
|
interface AppProps {
|
|
56
19
|
rootElement: HTMLElement;
|
|
@@ -103,15 +66,11 @@ const App: React.FC<AppProps> = ({ rootElement }) => {
|
|
|
103
66
|
const basePath = baseElement?.getAttribute('href') || '';
|
|
104
67
|
|
|
105
68
|
return (
|
|
106
|
-
<
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
</Routes>
|
|
112
|
-
</BrowserRouter>
|
|
113
|
-
</RoutesProvider>
|
|
114
|
-
</AuthProvider>
|
|
69
|
+
<RoutesProvider>
|
|
70
|
+
<Router basename={basePath}>
|
|
71
|
+
<AppRoutes />
|
|
72
|
+
</Router>
|
|
73
|
+
</RoutesProvider>
|
|
115
74
|
);
|
|
116
75
|
};
|
|
117
76
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Routes, Route, Navigate } from 'react-router-dom';
|
|
2
|
+
import AuthPage from '../../pages/AuthPage/AuthPage';
|
|
3
|
+
import Home from '../../pages/Home/Home';
|
|
4
|
+
import DefaultLayout from '../../layouts/default/DefaultLayout';
|
|
5
|
+
import ProtectedRoute from './ProtectedRoute';
|
|
6
|
+
import { useRoutesContext } from '@/store/RoutesContext';
|
|
7
|
+
import PBCContainer from '@/pbc/container';
|
|
8
|
+
import NotFoundPage from '@/pages/NotFoundPage/NotFoundPage.tsx';
|
|
9
|
+
|
|
10
|
+
const AppRoutes = () => {
|
|
11
|
+
const routes = useRoutesContext();
|
|
12
|
+
return (
|
|
13
|
+
<Routes>
|
|
14
|
+
<Route path="/login" element={<AuthPage />} />
|
|
15
|
+
<Route path="/" element={<Navigate to="/{{kebabCase routes.[0].name}}" replace />} />
|
|
16
|
+
<Route element={<DefaultLayout />}>
|
|
17
|
+
<Route path="/" element={<Home />} />
|
|
18
|
+
{routes.map(route => (<Route
|
|
19
|
+
key={route.path}
|
|
20
|
+
path={route.path}
|
|
21
|
+
element={
|
|
22
|
+
<ProtectedRoute>
|
|
23
|
+
{route.data?.pbcElement ? <PBCContainer /> : route.element}
|
|
24
|
+
</ProtectedRoute>
|
|
25
|
+
}
|
|
26
|
+
/>))}
|
|
27
|
+
</Route>
|
|
28
|
+
|
|
29
|
+
<Route path="*" element={<NotFoundPage />} />
|
|
30
|
+
</Routes>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default AppRoutes;
|
|
35
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Navigate, useLocation } from 'react-router-dom';
|
|
2
|
+
import { getUser } from '@genesislcap/foundation-user';
|
|
3
|
+
|
|
4
|
+
interface ProtectedRouteProps {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function ProtectedRoute({ children }: ProtectedRouteProps) {
|
|
9
|
+
if (!getUser().isAuthenticated) {
|
|
10
|
+
const location = useLocation();
|
|
11
|
+
return <Navigate to="/login" state={{ from: location }} replace />;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return <>{children}</>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default ProtectedRoute;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
import { RouteObject, useNavigate } from 'react-router';
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { RouteObject, useNavigate, Outlet } from 'react-router-dom';
|
|
3
3
|
import { configureDesignSystem, getNavItems } from '@genesislcap/foundation-ui';
|
|
4
4
|
import {
|
|
5
5
|
baseLayerLuminance,
|
|
@@ -10,10 +10,9 @@ import PBCElementsRenderer from '@/pbc/elementsRenderer';
|
|
|
10
10
|
import * as designTokens from '@/styles/design-tokens.json';
|
|
11
11
|
import { useRoutesContext } from '@/store/RoutesContext';
|
|
12
12
|
import { AUTH_PATH } from '@/config';
|
|
13
|
+
import { LOGOUT_URL } from '@genesislcap/foundation-utils';
|
|
13
14
|
|
|
14
|
-
interface DefaultLayoutProps {
|
|
15
|
-
children: ReactNode;
|
|
16
|
-
}
|
|
15
|
+
interface DefaultLayoutProps {}
|
|
17
16
|
|
|
18
17
|
type ExtendedRouteObject = RouteObject & {
|
|
19
18
|
data?: {
|
|
@@ -22,7 +21,7 @@ type ExtendedRouteObject = RouteObject & {
|
|
|
22
21
|
path: string;
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
const DefaultLayout: React.FC<DefaultLayoutProps> = (
|
|
24
|
+
const DefaultLayout: React.FC<DefaultLayoutProps> = () => {
|
|
26
25
|
const navigate = useNavigate();
|
|
27
26
|
const designSystemProviderRef = useRef<HTMLElement>(null);
|
|
28
27
|
const routes = useRoutesContext() as ExtendedRouteObject[];
|
|
@@ -59,7 +58,10 @@ const DefaultLayout: React.FC<DefaultLayoutProps> = ({ children }) => {
|
|
|
59
58
|
<PBCElementsRenderer target={['layout-start']} />
|
|
60
59
|
<foundation-header
|
|
61
60
|
onluminance-icon-clicked={onLuminanceToggle}
|
|
62
|
-
|
|
61
|
+
logout={async () => {
|
|
62
|
+
await fetch(LOGOUT_URL);
|
|
63
|
+
window.location.reload()
|
|
64
|
+
}}
|
|
63
65
|
show-luminance-toggle-button
|
|
64
66
|
show-misc-toggle-button
|
|
65
67
|
routeNavItems={navItems}
|
|
@@ -68,7 +70,7 @@ const DefaultLayout: React.FC<DefaultLayoutProps> = ({ children }) => {
|
|
|
68
70
|
</foundation-header>
|
|
69
71
|
<section className={styles['content']}>
|
|
70
72
|
<PBCElementsRenderer target={['content-start']} />
|
|
71
|
-
|
|
73
|
+
<Outlet />
|
|
72
74
|
<PBCElementsRenderer target={['content', 'content-end']} />
|
|
73
75
|
</section>
|
|
74
76
|
<PBCElementsRenderer target={['layout', 'layout-end']} />
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import React, {useEffect} from 'react';
|
|
2
2
|
import './AuthPage.css';
|
|
3
3
|
import { configureFoundationLogin } from "@/share/foundation-login.ts";
|
|
4
|
-
import { useNavigate } from 'react-router';
|
|
4
|
+
import { useNavigate, useLocation } from 'react-router-dom';
|
|
5
5
|
|
|
6
6
|
const AuthPage: React.FC = () => {
|
|
7
7
|
const navigate = useNavigate();
|
|
8
|
+
const location = useLocation();
|
|
8
9
|
|
|
9
10
|
useEffect(() => {
|
|
10
|
-
configureFoundationLogin({ navigate });
|
|
11
|
+
configureFoundationLogin({ navigate, location });
|
|
11
12
|
}, []);
|
|
12
13
|
|
|
13
14
|
return (
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import React, { useEffect, useRef
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
2
|
import { deriveElementTag } from './utils';
|
|
3
3
|
import { useRoutesContext } from '@/store/RoutesContext';
|
|
4
|
-
import { useLocation } from 'react-router';
|
|
4
|
+
import { useLocation, RouteObject } from 'react-router-dom';
|
|
5
5
|
|
|
6
6
|
type ExtendedRouteObject = RouteObject & {
|
|
7
7
|
data?: {
|
|
@@ -3,12 +3,18 @@ import { AUTH_PATH } from '@/config';
|
|
|
3
3
|
import { environment } from "@/environments/environment.ts";
|
|
4
4
|
import { Connect } from '@genesislcap/foundation-comms';
|
|
5
5
|
import { DI } from '@genesislcap/web-core';
|
|
6
|
-
import type { NavigateFunction } from 'react-router';
|
|
6
|
+
import type { NavigateFunction, Location as RouterLocation } from 'react-router-dom';
|
|
7
|
+
|
|
8
|
+
interface LocationState {
|
|
9
|
+
from?: {
|
|
10
|
+
pathname: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
7
13
|
|
|
8
14
|
/**
|
|
9
15
|
* Configure the micro frontend
|
|
10
16
|
*/
|
|
11
|
-
export const configureFoundationLogin = ({navigate}: { navigate: NavigateFunction}) => {
|
|
17
|
+
export const configureFoundationLogin = ({navigate, location}: { navigate: NavigateFunction, location: RouterLocation<LocationState>}) => {
|
|
12
18
|
const baseElement = document.querySelector('base');
|
|
13
19
|
const basePath = baseElement?.getAttribute('href') || '';
|
|
14
20
|
const connect = DI.getOrCreateDOMContainer().get(Connect);
|
|
@@ -27,9 +33,8 @@ export const configureFoundationLogin = ({navigate}: { navigate: NavigateFunctio
|
|
|
27
33
|
postLoginRedirect: async () => {
|
|
28
34
|
const url = environment.API_HOST;
|
|
29
35
|
await connect.connect(url);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
navigate(redirectUrl);
|
|
36
|
+
const from = location.state?.from?.pathname || '/';
|
|
37
|
+
navigate(from, { replace: true });
|
|
33
38
|
},
|
|
34
39
|
})
|
|
35
40
|
}
|
|
@@ -2,7 +2,6 @@ import { EntityManagement } from '@genesislcap/foundation-entity-management';
|
|
|
2
2
|
import { Form } from '@genesislcap/foundation-forms';
|
|
3
3
|
import { foundationLayoutComponents } from '@genesislcap/foundation-layout';
|
|
4
4
|
import { getApp } from '@genesislcap/foundation-shell/app';
|
|
5
|
-
import * as zeroDesignSystem from '@genesislcap/foundation-zero';
|
|
6
5
|
import { g2plotChartsComponents } from '@genesislcap/g2plot-chart';
|
|
7
6
|
import * as rapidDesignSystem from '@genesislcap/rapid-design-system';
|
|
8
7
|
import { rapidGridComponents } from '@genesislcap/rapid-grid-pro';
|
|
@@ -49,10 +48,4 @@ export async function registerComponents() {
|
|
|
49
48
|
},
|
|
50
49
|
});
|
|
51
50
|
|
|
52
|
-
/**
|
|
53
|
-
* May be still required while we transition all PBCs to rapid. Remove when complete.
|
|
54
|
-
*/
|
|
55
|
-
zeroDesignSystem
|
|
56
|
-
.provideDesignSystem()
|
|
57
|
-
.register(zeroDesignSystem.baseComponents, g2plotChartsComponents, foundationLayoutComponents);
|
|
58
51
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { createContext, useContext, ReactNode } from 'react';
|
|
2
|
-
import { RouteObject, Navigate } from 'react-router';
|
|
2
|
+
import { RouteObject, Navigate } from 'react-router-dom';
|
|
3
3
|
import { getApp } from '@genesislcap/foundation-shell/app';
|
|
4
4
|
import AuthPage from '@/pages/AuthPage/AuthPage';
|
|
5
5
|
import NotFoundPage from '@/pages/NotFoundPage/NotFoundPage';
|
package/package.json
CHANGED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { useEffect, ReactNode, useState } from 'react';
|
|
2
|
-
import {RouteObject, useNavigate} from 'react-router';
|
|
3
|
-
import hasPermissionHelper from '@/helpers/hasPermissionHelper';
|
|
4
|
-
import { useRoutesContext } from '@/store/RoutesContext';
|
|
5
|
-
import { NOT_PERMITTED_PATH, AUTH_PATH } from '@/config';
|
|
6
|
-
import { getUser } from '@genesislcap/foundation-user';
|
|
7
|
-
|
|
8
|
-
enum PermissionState {
|
|
9
|
-
ALLOWED = 'allowed',
|
|
10
|
-
DENIED = 'denied',
|
|
11
|
-
UNKNOWN = 'unknown',
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const redirectUrlByPermissionState: { [key in Partial<PermissionState>]?: string } = {
|
|
15
|
-
[PermissionState.DENIED]: NOT_PERMITTED_PATH,
|
|
16
|
-
[PermissionState.UNKNOWN]: AUTH_PATH,
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
type ExtendedRouteObject = RouteObject & {
|
|
20
|
-
data?: {
|
|
21
|
-
permissionCode?: string;
|
|
22
|
-
};
|
|
23
|
-
path: string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const ProtectedGuard: React.FC<{ children: ReactNode }> = ({ children }: { children: ReactNode }) => {
|
|
27
|
-
const routes = useRoutesContext() as ExtendedRouteObject[];
|
|
28
|
-
const [isConnected, setIsConnected] = useState<boolean | null>(null);
|
|
29
|
-
const isAuthenticated: boolean | null = null;
|
|
30
|
-
const route = routes.find(({ path }) => path === location.pathname);
|
|
31
|
-
const hasPermission = route?.data?.permissionCode ? hasPermissionHelper(route.data?.permissionCode) : true;
|
|
32
|
-
const navigate = useNavigate();
|
|
33
|
-
|
|
34
|
-
useEffect(() => {
|
|
35
|
-
if (!getUser().isAuthenticated){
|
|
36
|
-
getUser().trackPath();
|
|
37
|
-
navigate('/login')
|
|
38
|
-
}
|
|
39
|
-
}, []);
|
|
40
|
-
|
|
41
|
-
useEffect((): void => {
|
|
42
|
-
|
|
43
|
-
const isAuthenticated = getUser().isAuthenticated;
|
|
44
|
-
let permissionState;
|
|
45
|
-
|
|
46
|
-
if (!isAuthenticated) {
|
|
47
|
-
permissionState = PermissionState.UNKNOWN;
|
|
48
|
-
} else if (hasPermission === false) {
|
|
49
|
-
permissionState = PermissionState.DENIED;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (permissionState) {
|
|
53
|
-
const redirect = `${redirectUrlByPermissionState[permissionState]}`;
|
|
54
|
-
navigate(`${redirect}`);
|
|
55
|
-
}
|
|
56
|
-
}, [routes, isAuthenticated, hasPermission]);
|
|
57
|
-
|
|
58
|
-
return children;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export default ProtectedGuard;
|