Skip to content

Commit

Permalink
Merge pull request #1305 from syucream/fix/react-router-v6
Browse files Browse the repository at this point in the history
Upgrade react-router to v6
  • Loading branch information
userlocalhost authored Oct 28, 2024
2 parents fc245b6 + 8a4c443 commit b95b673
Show file tree
Hide file tree
Showing 58 changed files with 1,080 additions and 632 deletions.
8 changes: 7 additions & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@ import { createRoot } from "react-dom/client";

import { AironeSnackbarProvider } from "AironeSnackbarProvider";
import { AppRouter } from "AppRouter";
import { CheckTermsService } from "CheckTermsService";
import { ErrorHandler } from "ErrorHandler";
import { theme } from "Theme";
import "i18n/config";

const App: FC = () => {
return (
<ThemeProvider theme={theme}>
<AironeSnackbarProvider>
<AppRouter />
<ErrorHandler>
<CheckTermsService>
<AppRouter />
</CheckTermsService>
</ErrorHandler>
</AironeSnackbarProvider>
</ThemeProvider>
);
Expand Down
197 changes: 94 additions & 103 deletions frontend/src/AppRouter.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import React, { FC } from "react";
import { RouteComponentProps } from "react-router";
import { Route, BrowserRouter as Router, Switch } from "react-router-dom";
import {
createBrowserRouter,
createRoutesFromElements,
Outlet,
Route,
RouterProvider,
} from "react-router-dom";

import { ErrorHandler } from "./ErrorHandler";
import { ACLHistoryPage } from "./pages/ACLHistoryPage";
import { EntryCopyPage } from "./pages/EntryCopyPage";
import { EntryDetailsPage } from "./pages/EntryDetailsPage";
Expand All @@ -11,7 +15,6 @@ import { NotFoundErrorPage } from "./pages/NotFoundErrorPage";
import { RoleEditPage } from "./pages/RoleEditPage";
import { RoleListPage } from "./pages/RoleListPage";

import { CheckTermsService } from "CheckTermsService";
import {
aclHistoryPath,
aclPath,
Expand Down Expand Up @@ -68,110 +71,98 @@ interface Props {
customRoutes?: {
path: string;
routePath: string;
component?: FC;
render?: (
props: RouteComponentProps<{ [K: string]: string | undefined }>
) => React.ReactNode;
element: React.ReactNode;
}[];
}

export const AppRouter: FC<Props> = ({ customRoutes }) => {
return (
<Router>
<ErrorHandler>
<CheckTermsService>
<Switch>
<Route path={loginPath()} component={LoginPage} />
<Route path="/">
const router = createBrowserRouter(
createRoutesFromElements(
<Route>
<Route path={loginPath()} element={<LoginPage />} />
<Route
path="/"
element={
<>
<Header />
<Switch>
{customRoutes &&
customRoutes.map((r) => (
<Route key={r.path} path={r.path} exact>
<Switch>
<Route
path={r.routePath}
component={r.component}
render={r.render}
/>
</Switch>
</Route>
))}
<Outlet />
</>
}
>
{customRoutes &&
customRoutes.map((r) => (
<Route key={r.path} path={r.path}>
<Route path={r.routePath} element={r.element} />
</Route>
))}

<Route
path={advancedSearchPath()}
component={AdvancedSearchPage}
/>
<Route
path={advancedSearchResultPath()}
component={AdvancedSearchResultsPage}
/>
<Route
path={newEntryPath(":entityId")}
component={EntryEditPage}
/>
<Route
path={copyEntryPath(":entityId", ":entryId")}
component={EntryCopyPage}
/>
<Route
path={entryDetailsPath(":entityId", ":entryId")}
component={EntryDetailsPage}
/>
<Route
path={restoreEntryPath(":entityId")}
component={EntryRestorePage}
/>
<Route
path={entryEditPath(":entityId", ":entryId")}
component={EntryEditPage}
/>
<Route
path={showEntryHistoryPath(":entityId", ":entryId")}
component={EntryHistoryListPage}
/>
<Route
path={entityEntriesPath(":entityId")}
component={EntryListPage}
/>
<Route
path={entityHistoryPath(":entityId")}
component={EntityHistoryPage}
/>
<Route path={newEntityPath()} component={EntityEditPage} />
<Route
path={editEntityPath(":entityId")}
component={EntityEditPage}
/>
<Route path={entitiesPath()} component={EntityListPage} />
<Route path={newTriggerPath()} component={TriggerEditPage} />
<Route
path={editTriggerPath(":triggerId")}
component={TriggerEditPage}
/>
<Route path={triggersPath()} component={TriggerListPage} />
<Route path={newGroupPath()} component={GroupEditPage} />
<Route path={groupPath(":groupId")} component={GroupEditPage} />
<Route path={groupsPath()} component={GroupListPage} />
<Route path={jobsPath()} component={JobListPage} />
<Route
path={aclHistoryPath(":objectId")}
component={ACLHistoryPage}
/>
<Route path={aclPath(":objectId")} component={ACLEditPage} />
<Route path={newUserPath()} component={UserEditPage} />
<Route path={userPath(":userId")} component={UserEditPage} />
<Route path={usersPath()} component={UserListPage} />
<Route path={newRolePath()} component={RoleEditPage} />
<Route path={rolePath(":roleId")} component={RoleEditPage} />
<Route path={rolesPath()} component={RoleListPage} />
<Route path={topPath()} component={DashboardPage} exact />
<Route component={NotFoundErrorPage} />
</Switch>
</Route>
</Switch>
</CheckTermsService>
</ErrorHandler>
</Router>
<Route path={advancedSearchPath()} element={<AdvancedSearchPage />} />
<Route
path={advancedSearchResultPath()}
element={<AdvancedSearchResultsPage />}
/>
<Route path={newEntryPath(":entityId")} element={<EntryEditPage />} />
<Route
path={copyEntryPath(":entityId", ":entryId")}
element={<EntryCopyPage />}
/>
<Route
path={entryDetailsPath(":entityId", ":entryId")}
element={<EntryDetailsPage />}
/>
<Route
path={restoreEntryPath(":entityId")}
element={<EntryRestorePage />}
/>
<Route
path={entryEditPath(":entityId", ":entryId")}
element={<EntryEditPage />}
/>
<Route
path={showEntryHistoryPath(":entityId", ":entryId")}
element={<EntryHistoryListPage />}
/>
<Route
path={entityEntriesPath(":entityId")}
element={<EntryListPage />}
/>
<Route
path={entityHistoryPath(":entityId")}
element={<EntityHistoryPage />}
/>
<Route path={newEntityPath()} element={<EntityEditPage />} />
<Route
path={editEntityPath(":entityId")}
element={<EntityEditPage />}
/>
<Route path={entitiesPath()} element={<EntityListPage />} />
<Route path={newTriggerPath()} element={<TriggerEditPage />} />
<Route
path={editTriggerPath(":triggerId")}
element={<TriggerEditPage />}
/>
<Route path={triggersPath()} element={<TriggerListPage />} />
<Route path={newGroupPath()} element={<GroupEditPage />} />
<Route path={groupPath(":groupId")} element={<GroupEditPage />} />
<Route path={groupsPath()} element={<GroupListPage />} />
<Route path={jobsPath()} element={<JobListPage />} />
<Route
path={aclHistoryPath(":objectId")}
element={<ACLHistoryPage />}
/>
<Route path={aclPath(":objectId")} element={<ACLEditPage />} />
<Route path={newUserPath()} element={<UserEditPage />} />
<Route path={userPath(":userId")} element={<UserEditPage />} />
<Route path={usersPath()} element={<UserListPage />} />
<Route path={newRolePath()} element={<RoleEditPage />} />
<Route path={rolePath(":roleId")} element={<RoleEditPage />} />
<Route path={rolesPath()} element={<RoleListPage />} />
<Route path={topPath()} element={<DashboardPage />} />
<Route path="*" element={<NotFoundErrorPage />} />
</Route>
</Route>
)
);

return <RouterProvider router={router} />;
};
18 changes: 9 additions & 9 deletions frontend/src/ErrorHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import { styled } from "@mui/material/styles";
import React, { FC, useCallback, useEffect, useState } from "react";
import { ErrorBoundary, FallbackProps } from "react-error-boundary";
import { useHistory } from "react-router-dom";
import { useLocation, useNavigate } from "react-router-dom";
import { useError } from "react-use";

import { ForbiddenErrorPage } from "./pages/ForbiddenErrorPage";
Expand Down Expand Up @@ -46,16 +46,16 @@ interface GenericErrorProps {
}

const GenericError: FC<GenericErrorProps> = ({ children }) => {
const history = useHistory();
const navigate = useNavigate();
const [open, setOpen] = useState(true);

const handleGoToTop = useCallback(() => {
history.replace(topPath());
}, [history]);
navigate(topPath(), { replace: true });
}, [navigate]);

const handleReload = useCallback(() => {
history.go(0);
}, [history]);
navigate(0);
}, [navigate]);

