Add metadata editor to product creator

This commit is contained in:
dominik-zeglen 2020-08-31 16:58:07 +02:00
parent 7bb5ca231b
commit dde82e0756
3 changed files with 111 additions and 6 deletions

View file

@ -4,6 +4,7 @@ import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
import Container from "@saleor/components/Container";
import Form from "@saleor/components/Form";
import Grid from "@saleor/components/Grid";
import Metadata, { MetadataFormData } from "@saleor/components/Metadata";
import { MultiAutocompleteChoiceType } from "@saleor/components/MultiAutocompleteSelectField";
import PageHeader from "@saleor/components/PageHeader";
import SaveButtonBar from "@saleor/components/SaveButtonBar";
@ -25,6 +26,7 @@ import { SearchProductTypes_search_edges_node_productAttributes } from "@saleor/
import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses";
import createMultiAutocompleteSelectHandler from "@saleor/utils/handlers/multiAutocompleteSelectChangeHandler";
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
import { ContentState, convertToRaw, RawDraftContentState } from "draft-js";
import React from "react";
import { useIntl } from "react-intl";
@ -45,7 +47,7 @@ import ProductPricing from "../ProductPricing";
import ProductShipping from "../ProductShipping/ProductShipping";
import ProductStocks, { ProductStockInput } from "../ProductStocks";
interface FormData {
interface FormData extends MetadataFormData {
basePrice: number;
publicationDate: string;
category: string;
@ -133,6 +135,13 @@ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
const initialDescription = React.useRef(
convertToRaw(ContentState.createFromText(""))
);
const {
isMetadataModified,
isPrivateMetadataModified,
makeChangeHandler: makeMetadataChangeHandler
} = useMetadataChangeTrigger();
const initialData: FormData = {
basePrice: 0,
category: "",
@ -140,7 +149,9 @@ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
collections: [],
description: {} as any,
isPublished: false,
metadata: [],
name: "",
privateMetadata: [],
productType: "",
publicationDate: "",
seoDescription: "",
@ -168,12 +179,20 @@ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
const collections = getChoices(collectionChoiceList);
const productTypes = getChoices(productTypeChoiceList);
const handleSubmit = (data: FormData) =>
const handleSubmit = (data: FormData) => {
const metadata = isMetadataModified ? data.metadata : undefined;
const privateMetadata = isPrivateMetadataModified
? data.privateMetadata
: undefined;
onSubmit({
...data,
attributes,
stocks,
...data
metadata,
privateMetadata,
stocks
});
};
return (
<Form onSubmit={handleSubmit} initial={initialData} confirmLeave>
@ -212,6 +231,8 @@ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
productTypeChoiceList
);
const changeMetadata = makeMetadataChangeHandler(change);
return (
<Container>
<AppHeader onBack={onBack}>
@ -296,6 +317,8 @@ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
loading={disabled}
onChange={change}
/>
<CardSpacer />
<Metadata data={data} onChange={changeMetadata} />
</div>
<div>
<ProductOrganization

View file

@ -6,6 +6,11 @@ import useShop from "@saleor/hooks/useShop";
import useCategorySearch from "@saleor/searches/useCategorySearch";
import useCollectionSearch from "@saleor/searches/useCollectionSearch";
import useProductTypeSearch from "@saleor/searches/useProductTypeSearch";
import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler";
import {
useMetadataUpdate,
usePrivateMetadataUpdate
} from "@saleor/utils/metadata/updateMetadata";
import { useWarehouseList } from "@saleor/warehouses/queries";
import React from "react";
import { useIntl } from "react-intl";
@ -49,6 +54,8 @@ export const ProductCreateView: React.FC = () => {
first: 50
}
});
const [updateMetadata] = useMetadataUpdate({});
const [updatePrivateMetadata] = usePrivateMetadataUpdate({});
const handleBack = () => navigate(productListUrl());
@ -66,8 +73,8 @@ export const ProductCreateView: React.FC = () => {
}
});
const handleSubmit = (formData: ProductCreatePageSubmitData) => {
productCreate({
const handleCreate = async (formData: ProductCreatePageSubmitData) => {
const result = await productCreate({
variables: {
attributes: formData.attributes.map(attribute => ({
id: attribute.id,
@ -96,7 +103,14 @@ export const ProductCreateView: React.FC = () => {
weight: weight(formData.weight)
}
});
return result.data.productCreate?.product?.id || null;
};
const handleSubmit = createMetadataCreateHandler(
handleCreate,
updateMetadata,
updatePrivateMetadata
);
return (
<>

View file

@ -0,0 +1,68 @@
import { MetadataFormData } from "@saleor/components/Metadata/types";
import { MutationFunction } from "react-apollo";
import {
UpdateMetadata,
UpdateMetadataVariables
} from "../metadata/types/UpdateMetadata";
import {
UpdatePrivateMetadata,
UpdatePrivateMetadataVariables
} from "../metadata/types/UpdatePrivateMetadata";
function createMetadataCreateHandler<T extends MetadataFormData>(
create: (data: T) => Promise<string>,
setMetadata: MutationFunction<UpdateMetadata, UpdateMetadataVariables>,
setPrivateMetadata: MutationFunction<
UpdatePrivateMetadata,
UpdatePrivateMetadataVariables
>
) {
return async (data: T) => {
const id = await create(data);
if (id === null) {
return null;
}
if (data.metadata.length > 0) {
const updateMetaResult = await setMetadata({
variables: {
id,
input: data.metadata,
keysToDelete: []
}
});
const updateMetaErrors = [
...(updateMetaResult.data.deleteMetadata.errors || []),
...(updateMetaResult.data.updateMetadata.errors || [])
];
if (updateMetaErrors.length > 0) {
return updateMetaErrors;
}
}
if (data.privateMetadata.length > 0) {
const updatePrivateMetaResult = await setPrivateMetadata({
variables: {
id,
input: data.privateMetadata,
keysToDelete: []
}
});
const updatePrivateMetaErrors = [
...(updatePrivateMetaResult.data.deletePrivateMetadata.errors || []),
...(updatePrivateMetaResult.data.updatePrivateMetadata.errors || [])
];
if (updatePrivateMetaErrors.length > 0) {
return updatePrivateMetaErrors;
}
}
return [];
};
}
export default createMetadataCreateHandler;