diff --git a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Number.png b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Number.png index 1214fa5e39165f256383040ca50bd119ff1c1601..9ee197492d08335ebe3f31d837be0144b9518afc 100644 Binary files a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Number.png and b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Number.png differ diff --git a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Parameter_Search.png b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Parameter_Search.png index 3f46d051a2259d6b616c5f85b4ed7a8fff52ee5d..1e3d83344a1e07ed319ac2814248eaab976375ad 100644 Binary files a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Parameter_Search.png and b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Parameter_Search.png differ diff --git a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Parameter_Search_With_Value.png b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Parameter_Search_With_Value.png index de4855d83a4e3993a9a4a910c7e07446e28d8e89..7e1084705d7d451c0444e75cf633e9b96bcc1d8c 100644 Binary files a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Parameter_Search_With_Value.png and b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Parameter_Search_With_Value.png differ diff --git a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Text.png b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Text.png index 97d2e4c53b0bbac99327170c03cfe75d966e0c14..b4ae39631dbd665d30d6386aa43812795116fbd1 100644 Binary files a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Text.png and b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Text.png differ diff --git a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Text_With_Value.png b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Text_With_Value.png index 251cc6b0339e6a128c907c8c25267f5967188dc8..c196645baa81b300eb41e7fd8d3997e9f1e733d8 100644 Binary files a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Text_With_Value.png and b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Dark_Theme_Text_With_Value.png differ diff --git a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Date_Filter_Month_Year.png b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Date_Filter_Month_Year.png index 36863eb7f363089f7aadc5deb6c5855073365871..8c009930fe7a950683eca23ced607b4c3cbaa39e 100644 Binary files a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Date_Filter_Month_Year.png and b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Date_Filter_Month_Year.png differ diff --git a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Number.png b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Number.png index f9165a91a74099a151bb45878b98c681965dfda0..4051211c07be8281aebef6e0483fe32b5d05d362 100644 Binary files a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Number.png and b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Number.png differ diff --git a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Parameter_List_Single_With_Value.png b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Parameter_List_Single_With_Value.png index fc1f49c9ef7bff9c6f6ef58f573457c93eac6d21..9ca4904c1db13a95b9e49dc943eb3d1374f88a77 100644 Binary files a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Parameter_List_Single_With_Value.png and b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Parameter_List_Single_With_Value.png differ diff --git a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Parameter_List_With_Value.png b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Parameter_List_With_Value.png index 923a976c1e85039d5ae0be1faf504e22194605a0..f5901f6cab61d51be0a0c5ccb9c0885349421643 100644 Binary files a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Parameter_List_With_Value.png and b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Parameter_List_With_Value.png differ diff --git a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Parameter_Search.png b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Parameter_Search.png index 818270e9dfbdf9b90489b9186097fec21acc6544..0e075fb6cc53f29a7ffd13c269de671883cd63e2 100644 Binary files a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Parameter_Search.png and b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Parameter_Search.png differ diff --git a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Parameter_Search_With_Value.png b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Parameter_Search_With_Value.png index 43ab8fae5dc6a91883f9ce85105fbc3dfbefe63c..439c7f623647e363671c972fc58ed1a462795aaf 100644 Binary files a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Parameter_Search_With_Value.png and b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Parameter_Search_With_Value.png differ diff --git a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Text.png b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Text.png index 62e00c33bb30017886b56624763090aac7054c00..8c6d16f7529de6ca965f102e87eb0b22310b4494 100644 Binary files a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Text.png and b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Text.png differ diff --git a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Text_With_Value.png b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Text_With_Value.png index 8815c3985d39129f35360fbb4973d129235d460f..b61c72f1bd552a7988200af6e30b1970c9ffa081 100644 Binary files a/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Text_With_Value.png and b/.loki/reference/chrome_laptop_embed_PublicOrEmbeddedDashboardView_filters_Light_Theme_Text_With_Value.png differ diff --git a/e2e/test/scenarios/dashboard-filters/dashboard-chained-filters.cy.spec.js b/e2e/test/scenarios/dashboard-filters/dashboard-chained-filters.cy.spec.js index 8049a6e9dafd64a9a0b9a9ab9549555c94d3fc46..f9e5baff5987190c75bfe97651b7a20e022a28f8 100644 --- a/e2e/test/scenarios/dashboard-filters/dashboard-chained-filters.cy.spec.js +++ b/e2e/test/scenarios/dashboard-filters/dashboard-chained-filters.cy.spec.js @@ -173,7 +173,12 @@ describe("scenarios > dashboard > chained filter", () => { popover() .first() .within(() => { - multiAutocompleteInput().type("An"); + if (has_field_values === "search") { + multiAutocompleteInput().type("An"); + } + if (has_field_values === "list") { + cy.findByRole("textbox").type("An"); + } }); popover() diff --git a/e2e/test/scenarios/dashboard-filters/dashboard-filters-text-category.cy.spec.js b/e2e/test/scenarios/dashboard-filters/dashboard-filters-text-category.cy.spec.js index f22d734a77481873b6a683d8874ac3b93570bba8..3cf65e2a9c56316d05ea66914b960f126746df22 100644 --- a/e2e/test/scenarios/dashboard-filters/dashboard-filters-text-category.cy.spec.js +++ b/e2e/test/scenarios/dashboard-filters/dashboard-filters-text-category.cy.spec.js @@ -13,6 +13,7 @@ import { saveDashboard, selectDashboardFilter, setFilter, + sidebar, toggleFilterWidgetValues, toggleRequiredParameter, visitDashboard, @@ -232,7 +233,47 @@ describe("scenarios > dashboard > filters > text/category", () => { toggleFilterWidgetValues(["Twitter"], { buttonLabel: "Set to default", }); - filterWidget().findByText("Twitter"); + filterWidget().findByText("Twitter").should("be.visible"); + }); + + it("should use the list value picker for single-value category filters (metabase#49323)", () => { + setFilter("Text or Category", "Is"); + + selectDashboardFilter(cy.findByTestId("dashcard"), "Title"); + + sidebar().findByText("A single value").click(); + saveDashboard(); + + waitDashboardCardQuery(); + + filterWidget().contains("Text").click(); + popover().within(() => { + cy.findByRole("combobox").should("not.exist"); + cy.findByText("Aerodynamic Concrete Bench").should("be.visible").click(); + cy.findByText("Aerodynamic Bronze Hat").should("be.visible").click(); + cy.button("Add filter").click(); + }); + filterWidget().findByText("Aerodynamic Bronze Hat").should("be.visible"); + }); + + it("should use the list value picker for multi-value category filters (metabase#49323)", () => { + setFilter("Text or Category", "Is"); + + selectDashboardFilter(cy.findByTestId("dashcard"), "Title"); + + sidebar().findByText("Multiple values").click(); + saveDashboard(); + + waitDashboardCardQuery(); + + filterWidget().contains("Text").click(); + popover().within(() => { + cy.findByRole("combobox").should("not.exist"); + cy.findByText("Aerodynamic Concrete Bench").should("be.visible").click(); + cy.findByText("Aerodynamic Bronze Hat").should("be.visible").click(); + cy.button("Add filter").click(); + }); + filterWidget().findByText("2 selections").should("be.visible"); }); }); diff --git a/e2e/test/scenarios/dashboard-filters/parameters.cy.spec.js b/e2e/test/scenarios/dashboard-filters/parameters.cy.spec.js index 21d53cb88350e7a9bc1b7f102634f88f83a9247e..c40b2c51a05643009a499f32af90f5a60b870ec2 100644 --- a/e2e/test/scenarios/dashboard-filters/parameters.cy.spec.js +++ b/e2e/test/scenarios/dashboard-filters/parameters.cy.spec.js @@ -88,14 +88,14 @@ describe("scenarios > dashboard > parameters", () => { filterWidget().contains("Text").click(); // After typing "Ga", you should see this name! - popover().within(() => multiAutocompleteInput().type("Ga")); + popover().within(() => cy.findByPlaceholderText("Search").type("Ga")); cy.wait("@dashboard"); popover().last().contains("Gabrielle Considine"); // Continue typing a "d" and you see "Gadget" popover() .first() - .within(() => multiAutocompleteInput().type("d")); + .within(() => cy.findByPlaceholderText("Search").type("d")); cy.wait("@dashboard"); popover() 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 4462565c33ed1c6d43e17737f0d39d02e69be607..571b9975eaf439e8d1d387538948f7de64622fb7 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 @@ -192,7 +192,7 @@ describe("issue 8030 + 32444", () => { popover().within(() => { // the filter is connected only to the first card multiAutocompleteInput().type("1{enter}"); - cy.findByText("Add filter").click(); + cy.button("Add filter").click(); }); cy.wait("@getCardQuery1"); cy.get("@getCardQuery1.all").should("have.length", 2); @@ -589,7 +589,6 @@ describe("issues 15119 and 16112", () => { // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage cy.findByText(reviewerFilter.name).click(); popover().contains("adam").click(); - multiAutocompleteInput().blur(); cy.button("Add filter").click(); cy.findByTestId("dashcard-container").should("contain", "adam"); diff --git a/frontend/src/metabase/components/FieldValuesWidget/FieldValuesWidget.tsx b/frontend/src/metabase/components/FieldValuesWidget/FieldValuesWidget.tsx index 96a53e3a0eab0fbe7f75f5846b3e01b1581c126a..1da10e4769ca95c479a76fbe6a74bf423849e23f 100644 --- a/frontend/src/metabase/components/FieldValuesWidget/FieldValuesWidget.tsx +++ b/frontend/src/metabase/components/FieldValuesWidget/FieldValuesWidget.tsx @@ -163,10 +163,16 @@ export function FieldValuesWidgetInner({ const [isExpanded, setIsExpanded] = useState(false); const dispatch = useDispatch(); + const isSingleValueSearch = + valuesMode === "search" && !multi && !disableSearch; + const isListMode = + !disableList && + (shouldList({ parameter, fields, disableSearch }) || isSingleValueSearch); + const previousWidth = usePrevious(width); useMount(() => { - if (shouldList({ parameter, fields, disableSearch })) { + if (isListMode) { fetchValues(); } }); @@ -479,17 +485,15 @@ export function FieldValuesWidgetInner({ valuesMode, }); - const isListMode = - !disableList && - shouldList({ parameter, fields, disableSearch }) && - valuesMode === "list"; const isLoading = loadingState !== "LOADED"; - const hasListValues = hasList({ - parameter, - fields, - disableSearch, - options, - }); + const hasListValues = + hasList({ + parameter, + fields, + disableSearch, + options, + }) || + (isSingleValueSearch && options.length > 0); const valueForLabel = (label: string | number) => { const value = fieldValues.byLabel.get(label?.toString()); @@ -605,20 +609,22 @@ export function FieldValuesWidgetInner({ checkedColor={checkedColor} /> ) : !isSimpleInput ? ( - <MultiAutocomplete - data-testid="field-values-multi-autocomplete" - onSearchChange={onInputChange} - onChange={values => onChange(values.map(parseFreeformValue))} - value={value - .map(value => value?.toString()) - .filter((v): v is string => v !== null && v !== undefined)} - data={options.concat(valueOptions).map(renderStringOption)} - placeholder={tokenFieldPlaceholder} - shouldCreate={shouldCreate} - autoFocus={autoFocus} - icon={prefix && <span data-testid="input-prefix">{prefix}</span>} - itemComponent={CustomItemComponent} - /> + <Box pr="1rem"> + <MultiAutocomplete + data-testid="field-values-multi-autocomplete" + onSearchChange={onInputChange} + onChange={values => onChange(values.map(parseFreeformValue))} + value={value + .map(value => value?.toString()) + .filter((v): v is string => v !== null && v !== undefined)} + data={options.concat(valueOptions).map(renderStringOption)} + placeholder={tokenFieldPlaceholder} + shouldCreate={shouldCreate} + autoFocus={autoFocus} + icon={prefix && <span data-testid="input-prefix">{prefix}</span>} + itemComponent={CustomItemComponent} + /> + </Box> ) : ( <TokenField prefix={prefix} diff --git a/frontend/src/metabase/components/FieldValuesWidget/FieldValuesWidget.unit.spec.tsx b/frontend/src/metabase/components/FieldValuesWidget/FieldValuesWidget.unit.spec.tsx index aa0500fce87e5b8cc85f65d18e05a88c9b79a46b..e6afa4e58e28c3ec588f62d0fafecd03c1a1532c 100644 --- a/frontend/src/metabase/components/FieldValuesWidget/FieldValuesWidget.unit.spec.tsx +++ b/frontend/src/metabase/components/FieldValuesWidget/FieldValuesWidget.unit.spec.tsx @@ -132,11 +132,24 @@ describe("FieldValuesWidget", () => { describe("has_field_values = search", () => { const field = metadata.field(PEOPLE.EMAIL); - it("should not call fetchFieldValues", async () => { - const { fetchFieldValues } = await setup({ - fields: [field], + describe("multi = true", () => { + it("should not call fetchFieldValues", async () => { + const { fetchFieldValues } = await setup({ + fields: [field], + multi: true, + }); + expect(fetchFieldValues).not.toHaveBeenCalled(); + }); + }); + + describe("multi = false", () => { + it("should call fetchFieldValues", async () => { + const { fetchFieldValues } = await setup({ + fields: [field], + multi: false, + }); + expect(fetchFieldValues).toHaveBeenCalledWith(field); }); - expect(fetchFieldValues).not.toHaveBeenCalled(); }); it("should have 'Search by Vendor' as the placeholder text", async () => {