@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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@genesislcap/blank-app-seed-config",
3
3
  "description": "Genesis Blank App Seed Configuration",
4
- "version": "5.1.2-prerelease.2",
4
+ "version": "5.1.2-prerelease.3",
5
5
  "license": "Apache-2.0",
6
6
  "scripts": {
7
7
  "lint": "eslint .",
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 {Routes, Route, useLocation, BrowserRouter} from 'react-router';
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 LayoutWrapper from './layouts/LayoutWrapper';
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
- <AuthProvider>
107
- <RoutesProvider>
108
- <BrowserRouter basename={basePath}>
109
- <Routes>
110
- <Route path="*" element={<DynamicLayout />} />
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, { ReactNode, useEffect, useRef } from '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> = ({ children }) => {
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
- onlogout-clicked={() => navigate(`/${AUTH_PATH}`)}
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
- {children}
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, RouteObject } from 'react';
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
- const redirectUrl = '/{{kebabCase routes.[0].name}}';
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';
@@ -75,6 +75,7 @@ module.exports = (env, argv) => {
75
75
  new Dotenv(),
76
76
  new webpack.DefinePlugin({
77
77
  BUILDER: JSON.stringify('webpack'),
78
+ PUBLIC_PATH: JSON.stringify(publicPath),
78
79
  }),
79
80
  ],
80
81
  devServer: {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@genesislcap/blank-app-seed",
3
3
  "description": "Genesis Blank App Seed",
4
- "version": "5.1.2-prerelease.2",
4
+ "version": "5.1.2-prerelease.3",
5
5
  "license": "Apache-2.0",
6
6
  "scripts": {
7
7
  "release": "semantic-release"
@@ -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;