diff --git a/e2e/test/scenarios/visualizations-tabular/drillthroughs/table_drills.cy.spec.js b/e2e/test/scenarios/visualizations-tabular/drillthroughs/table_drills.cy.spec.js index 6e96dc3547f162d9da87c8f29b06e6bf98b68cd4..8bb7098f5b981bb569e534a1f1063cfdbdd8fce0 100644 --- a/e2e/test/scenarios/visualizations-tabular/drillthroughs/table_drills.cy.spec.js +++ b/e2e/test/scenarios/visualizations-tabular/drillthroughs/table_drills.cy.spec.js @@ -4,9 +4,10 @@ import { popover, restore, tableHeaderClick, + openTable, } from "e2e/support/helpers"; -const { REVIEWS, REVIEWS_ID } = SAMPLE_DATABASE; +const { REVIEWS, REVIEWS_ID, ACCOUNTS_ID } = SAMPLE_DATABASE; describe("scenarios > visualizations > drillthroughs > table_drills", () => { beforeEach(() => { @@ -210,3 +211,36 @@ describe("scenarios > visualizations > drillthroughs > table_drills", () => { .should("be.visible"); }); }); + +describe("scenarios > visualizations > drillthroughs > table_drills > nulls", () => { + beforeEach(() => { + // It's important to restore to the "setup" to have access to "Accounts" table + restore("setup"); + cy.signInAsAdmin(); + cy.viewport(1500, 800); + }); + + it("should display proper drills on a datetime cell click when there is no value (metabase#44101)", () => { + const CANCELLED_AT_INDEX = 9; + + openTable({ table: ACCOUNTS_ID, limit: 1 }); + cy.findAllByRole("gridcell") + .eq(CANCELLED_AT_INDEX) + .should("have.text", "") + .click({ force: true }); + + popover().within(() => { + cy.findByText("Filter by this date").should("be.visible"); + cy.findByText("Is empty").should("be.visible"); + cy.findByText("Not empty").should("be.visible").click(); + }); + + cy.findByTestId("filter-pill").should( + "have.text", + "Canceled At is not empty", + ); + cy.findAllByRole("gridcell") + .eq(CANCELLED_AT_INDEX) + .should("not.have.text", ""); + }); +}); diff --git a/frontend/src/metabase/querying/utils/drills/quick-filter-drill/quick-filter-drill.tsx b/frontend/src/metabase/querying/utils/drills/quick-filter-drill/quick-filter-drill.tsx index af3edc4a58a58a035e358e0d5e7e5c9e88cd5f94..b243c205b55cd20d94826635710f4d0ff985165f 100644 --- a/frontend/src/metabase/querying/utils/drills/quick-filter-drill/quick-filter-drill.tsx +++ b/frontend/src/metabase/querying/utils/drills/quick-filter-drill/quick-filter-drill.tsx @@ -37,24 +37,37 @@ function getActionOverrides( operator: Lib.QuickFilterDrillThruOperator, value: unknown, ): Partial<ClickAction> { - if (Lib.isDate(column) && value != null) { + if (Lib.isDate(column)) { const action: Partial<ClickAction> = { sectionTitle: t`Filter by this date`, sectionDirection: "column", buttonType: "horizontal", }; - switch (operator) { - case "=": - return { ...action, title: t`On` }; - case "≠": - return { ...action, title: t`Not on` }; - case ">": - return { ...action, title: t`After` }; - case "<": - return { ...action, title: t`Before` }; - default: - return action; + if (value !== null) { + switch (operator) { + case "=": + return { ...action, title: t`On` }; + case "≠": + return { ...action, title: t`Not on` }; + case ">": + return { ...action, title: t`After` }; + case "<": + return { ...action, title: t`Before` }; + default: + return action; + } + } + + if (value === null) { + switch (operator) { + case "=": + return { ...action, title: t`Is empty` }; + case "≠": + return { ...action, title: t`Not empty` }; + default: + return action; + } } }