UNPKG

ra-core

Version:

Core components of react-admin, a frontend Framework for building admin applications on top of REST services, using ES6, React

211 lines 8.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useEditController = void 0; const react_1 = require("react"); const auth_1 = require("../../auth/index.cjs"); const routing_1 = require("../../routing/index.cjs"); const notification_1 = require("../../notification/index.cjs"); const dataProvider_1 = require("../../dataProvider/index.cjs"); const i18n_1 = require("../../i18n/index.cjs"); const core_1 = require("../../core/index.cjs"); const saveContext_1 = require("../saveContext/index.cjs"); /** * Prepare data for the Edit view. * * useEditController does a few things: * - it grabs the id from the URL and the resource name from the ResourceContext, * - it fetches the record via useGetOne, * - it prepares the page title. * * @param {Object} props The props passed to the Edit component. * * @return {Object} controllerProps Fetched data and callbacks for the Edit view * * @example * * import { useEditController } from 'react-admin'; * import EditView from './EditView'; * * const MyEdit = () => { * const controllerProps = useEditController({ resource: 'posts', id: 123 }); * return <EditView {...controllerProps} {...props} />; * } */ const useEditController = (props = {}) => { const { disableAuthentication = false, id: propsId, mutationMode = 'undoable', mutationOptions = {}, queryOptions = {}, redirect: redirectTo = DefaultRedirect, redirectOnError = DefaultRedirectOnError, transform, } = props; const resource = (0, core_1.useResourceContext)(props); if (!resource) { throw new Error('useEditController requires a non-empty resource prop or context'); } const { isPending: isPendingAuthenticated } = (0, auth_1.useAuthenticated)({ enabled: !disableAuthentication, }); const { isPending: isPendingCanAccess } = (0, auth_1.useRequireAccess)({ action: 'edit', resource, enabled: !disableAuthentication && !isPendingAuthenticated, }); const getRecordRepresentation = (0, core_1.useGetRecordRepresentation)(resource); const translate = (0, i18n_1.useTranslate)(); const notify = (0, notification_1.useNotify)(); const redirect = (0, routing_1.useRedirect)(); const { id: routeId } = (0, routing_1.useParams)(); if (!routeId && !propsId) { throw new Error('useEditController requires an id prop or a route with an /:id? parameter.'); } const id = propsId ?? routeId; const { meta: queryMeta, ...otherQueryOptions } = queryOptions; const { meta: mutationMeta, onSuccess, onError, ...otherMutationOptions } = mutationOptions; if ((queryMeta || mutationMeta) && JSON.stringify(queryMeta) !== JSON.stringify(mutationMeta) && redirectTo === false) { console.warn('When not redirecting after editing, query meta and mutation meta should be the same, or you will have data update issues.'); } const { registerMutationMiddleware, getMutateWithMiddlewares, unregisterMutationMiddleware, } = (0, saveContext_1.useMutationMiddlewares)(); const { data: record, error, isLoading, isFetching, isPaused, isPending, isPlaceholderData, refetch, } = (0, dataProvider_1.useGetOne)(resource, { id, meta: queryMeta }, { enabled: (!isPendingAuthenticated && !isPendingCanAccess) || disableAuthentication, onError: () => { notify('ra.notification.item_doesnt_exist', { type: 'error', }); redirect(redirectOnError, resource, id); }, refetchOnReconnect: false, refetchOnWindowFocus: false, retry: false, ...otherQueryOptions, }); // eslint-disable-next-line eqeqeq if (record && record.id && record.id != id) { throw new Error(`useEditController: Fetched record's id attribute (${record.id}) must match the requested 'id' (${id})`); } const getResourceLabel = (0, core_1.useGetResourceLabel)(); const recordRepresentation = getRecordRepresentation(record); const defaultTitle = translate(`resources.${resource}.page.edit`, { id, record, recordRepresentation: typeof recordRepresentation === 'string' ? recordRepresentation : '', _: translate('ra.page.edit', { name: getResourceLabel(resource, 1), id, record, recordRepresentation: typeof recordRepresentation === 'string' ? recordRepresentation : '', }), }); const recordCached = { id, previousData: record }; const [update, { isPending: saving }] = (0, dataProvider_1.useUpdate)(resource, recordCached, { onSuccess: async (...args) => { if (onSuccess) { return onSuccess(...args); } const [data] = args; notify(`resources.${resource}.notifications.updated`, { type: 'info', messageArgs: { smart_count: 1, _: translate('ra.notification.updated', { smart_count: 1, }), }, undoable: mutationMode === 'undoable', }); redirect(redirectTo, resource, data.id, data); }, onError: (...args) => { if (onError) { return onError(...args); } const [error] = args; // Don't trigger a notification if this is a validation error // (notification will be handled by the useNotifyIsFormInvalid hook) const validationErrors = error?.body?.errors; const hasValidationErrors = !!validationErrors && Object.keys(validationErrors).length > 0; if (!hasValidationErrors || mutationMode !== 'pessimistic') { notify(typeof error === 'string' ? error : error.message || 'ra.notification.http_error', { type: 'error', messageArgs: { _: typeof error === 'string' ? error : error instanceof Error || (typeof error === 'object' && error !== null && error.hasOwnProperty('message')) ? // @ts-ignore error.message : undefined, }, }); } }, ...otherMutationOptions, mutationMode, returnPromise: mutationMode === 'pessimistic', getMutateWithMiddlewares, }); const save = (0, react_1.useCallback)((data, { onSuccess: onSuccessFromSave, onError: onErrorFromSave, transform: transformFromSave, meta: metaFromSave, } = {}) => Promise.resolve(transformFromSave ? transformFromSave(data, { previousData: recordCached.previousData, }) : transform ? transform(data, { previousData: recordCached.previousData, }) : data).then(async (data) => { try { await update(resource, { id, data, meta: metaFromSave ?? mutationMeta, previousData: record, }, { onError: onErrorFromSave, onSuccess: onSuccessFromSave, }); } catch (error) { if (error.body?.errors != null) { return error.body.errors; } } }), [ id, mutationMeta, record, resource, transform, update, recordCached.previousData, ]); return { defaultTitle, error, isFetching, isLoading, isPaused, isPending, isPlaceholderData, mutationMode, record, redirect: redirectTo, redirectOnError, refetch, registerMutationMiddleware, resource, save, saving, unregisterMutationMiddleware, }; }; exports.useEditController = useEditController; const DefaultRedirect = 'list'; const DefaultRedirectOnError = 'list'; //# sourceMappingURL=useEditController.js.map