Skip to content
Snippets Groups Projects
Unverified Commit 52b6a703 authored by Nick Fitzpatrick's avatar Nick Fitzpatrick Committed by GitHub
Browse files

use replace for programatic navigation in Table Metadata (#34756)

* use replace for programatic navigation

* adding comments
parent 8a4c335a
No related branches found
No related tags found
No related merge requests found
import { Route } from "react-router";
import { Link, Route } from "react-router";
import userEvent from "@testing-library/user-event";
import { within } from "@testing-library/react";
import type { Database } from "metabase-types/api";
......@@ -109,18 +109,36 @@ const JSON_DB = createMockDatabase({
interface SetupOpts {
databases?: Database[];
initialRoute?: string;
}
const setup = async ({ databases = [SAMPLE_DB] }: SetupOpts = {}) => {
const setup = async ({
databases = [SAMPLE_DB],
initialRoute = "admin/datamodel",
}: SetupOpts = {}) => {
setupDatabasesEndpoints(databases);
setupSearchEndpoints([]);
renderWithProviders(
<Route path="admin/datamodel">{getMetadataRoutes()}</Route>,
{ withRouter: true, initialRoute: "admin/datamodel" },
const OtherComponent = () => {
return (
<>
<span>Another route</span>
<Link to="admin/datamodel">Link to Datamodel</Link>
</>
);
};
const { history } = renderWithProviders(
<>
<Route path="notAdmin" component={OtherComponent} />
<Route path="admin/datamodel">{getMetadataRoutes()}</Route>
</>,
{ withRouter: true, initialRoute },
);
await waitForLoaderToBeRemoved();
return { history };
};
describe("MetadataEditor", () => {
......@@ -475,4 +493,20 @@ describe("MetadataEditor", () => {
expect(within(section).getByText("JSON.version")).toBeInTheDocument();
});
});
describe("navigation", () => {
it("should replace locations in history stack when being routed automatically", async () => {
const { history } = await setup({ initialRoute: "notAdmin" });
expect(screen.getByText("Link to Datamodel")).toBeInTheDocument();
userEvent.click(screen.getByText("Link to Datamodel"));
await waitForLoaderToBeRemoved();
expect(screen.getByText("Sample Database")).toBeInTheDocument();
history?.goBack();
expect(screen.getByText("Link to Datamodel")).toBeInTheDocument();
});
});
});
import { useLayoutEffect } from "react";
import { connect } from "react-redux";
import { push } from "react-router-redux";
import { push, replace } from "react-router-redux";
import { t } from "ttag";
import _ from "underscore";
import { PLUGIN_FEATURE_LEVEL_PERMISSIONS } from "metabase/plugins";
......@@ -24,12 +24,20 @@ interface DatabaseLoaderProps {
}
interface DispatchProps {
onSelectDatabase: (databaseId: DatabaseId) => void;
onSelectDatabase: (
databaseId: DatabaseId,
options: { useReplace?: boolean },
) => void;
}
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => ({
onSelectDatabase: databaseId =>
dispatch(push(Urls.dataModelDatabase(databaseId))),
// When navigating programatically, use replace so that the browser back button works
onSelectDatabase: (databaseId, { useReplace = false } = {}) =>
dispatch(
useReplace
? replace(Urls.dataModelDatabase(databaseId))
: push(Urls.dataModelDatabase(databaseId)),
),
});
type MetadataHeaderProps = OwnProps & DatabaseLoaderProps & DispatchProps;
......@@ -43,7 +51,7 @@ const MetadataHeader = ({
}: MetadataHeaderProps) => {
useLayoutEffect(() => {
if (databases.length > 0 && selectedDatabaseId == null) {
onSelectDatabase(databases[0].id);
onSelectDatabase(databases[0].id, { useReplace: true });
}
}, [databases, selectedDatabaseId, onSelectDatabase]);
......
import { useCallback, useLayoutEffect, useMemo, useState } from "react";
import { connect } from "react-redux";
import { push } from "react-router-redux";
import { push, replace } from "react-router-redux";
import cx from "classnames";
import { msgid, ngettext, t } from "ttag";
import _ from "underscore";
......@@ -22,14 +22,24 @@ interface SchemaLoaderProps {
}
interface DispatchProps {
onSelectSchema: (databaseId: DatabaseId, schemaId: SchemaId) => void;
onSelectSchema: (
databaseId: DatabaseId,
schemaId: SchemaId,
options?: { useReplace?: boolean },
) => void;
}
type MetadataSchemaListProps = OwnProps & SchemaLoaderProps & DispatchProps;
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => ({
onSelectSchema: (databaseId, schemaId) =>
dispatch(push(Urls.dataModelSchema(databaseId, schemaId))),
// When navigating programatically, use replace so that the browser back button works
onSelectSchema: (databaseId, schemaId, { useReplace = false } = {}) => {
dispatch(
useReplace
? replace(Urls.dataModelSchema(databaseId, schemaId))
: push(Urls.dataModelSchema(databaseId, schemaId)),
);
},
});
const MetadataSchemaList = ({
......@@ -58,7 +68,9 @@ const MetadataSchemaList = ({
useLayoutEffect(() => {
if (allSchemas.length === 1 && selectedSchemaId == null) {
onSelectSchema(selectedDatabaseId, allSchemas[0].id);
onSelectSchema(selectedDatabaseId, allSchemas[0].id, {
useReplace: true,
});
}
}, [selectedDatabaseId, selectedSchemaId, allSchemas, onSelectSchema]);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment