{"version":3,"file":"useDocument.mjs","sources":["../../../admin/src/hooks/useDocument.ts"],"sourcesContent":["/**\n * This hook doesn't use a context provider because we fetch directly from the server,\n * this sounds expensive but actually, it's really not. Because we have redux-toolkit-query\n * being a cache layer so if nothing invalidates the cache, we don't fetch again.\n */\n\nimport * as React from 'react';\n\nimport {\n useNotification,\n useAPIErrorHandler,\n useQueryParams,\n FormErrors,\n getYupValidationErrors,\n useForm,\n} from '@strapi/admin/strapi-admin';\nimport { useIntl } from 'react-intl';\nimport { useParams } from 'react-router-dom';\nimport { ValidationError } from 'yup';\n\nimport { SINGLE_TYPES } from '../constants/collections';\nimport { type AnyData, transformDocument } from '../pages/EditView/utils/data';\nimport { createDefaultForm } from '../pages/EditView/utils/forms';\nimport { useGetDocumentQuery } from '../services/documents';\nimport { buildValidParams } from '../utils/api';\nimport { createYupSchema } from '../utils/validation';\n\nimport { useContentTypeSchema, ComponentsDictionary } from './useContentTypeSchema';\nimport { useDocumentLayout } from './useDocumentLayout';\n\nimport type { FindOne } from '../../../shared/contracts/collection-types';\nimport type { ContentType } from '../../../shared/contracts/content-types';\nimport type { Modules } from '@strapi/types';\n\ninterface UseDocumentArgs {\n collectionType: string;\n model: string;\n documentId?: string;\n params?: object;\n}\n\ntype UseDocumentOpts = Parameters[1];\n\ntype Document = FindOne.Response['data'];\n\ntype Schema = ContentType;\n\ntype UseDocument = (\n args: UseDocumentArgs,\n opts?: UseDocumentOpts\n) => {\n /**\n * These are the schemas of the components used in the content type, organised\n * by their uid.\n */\n components: ComponentsDictionary;\n document?: Document;\n meta?: FindOne.Response['meta'];\n isLoading: boolean;\n /**\n * This is the schema of the content type, it is not the same as the layout.\n */\n schema?: Schema;\n schemas?: Schema[];\n hasError?: boolean;\n refetch: () => void;\n validate: (document: Document) => null | FormErrors;\n /**\n * Get the document's title\n */\n getTitle: (mainField: string) => string;\n /**\n * Get the initial form values for the document\n */\n getInitialFormValues: (isCreatingDocument?: boolean) => AnyData | undefined;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * useDocument\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * @alpha\n * @public\n * @description Returns a document based on the model, collection type & id passed as arguments.\n * Also extracts its schema from the redux cache to be used for creating a validation schema.\n * @example\n * ```tsx\n * const { id, model, collectionType } = useParams<{ id: string; model: string; collectionType: string }>();\n *\n * if(!model || !collectionType) return null;\n *\n * const { document, isLoading, validate } = useDocument({ documentId: id, model, collectionType, params: { locale: 'en-GB' } })\n * const { update } = useDocumentActions()\n *\n * const onSubmit = async (document: Document) => {\n * const errors = validate(document);\n *\n * if(errors) {\n * // handle errors\n * }\n *\n * await update({ collectionType, model, id }, document)\n * }\n * ```\n *\n * @see {@link https://contributor.strapi.io/docs/core/content-manager/hooks/use-document} for more information\n */\nconst useDocument: UseDocument = (args, opts) => {\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();\n const { formatMessage } = useIntl();\n\n const {\n currentData: data,\n isLoading: isLoadingDocument,\n isFetching: isFetchingDocument,\n error,\n refetch,\n } = useGetDocumentQuery(args, {\n ...opts,\n skip: (!args.documentId && args.collectionType !== SINGLE_TYPES) || opts?.skip,\n });\n const document = data?.data;\n const meta = data?.meta;\n\n const {\n components,\n schema,\n schemas,\n isLoading: isLoadingSchema,\n } = useContentTypeSchema(args.model);\n const isSingleType = schema?.kind === 'singleType';\n\n const getTitle = (mainField: string) => {\n // Always use mainField if it's not an id\n if (mainField !== 'id' && document?.[mainField]) {\n return document[mainField];\n }\n\n // When it's a singleType without a mainField, use the contentType displayName\n if (isSingleType && schema?.info.displayName) {\n return schema.info.displayName;\n }\n\n // Otherwise, use a fallback\n return formatMessage({\n id: 'content-manager.containers.untitled',\n defaultMessage: 'Untitled',\n });\n };\n\n React.useEffect(() => {\n if (error) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n }\n }, [toggleNotification, error, formatAPIError, args.collectionType]);\n\n const validationSchema = React.useMemo(() => {\n if (!schema) {\n return null;\n }\n\n return createYupSchema(schema.attributes, components);\n }, [schema, components]);\n\n const validate = React.useCallback(\n (document: Modules.Documents.AnyDocument): FormErrors | null => {\n if (!validationSchema) {\n throw new Error(\n 'There is no validation schema generated, this is likely due to the schema not being loaded yet.'\n );\n }\n\n try {\n validationSchema.validateSync(document, { abortEarly: false, strict: true });\n return null;\n } catch (error) {\n if (error instanceof ValidationError) {\n return getYupValidationErrors(error);\n }\n\n throw error;\n }\n },\n [validationSchema]\n );\n\n /**\n * Here we prepare the form for editing, we need to:\n * - remove prohibited fields from the document (passwords | ADD YOURS WHEN THERES A NEW ONE)\n * - swap out count objects on relations for empty arrays\n * - set __temp_key__ on array objects for drag & drop\n *\n * We also prepare the form for new documents, so we need to:\n * - set default values on fields\n */\n const getInitialFormValues = React.useCallback(\n (isCreatingDocument: boolean = false) => {\n if ((!document && !isCreatingDocument && !isSingleType) || !schema) {\n return undefined;\n }\n\n /**\n * Check that we have an ID so we know the\n * document has been created in some way.\n */\n const form = document?.id ? document : createDefaultForm(schema, components);\n\n return transformDocument(schema, components)(form);\n },\n [document, isSingleType, schema, components]\n );\n\n const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;\n const hasError = !!error;\n\n return {\n components,\n document,\n meta,\n isLoading,\n hasError,\n schema,\n schemas,\n validate,\n getTitle,\n getInitialFormValues,\n refetch,\n } satisfies ReturnType;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * useDoc\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * @internal this hook uses the router to extract the model, collection type & id from the url.\n * therefore, it shouldn't be used outside of the content-manager because it won't work as intended.\n */\nconst useDoc = () => {\n const { id, slug, collectionType, origin } = useParams<{\n id: string;\n origin: string;\n slug: string;\n collectionType: string;\n }>();\n const [{ query }] = useQueryParams();\n const params = React.useMemo(() => buildValidParams(query), [query]);\n\n if (!collectionType) {\n throw new Error('Could not find collectionType in url params');\n }\n\n if (!slug) {\n throw new Error('Could not find model in url params');\n }\n\n const document = useDocument(\n { documentId: origin || id, model: slug, collectionType, params },\n {\n skip: id === 'create' || (!origin && !id && collectionType !== SINGLE_TYPES),\n }\n );\n\n const returnId = origin || id === 'create' ? undefined : id;\n\n return {\n collectionType,\n model: slug,\n id: returnId,\n ...document,\n };\n};\n\n/**\n * @public\n * @experimental\n * Content manager context hooks for plugin development.\n * Make sure to use this hook inside the content manager.\n */\nconst useContentManagerContext = () => {\n const {\n collectionType,\n model,\n id,\n components,\n isLoading: isLoadingDoc,\n schema,\n schemas,\n } = useDoc();\n\n const layout = useDocumentLayout(model);\n\n const form = useForm('useContentManagerContext', (state) => state);\n\n const isSingleType = collectionType === SINGLE_TYPES;\n const slug = model;\n const isCreatingEntry = id === 'create';\n\n const {} = useContentTypeSchema();\n\n const isLoading = isLoadingDoc || layout.isLoading;\n const error = layout.error;\n\n return {\n error,\n isLoading,\n\n // Base metadata\n model,\n collectionType,\n id,\n slug,\n isCreatingEntry,\n isSingleType,\n hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,\n\n // All schema infos\n components,\n contentType: schema,\n contentTypes: schemas,\n\n // Form state\n form,\n\n // layout infos\n layout,\n };\n};\n\nexport { useDocument, useDoc, useContentManagerContext };\nexport type { UseDocument, UseDocumentArgs, Document, Schema, ComponentsDictionary };\n"],"names":["useDocument","args","opts","toggleNotification","useNotification","_unstableFormatAPIError","formatAPIError","useAPIErrorHandler","formatMessage","useIntl","currentData","data","isLoading","isLoadingDocument","isFetching","isFetchingDocument","error","refetch","useGetDocumentQuery","skip","documentId","collectionType","SINGLE_TYPES","document","meta","components","schema","schemas","isLoadingSchema","useContentTypeSchema","model","isSingleType","kind","getTitle","mainField","info","displayName","id","defaultMessage","React","useEffect","type","message","validationSchema","useMemo","createYupSchema","attributes","validate","useCallback","Error","validateSync","abortEarly","strict","ValidationError","getYupValidationErrors","getInitialFormValues","isCreatingDocument","undefined","form","createDefaultForm","transformDocument","hasError","useDoc","slug","origin","useParams","query","useQueryParams","params","buildValidParams","returnId","useContentManagerContext","isLoadingDoc","layout","useDocumentLayout","useForm","state","isCreatingEntry","hasDraftAndPublish","options","draftAndPublish","contentType","contentTypes"],"mappings":";;;;;;;;;;;;;;AA6EA;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA+BA,MAAMA,WAA2B,GAAA,CAACC,IAAMC,EAAAA,IAAAA,GAAAA;IACtC,MAAM,EAAEC,kBAAkB,EAAE,GAAGC,eAAAA,EAAAA;AAC/B,IAAA,MAAM,EAAEC,uBAAAA,EAAyBC,cAAc,EAAE,GAAGC,kBAAAA,EAAAA;IACpD,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAE1B,IAAA,MAAM,EACJC,WAAaC,EAAAA,IAAI,EACjBC,SAAAA,EAAWC,iBAAiB,EAC5BC,UAAAA,EAAYC,kBAAkB,EAC9BC,KAAK,EACLC,OAAO,EACR,GAAGC,oBAAoBjB,IAAM,EAAA;AAC5B,QAAA,GAAGC,IAAI;QACPiB,IAAM,EAAC,CAAClB,IAAKmB,CAAAA,UAAU,IAAInB,IAAKoB,CAAAA,cAAc,KAAKC,YAAAA,IAAiBpB,IAAMiB,EAAAA;AAC5E,KAAA,CAAA;AACA,IAAA,MAAMI,WAAWZ,IAAMA,EAAAA,IAAAA;AACvB,IAAA,MAAMa,OAAOb,IAAMa,EAAAA,IAAAA;AAEnB,IAAA,MAAM,EACJC,UAAU,EACVC,MAAM,EACNC,OAAO,EACPf,SAAAA,EAAWgB,eAAe,EAC3B,GAAGC,oBAAAA,CAAqB5B,KAAK6B,KAAK,CAAA;IACnC,MAAMC,YAAAA,GAAeL,QAAQM,IAAS,KAAA,YAAA;AAEtC,IAAA,MAAMC,WAAW,CAACC,SAAAA,GAAAA;;AAEhB,QAAA,IAAIA,SAAc,KAAA,IAAA,IAAQX,QAAU,GAACW,UAAU,EAAE;YAC/C,OAAOX,QAAQ,CAACW,SAAU,CAAA;AAC5B;;QAGA,IAAIH,YAAAA,IAAgBL,MAAQS,EAAAA,IAAAA,CAAKC,WAAa,EAAA;YAC5C,OAAOV,MAAAA,CAAOS,IAAI,CAACC,WAAW;AAChC;;AAGA,QAAA,OAAO5B,aAAc,CAAA;YACnB6B,EAAI,EAAA,qCAAA;YACJC,cAAgB,EAAA;AAClB,SAAA,CAAA;AACF,KAAA;AAEAC,IAAAA,KAAAA,CAAMC,SAAS,CAAC,IAAA;AACd,QAAA,IAAIxB,KAAO,EAAA;YACTb,kBAAmB,CAAA;gBACjBsC,IAAM,EAAA,QAAA;AACNC,gBAAAA,OAAAA,EAASpC,cAAeU,CAAAA,KAAAA;AAC1B,aAAA,CAAA;AACF;KACC,EAAA;AAACb,QAAAA,kBAAAA;AAAoBa,QAAAA,KAAAA;AAAOV,QAAAA,cAAAA;AAAgBL,QAAAA,IAAAA,CAAKoB;AAAe,KAAA,CAAA;IAEnE,MAAMsB,gBAAAA,GAAmBJ,KAAMK,CAAAA,OAAO,CAAC,IAAA;AACrC,QAAA,IAAI,CAAClB,MAAQ,EAAA;YACX,OAAO,IAAA;AACT;QAEA,OAAOmB,eAAAA,CAAgBnB,MAAOoB,CAAAA,UAAU,EAAErB,UAAAA,CAAAA;KACzC,EAAA;AAACC,QAAAA,MAAAA;AAAQD,QAAAA;AAAW,KAAA,CAAA;AAEvB,IAAA,MAAMsB,QAAWR,GAAAA,KAAAA,CAAMS,WAAW,CAChC,CAACzB,QAAAA,GAAAA;AACC,QAAA,IAAI,CAACoB,gBAAkB,EAAA;AACrB,YAAA,MAAM,IAAIM,KACR,CAAA,iGAAA,CAAA;AAEJ;QAEA,IAAI;YACFN,gBAAiBO,CAAAA,YAAY,CAAC3B,QAAU,EAAA;gBAAE4B,UAAY,EAAA,KAAA;gBAAOC,MAAQ,EAAA;AAAK,aAAA,CAAA;YAC1E,OAAO,IAAA;AACT,SAAA,CAAE,OAAOpC,KAAO,EAAA;AACd,YAAA,IAAIA,iBAAiBqC,eAAiB,EAAA;AACpC,gBAAA,OAAOC,sBAAuBtC,CAAAA,KAAAA,CAAAA;AAChC;YAEA,MAAMA,KAAAA;AACR;KAEF,EAAA;AAAC2B,QAAAA;AAAiB,KAAA,CAAA;AAGpB;;;;;;;;AAQC,MACD,MAAMY,oBAAuBhB,GAAAA,KAAAA,CAAMS,WAAW,CAC5C,CAACQ,qBAA8B,KAAK,GAAA;QAClC,IAAK,CAACjC,QAAY,IAAA,CAACiC,sBAAsB,CAACzB,YAAAA,IAAiB,CAACL,MAAQ,EAAA;YAClE,OAAO+B,SAAAA;AACT;AAEA;;;AAGC,UACD,MAAMC,IAAOnC,GAAAA,QAAAA,EAAUc,EAAKd,GAAAA,QAAAA,GAAWoC,kBAAkBjC,MAAQD,EAAAA,UAAAA,CAAAA;QAEjE,OAAOmC,iBAAAA,CAAkBlC,QAAQD,UAAYiC,CAAAA,CAAAA,IAAAA,CAAAA;KAE/C,EAAA;AAACnC,QAAAA,QAAAA;AAAUQ,QAAAA,YAAAA;AAAcL,QAAAA,MAAAA;AAAQD,QAAAA;AAAW,KAAA,CAAA;IAG9C,MAAMb,SAAAA,GAAYC,qBAAqBE,kBAAsBa,IAAAA,eAAAA;IAC7D,MAAMiC,QAAAA,GAAW,CAAC,CAAC7C,KAAAA;IAEnB,OAAO;AACLS,QAAAA,UAAAA;AACAF,QAAAA,QAAAA;AACAC,QAAAA,IAAAA;AACAZ,QAAAA,SAAAA;AACAiD,QAAAA,QAAAA;AACAnC,QAAAA,MAAAA;AACAC,QAAAA,OAAAA;AACAoB,QAAAA,QAAAA;AACAd,QAAAA,QAAAA;AACAsB,QAAAA,oBAAAA;AACAtC,QAAAA;AACF,KAAA;AACF;AAEA;;;;;AAOC,UACK6C,MAAS,GAAA,IAAA;IACb,MAAM,EAAEzB,EAAE,EAAE0B,IAAI,EAAE1C,cAAc,EAAE2C,MAAM,EAAE,GAAGC,SAAAA,EAAAA;AAM7C,IAAA,MAAM,CAAC,EAAEC,KAAK,EAAE,CAAC,GAAGC,cAAAA,EAAAA;AACpB,IAAA,MAAMC,SAAS7B,KAAMK,CAAAA,OAAO,CAAC,IAAMyB,iBAAiBH,KAAQ,CAAA,EAAA;AAACA,QAAAA;AAAM,KAAA,CAAA;AAEnE,IAAA,IAAI,CAAC7C,cAAgB,EAAA;AACnB,QAAA,MAAM,IAAI4B,KAAM,CAAA,6CAAA,CAAA;AAClB;AAEA,IAAA,IAAI,CAACc,IAAM,EAAA;AACT,QAAA,MAAM,IAAId,KAAM,CAAA,oCAAA,CAAA;AAClB;AAEA,IAAA,MAAM1B,WAAWvB,WACf,CAAA;AAAEoB,QAAAA,UAAAA,EAAY4C,MAAU3B,IAAAA,EAAAA;QAAIP,KAAOiC,EAAAA,IAAAA;AAAM1C,QAAAA,cAAAA;AAAgB+C,QAAAA;KACzD,EAAA;AACEjD,QAAAA,IAAAA,EAAMkB,OAAO,QAAa,IAAA,CAAC2B,MAAU,IAAA,CAAC3B,MAAMhB,cAAmBC,KAAAA;AACjE,KAAA,CAAA;AAGF,IAAA,MAAMgD,QAAWN,GAAAA,MAAAA,IAAU3B,EAAO,KAAA,QAAA,GAAWoB,SAAYpB,GAAAA,EAAAA;IAEzD,OAAO;AACLhB,QAAAA,cAAAA;QACAS,KAAOiC,EAAAA,IAAAA;QACP1B,EAAIiC,EAAAA,QAAAA;AACJ,QAAA,GAAG/C;AACL,KAAA;AACF;AAEA;;;;;AAKC,UACKgD,wBAA2B,GAAA,IAAA;AAC/B,IAAA,MAAM,EACJlD,cAAc,EACdS,KAAK,EACLO,EAAE,EACFZ,UAAU,EACVb,SAAAA,EAAW4D,YAAY,EACvB9C,MAAM,EACNC,OAAO,EACR,GAAGmC,MAAAA,EAAAA;AAEJ,IAAA,MAAMW,SAASC,iBAAkB5C,CAAAA,KAAAA,CAAAA;AAEjC,IAAA,MAAM4B,IAAOiB,GAAAA,OAAAA,CAAiB,0BAA4B,EAAA,CAACC,KAAUA,GAAAA,KAAAA,CAAAA;AAErE,IAAA,MAAM7C,eAAeV,cAAmBC,KAAAA,YAAAA;AACxC,IAAA,MAAMyC,IAAOjC,GAAAA,KAAAA;AACb,IAAA,MAAM+C,kBAAkBxC,EAAO,KAAA,QAAA;AAE/B,IAAWR,oBAAAA;IAEX,MAAMjB,SAAAA,GAAY4D,YAAgBC,IAAAA,MAAAA,CAAO7D,SAAS;IAClD,MAAMI,KAAAA,GAAQyD,OAAOzD,KAAK;IAE1B,OAAO;AACLA,QAAAA,KAAAA;AACAJ,QAAAA,SAAAA;;AAGAkB,QAAAA,KAAAA;AACAT,QAAAA,cAAAA;AACAgB,QAAAA,EAAAA;AACA0B,QAAAA,IAAAA;AACAc,QAAAA,eAAAA;AACA9C,QAAAA,YAAAA;QACA+C,kBAAoBpD,EAAAA,MAAAA,EAAQqD,SAASC,eAAmB,IAAA,KAAA;;AAGxDvD,QAAAA,UAAAA;QACAwD,WAAavD,EAAAA,MAAAA;QACbwD,YAAcvD,EAAAA,OAAAA;;AAGd+B,QAAAA,IAAAA;;AAGAe,QAAAA;AACF,KAAA;AACF;;;;"}