return (
<Dialog open={open} onClose={() => setOpen(false)}>
Expand Down Expand Up @@ -96,11 +96,11 @@ const GenericError: FC<GenericErrorProps> = ({ children }) => {
};

const ErrorFallback: FC<FallbackProps> = ({ error, resetErrorBoundary }) => {
const history = useHistory();
const location = useLocation();

history.listen(() => {
useEffect(() => {
resetErrorBoundary();
});
}, [location, resetErrorBoundary]);

switch (error.name) {
case ForbiddenError.errorName:
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/common/ImportForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Box, Button, Input, Typography } from "@mui/material";
import Encoding from "encoding-japanese";
import { useSnackbar } from "notistack";
import React, { ChangeEvent, FC, useState } from "react";
import { useHistory } from "react-router-dom";
import { useNavigate } from "react-router-dom";

import {
isResponseError,
Expand All @@ -15,7 +15,7 @@ interface Props {
}

export const ImportForm: FC<Props> = ({ handleImport, handleCancel }) => {
const history = useHistory();
const navigate = useNavigate();
const [file, setFile] = useState<File>();
const [errorMessage, setErrorMessage] = useState<string>("");
const { enqueueSnackbar } = useSnackbar();
Expand Down Expand Up @@ -43,7 +43,7 @@ export const ImportForm: FC<Props> = ({ handleImport, handleCancel }) => {

try {
await handleImport(fileReader.result);
history.go(0);
navigate(0);
} catch (e) {
if (e instanceof Error && isResponseError(e)) {
const reportableError = await toReportableNonFieldErrors(e);
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/components/entity/EntityControlMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from "@mui/material";
import { useSnackbar } from "notistack";
import React, { FC } from "react";
import { Link, useHistory } from "react-router-dom";
import { Link, useNavigate } from "react-router-dom";

import { RateLimitedClickable } from "../common/RateLimitedClickable";

Expand Down Expand Up @@ -43,7 +43,7 @@ export const EntityControlMenu: FC<Props> = ({
setToggle,
}) => {
const { enqueueSnackbar } = useSnackbar();
const history = useHistory();
const navigate = useNavigate();

const handleDelete = async (entityId: number) => {
await aironeApiClient
Expand All @@ -53,8 +53,8 @@ export const EntityControlMenu: FC<Props> = ({
variant: "success",
});
// A magic to reload the entity list with keeping snackbar
history.replace(topPath());
history.replace(entitiesPath());
navigate(topPath(), { replace: true });
navigate(entitiesPath(), { replace: true });
setToggle && setToggle();
})
.catch(() => {
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/entry/AdvancedSearchJoinModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
} from "@dmm-com/airone-apiclient-typescript-fetch";
import { Autocomplete, Box, Button, TextField } from "@mui/material";
import React, { FC, useState } from "react";
import { useHistory } from "react-router-dom";
import { useNavigate } from "react-router-dom";

import { AironeModal } from "components/common/AironeModal";
import { useAsyncWithThrow } from "hooks/useAsyncWithThrow";
Expand All @@ -28,7 +28,7 @@ export const AdvancedSearchJoinModal: FC<Props> = ({
handleClose,
refreshSearchResults,
}) => {
const history = useHistory();
const navigate = useNavigate();
// This is join attributes that have been already been selected before.
const currentAttrInfo: AdvancedSearchJoinAttrInfo | undefined =
joinAttrs.find((attr) => attr.name === targetAttrname);
Expand Down Expand Up @@ -73,7 +73,7 @@ export const AdvancedSearchJoinModal: FC<Props> = ({
refreshSearchResults();

// Update Page URL parameters
history.push({
navigate({
pathname: location.pathname,
search: "?" + params.toString(),
});
Expand Down
Loading

0 comments on commit b95b673

Please sign in to comment.