Files
pole-book/server/node_modules/@strapi/content-manager/dist/admin/hooks/useDocument.js

245 lines
8.5 KiB
JavaScript

'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 yup = require('yup');
var collections = require('../constants/collections.js');
var data = require('../pages/EditView/utils/data.js');
var forms = require('../pages/EditView/utils/forms.js');
var documents = require('../services/documents.js');
var api = require('../utils/api.js');
var validation = require('../utils/validation.js');
var useContentTypeSchema = require('./useContentTypeSchema.js');
var useDocumentLayout = require('./useDocumentLayout.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);
/* -------------------------------------------------------------------------------------------------
* useDocument
* -----------------------------------------------------------------------------------------------*/ /**
* @alpha
* @public
* @description Returns a document based on the model, collection type & id passed as arguments.
* Also extracts its schema from the redux cache to be used for creating a validation schema.
* @example
* ```tsx
* const { id, model, collectionType } = useParams<{ id: string; model: string; collectionType: string }>();
*
* if(!model || !collectionType) return null;
*
* const { document, isLoading, validate } = useDocument({ documentId: id, model, collectionType, params: { locale: 'en-GB' } })
* const { update } = useDocumentActions()
*
* const onSubmit = async (document: Document) => {
* const errors = validate(document);
*
* if(errors) {
* // handle errors
* }
*
* await update({ collectionType, model, id }, document)
* }
* ```
*
* @see {@link https://contributor.strapi.io/docs/core/content-manager/hooks/use-document} for more information
*/ const useDocument = (args, opts)=>{
const { toggleNotification } = strapiAdmin.useNotification();
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
const { formatMessage } = reactIntl.useIntl();
const { currentData: data$1, isLoading: isLoadingDocument, isFetching: isFetchingDocument, error, refetch } = documents.useGetDocumentQuery(args, {
...opts,
skip: !args.documentId && args.collectionType !== collections.SINGLE_TYPES || opts?.skip
});
const document = data$1?.data;
const meta = data$1?.meta;
const { components, schema, schemas, isLoading: isLoadingSchema } = useContentTypeSchema.useContentTypeSchema(args.model);
const isSingleType = schema?.kind === 'singleType';
const getTitle = (mainField)=>{
// Always use mainField if it's not an id
if (mainField !== 'id' && document?.[mainField]) {
return document[mainField];
}
// When it's a singleType without a mainField, use the contentType displayName
if (isSingleType && schema?.info.displayName) {
return schema.info.displayName;
}
// Otherwise, use a fallback
return formatMessage({
id: 'content-manager.containers.untitled',
defaultMessage: 'Untitled'
});
};
React__namespace.useEffect(()=>{
if (error) {
toggleNotification({
type: 'danger',
message: formatAPIError(error)
});
}
}, [
toggleNotification,
error,
formatAPIError,
args.collectionType
]);
const validationSchema = React__namespace.useMemo(()=>{
if (!schema) {
return null;
}
return validation.createYupSchema(schema.attributes, components);
}, [
schema,
components
]);
const validate = React__namespace.useCallback((document)=>{
if (!validationSchema) {
throw new Error('There is no validation schema generated, this is likely due to the schema not being loaded yet.');
}
try {
validationSchema.validateSync(document, {
abortEarly: false,
strict: true
});
return null;
} catch (error) {
if (error instanceof yup.ValidationError) {
return strapiAdmin.getYupValidationErrors(error);
}
throw error;
}
}, [
validationSchema
]);
/**
* Here we prepare the form for editing, we need to:
* - remove prohibited fields from the document (passwords | ADD YOURS WHEN THERES A NEW ONE)
* - swap out count objects on relations for empty arrays
* - set __temp_key__ on array objects for drag & drop
*
* We also prepare the form for new documents, so we need to:
* - set default values on fields
*/ const getInitialFormValues = React__namespace.useCallback((isCreatingDocument = false)=>{
if (!document && !isCreatingDocument && !isSingleType || !schema) {
return undefined;
}
/**
* Check that we have an ID so we know the
* document has been created in some way.
*/ const form = document?.id ? document : forms.createDefaultForm(schema, components);
return data.transformDocument(schema, components)(form);
}, [
document,
isSingleType,
schema,
components
]);
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
const hasError = !!error;
return {
components,
document,
meta,
isLoading,
hasError,
schema,
schemas,
validate,
getTitle,
getInitialFormValues,
refetch
};
};
/* -------------------------------------------------------------------------------------------------
* useDoc
* -----------------------------------------------------------------------------------------------*/ /**
* @internal this hook uses the router to extract the model, collection type & id from the url.
* therefore, it shouldn't be used outside of the content-manager because it won't work as intended.
*/ const useDoc = ()=>{
const { id, slug, collectionType, origin } = reactRouterDom.useParams();
const [{ query }] = strapiAdmin.useQueryParams();
const params = React__namespace.useMemo(()=>api.buildValidParams(query), [
query
]);
if (!collectionType) {
throw new Error('Could not find collectionType in url params');
}
if (!slug) {
throw new Error('Could not find model in url params');
}
const document = useDocument({
documentId: origin || id,
model: slug,
collectionType,
params
}, {
skip: id === 'create' || !origin && !id && collectionType !== collections.SINGLE_TYPES
});
const returnId = origin || id === 'create' ? undefined : id;
return {
collectionType,
model: slug,
id: returnId,
...document
};
};
/**
* @public
* @experimental
* Content manager context hooks for plugin development.
* Make sure to use this hook inside the content manager.
*/ const useContentManagerContext = ()=>{
const { collectionType, model, id, components, isLoading: isLoadingDoc, schema, schemas } = useDoc();
const layout = useDocumentLayout.useDocumentLayout(model);
const form = strapiAdmin.useForm('useContentManagerContext', (state)=>state);
const isSingleType = collectionType === collections.SINGLE_TYPES;
const slug = model;
const isCreatingEntry = id === 'create';
useContentTypeSchema.useContentTypeSchema();
const isLoading = isLoadingDoc || layout.isLoading;
const error = layout.error;
return {
error,
isLoading,
// Base metadata
model,
collectionType,
id,
slug,
isCreatingEntry,
isSingleType,
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
// All schema infos
components,
contentType: schema,
contentTypes: schemas,
// Form state
form,
// layout infos
layout
};
};
exports.useContentManagerContext = useContentManagerContext;
exports.useDoc = useDoc;
exports.useDocument = useDocument;
//# sourceMappingURL=useDocument.js.map