From 77541f2c304b117209c1eea7e4c595c803855bca Mon Sep 17 00:00:00 2001 From: Valery Bugakov Date: Mon, 20 Feb 2023 22:32:51 -0800 Subject: [PATCH] web: upgrade `react-router` to v6 (#47595) - Closes #33834 - Upgraded react-router to v6 - Migrated the web application to [the data-aware router introduced in v6.4.0](https://reactrouter.com/en/main/routers/picking-a-router#using-v64-data-apis). - Migrated `history.block` usages to the `unstable_useBlock` hook [introduced in v6.7.0](https://github.com/remix-run/react-router/issues/8139). - Removed explicit history reference from the `renderWithBrandedContext` utility used in unit tests. - Migrated the search-query state observer from `history.listen` to `useLocation` API. ## Test plan CI and manually visiting all the pages. --- .../panel/TabbedPanelContent.test.tsx | 6 +- .../components/panel/TabbedPanelContent.tsx | 2 +- .../components/FileMatchChildren.tsx | 2 +- .../search-ui/components/QueryExamples.tsx | 2 +- .../components/SymbolSearchResult.tsx | 2 +- .../components/codeLinkNavigation.ts | 2 +- .../search-ui/input/CodeMirrorQueryInput.tsx | 2 +- .../search-ui/input/codemirror/completion.ts | 2 +- .../src/search-ui/input/codemirror/index.ts | 2 +- .../CodeMirrorQueryInputWrapper.tsx | 2 +- .../results/StreamingSearchResultsList.tsx | 2 +- .../shared/components/HoverOverlay.story.tsx | 23 +-- client/common/src/types/utils.ts | 7 + client/common/src/util/compatNavigate.ts | 2 +- .../search/input/JetBrainsSearchBox.story.tsx | 73 ++++---- .../vscode/src/webview/search-panel/index.tsx | 7 +- .../sidebars/search/SearchSidebarView.tsx | 2 +- .../web/dev/utils/get-api-proxy-settings.ts | 3 +- client/web/src/Layout.tsx | 9 +- client/web/src/LegacyLayout.tsx | 9 +- client/web/src/LegacySourcegraphWebApp.tsx | 150 +++++---------- client/web/src/SearchQueryStateObserver.tsx | 99 ++++++++++ client/web/src/SourcegraphWebApp.tsx | 172 ++++++------------ client/web/src/api/ApiConsole.tsx | 2 +- client/web/src/auth/ResetPasswordPage.tsx | 2 +- client/web/src/auth/SignInPage.test.tsx | 2 +- client/web/src/auth/SignInPage.tsx | 2 +- client/web/src/auth/SignUpPage.test.tsx | 2 +- client/web/src/auth/SignUpPage.tsx | 2 +- client/web/src/auth/UnlockAccount.tsx | 2 +- .../src/auth/UsernamePasswordSignInForm.tsx | 2 +- client/web/src/auth/withAuthenticatedUser.tsx | 2 +- .../code-monitoring/CodeMonitoringNavItem.tsx | 15 -- .../src/codeintel/ReferencesPanel.test.tsx | 7 +- client/web/src/codeintel/ReferencesPanel.tsx | 2 +- .../CommunitySearchContextPage.tsx | 2 +- client/web/src/components/AwayPrompt.tsx | 62 +++---- client/web/src/components/Breadcrumbs.tsx | 2 +- .../FilteredConnection.test.tsx | 2 +- .../FilteredConnection/FilteredConnection.tsx | 2 +- .../hooks/usePageSwitcherPagination.test.tsx | 20 +- .../hooks/usePageSwitcherPagination.ts | 2 +- .../hooks/useShowMorePagination.test.tsx | 16 +- .../hooks/useShowMorePaginationUrl.ts | 2 +- .../src/components/LinkWithIcon.module.scss | 8 - client/web/src/components/LinkWithIcon.tsx | 36 ---- client/web/src/components/RedirectRoute.tsx | 2 +- client/web/src/components/Sidebar.tsx | 39 ++-- .../WebHoverOverlay/WebHoverOverlay.tsx | 2 +- client/web/src/components/WebStory.tsx | 41 +++-- .../web/src/components/diff/DiffHunk.test.tsx | 21 +-- client/web/src/components/diff/DiffHunk.tsx | 2 +- .../components/diff/DiffSplitHunk.test.tsx | 21 +-- .../web/src/components/diff/DiffSplitHunk.tsx | 2 +- .../web/src/components/diff/FileDiffNode.tsx | 2 +- .../AddExternalServicePage.tsx | 2 +- .../AddExternalServicesPage.tsx | 2 +- .../ExternalServiceEditPage.tsx | 2 +- .../externalServices/ExternalServicePage.tsx | 2 +- .../externalServices/ExternalServicesPage.tsx | 2 +- client/web/src/components/useUserHistory.ts | 2 +- client/web/src/contributions.ts | 2 +- .../batch-spec/edit/EditBatchSpecPage.tsx | 2 +- .../batch-spec/edit/library/LibraryPane.tsx | 2 +- .../batch-spec/edit/useExecuteBatchSpec.ts | 2 +- .../WorkspacesPreviewFilterRow.tsx | 2 +- .../batch-spec/execute/ActionsMenu.tsx | 2 +- .../execute/ExecuteBatchSpecPage.tsx | 2 +- .../execute/ReadOnlyBatchSpecForm.tsx | 2 +- .../workspaces/ExecutionWorkspaces.tsx | 2 +- .../workspaces/WorkspacesFilterRow.tsx | 2 +- .../execute/workspaces/WorkspacesListItem.tsx | 2 +- .../batches/close/BatchChangeCloseAlert.tsx | 2 +- .../batches/close/BatchChangeClosePage.tsx | 2 +- .../batches/create/ConfigurationForm.tsx | 2 +- .../batches/create/useInsightTemplates.ts | 2 +- .../batches/create/useSearchTemplate.ts | 2 +- .../BatchChangeDetailsActionSection.tsx | 2 +- .../batches/detail/BatchChangeDetailsPage.tsx | 2 +- .../batches/detail/BatchChangeDetailsTabs.tsx | 2 +- .../batches/detail/BulkOperationsAlerts.tsx | 2 +- .../detail/ChangesetsArchivedNotice.tsx | 2 +- .../detail/changesets/ChangesetFilterRow.tsx | 2 +- .../EmptyDraftChangesetListElement.tsx | 2 +- .../batches/global/GlobalBatchChangesArea.tsx | 2 +- .../batches/list/BatchChangeListPage.tsx | 2 +- .../batches/list/useBatchChangeListFilters.ts | 2 +- .../preview/BatchChangePreviewPage.tsx | 2 +- .../preview/BatchChangePreviewTabs.tsx | 2 +- .../preview/CreateUpdateBatchChangeAlert.tsx | 2 +- .../batches/preview/list/PreviewFilterRow.tsx | 2 +- .../code-monitoring/CodeMonitorList.tsx | 2 +- .../CodeMonitoringPage.test.tsx | 15 +- .../CreateCodeMonitorPage.test.tsx | 2 +- .../code-monitoring/CreateCodeMonitorPage.tsx | 2 +- .../ManageCodeMonitorPage.test.tsx | 8 +- .../code-monitoring/ManageCodeMonitorPage.tsx | 2 +- .../components/CodeMonitorForm.tsx | 2 +- .../components/DeleteMonitorModal.tsx | 2 +- .../global/GlobalCodeMonitoringArea.tsx | 2 +- .../pages/CodeIntelConfigurationPage.tsx | 2 +- .../CodeIntelConfigurationPolicyPage.tsx | 2 +- .../pages/CodeIntelPreciseIndexPage.tsx | 2 +- .../pages/CodeIntelPreciseIndexesPage.tsx | 2 +- .../codeintel/repo/CodeIntelSidebar.tsx | 34 ++-- .../repo/RepositoryCodeIntelArea.tsx | 6 +- .../src/enterprise/cody/GlobalCodyArea.tsx | 2 +- .../src/enterprise/embed/EmbeddedWebApp.tsx | 88 +++++---- .../executors/ExecutorsSiteAdminArea.tsx | 2 +- .../insights/CodeInsightsAppRouter.tsx | 2 +- .../pages/CodeInsightsRootPage.test.tsx | 15 +- .../insights/pages/CodeInsightsRootPage.tsx | 2 +- .../InsightsDashboardCreationPage.tsx | 2 +- .../DashboardsContentPage.test.tsx | 8 +- .../dashboard-view/DashboardsView.tsx | 2 +- .../dashboards-content/DashboardsContent.tsx | 2 +- .../DeleteDashboardModal.tsx | 2 +- .../edit-dashboard/EditDashobardPage.tsx | 2 +- .../insights/creation/CreationRoutes.tsx | 2 +- .../insights/creation/InsightCreationPage.tsx | 2 +- .../creation/intro/IntroCreationPage.tsx | 2 +- .../insights/edit-insight/EditInsightPage.tsx | 2 +- .../hooks/use-edit-page-handlers.ts | 2 +- .../insight/CodeInsightIndependentPage.tsx | 2 +- .../CodeInsightIndependentPageActions.tsx | 2 +- .../StandaloneBackendInsight.tsx | 2 +- .../CodeInsightsExamples.tsx | 2 +- client/web/src/enterprise/routes.tsx | 2 +- .../CreateSearchContextPage.tsx | 2 +- .../DeleteSearchContextModal.tsx | 2 +- .../searchContexts/EditSearchContextPage.tsx | 2 +- .../searchContexts/SearchContextForm.tsx | 2 +- .../searchContexts/SearchContextPage.tsx | 2 +- .../SearchContextsList.test.tsx | 2 +- .../site-admin/SiteAdminLsifUploadPage.tsx | 2 +- ...SiteAdminCreateProductSubscriptionPage.tsx | 2 +- .../SiteAdminProductSubscriptionPage.tsx | 2 +- .../web/src/enterprise/site-admin/routes.tsx | 2 +- ...erSubscriptionsProductSubscriptionPage.tsx | 2 +- .../extensions/components/ActionItemsBar.tsx | 2 +- client/web/src/hooks/useRoutesMatch.ts | 2 +- .../useScrollManager.test.tsx | 22 +-- .../useScrollManager/useScrollManager.ts | 2 +- .../web/src/hooks/useUrlSyncedState.test.ts | 2 +- client/web/src/hooks/useUrlSyncedState.ts | 2 +- .../integration/search-aggregation.test.ts | 5 +- .../src/integration/search-contexts.test.ts | 6 +- client/web/src/marketing/page/SurveyForm.tsx | 2 +- .../src/marketing/page/SurveyPage.test.tsx | 23 +-- client/web/src/marketing/page/SurveyPage.tsx | 2 +- client/web/src/nav/GlobalNavbar.tsx | 2 +- client/web/src/nav/NavBar/NavBar.tsx | 16 +- client/web/src/nav/NavBar/NavDropdown.tsx | 2 +- client/web/src/nav/UserNavItem.test.tsx | 39 ++-- .../createPage/CreateNotebookPage.tsx | 2 +- .../notebooks/listPage/NotebooksListPage.tsx | 2 +- .../notebooks/notebook/NotebookComponent.tsx | 2 +- .../notebookPage/DeleteNotebookModal.tsx | 2 +- .../notebookPage/EmbeddedNotebookPage.tsx | 2 +- .../notebooks/notebookPage/NotebookPage.tsx | 2 +- client/web/src/org/OrgsArea.tsx | 2 +- client/web/src/org/area/OrgArea.tsx | 2 +- client/web/src/org/area/OrgHeader.tsx | 28 +-- .../src/org/area/OrgInvitationPageLegacy.tsx | 2 +- client/web/src/org/area/routes.tsx | 2 +- .../src/org/invitations/OrgInvitationPage.tsx | 2 +- .../web/src/org/new/NewOrganizationPage.tsx | 2 +- .../web/src/org/settings/DeleteOrgModal.tsx | 2 +- .../web/src/org/settings/OrgSettingsArea.tsx | 2 +- .../src/org/settings/OrgSettingsSidebar.tsx | 2 +- .../codeHosts/InstallGitHubAppSuccessPage.tsx | 2 +- .../members/OrgSettingsMembersPage.tsx | 2 +- client/web/src/person/PersonLink.test.tsx | 23 +-- client/web/src/repo/RepoContainer.tsx | 2 +- client/web/src/repo/RepoHeader.tsx | 2 +- client/web/src/repo/RepoRevisionContainer.tsx | 2 +- client/web/src/repo/RepoRevisionSidebar.tsx | 2 +- .../src/repo/RepoRevisionSidebarCommits.tsx | 2 +- .../src/repo/RepoRevisionSidebarFileTree.tsx | 2 +- .../repo/RepoRevisionSidebarSymbolTree.tsx | 2 +- .../repo/RepoRevisionSidebarSymbols.test.tsx | 4 +- .../src/repo/RepoRevisionSidebarSymbols.tsx | 7 +- .../web/src/repo/RepositoryFileTreePage.tsx | 2 +- .../RevisionsPopoverCommits.tsx | 2 +- .../RevisionsPopoverReferences.tsx | 2 +- .../src/repo/actions/GoToPermalinkAction.tsx | 2 +- client/web/src/repo/blob/BlameColumn.tsx | 2 +- client/web/src/repo/blob/BlameDecoration.tsx | 2 +- .../web/src/repo/blob/BlobLoadingSpinner.tsx | 2 +- client/web/src/repo/blob/BlobPage.tsx | 2 +- client/web/src/repo/blob/CodeMirrorBlob.tsx | 2 +- client/web/src/repo/blob/LegacyBlob.tsx | 2 +- client/web/src/repo/blob/RenderedFile.tsx | 2 +- .../repo/blob/actions/ToggleHistoryPanel.tsx | 2 +- .../blob/actions/ToggleOwnershipPanel.tsx | 2 +- .../blob/actions/ToggleRenderedFileMode.tsx | 2 +- .../blob/codemirror/blame-decorations.tsx | 2 +- .../repo/blob/codemirror/react-interop.tsx | 9 +- .../codemirror/token-selection/definition.ts | 2 +- .../codemirror/token-selection/selections.ts | 2 +- .../repo/blob/codemirror/tokens-as-links.ts | 2 +- client/web/src/repo/blob/panel/BlobPanel.tsx | 2 +- .../repo/branches/RepositoryBranchesArea.tsx | 2 +- .../branches/RepositoryBranchesNavbar.tsx | 17 +- .../src/repo/commit/RepositoryCommitPage.tsx | 2 +- .../repo/commits/RepositoryCommitsPage.tsx | 2 +- .../repo/compare/RepositoryCompareArea.tsx | 2 +- .../compare/RepositoryCompareCommitsPage.tsx | 2 +- .../compare/RepositoryCompareOverviewPage.tsx | 2 +- .../RepositoryReleasesTagsPage.test.tsx | 2 +- .../src/repo/settings/RepoSettingsArea.tsx | 2 +- .../src/repo/settings/RepoSettingsSidebar.tsx | 23 +-- .../settings/components/RedirectionAlert.tsx | 2 +- .../stats/RepositoryStatsContributorsPage.tsx | 2 +- client/web/src/repo/tree/TreePage.tsx | 2 +- client/web/src/routes.tsx | 2 +- .../savedSearches/SavedSearchCreateForm.tsx | 2 +- .../src/savedSearches/SavedSearchListPage.tsx | 4 +- .../src/savedSearches/SavedSearchModal.tsx | 2 +- .../savedSearches/SavedSearchUpdateForm.tsx | 2 +- client/web/src/search/Notepad.tsx | 2 +- client/web/src/search/SearchConsolePage.tsx | 2 +- client/web/src/search/SearchPageWrapper.tsx | 2 +- .../web/src/search/home/SearchPageInput.tsx | 2 +- client/web/src/search/index.test.ts | 31 ++-- client/web/src/search/index.ts | 6 +- .../web/src/search/input/SearchNavbarItem.tsx | 2 +- .../results/SearchResultsCacheProvider.tsx | 2 +- .../results/SearchResultsInfoBar.test.tsx | 5 +- .../search/results/SearchResultsInfoBar.tsx | 2 +- .../results/StreamingSearchResults.test.tsx | 13 +- .../search/results/StreamingSearchResults.tsx | 2 +- .../results/components/aggregation/hooks.ts | 2 +- ...ynamicallyImportedMonacoSettingsEditor.tsx | 23 +-- client/web/src/settings/SettingsFile.tsx | 19 +- .../RemoteRepositoriesStep.tsx | 2 +- .../code-hosts/CodeHostCreation.tsx | 2 +- .../components/code-hosts/CodeHostEdit.tsx | 2 +- .../components/setup-steps/SetupSteps.tsx | 2 +- client/web/src/site-admin/SiteAdminArea.tsx | 2 +- .../SiteAdminExternalServicesArea.tsx | 2 +- .../SiteAdminFeatureFlagConfigurationPage.tsx | 2 +- .../site-admin/SiteAdminRepositoriesPage.tsx | 2 +- .../web/src/site-admin/SiteAdminSidebar.tsx | 4 +- .../site-admin/SiteAdminWebhookPage.story.tsx | 2 +- .../src/site-admin/SiteAdminWebhookPage.tsx | 2 +- .../SiteAdminWebhookUpdatePage.story.tsx | 2 +- .../site-admin/SiteAdminWebhookUpdatePage.tsx | 2 +- .../site-admin/WebhookCreateUpdatePage.tsx | 2 +- .../analytics/components/ValueLegendList.tsx | 2 +- .../src/site-admin/init/SiteInitPage.test.tsx | 10 +- .../web/src/site-admin/init/SiteInitPage.tsx | 2 +- .../outbound-webhooks/CreatePage.tsx | 2 +- .../site-admin/outbound-webhooks/EditPage.tsx | 2 +- .../outbound-webhooks/logs/Logs.tsx | 2 +- client/web/src/stores/experimentalFeatures.ts | 5 +- .../src/tour/components/Tour/Tour.test.tsx | 11 +- .../web/src/tour/components/Tour/TourTask.tsx | 2 +- client/web/src/tree/Tree.tsx | 2 +- client/web/src/user/area/UserArea.tsx | 2 +- client/web/src/user/area/UserAreaHeader.tsx | 7 +- client/web/src/user/area/routes.tsx | 2 +- .../src/user/settings/RedirectToUserPage.tsx | 2 +- .../user/settings/RedirectToUserSettings.tsx | 2 +- .../src/user/settings/UserSettingsArea.tsx | 2 +- .../src/user/settings/UserSettingsSidebar.tsx | 2 +- ...rSettingsCreateAccessTokenCallbackPage.tsx | 2 +- .../UserSettingsCreateAccessTokenPage.tsx | 2 +- .../accessTokens/UserSettingsTokensArea.tsx | 2 +- .../accessTokens/UserSettingsTokensPage.tsx | 2 +- .../settings/profile/EditUserProfileForm.tsx | 2 +- .../profile/UserSettingsProfilePage.test.tsx | 7 +- client/web/src/user/settings/routes.tsx | 2 +- client/web/src/util/globalHistory.ts | 7 - client/web/src/util/location.ts | 12 -- .../BeforeUnloadPrompt/BeforeUnloadPrompt.tsx | 17 ++ .../components/BeforeUnloadPrompt/index.ts | 1 + .../src/components/Markdown/Markdown.tsx | 2 +- client/wildcard/src/components/index.ts | 3 +- client/wildcard/src/hooks/index.ts | 1 + client/wildcard/src/hooks/usePrompt.tsx | 44 +++++ .../wildcard/src/hooks/useSearchParameters.ts | 2 +- client/wildcard/src/stories/BrandedStory.tsx | 7 +- .../testing/render-with-branded-context.tsx | 122 +++++++++---- package.json | 15 +- pnpm-lock.yaml | 115 ++---------- 286 files changed, 994 insertions(+), 1175 deletions(-) create mode 100644 client/web/src/SearchQueryStateObserver.tsx delete mode 100644 client/web/src/code-monitoring/CodeMonitoringNavItem.tsx delete mode 100644 client/web/src/components/LinkWithIcon.module.scss delete mode 100644 client/web/src/components/LinkWithIcon.tsx delete mode 100644 client/web/src/util/globalHistory.ts delete mode 100644 client/web/src/util/location.ts create mode 100644 client/wildcard/src/components/BeforeUnloadPrompt/BeforeUnloadPrompt.tsx create mode 100644 client/wildcard/src/components/BeforeUnloadPrompt/index.ts create mode 100644 client/wildcard/src/hooks/usePrompt.tsx diff --git a/client/branded/src/components/panel/TabbedPanelContent.test.tsx b/client/branded/src/components/panel/TabbedPanelContent.test.tsx index f365778fb92..89dc2e26007 100644 --- a/client/branded/src/components/panel/TabbedPanelContent.test.tsx +++ b/client/branded/src/components/panel/TabbedPanelContent.test.tsx @@ -34,8 +34,8 @@ describe('TabbedPanel', () => { const panelButton = await renderResult.findByRole('tab', { name: panelToSelect.title }) fireEvent.click(panelButton) - expect(renderResult.history.location.pathname).toEqual(location.pathname) - expect(renderResult.history.location.search).toEqual(location.search) - expect(renderResult.history.location.hash).toEqual(`#tab=${panelToSelect.id}`) + expect(renderResult.locationRef.current?.pathname).toEqual(location.pathname) + expect(renderResult.locationRef.current?.search).toEqual(location.search) + expect(renderResult.locationRef.current?.hash).toEqual(`#tab=${panelToSelect.id}`) }) }) diff --git a/client/branded/src/components/panel/TabbedPanelContent.tsx b/client/branded/src/components/panel/TabbedPanelContent.tsx index b8a9d0f04b7..c474bfaa9b4 100644 --- a/client/branded/src/components/panel/TabbedPanelContent.tsx +++ b/client/branded/src/components/panel/TabbedPanelContent.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react' import { mdiClose } from '@mdi/js' import classNames from 'classnames' -import { useLocation, useNavigate } from 'react-router-dom-v5-compat' +import { useLocation, useNavigate } from 'react-router-dom' import { BehaviorSubject, Observable } from 'rxjs' import { map } from 'rxjs/operators' diff --git a/client/branded/src/search-ui/components/FileMatchChildren.tsx b/client/branded/src/search-ui/components/FileMatchChildren.tsx index 5129d5a0f17..d08c05ab168 100644 --- a/client/branded/src/search-ui/components/FileMatchChildren.tsx +++ b/client/branded/src/search-ui/components/FileMatchChildren.tsx @@ -1,7 +1,7 @@ import React, { useCallback, KeyboardEvent, MouseEvent } from 'react' import classNames from 'classnames' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { Observable } from 'rxjs' import { map } from 'rxjs/operators' diff --git a/client/branded/src/search-ui/components/QueryExamples.tsx b/client/branded/src/search-ui/components/QueryExamples.tsx index c4433f44474..2804fbeb661 100644 --- a/client/branded/src/search-ui/components/QueryExamples.tsx +++ b/client/branded/src/search-ui/components/QueryExamples.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useState } from 'react' import { mdiOpenInNew } from '@mdi/js' import classNames from 'classnames' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { SearchPatternType } from '@sourcegraph/shared/src/graphql-operations' import { EditorHint, QueryState } from '@sourcegraph/shared/src/search' diff --git a/client/branded/src/search-ui/components/SymbolSearchResult.tsx b/client/branded/src/search-ui/components/SymbolSearchResult.tsx index a831541e131..14ebed63fdd 100644 --- a/client/branded/src/search-ui/components/SymbolSearchResult.tsx +++ b/client/branded/src/search-ui/components/SymbolSearchResult.tsx @@ -1,7 +1,7 @@ import React, { useCallback, KeyboardEvent, MouseEvent } from 'react' import classNames from 'classnames' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { Observable } from 'rxjs' import { map } from 'rxjs/operators' diff --git a/client/branded/src/search-ui/components/codeLinkNavigation.ts b/client/branded/src/search-ui/components/codeLinkNavigation.ts index 19a1e8298f5..72d3e93815a 100644 --- a/client/branded/src/search-ui/components/codeLinkNavigation.ts +++ b/client/branded/src/search-ui/components/codeLinkNavigation.ts @@ -1,6 +1,6 @@ import React, { MouseEvent, KeyboardEvent } from 'react' -import { NavigateFunction } from 'react-router-dom-v5-compat' +import { NavigateFunction } from 'react-router-dom' /** * A helper function to replicate browser behavior when clicking on links. diff --git a/client/branded/src/search-ui/input/CodeMirrorQueryInput.tsx b/client/branded/src/search-ui/input/CodeMirrorQueryInput.tsx index ec65bd5a04d..62b6fe927ee 100644 --- a/client/branded/src/search-ui/input/CodeMirrorQueryInput.tsx +++ b/client/branded/src/search-ui/input/CodeMirrorQueryInput.tsx @@ -26,7 +26,7 @@ import { WidgetType, } from '@codemirror/view' import classNames from 'classnames' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { renderMarkdown } from '@sourcegraph/common' import { TraceSpanProvider } from '@sourcegraph/observability-client' diff --git a/client/branded/src/search-ui/input/codemirror/completion.ts b/client/branded/src/search-ui/input/codemirror/completion.ts index 055e981a42c..977df8630de 100644 --- a/client/branded/src/search-ui/input/codemirror/completion.ts +++ b/client/branded/src/search-ui/input/codemirror/completion.ts @@ -46,7 +46,7 @@ import { mdiWrench, } from '@mdi/js' import { isEqual, startCase } from 'lodash' -import { NavigateFunction } from 'react-router-dom-v5-compat' +import { NavigateFunction } from 'react-router-dom' import { isDefined } from '@sourcegraph/common' import { SymbolKind } from '@sourcegraph/shared/src/graphql-operations' diff --git a/client/branded/src/search-ui/input/codemirror/index.ts b/client/branded/src/search-ui/input/codemirror/index.ts index 21a7296cfc6..b29b4011300 100644 --- a/client/branded/src/search-ui/input/codemirror/index.ts +++ b/client/branded/src/search-ui/input/codemirror/index.ts @@ -1,6 +1,6 @@ import { ChangeSpec, EditorState, Extension } from '@codemirror/state' import { EditorView, ViewUpdate } from '@codemirror/view' -import { NavigateFunction } from 'react-router-dom-v5-compat' +import { NavigateFunction } from 'react-router-dom' import { Observable } from 'rxjs' import { createCancelableFetchSuggestions } from '@sourcegraph/shared/src/search/query/providers-utils' diff --git a/client/branded/src/search-ui/input/experimental/CodeMirrorQueryInputWrapper.tsx b/client/branded/src/search-ui/input/experimental/CodeMirrorQueryInputWrapper.tsx index 66eb5b812df..4044d2245b8 100644 --- a/client/branded/src/search-ui/input/experimental/CodeMirrorQueryInputWrapper.tsx +++ b/client/branded/src/search-ui/input/experimental/CodeMirrorQueryInputWrapper.tsx @@ -4,7 +4,7 @@ import { defaultKeymap, historyKeymap, history as codemirrorHistory } from '@cod import { Compartment, EditorState, Extension, Prec } from '@codemirror/state' import { EditorView, keymap, drawSelection } from '@codemirror/view' import inRange from 'lodash/inRange' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import useResizeObserver from 'use-resize-observer' import * as uuid from 'uuid' diff --git a/client/branded/src/search-ui/results/StreamingSearchResultsList.tsx b/client/branded/src/search-ui/results/StreamingSearchResultsList.tsx index d3b1432aca1..fae873247bd 100644 --- a/client/branded/src/search-ui/results/StreamingSearchResultsList.tsx +++ b/client/branded/src/search-ui/results/StreamingSearchResultsList.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useState } from 'react' import classNames from 'classnames' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { Observable } from 'rxjs' import { TraceSpanProvider } from '@sourcegraph/observability-client' diff --git a/client/browser/src/shared/components/HoverOverlay.story.tsx b/client/browser/src/shared/components/HoverOverlay.story.tsx index d79932e71f2..3eacabf5045 100644 --- a/client/browser/src/shared/components/HoverOverlay.story.tsx +++ b/client/browser/src/shared/components/HoverOverlay.story.tsx @@ -2,7 +2,6 @@ import bitbucketStyles from '@atlassian/aui/dist/aui/css/aui.css' import { DecoratorFn, Meta, Story } from '@storybook/react' import classNames from 'classnames' import { BrowserRouter } from 'react-router-dom' -import { CompatRouter } from 'react-router-dom-v5-compat' import { registerHighlightContributions } from '@sourcegraph/common' import { NotificationType } from '@sourcegraph/shared/src/api/extension/extensionHostApi' @@ -58,18 +57,16 @@ const BITBUCKET_CLASS_PROPS: HoverOverlayClassProps = { export const BitbucketStyles: Story = (props = {}) => ( - - - + ) BitbucketStyles.storyName = 'Bitbucket styles' diff --git a/client/common/src/types/utils.ts b/client/common/src/types/utils.ts index 6745ed21dc4..8c616d557bd 100644 --- a/client/common/src/types/utils.ts +++ b/client/common/src/types/utils.ts @@ -1,4 +1,11 @@ +import { Falsey } from 'utility-types' + /** * Returns true if `val` is not `null` or `undefined` */ export const isDefined = (value: T): value is NonNullable => value !== undefined && value !== null + +/** + * Returns true if `val` is truthy. + */ +export const isTruthy = (value: T | Falsey): value is T => !!value diff --git a/client/common/src/util/compatNavigate.ts b/client/common/src/util/compatNavigate.ts index 1bf4680247f..dbe7bdc2b89 100644 --- a/client/common/src/util/compatNavigate.ts +++ b/client/common/src/util/compatNavigate.ts @@ -1,5 +1,5 @@ import { History } from 'history' -import { NavigateFunction, NavigateOptions, To } from 'react-router-dom-v5-compat' +import { NavigateFunction, NavigateOptions, To } from 'react-router-dom' export type HistoryOrNavigate = History | NavigateFunction diff --git a/client/jetbrains/webview/src/search/input/JetBrainsSearchBox.story.tsx b/client/jetbrains/webview/src/search/input/JetBrainsSearchBox.story.tsx index cf4b32be006..0dd1ae61244 100644 --- a/client/jetbrains/webview/src/search/input/JetBrainsSearchBox.story.tsx +++ b/client/jetbrains/webview/src/search/input/JetBrainsSearchBox.story.tsx @@ -2,7 +2,6 @@ import { useEffect, useRef } from 'react' import { DecoratorFn, Meta, Story } from '@storybook/react' import { BrowserRouter } from 'react-router-dom' -import { CompatRouter } from 'react-router-dom-v5-compat' import { EMPTY, NEVER } from 'rxjs' import { useDarkMode } from 'storybook-dark-mode' @@ -45,45 +44,43 @@ export const JetBrainsSearchBoxStory: Story = () => { return ( - -
-
-
- {}} - patternType={SearchPatternType.regexp} - setPatternType={() => {}} - isSourcegraphDotCom={false} - structuralSearchDisabled={false} - queryState={{ query: 'type:file test AND test repo:contains.file(CHANGELOG)' }} - onChange={() => {}} - onSubmit={() => {}} - authenticatedUser={null} - searchContextsEnabled={true} - showSearchContext={true} - showSearchContextManagement={false} - setSelectedSearchContextSpec={() => {}} - selectedSearchContextSpec={undefined} - fetchSearchContexts={() => { - throw new Error('fetchSearchContexts') - }} - getUserSearchContextNamespaces={() => []} - fetchStreamSuggestions={() => NEVER} - settingsCascade={EMPTY_SETTINGS_CASCADE} - globbing={false} - isLightTheme={!isDarkTheme} - telemetryService={NOOP_TELEMETRY_SERVICE} - platformContext={{ requestGraphQL: () => EMPTY }} - className="" - containerClassName="" - autoFocus={true} - hideHelpButton={true} - /> -
+
+
+
+ {}} + patternType={SearchPatternType.regexp} + setPatternType={() => {}} + isSourcegraphDotCom={false} + structuralSearchDisabled={false} + queryState={{ query: 'type:file test AND test repo:contains.file(CHANGELOG)' }} + onChange={() => {}} + onSubmit={() => {}} + authenticatedUser={null} + searchContextsEnabled={true} + showSearchContext={true} + showSearchContextManagement={false} + setSelectedSearchContextSpec={() => {}} + selectedSearchContextSpec={undefined} + fetchSearchContexts={() => { + throw new Error('fetchSearchContexts') + }} + getUserSearchContextNamespaces={() => []} + fetchStreamSuggestions={() => NEVER} + settingsCascade={EMPTY_SETTINGS_CASCADE} + globbing={false} + isLightTheme={!isDarkTheme} + telemetryService={NOOP_TELEMETRY_SERVICE} + platformContext={{ requestGraphQL: () => EMPTY }} + className="" + containerClassName="" + autoFocus={true} + hideHelpButton={true} + />
- +
) diff --git a/client/vscode/src/webview/search-panel/index.tsx b/client/vscode/src/webview/search-panel/index.tsx index 02e35931385..a542258e6c4 100644 --- a/client/vscode/src/webview/search-panel/index.tsx +++ b/client/vscode/src/webview/search-panel/index.tsx @@ -5,8 +5,7 @@ import React, { useMemo } from 'react' import { VSCodeProgressRing } from '@vscode/webview-ui-toolkit/react' import * as Comlink from 'comlink' import { createRoot } from 'react-dom/client' -import { MemoryRouter } from 'react-router' -import { CompatRouter } from 'react-router-dom-v5-compat' +import { MemoryRouter } from 'react-router-dom' import { wrapRemoteObservable } from '@sourcegraph/shared/src/api/client/api/common' import { ShortcutProvider } from '@sourcegraph/shared/src/react-shortcuts' @@ -117,9 +116,7 @@ root.render( {/* Required for shared components that depend on `location`. */} - -
- +
diff --git a/client/vscode/src/webview/sidebars/search/SearchSidebarView.tsx b/client/vscode/src/webview/sidebars/search/SearchSidebarView.tsx index 2b68991a180..f80a840e8c5 100644 --- a/client/vscode/src/webview/sidebars/search/SearchSidebarView.tsx +++ b/client/vscode/src/webview/sidebars/search/SearchSidebarView.tsx @@ -1,6 +1,6 @@ import React, { FC, ReactElement, ReactNode, useCallback, useMemo } from 'react' -import { useLocation, useNavigate } from 'react-router-dom-v5-compat' +import { useLocation, useNavigate } from 'react-router-dom' import { useDeepCompareEffectNoCheck } from 'use-deep-compare-effect' import create from 'zustand' diff --git a/client/web/dev/utils/get-api-proxy-settings.ts b/client/web/dev/utils/get-api-proxy-settings.ts index d98d9558230..d4741e26aa5 100644 --- a/client/web/dev/utils/get-api-proxy-settings.ts +++ b/client/web/dev/utils/get-api-proxy-settings.ts @@ -49,7 +49,8 @@ export function getAPIProxySettings(options: GetAPIProxySettingsOptions): ProxyS // the index.html generated by `getLocalIndexHTML`. if ( getLocalIndexHTML && - proxyRes.statusCode === 200 && + // router.go is not up to date with client routes and still serves index.html with 404 + (proxyRes.statusCode === 200 || proxyRes.statusCode === 404) && proxyRes.headers['content-type'] && proxyRes.headers['content-type'].includes('text/html') ) { diff --git a/client/web/src/Layout.tsx b/client/web/src/Layout.tsx index 9ddfd263459..d6b8ca69893 100644 --- a/client/web/src/Layout.tsx +++ b/client/web/src/Layout.tsx @@ -1,7 +1,7 @@ import React, { Suspense, useCallback, useRef, useState } from 'react' import classNames from 'classnames' -import { useLocation, Navigate, Outlet } from 'react-router-dom-v5-compat' +import { Outlet, useLocation, Navigate } from 'react-router-dom' import { Observable } from 'rxjs' import { TabbedPanelContent } from '@sourcegraph/branded/src/components/panel/TabbedPanelContent' @@ -40,6 +40,7 @@ import type { NotebookProps } from './notebooks' import { EnterprisePageRoutes, PageRoutes } from './routes.constants' import { parseSearchURLQuery, SearchAggregationProps, SearchStreamingProps } from './search' import { NotepadContainer } from './search/Notepad' +import { SearchQueryStateObserver } from './SearchQueryStateObserver' import { useExperimentalFeatures } from './stores' import { ThemePreferenceProps, useTheme } from './theme' import { getExperimentalFeatures } from './util/get-experimental-features' @@ -274,6 +275,12 @@ export const Layout: React.FC = props => { userHistory={userHistory} /> )} +
) } diff --git a/client/web/src/LegacyLayout.tsx b/client/web/src/LegacyLayout.tsx index 70168e82a6c..9df137ff225 100644 --- a/client/web/src/LegacyLayout.tsx +++ b/client/web/src/LegacyLayout.tsx @@ -1,7 +1,7 @@ import React, { Suspense, useCallback, useRef, useState } from 'react' import classNames from 'classnames' -import { matchPath, useLocation, Route, Routes, Navigate } from 'react-router-dom-v5-compat' +import { matchPath, useLocation, Route, Routes, Navigate } from 'react-router-dom' import { Observable } from 'rxjs' import { TabbedPanelContent } from '@sourcegraph/branded/src/components/panel/TabbedPanelContent' @@ -51,6 +51,7 @@ import type { LegacyLayoutRouteComponentProps, LayoutRouteProps } from './routes import { EnterprisePageRoutes, PageRoutes } from './routes.constants' import { parseSearchURLQuery, SearchAggregationProps, SearchStreamingProps } from './search' import { NotepadContainer } from './search/Notepad' +import { SearchQueryStateObserver } from './SearchQueryStateObserver' import type { SiteAdminAreaRoute } from './site-admin/SiteAdminArea' import type { SiteAdminSideBarGroups } from './site-admin/SiteAdminSidebar' import { useExperimentalFeatures } from './stores' @@ -328,6 +329,12 @@ export const LegacyLayout: React.FunctionComponent )} +
) } diff --git a/client/web/src/LegacySourcegraphWebApp.tsx b/client/web/src/LegacySourcegraphWebApp.tsx index acbff69c7e8..0c3e55d201e 100644 --- a/client/web/src/LegacySourcegraphWebApp.tsx +++ b/client/web/src/LegacySourcegraphWebApp.tsx @@ -4,10 +4,9 @@ import * as React from 'react' import { ApolloProvider } from '@apollo/client' import ServerIcon from 'mdi-react/ServerIcon' -import { Router } from 'react-router' -import { CompatRouter, Routes, Route } from 'react-router-dom-v5-compat' +import { RouterProvider, createBrowserRouter, createRoutesFromElements, Route } from 'react-router-dom' import { combineLatest, from, Subscription, fromEvent, of, Subject, Observable } from 'rxjs' -import { first, startWith, switchMap, map, distinctUntilChanged } from 'rxjs/operators' +import { startWith, switchMap } from 'rxjs/operators' import { logger } from '@sourcegraph/common' import { GraphQLClient, HTTPStatusError } from '@sourcegraph/http-client' @@ -36,7 +35,6 @@ import { getDefaultSearchContextSpec, } from '@sourcegraph/shared/src/search' import { FilterType } from '@sourcegraph/shared/src/search/query/filters' -import { omitFilter } from '@sourcegraph/shared/src/search/query/transformer' import { filterExists } from '@sourcegraph/shared/src/search/query/validate' import { aggregateStreamingSearch } from '@sourcegraph/shared/src/search/stream' import { EMPTY_SETTINGS_CASCADE, SettingsCascadeProps } from '@sourcegraph/shared/src/settings/settings' @@ -68,8 +66,9 @@ import type { RepoRevisionContainerRoute } from './repo/RepoRevisionContainer' import type { RepoSettingsAreaRoute } from './repo/settings/RepoSettingsArea' import type { RepoSettingsSideBarGroup } from './repo/settings/RepoSettingsSidebar' import type { LayoutRouteProps } from './routes' -import { parseSearchURL, getQueryStateFromLocation, SearchAggregationProps } from './search' +import { parseSearchURL, SearchAggregationProps } from './search' import { SearchResultsCacheProvider } from './search/results/SearchResultsCacheProvider' +import { GLOBAL_SEARCH_CONTEXT_SPEC } from './SearchQueryStateObserver' import type { SiteAdminAreaRoute } from './site-admin/SiteAdminArea' import type { SiteAdminSideBarGroups } from './site-admin/SiteAdminSidebar' import { @@ -77,18 +76,13 @@ import { setExperimentalFeaturesFromSettings, getExperimentalFeatures, useNavbarQueryState, - observeStore, - useExperimentalFeatures, } from './stores' -import { setQueryStateFromURL } from './stores/navbarSearchQueryState' import { eventLogger } from './tracking/eventLogger' import type { UserAreaRoute } from './user/area/UserArea' import type { UserAreaHeaderNavItem } from './user/area/UserAreaHeader' import type { UserSettingsAreaRoute } from './user/settings/UserSettingsArea' import type { UserSettingsSidebarItems } from './user/settings/UserSettingsSidebar' import { UserSessionStores } from './UserSessionStores' -import { globalHistory } from './util/globalHistory' -import { observeLocation } from './util/location' import { siteSubjectNoAdmin, viewerSubjectFromSettings } from './util/settings' import styles from './LegacySourcegraphWebApp.module.scss' @@ -160,8 +154,6 @@ const WILDCARD_THEME: WildcardTheme = { isBranded: true, } -const GLOBAL_SEARCH_CONTEXT_SPEC = 'global' - setLinkComponent(RouterLink) /** @@ -268,58 +260,6 @@ export class LegacySourcegraphWebApp extends React.Component< logger.error('Error sending search context to extensions!', error) }) - // Update search query state whenever the URL changes - this.subscriptions.add( - combineLatest([ - observeStore(useExperimentalFeatures).pipe( - map(([features]) => features.searchQueryInput === 'experimental'), - // This ensures that the query stays unmodified until we know - // whether the feature flag is set or not. - startWith(true), - distinctUntilChanged() - ), - getQueryStateFromLocation({ - location: observeLocation(globalHistory).pipe(startWith(globalHistory.location)), - isSearchContextAvailable: (searchContext: string) => - this.props.searchContextsEnabled - ? isSearchContextSpecAvailable({ - spec: searchContext, - platformContext: this.platformContext, - }) - .pipe(first()) - .toPromise() - : Promise.resolve(false), - }), - ]).subscribe(([enableExperimentalSearchInput, parsedSearchURLAndContext]) => { - if (parsedSearchURLAndContext.query) { - // Only override filters and update query from URL if there - // is a search query. - if (!parsedSearchURLAndContext.searchContextSpec) { - // If no search context is present we have to fall back - // to the global search context to match the server - // behavior. - this.setSelectedSearchContextSpec(GLOBAL_SEARCH_CONTEXT_SPEC) - } else if ( - parsedSearchURLAndContext.searchContextSpec.spec !== this.state.selectedSearchContextSpec - ) { - this.setSelectedSearchContextSpec(parsedSearchURLAndContext.searchContextSpec.spec) - } - - const processedQuery = - !enableExperimentalSearchInput && - parsedSearchURLAndContext.searchContextSpec && - this.props.searchContextsEnabled - ? omitFilter( - parsedSearchURLAndContext.query, - parsedSearchURLAndContext.searchContextSpec.filter - ) - : parsedSearchURLAndContext.query - - setQueryStateFromURL(parsedSearchURLAndContext, processedQuery) - } - }) - ) - this.userRepositoriesUpdates.next() } @@ -359,6 +299,45 @@ export class LegacySourcegraphWebApp extends React.Component< return null } + const router = createBrowserRouter( + createRoutesFromElements( + + } + /> + ) + ) + return ( - - - - - } - /> - - - + {this.extensionsController !== null && window.context.enableLegacyExtensions ? ( void +} + +// Update search query state whenever the URL changes +export const SearchQueryStateObserver: FC = props => { + const { searchContextsEnabled, platformContext, setSelectedSearchContextSpec, selectedSearchContextSpec } = props + + const location = useLocation() + + const selectedSearchContextSpecRef = useRef(selectedSearchContextSpec) + selectedSearchContextSpecRef.current = selectedSearchContextSpec + + const { searchQueryInput, isInitialized } = useExperimentalFeatures() + + // This ensures that the query stays unmodified until we know + // whether the feature flag is set or not. + const enableExperimentalSearchInput = isInitialized ? searchQueryInput === 'experimental' : true + const enableExperimentalSearchInputRef = useRef(enableExperimentalSearchInput) + enableExperimentalSearchInputRef.current = enableExperimentalSearchInput + + // Create `locationSubject` once on mount. New values are provided in the `useEffect` hook. + // eslint-disable-next-line react-hooks/exhaustive-deps + const [locationSubject] = useState(() => new BehaviorSubject(location)) + + useEffect(() => { + locationSubject.next(location) + }, [location, locationSubject]) + + useEffect(() => { + const subscription = getQueryStateFromLocation({ + location: locationSubject, + isSearchContextAvailable: (searchContext: string) => + searchContextsEnabled + ? isSearchContextSpecAvailable({ + spec: searchContext, + platformContext, + }) + .pipe(first()) + .toPromise() + : Promise.resolve(false), + }).subscribe(parsedSearchURLAndContext => { + if (parsedSearchURLAndContext.query) { + // Only override filters and update query from URL if there + // is a search query. + if (!parsedSearchURLAndContext.searchContextSpec) { + // If no search context is present we have to fall back + // to the global search context to match the server + // behavior. + setSelectedSearchContextSpec(GLOBAL_SEARCH_CONTEXT_SPEC) + } else if (parsedSearchURLAndContext.searchContextSpec.spec !== selectedSearchContextSpecRef.current) { + setSelectedSearchContextSpec(parsedSearchURLAndContext.searchContextSpec.spec) + } + + const processedQuery = + !enableExperimentalSearchInputRef.current && + parsedSearchURLAndContext.searchContextSpec && + searchContextsEnabled + ? omitFilter( + parsedSearchURLAndContext.query, + parsedSearchURLAndContext.searchContextSpec.filter + ) + : parsedSearchURLAndContext.query + + setQueryStateFromURL(parsedSearchURLAndContext, processedQuery) + } + }) + + return () => subscription.unsubscribe() + }, [ + locationSubject, + platformContext, + searchContextsEnabled, + selectedSearchContextSpecRef, + enableExperimentalSearchInputRef, + setSelectedSearchContextSpec, + ]) + + return null +} diff --git a/client/web/src/SourcegraphWebApp.tsx b/client/web/src/SourcegraphWebApp.tsx index c0bacbc4ea7..5f1cd049a38 100644 --- a/client/web/src/SourcegraphWebApp.tsx +++ b/client/web/src/SourcegraphWebApp.tsx @@ -5,12 +5,11 @@ import { useCallback, useEffect, useRef, useState } from 'react' import { ApolloProvider } from '@apollo/client' import ServerIcon from 'mdi-react/ServerIcon' -import { Router } from 'react-router' -import { CompatRouter, Routes, Route } from 'react-router-dom-v5-compat' +import { RouterProvider, createBrowserRouter } from 'react-router-dom' import { combineLatest, from, Subscription, fromEvent, of, Subject, Observable } from 'rxjs' -import { distinctUntilChanged, first, map, startWith, switchMap } from 'rxjs/operators' +import { startWith, switchMap } from 'rxjs/operators' -import { isMacPlatform, logger } from '@sourcegraph/common' +import { isTruthy, isMacPlatform, logger } from '@sourcegraph/common' import { GraphQLClient, HTTPStatusError } from '@sourcegraph/http-client' import { SharedSpanName, TraceSpanProvider } from '@sourcegraph/observability-client' import { FetchFileParameters, fetchHighlightedFileLineRanges } from '@sourcegraph/shared/src/backend/file' @@ -30,7 +29,6 @@ import { getDefaultSearchContextSpec, } from '@sourcegraph/shared/src/search' import { FilterType } from '@sourcegraph/shared/src/search/query/filters' -import { omitFilter } from '@sourcegraph/shared/src/search/query/transformer' import { filterExists } from '@sourcegraph/shared/src/search/query/validate' import { aggregateStreamingSearch } from '@sourcegraph/shared/src/search/stream' import { @@ -68,8 +66,9 @@ import type { RepoRevisionContainerRoute } from './repo/RepoRevisionContainer' import type { RepoSettingsAreaRoute } from './repo/settings/RepoSettingsArea' import type { RepoSettingsSideBarGroup } from './repo/settings/RepoSettingsSidebar' import type { LayoutRouteProps, LegacyLayoutRouteComponentProps } from './routes' -import { parseSearchURL, getQueryStateFromLocation, SearchAggregationProps } from './search' +import { parseSearchURL, SearchAggregationProps } from './search' import { SearchResultsCacheProvider } from './search/results/SearchResultsCacheProvider' +import { GLOBAL_SEARCH_CONTEXT_SPEC } from './SearchQueryStateObserver' import type { SiteAdminAreaRoute } from './site-admin/SiteAdminArea' import type { SiteAdminSideBarGroups } from './site-admin/SiteAdminSidebar' import { @@ -77,10 +76,7 @@ import { setExperimentalFeaturesFromSettings, getExperimentalFeatures, useNavbarQueryState, - observeStore, - useExperimentalFeatures, } from './stores' -import { setQueryStateFromURL } from './stores/navbarSearchQueryState' import { useThemeProps } from './theme' import { eventLogger } from './tracking/eventLogger' import type { UserAreaRoute } from './user/area/UserArea' @@ -88,8 +84,6 @@ import type { UserAreaHeaderNavItem } from './user/area/UserAreaHeader' import type { UserSettingsAreaRoute } from './user/settings/UserSettingsArea' import type { UserSettingsSidebarItems } from './user/settings/UserSettingsSidebar' import { UserSessionStores } from './UserSessionStores' -import { globalHistory } from './util/globalHistory' -import { observeLocation } from './util/location' import { siteSubjectNoAdmin, viewerSubjectFromSettings } from './util/settings' import styles from './LegacySourcegraphWebApp.module.scss' @@ -125,8 +119,6 @@ const WILDCARD_THEME: WildcardTheme = { isBranded: true, } -const GLOBAL_SEARCH_CONTEXT_SPEC = 'global' - setLinkComponent(RouterLink) export const SourcegraphWebApp: React.FC = props => { @@ -298,55 +290,6 @@ export const SourcegraphWebApp: React.FC = props => { setWorkspaceSearchContext(selectedSearchContextSpec) - // Update search query state whenever the URL changes - subscriptions.add( - combineLatest([ - observeStore(useExperimentalFeatures).pipe( - map(([features]) => features.searchQueryInput === 'experimental'), - // This ensures that the query stays unmodified until we know - // whether the feature flag is set or not. - startWith(true), - distinctUntilChanged() - ), - getQueryStateFromLocation({ - location: observeLocation(globalHistory).pipe(startWith(globalHistory.location)), - isSearchContextAvailable: (searchContext: string) => - props.searchContextsEnabled - ? isSearchContextSpecAvailable({ spec: searchContext, platformContext }) - .pipe(first()) - .toPromise() - : Promise.resolve(false), - }), - ]).subscribe(([enableExperimentalQueryInput, parsedSearchURLAndContext]) => { - if (parsedSearchURLAndContext.query) { - // Only override filters and update query from URL if there - // is a search query. - if (!parsedSearchURLAndContext.searchContextSpec) { - // If no search context is present we have to fall back - // to the global search context to match the server - // behavior. - setSelectedSearchContextSpec(GLOBAL_SEARCH_CONTEXT_SPEC) - } else if ( - parsedSearchURLAndContext.searchContextSpec.spec !== selectedSearchContextSpecRef.current - ) { - setSelectedSearchContextSpec(parsedSearchURLAndContext.searchContextSpec.spec) - } - - const processedQuery = - !enableExperimentalQueryInput && - parsedSearchURLAndContext.searchContextSpec && - props.searchContextsEnabled - ? omitFilter( - parsedSearchURLAndContext.query, - parsedSearchURLAndContext.searchContextSpec.filter - ) - : parsedSearchURLAndContext.query - - setQueryStateFromURL(parsedSearchURLAndContext, processedQuery) - } - }) - ) - userRepositoriesUpdates.next() return () => subscriptions.unsubscribe() @@ -421,6 +364,55 @@ export const SourcegraphWebApp: React.FC = props => { return null } + const router = createBrowserRouter([ + { + element: ( + + ), + children: props.routes + .map( + ({ condition = () => true, render, path }) => + condition(context) && { + path: path.slice(1), // remove leading slash + element: render(context), + } + ) + .filter(isTruthy), + }, + ]) + return ( = props => { /* eslint-enable react/no-children-prop, react/jsx-key */ ]} > - - - - - } - > - {props.routes.map( - ({ condition = () => true, ...route }) => - condition(context) && ( - - ) - )} - - - - + ) diff --git a/client/web/src/api/ApiConsole.tsx b/client/web/src/api/ApiConsole.tsx index 01ca8bdc37b..4e627149952 100644 --- a/client/web/src/api/ApiConsole.tsx +++ b/client/web/src/api/ApiConsole.tsx @@ -2,7 +2,7 @@ import * as React from 'react' import * as _graphiqlModule from 'graphiql' // type only import * as H from 'history' -import { useNavigate, useLocation, type NavigateFunction } from 'react-router-dom-v5-compat' +import { useNavigate, useLocation, type NavigateFunction } from 'react-router-dom' import { from as fromPromise, Subject, Subscription } from 'rxjs' import { catchError, debounceTime } from 'rxjs/operators' diff --git a/client/web/src/auth/ResetPasswordPage.tsx b/client/web/src/auth/ResetPasswordPage.tsx index a00d69b5fb9..b4726cafb18 100644 --- a/client/web/src/auth/ResetPasswordPage.tsx +++ b/client/web/src/auth/ResetPasswordPage.tsx @@ -1,7 +1,7 @@ import * as React from 'react' import classNames from 'classnames' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { asError, ErrorLike, isErrorLike, logger } from '@sourcegraph/common' import { Button, Link, LoadingSpinner, Alert, Text, Input, ErrorAlert, Form } from '@sourcegraph/wildcard' diff --git a/client/web/src/auth/SignInPage.test.tsx b/client/web/src/auth/SignInPage.test.tsx index 6e222225273..86da42eee11 100644 --- a/client/web/src/auth/SignInPage.test.tsx +++ b/client/web/src/auth/SignInPage.test.tsx @@ -1,5 +1,5 @@ import { within } from '@testing-library/dom' -import { Route, Routes } from 'react-router-dom-v5-compat' +import { Route, Routes } from 'react-router-dom' import { renderWithBrandedContext } from '@sourcegraph/wildcard/src/testing' diff --git a/client/web/src/auth/SignInPage.tsx b/client/web/src/auth/SignInPage.tsx index 7b927781810..bd7ce2260f4 100644 --- a/client/web/src/auth/SignInPage.tsx +++ b/client/web/src/auth/SignInPage.tsx @@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react' import { mdiBitbucket, mdiGithub, mdiGitlab, mdiEmail } from '@mdi/js' import classNames from 'classnames' import { partition } from 'lodash' -import { Navigate, useLocation, useSearchParams } from 'react-router-dom-v5-compat' +import { Navigate, useLocation, useSearchParams } from 'react-router-dom' import { Alert, Icon, Text, Link, Button, ErrorAlert, AnchorLink } from '@sourcegraph/wildcard' diff --git a/client/web/src/auth/SignUpPage.test.tsx b/client/web/src/auth/SignUpPage.test.tsx index c1adf8196f7..1b8bd19d3fc 100644 --- a/client/web/src/auth/SignUpPage.test.tsx +++ b/client/web/src/auth/SignUpPage.test.tsx @@ -1,4 +1,4 @@ -import { Route, Routes } from 'react-router-dom-v5-compat' +import { Route, Routes } from 'react-router-dom' import { NOOP_TELEMETRY_SERVICE } from '@sourcegraph/shared/src/telemetry/telemetryService' import { MockedTestProvider } from '@sourcegraph/shared/src/testing/apollo' diff --git a/client/web/src/auth/SignUpPage.tsx b/client/web/src/auth/SignUpPage.tsx index ad26a93539a..1916bdb201f 100644 --- a/client/web/src/auth/SignUpPage.tsx +++ b/client/web/src/auth/SignUpPage.tsx @@ -1,7 +1,7 @@ import React, { useEffect } from 'react' import classNames from 'classnames' -import { Navigate, useLocation } from 'react-router-dom-v5-compat' +import { Navigate, useLocation } from 'react-router-dom' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' import { ThemeProps } from '@sourcegraph/shared/src/theme' diff --git a/client/web/src/auth/UnlockAccount.tsx b/client/web/src/auth/UnlockAccount.tsx index 189b5116d73..d496b755538 100644 --- a/client/web/src/auth/UnlockAccount.tsx +++ b/client/web/src/auth/UnlockAccount.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useState } from 'react' -import { Navigate, useLocation, useParams } from 'react-router-dom-v5-compat' +import { Navigate, useLocation, useParams } from 'react-router-dom' import { Alert, Link, LoadingSpinner, ErrorAlert } from '@sourcegraph/wildcard' diff --git a/client/web/src/auth/UsernamePasswordSignInForm.tsx b/client/web/src/auth/UsernamePasswordSignInForm.tsx index 0c5e8d41629..a9cdedaaaee 100644 --- a/client/web/src/auth/UsernamePasswordSignInForm.tsx +++ b/client/web/src/auth/UsernamePasswordSignInForm.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useState } from 'react' import classNames from 'classnames' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { asError, logger } from '@sourcegraph/common' import { Label, Button, LoadingSpinner, Link, Text, Input, Form } from '@sourcegraph/wildcard' diff --git a/client/web/src/auth/withAuthenticatedUser.tsx b/client/web/src/auth/withAuthenticatedUser.tsx index a0bd10c76ab..f03c1bfc926 100644 --- a/client/web/src/auth/withAuthenticatedUser.tsx +++ b/client/web/src/auth/withAuthenticatedUser.tsx @@ -1,6 +1,6 @@ import React from 'react' -import { Navigate } from 'react-router-dom-v5-compat' +import { Navigate } from 'react-router-dom' import { AuthenticatedUser } from '../auth' diff --git a/client/web/src/code-monitoring/CodeMonitoringNavItem.tsx b/client/web/src/code-monitoring/CodeMonitoringNavItem.tsx deleted file mode 100644 index e6bfa7aeb3e..00000000000 --- a/client/web/src/code-monitoring/CodeMonitoringNavItem.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react' - -import { LinkWithIcon } from '../components/LinkWithIcon' - -import { CodeMonitoringLogo } from './CodeMonitoringLogo' - -export const CodeMonitoringNavItem: React.FunctionComponent> = () => ( - -) diff --git a/client/web/src/codeintel/ReferencesPanel.test.tsx b/client/web/src/codeintel/ReferencesPanel.test.tsx index 1014d421319..65941916dfc 100644 --- a/client/web/src/codeintel/ReferencesPanel.test.tsx +++ b/client/web/src/codeintel/ReferencesPanel.test.tsx @@ -1,4 +1,5 @@ import { within, fireEvent } from '@testing-library/react' +import { createPath } from 'react-router-dom' import { MockedTestProvider, waitForNextApolloResponse } from '@sourcegraph/shared/src/testing/apollo' import '@sourcegraph/shared/dev/mockReactVisibilitySensor' @@ -53,7 +54,7 @@ describe('ReferencesPanel', () => { }) it('renders a code view when clicking on a location', async () => { - const { history, ...result } = await renderReferencesPanel() + const { locationRef, ...result } = await renderReferencesPanel() const definitionsList = result.getByTestId('definitions') const referencesList = result.getByTestId('references') @@ -95,11 +96,11 @@ describe('ReferencesPanel', () => { expect(codeView).toHaveTextContent('package diff import') // Assert the current URL points at the reference panel - expect(history.createHref(history.location)).toBe( + expect(createPath(locationRef.current!)).toBe( '/github.com/sourcegraph/go-diff@9d1f353a285b3094bc33bdae277a19aedabe8b71/-/blob/diff/diff.go?L16:2&subtree=true#tab=references' ) // Click on reference the second time promotes the active location to the URL (and main blob view) fireEvent.click(referenceButton) - expect(history.createHref(history.location)).toBe(fullReferenceURL) + expect(createPath(locationRef.current!)).toBe(fullReferenceURL) }) }) diff --git a/client/web/src/codeintel/ReferencesPanel.tsx b/client/web/src/codeintel/ReferencesPanel.tsx index b459709ecd3..307a06c86b3 100644 --- a/client/web/src/codeintel/ReferencesPanel.tsx +++ b/client/web/src/codeintel/ReferencesPanel.tsx @@ -4,7 +4,7 @@ import { mdiArrowCollapseRight, mdiChevronDown, mdiChevronUp, mdiFilterOutline, import classNames from 'classnames' import * as H from 'history' import { capitalize, uniqBy } from 'lodash' -import { useNavigate, useLocation } from 'react-router-dom-v5-compat' +import { useNavigate, useLocation } from 'react-router-dom' import { Observable, of } from 'rxjs' import { map } from 'rxjs/operators' diff --git a/client/web/src/communitySearchContexts/CommunitySearchContextPage.tsx b/client/web/src/communitySearchContexts/CommunitySearchContextPage.tsx index bf2b2ccc83f..eab1ef3cd08 100644 --- a/client/web/src/communitySearchContexts/CommunitySearchContextPage.tsx +++ b/client/web/src/communitySearchContexts/CommunitySearchContextPage.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useMemo, useState } from 'react' import { mdiSourceRepositoryMultiple, mdiGithub, mdiGitlab, mdiBitbucket } from '@mdi/js' import classNames from 'classnames' -import { useNavigate, useLocation } from 'react-router-dom-v5-compat' +import { useNavigate, useLocation } from 'react-router-dom' import { catchError, startWith } from 'rxjs/operators' import { SyntaxHighlightedSearchQuery } from '@sourcegraph/branded' diff --git a/client/web/src/components/AwayPrompt.tsx b/client/web/src/components/AwayPrompt.tsx index 98ba75f4310..3e14d923a68 100644 --- a/client/web/src/components/AwayPrompt.tsx +++ b/client/web/src/components/AwayPrompt.tsx @@ -1,16 +1,12 @@ -import { FC, useEffect, useState, useRef } from 'react' +import { FC, useState, useCallback } from 'react' -import * as H from 'history' -import { useNavigate } from 'react-router-dom-v5-compat' +import { Location, useNavigate, unstable_useBlocker as useBlocker, unstable_BlockerFunction } from 'react-router-dom' import { Button, Modal, H3 } from '@sourcegraph/wildcard' -import { globalHistory } from '../util/globalHistory' - -type Func = () => void interface Props { message: string - when: Func | boolean + when: boolean | (() => boolean) header?: string button_ok_text?: string button_cancel_text?: string @@ -22,42 +18,42 @@ export const AwayPrompt: FC = props => { const { message, when, header = 'Navigate away?', button_ok_text = 'OK', button_cancel_text = 'Cancel' } = props const navigate = useNavigate() - const [pendingLocation, setPendingLocation] = useState() - const unblock = useRef<() => void>() + const [pendingLocation, setPendingLocation] = useState() + + const blocker = useBlocker( + useCallback( + ({ currentLocation, nextLocation }) => { + if (nextLocation.state === ALLOW_NAVIGATION) { + return false + } + + const shouldBlock = typeof when === 'boolean' ? when : when() + + if (shouldBlock) { + setPendingLocation(nextLocation) + + // prevent navigation for now - pop-up is shown + return true + } + + return false + }, + [when] + ) + ) const closeModal = (shouldNavigate: boolean): void => { // close modal setPendingLocation(undefined) if (pendingLocation && shouldNavigate) { - unblock.current?.() + if (blocker.state === 'blocked') { + blocker.reset() + } navigate(pendingLocation) } } - useEffect(() => { - unblock.current = globalHistory.block(location => { - if (location.state === ALLOW_NAVIGATION) { - return unblock.current?.() - } - - const shouldBlock = typeof when === 'boolean' ? when : when() - - if (shouldBlock) { - setPendingLocation(location) - - // prevent navigation for now - pop-up is shown - return false - } - - return unblock.current?.() - }) - - return () => { - unblock.current?.() - } - }, [when]) - return pendingLocation ? (

