From 3c714aeff107fbd69589b1efb7d1e2f4554b55be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 4 Jul 2024 11:22:08 +0200 Subject: [PATCH] Use Combobox in datagrid dropdown (#5010) * Combobox allow empty option * Use new combobox component in datagrid dropdown cell * Update dropdown * Fix remove value from dropdown * Add changeset * Fix types * Fix ts strict * Extract messages * Update changeset --- .changeset/slow-lemons-care.md | 5 + locale/defaultMessages.json | 4 + .../Combobox/components/Combobox.tsx | 13 ++- .../Combobox/hooks/useComboboxEmptyOption.ts | 19 ++++ .../Datagrid/customCells/DropdownCell.tsx | 95 ++++++++----------- src/components/Datagrid/customCells/cells.ts | 16 +--- .../OrderPaymentOrTransaction.test.tsx | 2 + 7 files changed, 87 insertions(+), 67 deletions(-) create mode 100644 .changeset/slow-lemons-care.md create mode 100644 src/components/Combobox/hooks/useComboboxEmptyOption.ts diff --git a/.changeset/slow-lemons-care.md b/.changeset/slow-lemons-care.md new file mode 100644 index 00000000000..ca82915d695 --- /dev/null +++ b/.changeset/slow-lemons-care.md @@ -0,0 +1,5 @@ +--- +"saleor-dashboard": patch +--- + +The selected value is no longer filtering the options when using any select list in product variant table diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index d999798271d..4b76f93589e 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -7740,6 +7740,10 @@ "context": "search label", "string": "Search Countries" }, + "pGfO2i": { + "context": "empty option", + "string": "None" + }, "pGwvpX": { "context": "status", "string": "Deactivated" diff --git a/src/components/Combobox/components/Combobox.tsx b/src/components/Combobox/components/Combobox.tsx index fc3a97f5d7d..a637adfd905 100644 --- a/src/components/Combobox/components/Combobox.tsx +++ b/src/components/Combobox/components/Combobox.tsx @@ -10,6 +10,7 @@ import React, { ReactNode, useEffect, useRef, useState } from "react"; import { useIntl } from "react-intl"; import { useCombbobxCustomOption } from "../hooks/useCombbobxCustomOption"; +import { useComboboxEmptyOption } from "../hooks/useComboboxEmptyOption"; import { useComboboxHandlers } from "../hooks/useComboboxHandlers"; type HandleOnChangeValue = Option | null; @@ -22,6 +23,7 @@ type ComboboxProps = Omit< fetchOptions: (data: string) => void; allowCustomValues?: boolean; alwaysFetchOnFocus?: boolean; + allowEmptyValue?: boolean; fetchMore?: FetchMoreProps; value: Option | null; onChange: (event: ChangeEvent) => void; @@ -34,6 +36,7 @@ const ComboboxRoot = ({ options, alwaysFetchOnFocus = false, allowCustomValues = false, + allowEmptyValue = false, fetchMore, loading, children, @@ -64,6 +67,8 @@ const ComboboxRoot = ({ selectedValue, }); + const { emptyOption } = useComboboxEmptyOption(); + const handleOnChange = (value: HandleOnChangeValue) => { onChange({ target: { value: value?.value ?? null, name: rest.name ?? "" }, @@ -73,7 +78,13 @@ const ComboboxRoot = ({ return ( { diff --git a/src/components/Combobox/hooks/useComboboxEmptyOption.ts b/src/components/Combobox/hooks/useComboboxEmptyOption.ts new file mode 100644 index 00000000000..5c0d35392b1 --- /dev/null +++ b/src/components/Combobox/hooks/useComboboxEmptyOption.ts @@ -0,0 +1,19 @@ +import { Option } from "@saleor/macaw-ui-next"; +import { useIntl } from "react-intl"; + +export const useComboboxEmptyOption = () => { + const intl = useIntl(); + + const emptyOption: Option = { + label: intl.formatMessage({ + id: "pGfO2i", + defaultMessage: "None", + description: "empty option", + }), + value: "", + }; + + return { + emptyOption, + }; +}; diff --git a/src/components/Datagrid/customCells/DropdownCell.tsx b/src/components/Datagrid/customCells/DropdownCell.tsx index a9855359046..2a68c84c3fa 100644 --- a/src/components/Datagrid/customCells/DropdownCell.tsx +++ b/src/components/Datagrid/customCells/DropdownCell.tsx @@ -1,4 +1,4 @@ -// @ts-strict-ignore +import { Combobox } from "@dashboard/components/Combobox"; import { CustomCell, CustomRenderer, @@ -6,91 +6,76 @@ import { GridCellKind, ProvideEditorCallback, } from "@glideapps/glide-data-grid"; -import { makeStyles } from "@saleor/macaw-ui"; +import { Option } from "@saleor/macaw-ui-next"; import pick from "lodash/pick"; import React from "react"; -import SingleAutocompleteSelectField, { - SingleAutocompleteSelectFieldProps, -} from "../../SingleAutocompleteSelectField"; -import { Choice } from "../../SingleSelectField"; - -export type DropdownChoice = Choice; -export type DropdownCellContentProps = Pick< - SingleAutocompleteSelectFieldProps, - "allowCustomValues" | "emptyOption" ->; - -export type DropdownCellGetSuggestionsFn = ( - text: string, -) => Promise; -interface DropdownCellProps extends DropdownCellContentProps { - readonly choices?: DropdownChoice[]; +export type DropdownCellGetSuggestionsFn = (text: string) => Promise; +export interface DropdownCellProps { + readonly choices?: Option[]; readonly update?: DropdownCellGetSuggestionsFn; readonly kind: "dropdown-cell"; - readonly value: DropdownChoice | null; + readonly value: Option | null; + readonly allowCustomValues?: boolean; + readonly emptyOption?: boolean; } export type DropdownCell = CustomCell; -export const emptyDropdownCellValue: DropdownChoice = { +export const emptyDropdownCellValue: Option = { label: "", - value: null, + value: "", }; -const useStyles = makeStyles( - { - root: { - "& > div": { - padding: 0, - }, - "& input": { - height: "unset", - }, - }, - }, - { name: "DropdownCell" }, -); - const DropdownCellEdit: ReturnType> = ({ value: cell, onFinishedEditing, }) => { - const [data, setData] = React.useState([]); + const [data, setData] = React.useState([]); + const getChoices = React.useCallback( async (text: string) => { - setData(await cell.data.update(text)); + setData((await cell.data?.update?.(text)) ?? []); }, [cell.data], ); - const classes = useStyles(); const userProps = pick(cell.data, ["allowCustomValues", "emptyOption"]); const props = cell.data.update ? { fetchOnFocus: true, fetchChoices: getChoices, choices: data } - : { choices: cell.data.choices }; + : { + fetchOnFocus: false, + fetchChoices: () => Promise.resolve([]), + choices: cell.data.choices, + }; return ( - - onFinishedEditing({ + undefined, + }} + options={props.choices ?? []} + value={cell.data.value} + fetchOptions={props.fetchChoices} + loading={false} + name="" + onChange={event => { + return onFinishedEditing({ ...cell, data: { ...cell.data, - value: props.choices.find(c => c.value === event.target.value) ?? { - label: event.target.value, - value: event.target.value, + value: props.choices?.find(c => c.value === event.target.value) ?? { + label: event.target.value ?? "", + value: event.target.value ?? "", }, }, - }) - } - name="" - displayValue={cell.data.value.label} - value={cell.data.value.value} + }); + }} /> ); }; @@ -104,7 +89,7 @@ export const dropdownCellRenderer: CustomRenderer = { ctx.fillStyle = theme.textDark; ctx.fillText( - value.label, + value?.label ?? "", rect.x + 8, rect.y + rect.height / 2 + getMiddleCenterBias(ctx, theme), ); diff --git a/src/components/Datagrid/customCells/cells.ts b/src/components/Datagrid/customCells/cells.ts index 6789345d1cb..3a491ac1357 100644 --- a/src/components/Datagrid/customCells/cells.ts +++ b/src/components/Datagrid/customCells/cells.ts @@ -11,12 +11,9 @@ import { GridCellKind, TextCell, } from "@glideapps/glide-data-grid"; +import { Option } from "@saleor/macaw-ui-next"; -import { - DropdownCell, - DropdownCellContentProps, - DropdownChoice, -} from "./DropdownCell"; +import { DropdownCell, DropdownCellProps } from "./DropdownCell"; import { MoneyCell, MoneyDiscuntedCell } from "./Money"; import { hueToPillColorLight, @@ -186,12 +183,9 @@ export function moneyDiscountedCell( } export function dropdownCell( - value: DropdownChoice, - dataOpts: DropdownCellContentProps & - ( - | { choices: DropdownChoice[] } - | { update: (text: string) => Promise } - ), + value: Option, + dataOpts: Pick & + ({ choices: Option[] } | { update: (text: string) => Promise }), opts?: Partial, ): DropdownCell { return { diff --git a/src/orders/components/OrderPaymentOrTransaction/OrderPaymentOrTransaction.test.tsx b/src/orders/components/OrderPaymentOrTransaction/OrderPaymentOrTransaction.test.tsx index b15d6bd0222..315565c1479 100644 --- a/src/orders/components/OrderPaymentOrTransaction/OrderPaymentOrTransaction.test.tsx +++ b/src/orders/components/OrderPaymentOrTransaction/OrderPaymentOrTransaction.test.tsx @@ -33,6 +33,8 @@ jest.mock("@saleor/macaw-ui", () => ({ jest.mock("@saleor/macaw-ui-next", () => ({ useTheme: jest.fn(() => () => ({})), Divider: jest.fn(() => <>), + DynamicCombobox: jest.fn(() => <>), + DynamicMultiselect: jest.fn(() => <>), vars: { colors: { border: {