2020-11-04 10:48:49 +00:00
|
|
|
import { OutputData } from "@editorjs/editorjs";
|
2020-12-16 10:53:28 +00:00
|
|
|
import { AttributeInput } from "@saleor/components/Attributes";
|
2020-11-04 10:48:49 +00:00
|
|
|
import { MetadataFormData } from "@saleor/components/Metadata";
|
|
|
|
import { RichTextEditorChange } from "@saleor/components/RichTextEditor";
|
2020-11-19 14:42:14 +00:00
|
|
|
import { PageTypeFragment } from "@saleor/fragments/types/PageTypeFragment";
|
2020-11-06 10:54:03 +00:00
|
|
|
import useForm, { FormChange, SubmitPromise } from "@saleor/hooks/useForm";
|
2020-12-16 10:53:28 +00:00
|
|
|
import useFormset, {
|
|
|
|
FormsetChange,
|
|
|
|
FormsetData
|
|
|
|
} from "@saleor/hooks/useFormset";
|
2020-11-19 14:42:14 +00:00
|
|
|
import useStateFromProps from "@saleor/hooks/useStateFromProps";
|
|
|
|
import {
|
|
|
|
PageDetails_page,
|
|
|
|
PageDetails_page_pageType
|
|
|
|
} from "@saleor/pages/types/PageDetails";
|
2020-12-16 10:53:28 +00:00
|
|
|
import {
|
|
|
|
getAttributeInputFromPage,
|
|
|
|
getAttributesDisplayData
|
|
|
|
} from "@saleor/pages/utils/data";
|
2020-11-19 14:42:14 +00:00
|
|
|
import { createPageTypeSelectHandler } from "@saleor/pages/utils/handlers";
|
|
|
|
import {
|
|
|
|
createAttributeChangeHandler,
|
2020-12-16 10:53:28 +00:00
|
|
|
createAttributeFileChangeHandler,
|
2020-11-19 14:42:14 +00:00
|
|
|
createAttributeMultiChangeHandler
|
|
|
|
} from "@saleor/products/utils/handlers";
|
2020-11-04 10:48:49 +00:00
|
|
|
import getPublicationData from "@saleor/utils/data/getPublicationData";
|
|
|
|
import handleFormSubmit from "@saleor/utils/handlers/handleFormSubmit";
|
|
|
|
import { mapMetadataItemToInput } from "@saleor/utils/maps";
|
|
|
|
import getMetadata from "@saleor/utils/metadata/getMetadata";
|
|
|
|
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
|
|
|
|
import useRichText from "@saleor/utils/richText/useRichText";
|
2020-12-16 10:53:28 +00:00
|
|
|
import React, { useEffect } from "react";
|
2020-11-19 14:42:14 +00:00
|
|
|
|
2020-11-04 10:48:49 +00:00
|
|
|
export interface PageFormData extends MetadataFormData {
|
|
|
|
isPublished: boolean;
|
|
|
|
publicationDate: string;
|
|
|
|
seoDescription: string;
|
|
|
|
seoTitle: string;
|
|
|
|
slug: string;
|
|
|
|
title: string;
|
2020-11-19 14:42:14 +00:00
|
|
|
pageType: string;
|
2020-11-04 10:48:49 +00:00
|
|
|
}
|
|
|
|
export interface PageData extends PageFormData {
|
2020-12-16 10:53:28 +00:00
|
|
|
attributes: AttributeInput[];
|
|
|
|
content: OutputData;
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface PageSubmitData extends PageFormData {
|
|
|
|
attributes: AttributeInput[];
|
|
|
|
attributesWithNewFileValue: FormsetData<null, File>;
|
2020-11-04 10:48:49 +00:00
|
|
|
content: OutputData;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface PageUpdateHandlers {
|
|
|
|
changeMetadata: FormChange;
|
|
|
|
changeContent: RichTextEditorChange;
|
2020-11-19 14:42:14 +00:00
|
|
|
selectPageType: FormChange;
|
2020-12-16 10:53:28 +00:00
|
|
|
selectAttribute: FormsetChange<string>;
|
|
|
|
selectAttributeMulti: FormsetChange<string>;
|
|
|
|
selectAttributeFile: FormsetChange<File>;
|
2020-11-04 10:48:49 +00:00
|
|
|
}
|
|
|
|
export interface UsePageUpdateFormResult {
|
|
|
|
change: FormChange;
|
|
|
|
data: PageData;
|
2020-11-19 14:42:14 +00:00
|
|
|
pageType: PageTypeFragment;
|
2020-11-04 10:48:49 +00:00
|
|
|
handlers: PageUpdateHandlers;
|
|
|
|
hasChanged: boolean;
|
|
|
|
submit: () => void;
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface PageFormProps {
|
|
|
|
children: (props: UsePageUpdateFormResult) => React.ReactNode;
|
|
|
|
page: PageDetails_page;
|
2020-11-19 14:42:14 +00:00
|
|
|
pageTypes?: PageDetails_page_pageType[];
|
2020-11-06 10:54:03 +00:00
|
|
|
onSubmit: (data: PageData) => SubmitPromise;
|
2020-11-04 10:48:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function usePageForm(
|
|
|
|
page: PageDetails_page,
|
2020-11-19 14:42:14 +00:00
|
|
|
onSubmit: (data: PageData) => SubmitPromise,
|
|
|
|
pageTypes?: PageDetails_page_pageType[]
|
2020-11-04 10:48:49 +00:00
|
|
|
): UsePageUpdateFormResult {
|
|
|
|
const [changed, setChanged] = React.useState(false);
|
|
|
|
const triggerChange = () => setChanged(true);
|
|
|
|
|
|
|
|
const pageExists = page !== null;
|
|
|
|
|
2020-12-16 10:53:28 +00:00
|
|
|
const attributes = useFormset(getAttributeInputFromPage(page));
|
|
|
|
const attributesWithNewFileValue = useFormset<null, File>([]);
|
2020-11-19 14:42:14 +00:00
|
|
|
|
2020-11-04 10:48:49 +00:00
|
|
|
const form = useForm<PageFormData>({
|
|
|
|
isPublished: page?.isPublished,
|
|
|
|
metadata: pageExists ? page?.metadata?.map(mapMetadataItemToInput) : [],
|
2020-11-19 14:42:14 +00:00
|
|
|
pageType: page?.pageType.id || "",
|
2020-11-04 10:48:49 +00:00
|
|
|
privateMetadata: pageExists
|
|
|
|
? page?.privateMetadata?.map(mapMetadataItemToInput)
|
|
|
|
: [],
|
|
|
|
publicationDate: page?.publicationDate || "",
|
|
|
|
seoDescription: page?.seoDescription || "",
|
|
|
|
seoTitle: page?.seoTitle || "",
|
|
|
|
slug: page?.slug || "",
|
|
|
|
title: page?.title || ""
|
|
|
|
});
|
|
|
|
const [content, changeContent] = useRichText({
|
|
|
|
initial: pageExists ? page?.contentJson : null,
|
|
|
|
triggerChange
|
|
|
|
});
|
|
|
|
|
2020-11-19 14:42:14 +00:00
|
|
|
const [pageType, setPageType] = useStateFromProps<PageTypeFragment>(
|
|
|
|
page?.pageType || null
|
|
|
|
);
|
|
|
|
|
2020-11-04 10:48:49 +00:00
|
|
|
const {
|
|
|
|
isMetadataModified,
|
|
|
|
isPrivateMetadataModified,
|
|
|
|
makeChangeHandler: makeMetadataChangeHandler
|
|
|
|
} = useMetadataChangeTrigger();
|
|
|
|
|
|
|
|
const handleChange: FormChange = (event, cb) => {
|
|
|
|
form.change(event, cb);
|
|
|
|
triggerChange();
|
|
|
|
};
|
|
|
|
const changeMetadata = makeMetadataChangeHandler(handleChange);
|
2020-11-19 14:42:14 +00:00
|
|
|
const selectPageType = createPageTypeSelectHandler(
|
|
|
|
handleChange,
|
2020-12-16 10:53:28 +00:00
|
|
|
attributes.set,
|
2020-11-19 14:42:14 +00:00
|
|
|
setPageType,
|
|
|
|
pageTypes
|
|
|
|
);
|
2020-12-16 10:53:28 +00:00
|
|
|
const handleAttributeChange = createAttributeChangeHandler(
|
|
|
|
attributes.change,
|
2020-11-19 14:42:14 +00:00
|
|
|
triggerChange
|
|
|
|
);
|
2020-12-16 10:53:28 +00:00
|
|
|
const handleAttributeMultiChange = createAttributeMultiChangeHandler(
|
|
|
|
attributes.change,
|
|
|
|
attributes.data,
|
2020-11-19 14:42:14 +00:00
|
|
|
triggerChange
|
|
|
|
);
|
2020-12-16 10:53:28 +00:00
|
|
|
const handleAttributeFileChange = createAttributeFileChangeHandler(
|
|
|
|
attributes.change,
|
|
|
|
attributesWithNewFileValue.data,
|
|
|
|
attributesWithNewFileValue.add,
|
|
|
|
attributesWithNewFileValue.change,
|
|
|
|
triggerChange
|
|
|
|
);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
attributesWithNewFileValue.set([]);
|
|
|
|
}, [page]);
|
2020-11-04 10:48:49 +00:00
|
|
|
|
|
|
|
// Need to make it function to always have content.current up to date
|
|
|
|
const getData = (): PageData => ({
|
|
|
|
...form.data,
|
2020-12-16 10:53:28 +00:00
|
|
|
attributes: getAttributesDisplayData(
|
|
|
|
attributes.data,
|
|
|
|
attributesWithNewFileValue.data
|
|
|
|
),
|
2020-11-04 10:48:49 +00:00
|
|
|
content: content.current
|
|
|
|
});
|
|
|
|
|
2020-12-16 10:53:28 +00:00
|
|
|
const getSubmitData = (): PageSubmitData => ({
|
2020-11-04 10:48:49 +00:00
|
|
|
...getData(),
|
|
|
|
...getMetadata(form.data, isMetadataModified, isPrivateMetadataModified),
|
2020-12-16 10:53:28 +00:00
|
|
|
...getPublicationData(form.data),
|
|
|
|
attributesWithNewFileValue: attributesWithNewFileValue.data
|
2020-11-04 10:48:49 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
const submit = () =>
|
|
|
|
pageExists
|
|
|
|
? handleFormSubmit(getSubmitData(), onSubmit, setChanged)
|
|
|
|
: onSubmit(getSubmitData());
|
|
|
|
|
|
|
|
return {
|
|
|
|
change: handleChange,
|
|
|
|
data: getData(),
|
|
|
|
handlers: {
|
|
|
|
changeContent,
|
2020-11-19 14:42:14 +00:00
|
|
|
changeMetadata,
|
2020-12-16 10:53:28 +00:00
|
|
|
selectAttribute: handleAttributeChange,
|
|
|
|
selectAttributeFile: handleAttributeFileChange,
|
|
|
|
selectAttributeMulti: handleAttributeMultiChange,
|
2020-11-19 14:42:14 +00:00
|
|
|
selectPageType
|
2020-11-04 10:48:49 +00:00
|
|
|
},
|
|
|
|
hasChanged: changed,
|
2020-11-19 14:42:14 +00:00
|
|
|
pageType,
|
2020-11-04 10:48:49 +00:00
|
|
|
submit
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-11-19 14:42:14 +00:00
|
|
|
const PageForm: React.FC<PageFormProps> = ({
|
|
|
|
children,
|
|
|
|
page,
|
|
|
|
pageTypes,
|
|
|
|
onSubmit
|
|
|
|
}) => {
|
|
|
|
const props = usePageForm(page, onSubmit, pageTypes);
|
2020-11-04 10:48:49 +00:00
|
|
|
|
|
|
|
return <form onSubmit={props.submit}>{children(props)}</form>;
|
|
|
|
};
|
|
|
|
|
|
|
|
PageForm.displayName = "PageForm";
|
|
|
|
export default PageForm;
|