{header}

diff --git a/client/web/src/components/Breadcrumbs.tsx b/client/web/src/components/Breadcrumbs.tsx index 2d97491d495..bade101d0a8 100644 --- a/client/web/src/components/Breadcrumbs.tsx +++ b/client/web/src/components/Breadcrumbs.tsx @@ -3,7 +3,7 @@ import React, { FC, useState, useEffect, useMemo, useCallback } from 'react' import { mdiChevronRight } from '@mdi/js' import classNames from 'classnames' import { sortBy } from 'lodash' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { Unsubscribable } from 'rxjs' import { isDefined } from '@sourcegraph/common' diff --git a/client/web/src/components/FilteredConnection/FilteredConnection.test.tsx b/client/web/src/components/FilteredConnection/FilteredConnection.test.tsx index 8b4442f2229..f0397e70019 100644 --- a/client/web/src/components/FilteredConnection/FilteredConnection.test.tsx +++ b/client/web/src/components/FilteredConnection/FilteredConnection.test.tsx @@ -2,7 +2,7 @@ import { useEffect } from 'react' import { cleanup, fireEvent, render, screen, waitFor, act } from '@testing-library/react' import * as H from 'history' -import { MemoryRouter, useLocation } from 'react-router-dom-v5-compat' +import { MemoryRouter, useLocation } from 'react-router-dom' import { BehaviorSubject } from 'rxjs' import sinon from 'sinon' diff --git a/client/web/src/components/FilteredConnection/FilteredConnection.tsx b/client/web/src/components/FilteredConnection/FilteredConnection.tsx index 84559814616..fb506007f3a 100644 --- a/client/web/src/components/FilteredConnection/FilteredConnection.tsx +++ b/client/web/src/components/FilteredConnection/FilteredConnection.tsx @@ -2,7 +2,7 @@ import * as React from 'react' import * as H from 'history' import { isEqual, uniq } from 'lodash' -import { NavigateFunction, useLocation, useNavigate } from 'react-router-dom-v5-compat' +import { NavigateFunction, useLocation, useNavigate } from 'react-router-dom' import { combineLatest, merge, Observable, of, Subject, Subscription } from 'rxjs' import { catchError, diff --git a/client/web/src/components/FilteredConnection/hooks/usePageSwitcherPagination.test.tsx b/client/web/src/components/FilteredConnection/hooks/usePageSwitcherPagination.test.tsx index 750ddaedb48..07cd77fb1cb 100644 --- a/client/web/src/components/FilteredConnection/hooks/usePageSwitcherPagination.test.tsx +++ b/client/web/src/components/FilteredConnection/hooks/usePageSwitcherPagination.test.tsx @@ -251,7 +251,7 @@ describe('usePageSwitcherPagination', () => { expect(page.getByText('Next page')).toBeVisible() expect(page.getByText('Last page')).toBeVisible() - expect(page.history.location.search).toBe('') + expect(page.locationRef.current?.search).toBe('') }) it('supports forward pagination', async () => { @@ -270,7 +270,7 @@ describe('usePageSwitcherPagination', () => { expect(page.getByText('Next page')).toBeVisible() expect(page.getByText('Last page')).toBeVisible() - expect(page.history.location.search).toBe(`?after=${getCursorForId('3')}`) + expect(page.locationRef.current?.search).toBe(`?after=${getCursorForId('3')}`) await goToNextPage(page) @@ -285,7 +285,7 @@ describe('usePageSwitcherPagination', () => { expect(page.getByText('Next page')).toBeVisible() expect(page.getByText('Last page')).toBeVisible() - expect(page.history.location.search).toBe(`?after=${getCursorForId('6')}`) + expect(page.locationRef.current?.search).toBe(`?after=${getCursorForId('6')}`) await goToNextPage(page) @@ -298,7 +298,7 @@ describe('usePageSwitcherPagination', () => { expect(() => page.getByText('Next page')).toThrowError(/Unable to find an element/) expect(page.getByText('Last page')).toBeVisible() - expect(page.history.location.search).toBe(`?after=${getCursorForId('9')}`) + expect(page.locationRef.current?.search).toBe(`?after=${getCursorForId('9')}`) }) it('supports restoration from forward pagination URL', async () => { @@ -332,7 +332,7 @@ describe('usePageSwitcherPagination', () => { expect(page.getByText('Next page')).toBeVisible() expect(page.getByText('Last page')).toBeVisible() - expect(page.history.location.search).toBe('') + expect(page.locationRef.current?.search).toBe('') }) it('supports jumping to the last page', async () => { @@ -351,7 +351,7 @@ describe('usePageSwitcherPagination', () => { expect(() => page.getByText('Next page')).toThrowError(/Unable to find an element/) expect(page.getByText('Last page')).toBeVisible() - expect(page.history.location.search).toBe('?last=3') + expect(page.locationRef.current?.search).toBe('?last=3') }) it('supports restoration from last page URL', async () => { @@ -386,7 +386,7 @@ describe('usePageSwitcherPagination', () => { expect(page.getByText('Next page')).toBeVisible() expect(page.getByText('Last page')).toBeVisible() - expect(page.history.location.search).toBe(`?before=${getCursorForId('8')}`) + expect(page.locationRef.current?.search).toBe(`?before=${getCursorForId('8')}`) await goToPreviousPage(page) @@ -401,7 +401,7 @@ describe('usePageSwitcherPagination', () => { expect(page.getByText('Next page')).toBeVisible() expect(page.getByText('Last page')).toBeVisible() - expect(page.history.location.search).toBe(`?before=${getCursorForId('5')}`) + expect(page.locationRef.current?.search).toBe(`?before=${getCursorForId('5')}`) await goToPreviousPage(page) @@ -414,7 +414,7 @@ describe('usePageSwitcherPagination', () => { expect(page.getByText('Next page')).toBeVisible() expect(page.getByText('Last page')).toBeVisible() - expect(page.history.location.search).toBe(`?before=${getCursorForId('2')}`) + expect(page.locationRef.current?.search).toBe(`?before=${getCursorForId('2')}`) }) it('supports restoration from backward pagination URL', async () => { @@ -448,6 +448,6 @@ describe('usePageSwitcherPagination', () => { await goToLastPage(page) - expect(page.history.location.search).toBe(`?after=${getCursorForId('6')}`) + expect(page.locationRef.current?.search).toBe(`?after=${getCursorForId('6')}`) }) }) diff --git a/client/web/src/components/FilteredConnection/hooks/usePageSwitcherPagination.ts b/client/web/src/components/FilteredConnection/hooks/usePageSwitcherPagination.ts index 07809401366..114f0f64420 100644 --- a/client/web/src/components/FilteredConnection/hooks/usePageSwitcherPagination.ts +++ b/client/web/src/components/FilteredConnection/hooks/usePageSwitcherPagination.ts @@ -1,7 +1,7 @@ import { useCallback, useMemo } from 'react' import { ApolloError, WatchQueryFetchPolicy } from '@apollo/client' -import { useNavigate, useLocation } from 'react-router-dom-v5-compat' +import { useNavigate, useLocation } from 'react-router-dom' import { GraphQLResult, useQuery } from '@sourcegraph/http-client' diff --git a/client/web/src/components/FilteredConnection/hooks/useShowMorePagination.test.tsx b/client/web/src/components/FilteredConnection/hooks/useShowMorePagination.test.tsx index 497f5d85892..d2278e57546 100644 --- a/client/web/src/components/FilteredConnection/hooks/useShowMorePagination.test.tsx +++ b/client/web/src/components/FilteredConnection/hooks/useShowMorePagination.test.tsx @@ -177,7 +177,7 @@ describe('useShowMorePagination', () => { expect(queries.getByText('repo-A')).toBeVisible() expect(queries.getByText('Total count: 4')).toBeVisible() expect(queries.getByText('Fetch more')).toBeVisible() - expect(queries.history.location.search).toBe('') + expect(queries.locationRef.current?.search).toBe('') }) it('fetches next page of results correctly', async () => { @@ -194,7 +194,7 @@ describe('useShowMorePagination', () => { expect(queries.getByText('Fetch more')).toBeVisible() // URL updates to match visible results - expect(queries.history.location.search).toBe('?visible=2') + expect(queries.locationRef.current?.search).toBe('?visible=2') }) it('fetches final page of results correctly', async () => { @@ -217,7 +217,7 @@ describe('useShowMorePagination', () => { expect(queries.queryByText('Fetch more')).not.toBeInTheDocument() // URL updates to match visible results - expect(queries.history.location.search).toBe('?visible=4') + expect(queries.locationRef.current?.search).toBe('?visible=4') }) it('fetches correct amount of results when navigating directly with a URL', async () => { @@ -249,7 +249,7 @@ describe('useShowMorePagination', () => { expect(queries.getByText('Total count: 4')).toBeVisible() // URL should be overidden - expect(queries.history.location.search).toBe('?visible=4') + expect(queries.locationRef.current?.search).toBe('?visible=4') }) }) @@ -290,7 +290,7 @@ describe('useShowMorePagination', () => { expect(queries.getByText('repo-A')).toBeVisible() expect(queries.getByText('Total count: 4')).toBeVisible() expect(queries.getByText('Fetch more')).toBeVisible() - expect(queries.history.location.search).toBe('') + expect(queries.locationRef.current?.search).toBe('') }) it('fetches next page of results correctly', async () => { @@ -307,7 +307,7 @@ describe('useShowMorePagination', () => { expect(queries.getByText('Fetch more')).toBeVisible() // URL updates to match the new request - expect(queries.history.location.search).toBe('?first=2') + expect(queries.locationRef.current?.search).toBe('?first=2') }) it('fetches final page of results correctly', async () => { @@ -329,7 +329,7 @@ describe('useShowMorePagination', () => { expect(queries.queryByText('Fetch more')).not.toBeInTheDocument() // URL updates to match the new request - expect(queries.history.location.search).toBe('?first=4') + expect(queries.locationRef.current?.search).toBe('?first=4') }) it('fetches correct amount of results when navigating directly with a URL', async () => { @@ -349,7 +349,7 @@ describe('useShowMorePagination', () => { expect(queries.getByText('Total count: 4')).toBeVisible() // URL should be overidden - expect(queries.history.location.search).toBe('?first=4') + expect(queries.locationRef.current?.search).toBe('?first=4') }) }) }) diff --git a/client/web/src/components/FilteredConnection/hooks/useShowMorePaginationUrl.ts b/client/web/src/components/FilteredConnection/hooks/useShowMorePaginationUrl.ts index d41336f71bf..de4c9ffcd02 100644 --- a/client/web/src/components/FilteredConnection/hooks/useShowMorePaginationUrl.ts +++ b/client/web/src/components/FilteredConnection/hooks/useShowMorePaginationUrl.ts @@ -1,6 +1,6 @@ import { useEffect } from 'react' -import { useNavigate, useLocation } from 'react-router-dom-v5-compat' +import { useNavigate, useLocation } from 'react-router-dom' import { getUrlQuery, GetUrlQueryParameters } from '../utils' diff --git a/client/web/src/components/LinkWithIcon.module.scss b/client/web/src/components/LinkWithIcon.module.scss deleted file mode 100644 index 5477ebe4df8..00000000000 --- a/client/web/src/components/LinkWithIcon.module.scss +++ /dev/null @@ -1,8 +0,0 @@ -.link-with-icon { - padding: var(--nav-link-padding-y) var(--nav-link-padding-x); - - &:global(.active):not(:global(.focus)):not(:focus) { - // To override default active btn shadow - box-shadow: none !important; - } -} diff --git a/client/web/src/components/LinkWithIcon.tsx b/client/web/src/components/LinkWithIcon.tsx deleted file mode 100644 index 263dea59b92..00000000000 --- a/client/web/src/components/LinkWithIcon.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' - -import classNames from 'classnames' -import { kebabCase } from 'lodash' -import { NavLink, NavLinkProps } from 'react-router-dom' - -import { Button, Icon } from '@sourcegraph/wildcard' - -import styles from './LinkWithIcon.module.scss' - -interface LinkWithIconProps extends NavLinkProps { - text: string - icon: React.ComponentType<{ className?: string }> -} - -/** - * A link displaying an icon along with text. - */ -export const LinkWithIcon: React.FunctionComponent> = props => { - const { to, exact, text, className, activeClassName, icon: linkIcon } = props - - return ( - - ) -} diff --git a/client/web/src/components/RedirectRoute.tsx b/client/web/src/components/RedirectRoute.tsx index 48861310da2..48e79068b2f 100644 --- a/client/web/src/components/RedirectRoute.tsx +++ b/client/web/src/components/RedirectRoute.tsx @@ -1,6 +1,6 @@ import { FC } from 'react' -import { Location, Navigate, Params, useLocation, useParams } from 'react-router-dom-v5-compat' +import { Location, Navigate, Params, useLocation, useParams } from 'react-router-dom' interface RedirectRouteProps { getRedirectURL: (data: { location: Location; params: Params }) => string diff --git a/client/web/src/components/Sidebar.tsx b/client/web/src/components/Sidebar.tsx index fd8c825a296..27c4ea22760 100644 --- a/client/web/src/components/Sidebar.tsx +++ b/client/web/src/components/Sidebar.tsx @@ -1,9 +1,9 @@ -import React from 'react' +import React, { FC, PropsWithChildren } from 'react' import { mdiMenuDown, mdiMenuUp } from '@mdi/js' import classNames from 'classnames' import kebabCase from 'lodash/kebabCase' -import { useRouteMatch } from 'react-router-dom' +import { useMatch } from 'react-router-dom' import { AnchorLink, @@ -19,20 +19,28 @@ import { import styles from './Sidebar.module.scss' +interface SidebarNavItemProps { + to: string + className?: string + source?: string + onClick?: () => void + exact?: boolean +} + /** * Item of `SideBarGroup`. */ -export const SidebarNavItem: React.FunctionComponent< - React.PropsWithChildren<{ - to: string - className?: string - exact?: boolean - source?: string - onClick?: () => void - }> -> = ({ children, className, to, exact, source, onClick }) => { +export const SidebarNavItem: FC> = ({ + children, + className, + to, + source, + onClick, + exact = false, +}) => { + // Match nested routes too. + const routeMatch = useMatch(to + (exact ? '' : '/*')) const buttonClassNames = classNames('text-left d-flex', styles.linkInactive, className) - const routeMatch = useRouteMatch({ path: to, exact }) if (source === 'server') { return ( @@ -43,12 +51,7 @@ export const SidebarNavItem: React.FunctionComponent< } return ( - + {children} ) diff --git a/client/web/src/components/WebHoverOverlay/WebHoverOverlay.tsx b/client/web/src/components/WebHoverOverlay/WebHoverOverlay.tsx index 88ded4ae51b..c9e48c90293 100644 --- a/client/web/src/components/WebHoverOverlay/WebHoverOverlay.tsx +++ b/client/web/src/components/WebHoverOverlay/WebHoverOverlay.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useEffect } from 'react' import classNames from 'classnames' -import { Location, useLocation } from 'react-router-dom-v5-compat' +import { Location, useLocation } from 'react-router-dom' import { fromEvent, Observable } from 'rxjs' import { finalize, tap } from 'rxjs/operators' diff --git a/client/web/src/components/WebStory.tsx b/client/web/src/components/WebStory.tsx index c806fb6d54c..74bae748e84 100644 --- a/client/web/src/components/WebStory.tsx +++ b/client/web/src/components/WebStory.tsx @@ -1,7 +1,6 @@ import { FC } from 'react' -import { MemoryRouter, MemoryRouterProps } from 'react-router' -import { Routes, Route, CompatRouter } from 'react-router-dom-v5-compat' +import { RouterProvider, createMemoryRouter, MemoryRouterProps } from 'react-router-dom' import { MockedStoryProvider, MockedStoryProviderProps } from '@sourcegraph/shared/src/stories' import { NOOP_TELEMETRY_SERVICE, TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' @@ -40,7 +39,8 @@ export const WebStory: FC = ({ mocks, path = '*', useStrictMocking, - ...memoryRouterProps + initialEntries = ['/'], + initialIndex = 1, }) => { const isLightTheme = useTheme() const breadcrumbSetters = useBreadcrumbs() @@ -48,25 +48,28 @@ export const WebStory: FC = ({ usePrependStyles('web-styles', webStyles) setExperimentalFeaturesForTesting() + const routes = [ + { + path, + element: ( + + ), + }, + ] + + const router = createMemoryRouter(routes, { + initialEntries, + initialIndex, + }) + return ( - - - - - } - /> - - - + ) diff --git a/client/web/src/components/diff/DiffHunk.test.tsx b/client/web/src/components/diff/DiffHunk.test.tsx index e9da713194b..c0e93bb1aca 100644 --- a/client/web/src/components/diff/DiffHunk.test.tsx +++ b/client/web/src/components/diff/DiffHunk.test.tsx @@ -1,14 +1,11 @@ import { render } from '@testing-library/react' -import { createMemoryHistory } from 'history' -import { Router } from 'react-router-dom' -import { CompatRouter } from 'react-router-dom-v5-compat' +import { MemoryRouter } from 'react-router-dom' import { DiffHunkLineType, FileDiffHunkFields } from '../../graphql-operations' import { DiffHunk } from './DiffHunk' describe('DiffHunk', () => { - const history = createMemoryHistory() const hunk: FileDiffHunkFields = { oldRange: { startLine: 159, lines: 7 }, oldNoNewlineAt: false, @@ -56,15 +53,13 @@ describe('DiffHunk', () => { it('renders a unified diff view for the given diff hunk', () => { expect( render( - - - - - - -
-
-
+ + + + + +
+
).asFragment() ).toMatchSnapshot() }) diff --git a/client/web/src/components/diff/DiffHunk.tsx b/client/web/src/components/diff/DiffHunk.tsx index 3542fe29bbc..a4bfbbc17d7 100644 --- a/client/web/src/components/diff/DiffHunk.tsx +++ b/client/web/src/components/diff/DiffHunk.tsx @@ -3,7 +3,7 @@ import * as React from 'react' import { VisuallyHidden } from '@reach/visually-hidden' import classNames from 'classnames' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { createLinkUrl, Link } from '@sourcegraph/wildcard' diff --git a/client/web/src/components/diff/DiffSplitHunk.test.tsx b/client/web/src/components/diff/DiffSplitHunk.test.tsx index 0cb2c9cd468..8e63774f0ec 100644 --- a/client/web/src/components/diff/DiffSplitHunk.test.tsx +++ b/client/web/src/components/diff/DiffSplitHunk.test.tsx @@ -1,7 +1,5 @@ import { cleanup, fireEvent, render, RenderResult } from '@testing-library/react' -import { createMemoryHistory } from 'history' -import { Router } from 'react-router' -import { CompatRouter } from 'react-router-dom-v5-compat' +import { MemoryRouter } from 'react-router-dom' import { DiffHunkLineType, FileDiffHunkFields } from '../../graphql-operations' @@ -54,19 +52,16 @@ describe('DiffSplitHunk', () => { }, } - const history = createMemoryHistory() let queries: RenderResult const renderWithProps = (props: DiffHunkProps): RenderResult => render( - - - - - - -
-
-
+ + + + + +
+
) afterEach(cleanup) diff --git a/client/web/src/components/diff/DiffSplitHunk.tsx b/client/web/src/components/diff/DiffSplitHunk.tsx index 65c02bad880..08cd198e2b4 100644 --- a/client/web/src/components/diff/DiffSplitHunk.tsx +++ b/client/web/src/components/diff/DiffSplitHunk.tsx @@ -1,7 +1,7 @@ import * as React from 'react' import classNames from 'classnames' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { DiffHunkLineType, FileDiffHunkFields } from '../../graphql-operations' diff --git a/client/web/src/components/diff/FileDiffNode.tsx b/client/web/src/components/diff/FileDiffNode.tsx index c3b16adb59a..1bf54800c7c 100644 --- a/client/web/src/components/diff/FileDiffNode.tsx +++ b/client/web/src/components/diff/FileDiffNode.tsx @@ -3,7 +3,7 @@ import React, { useState, useCallback } from 'react' import { mdiChevronDown, mdiChevronUp } from '@mdi/js' import classNames from 'classnames' import prettyBytes from 'pretty-bytes' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { Button, Badge, Link, Icon, Text, createLinkUrl, Tooltip } from '@sourcegraph/wildcard' diff --git a/client/web/src/components/externalServices/AddExternalServicePage.tsx b/client/web/src/components/externalServices/AddExternalServicePage.tsx index 4cde3ad89cd..2a6686e5ee0 100644 --- a/client/web/src/components/externalServices/AddExternalServicePage.tsx +++ b/client/web/src/components/externalServices/AddExternalServicePage.tsx @@ -1,6 +1,6 @@ import { FC, useEffect, useCallback, useState } from 'react' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { asError, isErrorLike, logger, renderMarkdown } from '@sourcegraph/common' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' diff --git a/client/web/src/components/externalServices/AddExternalServicesPage.tsx b/client/web/src/components/externalServices/AddExternalServicesPage.tsx index e06772163be..02bcff36384 100644 --- a/client/web/src/components/externalServices/AddExternalServicesPage.tsx +++ b/client/web/src/components/externalServices/AddExternalServicesPage.tsx @@ -1,7 +1,7 @@ import { FC } from 'react' import { mdiInformation } from '@mdi/js' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' import { ThemeProps } from '@sourcegraph/shared/src/theme' diff --git a/client/web/src/components/externalServices/ExternalServiceEditPage.tsx b/client/web/src/components/externalServices/ExternalServiceEditPage.tsx index d0ade1538e5..0b515c7b304 100644 --- a/client/web/src/components/externalServices/ExternalServiceEditPage.tsx +++ b/client/web/src/components/externalServices/ExternalServiceEditPage.tsx @@ -1,7 +1,7 @@ import React, { FC, useEffect, useState, useCallback } from 'react' import { mdiCog } from '@mdi/js' -import { Navigate, useParams } from 'react-router-dom-v5-compat' +import { Navigate, useParams } from 'react-router-dom' import { useQuery } from '@sourcegraph/http-client' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' diff --git a/client/web/src/components/externalServices/ExternalServicePage.tsx b/client/web/src/components/externalServices/ExternalServicePage.tsx index c5d5d8bc149..b0fe9a9974d 100644 --- a/client/web/src/components/externalServices/ExternalServicePage.tsx +++ b/client/web/src/components/externalServices/ExternalServicePage.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState, useCallback, useMemo, FC } from 'react' import { mdiCog, mdiConnection, mdiDelete } from '@mdi/js' import MapSearchIcon from 'mdi-react/MapSearchIcon' -import { useNavigate, useParams } from 'react-router-dom-v5-compat' +import { useNavigate, useParams } from 'react-router-dom' import { Subject } from 'rxjs' import { asError, isErrorLike } from '@sourcegraph/common' diff --git a/client/web/src/components/externalServices/ExternalServicesPage.tsx b/client/web/src/components/externalServices/ExternalServicesPage.tsx index c5c0d9c93fd..ecb9f4818cf 100644 --- a/client/web/src/components/externalServices/ExternalServicesPage.tsx +++ b/client/web/src/components/externalServices/ExternalServicesPage.tsx @@ -1,7 +1,7 @@ import { FC, useEffect } from 'react' import { mdiPlus } from '@mdi/js' -import { Navigate } from 'react-router-dom-v5-compat' +import { Navigate } from 'react-router-dom' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' import { Link, ButtonLink, Icon, PageHeader, Container } from '@sourcegraph/wildcard' diff --git a/client/web/src/components/useUserHistory.ts b/client/web/src/components/useUserHistory.ts index 6f8c6ab2834..66fa2589fc4 100644 --- a/client/web/src/components/useUserHistory.ts +++ b/client/web/src/components/useUserHistory.ts @@ -1,7 +1,7 @@ import { useEffect, useMemo } from 'react' import * as H from 'history' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { parseBrowserRepoURL } from '../util/url' diff --git a/client/web/src/contributions.ts b/client/web/src/contributions.ts index 826de7a9f7a..ed957d46243 100644 --- a/client/web/src/contributions.ts +++ b/client/web/src/contributions.ts @@ -1,6 +1,6 @@ import { useEffect, useRef, useState } from 'react' -import { useLocation, useNavigate } from 'react-router-dom-v5-compat' +import { useLocation, useNavigate } from 'react-router-dom' import { Subscription } from 'rxjs' import { ExtensionsControllerProps } from '@sourcegraph/shared/src/extensions/controller' diff --git a/client/web/src/enterprise/batches/batch-spec/edit/EditBatchSpecPage.tsx b/client/web/src/enterprise/batches/batch-spec/edit/EditBatchSpecPage.tsx index 577953b90d5..1fb100481c8 100644 --- a/client/web/src/enterprise/batches/batch-spec/edit/EditBatchSpecPage.tsx +++ b/client/web/src/enterprise/batches/batch-spec/edit/EditBatchSpecPage.tsx @@ -1,7 +1,7 @@ import React, { FC, useCallback, useMemo, useState } from 'react' import AlertCircleIcon from 'mdi-react/AlertCircleIcon' -import { useNavigate, useParams } from 'react-router-dom-v5-compat' +import { useNavigate, useParams } from 'react-router-dom' import { useQuery } from '@sourcegraph/http-client' import { Settings, SettingsCascadeProps } from '@sourcegraph/shared/src/settings/settings' diff --git a/client/web/src/enterprise/batches/batch-spec/edit/library/LibraryPane.tsx b/client/web/src/enterprise/batches/batch-spec/edit/library/LibraryPane.tsx index 20a03900f09..64ea93f4f3e 100644 --- a/client/web/src/enterprise/batches/batch-spec/edit/library/LibraryPane.tsx +++ b/client/web/src/enterprise/batches/batch-spec/edit/library/LibraryPane.tsx @@ -1,7 +1,7 @@ import React, { useState, useCallback } from 'react' import { mdiChevronDoubleLeft, mdiChevronDoubleRight, mdiOpenInNew } from '@mdi/js' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { animated, useSpring } from 'react-spring' import { Button, useLocalStorage, H3, H4, Icon, Link, Text, VIEWPORT_XL } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/batches/batch-spec/edit/useExecuteBatchSpec.ts b/client/web/src/enterprise/batches/batch-spec/edit/useExecuteBatchSpec.ts index e945ef92ee3..e70c03d48cd 100644 --- a/client/web/src/enterprise/batches/batch-spec/edit/useExecuteBatchSpec.ts +++ b/client/web/src/enterprise/batches/batch-spec/edit/useExecuteBatchSpec.ts @@ -1,6 +1,6 @@ import { useCallback, useState } from 'react' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { useMutation } from '@sourcegraph/http-client' import { Scalars } from '@sourcegraph/shared/src/graphql-operations' diff --git a/client/web/src/enterprise/batches/batch-spec/edit/workspaces-preview/WorkspacesPreviewFilterRow.tsx b/client/web/src/enterprise/batches/batch-spec/edit/workspaces-preview/WorkspacesPreviewFilterRow.tsx index c93918917cd..3d5c66268b1 100644 --- a/client/web/src/enterprise/batches/batch-spec/edit/workspaces-preview/WorkspacesPreviewFilterRow.tsx +++ b/client/web/src/enterprise/batches/batch-spec/edit/workspaces-preview/WorkspacesPreviewFilterRow.tsx @@ -1,6 +1,6 @@ import React, { FC, useCallback, useRef, useState } from 'react' -import { useLocation, useNavigate } from 'react-router-dom-v5-compat' +import { useLocation, useNavigate } from 'react-router-dom' import { Input, Form } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/batches/batch-spec/execute/ActionsMenu.tsx b/client/web/src/enterprise/batches/batch-spec/execute/ActionsMenu.tsx index 20fcd017433..356c948fb7e 100644 --- a/client/web/src/enterprise/batches/batch-spec/execute/ActionsMenu.tsx +++ b/client/web/src/enterprise/batches/batch-spec/execute/ActionsMenu.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useState } from 'react' import { mdiChevronDown, mdiAlertCircle, mdiPencil, mdiClose, mdiSync, mdiCloseCircleOutline } from '@mdi/js' import { noop } from 'lodash' -import { useNavigate, useLocation } from 'react-router-dom-v5-compat' +import { useNavigate, useLocation } from 'react-router-dom' import { useMutation } from '@sourcegraph/http-client' import { diff --git a/client/web/src/enterprise/batches/batch-spec/execute/ExecuteBatchSpecPage.tsx b/client/web/src/enterprise/batches/batch-spec/execute/ExecuteBatchSpecPage.tsx index e7f23259ba3..e490a0f3b2f 100644 --- a/client/web/src/enterprise/batches/batch-spec/execute/ExecuteBatchSpecPage.tsx +++ b/client/web/src/enterprise/batches/batch-spec/execute/ExecuteBatchSpecPage.tsx @@ -4,7 +4,7 @@ import { mdiProgressClock } from '@mdi/js' import { VisuallyHidden } from '@reach/visually-hidden' import AlertCircleIcon from 'mdi-react/AlertCircleIcon' import MapSearchIcon from 'mdi-react/MapSearchIcon' -import { Navigate, Route, Routes, useParams } from 'react-router-dom-v5-compat' +import { Navigate, Route, Routes, useParams } from 'react-router-dom' import { Timestamp } from '@sourcegraph/branded/src/components/Timestamp' import { useQuery } from '@sourcegraph/http-client' diff --git a/client/web/src/enterprise/batches/batch-spec/execute/ReadOnlyBatchSpecForm.tsx b/client/web/src/enterprise/batches/batch-spec/execute/ReadOnlyBatchSpecForm.tsx index 9104c4797e6..d89815dff05 100644 --- a/client/web/src/enterprise/batches/batch-spec/execute/ReadOnlyBatchSpecForm.tsx +++ b/client/web/src/enterprise/batches/batch-spec/execute/ReadOnlyBatchSpecForm.tsx @@ -1,6 +1,6 @@ import React, { FC, useMemo, useState } from 'react' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { useMutation } from '@sourcegraph/http-client' import { ThemeProps } from '@sourcegraph/shared/src/theme' diff --git a/client/web/src/enterprise/batches/batch-spec/execute/workspaces/ExecutionWorkspaces.tsx b/client/web/src/enterprise/batches/batch-spec/execute/workspaces/ExecutionWorkspaces.tsx index a6c4417dcb0..d363e290369 100644 --- a/client/web/src/enterprise/batches/batch-spec/execute/workspaces/ExecutionWorkspaces.tsx +++ b/client/web/src/enterprise/batches/batch-spec/execute/workspaces/ExecutionWorkspaces.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useRef } from 'react' import { mdiClose } from '@mdi/js' import { VisuallyHidden } from '@reach/visually-hidden' -import { useNavigate, useParams } from 'react-router-dom-v5-compat' +import { useNavigate, useParams } from 'react-router-dom' import { ThemeProps } from '@sourcegraph/shared/src/theme' import { Card, CardBody, H3, H1, Icon, Text, Code, ErrorAlert } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/batches/batch-spec/execute/workspaces/WorkspacesFilterRow.tsx b/client/web/src/enterprise/batches/batch-spec/execute/workspaces/WorkspacesFilterRow.tsx index 3d9c9d879cd..25c1aa2affb 100644 --- a/client/web/src/enterprise/batches/batch-spec/execute/workspaces/WorkspacesFilterRow.tsx +++ b/client/web/src/enterprise/batches/batch-spec/execute/workspaces/WorkspacesFilterRow.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react' import { lowerCase, upperFirst } from 'lodash' -import { useLocation, useNavigate } from 'react-router-dom-v5-compat' +import { useLocation, useNavigate } from 'react-router-dom' import { Input, Select, Form } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/batches/batch-spec/execute/workspaces/WorkspacesListItem.tsx b/client/web/src/enterprise/batches/batch-spec/execute/workspaces/WorkspacesListItem.tsx index 16280b755f3..9a60281d90e 100644 --- a/client/web/src/enterprise/batches/batch-spec/execute/workspaces/WorkspacesListItem.tsx +++ b/client/web/src/enterprise/batches/batch-spec/execute/workspaces/WorkspacesListItem.tsx @@ -1,6 +1,6 @@ import { FC, useCallback } from 'react' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { DiffStat } from '../../../../../components/diff/DiffStat' import { diff --git a/client/web/src/enterprise/batches/close/BatchChangeCloseAlert.tsx b/client/web/src/enterprise/batches/close/BatchChangeCloseAlert.tsx index 5c2c722e924..03ff47bcac8 100644 --- a/client/web/src/enterprise/batches/close/BatchChangeCloseAlert.tsx +++ b/client/web/src/enterprise/batches/close/BatchChangeCloseAlert.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useState } from 'react' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { isErrorLike, asError, pluralize } from '@sourcegraph/common' import { Button, AlertLink, CardBody, Card, Alert, Checkbox, Text, ErrorAlert } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/batches/close/BatchChangeClosePage.tsx b/client/web/src/enterprise/batches/close/BatchChangeClosePage.tsx index dd99defca6a..73a6ac4d8c4 100644 --- a/client/web/src/enterprise/batches/close/BatchChangeClosePage.tsx +++ b/client/web/src/enterprise/batches/close/BatchChangeClosePage.tsx @@ -2,7 +2,7 @@ import React, { useState, useMemo, useCallback } from 'react' import { subDays } from 'date-fns' import AlertCircleIcon from 'mdi-react/AlertCircleIcon' -import { useParams } from 'react-router-dom-v5-compat' +import { useParams } from 'react-router-dom' import { ErrorLike, isErrorLike } from '@sourcegraph/common' import { PageHeader, LoadingSpinner, useObservable } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/batches/create/ConfigurationForm.tsx b/client/web/src/enterprise/batches/create/ConfigurationForm.tsx index 1ac8b0459a0..94510ac0849 100644 --- a/client/web/src/enterprise/batches/create/ConfigurationForm.tsx +++ b/client/web/src/enterprise/batches/create/ConfigurationForm.tsx @@ -3,7 +3,7 @@ import React, { useCallback, useState } from 'react' import { mdiInformationOutline, mdiLock } from '@mdi/js' import classNames from 'classnames' import { noop } from 'lodash' -import { useNavigate, useLocation } from 'react-router-dom-v5-compat' +import { useNavigate, useLocation } from 'react-router-dom' import { useMutation } from '@sourcegraph/http-client' import { UserSettingFields, OrgSettingFields } from '@sourcegraph/shared/src/graphql-operations' diff --git a/client/web/src/enterprise/batches/create/useInsightTemplates.ts b/client/web/src/enterprise/batches/create/useInsightTemplates.ts index 179eba18a57..b4c12c367a2 100644 --- a/client/web/src/enterprise/batches/create/useInsightTemplates.ts +++ b/client/web/src/enterprise/batches/create/useInsightTemplates.ts @@ -1,4 +1,4 @@ -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { Settings, SettingsCascadeOrError } from '@sourcegraph/shared/src/settings/settings' diff --git a/client/web/src/enterprise/batches/create/useSearchTemplate.ts b/client/web/src/enterprise/batches/create/useSearchTemplate.ts index ebb4bd7e68d..2328d1627bc 100644 --- a/client/web/src/enterprise/batches/create/useSearchTemplate.ts +++ b/client/web/src/enterprise/batches/create/useSearchTemplate.ts @@ -1,4 +1,4 @@ -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import helloWorldSample from '../batch-spec/edit/library/hello-world.batch.yaml' import { insertQueryIntoLibraryItem, insertNameIntoLibraryItem } from '../batch-spec/yaml-util' diff --git a/client/web/src/enterprise/batches/detail/BatchChangeDetailsActionSection.tsx b/client/web/src/enterprise/batches/detail/BatchChangeDetailsActionSection.tsx index 9a5a1cf34c6..f04790f1bf3 100644 --- a/client/web/src/enterprise/batches/detail/BatchChangeDetailsActionSection.tsx +++ b/client/web/src/enterprise/batches/detail/BatchChangeDetailsActionSection.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useState } from 'react' import { mdiInformation, mdiClose, mdiDelete, mdiPencil } from '@mdi/js' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { isErrorLike, asError } from '@sourcegraph/common' import { Settings } from '@sourcegraph/shared/src/schema/settings.schema' diff --git a/client/web/src/enterprise/batches/detail/BatchChangeDetailsPage.tsx b/client/web/src/enterprise/batches/detail/BatchChangeDetailsPage.tsx index 73866c330a4..70b6151bec5 100644 --- a/client/web/src/enterprise/batches/detail/BatchChangeDetailsPage.tsx +++ b/client/web/src/enterprise/batches/detail/BatchChangeDetailsPage.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useMemo } from 'react' import { subDays, startOfDay } from 'date-fns' import AlertCircleIcon from 'mdi-react/AlertCircleIcon' -import { useParams } from 'react-router-dom-v5-compat' +import { useParams } from 'react-router-dom' import { useQuery } from '@sourcegraph/http-client' import { AuthenticatedUser } from '@sourcegraph/shared/src/auth' diff --git a/client/web/src/enterprise/batches/detail/BatchChangeDetailsTabs.tsx b/client/web/src/enterprise/batches/detail/BatchChangeDetailsTabs.tsx index 56478378234..efc53ec43ec 100644 --- a/client/web/src/enterprise/batches/detail/BatchChangeDetailsTabs.tsx +++ b/client/web/src/enterprise/batches/detail/BatchChangeDetailsTabs.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useMemo, useState } from 'react' import { mdiSourceBranch, mdiChartLineVariant, mdiFileDocument, mdiArchive, mdiMonitorStar } from '@mdi/js' -import { useNavigate, useLocation } from 'react-router-dom-v5-compat' +import { useNavigate, useLocation } from 'react-router-dom' import { Settings, SettingsCascadeProps } from '@sourcegraph/shared/src/settings/settings' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' diff --git a/client/web/src/enterprise/batches/detail/BulkOperationsAlerts.tsx b/client/web/src/enterprise/batches/detail/BulkOperationsAlerts.tsx index 118ff5a4de9..ff0d3c885b0 100644 --- a/client/web/src/enterprise/batches/detail/BulkOperationsAlerts.tsx +++ b/client/web/src/enterprise/batches/detail/BulkOperationsAlerts.tsx @@ -1,6 +1,6 @@ import React from 'react' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { pluralize } from '@sourcegraph/common' import { BulkOperationState } from '@sourcegraph/shared/src/graphql-operations' diff --git a/client/web/src/enterprise/batches/detail/ChangesetsArchivedNotice.tsx b/client/web/src/enterprise/batches/detail/ChangesetsArchivedNotice.tsx index 23f4d8182a7..09c57c59f0f 100644 --- a/client/web/src/enterprise/batches/detail/ChangesetsArchivedNotice.tsx +++ b/client/web/src/enterprise/batches/detail/ChangesetsArchivedNotice.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from 'react' import { mdiArchive } from '@mdi/js' -import { useLocation, useNavigate } from 'react-router-dom-v5-compat' +import { useLocation, useNavigate } from 'react-router-dom' import { pluralize } from '@sourcegraph/common' import { Link, Icon } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/batches/detail/changesets/ChangesetFilterRow.tsx b/client/web/src/enterprise/batches/detail/changesets/ChangesetFilterRow.tsx index cf0d0f04e13..633ff24e375 100644 --- a/client/web/src/enterprise/batches/detail/changesets/ChangesetFilterRow.tsx +++ b/client/web/src/enterprise/batches/detail/changesets/ChangesetFilterRow.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect, useRef, useCallback } from 'react' -import { useLocation, useNavigate } from 'react-router-dom-v5-compat' +import { useLocation, useNavigate } from 'react-router-dom' import { Input, Form } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/batches/detail/changesets/EmptyDraftChangesetListElement.tsx b/client/web/src/enterprise/batches/detail/changesets/EmptyDraftChangesetListElement.tsx index a049804ffcd..550a9564724 100644 --- a/client/web/src/enterprise/batches/detail/changesets/EmptyDraftChangesetListElement.tsx +++ b/client/web/src/enterprise/batches/detail/changesets/EmptyDraftChangesetListElement.tsx @@ -1,6 +1,6 @@ import React from 'react' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { Link, H3, Text } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/batches/global/GlobalBatchChangesArea.tsx b/client/web/src/enterprise/batches/global/GlobalBatchChangesArea.tsx index 00f36eb80d1..6e4627d3051 100644 --- a/client/web/src/enterprise/batches/global/GlobalBatchChangesArea.tsx +++ b/client/web/src/enterprise/batches/global/GlobalBatchChangesArea.tsx @@ -1,6 +1,6 @@ import React from 'react' -import { Routes, Route } from 'react-router-dom-v5-compat' +import { Routes, Route } from 'react-router-dom' import { Scalars } from '@sourcegraph/shared/src/graphql-operations' import { SettingsCascadeProps } from '@sourcegraph/shared/src/settings/settings' diff --git a/client/web/src/enterprise/batches/list/BatchChangeListPage.tsx b/client/web/src/enterprise/batches/list/BatchChangeListPage.tsx index 48846fd0f91..b7111f9639b 100644 --- a/client/web/src/enterprise/batches/list/BatchChangeListPage.tsx +++ b/client/web/src/enterprise/batches/list/BatchChangeListPage.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useCallback, useState, useMemo } from 'react' import classNames from 'classnames' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { pluralize } from '@sourcegraph/common' import { dataOrThrowErrors, useQuery } from '@sourcegraph/http-client' diff --git a/client/web/src/enterprise/batches/list/useBatchChangeListFilters.ts b/client/web/src/enterprise/batches/list/useBatchChangeListFilters.ts index f6c83297a83..958b3c4f2f4 100644 --- a/client/web/src/enterprise/batches/list/useBatchChangeListFilters.ts +++ b/client/web/src/enterprise/batches/list/useBatchChangeListFilters.ts @@ -1,6 +1,6 @@ import { useCallback, useEffect, useState } from 'react' -import { useLocation, useNavigate } from 'react-router-dom-v5-compat' +import { useLocation, useNavigate } from 'react-router-dom' import { LegacyBatchChangesFilter } from '@sourcegraph/shared/src/settings/temporary/TemporarySettings' import { useTemporarySetting } from '@sourcegraph/shared/src/settings/temporary/useTemporarySetting' diff --git a/client/web/src/enterprise/batches/preview/BatchChangePreviewPage.tsx b/client/web/src/enterprise/batches/preview/BatchChangePreviewPage.tsx index c395675f219..948831d95d6 100644 --- a/client/web/src/enterprise/batches/preview/BatchChangePreviewPage.tsx +++ b/client/web/src/enterprise/batches/preview/BatchChangePreviewPage.tsx @@ -1,7 +1,7 @@ import { FC, useEffect } from 'react' import AlertCircleIcon from 'mdi-react/AlertCircleIcon' -import { useParams } from 'react-router-dom-v5-compat' +import { useParams } from 'react-router-dom' import { useQuery } from '@sourcegraph/http-client' import { Alert, LoadingSpinner, PageHeader } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/batches/preview/BatchChangePreviewTabs.tsx b/client/web/src/enterprise/batches/preview/BatchChangePreviewTabs.tsx index 22f2f94d82b..e9af6ad55c2 100644 --- a/client/web/src/enterprise/batches/preview/BatchChangePreviewTabs.tsx +++ b/client/web/src/enterprise/batches/preview/BatchChangePreviewTabs.tsx @@ -1,7 +1,7 @@ import React, { useCallback } from 'react' import { mdiSourceBranch, mdiFileDocument } from '@mdi/js' -import { useNavigate, useLocation } from 'react-router-dom-v5-compat' +import { useNavigate, useLocation } from 'react-router-dom' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' import { ThemeProps } from '@sourcegraph/shared/src/theme' diff --git a/client/web/src/enterprise/batches/preview/CreateUpdateBatchChangeAlert.tsx b/client/web/src/enterprise/batches/preview/CreateUpdateBatchChangeAlert.tsx index 9b99f9dfa7b..ffec222e7ae 100644 --- a/client/web/src/enterprise/batches/preview/CreateUpdateBatchChangeAlert.tsx +++ b/client/web/src/enterprise/batches/preview/CreateUpdateBatchChangeAlert.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useContext, useState } from 'react' import classNames from 'classnames' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { isErrorLike } from '@sourcegraph/common' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' diff --git a/client/web/src/enterprise/batches/preview/list/PreviewFilterRow.tsx b/client/web/src/enterprise/batches/preview/list/PreviewFilterRow.tsx index da92ac1b5ea..fa5c27a8255 100644 --- a/client/web/src/enterprise/batches/preview/list/PreviewFilterRow.tsx +++ b/client/web/src/enterprise/batches/preview/list/PreviewFilterRow.tsx @@ -1,6 +1,6 @@ import React, { FC, useCallback, useContext, useEffect, useRef } from 'react' -import { useLocation, useNavigate } from 'react-router-dom-v5-compat' +import { useLocation, useNavigate } from 'react-router-dom' import { Input, Form } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/code-monitoring/CodeMonitorList.tsx b/client/web/src/enterprise/code-monitoring/CodeMonitorList.tsx index b4b0d66b209..873fd259f94 100644 --- a/client/web/src/enterprise/code-monitoring/CodeMonitorList.tsx +++ b/client/web/src/enterprise/code-monitoring/CodeMonitorList.tsx @@ -1,6 +1,6 @@ import React, { useCallback } from 'react' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { of } from 'rxjs' import { buildCloudTrialURL } from '@sourcegraph/shared/src/util/url' diff --git a/client/web/src/enterprise/code-monitoring/CodeMonitoringPage.test.tsx b/client/web/src/enterprise/code-monitoring/CodeMonitoringPage.test.tsx index 7a59dd4b907..3579141f9a0 100644 --- a/client/web/src/enterprise/code-monitoring/CodeMonitoringPage.test.tsx +++ b/client/web/src/enterprise/code-monitoring/CodeMonitoringPage.test.tsx @@ -1,6 +1,5 @@ import { render, fireEvent } from '@testing-library/react' -import { MemoryRouter } from 'react-router' -import { CompatRouter } from 'react-router-dom-v5-compat' +import { MemoryRouter } from 'react-router-dom' import { of } from 'rxjs' import sinon from 'sinon' @@ -50,9 +49,7 @@ describe('CodeMonitoringListPage', () => { test('Clicking enabled toggle calls toggleCodeMonitorEnabled', () => { const component = render( - - - + ) const toggle = component.getByTestId('toggle-monitor-enabled') @@ -63,9 +60,7 @@ describe('CodeMonitoringListPage', () => { test('Switching tabs from getting started to empty list works', () => { const component = render( - - - + ) const codeMonitorsButton = component.getByRole('button', { name: 'Code monitors' }) @@ -78,9 +73,7 @@ describe('CodeMonitoringListPage', () => { test('Switching tabs from list to getting started works', () => { const component = render( - - - + ) const gettingStartedButton = component.getByRole('button', { name: 'Getting started' }) diff --git a/client/web/src/enterprise/code-monitoring/CreateCodeMonitorPage.test.tsx b/client/web/src/enterprise/code-monitoring/CreateCodeMonitorPage.test.tsx index 7ec915b5447..b3bd75e32e2 100644 --- a/client/web/src/enterprise/code-monitoring/CreateCodeMonitorPage.test.tsx +++ b/client/web/src/enterprise/code-monitoring/CreateCodeMonitorPage.test.tsx @@ -1,6 +1,6 @@ import { screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { Route, Routes } from 'react-router-dom-v5-compat' +import { Route, Routes } from 'react-router-dom' import { NEVER, of } from 'rxjs' import sinon from 'sinon' diff --git a/client/web/src/enterprise/code-monitoring/CreateCodeMonitorPage.tsx b/client/web/src/enterprise/code-monitoring/CreateCodeMonitorPage.tsx index 4072401a00e..1df85dfbd06 100644 --- a/client/web/src/enterprise/code-monitoring/CreateCodeMonitorPage.tsx +++ b/client/web/src/enterprise/code-monitoring/CreateCodeMonitorPage.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useEffect, useMemo } from 'react' import { VisuallyHidden } from '@reach/visually-hidden' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { Observable } from 'rxjs' import { ThemeProps } from '@sourcegraph/shared/src/theme' diff --git a/client/web/src/enterprise/code-monitoring/ManageCodeMonitorPage.test.tsx b/client/web/src/enterprise/code-monitoring/ManageCodeMonitorPage.test.tsx index 65fd2e45f47..fc3d08ac75a 100644 --- a/client/web/src/enterprise/code-monitoring/ManageCodeMonitorPage.test.tsx +++ b/client/web/src/enterprise/code-monitoring/ManageCodeMonitorPage.test.tsx @@ -1,6 +1,6 @@ import { screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { Route, Routes } from 'react-router-dom-v5-compat/' +import { Route, Routes } from 'react-router-dom' import { of } from 'rxjs' import sinon from 'sinon' @@ -204,8 +204,7 @@ describe('ManageCodeMonitorPage', () => { }) test('Clicking delete code monitor opens deletion confirmation modal', () => { - let currentPathname = '' - renderWithBrandedContext( + const { locationRef } = renderWithBrandedContext( } /> @@ -214,7 +213,6 @@ describe('ManageCodeMonitorPage', () => { , { route: '/code-monitoring/test-monitor-id', - onLocationChange: location => (currentPathname = location.pathname), } ) userEvent.click(screen.getByTestId('delete-monitor')) @@ -225,6 +223,6 @@ describe('ManageCodeMonitorPage', () => { userEvent.click(confirmDeleteButton) sinon.assert.calledOnce(props.deleteCodeMonitor) - expect(currentPathname).toEqual('/code-monitoring') + expect(locationRef.current?.pathname).toEqual('/code-monitoring') }) }) diff --git a/client/web/src/enterprise/code-monitoring/ManageCodeMonitorPage.tsx b/client/web/src/enterprise/code-monitoring/ManageCodeMonitorPage.tsx index 67a713da292..eca6c728b99 100644 --- a/client/web/src/enterprise/code-monitoring/ManageCodeMonitorPage.tsx +++ b/client/web/src/enterprise/code-monitoring/ManageCodeMonitorPage.tsx @@ -1,7 +1,7 @@ import React, { useEffect } from 'react' import { VisuallyHidden } from '@reach/visually-hidden' -import { useParams } from 'react-router-dom-v5-compat' +import { useParams } from 'react-router-dom' import { Observable } from 'rxjs' import { startWith, catchError, tap } from 'rxjs/operators' diff --git a/client/web/src/enterprise/code-monitoring/components/CodeMonitorForm.tsx b/client/web/src/enterprise/code-monitoring/components/CodeMonitorForm.tsx index 2f6c38ed02a..486304abf7d 100644 --- a/client/web/src/enterprise/code-monitoring/components/CodeMonitorForm.tsx +++ b/client/web/src/enterprise/code-monitoring/components/CodeMonitorForm.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useMemo, useState } from 'react' import classNames from 'classnames' import { isEqual } from 'lodash' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { Observable } from 'rxjs' import { mergeMap, startWith, catchError, tap, filter } from 'rxjs/operators' diff --git a/client/web/src/enterprise/code-monitoring/components/DeleteMonitorModal.tsx b/client/web/src/enterprise/code-monitoring/components/DeleteMonitorModal.tsx index f0a96f8880e..050e783cec3 100644 --- a/client/web/src/enterprise/code-monitoring/components/DeleteMonitorModal.tsx +++ b/client/web/src/enterprise/code-monitoring/components/DeleteMonitorModal.tsx @@ -1,6 +1,6 @@ import React, { useCallback } from 'react' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { Observable, throwError } from 'rxjs' import { mergeMap, startWith, tap, catchError } from 'rxjs/operators' diff --git a/client/web/src/enterprise/code-monitoring/global/GlobalCodeMonitoringArea.tsx b/client/web/src/enterprise/code-monitoring/global/GlobalCodeMonitoringArea.tsx index 66e21bc6944..49eb2b88a9e 100644 --- a/client/web/src/enterprise/code-monitoring/global/GlobalCodeMonitoringArea.tsx +++ b/client/web/src/enterprise/code-monitoring/global/GlobalCodeMonitoringArea.tsx @@ -1,6 +1,6 @@ import React from 'react' -import { Routes, Route } from 'react-router-dom-v5-compat' +import { Routes, Route } from 'react-router-dom' import { PlatformContextProps } from '@sourcegraph/shared/src/platform/context' import { SettingsCascadeProps } from '@sourcegraph/shared/src/settings/settings' diff --git a/client/web/src/enterprise/codeintel/configuration/pages/CodeIntelConfigurationPage.tsx b/client/web/src/enterprise/codeintel/configuration/pages/CodeIntelConfigurationPage.tsx index 95b708880ce..fa8be9db7bd 100644 --- a/client/web/src/enterprise/codeintel/configuration/pages/CodeIntelConfigurationPage.tsx +++ b/client/web/src/enterprise/codeintel/configuration/pages/CodeIntelConfigurationPage.tsx @@ -13,7 +13,7 @@ import { mdiSourceRepository, } from '@mdi/js' import classNames from 'classnames' -import { useNavigate, useLocation } from 'react-router-dom-v5-compat' +import { useNavigate, useLocation } from 'react-router-dom' import { Subject } from 'rxjs' import { RepoLink } from '@sourcegraph/shared/src/components/RepoLink' diff --git a/client/web/src/enterprise/codeintel/configuration/pages/CodeIntelConfigurationPolicyPage.tsx b/client/web/src/enterprise/codeintel/configuration/pages/CodeIntelConfigurationPolicyPage.tsx index ab474b98912..6513c54e801 100644 --- a/client/web/src/enterprise/codeintel/configuration/pages/CodeIntelConfigurationPolicyPage.tsx +++ b/client/web/src/enterprise/codeintel/configuration/pages/CodeIntelConfigurationPolicyPage.tsx @@ -4,7 +4,7 @@ import { ApolloError } from '@apollo/client' import { mdiDelete, mdiGraveStone } from '@mdi/js' import classNames from 'classnames' import { debounce } from 'lodash' -import { useNavigate, useParams, useLocation } from 'react-router-dom-v5-compat' +import { useNavigate, useParams, useLocation } from 'react-router-dom' import { Toggle } from '@sourcegraph/branded/src/components/Toggle' import { useLazyQuery } from '@sourcegraph/http-client' diff --git a/client/web/src/enterprise/codeintel/indexes/pages/CodeIntelPreciseIndexPage.tsx b/client/web/src/enterprise/codeintel/indexes/pages/CodeIntelPreciseIndexPage.tsx index 2572e2e74fc..71798feb6ba 100644 --- a/client/web/src/enterprise/codeintel/indexes/pages/CodeIntelPreciseIndexPage.tsx +++ b/client/web/src/enterprise/codeintel/indexes/pages/CodeIntelPreciseIndexPage.tsx @@ -3,7 +3,7 @@ import { FunctionComponent, useCallback, useEffect, useMemo, useState } from 're import { useApolloClient } from '@apollo/client' import { mdiDelete, mdiGraph, mdiHistory, mdiRecycle, mdiRedo, mdiTimerSand } from '@mdi/js' import classNames from 'classnames' -import { Navigate, useLocation, useParams, useNavigate } from 'react-router-dom-v5-compat' +import { Navigate, useLocation, useParams, useNavigate } from 'react-router-dom' import { takeWhile } from 'rxjs/operators' import { ErrorLike, isErrorLike } from '@sourcegraph/common' diff --git a/client/web/src/enterprise/codeintel/indexes/pages/CodeIntelPreciseIndexesPage.tsx b/client/web/src/enterprise/codeintel/indexes/pages/CodeIntelPreciseIndexesPage.tsx index 2a2f34c839a..ea1fffab554 100644 --- a/client/web/src/enterprise/codeintel/indexes/pages/CodeIntelPreciseIndexesPage.tsx +++ b/client/web/src/enterprise/codeintel/indexes/pages/CodeIntelPreciseIndexesPage.tsx @@ -3,7 +3,7 @@ import { FunctionComponent, useCallback, useEffect, useMemo, useState } from 're import { useApolloClient } from '@apollo/client' import { mdiChevronRight, mdiDelete, mdiMapSearch, mdiRedo } from '@mdi/js' import classNames from 'classnames' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { of, Subject } from 'rxjs' import { tap } from 'rxjs/operators' diff --git a/client/web/src/enterprise/codeintel/repo/CodeIntelSidebar.tsx b/client/web/src/enterprise/codeintel/repo/CodeIntelSidebar.tsx index b9e7eb094ab..449440bbd45 100644 --- a/client/web/src/enterprise/codeintel/repo/CodeIntelSidebar.tsx +++ b/client/web/src/enterprise/codeintel/repo/CodeIntelSidebar.tsx @@ -1,4 +1,4 @@ -import * as React from 'react' +import { FC } from 'react' import { SidebarGroupHeader, SidebarGroup, SidebarNavItem } from '../../../components/Sidebar' import { NavGroupDescriptor } from '../../../util/contributions' @@ -14,27 +14,17 @@ interface Props { } /** Sidebar for code navigation pages. */ -export const CodeIntelSidebar: React.FunctionComponent> = ({ - codeIntelSidebarGroups, - className, - repo, -}: Props) => ( +export const CodeIntelSidebar: FC = ({ codeIntelSidebarGroups, className, repo }) => (
- {codeIntelSidebarGroups.map( - ({ header, items, condition = () => true }, index) => - condition({}) && ( - - {header && } - {items.map( - ({ label, to, exact, condition = () => true }) => - condition({}) && ( - - {label} - - ) - )} - - ) - )} + {codeIntelSidebarGroups.map(({ header, items }, index) => ( + + {header && } + {items.map(({ label, to }) => ( + + {label} + + ))} + + ))}
) diff --git a/client/web/src/enterprise/codeintel/repo/RepositoryCodeIntelArea.tsx b/client/web/src/enterprise/codeintel/repo/RepositoryCodeIntelArea.tsx index ee67bf9ddd1..a8f24321a73 100644 --- a/client/web/src/enterprise/codeintel/repo/RepositoryCodeIntelArea.tsx +++ b/client/web/src/enterprise/codeintel/repo/RepositoryCodeIntelArea.tsx @@ -1,6 +1,6 @@ import { FC } from 'react' -import { Routes, Route, Navigate } from 'react-router-dom-v5-compat' +import { Routes, Route, Navigate } from 'react-router-dom' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' import { ThemeProps } from '@sourcegraph/shared/src/theme' @@ -137,13 +137,13 @@ const BREADCRUMB = { key: 'code-intelligence', element: 'Code graph data' } * Renders pages related to repository code graph. */ export const RepositoryCodeIntelArea: FC = props => { - const { useBreadcrumb } = props + const { useBreadcrumb, repo } = props useBreadcrumb(BREADCRUMB) return (
- +
diff --git a/client/web/src/enterprise/cody/GlobalCodyArea.tsx b/client/web/src/enterprise/cody/GlobalCodyArea.tsx index b85ea0690b6..96cdddee2b5 100644 --- a/client/web/src/enterprise/cody/GlobalCodyArea.tsx +++ b/client/web/src/enterprise/cody/GlobalCodyArea.tsx @@ -1,6 +1,6 @@ import React from 'react' -import { Routes, Route } from 'react-router-dom-v5-compat' +import { Routes, Route } from 'react-router-dom' import { Page } from '../../components/Page' import { useFeatureFlag } from '../../featureFlags/useFeatureFlag' diff --git a/client/web/src/enterprise/embed/EmbeddedWebApp.tsx b/client/web/src/enterprise/embed/EmbeddedWebApp.tsx index 686559d49eb..7704f36c44a 100644 --- a/client/web/src/enterprise/embed/EmbeddedWebApp.tsx +++ b/client/web/src/enterprise/embed/EmbeddedWebApp.tsx @@ -1,7 +1,6 @@ import { FC, Suspense, useEffect, useMemo } from 'react' -import { Router } from 'react-router' -import { CompatRouter, Routes, Route } from 'react-router-dom-v5-compat' +import { BrowserRouter, Routes, Route } from 'react-router-dom' import { createController as createExtensionsController } from '@sourcegraph/shared/src/extensions/createSyncLoadedController' import { lazyComponent } from '@sourcegraph/shared/src/util/lazyComponent' @@ -12,7 +11,6 @@ import '../../SourcegraphWebApp.scss' import { GlobalContributions } from '../../contributions' import { createPlatformContext } from '../../platform/context' import { useTheme, ThemePreference } from '../../theme' -import { globalHistory } from '../../util/globalHistory' import { OpenNewTabAnchorLink } from './OpenNewTabAnchorLink' @@ -61,48 +59,46 @@ export const EmbeddedWebApp: FC = () => { // // IMPORTANT: Please consult with the security team if you are unsure whether your changes could introduce security exploits. return ( - - - -
- - -
- } - > - - - } - /> - - Invalid embedding route, please check the embedding URL. - - } - /> - - - -
- - - + + +
+ + +
+ } + > + + + } + /> + + Invalid embedding route, please check the embedding URL. + + } + /> + + + +
+
+ ) } diff --git a/client/web/src/enterprise/executors/ExecutorsSiteAdminArea.tsx b/client/web/src/enterprise/executors/ExecutorsSiteAdminArea.tsx index 9f89beba9d7..15eaa968e60 100644 --- a/client/web/src/enterprise/executors/ExecutorsSiteAdminArea.tsx +++ b/client/web/src/enterprise/executors/ExecutorsSiteAdminArea.tsx @@ -1,6 +1,6 @@ import { FC } from 'react' -import { Route, Routes } from 'react-router-dom-v5-compat' +import { Route, Routes } from 'react-router-dom' import { lazyComponent } from '@sourcegraph/shared/src/util/lazyComponent' diff --git a/client/web/src/enterprise/insights/CodeInsightsAppRouter.tsx b/client/web/src/enterprise/insights/CodeInsightsAppRouter.tsx index 159cde2c909..3025d026daa 100644 --- a/client/web/src/enterprise/insights/CodeInsightsAppRouter.tsx +++ b/client/web/src/enterprise/insights/CodeInsightsAppRouter.tsx @@ -1,7 +1,7 @@ import { FC, useEffect, useState } from 'react' import { gql, useLazyQuery } from '@apollo/client' -import { Route, Routes, Navigate } from 'react-router-dom-v5-compat' +import { Route, Routes, Navigate } from 'react-router-dom' import { useTemporarySetting } from '@sourcegraph/shared/src/settings/temporary/useTemporarySetting' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' diff --git a/client/web/src/enterprise/insights/pages/CodeInsightsRootPage.test.tsx b/client/web/src/enterprise/insights/pages/CodeInsightsRootPage.test.tsx index d01c9c49dbe..80e0820c463 100644 --- a/client/web/src/enterprise/insights/pages/CodeInsightsRootPage.test.tsx +++ b/client/web/src/enterprise/insights/pages/CodeInsightsRootPage.test.tsx @@ -4,8 +4,7 @@ import { ReactElement } from 'react' import { MockedResponse } from '@apollo/client/testing' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { MemoryRouter } from 'react-router-dom' -import { Routes, Route, CompatRouter } from 'react-router-dom-v5-compat' +import { MemoryRouter, Routes, Route } from 'react-router-dom' import sinon from 'sinon' import { getDocumentNode } from '@sourcegraph/http-client' @@ -22,8 +21,8 @@ interface ReactRouterMock { useNavigate: () => unknown } -jest.mock('react-router', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => ({ push: jest.fn(), }), @@ -87,11 +86,9 @@ const renderWithBrandedContext = (component: ReactElement, { route = '/', path = - - - - - + + + diff --git a/client/web/src/enterprise/insights/pages/CodeInsightsRootPage.tsx b/client/web/src/enterprise/insights/pages/CodeInsightsRootPage.tsx index 02e12a9e9ab..5151f9ca4fb 100644 --- a/client/web/src/enterprise/insights/pages/CodeInsightsRootPage.tsx +++ b/client/web/src/enterprise/insights/pages/CodeInsightsRootPage.tsx @@ -1,7 +1,7 @@ import { Suspense, FC, memo } from 'react' import { mdiPlus } from '@mdi/js' -import { useParams, useNavigate } from 'react-router-dom-v5-compat' +import { useParams, useNavigate } from 'react-router-dom' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' import { lazyComponent } from '@sourcegraph/shared/src/util/lazyComponent' diff --git a/client/web/src/enterprise/insights/pages/dashboards/creation/InsightsDashboardCreationPage.tsx b/client/web/src/enterprise/insights/pages/dashboards/creation/InsightsDashboardCreationPage.tsx index a39b25f1bb4..568af287daa 100644 --- a/client/web/src/enterprise/insights/pages/dashboards/creation/InsightsDashboardCreationPage.tsx +++ b/client/web/src/enterprise/insights/pages/dashboards/creation/InsightsDashboardCreationPage.tsx @@ -1,7 +1,7 @@ import React, { useContext, useMemo } from 'react' import classNames from 'classnames' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' import { PageHeader, Container, Button, LoadingSpinner, useObservable, Link, Tooltip } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/insights/pages/dashboards/dashboard-view/DashboardsContentPage.test.tsx b/client/web/src/enterprise/insights/pages/dashboards/dashboard-view/DashboardsContentPage.test.tsx index 58457760b2a..0b5a485e4fb 100644 --- a/client/web/src/enterprise/insights/pages/dashboards/dashboard-view/DashboardsContentPage.test.tsx +++ b/client/web/src/enterprise/insights/pages/dashboards/dashboard-view/DashboardsContentPage.test.tsx @@ -217,7 +217,7 @@ describe('DashboardsContent', () => { it('redirect to new dashboard page on selection', async () => { const screen = renderDashboardsContent() - const { history, user } = screen + const { locationRef, user } = screen const chooseDashboard = await waitFor(() => screen.getByRole('button', { name: /Choose a dashboard/ })) user.click(chooseDashboard) @@ -229,17 +229,15 @@ describe('DashboardsContent', () => { user.click(dashboard2) } - expect(history.location.pathname).toEqual('/insights/dashboards/bar') + expect(locationRef.current?.pathname).toEqual('/insights/dashboards/bar') }) it('redirects to dashboard edit page', async () => { const screen = renderDashboardsContent() - const { history } = screen - await triggerDashboardMenuItem(screen, 'Configure dashboard') - expect(history.location.pathname).toEqual('/insights/dashboards/foo/edit') + expect(screen.locationRef.current?.pathname).toEqual('/insights/dashboards/foo/edit') }) it('opens add insight modal', async () => { diff --git a/client/web/src/enterprise/insights/pages/dashboards/dashboard-view/DashboardsView.tsx b/client/web/src/enterprise/insights/pages/dashboards/dashboard-view/DashboardsView.tsx index b05f5182452..db51dfe2c5c 100644 --- a/client/web/src/enterprise/insights/pages/dashboards/dashboard-view/DashboardsView.tsx +++ b/client/web/src/enterprise/insights/pages/dashboards/dashboard-view/DashboardsView.tsx @@ -1,6 +1,6 @@ import { FC } from 'react' -import { Navigate } from 'react-router-dom-v5-compat' +import { Navigate } from 'react-router-dom' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' import { LoadingSpinner } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/insights/pages/dashboards/dashboard-view/components/dashboards-content/DashboardsContent.tsx b/client/web/src/enterprise/insights/pages/dashboards/dashboard-view/components/dashboards-content/DashboardsContent.tsx index 3fc0f3abb16..8c6e4d10e8e 100644 --- a/client/web/src/enterprise/insights/pages/dashboards/dashboard-view/components/dashboards-content/DashboardsContent.tsx +++ b/client/web/src/enterprise/insights/pages/dashboards/dashboard-view/components/dashboards-content/DashboardsContent.tsx @@ -3,7 +3,7 @@ import { FC, useEffect, useState } from 'react' import classNames from 'classnames' import MapSearchIcon from 'mdi-react/MapSearchIcon' import ViewDashboardOutlineIcon from 'mdi-react/ViewDashboardOutlineIcon' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { useTemporarySetting } from '@sourcegraph/shared/src/settings/temporary/useTemporarySetting' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' diff --git a/client/web/src/enterprise/insights/pages/dashboards/dashboard-view/components/delete-dashboard-modal/DeleteDashboardModal.tsx b/client/web/src/enterprise/insights/pages/dashboards/dashboard-view/components/delete-dashboard-modal/DeleteDashboardModal.tsx index ffa3794af0e..6dcf979a178 100644 --- a/client/web/src/enterprise/insights/pages/dashboards/dashboard-view/components/delete-dashboard-modal/DeleteDashboardModal.tsx +++ b/client/web/src/enterprise/insights/pages/dashboards/dashboard-view/components/delete-dashboard-modal/DeleteDashboardModal.tsx @@ -2,7 +2,7 @@ import React from 'react' import { mdiClose } from '@mdi/js' import { VisuallyHidden } from '@reach/visually-hidden' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { isErrorLike } from '@sourcegraph/common' import { Button, Modal, H2, Icon, ErrorAlert } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/insights/pages/dashboards/edit-dashboard/EditDashobardPage.tsx b/client/web/src/enterprise/insights/pages/dashboards/edit-dashboard/EditDashobardPage.tsx index 787831a71f9..c63878a8c7f 100644 --- a/client/web/src/enterprise/insights/pages/dashboards/edit-dashboard/EditDashobardPage.tsx +++ b/client/web/src/enterprise/insights/pages/dashboards/edit-dashboard/EditDashobardPage.tsx @@ -2,7 +2,7 @@ import { FC, useContext, useMemo } from 'react' import classNames from 'classnames' import MapSearchIcon from 'mdi-react/MapSearchIcon' -import { useParams, useNavigate } from 'react-router-dom-v5-compat' +import { useParams, useNavigate } from 'react-router-dom' import { Button, diff --git a/client/web/src/enterprise/insights/pages/insights/creation/CreationRoutes.tsx b/client/web/src/enterprise/insights/pages/insights/creation/CreationRoutes.tsx index 78ade0f7a9d..1722d12e134 100644 --- a/client/web/src/enterprise/insights/pages/insights/creation/CreationRoutes.tsx +++ b/client/web/src/enterprise/insights/pages/insights/creation/CreationRoutes.tsx @@ -1,6 +1,6 @@ import { FC } from 'react' -import { Routes, Route } from 'react-router-dom-v5-compat' +import { Routes, Route } from 'react-router-dom' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' import { lazyComponent } from '@sourcegraph/shared/src/util/lazyComponent' diff --git a/client/web/src/enterprise/insights/pages/insights/creation/InsightCreationPage.tsx b/client/web/src/enterprise/insights/pages/insights/creation/InsightCreationPage.tsx index 493bb0f8b6d..ed455afec8c 100644 --- a/client/web/src/enterprise/insights/pages/insights/creation/InsightCreationPage.tsx +++ b/client/web/src/enterprise/insights/pages/insights/creation/InsightCreationPage.tsx @@ -1,6 +1,6 @@ import { FC, useContext } from 'react' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' diff --git a/client/web/src/enterprise/insights/pages/insights/creation/intro/IntroCreationPage.tsx b/client/web/src/enterprise/insights/pages/insights/creation/intro/IntroCreationPage.tsx index 99e84c5e89a..7e66cf6646e 100644 --- a/client/web/src/enterprise/insights/pages/insights/creation/intro/IntroCreationPage.tsx +++ b/client/web/src/enterprise/insights/pages/insights/creation/intro/IntroCreationPage.tsx @@ -1,6 +1,6 @@ import React, { useEffect } from 'react' -import { useLocation, useNavigate } from 'react-router-dom-v5-compat' +import { useLocation, useNavigate } from 'react-router-dom' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' import { PageHeader, Link } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/insights/pages/insights/edit-insight/EditInsightPage.tsx b/client/web/src/enterprise/insights/pages/insights/edit-insight/EditInsightPage.tsx index e35301a37df..5870fd9c45c 100644 --- a/client/web/src/enterprise/insights/pages/insights/edit-insight/EditInsightPage.tsx +++ b/client/web/src/enterprise/insights/pages/insights/edit-insight/EditInsightPage.tsx @@ -1,7 +1,7 @@ import { FC, useContext, useMemo } from 'react' import MapSearchIcon from 'mdi-react/MapSearchIcon' -import { useParams } from 'react-router-dom-v5-compat' +import { useParams } from 'react-router-dom' import { LoadingSpinner, useObservable, Link, PageHeader, Text } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/insights/pages/insights/edit-insight/hooks/use-edit-page-handlers.ts b/client/web/src/enterprise/insights/pages/insights/edit-insight/hooks/use-edit-page-handlers.ts index 100614935f5..83bff644d6d 100644 --- a/client/web/src/enterprise/insights/pages/insights/edit-insight/hooks/use-edit-page-handlers.ts +++ b/client/web/src/enterprise/insights/pages/insights/edit-insight/hooks/use-edit-page-handlers.ts @@ -1,6 +1,6 @@ import { useContext } from 'react' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { SubmissionErrors } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/insights/pages/insights/insight/CodeInsightIndependentPage.tsx b/client/web/src/enterprise/insights/pages/insights/insight/CodeInsightIndependentPage.tsx index 64da40eba9d..556c5c03725 100644 --- a/client/web/src/enterprise/insights/pages/insights/insight/CodeInsightIndependentPage.tsx +++ b/client/web/src/enterprise/insights/pages/insights/insight/CodeInsightIndependentPage.tsx @@ -1,6 +1,6 @@ import { FunctionComponent, useContext, useEffect, useMemo } from 'react' -import { useParams } from 'react-router-dom-v5-compat' +import { useParams } from 'react-router-dom' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' import { LoadingSpinner, PageHeader, useObservable } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/insights/pages/insights/insight/components/actions/CodeInsightIndependentPageActions.tsx b/client/web/src/enterprise/insights/pages/insights/insight/components/actions/CodeInsightIndependentPageActions.tsx index 18912bf0eb7..61b825211cb 100644 --- a/client/web/src/enterprise/insights/pages/insights/insight/components/actions/CodeInsightIndependentPageActions.tsx +++ b/client/web/src/enterprise/insights/pages/insights/insight/components/actions/CodeInsightIndependentPageActions.tsx @@ -2,7 +2,7 @@ import { FunctionComponent, useRef, useState } from 'react' import { mdiLinkVariant } from '@mdi/js' import { escapeRegExp } from 'lodash' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' import { Button, Link, Icon, Tooltip } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/insights/pages/insights/insight/components/standalone-backend-insight/StandaloneBackendInsight.tsx b/client/web/src/enterprise/insights/pages/insights/insight/components/standalone-backend-insight/StandaloneBackendInsight.tsx index 849788c8816..b842650ff5e 100644 --- a/client/web/src/enterprise/insights/pages/insights/insight/components/standalone-backend-insight/StandaloneBackendInsight.tsx +++ b/client/web/src/enterprise/insights/pages/insights/insight/components/standalone-backend-insight/StandaloneBackendInsight.tsx @@ -1,7 +1,7 @@ import React, { useContext, useState } from 'react' import classNames from 'classnames' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { useQuery } from '@sourcegraph/http-client' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' diff --git a/client/web/src/enterprise/insights/pages/landing/getting-started/components/code-insights-examples/CodeInsightsExamples.tsx b/client/web/src/enterprise/insights/pages/landing/getting-started/components/code-insights-examples/CodeInsightsExamples.tsx index 3e535f8e4ed..c93ed29638f 100644 --- a/client/web/src/enterprise/insights/pages/landing/getting-started/components/code-insights-examples/CodeInsightsExamples.tsx +++ b/client/web/src/enterprise/insights/pages/landing/getting-started/components/code-insights-examples/CodeInsightsExamples.tsx @@ -1,6 +1,6 @@ import { FunctionComponent } from 'react' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService' import { Link, H2, Text } from '@sourcegraph/wildcard' diff --git a/client/web/src/enterprise/routes.tsx b/client/web/src/enterprise/routes.tsx index c2d47ce8082..93226fb1e07 100644 --- a/client/web/src/enterprise/routes.tsx +++ b/client/web/src/enterprise/routes.tsx @@ -1,4 +1,4 @@ -import { Navigate } from 'react-router-dom-v5-compat' +import { Navigate } from 'react-router-dom' import { isErrorLike } from '@sourcegraph/common' import { SettingsCascadeOrError } from '@sourcegraph/shared/src/settings/settings' diff --git a/client/web/src/enterprise/searchContexts/CreateSearchContextPage.tsx b/client/web/src/enterprise/searchContexts/CreateSearchContextPage.tsx index 3db83722ce7..e38508dfb6b 100644 --- a/client/web/src/enterprise/searchContexts/CreateSearchContextPage.tsx +++ b/client/web/src/enterprise/searchContexts/CreateSearchContextPage.tsx @@ -1,7 +1,7 @@ import React, { useCallback } from 'react' import { mdiMagnify } from '@mdi/js' -import { Navigate, useLocation } from 'react-router-dom-v5-compat' +import { Navigate, useLocation } from 'react-router-dom' import { Observable } from 'rxjs' import { diff --git a/client/web/src/enterprise/searchContexts/DeleteSearchContextModal.tsx b/client/web/src/enterprise/searchContexts/DeleteSearchContextModal.tsx index 16900469921..ae2daa9d5bc 100644 --- a/client/web/src/enterprise/searchContexts/DeleteSearchContextModal.tsx +++ b/client/web/src/enterprise/searchContexts/DeleteSearchContextModal.tsx @@ -1,6 +1,6 @@ import React, { useCallback } from 'react' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { Observable } from 'rxjs' import { mergeMap, startWith, tap, catchError } from 'rxjs/operators' diff --git a/client/web/src/enterprise/searchContexts/EditSearchContextPage.tsx b/client/web/src/enterprise/searchContexts/EditSearchContextPage.tsx index c98ff71abd2..cf323db5c37 100644 --- a/client/web/src/enterprise/searchContexts/EditSearchContextPage.tsx +++ b/client/web/src/enterprise/searchContexts/EditSearchContextPage.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useMemo } from 'react' import { mdiMagnify } from '@mdi/js' -import { useParams } from 'react-router-dom-v5-compat' +import { useParams } from 'react-router-dom' import { Observable, of, throwError } from 'rxjs' import { catchError, startWith, switchMap } from 'rxjs/operators' diff --git a/client/web/src/enterprise/searchContexts/SearchContextForm.tsx b/client/web/src/enterprise/searchContexts/SearchContextForm.tsx index 8ff65334385..48ab5331a88 100644 --- a/client/web/src/enterprise/searchContexts/SearchContextForm.tsx +++ b/client/web/src/enterprise/searchContexts/SearchContextForm.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useMemo, useState } from 'react' import classNames from 'classnames' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { Observable, of, throwError } from 'rxjs' import { catchError, map, startWith, switchMap, tap } from 'rxjs/operators' diff --git a/client/web/src/enterprise/searchContexts/SearchContextPage.tsx b/client/web/src/enterprise/searchContexts/SearchContextPage.tsx index 58d8463ce74..ac1ffa067e9 100644 --- a/client/web/src/enterprise/searchContexts/SearchContextPage.tsx +++ b/client/web/src/enterprise/searchContexts/SearchContextPage.tsx @@ -3,7 +3,7 @@ import React, { useCallback, useMemo, useState } from 'react' import { mdiMagnify } from '@mdi/js' import classNames from 'classnames' import { debounce } from 'lodash' -import { useParams } from 'react-router-dom-v5-compat' +import { useParams } from 'react-router-dom' import { catchError, startWith } from 'rxjs/operators' import { SyntaxHighlightedSearchQuery } from '@sourcegraph/branded' diff --git a/client/web/src/enterprise/searchContexts/SearchContextsList.test.tsx b/client/web/src/enterprise/searchContexts/SearchContextsList.test.tsx index 371ab43a34f..7ece66b6139 100644 --- a/client/web/src/enterprise/searchContexts/SearchContextsList.test.tsx +++ b/client/web/src/enterprise/searchContexts/SearchContextsList.test.tsx @@ -1,7 +1,7 @@ import { MockedProvider, MockedResponse } from '@apollo/client/testing' import { getAllByRole, getByRole, queryByRole, render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { MemoryRouter } from 'react-router-dom-v5-compat' +import { MemoryRouter } from 'react-router-dom' import { spy, stub, assert } from 'sinon' import { getDocumentNode } from '@sourcegraph/http-client' diff --git a/client/web/src/enterprise/site-admin/SiteAdminLsifUploadPage.tsx b/client/web/src/enterprise/site-admin/SiteAdminLsifUploadPage.tsx index f891020150f..7dbfbbf4966 100644 --- a/client/web/src/enterprise/site-admin/SiteAdminLsifUploadPage.tsx +++ b/client/web/src/enterprise/site-admin/SiteAdminLsifUploadPage.tsx @@ -1,6 +1,6 @@ import { useEffect, useMemo } from 'react' -import { Navigate, useParams } from 'react-router-dom-v5-compat' +import { Navigate, useParams } from 'react-router-dom' import { catchError } from 'rxjs/operators' import { asError, ErrorLike, isErrorLike } from '@sourcegraph/common' diff --git a/client/web/src/enterprise/site-admin/dotcom/productSubscriptions/SiteAdminCreateProductSubscriptionPage.tsx b/client/web/src/enterprise/site-admin/dotcom/productSubscriptions/SiteAdminCreateProductSubscriptionPage.tsx index d8d23ee25f9..8472b36c5e7 100644 --- a/client/web/src/enterprise/site-admin/dotcom/productSubscriptions/SiteAdminCreateProductSubscriptionPage.tsx +++ b/client/web/src/enterprise/site-admin/dotcom/productSubscriptions/SiteAdminCreateProductSubscriptionPage.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useEffect } from 'react' import { mdiPlus } from '@mdi/js' -import { Navigate } from 'react-router-dom-v5-compat' +import { Navigate } from 'react-router-dom' import { merge, of, Observable } from 'rxjs' import { catchError, concatMapTo, map, tap } from 'rxjs/operators' diff --git a/client/web/src/enterprise/site-admin/dotcom/productSubscriptions/SiteAdminProductSubscriptionPage.tsx b/client/web/src/enterprise/site-admin/dotcom/productSubscriptions/SiteAdminProductSubscriptionPage.tsx index d8b0ba1fb36..8b53e42e57c 100644 --- a/client/web/src/enterprise/site-admin/dotcom/productSubscriptions/SiteAdminProductSubscriptionPage.tsx +++ b/client/web/src/enterprise/site-admin/dotcom/productSubscriptions/SiteAdminProductSubscriptionPage.tsx @@ -1,7 +1,7 @@ import React, { useState, useMemo, useEffect, useCallback } from 'react' import { mdiArrowLeft, mdiPlus } from '@mdi/js' -import { useNavigate, useParams } from 'react-router-dom-v5-compat' +import { useNavigate, useParams } from 'react-router-dom' import { Observable, Subject, NEVER } from 'rxjs' import { catchError, map, mapTo, startWith, switchMap, tap, filter } from 'rxjs/operators' diff --git a/client/web/src/enterprise/site-admin/routes.tsx b/client/web/src/enterprise/site-admin/routes.tsx index d7b3dcbac45..c07af526441 100644 --- a/client/web/src/enterprise/site-admin/routes.tsx +++ b/client/web/src/enterprise/site-admin/routes.tsx @@ -1,4 +1,4 @@ -import { Navigate, useLocation, useParams } from 'react-router-dom-v5-compat' +import { Navigate, useLocation, useParams } from 'react-router-dom' import { lazyComponent } from '@sourcegraph/shared/src/util/lazyComponent' diff --git a/client/web/src/enterprise/user/productSubscriptions/UserSubscriptionsProductSubscriptionPage.tsx b/client/web/src/enterprise/user/productSubscriptions/UserSubscriptionsProductSubscriptionPage.tsx index 3b36d358758..dc59005c2cd 100644 --- a/client/web/src/enterprise/user/productSubscriptions/UserSubscriptionsProductSubscriptionPage.tsx +++ b/client/web/src/enterprise/user/productSubscriptions/UserSubscriptionsProductSubscriptionPage.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useMemo } from 'react' import { parseISO } from 'date-fns' -import { useParams } from 'react-router-dom-v5-compat' +import { useParams } from 'react-router-dom' import { Observable } from 'rxjs' import { catchError, map, startWith } from 'rxjs/operators' import { validate as validateUUID } from 'uuid' diff --git a/client/web/src/extensions/components/ActionItemsBar.tsx b/client/web/src/extensions/components/ActionItemsBar.tsx index 9b466bfdceb..a8e4a1b82b5 100644 --- a/client/web/src/extensions/components/ActionItemsBar.tsx +++ b/client/web/src/extensions/components/ActionItemsBar.tsx @@ -4,7 +4,7 @@ import { mdiChevronDoubleDown, mdiChevronDoubleUp, mdiMenuDown, mdiMenuUp, mdiPu import VisuallyHidden from '@reach/visually-hidden' import classNames from 'classnames' import { head, last } from 'lodash' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { BehaviorSubject, from, of } from 'rxjs' import { distinctUntilChanged, map } from 'rxjs/operators' import { focusable, FocusableElement } from 'tabbable' diff --git a/client/web/src/hooks/useRoutesMatch.ts b/client/web/src/hooks/useRoutesMatch.ts index 7b6a4d4a2fe..7f0b76f06f5 100644 --- a/client/web/src/hooks/useRoutesMatch.ts +++ b/client/web/src/hooks/useRoutesMatch.ts @@ -1,4 +1,4 @@ -import { matchPath, useLocation } from 'react-router-dom-v5-compat' +import { matchPath, useLocation } from 'react-router-dom' import { LayoutRouteProps } from '../routes' diff --git a/client/web/src/hooks/useScrollManager/useScrollManager.test.tsx b/client/web/src/hooks/useScrollManager/useScrollManager.test.tsx index 475b728d0d8..90d9204ade5 100644 --- a/client/web/src/hooks/useScrollManager/useScrollManager.test.tsx +++ b/client/web/src/hooks/useScrollManager/useScrollManager.test.tsx @@ -1,7 +1,7 @@ import { useRef } from 'react' import { act, fireEvent, screen } from '@testing-library/react' -import { Route } from 'react-router' +import { Routes, Route } from 'react-router-dom' import { spy, assert } from 'sinon' import { renderWithBrandedContext } from '@sourcegraph/wildcard/src/testing' @@ -20,10 +20,10 @@ const TestPage = ({ id }: { id: string }) => { } const TestApp = () => ( -
- } /> - } /> -
+ + } /> + } /> + ) describe('useScrollManager', () => { @@ -44,7 +44,7 @@ describe('useScrollManager', () => { const wrapper = renderWithBrandedContext() act(() => { - wrapper.history.push('/page-1') + wrapper.navigateRef.current?.('/page-1') }) // Called when pushing history assert.callCount(scrollToMock, 1) @@ -57,7 +57,7 @@ describe('useScrollManager', () => { // Navigate to other page act(() => { - wrapper.history.push('/page-2') + wrapper.navigateRef.current?.('/page-2') }) // Called when pushing history assert.callCount(scrollToMock, 2) @@ -70,7 +70,7 @@ describe('useScrollManager', () => { // Navigate backwards to first page act(() => { - wrapper.history.goBack() + wrapper.navigateRef.current?.(-1) }) // Check that we attempt to scroll back to the correct position assert.callCount(scrollToMock, 3) @@ -78,7 +78,7 @@ describe('useScrollManager', () => { // Navigate forwards to second page act(() => { - wrapper.history.goForward() + wrapper.navigateRef.current?.(1) }) // Check that we attempt to scroll back to the correct position assert.callCount(scrollToMock, 4) @@ -86,7 +86,7 @@ describe('useScrollManager', () => { // Navigate directly to the first page act(() => { - wrapper.history.push('/page-1') + wrapper.navigateRef.current?.('/page-1') }) // Check that we attempted to scroll back to top on push assert.callCount(scrollToMock, 5) @@ -94,7 +94,7 @@ describe('useScrollManager', () => { // Replace history with second page act(() => { - wrapper.history.replace('/page-2') + wrapper.navigateRef.current?.('/page-2', { replace: true }) }) // Check that we did not attempt to scroll on history replace assert.callCount(scrollToMock, 5) diff --git a/client/web/src/hooks/useScrollManager/useScrollManager.ts b/client/web/src/hooks/useScrollManager/useScrollManager.ts index 0af2f638e55..28a59c42bba 100644 --- a/client/web/src/hooks/useScrollManager/useScrollManager.ts +++ b/client/web/src/hooks/useScrollManager/useScrollManager.ts @@ -1,7 +1,7 @@ import { useEffect } from 'react' import { debounce } from 'lodash' -import { useLocation, useNavigationType } from 'react-router-dom-v5-compat' +import { useLocation, useNavigationType } from 'react-router-dom' import { logger } from '@sourcegraph/common' diff --git a/client/web/src/hooks/useUrlSyncedState.test.ts b/client/web/src/hooks/useUrlSyncedState.test.ts index 6e908796fb7..3d53b876cae 100644 --- a/client/web/src/hooks/useUrlSyncedState.test.ts +++ b/client/web/src/hooks/useUrlSyncedState.test.ts @@ -1,5 +1,5 @@ import { renderHook, act } from '@testing-library/react' -import type { useNavigate } from 'react-router-dom-v5-compat' +import type { useNavigate } from 'react-router-dom' import sinon from 'sinon' import { useURLSyncedState } from './useUrlSyncedState' diff --git a/client/web/src/hooks/useUrlSyncedState.ts b/client/web/src/hooks/useUrlSyncedState.ts index c3e4686b9a7..2770a377e28 100644 --- a/client/web/src/hooks/useUrlSyncedState.ts +++ b/client/web/src/hooks/useUrlSyncedState.ts @@ -1,6 +1,6 @@ import { useState, useEffect } from 'react' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' /** * "useState" like hook that syncs state with URL search parameters. diff --git a/client/web/src/integration/search-aggregation.test.ts b/client/web/src/integration/search-aggregation.test.ts index ddba6e97d79..c02c78f0fb6 100644 --- a/client/web/src/integration/search-aggregation.test.ts +++ b/client/web/src/integration/search-aggregation.test.ts @@ -180,7 +180,10 @@ describe('Search aggregation', () => { latestSettings: { id: 0, contents: JSON.stringify({ - experimentalFeatures: { searchResultsAggregations: true }, + experimentalFeatures: { + searchResultsAggregations: true, + searchQueryInput: 'v1', + }, }), }, }, diff --git a/client/web/src/integration/search-contexts.test.ts b/client/web/src/integration/search-contexts.test.ts index d5cbab32791..fd8d4a35ad5 100644 --- a/client/web/src/integration/search-contexts.test.ts +++ b/client/web/src/integration/search-contexts.test.ts @@ -45,6 +45,7 @@ describe('Search contexts', () => { user: { experimentalFeatures: { showSearchContext: true, + searchQueryInput: 'v1', }, }, }), @@ -191,7 +192,7 @@ describe('Search contexts', () => { // Enter repositories const repositoriesConfig = - '[{ "repository": "github.com/example/example", "revisions": ["main", "pr/feature1"] }]' + '[{ "repository": "github.com/example/example", "revisions": ["main", "pr/feature1"] }]' { const editor = await createEditorAPI(driver, '[data-testid="repositories-config-area"] .test-editor') await editor.replace(repositoriesConfig, 'paste') @@ -372,8 +373,7 @@ describe('Search contexts', () => { }) // Enter repositories - const repositoriesConfig = - '[{ "repository": "github.com/example/example", "revisions": ["main", "pr/feature1"] }]' + const repositoriesConfig = '[{ "repository": "github.com/example/example", "revisions": ["main"] }]' const editor = await createEditorAPI(driver, '[data-testid="repositories-config-area"] .test-editor') await editor.replace(repositoriesConfig, 'paste') diff --git a/client/web/src/marketing/page/SurveyForm.tsx b/client/web/src/marketing/page/SurveyForm.tsx index 1832b68c5a1..1ee212b6440 100644 --- a/client/web/src/marketing/page/SurveyForm.tsx +++ b/client/web/src/marketing/page/SurveyForm.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react' -import { useNavigate } from 'react-router-dom-v5-compat' +import { useNavigate } from 'react-router-dom' import { useMutation, gql } from '@sourcegraph/http-client' import { Button, LoadingSpinner, Label, Text, Form } from '@sourcegraph/wildcard' diff --git a/client/web/src/marketing/page/SurveyPage.test.tsx b/client/web/src/marketing/page/SurveyPage.test.tsx index 772a7fe7f33..bf01e590976 100644 --- a/client/web/src/marketing/page/SurveyPage.test.tsx +++ b/client/web/src/marketing/page/SurveyPage.test.tsx @@ -1,7 +1,5 @@ import { MockedProviderProps } from '@apollo/client/testing' import { cleanup, fireEvent, within, waitFor } from '@testing-library/react' -import { createMemoryHistory } from 'history' -import { Route, Routes } from 'react-router-dom-v5-compat' import { MockedTestProvider } from '@sourcegraph/shared/src/testing/apollo' import { RenderWithBrandedContextResult, renderWithBrandedContext } from '@sourcegraph/wildcard/src/testing' @@ -25,19 +23,18 @@ describe('SurveyPage', () => { afterEach(cleanup) - const renderSurveyPage = ({ mocks, routerProps }: RenderSurveyPageParameters) => { - const history = createMemoryHistory() - history.push(`/survey/${routerProps?.matchParam || ''}`, routerProps?.locationState) - - return renderWithBrandedContext( + const renderSurveyPage = ({ mocks, routerProps }: RenderSurveyPageParameters) => renderWithBrandedContext( - - } /> - + , - { route: '/', history } + { + path: '/survey/:score?', + route: { + pathname: `/survey/${routerProps?.matchParam || ''}`, + state: routerProps?.locationState, + }, + } ) - } describe('Prior to submission', () => { beforeEach(() => { @@ -62,7 +59,7 @@ describe('SurveyPage', () => { fireEvent.click(renderResult.getByText('Submit')) - await waitFor(() => expect(renderResult.history.location.pathname).toBe('/survey/thanks')) + await waitFor(() => expect(renderResult.locationRef.current?.pathname).toBe('/survey/thanks')) }) }) diff --git a/client/web/src/marketing/page/SurveyPage.tsx b/client/web/src/marketing/page/SurveyPage.tsx index 666b43b4d5d..8925d025675 100644 --- a/client/web/src/marketing/page/SurveyPage.tsx +++ b/client/web/src/marketing/page/SurveyPage.tsx @@ -1,6 +1,6 @@ import React, { useEffect } from 'react' -import { useParams, useLocation } from 'react-router-dom-v5-compat' +import { useParams, useLocation } from 'react-router-dom' import { FeedbackText } from '@sourcegraph/wildcard' diff --git a/client/web/src/nav/GlobalNavbar.tsx b/client/web/src/nav/GlobalNavbar.tsx index d3cfc023d0a..47f305ec2dd 100644 --- a/client/web/src/nav/GlobalNavbar.tsx +++ b/client/web/src/nav/GlobalNavbar.tsx @@ -4,7 +4,7 @@ import classNames from 'classnames' import BarChartIcon from 'mdi-react/BarChartIcon' import BookOutlineIcon from 'mdi-react/BookOutlineIcon' import MagnifyIcon from 'mdi-react/MagnifyIcon' -import { useLocation } from 'react-router-dom-v5-compat' +import { useLocation } from 'react-router-dom' import { ContributableMenu } from '@sourcegraph/client-api' import { isErrorLike, isMacPlatform } from '@sourcegraph/common' diff --git a/client/web/src/nav/NavBar/NavBar.tsx b/client/web/src/nav/NavBar/NavBar.tsx index acffa50cfc3..01cc37af40a 100644 --- a/client/web/src/nav/NavBar/NavBar.tsx +++ b/client/web/src/nav/NavBar/NavBar.tsx @@ -2,8 +2,7 @@ import React, { useEffect, useRef, useState, forwardRef } from 'react' import { mdiChevronDown, mdiChevronUp, mdiMenu } from '@mdi/js' import classNames from 'classnames' -import H from 'history' -import { LinkProps, NavLink as RouterLink } from 'react-router-dom' +import { LinkProps, NavLink as RouterNavLink } from 'react-router-dom' import { Button, Link, Icon, H1, ForwardReferenceComponent } from '@sourcegraph/wildcard' @@ -33,7 +32,7 @@ interface NavActionsProps { className?: string } -export interface NavLinkProps extends NavItemProps, Pick, 'to'> { +export interface NavLinkProps extends NavItemProps, Pick { external?: boolean className?: string variant?: 'compact' @@ -63,9 +62,9 @@ export const NavBar = forwardRef( ({ children, logo }, reference): JSX.Element => (