From 7d4bfaaee6e05831615a2cd432d900b7b90597ec Mon Sep 17 00:00:00 2001
From: Oisin Coveney <oisin@metabase.com>
Date: Mon, 28 Oct 2024 15:34:03 +0200
Subject: [PATCH] Convert ChartSettingsButton to mantine (#49171)

---
 .../ChartSettingsButton.tsx                   | 64 +++++++++-------
 .../ChartSettingsButton.unit.spec.tsx         | 75 +++++++++++++++++++
 .../ChartSettingsButton/index.ts              |  1 +
 .../DashCardActionButton/index.ts             |  1 +
 4 files changed, 116 insertions(+), 25 deletions(-)
 create mode 100644 frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ChartSettingsButton/ChartSettingsButton.unit.spec.tsx
 create mode 100644 frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ChartSettingsButton/index.ts
 create mode 100644 frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/DashCardActionButton/index.ts

diff --git a/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ChartSettingsButton/ChartSettingsButton.tsx b/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ChartSettingsButton/ChartSettingsButton.tsx
index 9a597c51473..a6e1b047476 100644
--- a/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ChartSettingsButton/ChartSettingsButton.tsx
+++ b/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ChartSettingsButton/ChartSettingsButton.tsx
@@ -1,7 +1,9 @@
+import { useDisclosure } from "@mantine/hooks";
 import { t } from "ttag";
 
-import ModalWithTrigger from "metabase/components/ModalWithTrigger";
+import { DEFAULT_Z_INDEX } from "metabase/components/Popover/constants";
 import CS from "metabase/css/core/index.css";
+import { Modal } from "metabase/ui";
 import { ChartSettingsWithState } from "metabase/visualizations/components/ChartSettings";
 import type {
   Dashboard,
@@ -10,7 +12,7 @@ import type {
   VisualizationSettings,
 } from "metabase-types/api";
 
-import { DashCardActionButton } from "../DashCardActionButton/DashCardActionButton";
+import { DashCardActionButton } from "../DashCardActionButton";
 
 interface Props {
   series: Series;
@@ -25,29 +27,41 @@ export function ChartSettingsButton({
   dashcard,
   onReplaceAllVisualizationSettings,
 }: Props) {
+  const [isOpened, { open, close }] = useDisclosure(false);
+
   return (
-    <ModalWithTrigger
-      wide
-      tall
-      triggerElement={
-        <DashCardActionButton
-          as="div"
-          tooltip={t`Visualization options`}
-          aria-label={t`Show visualization options`}
-        >
-          <DashCardActionButton.Icon name="palette" />
-        </DashCardActionButton>
-      }
-      enableMouseEvents
-    >
-      <ChartSettingsWithState
-        className={CS.spread}
-        series={series}
-        onChange={onReplaceAllVisualizationSettings}
-        isDashboard
-        dashboard={dashboard}
-        dashcard={dashcard}
-      />
-    </ModalWithTrigger>
+    <>
+      <DashCardActionButton
+        as="div"
+        tooltip={t`Visualization options`}
+        aria-label={t`Show visualization options`}
+        onClick={open}
+      >
+        <DashCardActionButton.Icon name="palette" />
+      </DashCardActionButton>
+
+      {/* zIndex is a hack for now until the inner popovers are converted to mantine */}
+      <Modal.Root
+        opened={isOpened}
+        onClose={close}
+        size="85%"
+        zIndex={DEFAULT_Z_INDEX - 1}
+      >
+        <Modal.Overlay />
+        <Modal.Content mih="85%">
+          <Modal.Body>
+            <ChartSettingsWithState
+              className={CS.spread}
+              series={series}
+              onChange={onReplaceAllVisualizationSettings}
+              isDashboard
+              dashboard={dashboard}
+              dashcard={dashcard}
+              onClose={close}
+            />
+          </Modal.Body>
+        </Modal.Content>
+      </Modal.Root>
+    </>
   );
 }
diff --git a/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ChartSettingsButton/ChartSettingsButton.unit.spec.tsx b/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ChartSettingsButton/ChartSettingsButton.unit.spec.tsx
new file mode 100644
index 00000000000..977e5ecca8b
--- /dev/null
+++ b/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ChartSettingsButton/ChartSettingsButton.unit.spec.tsx
@@ -0,0 +1,75 @@
+import userEvent from "@testing-library/user-event";
+
+import { setupDatabaseEndpoints } from "__support__/server-mocks";
+import { renderWithProviders, screen } from "__support__/ui";
+import { ChartSettingsButton } from "metabase/dashboard/components/DashCard/DashCardActionsPanel/ChartSettingsButton/ChartSettingsButton";
+import registerVisualizations from "metabase/visualizations/register";
+import {
+  createMockColumn,
+  createMockDashboard,
+  createMockDatabase,
+  createMockSingleSeries,
+} from "metabase-types/api/mocks";
+
+registerVisualizations();
+
+const rows = [["John", "John Smith Jr"]];
+const MOCK_SERIES = [
+  createMockSingleSeries(
+    { display: "line" },
+    {
+      data: {
+        rows,
+        cols: [
+          createMockColumn({
+            base_type: "string",
+            name: "Short name",
+            display_name: "Short name",
+          }),
+          createMockColumn({
+            base_type: "string",
+            name: "Long name",
+            display_name: "Long name",
+            visibility_type: "normal",
+          }),
+        ],
+      },
+    },
+  ),
+];
+
+const MOCK_DASHBOARD = createMockDashboard();
+const MOCK_DATABASE = createMockDatabase();
+
+const setup = () => {
+  const onReplaceAllVisualizationSettings = jest.fn();
+
+  setupDatabaseEndpoints(MOCK_DATABASE);
+
+  renderWithProviders(
+    <ChartSettingsButton
+      series={MOCK_SERIES}
+      dashboard={MOCK_DASHBOARD}
+      onReplaceAllVisualizationSettings={onReplaceAllVisualizationSettings}
+    />,
+  );
+};
+
+describe("ChartSettingsButton", () => {
+  it("should render the button", () => {
+    setup();
+    expect(screen.getByLabelText("palette icon")).toBeInTheDocument();
+  });
+
+  it("should render the settings and visualization modal when the button is clicked", async () => {
+    setup();
+    await userEvent.click(screen.getByLabelText("palette icon"));
+
+    expect(screen.getByTestId("chartsettings-sidebar")).toBeInTheDocument();
+    expect(screen.getByTestId("visualization-root")).toBeInTheDocument();
+
+    await userEvent.click(screen.getByText("Linear Interpolated"));
+
+    expect(screen.getByTestId("popover")).toBeInTheDocument();
+  });
+});
diff --git a/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ChartSettingsButton/index.ts b/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ChartSettingsButton/index.ts
new file mode 100644
index 00000000000..13d49d00a8d
--- /dev/null
+++ b/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ChartSettingsButton/index.ts
@@ -0,0 +1 @@
+export * from "./ChartSettingsButton";
diff --git a/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/DashCardActionButton/index.ts b/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/DashCardActionButton/index.ts
new file mode 100644
index 00000000000..d461a421f8f
--- /dev/null
+++ b/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/DashCardActionButton/index.ts
@@ -0,0 +1 @@
+export * from "./DashCardActionButton";
-- 
GitLab