Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade react-router to v6 #1305

Merged
merged 7 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading