Skip to content
Snippets Groups Projects
Unverified Commit 6deb7b70 authored by Alexander Polyankin's avatar Alexander Polyankin Committed by GitHub
Browse files

Reset join condition state when the rhs table changes (#48951)

parent 80af6c86
No related branches found
No related tags found
No related merge requests found
...@@ -5,6 +5,7 @@ import { ...@@ -5,6 +5,7 @@ import {
assertQueryBuilderRowCount, assertQueryBuilderRowCount,
cartesianChartCircle, cartesianChartCircle,
chartPathWithFillColor, chartPathWithFillColor,
createQuestion,
dashboardGrid, dashboardGrid,
echartsContainer, echartsContainer,
enterCustomColumnDetails, enterCustomColumnDetails,
...@@ -27,6 +28,7 @@ import { ...@@ -27,6 +28,7 @@ import {
selectSavedQuestionsToJoin, selectSavedQuestionsToJoin,
startNewQuestion, startNewQuestion,
summarize, summarize,
tableInteractive,
visitDashboard, visitDashboard,
visitQuestionAdhoc, visitQuestionAdhoc,
visualize, visualize,
...@@ -1361,3 +1363,78 @@ describe("issue 45300", () => { ...@@ -1361,3 +1363,78 @@ describe("issue 45300", () => {
); );
}); });
}); });
describe("issue 46675", () => {
const questionDetails = {
query: {
"source-table": ORDERS_ID,
},
};
beforeEach(() => {
restore();
cy.signInAsNormalUser();
cy.log("create draft state with a rhs table and a lhs column");
createQuestion(questionDetails, { visitQuestion: true });
openNotebook();
getNotebookStep("data").findByLabelText("Join data").click();
entityPickerModal().within(() => {
entityPickerModalTab("Tables").click();
cy.findByText("Reviews").click();
});
popover().findByText("ID").click();
});
it("should reset the draft join state when the source table changes (metabase#46675)", () => {
cy.log("change the source table and verify that the state was reset");
getNotebookStep("data").findByText("Orders").click();
entityPickerModal().within(() => {
entityPickerModalTab("Tables").click();
cy.findByText("Products").click();
});
getNotebookStep("join").within(() => {
cy.findByLabelText("Left table").should("have.text", "Products");
cy.findByLabelText("Right table").should("have.text", "Pick data…");
cy.findByLabelText("Left column").should("not.exist");
});
cy.log("complete the join and make sure the query can be executed");
getNotebookStep("join")
.findByLabelText("Right table")
.findByText("Pick data…")
.click();
entityPickerModal().within(() => {
entityPickerModalTab("Tables").click();
cy.findByText("Orders").click();
});
visualize();
tableInteractive().should("be.visible");
});
it("should reset the draft join state when the source table changes (metabase#46675)", () => {
cy.log("change the rhs table and verify that the state was reset");
getNotebookStep("join")
.findByLabelText("Right table")
.findByText("Reviews")
.click();
entityPickerModal().within(() => {
entityPickerModalTab("Tables").click();
cy.findByText("Orders").click();
});
getNotebookStep("join").within(() => {
cy.findByLabelText("Left table").should("have.text", "Orders");
cy.findByLabelText("Right table").should("have.text", "Orders");
cy.findByLabelText("Left column").should(
"contain.text",
"Pick a column…",
);
});
cy.log("complete the join and make sure the query can be executed");
popover().findByText("ID").click();
popover().findByText("ID").click();
visualize();
tableInteractive().should("be.visible");
});
});
...@@ -69,6 +69,7 @@ export function JoinComplete({ ...@@ -69,6 +69,7 @@ export function JoinComplete({
} else { } else {
onDraftRhsTableChange(newTable); onDraftRhsTableChange(newTable);
} }
setIsAddingNewCondition(false);
}; };
const handleAddCondition = (newCondition: Lib.JoinCondition) => { const handleAddCondition = (newCondition: Lib.JoinCondition) => {
......
import { useState } from "react"; import { useLayoutEffect, useState } from "react";
import { Box, Flex } from "metabase/ui"; import { Box, Flex } from "metabase/ui";
import * as Lib from "metabase-lib"; import * as Lib from "metabase-lib";
...@@ -16,6 +16,7 @@ interface JoinConditionDraftProps { ...@@ -16,6 +16,7 @@ interface JoinConditionDraftProps {
stageIndex: number; stageIndex: number;
joinable: Lib.JoinOrJoinable; joinable: Lib.JoinOrJoinable;
lhsTableName: string; lhsTableName: string;
rhsTable?: Lib.Joinable;
rhsTableName: string | undefined; rhsTableName: string | undefined;
isReadOnly: boolean; isReadOnly: boolean;
isRemovable: boolean; isRemovable: boolean;
...@@ -29,6 +30,7 @@ export function JoinConditionDraft({ ...@@ -29,6 +30,7 @@ export function JoinConditionDraft({
stageIndex, stageIndex,
joinable, joinable,
lhsTableName, lhsTableName,
rhsTable,
rhsTableName, rhsTableName,
isReadOnly, isReadOnly,
isRemovable, isRemovable,
...@@ -77,6 +79,13 @@ export function JoinConditionDraft({ ...@@ -77,6 +79,13 @@ export function JoinConditionDraft({
handleColumnChange(lhsColumn, newRhsColumn); handleColumnChange(lhsColumn, newRhsColumn);
}; };
useLayoutEffect(() => {
setLhsColumn(undefined);
setRhsColumn(undefined);
setIsLhsOpened(true);
setIsRhsOpened(false);
}, [rhsTable]);
return ( return (
<JoinConditionRoot> <JoinConditionRoot>
<Flex align="center" gap="xs" mih="47px" p="xs"> <Flex align="center" gap="xs" mih="47px" p="xs">
......
import { useEffect, useMemo, useState } from "react"; import { useLayoutEffect, useMemo, useState } from "react";
import { useLatest } from "react-use"; import { useLatest } from "react-use";
import { t } from "ttag"; import { t } from "ttag";
...@@ -33,7 +33,7 @@ export function JoinDraft({ ...@@ -33,7 +33,7 @@ export function JoinDraft({
isReadOnly, isReadOnly,
onJoinChange, onJoinChange,
}: JoinDraftProps) { }: JoinDraftProps) {
const databaseId = Lib.databaseID(query); const sourceTableId = Lib.sourceTableOrCardId(query);
const [strategy, setStrategy] = useState( const [strategy, setStrategy] = useState(
() => initialStrategy ?? getDefaultJoinStrategy(query, stageIndex), () => initialStrategy ?? getDefaultJoinStrategy(query, stageIndex),
); );
...@@ -87,23 +87,21 @@ export function JoinDraft({ ...@@ -87,23 +87,21 @@ export function JoinDraft({
} }
}; };
const resetStateRef = useLatest(() => { const handleReset = () => {
const rhsTableColumns = initialRhsTable const rhsTableColumns = initialRhsTable
? Lib.joinableColumns(query, stageIndex, initialRhsTable) ? Lib.joinableColumns(query, stageIndex, initialRhsTable)
: []; : [];
setStrategy(initialStrategy ?? getDefaultJoinStrategy(query, stageIndex)); setStrategy(initialStrategy ?? getDefaultJoinStrategy(query, stageIndex));
setRhsTable(initialRhsTable); setRhsTable(initialRhsTable);
setRhsTableColumns(rhsTableColumns); setRhsTableColumns(rhsTableColumns);
setSelectedRhsTableColumns(rhsTableColumns); setSelectedRhsTableColumns(rhsTableColumns);
setLhsColumn(undefined); setLhsColumn(undefined);
}); };
useEffect( const handleResetRef = useLatest(handleReset);
function resetStateOnDatabaseChange() { useLayoutEffect(
resetStateRef.current(); () => handleResetRef.current(),
}, [sourceTableId, handleResetRef],
[databaseId, resetStateRef],
); );
return ( return (
...@@ -150,6 +148,7 @@ export function JoinDraft({ ...@@ -150,6 +148,7 @@ export function JoinDraft({
stageIndex={stageIndex} stageIndex={stageIndex}
joinable={rhsTable} joinable={rhsTable}
lhsTableName={lhsTableName} lhsTableName={lhsTableName}
rhsTable={rhsTable}
rhsTableName={rhsTableName} rhsTableName={rhsTableName}
isReadOnly={isReadOnly} isReadOnly={isReadOnly}
isRemovable={false} isRemovable={false}
......
...@@ -559,6 +559,28 @@ describe("Notebook Editor > Join Step", () => { ...@@ -559,6 +559,28 @@ describe("Notebook Editor > Join Step", () => {
expect(condition.operator.shortName).toBe("!="); expect(condition.operator.shortName).toBe("!=");
}); });
it("should reset the draft join condition state when the rhs table is changed", async () => {
setup();
const rhsTablePicker = screen.getByLabelText("Right table");
await userEvent.click(within(rhsTablePicker).getByRole("button"));
const entityPickerModal = await screen.findByTestId("entity-picker-modal");
await waitForLoaderToBeRemoved();
await userEvent.click(within(entityPickerModal).getByText("Reviews"));
const lhsColumnPicker = await screen.findByTestId("lhs-column-picker");
await userEvent.click(within(lhsColumnPicker).getByText("ID"));
const newRhsTablePicker = screen.getByLabelText("Right table");
await userEvent.click(within(newRhsTablePicker).getByText("Reviews"));
const newEntityPickerModal = await screen.findByTestId(
"entity-picker-modal",
);
await waitForLoaderToBeRemoved();
await userEvent.click(within(newEntityPickerModal).getByText("Orders"));
const lhsColumn = screen.getByLabelText("Left column");
expect(within(lhsColumn).getByText("Pick a column…")).toBeInTheDocument();
expect(within(lhsColumn).queryByText("ID")).not.toBeInTheDocument();
});
describe("join strategies", () => { describe("join strategies", () => {
it("should be able to change the join strategy for a new join clause", async () => { it("should be able to change the join strategy for a new join clause", async () => {
const { getRecentJoin } = setup(); const { getRecentJoin } = setup();
......
import { useCallback, useMemo, useState } from "react"; import { useCallback, useMemo, useState } from "react";
import { useSelector } from "metabase/lib/redux";
import { getQuestionSteps } from "metabase/querying/notebook/utils/steps"; import { getQuestionSteps } from "metabase/querying/notebook/utils/steps";
import { getMetadata } from "metabase/selectors/metadata";
import type { Query } from "metabase-lib"; import type { Query } from "metabase-lib";
import * as Lib from "metabase-lib"; import * as Lib from "metabase-lib";
import type Question from "metabase-lib/v1/Question"; import type Question from "metabase-lib/v1/Question";
...@@ -39,7 +37,7 @@ export function NotebookStepList({ ...@@ -39,7 +37,7 @@ export function NotebookStepList({
updateQuestion, updateQuestion,
readOnly = false, readOnly = false,
}: NotebookStepListProps) { }: NotebookStepListProps) {
const metadata = useSelector(getMetadata); const metadata = question.metadata();
const [openSteps, setOpenSteps] = useState<OpenSteps>( const [openSteps, setOpenSteps] = useState<OpenSteps>(
getInitialOpenSteps(question, readOnly), getInitialOpenSteps(question, readOnly),
); );
......
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