diff --git a/admin/src/components/CheckboxListDefaultInput.tsx b/admin/src/components/CheckboxListDefaultInput.tsx index 465d0d3..ffd0551 100644 --- a/admin/src/components/CheckboxListDefaultInput.tsx +++ b/admin/src/components/CheckboxListDefaultInput.tsx @@ -1,6 +1,6 @@ import type { ReactNode } from 'react'; -import { Box, Checkbox, Field, Flex, Typography } from '@strapi/design-system'; +import { Box, Field, MultiSelect, MultiSelectOption, Typography } from '@strapi/design-system'; import { useIntl } from 'react-intl'; type CheckboxListDefaultInputProps = { @@ -23,6 +23,9 @@ type CheckboxListDefaultInputProps = { error?: string; modifiedData?: { enum?: string[]; + options?: { + enum?: string[]; + }; }; }; @@ -51,23 +54,26 @@ const CheckboxListDefaultInput = ({ modifiedData, }: CheckboxListDefaultInputProps) => { const { formatMessage } = useIntl(); - const enumValues = Array.isArray(modifiedData?.enum) ? modifiedData.enum : []; + const enumValues = Array.isArray(modifiedData?.options?.enum) + ? modifiedData.options.enum + : Array.isArray(modifiedData?.enum) + ? modifiedData.enum + : []; const selectedValues = normalizeValue(value); + const uniqueValues = Array.from( + new Set(enumValues.filter((option) => typeof option === 'string' && option.trim().length > 0)) + ); const label = intlLabel ? formatMessage(intlLabel, intlLabel.values ?? {}) : name; const hint = description ? formatMessage(description, description.values ?? {}) : undefined; - const handleToggle = (option: string, isChecked: boolean) => { - const nextValues = isChecked - ? Array.from(new Set([...selectedValues, option])) - : selectedValues.filter((item) => item !== option); - + const handleChange = (nextValues: string[] | undefined) => { onChange({ target: { name, - value: nextValues, + value: Array.isArray(nextValues) ? nextValues : [], }, }); }; @@ -75,21 +81,28 @@ const CheckboxListDefaultInput = ({ return ( {label} - {enumValues.length > 0 ? ( - - {enumValues.map((option) => ( - - handleToggle(option, Boolean(checked)) - } - > - {option} - - ))} - + {uniqueValues.length > 0 ? ( + + + {uniqueValues.map((option) => ( + + {option} + + ))} + + ) : ( diff --git a/admin/src/components/CheckboxListEnumInput.tsx b/admin/src/components/CheckboxListEnumInput.tsx new file mode 100644 index 0000000..0a1ac73 --- /dev/null +++ b/admin/src/components/CheckboxListEnumInput.tsx @@ -0,0 +1,126 @@ +import type { ChangeEvent, ReactNode } from 'react'; + +import { Field, Textarea } from '@strapi/design-system'; +import { useIntl } from 'react-intl'; + +type CheckboxListEnumInputProps = { + name: string; + value?: unknown; + onChange: (eventOrPath: { target: { name: string; value: string[] } }, value?: unknown) => void; + intlLabel: { + id: string; + defaultMessage: string; + values?: Record; + }; + description?: { + id: string; + defaultMessage: string; + values?: Record; + } | null; + labelAction?: ReactNode; + placeholder?: { + id: string; + defaultMessage: string; + values?: Record; + } | null; + disabled?: boolean; + error?: string; + modifiedData?: { + enum?: string[]; + options?: { + enum?: string[]; + }; + }; +}; + +const normalizeEnum = (value: unknown): string[] => { + if (Array.isArray(value)) { + return value.filter((item): item is string => typeof item === 'string'); + } + + return []; +}; + +const CheckboxListEnumInput = ({ + description = null, + disabled = false, + error = '', + intlLabel, + labelAction, + name, + onChange, + placeholder = null, + value, + modifiedData, +}: CheckboxListEnumInputProps) => { + const { formatMessage } = useIntl(); + + const fallbackEnum = normalizeEnum(modifiedData?.enum); + const resolvedEnum = normalizeEnum(value).length > 0 ? normalizeEnum(value) : fallbackEnum; + + const errorMessage = error + ? formatMessage({ + id: error, + defaultMessage: error, + }) + : ''; + + const hint = description + ? formatMessage( + { + id: description.id, + defaultMessage: description.defaultMessage, + }, + description.values + ) + : ''; + + const label = formatMessage(intlLabel, intlLabel.values ?? {}); + const formattedPlaceholder = placeholder + ? formatMessage( + { + id: placeholder.id, + defaultMessage: placeholder.defaultMessage, + }, + placeholder.values + ) + : ''; + + const inputValue = resolvedEnum.join('\n'); + + const handleChange = (event: ChangeEvent) => { + const arrayValue = event.target.value.split('\n'); + + onChange({ + target: { + name, + value: arrayValue, + }, + }); + + if (name !== 'enum') { + onChange({ + target: { + name: 'enum', + value: arrayValue, + }, + }); + } + }; + + return ( + + {label} +