From 33e22729ee7317f5afecb79f06b4f873dc3e376d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Herv=C3=A9=20Dombya?=
<135591453+hervedombya@users.noreply.github.com>
Date: Thu, 28 Nov 2024 11:22:41 +0100
Subject: [PATCH] Update react-router to v6 and refactor navigation hooks in
components
---
package-lock.json | 118 +++++-------------
package.json | 4 +-
.../emptystate/Emptystate.component.tsx | 6 +-
.../tablev2/SearchWithQueryParams.tsx | 6 +-
.../components/tabsv2/Tabsv2.component.tsx | 102 +++++++--------
.../AttachmentConfirmationModal.tsx | 14 +--
6 files changed, 93 insertions(+), 157 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index baf0fc5e4e..54197fd4fe 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,8 +27,8 @@
"react-dropzone": "^14.2.3",
"react-hook-form": "^7.49.2",
"react-query": "^3.34.0",
- "react-router": "5.2.0",
- "react-router-dom": "5.2.0",
+ "react-router": "^6.28.0",
+ "react-router-dom": "^6.28.0",
"react-select": "4.3.1",
"react-table": "^7.7.0",
"react-test-renderer": "^18.3.1",
@@ -3576,6 +3576,14 @@
"integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==",
"dev": true
},
+ "node_modules/@remix-run/router": {
+ "version": "1.21.0",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.21.0.tgz",
+ "integrity": "sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/@rtsao/scc": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
@@ -12458,19 +12466,6 @@
"resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz",
"integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q=="
},
- "node_modules/history": {
- "version": "4.10.1",
- "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
- "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
- "dependencies": {
- "@babel/runtime": "^7.1.2",
- "loose-envify": "^1.2.0",
- "resolve-pathname": "^3.0.0",
- "tiny-invariant": "^1.0.2",
- "tiny-warning": "^1.0.0",
- "value-equal": "^1.0.1"
- }
- },
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@@ -13790,7 +13785,8 @@
"node_modules/isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="
+ "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
+ "dev": true
},
"node_modules/isbinaryfile": {
"version": "4.0.10",
@@ -16795,20 +16791,6 @@
"node": ">=4"
}
},
- "node_modules/mini-create-react-context": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz",
- "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==",
- "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
- "dependencies": {
- "@babel/runtime": "^7.12.1",
- "tiny-warning": "^1.0.3"
- },
- "peerDependencies": {
- "prop-types": "^15.0.0",
- "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/minimatch": {
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
@@ -18884,55 +18866,35 @@
}
},
"node_modules/react-router": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz",
- "integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==",
- "dependencies": {
- "@babel/runtime": "^7.1.2",
- "history": "^4.9.0",
- "hoist-non-react-statics": "^3.1.0",
- "loose-envify": "^1.3.1",
- "mini-create-react-context": "^0.4.0",
- "path-to-regexp": "^1.7.0",
- "prop-types": "^15.6.2",
- "react-is": "^16.6.0",
- "tiny-invariant": "^1.0.2",
- "tiny-warning": "^1.0.0"
+ "version": "6.28.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.28.0.tgz",
+ "integrity": "sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg==",
+ "dependencies": {
+ "@remix-run/router": "1.21.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
},
"peerDependencies": {
- "react": ">=15"
+ "react": ">=16.8"
}
},
"node_modules/react-router-dom": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz",
- "integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==",
+ "version": "6.28.0",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.28.0.tgz",
+ "integrity": "sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg==",
"dependencies": {
- "@babel/runtime": "^7.1.2",
- "history": "^4.9.0",
- "loose-envify": "^1.3.1",
- "prop-types": "^15.6.2",
- "react-router": "5.2.0",
- "tiny-invariant": "^1.0.2",
- "tiny-warning": "^1.0.0"
+ "@remix-run/router": "1.21.0",
+ "react-router": "6.28.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
},
"peerDependencies": {
- "react": ">=15"
- }
- },
- "node_modules/react-router/node_modules/path-to-regexp": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz",
- "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==",
- "dependencies": {
- "isarray": "0.0.1"
+ "react": ">=16.8",
+ "react-dom": ">=16.8"
}
},
- "node_modules/react-router/node_modules/react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
- },
"node_modules/react-select": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/react-select/-/react-select-4.3.1.tgz",
@@ -19625,11 +19587,6 @@
"node": ">=4"
}
},
- "node_modules/resolve-pathname": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz",
- "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng=="
- },
"node_modules/resolve-url": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@@ -21579,12 +21536,8 @@
"node_modules/tiny-invariant": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
- "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="
- },
- "node_modules/tiny-warning": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
- "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
+ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
+ "dev": true
},
"node_modules/title-case": {
"version": "2.1.1",
@@ -22581,11 +22534,6 @@
"spdx-expression-parse": "^3.0.0"
}
},
- "node_modules/value-equal": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
- "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw=="
- },
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
diff --git a/package.json b/package.json
index bb7dce11c3..a868848960 100644
--- a/package.json
+++ b/package.json
@@ -115,8 +115,8 @@
"react-dropzone": "^14.2.3",
"react-hook-form": "^7.49.2",
"react-query": "^3.34.0",
- "react-router": "5.2.0",
- "react-router-dom": "5.2.0",
+ "react-router": "^6.28.0",
+ "react-router-dom": "^6.28.0",
"react-select": "4.3.1",
"react-table": "^7.7.0",
"react-test-renderer": "^18.3.1",
diff --git a/src/lib/components/emptystate/Emptystate.component.tsx b/src/lib/components/emptystate/Emptystate.component.tsx
index 41c95b8e7a..a39e412593 100644
--- a/src/lib/components/emptystate/Emptystate.component.tsx
+++ b/src/lib/components/emptystate/Emptystate.component.tsx
@@ -4,7 +4,7 @@ import { Button } from '../buttonv2/Buttonv2.component';
import { Icon, IconName } from '../icon/Icon.component';
import { LargeText } from '../text/Text.component';
import { CoreUITheme } from '../../style/theme';
-import { useHistory } from 'react-router';
+import { useNavigate } from 'react-router';
export type Props = {
listedResource: {
@@ -48,7 +48,7 @@ export const ActionWrapper = styled.div`
function EmptyState(props: Props) {
const { icon, listedResource, link, resourceToCreate, backgroundColor } =
props;
- const history = useHistory();
+ const navigate = useNavigate();
return (
}
type="button"
variant="primary"
- onClick={() => history.push(link)}
+ onClick={() => navigate(link)}
/>
)}
diff --git a/src/lib/components/tablev2/SearchWithQueryParams.tsx b/src/lib/components/tablev2/SearchWithQueryParams.tsx
index 12890c4ab7..8efbda41f5 100644
--- a/src/lib/components/tablev2/SearchWithQueryParams.tsx
+++ b/src/lib/components/tablev2/SearchWithQueryParams.tsx
@@ -1,5 +1,5 @@
import { useState } from 'react';
-import { useLocation, useHistory } from 'react-router-dom';
+import { useLocation, useNavigate } from 'react-router-dom';
import { TableSearch as Search, SearchProps } from './Search';
export type SearchWithQueryParamsProps = {
@@ -10,7 +10,7 @@ export type SearchWithQueryParamsProps = {
export function SearchWithQueryParams(props: SearchWithQueryParamsProps) {
const { queryParams = 'search', onChange, ...rest } = props;
const { search, pathname } = useLocation();
- const history = useHistory();
+ const navigate = useNavigate();
const params = new URLSearchParams(search);
const initialValue = params.get(queryParams) || '';
const [value, setValue] = useState(initialValue);
@@ -18,7 +18,7 @@ export function SearchWithQueryParams(props: SearchWithQueryParamsProps) {
function handleOnChange(value: string) {
const { onChange } = props;
params.set(queryParams, value);
- history.replace(`${pathname}?${params.toString()}`);
+ navigate(`${pathname}?${params.toString()}`, { replace: true });
setValue(value);
if (typeof onChange === 'function') {
diff --git a/src/lib/components/tabsv2/Tabsv2.component.tsx b/src/lib/components/tabsv2/Tabsv2.component.tsx
index f7ff371c3a..c81176648a 100644
--- a/src/lib/components/tabsv2/Tabsv2.component.tsx
+++ b/src/lib/components/tabsv2/Tabsv2.component.tsx
@@ -1,33 +1,25 @@
import React, {
createContext,
+ ReactElement,
+ useCallback,
useEffect,
useState,
- useCallback,
- ReactElement,
} from 'react';
+import { Route, Routes, useLocation, useNavigate } from 'react-router-dom';
+import styled from 'styled-components';
+import { ButtonIcon } from '../buttonv2/Buttonv2.component';
+import { BasicText, EmphaseText, SecondaryText } from '../text/Text.component';
+import { ScrollButton } from './ScrollButton';
import {
- TabBar,
ScrollableContainer,
+ TabBar,
TabContent,
TabItem,
TabsContainer,
TabsScroller,
} from './StyledTabs';
-import {
- useHistory,
- useLocation,
- useRouteMatch,
- matchPath,
- Route,
- Switch,
-} from 'react-router-dom';
-import { SecondaryText, BasicText, EmphaseText } from '../text/Text.component';
-import { ScrollButton } from './ScrollButton';
-import { Tab } from './Tab';
-import { TabProps, Query } from './Tab';
+import { Query, Tab, TabProps } from './Tab';
import { useScrollingTabs } from './useScrollingTabs';
-import { ButtonIcon } from '../buttonv2/Buttonv2.component';
-import styled from 'styled-components';
type TabsProps = {
activeTabColor?: string;
@@ -59,8 +51,8 @@ function Tabs({
...rest
}: TabsProps) {
const location = useLocation();
- const history = useHistory();
- const { url } = useRouteMatch();
+ const navigate = useNavigate();
+ const url = location.pathname;
const [selectedTabIndex, setSelectedTabIndex] = useState<
number | null | undefined
>(null);
@@ -110,15 +102,13 @@ function Tabs({
useEffect(() => {
let hasSelectedTab = false;
filteredTabsChildren.forEach((child, index) => {
+ const fullPath = child.props.path.startsWith('/')
+ ? child.props.path
+ : url + '/' + child.props.path;
+
const isSelected =
- !!matchPath(location.pathname, {
- path: child.props.path.startsWith('/')
- ? child.props.path
- : url + '/' + child.props.path,
- exact: child.props.exact,
- strict: child.props.strict,
- sensitive: child.props.sensitive,
- }) && (child.props.query ? matchQuery(child.props.query) : true);
+ location.pathname.match(new RegExp(`^${fullPath}$`, 'i')) &&
+ (child.props.query ? matchQuery(child.props.query) : true);
if (isSelected) {
setSelectedTabIndex(index);
@@ -127,6 +117,7 @@ function Tabs({
});
if (!hasSelectedTab) setSelectedTabIndex(null);
}, [location.pathname, filteredTabsChildren, matchQuery]);
+
const {
scrollButtonEndRef,
scrollButtonStartRef,
@@ -154,7 +145,7 @@ function Tabs({
className={`sc-tabs-item ${isSelected ? 'selected' : ''}`}
key={index}
role="tab"
- onClick={() => history.push(getPushHistoryPath(path, query))}
+ onClick={() => navigate(getPushHistoryPath(path, query))}
selected={isSelected}
tabHoverColor={tabHoverColor}
inactiveTabColor={inactiveTabColor}
@@ -168,7 +159,7 @@ function Tabs({
event.key === 'Spacebar'
) {
event.preventDefault();
- history.push(getPushHistoryPath(path, query));
+ navigate(getPushHistoryPath(path, query));
}
}}
{...childRest}
@@ -218,33 +209,30 @@ function Tabs({
/>
)}
-
- {filteredTabsChildren.map((tab, index) => (
-
- {!tab.props.query ||
- (tab.props.query && matchQuery(tab.props.query)) ? (
-
- {tab.props.children}
-
- ) : (
- <>>
- )}
-
- ))}
+
+ {filteredTabsChildren.map((tab, index) => (
+
+ {tab.props.children}
+
+ ) : null
+ }
+ />
+ ))}
+
);
@@ -252,4 +240,4 @@ function Tabs({
Tabs.Tab = Tab;
// re-export Tab
-export { Tabs, Tab };
+export { Tab, Tabs };
diff --git a/src/lib/organisms/attachments/AttachmentConfirmationModal.tsx b/src/lib/organisms/attachments/AttachmentConfirmationModal.tsx
index 2a9bbce229..54f2cc4aed 100644
--- a/src/lib/organisms/attachments/AttachmentConfirmationModal.tsx
+++ b/src/lib/organisms/attachments/AttachmentConfirmationModal.tsx
@@ -1,11 +1,11 @@
import { ComponentType, useState } from 'react';
-import { Column, Table } from '../../components/tablev2/Tablev2.component';
-import { Box, Button } from '../../next';
import { useMutation, UseMutationOptions } from 'react-query';
-import { AttachmentOperation, AttachmentAction } from './AttachmentTypes';
+import { useNavigate } from 'react-router';
import { useTheme } from 'styled-components';
-import { useHistory } from 'react-router';
import { Icon, LargerText, Modal, SecondaryText, Stack, Wrap } from '../..';
+import { Column, Table } from '../../components/tablev2/Tablev2.component';
+import { Box, Button } from '../../next';
+import { AttachmentAction, AttachmentOperation } from './AttachmentTypes';
type AttachmentStatus = 'Waiting for confirmation' | 'Error' | 'Success';
@@ -50,7 +50,7 @@ export function AttachmentConfirmationModal<
failedOperations: AttachmentOperation[],
) => void;
}) {
- const history = useHistory();
+ const navigate = useNavigate();
const [isModalOpen, setIsModalOpen] = useState(false);
@@ -135,7 +135,7 @@ export function AttachmentConfirmationModal<
onExit(successfulOperations, failedOperations);
}
handleClose();
- history.push(redirectUrl);
+ navigate(redirectUrl);
};
const modalFooter = () => {
return (
@@ -284,7 +284,7 @@ export function AttachmentConfirmationModal<
disabled={cancelButtonDisabled}
onClick={() => {
if (onCancel) onCancel();
- history.push(redirectUrl);
+ navigate(redirectUrl);
}}
/>