119 lines
3.5 KiB
TypeScript
119 lines
3.5 KiB
TypeScript
![]() |
import { OutputData } from "@editorjs/editorjs";
|
||
|
import { MetadataFormData } from "@saleor/components/Metadata";
|
||
|
import { RichTextEditorChange } from "@saleor/components/RichTextEditor";
|
||
|
import useForm, { FormChange } from "@saleor/hooks/useForm";
|
||
|
import { PageDetails_page } from "@saleor/pages/types/PageDetails";
|
||
|
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";
|
||
|
import React from "react";
|
||
|
|
||
|
export interface PageFormData extends MetadataFormData {
|
||
|
isPublished: boolean;
|
||
|
publicationDate: string;
|
||
|
seoDescription: string;
|
||
|
seoTitle: string;
|
||
|
slug: string;
|
||
|
title: string;
|
||
|
}
|
||
|
export interface PageData extends PageFormData {
|
||
|
content: OutputData;
|
||
|
}
|
||
|
|
||
|
interface PageUpdateHandlers {
|
||
|
changeMetadata: FormChange;
|
||
|
changeContent: RichTextEditorChange;
|
||
|
}
|
||
|
export interface UsePageUpdateFormResult {
|
||
|
change: FormChange;
|
||
|
data: PageData;
|
||
|
handlers: PageUpdateHandlers;
|
||
|
hasChanged: boolean;
|
||
|
submit: () => void;
|
||
|
}
|
||
|
|
||
|
export interface PageFormProps {
|
||
|
children: (props: UsePageUpdateFormResult) => React.ReactNode;
|
||
|
page: PageDetails_page;
|
||
|
onSubmit: (data: PageData) => Promise<any[]>;
|
||
|
}
|
||
|
|
||
|
function usePageForm(
|
||
|
page: PageDetails_page,
|
||
|
onSubmit: (data: PageData) => Promise<any[]>
|
||
|
): UsePageUpdateFormResult {
|
||
|
const [changed, setChanged] = React.useState(false);
|
||
|
const triggerChange = () => setChanged(true);
|
||
|
|
||
|
const pageExists = page !== null;
|
||
|
|
||
|
const form = useForm<PageFormData>({
|
||
|
isPublished: page?.isPublished,
|
||
|
metadata: pageExists ? page?.metadata?.map(mapMetadataItemToInput) : [],
|
||
|
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
|
||
|
});
|
||
|
|
||
|
const {
|
||
|
isMetadataModified,
|
||
|
isPrivateMetadataModified,
|
||
|
makeChangeHandler: makeMetadataChangeHandler
|
||
|
} = useMetadataChangeTrigger();
|
||
|
|
||
|
const handleChange: FormChange = (event, cb) => {
|
||
|
form.change(event, cb);
|
||
|
triggerChange();
|
||
|
};
|
||
|
const changeMetadata = makeMetadataChangeHandler(handleChange);
|
||
|
|
||
|
// Need to make it function to always have content.current up to date
|
||
|
const getData = (): PageData => ({
|
||
|
...form.data,
|
||
|
content: content.current
|
||
|
});
|
||
|
|
||
|
const getSubmitData = (): PageData => ({
|
||
|
...getData(),
|
||
|
...getMetadata(form.data, isMetadataModified, isPrivateMetadataModified),
|
||
|
...getPublicationData(form.data)
|
||
|
});
|
||
|
|
||
|
const submit = () =>
|
||
|
pageExists
|
||
|
? handleFormSubmit(getSubmitData(), onSubmit, setChanged)
|
||
|
: onSubmit(getSubmitData());
|
||
|
|
||
|
return {
|
||
|
change: handleChange,
|
||
|
data: getData(),
|
||
|
handlers: {
|
||
|
changeContent,
|
||
|
changeMetadata
|
||
|
},
|
||
|
hasChanged: changed,
|
||
|
submit
|
||
|
};
|
||
|
}
|
||
|
|
||
|
const PageForm: React.FC<PageFormProps> = ({ children, page, onSubmit }) => {
|
||
|
const props = usePageForm(page, onSubmit);
|
||
|
|
||
|
return <form onSubmit={props.submit}>{children(props)}</form>;
|
||
|
};
|
||
|
|
||
|
PageForm.displayName = "PageForm";
|
||
|
export default PageForm;
|