From 06c0218c1b010209468fa001dc99dd4efa0a653a Mon Sep 17 00:00:00 2001
From: Kamil Mielnik <kamil@kamilmielnik.com>
Date: Tue, 2 Jul 2024 21:03:12 +0700
Subject: [PATCH] Fix - Invalid join clause does not disappear after changing
 query source to use a different database (#45025)

* Reset JoinDraft state on database change (fixes metabase#42385)

* Add repro for #42385

* Use admin user
---
 .../joins/joins-reproductions.cy.spec.js      | 30 +++++++++++++++++++
 .../steps/JoinStep/JoinDraft/JoinDraft.tsx    | 23 +++++++++++++-
 2 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/e2e/test/scenarios/joins/joins-reproductions.cy.spec.js b/e2e/test/scenarios/joins/joins-reproductions.cy.spec.js
index 3a43c455b05..b0dc320d653 100644
--- a/e2e/test/scenarios/joins/joins-reproductions.cy.spec.js
+++ b/e2e/test/scenarios/joins/joins-reproductions.cy.spec.js
@@ -1233,3 +1233,33 @@ describe.skip("issue 27521", () => {
     cy.findAllByTestId("header-cell").eq(index).should("have.text", name);
   }
 });
+
+describe("issue 42385", { tags: "@external" }, () => {
+  beforeEach(() => {
+    restore("postgres-12");
+    cy.signInAsAdmin();
+  });
+
+  it("should remove invalid draft join clause when query database changes (metabase#42385)", () => {
+    openOrdersTable({ mode: "notebook" });
+    join();
+    entityPickerModal().within(() => {
+      entityPickerModalTab("Tables").click();
+      cy.findByText("Reviews").click();
+    });
+
+    getNotebookStep("data").findByTestId("data-step-cell").click();
+    entityPickerModal().within(() => {
+      cy.findByText("QA Postgres12").click();
+      cy.findByText("Reviews").click();
+    });
+
+    getNotebookStep("join").within(() => {
+      cy.findByLabelText("Right table")
+        .findByText("Pick data…")
+        .should("be.visible");
+      cy.findByLabelText("Left column").should("not.exist");
+      cy.findByLabelText("Right column").should("not.exist");
+    });
+  });
+});
diff --git a/frontend/src/metabase/query_builder/components/notebook/steps/JoinStep/JoinDraft/JoinDraft.tsx b/frontend/src/metabase/query_builder/components/notebook/steps/JoinStep/JoinDraft/JoinDraft.tsx
index c06494cc870..d21f899a8c3 100644
--- a/frontend/src/metabase/query_builder/components/notebook/steps/JoinStep/JoinDraft/JoinDraft.tsx
+++ b/frontend/src/metabase/query_builder/components/notebook/steps/JoinStep/JoinDraft/JoinDraft.tsx
@@ -1,4 +1,5 @@
-import { useMemo, useState } from "react";
+import { useEffect, useMemo, useState } from "react";
+import { useLatest } from "react-use";
 import { t } from "ttag";
 
 import { Box, Flex, Text } from "metabase/ui";
@@ -32,6 +33,7 @@ export function JoinDraft({
   isReadOnly,
   onJoinChange,
 }: JoinDraftProps) {
+  const databaseId = Lib.databaseID(query);
   const [strategy, setStrategy] = useState(
     () => initialStrategy ?? getDefaultJoinStrategy(query, stageIndex),
   );
@@ -85,6 +87,25 @@ export function JoinDraft({
     }
   };
 
+  const resetStateRef = useLatest(() => {
+    const rhsTableColumns = initialRhsTable
+      ? Lib.joinableColumns(query, stageIndex, initialRhsTable)
+      : [];
+
+    setStrategy(initialStrategy ?? getDefaultJoinStrategy(query, stageIndex));
+    setRhsTable(initialRhsTable);
+    setRhsTableColumns(rhsTableColumns);
+    setSelectedRhsTableColumns(rhsTableColumns);
+    setLhsColumn(undefined);
+  });
+
+  useEffect(
+    function resetStateOnDatabaseChange() {
+      resetStateRef.current();
+    },
+    [databaseId, resetStateRef],
+  );
+
   return (
     <Flex miw="100%" gap="1rem">
       <JoinCell color={color}>
-- 
GitLab