diff --git a/.changeset/lovely-hairs-smell.md b/.changeset/lovely-hairs-smell.md new file mode 100644 index 00000000000..fd636ebcb43 --- /dev/null +++ b/.changeset/lovely-hairs-smell.md @@ -0,0 +1,5 @@ +--- +"saleor-dashboard": patch +--- + +The boolean attribute has been changed from a toggle to a select. This change helps visualize when the attribute has not been set. diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index 4b76f93589e..197437e0d77 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -1406,6 +1406,10 @@ "context": "checkbox gift cards label", "string": "Automatically fulfill non shippable gift cards" }, + "7WEeNq": { + "context": "select label", + "string": "True" + }, "7WzUxn": { "context": "staff member status", "string": "Inactive" @@ -5746,6 +5750,10 @@ "b088Xv": { "string": "App doesn't provide a description." }, + "b1j4K6": { + "context": "select label", + "string": "False" + }, "b1t9bM": { "context": "empty headers text", "string": "No custom request headers created for this webhook. Use the button below to add new custom request header." @@ -6984,6 +6992,10 @@ "context": "app data privacy link", "string": "Learn more about data privacy" }, + "k62BKw": { + "context": "select label", + "string": "Unset" + }, "k6WDZl": { "context": "attribute is visible", "string": "Visible" diff --git a/src/attributes/utils/data.ts b/src/attributes/utils/data.ts index e6252408e28..daaec90764f 100644 --- a/src/attributes/utils/data.ts +++ b/src/attributes/utils/data.ts @@ -19,7 +19,6 @@ import { SearchProductsQuery, SelectedVariantAttributeFragment, UploadErrorFragment, - VariantAttributeFragment, } from "@dashboard/graphql"; import { FormsetData } from "@dashboard/hooks/useFormset"; import { AttributeValuesMetadata } from "@dashboard/products/utils/data"; @@ -160,16 +159,6 @@ export function getAttributeData( } } -export function getDefaultAttributeValues(attribute: VariantAttributeFragment) { - switch (attribute.inputType) { - case AttributeInputTypeEnum.BOOLEAN: - return ["false"]; - - default: - return []; - } -} - export function getSelectedAttributeValues( attribute: | PageSelectedAttributeFragment @@ -190,7 +179,7 @@ export function getSelectedAttributeValues( return [attribute.values[0]?.name]; case AttributeInputTypeEnum.BOOLEAN: - return [attribute.values[0]?.boolean ?? "false"]; + return [attribute.values[0]?.boolean]; case AttributeInputTypeEnum.DATE: return [attribute.values[0]?.date]; diff --git a/src/attributes/utils/handlers.ts b/src/attributes/utils/handlers.ts index 228e5bc542e..7fa883ff66d 100644 --- a/src/attributes/utils/handlers.ts +++ b/src/attributes/utils/handlers.ts @@ -228,7 +228,7 @@ function getFileInput( function getBooleanInput(attribute: AttributeInput) { return { id: attribute.id, - boolean: JSON.parse(attribute.value[0] ?? "false"), + boolean: attribute.value[0] ? JSON.parse(attribute.value[0]) : null, }; } diff --git a/src/components/Attributes/AttributeRow.tsx b/src/components/Attributes/AttributeRow.tsx index d30cb5a49b2..78b13c97b53 100644 --- a/src/components/Attributes/AttributeRow.tsx +++ b/src/components/Attributes/AttributeRow.tsx @@ -5,6 +5,8 @@ import ExtendedAttributeRow from "@dashboard/components/Attributes/ExtendedAttri import { attributeRowMessages } from "@dashboard/components/Attributes/messages"; import { SwatchRow } from "@dashboard/components/Attributes/SwatchRow"; import { + booleanAttrValueToValue, + getBooleanDropdownOptions, getErrorMessage, getFileChoice, getMultiChoices, @@ -17,7 +19,7 @@ import FileUploadField from "@dashboard/components/FileUploadField"; import RichTextEditor from "@dashboard/components/RichTextEditor"; import SortableChipsField from "@dashboard/components/SortableChipsField"; import { AttributeInputTypeEnum } from "@dashboard/graphql"; -import { Box, Input, Text, Toggle } from "@saleor/macaw-ui-next"; +import { Box, Input, Select, Text } from "@saleor/macaw-ui-next"; import React from "react"; import { useIntl } from "react-intl"; @@ -199,7 +201,14 @@ const AttributeRow: React.FC = ({ case AttributeInputTypeEnum.BOOLEAN: return ( - + = ({ flexDirection="column" alignItems="flex-end" > - onChange(attribute.id, checked)} - pressed={JSON.parse(attribute.value[0] ?? "false")} + value={booleanAttrValueToValue(attribute.value[0])} + onChange={value => + onChange( + attribute.id, + value === "unset" ? undefined : value === "true", + ) + } + options={getBooleanDropdownOptions(intl)} id={`attribute:${attribute.label}`} + disabled={disabled} /> {getErrorMessage(error, intl)} diff --git a/src/components/Attributes/utils.ts b/src/components/Attributes/utils.ts index 57380e29863..9d9fdf05761 100644 --- a/src/components/Attributes/utils.ts +++ b/src/components/Attributes/utils.ts @@ -157,3 +157,40 @@ export function getErrorMessage( return getPageErrorMessage(err, intl); } } + +export function booleanAttrValueToValue(value: unknown | undefined): string { + if (typeof value !== "boolean") { + return "unset"; + } + + return value ? "true" : "false"; +} + +export function getBooleanDropdownOptions(intl: IntlShape) { + return [ + { + label: intl.formatMessage({ + defaultMessage: "True", + id: "7WEeNq", + description: "select label", + }), + value: "true", + }, + { + label: intl.formatMessage({ + defaultMessage: "False", + id: "b1j4K6", + description: "select label", + }), + value: "false", + }, + { + label: intl.formatMessage({ + defaultMessage: "Unset", + id: "k62BKw", + description: "select label", + }), + value: "unset", + }, + ]; +} diff --git a/src/products/utils/data.ts b/src/products/utils/data.ts index 2d68d565422..b02c1f738d1 100644 --- a/src/products/utils/data.ts +++ b/src/products/utils/data.ts @@ -1,6 +1,5 @@ // @ts-strict-ignore import { - getDefaultAttributeValues, getSelectedAttributeValues, mergeChoicesWithValues, } from "@dashboard/attributes/utils/data"; @@ -111,7 +110,7 @@ export function getAttributeInputFromAttributes( }, id: attribute.id, label: attribute.name, - value: getDefaultAttributeValues(attribute), + value: [], })); }