diff --git a/e2e/support/commands/api/dashboard.js b/e2e/support/commands/api/dashboard.js
index edd17aa899bfd43471320677ea2259fbf93553f2..8cc6fe6b70d0077d584afd3a2d254edbc7f73f56 100644
--- a/e2e/support/commands/api/dashboard.js
+++ b/e2e/support/commands/api/dashboard.js
@@ -3,9 +3,10 @@ Cypress.Commands.add(
   (
     {
       name = "Test Dashboard",
+      auto_apply_filters,
       enable_embedding,
       embedding_params,
-      auto_apply_filters,
+      dashcards,
       ...dashboardDetails
     } = {},
     { wrapId = false, idAlias = "dashboardId" } = {},
@@ -18,11 +19,16 @@ Cypress.Commands.add(
         if (wrapId) {
           cy.wrap(body.id).as(idAlias);
         }
-        if (enable_embedding != null || auto_apply_filters != null) {
+        if (
+          enable_embedding != null ||
+          auto_apply_filters != null ||
+          Array.isArray(dashcards)
+        ) {
           cy.request("PUT", `/api/dashboard/${body.id}`, {
+            auto_apply_filters,
             enable_embedding,
             embedding_params,
-            auto_apply_filters,
+            dashcards,
           });
         }
       },
diff --git a/e2e/test/scenarios/dashboard-cards/click-behavior.cy.spec.js b/e2e/test/scenarios/dashboard-cards/click-behavior.cy.spec.js
index b630a6059c5f5d6005715ef7c50f5938165f9bc4..ba99cc7035a46ec85084daec2009c285dc4b02c7 100644
--- a/e2e/test/scenarios/dashboard-cards/click-behavior.cy.spec.js
+++ b/e2e/test/scenarios/dashboard-cards/click-behavior.cy.spec.js
@@ -1,5 +1,6 @@
 import { USER_GROUPS } from "e2e/support/cypress_data";
 import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
+import { ORDERS_QUESTION_ID } from "e2e/support/cypress_sample_instance_data";
 import {
   addOrUpdateDashboardCard,
   dashboardHeader,
@@ -19,7 +20,10 @@ import {
   visitEmbeddedPage,
 } from "e2e/support/helpers";
 
-import { createMockActionParameter } from "metabase-types/api/mocks";
+import {
+  createMockActionParameter,
+  createMockDashboardCard,
+} from "metabase-types/api/mocks";
 import { b64hash_to_utf8 } from "metabase/lib/encoding";
 
 const COUNT_COLUMN_ID = "count";
@@ -52,7 +56,7 @@ const FIRST_TAB = { id: 900, name: "first" };
 const SECOND_TAB = { id: 901, name: "second" };
 const THIRD_TAB = { id: 902, name: "third" };
 
-const { ORDERS_ID, ORDERS } = SAMPLE_DATABASE;
+const { ORDERS_ID, ORDERS, PEOPLE } = SAMPLE_DATABASE;
 
 const TARGET_DASHBOARD = {
   name: "Target dashboard",
@@ -109,6 +113,14 @@ const DASHBOARD_FILTER_TIME = createMockActionParameter({
   sectionId: "date",
 });
 
+const DASHBOARD_FILTER_NUMBER = createMockActionParameter({
+  id: "3",
+  name: "Number filter",
+  slug: "filter-number",
+  type: "number/>=",
+  sectionId: "number",
+});
+
 const QUERY_FILTER_CREATED_AT = [
   "between",
   [
@@ -263,7 +275,19 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
           wrapId: true,
           idAlias: "targetDashboardId",
         },
-      );
+      ).then(dashboardId => {
+        cy.request("PUT", `/api/dashboard/${dashboardId}`, {
+          dashcards: [
+            createMockDashboardCard({
+              card_id: ORDERS_QUESTION_ID,
+              parameter_mappings: [
+                createTextFilterMapping({ card_id: ORDERS_QUESTION_ID }),
+              ],
+            }),
+          ],
+        });
+      });
+
       cy.createQuestionAndDashboard({ questionDetails }).then(
         ({ body: card }) => {
           visitDashboard(card.dashboard_id);
@@ -305,7 +329,20 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
           wrapId: true,
           idAlias: "targetDashboardId",
         },
-      );
+      ).then(dashboardId => {
+        cy.request("PUT", `/api/dashboard/${dashboardId}`, {
+          dashcards: [
+            createMockDashboardCard({
+              card_id: ORDERS_QUESTION_ID,
+              parameter_mappings: [
+                createTextFilterMapping({ card_id: ORDERS_QUESTION_ID }),
+                createTimeFilterMapping({ card_id: ORDERS_QUESTION_ID }),
+              ],
+            }),
+          ],
+        });
+      });
+
       cy.createQuestionAndDashboard({ questionDetails }).then(
         ({ body: card }) => {
           visitDashboard(card.dashboard_id);
@@ -352,7 +389,20 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
         idAlias: "targetDashboardId",
       };
 
-      createDashboardWithTabs({ dashboard, tabs, options });
+      createDashboardWithTabs({
+        dashboard,
+        tabs,
+        dashcards: [
+          createMockDashboardCard({
+            dashboard_tab_id: SECOND_TAB.id,
+            card_id: ORDERS_QUESTION_ID,
+            parameter_mappings: [
+              createTextFilterMapping({ card_id: ORDERS_QUESTION_ID }),
+            ],
+          }),
+        ],
+        options,
+      });
 
       const TAB_SLUG_MAP = {};
 
@@ -787,8 +837,17 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
       };
 
       cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then(
-        ({ body: card }) => {
-          visitDashboard(card.dashboard_id);
+        ({ body: dashcard }) => {
+          addOrUpdateDashboardCard({
+            dashboard_id: dashcard.dashboard_id,
+            card_id: dashcard.card_id,
+            card: {
+              parameter_mappings: [
+                createTextFilterMapping({ card_id: dashcard.card_id }),
+              ],
+            },
+          });
+          visitDashboard(dashcard.dashboard_id);
         },
       );
 
@@ -815,7 +874,7 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
 
       cy.button(DASHBOARD_FILTER_TEXT.name).click();
       popover().within(() => {
-        cy.findByPlaceholderText("Enter some text").type(FILTER_VALUE);
+        cy.findByPlaceholderText("Search by Name").type("Dell Adams");
         cy.button("Add filter").click();
       });
 
@@ -845,12 +904,21 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
 
     it("allows updating single dashboard filter and changing it back to default click behavior", () => {
       const dashboardDetails = {
-        parameters: [DASHBOARD_FILTER_TEXT],
+        parameters: [DASHBOARD_FILTER_NUMBER],
       };
 
       cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then(
-        ({ body: card }) => {
-          visitDashboard(card.dashboard_id);
+        ({ body: dashcard }) => {
+          addOrUpdateDashboardCard({
+            dashboard_id: dashcard.dashboard_id,
+            card_id: dashcard.card_id,
+            card: {
+              parameter_mappings: [
+                createNumberFilterMapping({ card_id: dashcard.card_id }),
+              ],
+            },
+          });
+          visitDashboard(dashcard.dashboard_id);
           cy.location().then(({ pathname }) => {
             cy.wrap(pathname).as("originalPathname");
           });
@@ -861,7 +929,7 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
 
       getDashboardCard().realHover().icon("click").click();
       cy.get("aside").findByText("Update a dashboard filter").click();
-      addTextParameter();
+      addNumericParameter();
       cy.get("aside").button("Done").click();
 
       saveDashboard({ waitMs: 250 });
@@ -874,7 +942,7 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
         cy.location().should(({ pathname, search }) => {
           expect(pathname).to.equal(originalPathname);
           expect(search).to.equal(
-            `?${DASHBOARD_FILTER_TEXT.slug}=${POINT_COUNT}`,
+            `?${DASHBOARD_FILTER_NUMBER.slug}=${POINT_COUNT}`,
           );
         });
       });
@@ -888,8 +956,18 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
       };
 
       cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then(
-        ({ body: card }) => {
-          visitDashboard(card.dashboard_id);
+        ({ body: dashcard }) => {
+          addOrUpdateDashboardCard({
+            dashboard_id: dashcard.dashboard_id,
+            card_id: dashcard.card_id,
+            card: {
+              parameter_mappings: [
+                createTextFilterMapping({ card_id: dashcard.card_id }),
+                createTimeFilterMapping({ card_id: dashcard.card_id }),
+              ],
+            },
+          });
+          visitDashboard(dashcard.dashboard_id);
           cy.location().then(({ pathname }) => {
             cy.wrap(pathname).as("originalPathname");
           });
@@ -944,8 +1022,18 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
       };
 
       cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then(
-        ({ body: card }) => {
-          visitDashboard(card.dashboard_id);
+        ({ body: dashcard }) => {
+          addOrUpdateDashboardCard({
+            dashboard_id: dashcard.dashboard_id,
+            card_id: dashcard.card_id,
+            card: {
+              parameter_mappings: [
+                createTextFilterMapping({ card_id: dashcard.card_id }),
+                createTimeFilterMapping({ card_id: dashcard.card_id }),
+              ],
+            },
+          });
+          visitDashboard(dashcard.dashboard_id);
           cy.location().then(({ pathname }) => {
             cy.wrap(pathname).as("originalPathname");
           });
@@ -1011,6 +1099,15 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
         {
           ...TARGET_DASHBOARD,
           parameters: [DASHBOARD_FILTER_TEXT, DASHBOARD_FILTER_TIME],
+          dashcards: [
+            createMockDashboardCard({
+              card_id: ORDERS_QUESTION_ID,
+              parameter_mappings: [
+                createTextFilterMapping({ card_id: ORDERS_QUESTION_ID }),
+                createTimeFilterMapping({ card_id: ORDERS_QUESTION_ID }),
+              ],
+            }),
+          ],
         },
         {
           wrapId: true,
@@ -1140,7 +1237,21 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
         idAlias: "targetDashboardId",
       };
 
-      createDashboardWithTabs({ dashboard, tabs, options });
+      createDashboardWithTabs({
+        dashboard,
+        tabs,
+        dashcards: [
+          createMockDashboardCard({
+            dashboard_tab_id: SECOND_TAB.id,
+            card_id: ORDERS_QUESTION_ID,
+            parameter_mappings: [
+              createTextFilterMapping({ card_id: ORDERS_QUESTION_ID }),
+              createTimeFilterMapping({ card_id: ORDERS_QUESTION_ID }),
+            ],
+          }),
+        ],
+        options,
+      });
 
       const TAB_SLUG_MAP = {};
       tabs.forEach(tab => {
@@ -1202,6 +1313,15 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
         {
           ...TARGET_DASHBOARD,
           parameters: [DASHBOARD_FILTER_TEXT, DASHBOARD_FILTER_TIME],
+          dashcards: [
+            createMockDashboardCard({
+              card_id: ORDERS_QUESTION_ID,
+              parameter_mappings: [
+                createTextFilterMapping({ card_id: ORDERS_QUESTION_ID }),
+                createTimeFilterMapping({ card_id: ORDERS_QUESTION_ID }),
+              ],
+            }),
+          ],
         },
         {
           wrapId: true,
@@ -1209,8 +1329,17 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
         },
       );
       cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then(
-        ({ body: card }) => {
-          visitDashboard(card.dashboard_id);
+        ({ body: dashcard }) => {
+          addOrUpdateDashboardCard({
+            dashboard_id: dashcard.dashboard_id,
+            card_id: dashcard.card_id,
+            card: {
+              parameter_mappings: [
+                createTextFilterMapping({ card_id: dashcard.card_id }),
+              ],
+            },
+          });
+          visitDashboard(dashcard.dashboard_id);
           cy.location().then(({ pathname }) => {
             cy.wrap(pathname).as("originalPathname");
           });
@@ -1292,7 +1421,7 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
         cy.button(DASHBOARD_FILTER_TEXT.name).click();
         popover().within(() => {
           cy.icon("close").click();
-          cy.findByPlaceholderText("Enter some text").type(FILTER_VALUE);
+          cy.findByPlaceholderText("Search by Name").type("Dell Adams");
           cy.button("Update filter").click();
         });
         onNextAnchorClick(anchor => {
@@ -1301,7 +1430,7 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
           expect(anchor).to.have.attr("target", "_blank");
         });
         getTableCell(COLUMN_INDEX.CREATED_AT)
-          .should("have.text", `Created at: ${POINT_CREATED_AT_FORMATTED}`)
+          .should("have.text", `Created at: November 2023`)
           .click();
       })();
     });
@@ -1674,6 +1803,55 @@ const addTimeParameter = () => {
   });
 };
 
+const addNumericParameter = () => {
+  cy.get("aside").findByText(DASHBOARD_FILTER_NUMBER.name).click();
+  popover().within(() => {
+    cy.findByText(CREATED_AT_COLUMN_NAME).should("exist");
+    cy.findByText(COUNT_COLUMN_NAME).should("exist").click();
+  });
+};
+
+const createTextFilterMapping = ({ card_id }) => {
+  const fieldRef = [
+    "field",
+    PEOPLE.NAME,
+    {
+      "base-type": "type/Text",
+      "source-field": ORDERS.USER_ID,
+    },
+  ];
+
+  return {
+    card_id,
+    parameter_id: DASHBOARD_FILTER_TEXT.id,
+    target: ["dimension", fieldRef],
+  };
+};
+
+const createTimeFilterMapping = ({ card_id }) => {
+  const fieldRef = [
+    "field",
+    ORDERS.CREATED_AT,
+    { "base-type": "type/DateTime" },
+  ];
+
+  return {
+    card_id,
+    parameter_id: DASHBOARD_FILTER_TIME.id,
+    target: ["dimension", fieldRef],
+  };
+};
+
+const createNumberFilterMapping = ({ card_id }) => {
+  const fieldRef = ["field", ORDERS.QUANTITY, { "base-type": "type/Number" }];
+
+  return {
+    card_id,
+    parameter_id: DASHBOARD_FILTER_NUMBER.id,
+    target: ["dimension", fieldRef],
+  };
+};
+
 const assertDrillThroughMenuOpen = () => {
   popover()
     .should("contain", "See these Orders")
@@ -1730,21 +1908,24 @@ const getCountToDashboardFilterMapping = () => {
   return cy.get("aside").contains(`${COUNT_COLUMN_NAME} updates 1 filter`);
 };
 
-const createDashboardWithTabs = ({ dashboard, tabs, options }) => {
-  cy.createDashboard(dashboard, options);
-
-  cy.get(`@${options.idAlias}`)
-    .then(dashboardId => {
-      cy.request("PUT", `/api/dashboard/${dashboardId}/cards`, {
-        cards: [],
-        tabs,
-      });
-    })
-    .then(({ body }) => {
-      // wrap tabs
-
-      body.tabs.forEach(tab => {
+const createDashboardWithTabs = ({
+  dashboard: dashboardDetails,
+  tabs,
+  dashcards = [],
+  options,
+}) => {
+  cy.createDashboard(dashboardDetails).then(({ body: dashboard }) => {
+    if (options.wrapId) {
+      cy.wrap(dashboard.id).as(options.idAlias ?? "dashboardId");
+    }
+    cy.request("PUT", `/api/dashboard/${dashboard.id}`, {
+      ...dashboard,
+      dashcards,
+      tabs,
+    }).then(({ body: dashboard }) => {
+      dashboard.tabs.forEach(tab => {
         cy.wrap(tab.id).as(`${tab.name}-id`);
       });
     });
+  });
 };
diff --git a/e2e/test/scenarios/dashboard-filters/dashboard-filters-number.cy.spec.js b/e2e/test/scenarios/dashboard-filters/dashboard-filters-number.cy.spec.js
index 778bbc39dcfd5f7593d630a617507a1ac834b9ea..7b41969de4afba1947943beea447be223612a142 100644
--- a/e2e/test/scenarios/dashboard-filters/dashboard-filters-number.cy.spec.js
+++ b/e2e/test/scenarios/dashboard-filters/dashboard-filters-number.cy.spec.js
@@ -7,6 +7,7 @@ import {
   saveDashboard,
   setFilter,
   visitDashboard,
+  selectDashboardFilter,
 } from "e2e/support/helpers";
 import {
   ORDERS_DASHBOARD_ID,
@@ -57,6 +58,7 @@ describe("scenarios > dashboard > filters > number", () => {
 
   it(`should work when set as the default filter`, () => {
     setFilter("Number", "Equal to");
+    selectDashboardFilter(cy.findByTestId("dashcard"), "Tax");
     // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
     cy.findByText("Default value").next().click();
 
diff --git a/e2e/test/scenarios/dashboard-filters/dashboard-filters-source.cy.spec.js b/e2e/test/scenarios/dashboard-filters/dashboard-filters-source.cy.spec.js
index d43605185263d9f213bb3c93841b3737e0e432d3..a9532d5a2ac5793a1b506a20a5359266420e573b 100644
--- a/e2e/test/scenarios/dashboard-filters/dashboard-filters-source.cy.spec.js
+++ b/e2e/test/scenarios/dashboard-filters/dashboard-filters-source.cy.spec.js
@@ -79,21 +79,6 @@ describe("scenarios > dashboard > filters", { tags: "@slow" }, () => {
       archiveQuestion();
     });
 
-    it("should be able to use a structured question source without mapping to a field", () => {
-      cy.createQuestion(structuredSourceQuestion);
-      cy.createQuestionAndDashboard({
-        questionDetails: targetQuestion,
-      }).then(({ body: { dashboard_id } }) => {
-        visitDashboard(dashboard_id);
-      });
-
-      editDashboard();
-      setFilter("Text or Category", "Is");
-      setFilterQuestionSource({ question: "GUI source", field: "Category" });
-      saveDashboard();
-      filterDashboard();
-    });
-
     it("should be able to use a structured question source when embedded", () => {
       cy.createQuestion(structuredSourceQuestion).then(
         ({ body: { id: questionId } }) => {
diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/16663-filters-can-stay-in-url.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/16663-filters-can-stay-in-url.cy.spec.js
index 5de79913775dd315fe0d472e2bc7c782e05f4757..6b977a6dc8011c519143a3b29071fe3845cd8061 100644
--- a/e2e/test/scenarios/dashboard-filters/reproductions/16663-filters-can-stay-in-url.cy.spec.js
+++ b/e2e/test/scenarios/dashboard-filters/reproductions/16663-filters-can-stay-in-url.cy.spec.js
@@ -1,8 +1,12 @@
-import { restore, visitDashboard } from "e2e/support/helpers";
+import {
+  addOrUpdateDashboardCard,
+  restore,
+  visitDashboard,
+} from "e2e/support/helpers";
 
 import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
 
-const { ORDERS_ID } = SAMPLE_DATABASE;
+const { ORDERS, ORDERS_ID } = SAMPLE_DATABASE;
 
 const questionDetails = {
   query: {
@@ -10,18 +14,16 @@ const questionDetails = {
   },
 };
 
-const parameters = [
-  {
-    name: "Quarter and Year",
-    slug: "quarter_and_year",
-    id: "f8ae0c97",
-    type: "date/quarter-year",
-    sectionId: "date",
-    default: "Q1-2023",
-  },
-];
+const FILTER = {
+  name: "Quarter and Year",
+  slug: "quarter_and_year",
+  id: "f8ae0c97",
+  type: "date/quarter-year",
+  sectionId: "date",
+  default: "Q1-2023",
+};
 
-const dashboardDetails = { parameters };
+const dashboardDetails = { parameters: [FILTER] };
 
 describe("issue 16663", () => {
   beforeEach(() => {
@@ -37,6 +39,28 @@ describe("issue 16663", () => {
       ({ body: dashboardCard }) => {
         const { dashboard_id } = dashboardCard;
 
+        addOrUpdateDashboardCard({
+          dashboard_id: dashboardCard.dashboard_id,
+          card_id: dashboardCard.card_id,
+          card: {
+            parameter_mappings: [
+              {
+                parameter_id: FILTER.id,
+                card_id: dashboardCard.card_id,
+                target: [
+                  "dimension",
+                  [
+                    "field",
+                    ORDERS.CREATED_AT,
+                    {
+                      "base-type": "type/DateTime",
+                    },
+                  ],
+                ],
+              },
+            ],
+          },
+        });
         visitDashboard(dashboard_id);
       },
     );
diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/26230-dashboard-sticky-filter-incorrectly-positioned.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/26230-dashboard-sticky-filter-incorrectly-positioned.cy.spec.js
index 8d32c252b06a538cb0918e1e005dbd6c8a2f81b3..1a55166b152d5edf0d4af70ca1ee9dba95a85d9c 100644
--- a/e2e/test/scenarios/dashboard-filters/reproductions/26230-dashboard-sticky-filter-incorrectly-positioned.cy.spec.js
+++ b/e2e/test/scenarios/dashboard-filters/reproductions/26230-dashboard-sticky-filter-incorrectly-positioned.cy.spec.js
@@ -1,9 +1,9 @@
-import {
-  addOrUpdateDashboardCard,
-  getTextCardDetails,
-  restore,
-  visitDashboard,
-} from "e2e/support/helpers";
+import { restore, visitDashboard } from "e2e/support/helpers";
+import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
+import { ORDERS_QUESTION_ID } from "e2e/support/cypress_sample_instance_data";
+import { createMockDashboardCard } from "metabase-types/api/mocks";
+
+const { ORDERS, PEOPLE } = SAMPLE_DATABASE;
 
 describe("issue 26230", () => {
   beforeEach(() => {
@@ -33,36 +33,36 @@ describe("issue 26230", () => {
   });
 });
 
+const FILTER_1 = {
+  id: "12345678",
+  name: "Text",
+  slug: "text",
+  type: "string/=",
+  sectionId: "string",
+};
+
+const FILTER_2 = {
+  id: "87654321",
+  name: "Text",
+  slug: "text",
+  type: "string/=",
+  sectionId: "string",
+};
+
 function prepareAndVisitDashboards() {
   cy.createDashboard({
     name: "dashboard with a tall card",
-    parameters: [
-      {
-        id: "12345678",
-        name: "Text",
-        slug: "text",
-        type: "string/=",
-        sectionId: "string",
-      },
-    ],
+    parameters: [FILTER_1],
   }).then(({ body: { id } }) => {
-    createTextDashcard(id);
+    createDashCard(id, FILTER_1);
     bookmarkDashboard(id);
   });
 
   cy.createDashboard({
     name: "dashboard with a tall card 2",
-    parameters: [
-      {
-        id: "87654321",
-        name: "Text",
-        slug: "text",
-        type: "string/=",
-        sectionId: "string",
-      },
-    ],
+    parameters: [FILTER_2],
   }).then(({ body: { id } }) => {
-    createTextDashcard(id);
+    createDashCard(id, FILTER_2);
     bookmarkDashboard(id);
     visitDashboard(id);
   });
@@ -72,14 +72,30 @@ function bookmarkDashboard(dashboardId) {
   cy.request("POST", `/api/bookmark/dashboard/${dashboardId}`);
 }
 
-function createTextDashcard(id) {
-  addOrUpdateDashboardCard({
-    dashboard_id: id,
-    card_id: null,
-    card: getTextCardDetails({
-      size_x: 5,
-      size_y: 20,
-      text: "I am a tall card",
-    }),
+function createDashCard(dashboardId, mappedFilter) {
+  cy.request("PUT", `/api/dashboard/${dashboardId}`, {
+    dashcards: [
+      createMockDashboardCard({
+        id: -dashboardId,
+        dashboard_id: dashboardId,
+        size_x: 5,
+        size_y: 20,
+        card_id: ORDERS_QUESTION_ID,
+        parameter_mappings: [
+          {
+            parameter_id: mappedFilter.id,
+            card_id: ORDERS_QUESTION_ID,
+            target: [
+              "dimension",
+              [
+                "field",
+                PEOPLE.NAME,
+                { "base-type": "type/Text", "source-field": ORDERS.USER_ID },
+              ],
+            ],
+          },
+        ],
+      }),
+    ],
   });
 }
diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/31662-between-filter-default-value.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/31662-between-filter-default-value.cy.spec.js
index f9201162af6f993e5984fe2b93b6ffc4decf79fa..68d31baf7cb92009cfd345605ce629927386481c 100644
--- a/e2e/test/scenarios/dashboard-filters/reproductions/31662-between-filter-default-value.cy.spec.js
+++ b/e2e/test/scenarios/dashboard-filters/reproductions/31662-between-filter-default-value.cy.spec.js
@@ -1,4 +1,4 @@
-import { filterWidget, popover, restore } from "e2e/support/helpers";
+import { editDashboard, popover, restore, sidebar } from "e2e/support/helpers";
 
 const parameterDetails = {
   name: "Between",
@@ -29,10 +29,14 @@ describe("issue 31662", () => {
       },
     );
     cy.findByTestId("dashboard-empty-state").should("be.visible");
-    filterWidget().findByText("2 selections").click();
+    editDashboard();
+    cy.findByTestId("edit-dashboard-parameters-widget-container")
+      .findByText("Between")
+      .click();
+    sidebar().findByText("2 selections").click();
     popover().within(() => {
-      cy.findByDisplayValue("10").should("be.visible");
-      cy.findByDisplayValue("20").should("be.visible");
+      cy.findByDisplayValue("3").should("be.visible");
+      cy.findByDisplayValue("5").should("be.visible");
     });
   });
 });
diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/8030-32444-reload-card-without-change.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/8030-32444-reload-card-without-change.cy.spec.js
index a3f6d832f1885327c68b80bde91440e235a79697..b5e5d092183de1214a8ecfabdc3d994d9f56b996 100644
--- a/e2e/test/scenarios/dashboard-filters/reproductions/8030-32444-reload-card-without-change.cy.spec.js
+++ b/e2e/test/scenarios/dashboard-filters/reproductions/8030-32444-reload-card-without-change.cy.spec.js
@@ -7,6 +7,7 @@ import {
   editDashboard,
   setFilter,
   saveDashboard,
+  selectDashboardFilter,
 } from "e2e/support/helpers";
 import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
 
@@ -84,8 +85,7 @@ describe("issue 32444", () => {
 
   it("should not reload dashboard cards not connected to a filter (metabase#32444)", () => {
     cy.createDashboardWithQuestions({
-      dashboardName: "Dashboard with a card and filter",
-      questions: [questionWithFilter],
+      questions: [question1Details, questionWithFilter],
     }).then(({ dashboard }) => {
       cy.intercept(
         "POST",
@@ -95,15 +95,24 @@ describe("issue 32444", () => {
       visitDashboard(dashboard.id);
       editDashboard(dashboard.id);
 
+      cy.get("@getCardQuery.all").should("have.length", 2);
+
       setFilter("Text or Category", "Is");
+      selectDashboardFilter(cy.findAllByTestId("dashcard").first(), "Title");
+      cy.findAllByTestId("dashcard")
+        .eq(1)
+        .findByLabelText("Disconnect")
+        .click();
+
       saveDashboard();
 
       cy.wait("@getCardQuery");
-      cy.get("@getCardQuery.all").should("have.length", 1);
+      cy.get("@getCardQuery.all").should("have.length", 4);
 
-      addFilterValue(5);
+      addFilterValue("Aerodynamic Bronze Hat");
 
-      cy.get("@getCardQuery.all").should("have.length", 1);
+      cy.wait("@getCardQuery");
+      cy.get("@getCardQuery.all").should("have.length", 5);
     });
   });
 });
@@ -174,6 +183,6 @@ const interceptRequests = ({ dashboard_id, card1_id, card2_id }) => {
 
 function addFilterValue(value) {
   filterWidget().click();
-  cy.findByPlaceholderText("Enter some text").type(`${value}{enter}`);
+  cy.findByText(value).click();
   cy.button("Add filter").click();
 }
diff --git a/e2e/test/scenarios/dashboard/tabs.cy.spec.js b/e2e/test/scenarios/dashboard/tabs.cy.spec.js
index 12d53db14344b5ec736cdd9865b9d4b9c8b0c3fe..6f1c5b146e401c298997cc87e97d284cc3814d0f 100644
--- a/e2e/test/scenarios/dashboard/tabs.cy.spec.js
+++ b/e2e/test/scenarios/dashboard/tabs.cy.spec.js
@@ -32,14 +32,57 @@ import {
   popover,
 } from "e2e/support/helpers";
 
+import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
 import {
   ORDERS_DASHBOARD_ID,
   ORDERS_DASHBOARD_DASHCARD_ID,
   ORDERS_QUESTION_ID,
   ORDERS_COUNT_QUESTION_ID,
+  ORDERS_BY_YEAR_QUESTION_ID,
   ADMIN_PERSONAL_COLLECTION_ID,
   NORMAL_PERSONAL_COLLECTION_ID,
 } from "e2e/support/cypress_sample_instance_data";
+import { createMockDashboardCard } from "metabase-types/api/mocks";
+
+const { ORDERS, PEOPLE } = SAMPLE_DATABASE;
+
+const DASHBOARD_DATE_FILTER = {
+  id: "1",
+  name: "Date filter",
+  slug: "filter-date",
+  type: "date/month-year",
+};
+
+const DASHBOARD_NUMBER_FILTER = {
+  id: "2",
+  name: "Number filter",
+  slug: "filter-number",
+  type: "number/=",
+};
+
+const DASHBOARD_TEXT_FILTER = {
+  id: "3",
+  name: "Text filter",
+  slug: "filter-text",
+  type: "string/contains",
+};
+
+const DASHBOARD_LOCATION_FILTER = {
+  id: "4",
+  name: "Location filter",
+  slug: "filter-location",
+  type: "string/=",
+};
+
+const TAB_1 = {
+  id: 1,
+  name: "Tab 1",
+};
+
+const TAB_2 = {
+  id: 2,
+  name: "Tab 2",
+};
 
 describe("scenarios > dashboard > tabs", () => {
   beforeEach(() => {
@@ -77,6 +120,64 @@ describe("scenarios > dashboard > tabs", () => {
     });
   });
 
+  it("should only display filters mapped to cards on the selected tab", () => {
+    createDashboardWithTabs({
+      tabs: [TAB_1, TAB_2],
+      parameters: [
+        DASHBOARD_DATE_FILTER,
+        { ...DASHBOARD_NUMBER_FILTER, default: 20 },
+        { ...DASHBOARD_TEXT_FILTER, default: "fa" },
+        DASHBOARD_LOCATION_FILTER,
+      ],
+      dashcards: [
+        createMockDashboardCard({
+          id: -1,
+          card_id: ORDERS_QUESTION_ID,
+          dashboard_tab_id: TAB_1.id,
+          parameter_mappings: [
+            createDateFilterMapping({ card_id: ORDERS_QUESTION_ID }),
+            createTextFilterMapping({ card_id: ORDERS_BY_YEAR_QUESTION_ID }),
+          ],
+        }),
+        createMockDashboardCard({
+          id: -2,
+          card_id: ORDERS_BY_YEAR_QUESTION_ID,
+          dashboard_tab_id: TAB_2.id,
+          parameter_mappings: [
+            createDateFilterMapping({ card_id: ORDERS_BY_YEAR_QUESTION_ID }),
+            createNumberFilterMapping({ card_id: ORDERS_BY_YEAR_QUESTION_ID }),
+          ],
+        }),
+      ],
+    }).then(dashboard => visitDashboard(dashboard.id));
+
+    assertFiltersVisibility({
+      visible: [DASHBOARD_DATE_FILTER, DASHBOARD_TEXT_FILTER],
+      hidden: [DASHBOARD_NUMBER_FILTER, DASHBOARD_LOCATION_FILTER],
+    });
+
+    assertFilterValues([
+      [DASHBOARD_DATE_FILTER, undefined],
+      [DASHBOARD_TEXT_FILTER, "fa"],
+      [DASHBOARD_NUMBER_FILTER, 20],
+      [DASHBOARD_LOCATION_FILTER, undefined],
+    ]);
+
+    goToTab(TAB_2.name);
+
+    assertFiltersVisibility({
+      visible: [DASHBOARD_DATE_FILTER, DASHBOARD_NUMBER_FILTER],
+      hidden: [DASHBOARD_TEXT_FILTER, DASHBOARD_LOCATION_FILTER],
+    });
+
+    assertFilterValues([
+      [DASHBOARD_DATE_FILTER, undefined],
+      [DASHBOARD_TEXT_FILTER, "fa"],
+      [DASHBOARD_NUMBER_FILTER, 20],
+      [DASHBOARD_LOCATION_FILTER, undefined],
+    ]);
+  });
+
   it("should allow undoing a tab deletion", () => {
     visitDashboardAndCreateTab({
       dashboardId: ORDERS_DASHBOARD_ID,
@@ -544,3 +645,79 @@ function delayResponse(delayMs) {
     });
   };
 }
+
+function createDashboardWithTabs({ dashcards, tabs, ...dashboardDetails }) {
+  return cy.createDashboard(dashboardDetails).then(({ body: dashboard }) => {
+    cy.request("PUT", `/api/dashboard/${dashboard.id}`, {
+      ...dashboard,
+      dashcards,
+      tabs,
+    }).then(({ body: dashboard }) => cy.wrap(dashboard));
+  });
+}
+
+const createTextFilterMapping = ({ card_id }) => {
+  const fieldRef = [
+    "field",
+    PEOPLE.NAME,
+    {
+      "base-type": "type/Text",
+      "source-field": ORDERS.USER_ID,
+    },
+  ];
+
+  return {
+    card_id,
+    parameter_id: DASHBOARD_TEXT_FILTER.id,
+    target: ["dimension", fieldRef],
+  };
+};
+
+const createDateFilterMapping = ({ card_id }) => {
+  const fieldRef = [
+    "field",
+    ORDERS.CREATED_AT,
+    { "base-type": "type/DateTime" },
+  ];
+
+  return {
+    card_id,
+    parameter_id: DASHBOARD_DATE_FILTER.id,
+    target: ["dimension", fieldRef],
+  };
+};
+
+const createNumberFilterMapping = ({ card_id }) => {
+  const fieldRef = ["field", ORDERS.QUANTITY, { "base-type": "type/Number" }];
+
+  return {
+    card_id,
+    parameter_id: DASHBOARD_NUMBER_FILTER.id,
+    target: ["dimension", fieldRef],
+  };
+};
+
+function assertFiltersVisibility({ visible = [], hidden = [] }) {
+  cy.findByTestId("dashboard-parameters-widget-container", () => {
+    visible.forEach(filter => cy.findByText(filter.name).should("exist"));
+    hidden.forEach(filter => cy.findByText(filter.name).should("not.exist"));
+  });
+
+  // Ensure all filters are visible in edit mode
+  editDashboard();
+  cy.findByTestId("edit-dashboard-parameters-widget-container", () => {
+    [...visible, ...hidden].forEach(filter =>
+      cy.findByText(filter.name).should("exist"),
+    );
+  });
+
+  cy.findByTestId("edit-bar").button("Cancel").click();
+}
+
+function assertFilterValues(filterValues) {
+  filterValues.forEach(([filter, value]) => {
+    const displayValue = value === undefined ? "" : value.toString();
+    const filterQueryParameter = `${filter.slug}=${displayValue}`;
+    cy.location("search").should("contain", filterQueryParameter);
+  });
+}
diff --git a/e2e/test/scenarios/dashboard/text-dashcards.cy.spec.js b/e2e/test/scenarios/dashboard/text-dashcards.cy.spec.js
index 1f83409f1dd202755c83ef7277f32316dfd18372..c492ea9355cdcf432f24d495cd134fab8925b241 100644
--- a/e2e/test/scenarios/dashboard/text-dashcards.cy.spec.js
+++ b/e2e/test/scenarios/dashboard/text-dashcards.cy.spec.js
@@ -6,6 +6,7 @@ import {
   addTextBox,
   editDashboard,
   saveDashboard,
+  selectDashboardFilter,
   describeWithSnowplow,
   enableTracking,
   resetSnowplow,
@@ -146,6 +147,7 @@ describe("scenarios > dashboard > text and headings", () => {
         cy.findByText("Text or Category").click();
         cy.findByText("Is").click();
       });
+      selectDashboardFilter(cy.findAllByTestId("dashcard").first(), "Name");
       cy.findByTestId("edit-bar").findByText("Save").click();
 
       // confirm text box and filter are still there
diff --git a/e2e/test/scenarios/embedding/embedding-full-app.cy.spec.js b/e2e/test/scenarios/embedding/embedding-full-app.cy.spec.js
index 535eb09bea0e1f4e85a3cfc0ee22fb7533bc83a6..e227285553bf60b9f9a78feeba9dd97d2a849083 100644
--- a/e2e/test/scenarios/embedding/embedding-full-app.cy.spec.js
+++ b/e2e/test/scenarios/embedding/embedding-full-app.cy.spec.js
@@ -9,11 +9,16 @@ import {
   getDashboardCard,
   getTextCardDetails,
   updateDashboardCards,
+  getNextUnsavedDashboardCardId,
 } from "e2e/support/helpers";
+import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
 import {
   ORDERS_QUESTION_ID,
   ORDERS_DASHBOARD_ID,
 } from "e2e/support/cypress_sample_instance_data";
+import { createMockDashboardCard } from "metabase-types/api/mocks";
+
+const { ORDERS } = SAMPLE_DATABASE;
 
 describeEE("scenarios > embedding > full app", () => {
   beforeEach(() => {
@@ -342,11 +347,12 @@ describeEE("scenarios > embedding > full app", () => {
     });
 
     it("should have parameters header occupied the entire horizontal space when visiting a dashboard via navigation (metabase#30645)", () => {
+      const filterId = "50c9eac6";
       const dashboardDetails = {
         name: "interactive dashboard embedding",
         parameters: [
           {
-            id: "50c9eac6",
+            id: filterId,
             name: "ID",
             slug: "id",
             type: "id",
@@ -355,14 +361,33 @@ describeEE("scenarios > embedding > full app", () => {
       };
       cy.createDashboard(dashboardDetails).then(
         ({ body: { id: dashboardId } }) => {
-          const card = getTextCardDetails({
+          const textDashcard = getTextCardDetails({
             col: 0,
             row: 0,
             size_x: 6,
             size_y: 20,
             text: "I am a very long text card",
           });
-          updateDashboardCards({ dashboard_id: dashboardId, cards: [card] });
+          const dashcard = createMockDashboardCard({
+            id: getNextUnsavedDashboardCardId(),
+            col: 8,
+            row: 0,
+            card_id: ORDERS_QUESTION_ID,
+            parameter_mappings: [
+              {
+                parameter_id: filterId,
+                card_id: ORDERS_QUESTION_ID,
+                target: [
+                  "dimension",
+                  ["field", ORDERS.ID, { "base-type": "type/Integer" }],
+                ],
+              },
+            ],
+          });
+          updateDashboardCards({
+            dashboard_id: dashboardId,
+            cards: [dashcard, textDashcard],
+          });
         },
       );
 
diff --git a/frontend/src/metabase/dashboard/components/Dashboard/Dashboard.tsx b/frontend/src/metabase/dashboard/components/Dashboard/Dashboard.tsx
index 81a95e18f7dcf900bfe214dfc197805db4eba0b2..1302e6d9c18dce1fa9c6abd7c9d27169707e89ec 100644
--- a/frontend/src/metabase/dashboard/components/Dashboard/Dashboard.tsx
+++ b/frontend/src/metabase/dashboard/components/Dashboard/Dashboard.tsx
@@ -229,25 +229,41 @@ function DashboardInner(props: DashboardProps) {
   const previousTabId = usePrevious(selectedTabId);
   const previousParameterValues = usePrevious(parameterValues);
 
-  const visibleParameters = useMemo(
-    () => getVisibleParameters(parameters),
-    [parameters],
-  );
-
-  const tabHasCards = useMemo(() => {
+  const currentTabDashcards = useMemo(() => {
     if (!Array.isArray(dashboard?.dashcards)) {
-      return false;
+      return [];
     }
     if (!selectedTabId) {
-      return dashboard.dashcards.length > 0;
+      return dashboard.dashcards;
     }
-    const tabDashCards = dashboard.dashcards.filter(
+    return dashboard.dashcards.filter(
       dc => dc.dashboard_tab_id === selectedTabId,
     );
-    return tabDashCards.length > 0;
   }, [dashboard, selectedTabId]);
 
+  const hiddenParameterSlugs = useMemo(() => {
+    if (isEditing) {
+      // All filters should be visible in edit mode
+      return undefined;
+    }
+
+    const currentTabParameterIds = currentTabDashcards.flatMap(
+      dc => dc.parameter_mappings?.map(pm => pm.parameter_id) ?? [],
+    );
+    const hiddenParameters = parameters.filter(
+      parameter => !currentTabParameterIds.includes(parameter.id),
+    );
+
+    return hiddenParameters.map(p => p.slug).join(",");
+  }, [parameters, currentTabDashcards, isEditing]);
+
+  const visibleParameters = useMemo(
+    () => getVisibleParameters(parameters, hiddenParameterSlugs),
+    [parameters, hiddenParameterSlugs],
+  );
+
   const canWrite = Boolean(dashboard?.can_write);
+  const tabHasCards = currentTabDashcards.length > 0;
   const dashboardHasCards = dashboard?.dashcards.length > 0;
   const hasVisibleParameters = visibleParameters.length > 0;
 
@@ -439,6 +455,7 @@ function DashboardInner(props: DashboardProps) {
         isAutoApplyFilters ? parameterValues : draftParameterValues,
       )}
       editingParameter={editingParameter}
+      hideParameters={hiddenParameterSlugs}
       dashboard={dashboard}
       isFullscreen={isFullscreen}
       isNightMode={shouldRenderAsNightMode}