saleor-dashboard/src/attributes/views/AttributeCreate/AttributeCreate.tsx

214 lines
6.2 KiB
TypeScript
Raw Normal View History

2019-08-09 10:17:04 +00:00
import React from "react";
import { useIntl } from "react-intl";
2019-08-09 10:17:04 +00:00
import slugify from "slugify";
import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier";
2019-12-06 17:11:46 +00:00
import { maybe } from "@saleor/misc";
2019-08-09 10:17:04 +00:00
import { ReorderEvent, UserError } from "@saleor/types";
import {
add,
isSelected,
move,
remove,
updateAtIndex
} from "@saleor/utils/lists";
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,
AttributeAddUrlDialog,
AttributeAddUrlQueryParams,
attributeListUrl,
attributeUrl
} from "../../urls";
interface AttributeDetailsProps {
params: AttributeAddUrlQueryParams;
}
function areValuesEqual(
a: AttributeValueEditDialogFormData,
b: AttributeValueEditDialogFormData
) {
return a.name === b.name;
}
const AttributeDetails: React.FC<AttributeDetailsProps> = ({ params }) => {
const navigate = useNavigator();
const notify = useNotifier();
const intl = useIntl();
2019-08-09 10:17:04 +00:00
const [values, setValues] = React.useState<
AttributeValueEditDialogFormData[]
>([]);
const [valueErrors, setValueErrors] = React.useState<UserError[]>([]);
const id = params.id ? parseInt(params.id, 0) : undefined;
const closeModal = () =>
navigate(
attributeAddUrl({
...params,
action: undefined,
id: undefined
}),
true
);
const openModal = (action: AttributeAddUrlDialog, valueId?: string) =>
navigate(
attributeAddUrl({
...params,
action,
id: valueId
})
);
const handleValueDelete = () => {
setValues(remove(values[params.id], values, areValuesEqual));
closeModal();
};
const handleCreate = (data: AttributeCreate) => {
if (data.attributeCreate.errors.length === 0) {
notify({
text: intl.formatMessage({
2019-08-22 16:19:16 +00:00
defaultMessage: "Successfully created attribute"
})
});
2019-08-09 10:17:04 +00:00
navigate(attributeUrl(data.attributeCreate.attribute.id));
}
};
const handleValueUpdate = (input: AttributeValueEditDialogFormData) => {
if (isSelected(input, values, areValuesEqual)) {
setValueErrors([
{
field: "name",
message: intl.formatMessage(
{
2019-11-05 12:57:30 +00:00
defaultMessage: "A value named {name} already exists",
2019-08-22 16:19:16 +00:00
description: "attribute value edit error"
},
{
name: input.name
}
)
2019-08-09 10:17:04 +00:00
}
]);
} else {
setValues(updateAtIndex(input, values, id));
closeModal();
}
};
const handleValueCreate = (input: AttributeValueEditDialogFormData) => {
if (isSelected(input, values, areValuesEqual)) {
setValueErrors([
{
field: "name",
message: intl.formatMessage(
{
2019-11-05 12:57:30 +00:00
defaultMessage: "A value named {name} already exists",
2019-08-22 16:19:16 +00:00
description: "attribute value edit error"
},
{
name: input.name
}
)
2019-08-09 10:17:04 +00:00
}
]);
} else {
setValues(add(input, values));
closeModal();
}
};
const handleValueReorder = ({ newIndex, oldIndex }: ReorderEvent) =>
setValues(move(values[oldIndex], values, areValuesEqual, newIndex));
return (
<AttributeCreateMutation onCompleted={handleCreate}>
2019-12-06 17:11:46 +00:00
{(attributeCreate, attributeCreateOpts) => (
<>
<AttributePage
attribute={null}
disabled={false}
errors={maybe(
() => attributeCreateOpts.data.attributeCreate.errors,
[]
2019-08-09 10:17:04 +00:00
)}
2019-12-06 17:11:46 +00:00
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)}
2019-12-06 17:17:44 +00:00
saveButtonBarState={attributeCreateOpts.status}
2019-12-06 17:11:46 +00:00
values={values.map((value, valueIndex) => ({
__typename: "AttributeValue" as "AttributeValue",
id: valueIndex.toString(),
slug: slugify(value.name).toLowerCase(),
sortOrder: valueIndex,
type: null,
value: null,
...value
}))}
/>
<AttributeValueEditDialog
attributeValue={null}
confirmButtonState="default"
disabled={false}
errors={valueErrors}
open={params.action === "add-value"}
onClose={closeModal}
onSubmit={handleValueCreate}
/>
{values.length > 0 && (
<>
<AttributeValueDeleteDialog
attributeName={undefined}
open={params.action === "remove-value"}
name={maybe(() => values[id].name, "...")}
confirmButtonState="default"
onClose={closeModal}
onConfirm={handleValueDelete}
/>
<AttributeValueEditDialog
attributeValue={maybe(() => values[params.id])}
confirmButtonState="default"
disabled={false}
errors={valueErrors}
open={params.action === "edit-value"}
onClose={closeModal}
onSubmit={handleValueUpdate}
/>
</>
)}
</>
)}
2019-08-09 10:17:04 +00:00
</AttributeCreateMutation>
);
};
AttributeDetails.displayName = "AttributeDetails";
export default AttributeDetails;