saleor-dashboard/src/collections/components/CollectionCreatePage/form.tsx
Dominik Żegleń 7d9441a7ec
Use esbuild-loader (#1983)
* Minor fixes for intl messages

* Add esbuild-loader
* switch from babel to esbuild-loader
* use formatjs enforce-id linter

* Generate ids for intl messages

* id format defined by idInterpolationPattern

* Modify intl messages extraction

* remove react-intl-translations-manager
* remove transpile-tx.js
* use formatjs cli

* Modify defaultMessages.json

* modify ids in defaultMessages.json with defined idInterpolationPattern

* Fix errors

* Fix page crash

* Use babel to transpile tests

* Fix useStateFromProps

* Improve render count

* Add test to useStateFromProps

* Fix reloading state buh

* Do not check if form with channels is dirty

* Stop blocking save if form has not changed

* Remove debug code

* Fix form disabling

* Fix variant selection checkbox onClick

* Update translations

* Update messages

* Use esbuild to build storybook

Co-authored-by: Bartłomiej Wiaduch <tukan2can@gmail.com>
Co-authored-by: Jakub Majorek <majorek.jakub@gmail.com>
2022-05-05 09:54:28 +02:00

159 lines
4.1 KiB
TypeScript

import { OutputData } from "@editorjs/editorjs";
import { ChannelCollectionData } from "@saleor/channels/utils";
import { createChannelsChangeHandler } from "@saleor/collections/utils";
import { COLLECTION_CREATE_FORM_ID } from "@saleor/collections/views/consts";
import { useExitFormDialog } from "@saleor/components/Form/useExitFormDialog";
import { MetadataFormData } from "@saleor/components/Metadata";
import { RichTextEditorChange } from "@saleor/components/RichTextEditor";
import useForm, {
CommonUseFormResultWithHandlers,
FormChange,
SubmitPromise
} from "@saleor/hooks/useForm";
import useHandleFormSubmit from "@saleor/hooks/useHandleFormSubmit";
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
import useRichText from "@saleor/utils/richText/useRichText";
import React, { useEffect } from "react";
export interface CollectionCreateFormData extends MetadataFormData {
backgroundImage: {
url: string;
value: string;
};
backgroundImageAlt: string;
channelListings: ChannelCollectionData[];
name: string;
slug: string;
seoDescription: string;
seoTitle: string;
}
export interface CollectionCreateData extends CollectionCreateFormData {
description: OutputData;
}
interface CollectionCreateHandlers {
changeMetadata: FormChange;
changeDescription: RichTextEditorChange;
changeChannels: (
id: string,
data: Omit<ChannelCollectionData, "name" | "id">
) => void;
}
export type UseCollectionCreateFormResult = CommonUseFormResultWithHandlers<
CollectionCreateData,
CollectionCreateHandlers
>;
export interface CollectionCreateFormProps {
currentChannels: ChannelCollectionData[];
setChannels: (data: ChannelCollectionData[]) => void;
children: (props: UseCollectionCreateFormResult) => React.ReactNode;
onSubmit: (data: CollectionCreateData) => SubmitPromise;
disabled: boolean;
}
const getInitialData = (
currentChannels: ChannelCollectionData[]
): CollectionCreateFormData => ({
backgroundImage: {
url: null,
value: null
},
backgroundImageAlt: "",
channelListings: currentChannels,
metadata: [],
name: "",
privateMetadata: [],
seoDescription: "",
seoTitle: "",
slug: ""
});
function useCollectionCreateForm(
currentChannels: ChannelCollectionData[],
setChannels: (data: ChannelCollectionData[]) => void,
onSubmit: (data: CollectionCreateData) => SubmitPromise,
disabled: boolean
): UseCollectionCreateFormResult {
const {
handleChange,
data: formData,
triggerChange,
formId,
setIsSubmitDisabled
} = useForm(getInitialData(currentChannels), undefined, {
confirmLeave: true,
formId: COLLECTION_CREATE_FORM_ID
});
const handleFormSubmit = useHandleFormSubmit({
formId,
onSubmit
});
const { setExitDialogSubmitRef } = useExitFormDialog({
formId
});
const [description, changeDescription] = useRichText({
initial: null,
triggerChange
});
const {
makeChangeHandler: makeMetadataChangeHandler
} = useMetadataChangeTrigger();
const changeMetadata = makeMetadataChangeHandler(handleChange);
// Need to make it function to always have description.current up to date
const getData = (): CollectionCreateData => ({
...formData,
description: description.current
});
const handleChannelChange = createChannelsChangeHandler(
currentChannels,
setChannels,
triggerChange
);
const submit = () => handleFormSubmit(getData());
useEffect(() => setExitDialogSubmitRef(submit), [submit]);
const isSaveDisabled = disabled;
setIsSubmitDisabled(isSaveDisabled);
return {
change: handleChange,
data: getData(),
handlers: {
changeChannels: handleChannelChange,
changeDescription,
changeMetadata
},
submit,
isSaveDisabled
};
}
const CollectionCreateForm: React.FC<CollectionCreateFormProps> = ({
currentChannels,
setChannels,
children,
onSubmit,
disabled
}) => {
const props = useCollectionCreateForm(
currentChannels,
setChannels,
onSubmit,
disabled
);
return <form onSubmit={props.submit}>{children(props)}</form>;
};
CollectionCreateForm.displayName = "CollectionCreateForm";
export default CollectionCreateForm;