Add metadata editor to product creator
This commit is contained in:
parent
7bb5ca231b
commit
dde82e0756
3 changed files with 111 additions and 6 deletions
|
@ -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
|
||||
|
|
|
@ -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 (
|
||||
<>
|
||||
|
|
68
src/utils/handlers/metadataCreateHandler.ts
Normal file
68
src/utils/handlers/metadataCreateHandler.ts
Normal 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;
|
Loading…
Reference in a new issue