import React from "react"; import { useIntl } from "react-intl"; import slugify from "slugify"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import { maybe } from "@saleor/misc"; import { ReorderEvent, UserError } from "@saleor/types"; import { add, isSelected, move, remove, updateAtIndex } from "@saleor/utils/lists"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; import AttributePage from "../../components/AttributePage"; import AttributeValueDeleteDialog from "../../components/AttributeValueDeleteDialog"; import AttributeValueEditDialog, { AttributeValueEditDialogFormData } from "../../components/AttributeValueEditDialog"; import { AttributeCreateMutation } from "../../mutations"; import { AttributeCreate } from "../../types/AttributeCreate"; import { attributeAddUrl, AttributeAddUrlQueryParams, attributeListUrl, attributeUrl, AttributeAddUrlDialog } from "../../urls"; interface AttributeDetailsProps { params: AttributeAddUrlQueryParams; } function areValuesEqual( a: AttributeValueEditDialogFormData, b: AttributeValueEditDialogFormData ) { return a.name === b.name; } const AttributeDetails: React.FC = ({ params }) => { const navigate = useNavigator(); const notify = useNotifier(); const intl = useIntl(); const [values, setValues] = React.useState< AttributeValueEditDialogFormData[] >([]); const [valueErrors, setValueErrors] = React.useState([]); const id = params.id ? parseInt(params.id, 0) : undefined; const [openModal, closeModal] = createDialogActionHandlers< AttributeAddUrlDialog, AttributeAddUrlQueryParams >(navigate, attributeAddUrl, params); const handleValueDelete = () => { setValues(remove(values[params.id], values, areValuesEqual)); closeModal(); }; const handleCreate = (data: AttributeCreate) => { if (data.attributeCreate.errors.length === 0) { notify({ text: intl.formatMessage({ defaultMessage: "Successfully created attribute" }) }); navigate(attributeUrl(data.attributeCreate.attribute.id)); } }; const handleValueUpdate = (input: AttributeValueEditDialogFormData) => { if (isSelected(input, values, areValuesEqual)) { setValueErrors([ { field: "name", message: intl.formatMessage( { defaultMessage: "A value named {name} already exists", description: "attribute value edit error" }, { name: input.name } ) } ]); } else { setValues(updateAtIndex(input, values, id)); closeModal(); } }; const handleValueCreate = (input: AttributeValueEditDialogFormData) => { if (isSelected(input, values, areValuesEqual)) { setValueErrors([ { field: "name", message: intl.formatMessage( { defaultMessage: "A value named {name} already exists", description: "attribute value edit error" }, { name: input.name } ) } ]); } else { setValues(add(input, values)); closeModal(); } }; const handleValueReorder = ({ newIndex, oldIndex }: ReorderEvent) => setValues(move(values[oldIndex], values, areValuesEqual, newIndex)); return ( {(attributeCreate, attributeCreateOpts) => ( <> attributeCreateOpts.data.attributeCreate.errors, [] )} onBack={() => navigate(attributeListUrl())} onDelete={undefined} onSubmit={input => attributeCreate({ variables: { input: { ...input, storefrontSearchPosition: parseInt( input.storefrontSearchPosition, 0 ), values: values.map(value => ({ name: value.name })) } } }) } onValueAdd={() => openModal("add-value")} onValueDelete={id => openModal("remove-value", { id }) } onValueReorder={handleValueReorder} onValueUpdate={id => openModal("edit-value", { id }) } saveButtonBarState={attributeCreateOpts.status} values={values.map((value, valueIndex) => ({ __typename: "AttributeValue" as "AttributeValue", id: valueIndex.toString(), slug: slugify(value.name).toLowerCase(), sortOrder: valueIndex, type: null, value: null, ...value }))} /> {values.length > 0 && ( <> values[id].name, "...")} confirmButtonState="default" onClose={closeModal} onConfirm={handleValueDelete} /> values[params.id])} confirmButtonState="default" disabled={false} errors={valueErrors} open={params.action === "edit-value"} onClose={closeModal} onSubmit={handleValueUpdate} /> )} )} ); }; AttributeDetails.displayName = "AttributeDetails"; export default AttributeDetails;