Skip to content

Commit

Permalink
Migrate react-router to v6 (#4703)
Browse files Browse the repository at this point in the history
# What this PR does

- Migrate react-router from v5 to v6

Closes #4031
  • Loading branch information
teodosii authored Jul 26, 2024
1 parent 40b1046 commit 9e9e4a5
Show file tree
Hide file tree
Showing 32 changed files with 1,106 additions and 970 deletions.
3 changes: 0 additions & 3 deletions .config/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
{
"plugins": ["deprecation"],
"files": ["src/**/*.{ts,tsx}"],
"rules": {
"deprecation/deprecation": "warn"
},
"parserOptions": {
"project": "./tsconfig.json"
}
Expand Down
2 changes: 1 addition & 1 deletion .config/webpack/webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ const config = async (env): Promise<Configuration> => {

if (isWSL()) {
baseConfig.watchOptions = {
poll: 3000,
// poll: 3000,
ignored: /node_modules/,
};
}
Expand Down
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module.exports = {
{
files: ['src/**/*.{ts,tsx}'],
rules: {
'deprecation/deprecation': 'off',
'deprecation/deprecation': 'warn',
},
parserOptions: {
project: './tsconfig.json',
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@
"@types/react-copy-to-clipboard": "^5.0.4",
"@types/react-dom": "^18.0.6",
"@types/react-responsive": "^8.0.5",
"@types/react-router-dom": "^5.3.3",
"@types/react-test-renderer": "^18.0.5",
"@types/react-transition-group": "^4.4.5",
"@types/testing-library__jest-dom": "5.14.8",
Expand Down Expand Up @@ -170,7 +169,7 @@
"react-hook-form": "^7.50.1",
"react-modal": "^3.15.1",
"react-responsive": "^8.1.0",
"react-router-dom": "5.3.3",
"react-router-dom-v5-compat": "^6.25.1",
"react-sortable-hoc": "^1.11.0",
"react-string-replace": "^0.4.4",
"react-transition-group": "^4.4.5",
Expand Down
2 changes: 1 addition & 1 deletion src/components/PluginLink/PluginLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, { FC, useCallback, useMemo } from 'react';
import { css, cx } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '@grafana/ui';
import { Link } from 'react-router-dom';
import { Link } from 'react-router-dom-v5-compat';
import { bem } from 'styles/utils.styles';

import { getPathFromQueryParams } from 'utils/url';
Expand Down
7 changes: 4 additions & 3 deletions src/containers/IntegrationForm/IntegrationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
} from '@grafana/ui';
import { observer } from 'mobx-react';
import { Controller, useForm, useFormContext, FormProvider } from 'react-hook-form';
import { useHistory } from 'react-router-dom';
import { useNavigate } from 'react-router-dom-v5-compat';

import { HowTheIntegrationWorks } from 'components/HowTheIntegrationWorks/HowTheIntegrationWorks';
import { PluginLink } from 'components/PluginLink/PluginLink';
Expand Down Expand Up @@ -94,7 +94,7 @@ export const IntegrationForm = observer(
onBackClick,
}: IntegrationFormProps) => {
const store = useStore();
const history = useHistory();
const navigate = useNavigate();
const styles = useStyles2(getIntegrationFormStyles);
const isNew = id === 'new';
const {
Expand Down Expand Up @@ -453,7 +453,8 @@ export const IntegrationForm = observer(
async function createNewIntegration(): Promise<void | ApiSchemas['AlertReceiveChannelCreate']> {
const response = await alertReceiveChannelStore.create({ data, skipErrorHandling: true });
const pushHistory = (id: ApiSchemas['AlertReceiveChannel']['id']) =>
history.push(`${PLUGIN_ROOT}/integrations/${id}`);
navigate(`${PLUGIN_ROOT}/integrations/${id}`);

if (!response) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';

import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MemoryRouter } from 'react-router-dom';
import { MemoryRouter } from 'react-router-dom-v5-compat';

import { UserHelper } from 'models/user/user.helpers';
import { ApiSchemas } from 'network/oncall-api/api.types';
Expand Down
8 changes: 4 additions & 4 deletions src/containers/OutgoingWebhookForm/OutgoingWebhookForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import cn from 'classnames/bind';
import { observer } from 'mobx-react';
import { FormProvider, useForm, useFormContext } from 'react-hook-form';
import { useHistory } from 'react-router-dom';
import { useNavigate } from 'react-router-dom-v5-compat';

import { Text } from 'components/Text/Text';
import { OutgoingWebhookStatus } from 'containers/OutgoingWebhookStatus/OutgoingWebhookStatus';
Expand Down Expand Up @@ -304,7 +304,7 @@ interface EditWebhookTabsProps {
const EditWebhookTabs = (props: EditWebhookTabsProps) => {
const { id, data, action, onHide, onUpdate, onDelete, onSubmit, onTemplateEditClick, preset } = props;

const history = useHistory();
const navigate = useNavigate();

const [activeTab, setActiveTab] = useState(
action === WebhookFormActionType.EDIT_SETTINGS ? WebhookTabs.Settings.key : WebhookTabs.LastRun.key
Expand All @@ -323,7 +323,7 @@ const EditWebhookTabs = (props: EditWebhookTabsProps) => {
key={WebhookTabs.Settings.key}
onChangeTab={() => {
setActiveTab(WebhookTabs.Settings.key);
history.push(`${PLUGIN_ROOT}/outgoing_webhooks/edit/${id}`);
navigate(`${PLUGIN_ROOT}/outgoing_webhooks/edit/${id}`);
}}
active={activeTab === WebhookTabs.Settings.key}
label={WebhookTabs.Settings.value}
Expand All @@ -333,7 +333,7 @@ const EditWebhookTabs = (props: EditWebhookTabsProps) => {
key={WebhookTabs.LastRun.key}
onChangeTab={() => {
setActiveTab(WebhookTabs.LastRun.key);
history.push(`${PLUGIN_ROOT}/outgoing_webhooks/last_run/${id}`);
navigate(`${PLUGIN_ROOT}/outgoing_webhooks/last_run/${id}`);
}}
active={activeTab === WebhookTabs.LastRun.key}
label={WebhookTabs.LastRun.value}
Expand Down
4 changes: 2 additions & 2 deletions src/containers/PluginConfigPage/PluginConfigPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';

import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { useLocation as useLocationOriginal } from 'react-router-dom';
import { useLocation as useLocationOriginal } from 'react-router-dom-v5-compat';
import { OnCallPluginConfigPageProps } from 'types';

import { PluginState } from 'state/plugin/plugin';
Expand All @@ -17,7 +17,7 @@ jest.mock('../../../package.json', () => ({
version: 'v1.2.3',
}));

jest.mock('react-router-dom', () => ({
jest.mock('react-router-dom-v5-compat', () => ({
useLocation: jest.fn(() => ({
search: '',
})),
Expand Down
2 changes: 1 addition & 1 deletion src/containers/PluginConfigPage/PluginConfigPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { FC, useCallback, useEffect, useState } from 'react';

import { Button, HorizontalGroup, Label, Legend, LinkButton, LoadingPlaceholder, VerticalGroup } from '@grafana/ui';
import { useLocation } from 'react-router-dom';
import { useLocation } from 'react-router-dom-v5-compat';
import { OnCallPluginConfigPageProps } from 'types';

import { PluginState, PluginStatusResponseBase } from 'state/plugin/plugin';
Expand Down
12 changes: 7 additions & 5 deletions src/containers/Rotations/SchedulePersonal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { GrafanaTheme2 } from '@grafana/data';
import { Badge, BadgeColor, Button, HorizontalGroup, Icon, useStyles2, withTheme2 } from '@grafana/ui';
import dayjs from 'dayjs';
import { observer } from 'mobx-react';
import { RouteComponentProps, withRouter } from 'react-router-dom';
import { useNavigate } from 'react-router-dom-v5-compat';
import { CSSTransition, TransitionGroup } from 'react-transition-group';

import { Avatar } from 'components/Avatar/Avatar';
Expand All @@ -32,14 +32,16 @@ import { getRotationsStyles } from './Rotations.styles';

import animationStyles from './Rotations.module.css';

interface SchedulePersonalProps extends RouteComponentProps {
interface SchedulePersonalProps {
userPk: ApiSchemas['User']['pk'];
onSlotClick?: (event: Event) => void;
theme: GrafanaTheme2;
}

const _SchedulePersonal: FC<SchedulePersonalProps> = observer(({ userPk, onSlotClick, history }) => {
const _SchedulePersonal: FC<SchedulePersonalProps> = observer(({ userPk, onSlotClick }) => {
const store = useStore();
const navigate = useNavigate();

const { timezoneStore, scheduleStore, userStore } = store;
const updatePersonalEventsLoading = useIsLoading(ActionKey.UPDATE_PERSONAL_EVENTS);

Expand Down Expand Up @@ -77,7 +79,7 @@ const _SchedulePersonal: FC<SchedulePersonalProps> = observer(({ userPk, onSlotC
};

const openSchedule = (event: Event) => {
history.push(`${PLUGIN_ROOT}/schedules/${event.schedule?.id}`);
navigate(`${PLUGIN_ROOT}/schedules/${event.schedule?.id}`);
};

const currentTimeX = getCurrentTimeX(
Expand Down Expand Up @@ -172,4 +174,4 @@ const _SchedulePersonal: FC<SchedulePersonalProps> = observer(({ userPk, onSlotC
);
});

export const SchedulePersonal = withRouter(withTheme2(_SchedulePersonal));
export const SchedulePersonal = withTheme2(_SchedulePersonal);
8 changes: 4 additions & 4 deletions src/pages/NoMatch.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import React, { useEffect, useMemo } from 'react';

import qs from 'query-string';
import { useHistory } from 'react-router-dom';
import { useNavigate } from 'react-router-dom-v5-compat';

import { DEFAULT_PAGE, PLUGIN_ROOT } from 'utils/consts';
import { getPathFromQueryParams } from 'utils/url';

export const NoMatch = () => {
const history = useHistory();
const navigate = useNavigate();

const query = useMemo(() => qs.parse(window.location.search), [window.location.search]);

useEffect(() => {
if (query.page) {
const path = getPathFromQueryParams(query);
history.push(path);
navigate(path);
} else {
history.push(`${PLUGIN_ROOT}/${DEFAULT_PAGE}`);
navigate(`${PLUGIN_ROOT}/${DEFAULT_PAGE}`);
}
}, [query]);

Expand Down
49 changes: 33 additions & 16 deletions src/pages/escalation-chains/EscalationChains.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Button, HorizontalGroup, Icon, IconButton, Tooltip, VerticalGroup, withTheme2 } from '@grafana/ui';
import { observer } from 'mobx-react';
import { RouteComponentProps, withRouter } from 'react-router-dom';
import { getUtilStyles } from 'styles/utils.styles';

import { Collapse } from 'components/Collapse/Collapse';
Expand All @@ -30,10 +29,15 @@ import { PageProps, WithStoreProps } from 'state/types';
import { withMobXProviderContext } from 'state/withStore';
import { UserActions } from 'utils/authorization/authorization';
import { PAGE, PLUGIN_ROOT } from 'utils/consts';
import { PropsWithRouter, withRouter } from 'utils/hoc';

import { getEscalationChainStyles } from './EscalationChains.styles';

interface EscalationChainsPageProps extends WithStoreProps, PageProps, RouteComponentProps<{ id: string }> {
interface RouteProps {
id: string;
}

interface EscalationChainsPageProps extends WithStoreProps, PageProps, PropsWithRouter<RouteProps> {
theme: GrafanaTheme2;
}

Expand All @@ -60,7 +64,7 @@ class _EscalationChainsPage extends React.Component<EscalationChainsPageProps, E

const {
store,
match: {
router: {
params: { id },
},
} = this.props;
Expand Down Expand Up @@ -101,9 +105,11 @@ class _EscalationChainsPage extends React.Component<EscalationChainsPageProps, E
};

handleEsclalationSelect = (id: EscalationChain['id']) => {
const { history } = this.props;
const {
router: { navigate },
} = this.props;

history.push(`${PLUGIN_ROOT}/escalations/${id}${window.location.search}`);
navigate(`${PLUGIN_ROOT}/escalations/${id}${window.location.search}`);
};

setSelectedEscalationChain = async (escalationChainId: EscalationChain['id']) => {
Expand All @@ -119,15 +125,17 @@ class _EscalationChainsPage extends React.Component<EscalationChainsPageProps, E
};

componentDidUpdate(prevProps: EscalationChainsPageProps) {
if (this.props.match.params.id !== prevProps.match.params.id) {
const { router } = this.props;

if (router.params.id !== prevProps.router.params.id) {
this.parseQueryParams();
}
}

render() {
const {
store,
match: {
router: {
params: { id },
},
theme,
Expand Down Expand Up @@ -256,7 +264,7 @@ class _EscalationChainsPage extends React.Component<EscalationChainsPageProps, E

handleFiltersChange = (filters: FiltersValues, isOnMount = false) => {
const {
match: {
router: {
params: { id },
},
} = this.props;
Expand All @@ -272,15 +280,18 @@ class _EscalationChainsPage extends React.Component<EscalationChainsPageProps, E
};

autoSelectEscalationChain = () => {
const { store, history } = this.props;
const {
store,
router: { navigate },
} = this.props;
const { selectedEscalationChain } = this.state;
const { escalationChainStore } = store;

const searchResult = escalationChainStore.getSearchResult();

if (!searchResult.find((escalationChain: EscalationChain) => escalationChain.id === selectedEscalationChain)) {
const id = searchResult[0]?.id;
history.push(`${PLUGIN_ROOT}/escalations/${id || ''}${window.location.search}`);
navigate(`${PLUGIN_ROOT}/escalations/${id || ''}${window.location.search}`);
}
};

Expand Down Expand Up @@ -400,11 +411,13 @@ class _EscalationChainsPage extends React.Component<EscalationChainsPageProps, E

handleEscalationChainCreate = async (id: EscalationChain['id']) => {
const { selectedEscalationChain } = this.state;
const { history } = this.props;
const {
router: { navigate },
} = this.props;

await this.applyFilters();

history.push(`${PLUGIN_ROOT}/escalations/${id}${window.location.search}`);
navigate(`${PLUGIN_ROOT}/escalations/${id}${window.location.search}`);

// because this page wouldn't detect query.id change
if (selectedEscalationChain === id) {
Expand Down Expand Up @@ -444,7 +457,10 @@ class _EscalationChainsPage extends React.Component<EscalationChainsPageProps, E
};

handleDeleteEscalationChain = async () => {
const { store, history } = this.props;
const {
store,
router: { navigate },
} = this.props;
const { escalationChainStore } = store;
const { selectedEscalationChain, extraEscalationChains } = this.state;

Expand All @@ -464,10 +480,9 @@ class _EscalationChainsPage extends React.Component<EscalationChainsPageProps, E
}

const escalationChains = escalationChainStore.getSearchResult();

const newSelected = escalationChains[index - 1] || escalationChains[0];

history.push(`${PLUGIN_ROOT}/escalations/${newSelected?.id || ''}${window.location.search}`);
navigate(`${PLUGIN_ROOT}/escalations/${newSelected?.id || ''}${window.location.search}`);
};

handleEscalationChainNameChange = (value: string) => {
Expand All @@ -480,4 +495,6 @@ class _EscalationChainsPage extends React.Component<EscalationChainsPageProps, E
};
}

export const EscalationChainsPage = withRouter(withMobXProviderContext(withTheme2(_EscalationChainsPage)));
export const EscalationChainsPage = withRouter<RouteProps, Omit<EscalationChainsPageProps, 'store' | 'meta' | 'theme'>>(
withMobXProviderContext(withTheme2(_EscalationChainsPage))
);
Loading

0 comments on commit 9e9e4a5

Please sign in to comment.