diff --git a/apps/platform/.env b/apps/platform/.env index 66185f29a..fd275121a 100644 --- a/apps/platform/.env +++ b/apps/platform/.env @@ -1,3 +1,3 @@ -VITE_API_URL=https://api.partner-platform.dev.opentargets.xyz/api/v4/graphql +VITE_API_URL=https://api.platform.dev.opentargets.xyz/api/v4/graphql VITE_AI_API_URL=https://dev-ai-api-w37vlfsidq-ew.a.run.app VITE_PROFILE=default diff --git a/apps/platform/package.json b/apps/platform/package.json index 794bea94c..f12f0c5bd 100644 --- a/apps/platform/package.json +++ b/apps/platform/package.json @@ -34,7 +34,7 @@ "react-dropzone": "^14.2.3", "react-gtm-module": "^2.0.11", "react-helmet": "^6.0.0", - "react-router-dom": "5.1.2", + "react-router-dom": "6.28.0", "react-tsparticles": "^2.0.6", "sections": "*", "smiles-drawer": "^1.1.22", diff --git a/apps/platform/src/App.tsx b/apps/platform/src/App.tsx index a211cf2be..50279f113 100644 --- a/apps/platform/src/App.tsx +++ b/apps/platform/src/App.tsx @@ -1,4 +1,4 @@ -import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; +import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import { ApolloProvider } from "@apollo/client"; import { ThemeProvider, SearchProvider, PrivateRoute, ConfigurationProvider } from "ui"; @@ -33,49 +33,28 @@ function App(): ReactElement { searchPlaceholder="Search for a target, drug, disease, or phenotype..." > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + + } + /> + {/* } /> */} + diff --git a/apps/platform/src/components/AssociationsToolkit/components/Table/CellName.jsx b/apps/platform/src/components/AssociationsToolkit/components/Table/CellName.jsx index 4b93fe916..14c361fd3 100644 --- a/apps/platform/src/components/AssociationsToolkit/components/Table/CellName.jsx +++ b/apps/platform/src/components/AssociationsToolkit/components/Table/CellName.jsx @@ -21,7 +21,7 @@ import { faBezierCurve, } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { useHistory } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import useAotfContext from "../../hooks/useAotfContext"; import { ENTITIES, isPartnerPreview, TABLE_PREFIX } from "../../utils"; import { grey } from "@mui/material/colors"; @@ -85,7 +85,7 @@ const ContextMenuContainer = styled("div", { })); function CellName({ cell, colorScale }) { - const history = useHistory(); + const navigate = useNavigate(); const contextMenuRef = useRef(); const { entityToGet, pinnedEntries, setPinnedEntries, id: currentEntityId } = useAotfContext(); const { loading, prefix } = cell.table.getState(); @@ -180,15 +180,15 @@ function CellName({ cell, colorScale }) { }; const handleNavigateToProfile = () => { - history.push(profileURL); + navigate(profileURL); }; const handleNavigateToAssociations = () => { - history.push(associationsURL); + navigate(associationsURL); }; const handleNavigateToEvidence = () => { - history.push(evidenceURL); + navigate(evidenceURL); }; const loadingWidth = entityToGet === ENTITIES.TARGET ? 50 : 150; diff --git a/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx index 5202289f3..55b2b3b6e 100644 --- a/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx +++ b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx @@ -1,5 +1,5 @@ import { useQuery } from "@apollo/client"; -import { useLocation, useParams, Switch, Route, useRouteMatch, Link } from "react-router-dom"; +import { useLocation, useParams, Routes, Route, useMatch, Link } from "react-router-dom"; import { Box, Tabs, Tab } from "@mui/material"; import { BasePage, ScrollToTop } from "ui"; import Header from "./Header"; @@ -10,7 +10,7 @@ import Profile from "./Profile"; function CredibleSetPage() { const location = useLocation(); const { studyLocusId } = useParams() as { studyLocusId: string }; - const { path } = useRouteMatch(); + const { path } = useMatch(); const { loading, data } = useQuery(CREDIBLE_SET_PAGE_QUERY, { variables: { studyLocusId: studyLocusId }, @@ -62,7 +62,7 @@ function CredibleSetPage() { )} /> - + - + ); } diff --git a/apps/platform/src/pages/DiseasePage/DiseasePage.tsx b/apps/platform/src/pages/DiseasePage/DiseasePage.tsx index cff0d0ba2..c2a3f07a9 100644 --- a/apps/platform/src/pages/DiseasePage/DiseasePage.tsx +++ b/apps/platform/src/pages/DiseasePage/DiseasePage.tsx @@ -1,7 +1,7 @@ import { ReactElement } from "react"; import { useQuery } from "@apollo/client"; import { Box, Tab, Tabs } from "@mui/material"; -import { Link, Redirect, Route, Switch, useLocation, useParams } from "react-router-dom"; +import { Link, Navigate, Route, Routes, useLocation, useParams } from "react-router-dom"; import { BasePage, ScrollToTop } from "ui"; import Header from "./Header"; @@ -44,7 +44,7 @@ function DiseasePage(): ReactElement { >
- ( @@ -64,18 +64,14 @@ function DiseasePage(): ReactElement { )} - /> - - - - - - - - - - - + /> */} + + } /> + } /> + {/* + + */} + ); } diff --git a/apps/platform/src/pages/DrugPage/DrugPage.jsx b/apps/platform/src/pages/DrugPage/DrugPage.jsx index 92f384dbc..0c448d9ac 100644 --- a/apps/platform/src/pages/DrugPage/DrugPage.jsx +++ b/apps/platform/src/pages/DrugPage/DrugPage.jsx @@ -1,15 +1,7 @@ import { useQuery } from "@apollo/client"; import { BasePage, ScrollToTop } from "ui"; import { Box, Tabs, Tab } from "@mui/material"; -import { - useLocation, - useParams, - Switch, - Route, - useRouteMatch, - Link, - Redirect, -} from "react-router-dom"; +import { useLocation, useParams, Routes, Route, useMatch, Link, Navigate } from "react-router-dom"; import Header from "./Header"; import NotFoundPage from "../NotFoundPage"; @@ -20,7 +12,7 @@ import Profile from "./Profile"; function DrugPage() { const location = useLocation(); const { chemblId } = useParams(); - const { path } = useRouteMatch(); + const { path } = useMatch(); const { loading, data } = useQuery(DRUG_PAGE_QUERY, { variables: { chemblId }, @@ -56,14 +48,14 @@ function DrugPage() { )} /> - + - + - + ); } diff --git a/apps/platform/src/pages/SearchPage/SearchPage.jsx b/apps/platform/src/pages/SearchPage/SearchPage.jsx index f17c12888..d89142190 100644 --- a/apps/platform/src/pages/SearchPage/SearchPage.jsx +++ b/apps/platform/src/pages/SearchPage/SearchPage.jsx @@ -1,7 +1,7 @@ import { useState, useEffect, lazy, Suspense } from "react"; import queryString from "query-string"; import { Typography } from "@mui/material"; -import { useLocation, useHistory } from "react-router-dom"; +import { useLocation, useNavigate } from "react-router-dom"; import { LoadingBackdrop, EmptyPage, BasePage } from "ui"; import client from "../../client"; @@ -28,7 +28,7 @@ const parseQueryString = qs => { function SearchPage() { const location = useLocation(); - const history = useHistory(); + const navigate = useNavigate(); const { q, page, entities } = parseQueryString(location.search); const [data, setData] = useState(null); @@ -57,7 +57,7 @@ function SearchPage() { const handleChangePage = (event, pageChanged) => { const params = { q, page: pageChanged + 1, entities }; const qs = queryString.stringify(params, QS_OPTIONS); - history.push(`/search?${qs}`); + navigate(`/search?${qs}`); }; const handleSetEntity = entity => (event, checked) => { @@ -67,7 +67,7 @@ function SearchPage() { entities: checked ? [...entities, entity] : entities.filter(e => e !== entity), }; const qs = queryString.stringify(params, QS_OPTIONS); - history.push(`/search?${qs}`); + navigate(`/search?${qs}`); }; let SEARCH_CONTAINER = null; diff --git a/apps/platform/src/pages/StudyPage/StudyPage.tsx b/apps/platform/src/pages/StudyPage/StudyPage.tsx index 81dba7ef6..f75073977 100644 --- a/apps/platform/src/pages/StudyPage/StudyPage.tsx +++ b/apps/platform/src/pages/StudyPage/StudyPage.tsx @@ -1,15 +1,7 @@ import { useQuery } from "@apollo/client"; import { BasePage, ScrollToTop } from "ui"; import { Box, Tabs, Tab } from "@mui/material"; -import { - useLocation, - useParams, - Switch, - Route, - useRouteMatch, - Link, - Redirect, -} from "react-router-dom"; +import { useLocation, useParams, Routes, Route, useMatch, Link, Navigate } from "react-router-dom"; import Header from "./Header"; import NotFoundPage from "../NotFoundPage"; import STUDY_PAGE_QUERY from "./StudyPage.gql"; @@ -18,7 +10,7 @@ import Profile from "./Profile"; function StudyPage() { const location = useLocation(); const { studyId } = useParams() as { studyId: string }; - const { path } = useRouteMatch(); + const { path } = useMatch(); const { loading, data } = useQuery(STUDY_PAGE_QUERY, { variables: { studyId }, @@ -63,7 +55,7 @@ function StudyPage() { )} /> - + - + - + ); } diff --git a/apps/platform/src/pages/TargetPage/TargetPage.tsx b/apps/platform/src/pages/TargetPage/TargetPage.tsx index d59368d6d..8f36aa8be 100644 --- a/apps/platform/src/pages/TargetPage/TargetPage.tsx +++ b/apps/platform/src/pages/TargetPage/TargetPage.tsx @@ -1,15 +1,7 @@ import { ReactElement } from "react"; import { useQuery } from "@apollo/client"; import { Box, Tab, Tabs } from "@mui/material"; -import { - Link, - Route, - Switch, - useLocation, - useRouteMatch, - useParams, - Redirect, -} from "react-router-dom"; +import { Link, Route, Routes, useLocation, useMatch, useParams, Navigate } from "react-router-dom"; import { BasePage, ScrollToTop } from "ui"; import Header from "./Header"; @@ -27,7 +19,7 @@ type TargetURLParams = { function TargetPage(): ReactElement { const location = useLocation(); const { ensgId } = useParams(); - const { path } = useRouteMatch(); + const { path } = useMatch(); const { loading, data } = useQuery(TARGET_PAGE_QUERY, { variables: { ensgId }, @@ -90,7 +82,7 @@ function TargetPage(): ReactElement { )} /> - + @@ -98,9 +90,9 @@ function TargetPage(): ReactElement { - + - + ); } diff --git a/apps/platform/src/pages/VariantPage/VariantPage.tsx b/apps/platform/src/pages/VariantPage/VariantPage.tsx index 02ae6d28b..0846ab6d2 100644 --- a/apps/platform/src/pages/VariantPage/VariantPage.tsx +++ b/apps/platform/src/pages/VariantPage/VariantPage.tsx @@ -1,5 +1,5 @@ import { useQuery } from "@apollo/client"; -import { useLocation, useParams, Switch, Route, useRouteMatch, Link } from "react-router-dom"; +import { useLocation, useParams, Routes, Route, useMatch, Link } from "react-router-dom"; import { Box, Tabs, Tab } from "@mui/material"; import { BasePage, ScrollToTop } from "ui"; import Header from "./Header"; @@ -10,7 +10,7 @@ import Profile from "./Profile"; function VariantPage() { const location = useLocation(); const { varId } = useParams() as { varId: string }; - const { path } = useRouteMatch(); + const { path } = useMatch(); const { loading, data } = useQuery(VARIANT_PAGE_QUERY, { variables: { variantId: varId }, @@ -44,11 +44,11 @@ function VariantPage() { )} /> - + - + ); } diff --git a/packages/sections/package.json b/packages/sections/package.json index 6371354a4..ad537efca 100644 --- a/packages/sections/package.json +++ b/packages/sections/package.json @@ -35,7 +35,7 @@ "react": "^18.2.0", "react-helmet": "^6.0.0", "react-measure": "^2.1.2", - "react-router-dom": "5.1.2", + "react-router-dom": "6.28.0", "recoil": "^0.3.0", "smiles-drawer": "^1.1.22", "tsparticles": "^2.0.6", diff --git a/packages/ui/package.json b/packages/ui/package.json index 6aa53223a..4f808f704 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -30,7 +30,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-helmet": "^6.1.0", - "react-router-dom": "5.1.2", + "react-router-dom": "6.28.0", "react-scroll": "^1.8.9", "uuid": "^9.0.1" }, diff --git a/packages/ui/src/components/EntityPanel/EntityPanel.tsx b/packages/ui/src/components/EntityPanel/EntityPanel.tsx new file mode 100644 index 000000000..ff1abb7e5 --- /dev/null +++ b/packages/ui/src/components/EntityPanel/EntityPanel.tsx @@ -0,0 +1,4 @@ +function EntityPanel() { + return
EntityPanel
; +} +export default EntityPanel; diff --git a/packages/ui/src/components/PrivateRoute.jsx b/packages/ui/src/components/PrivateRoute.jsx index b97146241..bae2973ae 100644 --- a/packages/ui/src/components/PrivateRoute.jsx +++ b/packages/ui/src/components/PrivateRoute.jsx @@ -1,11 +1,11 @@ -import { Redirect } from "react-router-dom"; +import { Navigate } from "react-router-dom"; import usePermissions from "../hooks/usePermissions"; function PrivateRoute({ children }) { const { isPartnerPreview } = usePermissions(); if (!isPartnerPreview) { - return ; + return ; } return children; diff --git a/packages/ui/src/components/RoutingTabs/RoutingTabs.jsx b/packages/ui/src/components/RoutingTabs/RoutingTabs.jsx index 78a8de315..a00179f92 100644 --- a/packages/ui/src/components/RoutingTabs/RoutingTabs.jsx +++ b/packages/ui/src/components/RoutingTabs/RoutingTabs.jsx @@ -1,12 +1,12 @@ import { Suspense, Children, cloneElement } from "react"; -import { generatePath, Route, Switch, useHistory, useRouteMatch } from "react-router-dom"; +import { generatePath, Route, Routes, useNavigate, useMatch } from "react-router-dom"; import { Tabs, Box } from "@mui/material"; import { v1 } from "uuid"; import LoadingBackdrop from "../LoadingBackdrop"; function RoutingTabs({ children }) { - const match = useRouteMatch(); - const history = useHistory(); + const match = useMatch(); + const history = useNavigate(); const routes = []; const preparedChildren = Children.map(children, child => { @@ -31,7 +31,7 @@ function RoutingTabs({ children }) { {preparedChildren} }> - + {routes.map((route, index) => ( ))} - + ); diff --git a/packages/ui/src/components/ScrollToTop.tsx b/packages/ui/src/components/ScrollToTop.tsx index 41bf06c62..c0940afab 100644 --- a/packages/ui/src/components/ScrollToTop.tsx +++ b/packages/ui/src/components/ScrollToTop.tsx @@ -1,20 +1,14 @@ -import { Component } from "react"; -import { RouteComponentProps, withRouter } from "react-router-dom"; +import { useEffect } from "react"; +import { useLocation } from "react-router-dom"; -class ScrollToTop extends Component { - componentDidMount() { - window.scrollTo(0, 0); - } +const ScrollToTop = () => { + const location = useLocation(); - componentDidUpdate(prevProps: RouteComponentProps) { - if (this.props.location.pathname !== prevProps.location.pathname) { - window.scrollTo(0, 0); - } - } + useEffect(() => { + window.scrollTo(0, 0); + }, [location.pathname]); - render() { - return null; - } -} + return null; +}; -export default withRouter(ScrollToTop); +export default ScrollToTop; diff --git a/packages/ui/src/hooks/useListOption.js b/packages/ui/src/hooks/useListOption.js index 2199d8415..4f7621adc 100644 --- a/packages/ui/src/hooks/useListOption.js +++ b/packages/ui/src/hooks/useListOption.js @@ -1,8 +1,8 @@ -import { useHistory } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import { addSearchToLocalStorage } from "../components/GlobalSearch/utils/searchUtils"; function useListOption() { - const history = useHistory(); + const navigate = useNavigate(); const openListItem = option => { if (!option) return; @@ -11,16 +11,14 @@ function useListOption() { addSearchToLocalStorage(newOption); if (newOption.entity === "search") { - history.push(`/search?q=${newOption.name}&page=1`); + navigate(`/search?q=${newOption.name}&page=1`); } else if (newOption.entity === "study") { - history.push(`/${newOption.entity}/${newOption.studyId}`); + navigate(`/${newOption.entity}/${newOption.studyId}`); } else { - history.push( + navigate( `/${newOption.entity}/${newOption.id}${ - newOption.entity !== "drug" && newOption.entity !== "variant" - ? "/associations" - : "" - }` + newOption.entity !== "drug" && newOption.entity !== "variant" ? "/associations" : "" + }` ); } }; diff --git a/packages/ui/src/hooks/useStateParams.ts b/packages/ui/src/hooks/useStateParams.ts index c90a5a692..961127042 100644 --- a/packages/ui/src/hooks/useStateParams.ts +++ b/packages/ui/src/hooks/useStateParams.ts @@ -1,5 +1,5 @@ import { useEffect, useState } from "react"; -import { useHistory } from "react-router-dom"; +import { useLocation, useNavigate } from "react-router-dom"; function useStateParams( initialState: T, @@ -7,8 +7,9 @@ function useStateParams( serialize: (state: T) => string, deserialize: (state: string) => T ): [T, (state: T) => void] { - const history = useHistory(); - const search = new URLSearchParams(history.location.search); + const navigate = useNavigate(); + const location = useLocation(); + const search = new URLSearchParams(location.search); const existingValue = search.get(paramsName); const [state, setState] = useState(existingValue ? deserialize(existingValue) : initialState); @@ -22,10 +23,10 @@ function useStateParams( const onChange = (s: T) => { setState(s); - const searchParams = new URLSearchParams(history.location.search); + const searchParams = new URLSearchParams(location.search); searchParams.set(paramsName, serialize(s)); - const { pathname } = history.location; - history.push({ pathname, search: searchParams.toString() }); + const { pathname } = location; + navigate({ pathname, search: searchParams.toString() }); }; return [state, onChange]; diff --git a/packages/ui/src/index.tsx b/packages/ui/src/index.tsx index 818efb463..813621526 100644 --- a/packages/ui/src/index.tsx +++ b/packages/ui/src/index.tsx @@ -39,6 +39,7 @@ export { default as ApiPlaygroundDrawer } from "./components/ApiPlaygroundDrawer export { default as OtTable } from "./components/OtTable/OtTable"; export { default as OtPopper } from "./components/OtPopper"; export { default as OtScoreLinearBar } from "./components/OtScoreLinearBar"; +export { default as EntityPanel } from "./components/EntityPanel/EntityPanel"; export { default as EmptyPage } from "./pages/EmptyPage"; export { default as NotFoundPage } from "./pages/NotFoundPage"; diff --git a/yarn.lock b/yarn.lock index cde279ecb..509d20496 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2778,6 +2778,11 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== +"@remix-run/router@1.21.0": + version "1.21.0" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.21.0.tgz#c65ae4262bdcfe415dbd4f64ec87676e4a56e2b5" + integrity sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA== + "@repeaterjs/repeater@3.0.4": version "3.0.4" resolved "https://registry.yarnpkg.com/@repeaterjs/repeater/-/repeater-3.0.4.tgz#a04d63f4d1bf5540a41b01a921c9a7fddc3bd1ca" @@ -6494,7 +6499,7 @@ d3-array@2, d3-array@^2.3.0, d3-array@^2.8.0: dependencies: internmap "^1.0.0" -"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3, d3-array@^3.2.0, d3-array@^3.2.4: +"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3, d3-array@^3.2.0: version "3.2.4" resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5" integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== @@ -14421,6 +14426,14 @@ react-router-dom@5.1.2: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" +react-router-dom@6.28.0: + version "6.28.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.28.0.tgz#f73ebb3490e59ac9f299377062ad1d10a9f579e6" + integrity sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg== + dependencies: + "@remix-run/router" "1.21.0" + react-router "6.28.0" + react-router@5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.1.2.tgz#6ea51d789cb36a6be1ba5f7c0d48dd9e817d3418" @@ -14437,6 +14450,13 @@ react-router@5.1.2: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" +react-router@6.28.0: + version "6.28.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.28.0.tgz#29247c86d7ba901d7e5a13aa79a96723c3e59d0d" + integrity sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg== + dependencies: + "@remix-run/router" "1.21.0" + react-scripts@4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-4.0.3.tgz#b1cafed7c3fa603e7628ba0f187787964cb5d345"