From 16181dce67277b694e605fc2c0cc0fc2a2be8725 Mon Sep 17 00:00:00 2001
From: Alexander Polyankin <alexander.polyankin@metabase.com>
Date: Thu, 24 Oct 2024 10:51:51 -0400
Subject: [PATCH] Make it possible to remove a broken target when there are no
 options available (#49041)

---
 ...dashboard-filters-reproductions.cy.spec.js | 89 +++++++++++++++++++
 .../DashCardCardParameterMapperButton.tsx     | 32 +++----
 2 files changed, 105 insertions(+), 16 deletions(-)

diff --git a/e2e/test/scenarios/filters-reproductions/dashboard-filters-reproductions.cy.spec.js b/e2e/test/scenarios/filters-reproductions/dashboard-filters-reproductions.cy.spec.js
index 38ae40f1e8a..b8bb0fcab33 100644
--- a/e2e/test/scenarios/filters-reproductions/dashboard-filters-reproductions.cy.spec.js
+++ b/e2e/test/scenarios/filters-reproductions/dashboard-filters-reproductions.cy.spec.js
@@ -14,6 +14,7 @@ import {
   changeSynchronousBatchUpdateSetting,
   commandPalette,
   commandPaletteSearch,
+  createDashboard,
   createDashboardWithTabs,
   createNativeQuestion,
   createQuestion,
@@ -3806,3 +3807,91 @@ describe("issue 35852", () => {
     });
   }
 });
+
+describe("issue 32573", () => {
+  const modelDetails = {
+    name: "M1",
+    type: "model",
+    query: {
+      "source-table": ORDERS_ID,
+      fields: [["field", ORDERS.TAX, null]],
+    },
+  };
+
+  const parameterDetails = {
+    id: "92eb69ea",
+    name: "ID",
+    sectionId: "id",
+    slug: "id",
+    type: "id",
+    default: 1,
+  };
+
+  const dashboardDetails = {
+    parameters: [parameterDetails],
+  };
+
+  function getQuestionDetails(modelId) {
+    return {
+      name: "Q1",
+      type: "question",
+      query: {
+        "source-table": `card__${modelId}`,
+      },
+    };
+  }
+
+  function getParameterMapping(questionId) {
+    return {
+      card_id: questionId,
+      parameter_id: parameterDetails.id,
+      target: [
+        "dimension",
+        ["field", "ID", { "base-type": "type/BigInteger" }],
+      ],
+    };
+  }
+
+  beforeEach(() => {
+    restore();
+    cy.signInAsNormalUser();
+  });
+
+  it("should not crash a dashboard when there is a missing parameter column (metabase#32573)", () => {
+    createQuestion(modelDetails).then(({ body: model }) => {
+      createQuestion(getQuestionDetails(model.id)).then(
+        ({ body: question }) => {
+          createDashboard(dashboardDetails).then(({ body: dashboard }) => {
+            return cy
+              .request("PUT", `/api/dashboard/${dashboard.id}`, {
+                dashcards: [
+                  createMockDashboardCard({
+                    card_id: question.id,
+                    parameter_mappings: [getParameterMapping(question.id)],
+                    size_x: 6,
+                    size_y: 6,
+                  }),
+                ],
+              })
+              .then(() => visitDashboard(dashboard.id));
+          });
+        },
+      );
+    });
+    getDashboardCard()
+      .findByText("There was a problem displaying this chart.")
+      .should("be.visible");
+
+    editDashboard();
+    cy.findByTestId("fixed-width-filters").findByText("ID").click();
+    getDashboardCard().within(() => {
+      cy.findByText("Unknown Field").should("be.visible");
+      cy.findByLabelText("Disconnect").click();
+    });
+    saveDashboard();
+    getDashboardCard().within(() => {
+      cy.findByText("Q1").should("be.visible");
+      cy.findByText("Tax").should("be.visible");
+    });
+  });
+});
diff --git a/frontend/src/metabase/dashboard/components/DashCard/DashCardParameterMapper/DashCardCardParameterMapperButton.tsx b/frontend/src/metabase/dashboard/components/DashCard/DashCardParameterMapper/DashCardCardParameterMapperButton.tsx
index d3cdd56f022..5926fd10e64 100644
--- a/frontend/src/metabase/dashboard/components/DashCard/DashCardParameterMapper/DashCardCardParameterMapperButton.tsx
+++ b/frontend/src/metabase/dashboard/components/DashCard/DashCardParameterMapper/DashCardCardParameterMapperButton.tsx
@@ -71,6 +71,22 @@ export const DashCardCardParameterMapperButton = ({
         };
       }
 
+      if (target != null && !selectedMappingOption) {
+        return {
+          buttonVariant: "invalid",
+          buttonText: t`Unknown Field`,
+          buttonIcon: (
+            <CloseIconButton
+              aria-label={t`Disconnect`}
+              onClick={e => {
+                handleChangeTarget(null);
+                e.stopPropagation();
+              }}
+            />
+          ),
+        };
+      }
+
       if (isDisabled && !isVirtual) {
         return {
           buttonVariant: "disabled",
@@ -98,22 +114,6 @@ export const DashCardCardParameterMapperButton = ({
         };
       }
 
-      if (target != null) {
-        return {
-          buttonVariant: "invalid",
-          buttonText: t`Unknown Field`,
-          buttonIcon: (
-            <CloseIconButton
-              aria-label={t`Disconnect`}
-              onClick={e => {
-                handleChangeTarget(null);
-                e.stopPropagation();
-              }}
-            />
-          ),
-        };
-      }
-
       return {
         buttonVariant: "default",
         buttonTooltip: null,
-- 
GitLab