'use strict'; var React = require('react'); var strapiAdmin = require('@strapi/admin/strapi-admin'); var reactIntl = require('react-intl'); var reactRouterDom = require('react-router-dom'); var RelationModal = require('../pages/EditView/components/FormInputs/Relations/RelationModal.js'); var Preview = require('../preview/pages/Preview.js'); var documents = require('../services/documents.js'); var translations = require('../utils/translations.js'); function _interopNamespaceDefault(e) { var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React); const DEFAULT_UNEXPECTED_ERROR_MSG = { id: 'notification.error', defaultMessage: 'An error occurred, please try again' }; /** * @alpha * @public * @description Contains all the operations that can be performed on a single document. * Designed to be able to be used anywhere within a Strapi app. The hooks will handle * notifications should the operation fail, however the response is always returned incase * the user needs to handle side-effects. * @example * ```tsx * import { Form } from '@strapi/admin/admin'; * * const { id, model, collectionType } = useParams<{ id: string; model: string; collectionType: string }>(); * const { update } = useDocumentActions(); * * const handleSubmit = async (data) => { * await update({ collectionType, model, documentId: id }, data); * } * * return
* ``` * * @see {@link https://contributor.strapi.io/docs/core/content-manager/hooks/use-document-operations} for more information */ const useDocumentActions = ()=>{ const { toggleNotification } = strapiAdmin.useNotification(); const { formatMessage } = reactIntl.useIntl(); const { trackUsage } = strapiAdmin.useTracking(); const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(); const navigate = reactRouterDom.useNavigate(); const setCurrentStep = strapiAdmin.useGuidedTour('useDocumentActions', (state)=>state.setCurrentStep); // Get metadata from context providers for tracking purposes const previewContext = Preview.usePreviewContext('useDocumentActions', ()=>true, false); const relationContext = RelationModal.useRelationModal('useDocumentActions', ()=>true, false); const fromPreview = previewContext != undefined; const fromRelationModal = relationContext != undefined; const [deleteDocument, { isLoading: isDeleting }] = documents.useDeleteDocumentMutation(); const _delete = React__namespace.useCallback(async ({ collectionType, model, documentId, params }, trackerProperty)=>{ try { trackUsage('willDeleteEntry', trackerProperty); const res = await deleteDocument({ collectionType, model, documentId, params }); if ('error' in res) { toggleNotification({ type: 'danger', message: formatAPIError(res.error) }); return { error: res.error }; } toggleNotification({ type: 'success', message: formatMessage({ id: translations.getTranslation('success.record.delete'), defaultMessage: 'Deleted document' }) }); trackUsage('didDeleteEntry', trackerProperty); return res.data; } catch (err) { toggleNotification({ type: 'danger', message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG) }); trackUsage('didNotDeleteEntry', { error: err, ...trackerProperty }); throw err; } }, [ trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError ]); const [deleteManyDocuments, { isLoading: isDeletingMany }] = documents.useDeleteManyDocumentsMutation(); const deleteMany = React__namespace.useCallback(async ({ model, documentIds, params })=>{ try { trackUsage('willBulkDeleteEntries'); const res = await deleteManyDocuments({ model, documentIds, params }); if ('error' in res) { toggleNotification({ type: 'danger', message: formatAPIError(res.error) }); return { error: res.error }; } toggleNotification({ type: 'success', title: formatMessage({ id: translations.getTranslation('success.records.delete'), defaultMessage: 'Successfully deleted.' }), message: '' }); trackUsage('didBulkDeleteEntries'); return res.data; } catch (err) { toggleNotification({ type: 'danger', message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG) }); trackUsage('didNotBulkDeleteEntries'); throw err; } }, [ trackUsage, deleteManyDocuments, toggleNotification, formatMessage, formatAPIError ]); const [discardDocument, { isLoading: isDiscardingDocument }] = documents.useDiscardDocumentMutation(); const discard = React__namespace.useCallback(async ({ collectionType, model, documentId, params })=>{ try { const res = await discardDocument({ collectionType, model, documentId, params }); if ('error' in res) { toggleNotification({ type: 'danger', message: formatAPIError(res.error) }); return { error: res.error }; } toggleNotification({ type: 'success', message: formatMessage({ id: 'content-manager.success.record.discard', defaultMessage: 'Changes discarded' }) }); return res.data; } catch (err) { toggleNotification({ type: 'danger', message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG) }); throw err; } }, [ discardDocument, formatAPIError, formatMessage, toggleNotification ]); const [publishDocument, { isLoading: isPublishing }] = documents.usePublishDocumentMutation(); const publish = React__namespace.useCallback(async ({ collectionType, model, documentId, params }, data)=>{ try { trackUsage('willPublishEntry', { documentId }); const res = await publishDocument({ collectionType, model, documentId, data, params }); if ('error' in res) { toggleNotification({ type: 'danger', message: formatAPIError(res.error) }); return { error: res.error }; } trackUsage('didPublishEntry', { documentId, fromPreview, fromRelationModal }); toggleNotification({ type: 'success', message: formatMessage({ id: translations.getTranslation('success.record.publish'), defaultMessage: 'Published document' }) }); return res.data; } catch (err) { toggleNotification({ type: 'danger', message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG) }); throw err; } }, [ trackUsage, publishDocument, fromPreview, fromRelationModal, toggleNotification, formatMessage, formatAPIError ]); const [publishManyDocuments, { isLoading: isPublishingMany }] = documents.usePublishManyDocumentsMutation(); const publishMany = React__namespace.useCallback(async ({ model, documentIds, params })=>{ try { // TODO Confirm tracking events for bulk publish? const res = await publishManyDocuments({ model, documentIds, params }); if ('error' in res) { toggleNotification({ type: 'danger', message: formatAPIError(res.error) }); return { error: res.error }; } toggleNotification({ type: 'success', message: formatMessage({ id: translations.getTranslation('success.record.publish'), defaultMessage: 'Published document' }) }); return res.data; } catch (err) { toggleNotification({ type: 'danger', message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG) }); throw err; } }, [ // trackUsage, publishManyDocuments, toggleNotification, formatMessage, formatAPIError ]); const [updateDocument, { isLoading: isUpdating }] = documents.useUpdateDocumentMutation(); const update = React__namespace.useCallback(async ({ collectionType, model, documentId, params }, data, trackerProperty)=>{ try { trackUsage('willEditEntry', trackerProperty); const res = await updateDocument({ collectionType, model, documentId, data, params }); if ('error' in res) { toggleNotification({ type: 'danger', message: formatAPIError(res.error) }); trackUsage('didNotEditEntry', { error: res.error, ...trackerProperty }); return { error: res.error }; } trackUsage('didEditEntry', { ...trackerProperty, documentId: res.data.data.documentId, fromPreview, fromRelationModal }); toggleNotification({ type: 'success', message: formatMessage({ id: translations.getTranslation('success.record.save'), defaultMessage: 'Saved document' }) }); return res.data; } catch (err) { trackUsage('didNotEditEntry', { error: err, ...trackerProperty }); toggleNotification({ type: 'danger', message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG) }); throw err; } }, [ trackUsage, updateDocument, fromPreview, fromRelationModal, toggleNotification, formatMessage, formatAPIError ]); const [unpublishDocument] = documents.useUnpublishDocumentMutation(); const unpublish = React__namespace.useCallback(async ({ collectionType, model, documentId, params }, discardDraft = false)=>{ try { trackUsage('willUnpublishEntry'); const res = await unpublishDocument({ collectionType, model, documentId, params, data: { discardDraft } }); if ('error' in res) { toggleNotification({ type: 'danger', message: formatAPIError(res.error) }); return { error: res.error }; } trackUsage('didUnpublishEntry'); toggleNotification({ type: 'success', message: formatMessage({ id: translations.getTranslation('success.record.unpublish'), defaultMessage: 'Unpublished document' }) }); return res.data; } catch (err) { toggleNotification({ type: 'danger', message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG) }); throw err; } }, [ trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError ]); const [unpublishManyDocuments, { isLoading: isUnpublishingMany }] = documents.useUnpublishManyDocumentsMutation(); const unpublishMany = React__namespace.useCallback(async ({ model, documentIds, params })=>{ try { trackUsage('willBulkUnpublishEntries'); const res = await unpublishManyDocuments({ model, documentIds, params }); if ('error' in res) { toggleNotification({ type: 'danger', message: formatAPIError(res.error) }); return { error: res.error }; } trackUsage('didBulkUnpublishEntries'); toggleNotification({ type: 'success', title: formatMessage({ id: translations.getTranslation('success.records.unpublish'), defaultMessage: 'Successfully unpublished.' }), message: '' }); return res.data; } catch (err) { toggleNotification({ type: 'danger', message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG) }); trackUsage('didNotBulkUnpublishEntries'); throw err; } }, [ trackUsage, unpublishManyDocuments, toggleNotification, formatMessage, formatAPIError ]); const [createDocument] = documents.useCreateDocumentMutation(); const create = React__namespace.useCallback(async ({ model, params }, data, trackerProperty)=>{ try { const res = await createDocument({ model, data, params }); if ('error' in res) { toggleNotification({ type: 'danger', message: formatAPIError(res.error) }); trackUsage('didNotCreateEntry', { error: res.error, ...trackerProperty }); return { error: res.error }; } trackUsage('didCreateEntry', { ...trackerProperty, documentId: res.data.data.documentId, fromPreview, fromRelationModal }); toggleNotification({ type: 'success', message: formatMessage({ id: translations.getTranslation('success.record.save'), defaultMessage: 'Saved document' }) }); setCurrentStep('contentManager.success'); return res.data; } catch (err) { toggleNotification({ type: 'danger', message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG) }); trackUsage('didNotCreateEntry', { error: err, ...trackerProperty }); throw err; } }, [ createDocument, formatAPIError, formatMessage, fromPreview, fromRelationModal, setCurrentStep, toggleNotification, trackUsage ]); const [autoCloneDocument] = documents.useAutoCloneDocumentMutation(); const autoClone = React__namespace.useCallback(async ({ model, sourceId })=>{ try { const res = await autoCloneDocument({ model, sourceId }); if ('error' in res) { return { error: res.error }; } toggleNotification({ type: 'success', message: formatMessage({ id: translations.getTranslation('success.record.clone'), defaultMessage: 'Cloned document' }) }); return res.data; } catch (err) { toggleNotification({ type: 'danger', message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG) }); throw err; } }, [ autoCloneDocument, formatMessage, toggleNotification ]); const [cloneDocument] = documents.useCloneDocumentMutation(); const clone = React__namespace.useCallback(async ({ model, documentId, params }, body, trackerProperty)=>{ try { const { id: _id, ...restBody } = body; /** * If we're cloning we want to post directly to this endpoint * so that the relations even if they're not listed in the EditView * are correctly attached to the entry. */ const res = await cloneDocument({ model, sourceId: documentId, data: restBody, params }); if ('error' in res) { toggleNotification({ type: 'danger', message: formatAPIError(res.error) }); trackUsage('didNotCreateEntry', { error: res.error, ...trackerProperty }); return { error: res.error }; } trackUsage('didCreateEntry', trackerProperty); toggleNotification({ type: 'success', message: formatMessage({ id: translations.getTranslation('success.record.clone'), defaultMessage: 'Cloned document' }) }); // Redirect to normal edit view navigate(`../../${res.data.data.documentId}`, { relative: 'path' }); return res.data; } catch (err) { toggleNotification({ type: 'danger', message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG) }); trackUsage('didNotCreateEntry', { error: err, ...trackerProperty }); throw err; } }, [ cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate ]); const [getDoc] = documents.useLazyGetDocumentQuery(); const getDocument = React__namespace.useCallback(async (args)=>{ const { data } = await getDoc(args); return data; }, [ getDoc ]); return { isLoading: isPublishing || isUpdating || isDiscardingDocument || isDeleting || isDeletingMany || isUnpublishingMany || isPublishingMany, autoClone, clone, create, delete: _delete, deleteMany, discard, getDocument, publish, publishMany, unpublish, unpublishMany, update }; }; exports.useDocumentActions = useDocumentActions; //# sourceMappingURL=useDocumentActions.js.map