import { DialogContentText } from "@material-ui/core"; import { useAttributeValueDeleteMutation } from "@saleor/attributes/mutations"; import { getAttributesAfterFileAttributesUpdate, mergeAttributeValueDeleteErrors, mergeFileUploadErrors } from "@saleor/attributes/utils/data"; import { handleDeleteMultipleAttributeValues, handleUploadMultipleFiles, prepareAttributesInput } from "@saleor/attributes/utils/handlers"; import ActionDialog from "@saleor/components/ActionDialog"; import { AttributeInput } from "@saleor/components/Attributes"; import { WindowTitle } from "@saleor/components/WindowTitle"; import { DEFAULT_INITIAL_SEARCH_DATA, VALUES_PAGINATE_BY } from "@saleor/config"; import { useFileUploadMutation } from "@saleor/files/mutations"; import { AttributeErrorFragment } from "@saleor/fragments/types/AttributeErrorFragment"; import { PageErrorFragment } from "@saleor/fragments/types/PageErrorFragment"; import { UploadErrorFragment } from "@saleor/fragments/types/UploadErrorFragment"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import { commonMessages } from "@saleor/intl"; import usePageSearch from "@saleor/searches/usePageSearch"; import useProductSearch from "@saleor/searches/useProductSearch"; import createAttributeValueSearchHandler from "@saleor/utils/handlers/attributeValueSearchHandler"; import createMetadataUpdateHandler from "@saleor/utils/handlers/metadataUpdateHandler"; import { mapEdgesToItems } from "@saleor/utils/maps"; import { useMetadataUpdate, usePrivateMetadataUpdate } from "@saleor/utils/metadata/updateMetadata"; import { getParsedDataForJsonStringField } from "@saleor/utils/richText/misc"; import React from "react"; import { FormattedMessage, useIntl } from "react-intl"; import { getStringOrPlaceholder, maybe } from "../../misc"; import { AttributeValueInput, PageInput } from "../../types/globalTypes"; import PageDetailsPage from "../components/PageDetailsPage"; import { PageData, PageSubmitData } from "../components/PageDetailsPage/form"; import { usePageRemoveMutation, usePageUpdateMutation } from "../mutations"; import { usePageDetailsQuery } from "../queries"; import { PageRemove } from "../types/PageRemove"; import { pageListUrl, pageUrl, PageUrlQueryParams } from "../urls"; export interface PageDetailsProps { id: string; params: PageUrlQueryParams; } const createPageInput = ( data: PageData, updatedFileAttributes: AttributeValueInput[] ): PageInput => ({ attributes: prepareAttributesInput({ attributes: data.attributes, updatedFileAttributes }), content: getParsedDataForJsonStringField(data.content), isPublished: data.isPublished, publicationDate: data.publicationDate, seo: { description: data.seoDescription, title: data.seoTitle }, slug: data.slug === "" ? null : data.slug, title: data.title }); export const PageDetails: React.FC = ({ id, params }) => { const navigate = useNavigator(); const notify = useNotifier(); const intl = useIntl(); const [updateMetadata] = useMetadataUpdate({}); const [updatePrivateMetadata] = usePrivateMetadataUpdate({}); const pageDetails = usePageDetailsQuery({ variables: { id, firstValues: VALUES_PAGINATE_BY } }); const [uploadFile, uploadFileOpts] = useFileUploadMutation({}); const [pageUpdate, pageUpdateOpts] = usePageUpdateMutation({}); const [ deleteAttributeValue, deleteAttributeValueOpts ] = useAttributeValueDeleteMutation({}); const [pageRemove, pageRemoveOpts] = usePageRemoveMutation({ onCompleted: (data: PageRemove) => { if (data.pageDelete.errors.length === 0) { notify({ status: "success", text: intl.formatMessage(commonMessages.savedChanges) }); navigate(pageListUrl()); } } }); const handleAssignAttributeReferenceClick = (attribute: AttributeInput) => navigate( pageUrl(id, { action: "assign-attribute-value", id: attribute.id }) ); const handleUpdate = async (data: PageSubmitData) => { let errors: Array< AttributeErrorFragment | UploadErrorFragment | PageErrorFragment > = []; const uploadFilesResult = await handleUploadMultipleFiles( data.attributesWithNewFileValue, variables => uploadFile({ variables }) ); const deleteAttributeValuesResult = await handleDeleteMultipleAttributeValues( data.attributesWithNewFileValue, pageDetails?.data?.page?.attributes, variables => deleteAttributeValue({ variables }) ); const updatedFileAttributes = getAttributesAfterFileAttributesUpdate( data.attributesWithNewFileValue, uploadFilesResult ); const updateResult = await pageUpdate({ variables: { id, input: createPageInput(data, updatedFileAttributes), firstValues: VALUES_PAGINATE_BY } }); errors = [ ...errors, ...mergeFileUploadErrors(uploadFilesResult), ...mergeAttributeValueDeleteErrors(deleteAttributeValuesResult), ...updateResult.data.pageUpdate.errors ]; return errors; }; const handleSubmit = createMetadataUpdateHandler( pageDetails.data?.page, handleUpdate, variables => updateMetadata({ variables }), variables => updatePrivateMetadata({ variables }) ); const { loadMore: loadMorePages, search: searchPages, result: searchPagesOpts } = usePageSearch({ variables: DEFAULT_INITIAL_SEARCH_DATA }); const { loadMore: loadMoreProducts, search: searchProducts, result: searchProductsOpts } = useProductSearch({ variables: DEFAULT_INITIAL_SEARCH_DATA }); const { loadMore: loadMoreAttributeValues, search: searchAttributeValues, result: searchAttributeValuesOpts } = createAttributeValueSearchHandler(DEFAULT_INITIAL_SEARCH_DATA); const attributeValues = mapEdgesToItems( searchAttributeValuesOpts?.data?.attribute.choices ); const fetchMoreReferencePages = { hasMore: searchPagesOpts.data?.search?.pageInfo?.hasNextPage, loading: searchPagesOpts.loading, onFetchMore: loadMorePages }; const fetchMoreReferenceProducts = { hasMore: searchProductsOpts.data?.search?.pageInfo?.hasNextPage, loading: searchProductsOpts.loading, onFetchMore: loadMoreProducts }; const fetchMoreAttributeValues = { hasMore: !!searchAttributeValuesOpts.data?.attribute?.choices?.pageInfo ?.hasNextPage, loading: !!searchAttributeValuesOpts.loading, onFetchMore: loadMoreAttributeValues }; return ( <> pageDetails.data.page.title)} /> navigate(pageListUrl())} onRemove={() => navigate( pageUrl(id, { action: "remove" }) ) } onSubmit={handleSubmit} assignReferencesAttributeId={ params.action === "assign-attribute-value" && params.id } onAssignReferencesClick={handleAssignAttributeReferenceClick} referencePages={mapEdgesToItems(searchPagesOpts?.data?.search)} referenceProducts={mapEdgesToItems(searchProductsOpts?.data?.search)} fetchReferencePages={searchPages} fetchMoreReferencePages={fetchMoreReferencePages} fetchReferenceProducts={searchProducts} fetchMoreReferenceProducts={fetchMoreReferenceProducts} fetchAttributeValues={searchAttributeValues} fetchMoreAttributeValues={fetchMoreAttributeValues} onCloseDialog={() => navigate(pageUrl(id))} /> navigate(pageUrl(id))} onConfirm={() => pageRemove({ variables: { id } })} variant="delete" > {getStringOrPlaceholder(pageDetails.data?.page?.title)} ) }} /> ); }; PageDetails.displayName = "PageDetails"; export default PageDetails;