@strapi/content-manager 5.59.0 → 5.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/constants/customOrder.js +14 -0
- package/dist/admin/constants/customOrder.js.map +1 -0
- package/dist/admin/constants/customOrder.mjs +10 -0
- package/dist/admin/constants/customOrder.mjs.map +1 -0
- package/dist/admin/history/components/VersionInputRenderer.js +2 -1
- package/dist/admin/history/components/VersionInputRenderer.js.map +1 -1
- package/dist/admin/history/components/VersionInputRenderer.mjs +2 -1
- package/dist/admin/history/components/VersionInputRenderer.mjs.map +1 -1
- package/dist/admin/hooks/useDocument.js +22 -11
- package/dist/admin/hooks/useDocument.js.map +1 -1
- package/dist/admin/hooks/useDocument.mjs +22 -11
- package/dist/admin/hooks/useDocument.mjs.map +1 -1
- package/dist/admin/hooks/useDocumentLayout.js.map +1 -1
- package/dist/admin/hooks/useDocumentLayout.mjs.map +1 -1
- package/dist/admin/hooks/useHasBeenNearViewport.js +70 -0
- package/dist/admin/hooks/useHasBeenNearViewport.js.map +1 -0
- package/dist/admin/hooks/useHasBeenNearViewport.mjs +46 -0
- package/dist/admin/hooks/useHasBeenNearViewport.mjs.map +1 -0
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.js +102 -32
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.mjs +104 -35
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.js +20 -17
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.mjs +20 -17
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.js +15 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.mjs +17 -3
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withStrapiSchema.js +21 -0
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withStrapiSchema.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withStrapiSchema.mjs +22 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withStrapiSchema.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js +1 -0
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs +1 -0
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js +1 -0
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs +1 -0
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js +2 -0
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs +2 -0
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js +4 -7
- package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs +4 -7
- package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +46 -10
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs +47 -11
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormLayout.js +201 -50
- package/dist/admin/pages/EditView/components/FormLayout.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormLayout.mjs +202 -52
- package/dist/admin/pages/EditView/components/FormLayout.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/InputRenderer.js +3 -1
- package/dist/admin/pages/EditView/components/InputRenderer.js.map +1 -1
- package/dist/admin/pages/EditView/components/InputRenderer.mjs +3 -1
- package/dist/admin/pages/EditView/components/InputRenderer.mjs.map +1 -1
- package/dist/admin/pages/ListConfiguration/components/Settings.js +31 -2
- package/dist/admin/pages/ListConfiguration/components/Settings.js.map +1 -1
- package/dist/admin/pages/ListConfiguration/components/Settings.mjs +31 -2
- package/dist/admin/pages/ListConfiguration/components/Settings.mjs.map +1 -1
- package/dist/admin/pages/ListView/ListViewPage.js +196 -132
- package/dist/admin/pages/ListView/ListViewPage.js.map +1 -1
- package/dist/admin/pages/ListView/ListViewPage.mjs +196 -132
- package/dist/admin/pages/ListView/ListViewPage.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/CustomOrder.js +571 -0
- package/dist/admin/pages/ListView/components/CustomOrder.js.map +1 -0
- package/dist/admin/pages/ListView/components/CustomOrder.mjs +546 -0
- package/dist/admin/pages/ListView/components/CustomOrder.mjs.map +1 -0
- package/dist/admin/pages/ListView/components/TableActions.js +4 -1
- package/dist/admin/pages/ListView/components/TableActions.js.map +1 -1
- package/dist/admin/pages/ListView/components/TableActions.mjs +4 -1
- package/dist/admin/pages/ListView/components/TableActions.mjs.map +1 -1
- package/dist/admin/preview/components/PreviewSidePanel.js +2 -1
- package/dist/admin/preview/components/PreviewSidePanel.js.map +1 -1
- package/dist/admin/preview/components/PreviewSidePanel.mjs +2 -1
- package/dist/admin/preview/components/PreviewSidePanel.mjs.map +1 -1
- package/dist/admin/preview/utils/getPreviewUrlStatus.js +17 -0
- package/dist/admin/preview/utils/getPreviewUrlStatus.js.map +1 -0
- package/dist/admin/preview/utils/getPreviewUrlStatus.mjs +15 -0
- package/dist/admin/preview/utils/getPreviewUrlStatus.mjs.map +1 -0
- package/dist/admin/services/documents.js +22 -1
- package/dist/admin/services/documents.js.map +1 -1
- package/dist/admin/services/documents.mjs +21 -2
- package/dist/admin/services/documents.mjs.map +1 -1
- package/dist/admin/src/constants/customOrder.d.ts +8 -0
- package/dist/admin/src/exports.d.ts +1 -1
- package/dist/admin/src/history/components/VersionInputRenderer.d.ts +3 -1
- package/dist/admin/src/hooks/useDocument.d.ts +4 -0
- package/dist/admin/src/hooks/useDocumentLayout.d.ts +6 -2
- package/dist/admin/src/hooks/useHasBeenNearViewport.d.ts +13 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.d.ts +13 -1
- package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +11 -1
- package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +2 -0
- package/dist/admin/src/pages/ListView/components/CustomOrder.d.ts +72 -0
- package/dist/admin/src/preview/utils/getPreviewUrlStatus.d.ts +6 -0
- package/dist/admin/src/services/documents.d.ts +10 -2
- package/dist/admin/translations/en.json.js +9 -0
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +9 -0
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/server/audit-logs.js +36 -0
- package/dist/server/audit-logs.js.map +1 -0
- package/dist/server/audit-logs.mjs +33 -0
- package/dist/server/audit-logs.mjs.map +1 -0
- package/dist/server/bootstrap.js +8 -0
- package/dist/server/bootstrap.js.map +1 -1
- package/dist/server/bootstrap.mjs +8 -0
- package/dist/server/bootstrap.mjs.map +1 -1
- package/dist/server/controllers/collection-types.js +8 -0
- package/dist/server/controllers/collection-types.js.map +1 -1
- package/dist/server/controllers/collection-types.mjs +8 -0
- package/dist/server/controllers/collection-types.mjs.map +1 -1
- package/dist/server/controllers/content-types.js +15 -0
- package/dist/server/controllers/content-types.js.map +1 -1
- package/dist/server/controllers/content-types.mjs +16 -1
- package/dist/server/controllers/content-types.mjs.map +1 -1
- package/dist/server/controllers/index.js +3 -1
- package/dist/server/controllers/index.js.map +1 -1
- package/dist/server/controllers/index.mjs +2 -0
- package/dist/server/controllers/index.mjs.map +1 -1
- package/dist/server/controllers/relations.js +53 -17
- package/dist/server/controllers/relations.js.map +1 -1
- package/dist/server/controllers/relations.mjs +54 -18
- package/dist/server/controllers/relations.mjs.map +1 -1
- package/dist/server/controllers/single-types.js +10 -1
- package/dist/server/controllers/single-types.js.map +1 -1
- package/dist/server/controllers/single-types.mjs +10 -1
- package/dist/server/controllers/single-types.mjs.map +1 -1
- package/dist/server/controllers/validation/model-configuration.js +2 -1
- package/dist/server/controllers/validation/model-configuration.js.map +1 -1
- package/dist/server/controllers/validation/model-configuration.mjs +2 -1
- package/dist/server/controllers/validation/model-configuration.mjs.map +1 -1
- package/dist/server/custom-order/constants.js +21 -0
- package/dist/server/custom-order/constants.js.map +1 -0
- package/dist/server/custom-order/constants.mjs +17 -0
- package/dist/server/custom-order/constants.mjs.map +1 -0
- package/dist/server/custom-order/controllers/custom-order.js +77 -0
- package/dist/server/custom-order/controllers/custom-order.js.map +1 -0
- package/dist/server/custom-order/controllers/custom-order.mjs +75 -0
- package/dist/server/custom-order/controllers/custom-order.mjs.map +1 -0
- package/dist/server/custom-order/controllers/index.js +10 -0
- package/dist/server/custom-order/controllers/index.js.map +1 -0
- package/dist/server/custom-order/controllers/index.mjs +8 -0
- package/dist/server/custom-order/controllers/index.mjs.map +1 -0
- package/dist/server/custom-order/index.js +71 -0
- package/dist/server/custom-order/index.js.map +1 -0
- package/dist/server/custom-order/index.mjs +69 -0
- package/dist/server/custom-order/index.mjs.map +1 -0
- package/dist/server/custom-order/routes/custom-order.js +38 -0
- package/dist/server/custom-order/routes/custom-order.js.map +1 -0
- package/dist/server/custom-order/routes/custom-order.mjs +36 -0
- package/dist/server/custom-order/routes/custom-order.mjs.map +1 -0
- package/dist/server/custom-order/routes/index.js +13 -0
- package/dist/server/custom-order/routes/index.js.map +1 -0
- package/dist/server/custom-order/routes/index.mjs +11 -0
- package/dist/server/custom-order/routes/index.mjs.map +1 -0
- package/dist/server/custom-order/services/custom-order.js +286 -0
- package/dist/server/custom-order/services/custom-order.js.map +1 -0
- package/dist/server/custom-order/services/custom-order.mjs +284 -0
- package/dist/server/custom-order/services/custom-order.mjs.map +1 -0
- package/dist/server/custom-order/services/document-middleware.js +83 -0
- package/dist/server/custom-order/services/document-middleware.js.map +1 -0
- package/dist/server/custom-order/services/document-middleware.mjs +81 -0
- package/dist/server/custom-order/services/document-middleware.mjs.map +1 -0
- package/dist/server/custom-order/services/index.js +10 -0
- package/dist/server/custom-order/services/index.js.map +1 -0
- package/dist/server/custom-order/services/index.mjs +8 -0
- package/dist/server/custom-order/services/index.mjs.map +1 -0
- package/dist/server/custom-order/services/utils.js +152 -0
- package/dist/server/custom-order/services/utils.js.map +1 -0
- package/dist/server/custom-order/services/utils.mjs +148 -0
- package/dist/server/custom-order/services/utils.mjs.map +1 -0
- package/dist/server/custom-order/utils.js +13 -0
- package/dist/server/custom-order/utils.js.map +1 -0
- package/dist/server/custom-order/utils.mjs +10 -0
- package/dist/server/custom-order/utils.mjs.map +1 -0
- package/dist/server/history/constants.js +2 -1
- package/dist/server/history/constants.js.map +1 -1
- package/dist/server/history/constants.mjs +2 -1
- package/dist/server/history/constants.mjs.map +1 -1
- package/dist/server/history/controllers/history-version.js +6 -2
- package/dist/server/history/controllers/history-version.js.map +1 -1
- package/dist/server/history/controllers/history-version.mjs +6 -2
- package/dist/server/history/controllers/history-version.mjs.map +1 -1
- package/dist/server/history/services/history.js +24 -7
- package/dist/server/history/services/history.js.map +1 -1
- package/dist/server/history/services/history.mjs +25 -8
- package/dist/server/history/services/history.mjs.map +1 -1
- package/dist/server/history/services/lifecycles.js +2 -16
- package/dist/server/history/services/lifecycles.js.map +1 -1
- package/dist/server/history/services/lifecycles.mjs +2 -16
- package/dist/server/history/services/lifecycles.mjs.map +1 -1
- package/dist/server/mcp/schemas/filters-schema.js +10 -2
- package/dist/server/mcp/schemas/filters-schema.js.map +1 -1
- package/dist/server/mcp/schemas/filters-schema.mjs +10 -2
- package/dist/server/mcp/schemas/filters-schema.mjs.map +1 -1
- package/dist/server/preview/controllers/validation/preview.js +1 -1
- package/dist/server/preview/controllers/validation/preview.js.map +1 -1
- package/dist/server/preview/controllers/validation/preview.mjs +2 -2
- package/dist/server/preview/controllers/validation/preview.mjs.map +1 -1
- package/dist/server/register.js +4 -0
- package/dist/server/register.js.map +1 -1
- package/dist/server/register.mjs +4 -0
- package/dist/server/register.mjs.map +1 -1
- package/dist/server/routes/index.js +3 -1
- package/dist/server/routes/index.js.map +1 -1
- package/dist/server/routes/index.mjs +2 -0
- package/dist/server/routes/index.mjs.map +1 -1
- package/dist/server/services/content-types.js +2 -2
- package/dist/server/services/content-types.js.map +1 -1
- package/dist/server/services/content-types.mjs +2 -2
- package/dist/server/services/content-types.mjs.map +1 -1
- package/dist/server/services/document-manager.js +13 -0
- package/dist/server/services/document-manager.js.map +1 -1
- package/dist/server/services/document-manager.mjs +14 -1
- package/dist/server/services/document-manager.mjs.map +1 -1
- package/dist/server/services/document-metadata.js +1 -1
- package/dist/server/services/document-metadata.js.map +1 -1
- package/dist/server/services/document-metadata.mjs +1 -1
- package/dist/server/services/document-metadata.mjs.map +1 -1
- package/dist/server/services/index.js +3 -1
- package/dist/server/services/index.js.map +1 -1
- package/dist/server/services/index.mjs +2 -0
- package/dist/server/services/index.mjs.map +1 -1
- package/dist/server/services/utils/configuration/settings.js +2 -1
- package/dist/server/services/utils/configuration/settings.js.map +1 -1
- package/dist/server/services/utils/configuration/settings.mjs +2 -1
- package/dist/server/services/utils/configuration/settings.mjs.map +1 -1
- package/dist/server/src/audit-logs.d.ts +40 -0
- package/dist/server/src/audit-logs.d.ts.map +1 -0
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/content-types.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +21 -3
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts +19 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/single-types.d.ts +1 -1
- package/dist/server/src/controllers/single-types.d.ts.map +1 -1
- package/dist/server/src/custom-order/constants.d.ts +18 -0
- package/dist/server/src/custom-order/constants.d.ts.map +1 -0
- package/dist/server/src/custom-order/controllers/custom-order.d.ts +8 -0
- package/dist/server/src/custom-order/controllers/custom-order.d.ts.map +1 -0
- package/dist/server/src/custom-order/controllers/index.d.ts +3 -0
- package/dist/server/src/custom-order/controllers/index.d.ts.map +1 -0
- package/dist/server/src/custom-order/index.d.ts +8 -0
- package/dist/server/src/custom-order/index.d.ts.map +1 -0
- package/dist/server/src/custom-order/routes/custom-order.d.ts +4 -0
- package/dist/server/src/custom-order/routes/custom-order.d.ts.map +1 -0
- package/dist/server/src/custom-order/routes/index.d.ts +10 -0
- package/dist/server/src/custom-order/routes/index.d.ts.map +1 -0
- package/dist/server/src/custom-order/services/custom-order.d.ts +43 -0
- package/dist/server/src/custom-order/services/custom-order.d.ts.map +1 -0
- package/dist/server/src/custom-order/services/document-middleware.d.ts +16 -0
- package/dist/server/src/custom-order/services/document-middleware.d.ts.map +1 -0
- package/dist/server/src/custom-order/services/index.d.ts +24 -0
- package/dist/server/src/custom-order/services/index.d.ts.map +1 -0
- package/dist/server/src/custom-order/services/utils.d.ts +34 -0
- package/dist/server/src/custom-order/services/utils.d.ts.map +1 -0
- package/dist/server/src/custom-order/utils.d.ts +6 -0
- package/dist/server/src/custom-order/utils.d.ts.map +1 -0
- package/dist/server/src/history/constants.d.ts.map +1 -1
- package/dist/server/src/history/controllers/history-version.d.ts.map +1 -1
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +22 -6
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/mcp/schemas/filters-schema.d.ts.map +1 -1
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/index.d.ts.map +1 -1
- package/dist/server/src/services/content-types.d.ts +1 -3
- package/dist/server/src/services/content-types.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +1 -3
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/utils/configuration/settings.d.ts.map +1 -1
- package/dist/shared/contracts/content-types.d.ts +5 -0
- package/dist/shared/contracts/content-types.d.ts.map +1 -1
- package/dist/shared/contracts/custom-order.d.ts +33 -0
- package/dist/shared/contracts/custom-order.d.ts.map +1 -0
- package/dist/shared/contracts/custom-order.js +3 -0
- package/dist/shared/contracts/custom-order.js.map +1 -0
- package/dist/shared/contracts/custom-order.mjs +2 -0
- package/dist/shared/contracts/custom-order.mjs.map +1 -0
- package/dist/shared/contracts/history-versions.d.ts +0 -1
- package/dist/shared/contracts/history-versions.d.ts.map +1 -1
- package/dist/shared/contracts/index.d.ts +1 -0
- package/dist/shared/contracts/index.d.ts.map +1 -1
- package/dist/shared/contracts/index.js +2 -0
- package/dist/shared/contracts/index.js.map +1 -1
- package/dist/shared/contracts/index.mjs +2 -0
- package/dist/shared/contracts/index.mjs.map +1 -1
- package/package.json +10 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDocumentLayout.mjs","sources":["../../../admin/src/hooks/useDocumentLayout.ts"],"sourcesContent":["import * as React from 'react';\n\nimport { SerializedError } from '@reduxjs/toolkit';\nimport {\n useNotification,\n useStrapiApp,\n useAPIErrorHandler,\n useQueryParams,\n} from '@strapi/admin/strapi-admin';\n\nimport { HOOKS } from '../constants/hooks';\nimport { useGetContentTypeConfigurationQuery } from '../services/contentTypes';\nimport { BaseQueryError } from '../utils/api';\nimport { getMainField } from '../utils/attributes';\nimport { normalizeContentManagerLayout } from '../utils/layouts/normalizeContentManagerLayout';\n\nimport { useContentTypeSchema } from './useContentTypeSchema';\nimport {\n type ComponentsDictionary,\n type Document,\n type Schema,\n useDoc,\n useDocument,\n} from './useDocument';\n\nimport type { ComponentConfiguration } from '../../../shared/contracts/components';\nimport type {\n Metadatas,\n FindContentTypeConfiguration,\n Settings,\n} from '../../../shared/contracts/content-types';\nimport type { Filters, InputProps, Table } from '@strapi/admin/strapi-admin';\nimport type { Schema as SchemaUtils } from '@strapi/types';\n\ntype LayoutOptions = Schema['options'] & Schema['pluginOptions'] & object;\n\ninterface LayoutSettings extends Settings {\n displayName?: string;\n icon?: never;\n}\n\ninterface ListFieldLayout\n extends Table.Header<Document, ListFieldLayout>, Pick<Filters.Filter, 'mainField'> {\n attribute: SchemaUtils.Attribute.AnyAttribute | { type: 'custom' };\n}\n\ninterface ListLayout {\n layout: ListFieldLayout[];\n components?: never;\n metadatas: {\n [K in keyof Metadatas]: Metadatas[K]['list'];\n };\n options: LayoutOptions;\n settings: LayoutSettings;\n}\ninterface EditFieldSharedProps\n extends Omit<InputProps, 'hint' | 'label' | 'type'>, Pick<Filters.Filter, 'mainField'> {\n hint?: string;\n label: string;\n size: number;\n unique?: boolean;\n visible?: boolean;\n}\n\n/**\n * Map over all the types in Attribute Types and use that to create a union of new types where the attribute type\n * is under the property attribute and the type is under the property type.\n */\ntype EditFieldLayout = {\n [K in SchemaUtils.Attribute.Kind]: EditFieldSharedProps & {\n attribute: Extract<SchemaUtils.Attribute.AnyAttribute, { type: K }>;\n type: K;\n };\n}[SchemaUtils.Attribute.Kind];\n\ninterface EditLayout {\n layout: Array<Array<EditFieldLayout[]>>;\n components: {\n [uid: string]: {\n layout: Array<EditFieldLayout[]>;\n settings: ComponentConfiguration['settings'] & {\n displayName?: string;\n icon?: string;\n };\n };\n };\n metadatas: {\n [K in keyof Metadatas]: Metadatas[K]['edit'];\n };\n options: LayoutOptions;\n settings: LayoutSettings;\n}\n\n/**\n * Data required to resolve `mainField` when converting list column names to field layouts for\n * component and relation attributes; mirrors the fourth and fifth arguments of `formatListLayout`.\n */\ntype ListViewConversionContext = {\n componentConfigurations: FindContentTypeConfiguration.Response['data']['components'];\n componentSchemas: ComponentsDictionary;\n contentTypeSchemas: Schema[];\n};\n\ntype UseDocumentLayout = (model: string) => {\n error?: BaseQueryError | SerializedError;\n isLoading: boolean;\n /**\n * This is the layout for the edit view,\n */\n edit: EditLayout;\n list: ListLayout;\n /**\n * Populated when configuration is loaded; pass into `convertListLayoutToFieldLayouts` with\n * `list.metadatas` when mapping persisted list column names (e.g. custom displayed headers).\n */\n listViewConversionContext: ListViewConversionContext | null;\n};\n\ntype ResolvedLayouts = {\n edit: EditLayout;\n list: ListLayout;\n listViewConversionContext: ListViewConversionContext;\n};\n\ntype ResolvedLayoutCacheEntry = {\n components: ComponentsDictionary;\n data: LayoutData;\n model: string;\n schema?: Schema;\n schemas: Schema[];\n value: ResolvedLayouts;\n};\n\nconst RESOLVED_LAYOUT_CACHE_LIMIT = 25;\n// Module-level cache keeps resolved layout object identities stable across hook instances\n// when RTK Query returns the same schema/configuration references.\nconst resolvedLayoutCache: ResolvedLayoutCacheEntry[] = [];\n\nconst getCachedResolvedLayouts = ({\n components,\n data,\n model,\n schema,\n schemas,\n}: Omit<ResolvedLayoutCacheEntry, 'value'>) => {\n return resolvedLayoutCache.find(\n (entry) =>\n entry.components === components &&\n entry.data === data &&\n entry.model === model &&\n entry.schema === schema &&\n entry.schemas === schemas\n )?.value;\n};\n\nconst setCachedResolvedLayouts = (entry: ResolvedLayoutCacheEntry) => {\n resolvedLayoutCache.unshift(entry);\n\n if (resolvedLayoutCache.length > RESOLVED_LAYOUT_CACHE_LIMIT) {\n resolvedLayoutCache.pop();\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * useDocumentLayout\n * -----------------------------------------------------------------------------------------------*/\n\nconst DEFAULT_SETTINGS = {\n bulkable: false,\n filterable: false,\n searchable: false,\n pagination: false,\n defaultSortBy: '',\n defaultSortOrder: 'asc',\n mainField: 'id',\n pageSize: 10,\n relationOpenMode: 'modal' as const,\n};\n\n/**\n * @alpha\n * @description This hook is used to get the layouts for either the edit view or list view of a specific content-type\n * including the layouts for the components used in the content-type. It also runs the mutation hook waterfall so the data\n * is consistent wherever it is used. It's a light wrapper around the `useDocument` hook, but provides the `skip` option a document\n * is not fetched, however, it does fetch the schemas & components if they do not already exist in the cache.\n *\n * If the fetch fails, it will display a notification to the user.\n *\n * @example\n * ```tsx\n * const { model } = useParams<{ model: string }>();\n * const { edit: { schema: layout } } = useDocumentLayout(model);\n *\n * return layout.map(panel => panel.map(row => row.map(field => <Field.Root {...field} />)))\n * ```\n *\n */\nconst useDocumentLayout: UseDocumentLayout = (model) => {\n const { schema, components } = useDocument({ model, collectionType: '' }, { skip: true });\n const [{ query }] = useQueryParams();\n const runHookWaterfall = useStrapiApp('useDocumentLayout', (state) => state.runHookWaterfall);\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();\n const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();\n\n const {\n currentData: data,\n isLoading: isLoadingConfigs,\n error,\n } = useGetContentTypeConfigurationQuery(model);\n\n const isConfigResolvedForModel = data?.contentType?.uid === model;\n const isLoading = isLoadingSchemas || isLoadingConfigs || (!error && !isConfigResolvedForModel);\n const stableLayoutsByModelRef = React.useRef(\n new Map<\n string,\n {\n edit: EditLayout;\n list: ListLayout;\n listViewConversionContext: ListViewConversionContext | null;\n }\n >()\n );\n\n React.useEffect(() => {\n if (error) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n }\n }, [error, formatAPIError, toggleNotification]);\n\n const resolvedLayouts = React.useMemo(() => {\n if (!data || isLoading) {\n return null;\n }\n\n const cachedLayouts = getCachedResolvedLayouts({ components, data, model, schema, schemas });\n\n if (cachedLayouts) {\n return cachedLayouts;\n }\n\n const normalizedData = normalizeContentManagerLayout(data, { schemas, schema, components });\n const edit = formatEditLayout(normalizedData, { schemas, schema, components });\n const list = formatListLayout(normalizedData, { schemas, schema, components });\n const listViewConversionContext: ListViewConversionContext = {\n componentConfigurations: normalizedData.components,\n componentSchemas: components,\n contentTypeSchemas: schemas,\n };\n\n const layouts = { edit, list, listViewConversionContext };\n\n setCachedResolvedLayouts({ components, data, model, schema, schemas, value: layouts });\n\n return layouts;\n }, [data, isLoading, model, schemas, schema, components]);\n\n React.useEffect(() => {\n if (resolvedLayouts) {\n stableLayoutsByModelRef.current.set(model, resolvedLayouts);\n }\n }, [model, resolvedLayouts]);\n\n const stableLayouts = resolvedLayouts ?? stableLayoutsByModelRef.current.get(model) ?? null;\n\n const editLayout = React.useMemo(\n () =>\n stableLayouts?.edit ??\n ({\n layout: [],\n components: {},\n metadatas: {},\n options: {},\n settings: DEFAULT_SETTINGS,\n } as EditLayout),\n [stableLayouts]\n );\n\n const listLayout = React.useMemo(\n () =>\n stableLayouts?.list ??\n ({\n layout: [],\n metadatas: {},\n options: {},\n settings: DEFAULT_SETTINGS,\n } as ListLayout),\n [stableLayouts]\n );\n\n const { layout: edit } = React.useMemo(\n () =>\n runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {\n layout: editLayout,\n query,\n }),\n [editLayout, query, runHookWaterfall]\n );\n\n const listViewConversionContext = stableLayouts?.listViewConversionContext ?? null;\n\n return {\n error,\n isLoading,\n edit,\n list: listLayout,\n listViewConversionContext,\n } satisfies ReturnType<UseDocumentLayout>;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * useDocLayout\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * @internal this hook uses the internal useDoc hook, as such it shouldn't be used outside of the\n * content-manager because it won't work as intended.\n */\nconst useDocLayout = () => {\n const { model } = useDoc();\n return useDocumentLayout(model);\n};\n\n/* -------------------------------------------------------------------------------------------------\n * formatEditLayout\n * -----------------------------------------------------------------------------------------------*/\ntype LayoutData = FindContentTypeConfiguration.Response['data'];\n\n/**\n * @internal\n * @description takes the configuration data, the schema & the components used in the schema and formats the edit view\n * versions of the schema & components. This is then used to render the edit view of the content-type.\n */\nconst formatEditLayout = (\n data: LayoutData,\n {\n schemas,\n schema,\n components,\n }: { schemas: Schema[]; schema?: Schema; components: ComponentsDictionary }\n): EditLayout => {\n let currentPanelIndex = 0;\n /**\n * The fields arranged by the panels, new panels are made for dynamic zones only.\n */\n const panelledEditAttributes = convertEditLayoutToFieldLayouts(\n data.contentType.layouts.edit,\n schema?.attributes,\n data.contentType.metadatas,\n { configurations: data.components, schemas: components },\n schemas\n ).reduce<Array<EditFieldLayout[][]>>((panels, row) => {\n if (row.some((field) => field.type === 'dynamiczone')) {\n panels.push([row]);\n currentPanelIndex += 2;\n } else {\n if (!panels[currentPanelIndex]) {\n panels.push([row]);\n } else {\n panels[currentPanelIndex].push(row);\n }\n }\n\n return panels;\n }, []);\n\n const componentEditAttributes = Object.entries(data.components).reduce<EditLayout['components']>(\n (acc, [uid, configuration]) => {\n const componentSchema = components[uid];\n\n // Persisted configuration can reference component UIDs absent from `/init`.\n if (!componentSchema) {\n return acc;\n }\n\n acc[uid] = {\n layout: convertEditLayoutToFieldLayouts(\n configuration.layouts.edit,\n componentSchema.attributes,\n configuration.metadatas,\n { configurations: data.components, schemas: components }\n ),\n settings: {\n ...configuration.settings,\n icon: componentSchema.info.icon,\n displayName: componentSchema.info.displayName,\n },\n };\n return acc;\n },\n {}\n );\n\n const editMetadatas = Object.entries(data.contentType.metadatas).reduce<EditLayout['metadatas']>(\n (acc, [attribute, metadata]) => {\n return {\n ...acc,\n [attribute]: metadata.edit,\n };\n },\n {}\n );\n\n return {\n layout: panelledEditAttributes,\n components: componentEditAttributes,\n metadatas: editMetadatas,\n settings: {\n ...data.contentType.settings,\n displayName: schema?.info?.displayName,\n },\n options: {\n ...schema?.options,\n ...schema?.pluginOptions,\n ...data.contentType.options,\n },\n };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * convertEditLayoutToFieldLayouts\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * @internal\n * @description takes the edit layout from either a content-type or a component\n * and formats it into a generic object that can be used to correctly render\n * the form fields.\n */\nconst convertEditLayoutToFieldLayouts = (\n rows: LayoutData['contentType']['layouts']['edit'],\n attributes: Schema['attributes'] = {},\n metadatas: Metadatas,\n components?: {\n configurations: Record<string, ComponentConfiguration>;\n schemas: ComponentsDictionary;\n },\n schemas: Schema[] = []\n) => {\n return rows.map((row) =>\n row\n .map((field) => {\n const attribute = attributes[field.name];\n\n if (!attribute) {\n return null;\n }\n\n const fieldMetadata = metadatas[field.name];\n if (!fieldMetadata) {\n return null;\n }\n\n const { edit: metadata } = fieldMetadata;\n\n const settings: Partial<Settings> =\n attribute.type === 'component' && components\n ? (components.configurations[attribute.component]?.settings ?? {})\n : {};\n\n return {\n attribute,\n disabled: !metadata.editable,\n hint: metadata.description,\n label: metadata.label ?? '',\n name: field.name,\n // @ts-expect-error – mainField does exist on the metadata for a relation.\n mainField: getMainField(attribute, metadata.mainField || settings.mainField, {\n schemas,\n components: components?.schemas ?? {},\n }),\n placeholder: metadata.placeholder ?? '',\n required: attribute.required ?? false,\n size: field.size,\n unique: 'unique' in attribute ? attribute.unique : false,\n visible: metadata.visible ?? true,\n type: attribute.type,\n };\n })\n .filter((field) => field !== null)\n ) as EditFieldLayout[][];\n};\n\n/* -------------------------------------------------------------------------------------------------\n * formatListLayout\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * @internal\n * @description takes the complete configuration data, the schema & the components used in the schema and\n * formats a list view layout for the content-type. This is much simpler than the edit view layout as there\n * are less options to consider.\n */\nconst formatListLayout = (\n data: LayoutData,\n {\n schemas,\n schema,\n components,\n }: { schemas: Schema[]; schema?: Schema; components: ComponentsDictionary }\n): ListLayout => {\n const listMetadatas = Object.entries(data.contentType.metadatas).reduce<ListLayout['metadatas']>(\n (acc, [attribute, metadata]) => {\n return {\n ...acc,\n [attribute]: metadata.list,\n };\n },\n {}\n );\n /**\n * The fields arranged by the panels, new panels are made for dynamic zones only.\n */\n const listAttributes = convertListLayoutToFieldLayouts(\n data.contentType.layouts.list,\n schema?.attributes,\n listMetadatas,\n { configurations: data.components, schemas: components },\n schemas\n );\n\n return {\n layout: listAttributes,\n settings: { ...data.contentType.settings, displayName: schema?.info?.displayName },\n metadatas: listMetadatas,\n options: {\n ...schema?.options,\n ...schema?.pluginOptions,\n ...data.contentType.options,\n },\n };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * convertListLayoutToFieldLayouts\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * @internal\n * @description takes the columns from the list view configuration and formats them into a generic object\n * combinining metadata and attribute data.\n *\n * @note We do use this to reformat the list of strings when updating the displayed headers for the list view.\n */\nconst convertListLayoutToFieldLayouts = (\n columns: LayoutData['contentType']['layouts']['list'],\n attributes: Schema['attributes'] = {},\n metadatas: ListLayout['metadatas'],\n components?: {\n configurations: Record<string, ComponentConfiguration>;\n schemas: ComponentsDictionary;\n },\n schemas: Schema[] = []\n) => {\n return columns\n .map((name) => {\n const attribute = attributes[name];\n\n if (!attribute) {\n return null;\n }\n\n const metadata = metadatas[name];\n if (!metadata) {\n return null;\n }\n\n const settings: Partial<Settings> =\n attribute.type === 'component' && components\n ? (components.configurations[attribute.component]?.settings ?? {})\n : {};\n\n return {\n attribute,\n label: metadata.label ?? '',\n mainField: getMainField(attribute, metadata.mainField || settings.mainField, {\n schemas,\n components: components?.schemas ?? {},\n }),\n name: name,\n searchable: metadata.searchable ?? true,\n sortable: metadata.sortable ?? true,\n } satisfies ListFieldLayout;\n })\n .filter((field) => field !== null) as ListFieldLayout[];\n};\n\nexport {\n useDocLayout,\n useDocumentLayout,\n convertListLayoutToFieldLayouts,\n convertEditLayoutToFieldLayouts,\n DEFAULT_SETTINGS,\n};\nexport type { EditLayout, EditFieldLayout, ListLayout, ListFieldLayout, UseDocumentLayout };\n"],"names":["RESOLVED_LAYOUT_CACHE_LIMIT","resolvedLayoutCache","getCachedResolvedLayouts","components","data","model","schema","schemas","find","entry","value","setCachedResolvedLayouts","unshift","length","pop","DEFAULT_SETTINGS","bulkable","filterable","searchable","pagination","defaultSortBy","defaultSortOrder","mainField","pageSize","relationOpenMode","useDocumentLayout","useDocument","collectionType","skip","query","useQueryParams","runHookWaterfall","useStrapiApp","state","toggleNotification","useNotification","_unstableFormatAPIError","formatAPIError","useAPIErrorHandler","isLoading","isLoadingSchemas","useContentTypeSchema","currentData","isLoadingConfigs","error","useGetContentTypeConfigurationQuery","isConfigResolvedForModel","contentType","uid","stableLayoutsByModelRef","React","useRef","Map","useEffect","type","message","resolvedLayouts","useMemo","cachedLayouts","normalizedData","normalizeContentManagerLayout","edit","formatEditLayout","list","formatListLayout","listViewConversionContext","componentConfigurations","componentSchemas","contentTypeSchemas","layouts","current","set","stableLayouts","get","editLayout","layout","metadatas","options","settings","listLayout","HOOKS","MUTATE_EDIT_VIEW_LAYOUT","useDocLayout","useDoc","currentPanelIndex","panelledEditAttributes","convertEditLayoutToFieldLayouts","attributes","configurations","reduce","panels","row","some","field","push","componentEditAttributes","Object","entries","acc","configuration","componentSchema","icon","info","displayName","editMetadatas","attribute","metadata","pluginOptions","rows","map","name","fieldMetadata","component","disabled","editable","hint","description","label","getMainField","placeholder","required","size","unique","visible","filter","listMetadatas","listAttributes","convertListLayoutToFieldLayouts","columns","sortable"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useDocumentLayout.mjs","sources":["../../../admin/src/hooks/useDocumentLayout.ts"],"sourcesContent":["import * as React from 'react';\n\nimport { SerializedError } from '@reduxjs/toolkit';\nimport {\n useNotification,\n useStrapiApp,\n useAPIErrorHandler,\n useQueryParams,\n} from '@strapi/admin/strapi-admin';\n\nimport { HOOKS } from '../constants/hooks';\nimport { useGetContentTypeConfigurationQuery } from '../services/contentTypes';\nimport { BaseQueryError } from '../utils/api';\nimport { getMainField } from '../utils/attributes';\nimport { normalizeContentManagerLayout } from '../utils/layouts/normalizeContentManagerLayout';\n\nimport { useContentTypeSchema } from './useContentTypeSchema';\nimport {\n type ComponentsDictionary,\n type Document,\n type Schema,\n useDoc,\n useDocument,\n} from './useDocument';\n\nimport type { ComponentConfiguration } from '../../../shared/contracts/components';\nimport type {\n Metadatas,\n FindContentTypeConfiguration,\n Settings,\n} from '../../../shared/contracts/content-types';\nimport type { Filters, InputProps, Table } from '@strapi/admin/strapi-admin';\nimport type { Schema as SchemaUtils } from '@strapi/types';\n\ntype LayoutOptions = Schema['options'] & Schema['pluginOptions'] & object;\n\ninterface LayoutSettings extends Settings {\n displayName?: string;\n icon?: never;\n}\n\ninterface ListCellMeta {\n collectionType: string;\n model: string;\n}\n\ninterface ListFieldLayout\n extends Table.Header<Document, ListFieldLayout, ListCellMeta>, Pick<Filters.Filter, 'mainField'> {\n attribute: SchemaUtils.Attribute.AnyAttribute | { type: 'custom' };\n}\n\ninterface ListLayout {\n layout: ListFieldLayout[];\n components?: never;\n metadatas: {\n [K in keyof Metadatas]: Metadatas[K]['list'];\n };\n options: LayoutOptions;\n settings: LayoutSettings;\n}\ninterface EditFieldSharedProps\n extends Omit<InputProps, 'hint' | 'label' | 'type'>, Pick<Filters.Filter, 'mainField'> {\n hint?: string;\n label: string;\n size: number;\n unique?: boolean;\n visible?: boolean;\n}\n\n/**\n * Map over all the types in Attribute Types and use that to create a union of new types where the attribute type\n * is under the property attribute and the type is under the property type.\n */\ntype EditFieldLayout = {\n [K in SchemaUtils.Attribute.Kind]: EditFieldSharedProps & {\n attribute: Extract<SchemaUtils.Attribute.AnyAttribute, { type: K }>;\n type: K;\n };\n}[SchemaUtils.Attribute.Kind];\n\ninterface EditLayout {\n layout: Array<Array<EditFieldLayout[]>>;\n components: {\n [uid: string]: {\n layout: Array<EditFieldLayout[]>;\n settings: ComponentConfiguration['settings'] & {\n displayName?: string;\n icon?: string;\n };\n };\n };\n metadatas: {\n [K in keyof Metadatas]: Metadatas[K]['edit'];\n };\n options: LayoutOptions;\n settings: LayoutSettings;\n}\n\n/**\n * Data required to resolve `mainField` when converting list column names to field layouts for\n * component and relation attributes; mirrors the fourth and fifth arguments of `formatListLayout`.\n */\ntype ListViewConversionContext = {\n componentConfigurations: FindContentTypeConfiguration.Response['data']['components'];\n componentSchemas: ComponentsDictionary;\n contentTypeSchemas: Schema[];\n};\n\ntype UseDocumentLayout = (model: string) => {\n error?: BaseQueryError | SerializedError;\n isLoading: boolean;\n /**\n * This is the layout for the edit view,\n */\n edit: EditLayout;\n list: ListLayout;\n /**\n * Populated when configuration is loaded; pass into `convertListLayoutToFieldLayouts` with\n * `list.metadatas` when mapping persisted list column names (e.g. custom displayed headers).\n */\n listViewConversionContext: ListViewConversionContext | null;\n};\n\ntype ResolvedLayouts = {\n edit: EditLayout;\n list: ListLayout;\n listViewConversionContext: ListViewConversionContext;\n};\n\ntype ResolvedLayoutCacheEntry = {\n components: ComponentsDictionary;\n data: LayoutData;\n model: string;\n schema?: Schema;\n schemas: Schema[];\n value: ResolvedLayouts;\n};\n\nconst RESOLVED_LAYOUT_CACHE_LIMIT = 25;\n// Module-level cache keeps resolved layout object identities stable across hook instances\n// when RTK Query returns the same schema/configuration references.\nconst resolvedLayoutCache: ResolvedLayoutCacheEntry[] = [];\n\nconst getCachedResolvedLayouts = ({\n components,\n data,\n model,\n schema,\n schemas,\n}: Omit<ResolvedLayoutCacheEntry, 'value'>) => {\n return resolvedLayoutCache.find(\n (entry) =>\n entry.components === components &&\n entry.data === data &&\n entry.model === model &&\n entry.schema === schema &&\n entry.schemas === schemas\n )?.value;\n};\n\nconst setCachedResolvedLayouts = (entry: ResolvedLayoutCacheEntry) => {\n resolvedLayoutCache.unshift(entry);\n\n if (resolvedLayoutCache.length > RESOLVED_LAYOUT_CACHE_LIMIT) {\n resolvedLayoutCache.pop();\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * useDocumentLayout\n * -----------------------------------------------------------------------------------------------*/\n\nconst DEFAULT_SETTINGS = {\n bulkable: false,\n filterable: false,\n searchable: false,\n pagination: false,\n defaultSortBy: '',\n defaultSortOrder: 'asc',\n mainField: 'id',\n pageSize: 10,\n relationOpenMode: 'modal' as const,\n};\n\n/**\n * @alpha\n * @description This hook is used to get the layouts for either the edit view or list view of a specific content-type\n * including the layouts for the components used in the content-type. It also runs the mutation hook waterfall so the data\n * is consistent wherever it is used. It's a light wrapper around the `useDocument` hook, but provides the `skip` option a document\n * is not fetched, however, it does fetch the schemas & components if they do not already exist in the cache.\n *\n * If the fetch fails, it will display a notification to the user.\n *\n * @example\n * ```tsx\n * const { model } = useParams<{ model: string }>();\n * const { edit: { schema: layout } } = useDocumentLayout(model);\n *\n * return layout.map(panel => panel.map(row => row.map(field => <Field.Root {...field} />)))\n * ```\n *\n */\nconst useDocumentLayout: UseDocumentLayout = (model) => {\n const { schema, components } = useDocument({ model, collectionType: '' }, { skip: true });\n const [{ query }] = useQueryParams();\n const runHookWaterfall = useStrapiApp('useDocumentLayout', (state) => state.runHookWaterfall);\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();\n const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();\n\n const {\n currentData: data,\n isLoading: isLoadingConfigs,\n error,\n } = useGetContentTypeConfigurationQuery(model);\n\n const isConfigResolvedForModel = data?.contentType?.uid === model;\n const isLoading = isLoadingSchemas || isLoadingConfigs || (!error && !isConfigResolvedForModel);\n const stableLayoutsByModelRef = React.useRef(\n new Map<\n string,\n {\n edit: EditLayout;\n list: ListLayout;\n listViewConversionContext: ListViewConversionContext | null;\n }\n >()\n );\n\n React.useEffect(() => {\n if (error) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n }\n }, [error, formatAPIError, toggleNotification]);\n\n const resolvedLayouts = React.useMemo(() => {\n if (!data || isLoading) {\n return null;\n }\n\n const cachedLayouts = getCachedResolvedLayouts({ components, data, model, schema, schemas });\n\n if (cachedLayouts) {\n return cachedLayouts;\n }\n\n const normalizedData = normalizeContentManagerLayout(data, { schemas, schema, components });\n const edit = formatEditLayout(normalizedData, { schemas, schema, components });\n const list = formatListLayout(normalizedData, { schemas, schema, components });\n const listViewConversionContext: ListViewConversionContext = {\n componentConfigurations: normalizedData.components,\n componentSchemas: components,\n contentTypeSchemas: schemas,\n };\n\n const layouts = { edit, list, listViewConversionContext };\n\n setCachedResolvedLayouts({ components, data, model, schema, schemas, value: layouts });\n\n return layouts;\n }, [data, isLoading, model, schemas, schema, components]);\n\n React.useEffect(() => {\n if (resolvedLayouts) {\n stableLayoutsByModelRef.current.set(model, resolvedLayouts);\n }\n }, [model, resolvedLayouts]);\n\n const stableLayouts = resolvedLayouts ?? stableLayoutsByModelRef.current.get(model) ?? null;\n\n const editLayout = React.useMemo(\n () =>\n stableLayouts?.edit ??\n ({\n layout: [],\n components: {},\n metadatas: {},\n options: {},\n settings: DEFAULT_SETTINGS,\n } as EditLayout),\n [stableLayouts]\n );\n\n const listLayout = React.useMemo(\n () =>\n stableLayouts?.list ??\n ({\n layout: [],\n metadatas: {},\n options: {},\n settings: DEFAULT_SETTINGS,\n } as ListLayout),\n [stableLayouts]\n );\n\n const { layout: edit } = React.useMemo(\n () =>\n runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {\n layout: editLayout,\n query,\n }),\n [editLayout, query, runHookWaterfall]\n );\n\n const listViewConversionContext = stableLayouts?.listViewConversionContext ?? null;\n\n return {\n error,\n isLoading,\n edit,\n list: listLayout,\n listViewConversionContext,\n } satisfies ReturnType<UseDocumentLayout>;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * useDocLayout\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * @internal this hook uses the internal useDoc hook, as such it shouldn't be used outside of the\n * content-manager because it won't work as intended.\n */\nconst useDocLayout = () => {\n const { model } = useDoc();\n return useDocumentLayout(model);\n};\n\n/* -------------------------------------------------------------------------------------------------\n * formatEditLayout\n * -----------------------------------------------------------------------------------------------*/\ntype LayoutData = FindContentTypeConfiguration.Response['data'];\n\n/**\n * @internal\n * @description takes the configuration data, the schema & the components used in the schema and formats the edit view\n * versions of the schema & components. This is then used to render the edit view of the content-type.\n */\nconst formatEditLayout = (\n data: LayoutData,\n {\n schemas,\n schema,\n components,\n }: { schemas: Schema[]; schema?: Schema; components: ComponentsDictionary }\n): EditLayout => {\n let currentPanelIndex = 0;\n /**\n * The fields arranged by the panels, new panels are made for dynamic zones only.\n */\n const panelledEditAttributes = convertEditLayoutToFieldLayouts(\n data.contentType.layouts.edit,\n schema?.attributes,\n data.contentType.metadatas,\n { configurations: data.components, schemas: components },\n schemas\n ).reduce<Array<EditFieldLayout[][]>>((panels, row) => {\n if (row.some((field) => field.type === 'dynamiczone')) {\n panels.push([row]);\n currentPanelIndex += 2;\n } else {\n if (!panels[currentPanelIndex]) {\n panels.push([row]);\n } else {\n panels[currentPanelIndex].push(row);\n }\n }\n\n return panels;\n }, []);\n\n const componentEditAttributes = Object.entries(data.components).reduce<EditLayout['components']>(\n (acc, [uid, configuration]) => {\n const componentSchema = components[uid];\n\n // Persisted configuration can reference component UIDs absent from `/init`.\n if (!componentSchema) {\n return acc;\n }\n\n acc[uid] = {\n layout: convertEditLayoutToFieldLayouts(\n configuration.layouts.edit,\n componentSchema.attributes,\n configuration.metadatas,\n { configurations: data.components, schemas: components }\n ),\n settings: {\n ...configuration.settings,\n icon: componentSchema.info.icon,\n displayName: componentSchema.info.displayName,\n },\n };\n return acc;\n },\n {}\n );\n\n const editMetadatas = Object.entries(data.contentType.metadatas).reduce<EditLayout['metadatas']>(\n (acc, [attribute, metadata]) => {\n return {\n ...acc,\n [attribute]: metadata.edit,\n };\n },\n {}\n );\n\n return {\n layout: panelledEditAttributes,\n components: componentEditAttributes,\n metadatas: editMetadatas,\n settings: {\n ...data.contentType.settings,\n displayName: schema?.info?.displayName,\n },\n options: {\n ...schema?.options,\n ...schema?.pluginOptions,\n ...data.contentType.options,\n },\n };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * convertEditLayoutToFieldLayouts\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * @internal\n * @description takes the edit layout from either a content-type or a component\n * and formats it into a generic object that can be used to correctly render\n * the form fields.\n */\nconst convertEditLayoutToFieldLayouts = (\n rows: LayoutData['contentType']['layouts']['edit'],\n attributes: Schema['attributes'] = {},\n metadatas: Metadatas,\n components?: {\n configurations: Record<string, ComponentConfiguration>;\n schemas: ComponentsDictionary;\n },\n schemas: Schema[] = []\n) => {\n return rows.map((row) =>\n row\n .map((field) => {\n const attribute = attributes[field.name];\n\n if (!attribute) {\n return null;\n }\n\n const fieldMetadata = metadatas[field.name];\n if (!fieldMetadata) {\n return null;\n }\n\n const { edit: metadata } = fieldMetadata;\n\n const settings: Partial<Settings> =\n attribute.type === 'component' && components\n ? (components.configurations[attribute.component]?.settings ?? {})\n : {};\n\n return {\n attribute,\n disabled: !metadata.editable,\n hint: metadata.description,\n label: metadata.label ?? '',\n name: field.name,\n // @ts-expect-error – mainField does exist on the metadata for a relation.\n mainField: getMainField(attribute, metadata.mainField || settings.mainField, {\n schemas,\n components: components?.schemas ?? {},\n }),\n placeholder: metadata.placeholder ?? '',\n required: attribute.required ?? false,\n size: field.size,\n unique: 'unique' in attribute ? attribute.unique : false,\n visible: metadata.visible ?? true,\n type: attribute.type,\n };\n })\n .filter((field) => field !== null)\n ) as EditFieldLayout[][];\n};\n\n/* -------------------------------------------------------------------------------------------------\n * formatListLayout\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * @internal\n * @description takes the complete configuration data, the schema & the components used in the schema and\n * formats a list view layout for the content-type. This is much simpler than the edit view layout as there\n * are less options to consider.\n */\nconst formatListLayout = (\n data: LayoutData,\n {\n schemas,\n schema,\n components,\n }: { schemas: Schema[]; schema?: Schema; components: ComponentsDictionary }\n): ListLayout => {\n const listMetadatas = Object.entries(data.contentType.metadatas).reduce<ListLayout['metadatas']>(\n (acc, [attribute, metadata]) => {\n return {\n ...acc,\n [attribute]: metadata.list,\n };\n },\n {}\n );\n /**\n * The fields arranged by the panels, new panels are made for dynamic zones only.\n */\n const listAttributes = convertListLayoutToFieldLayouts(\n data.contentType.layouts.list,\n schema?.attributes,\n listMetadatas,\n { configurations: data.components, schemas: components },\n schemas\n );\n\n return {\n layout: listAttributes,\n settings: { ...data.contentType.settings, displayName: schema?.info?.displayName },\n metadatas: listMetadatas,\n options: {\n ...schema?.options,\n ...schema?.pluginOptions,\n ...data.contentType.options,\n },\n };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * convertListLayoutToFieldLayouts\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * @internal\n * @description takes the columns from the list view configuration and formats them into a generic object\n * combinining metadata and attribute data.\n *\n * @note We do use this to reformat the list of strings when updating the displayed headers for the list view.\n */\nconst convertListLayoutToFieldLayouts = (\n columns: LayoutData['contentType']['layouts']['list'],\n attributes: Schema['attributes'] = {},\n metadatas: ListLayout['metadatas'],\n components?: {\n configurations: Record<string, ComponentConfiguration>;\n schemas: ComponentsDictionary;\n },\n schemas: Schema[] = []\n) => {\n return columns\n .map((name) => {\n const attribute = attributes[name];\n\n if (!attribute) {\n return null;\n }\n\n const metadata = metadatas[name];\n if (!metadata) {\n return null;\n }\n\n const settings: Partial<Settings> =\n attribute.type === 'component' && components\n ? (components.configurations[attribute.component]?.settings ?? {})\n : {};\n\n return {\n attribute,\n label: metadata.label ?? '',\n mainField: getMainField(attribute, metadata.mainField || settings.mainField, {\n schemas,\n components: components?.schemas ?? {},\n }),\n name: name,\n searchable: metadata.searchable ?? true,\n sortable: metadata.sortable ?? true,\n } satisfies ListFieldLayout;\n })\n .filter((field) => field !== null) as ListFieldLayout[];\n};\n\nexport {\n useDocLayout,\n useDocumentLayout,\n convertListLayoutToFieldLayouts,\n convertEditLayoutToFieldLayouts,\n DEFAULT_SETTINGS,\n};\nexport type {\n EditLayout,\n EditFieldLayout,\n ListCellMeta,\n ListLayout,\n ListFieldLayout,\n UseDocumentLayout,\n};\n"],"names":["RESOLVED_LAYOUT_CACHE_LIMIT","resolvedLayoutCache","getCachedResolvedLayouts","components","data","model","schema","schemas","find","entry","value","setCachedResolvedLayouts","unshift","length","pop","DEFAULT_SETTINGS","bulkable","filterable","searchable","pagination","defaultSortBy","defaultSortOrder","mainField","pageSize","relationOpenMode","useDocumentLayout","useDocument","collectionType","skip","query","useQueryParams","runHookWaterfall","useStrapiApp","state","toggleNotification","useNotification","_unstableFormatAPIError","formatAPIError","useAPIErrorHandler","isLoading","isLoadingSchemas","useContentTypeSchema","currentData","isLoadingConfigs","error","useGetContentTypeConfigurationQuery","isConfigResolvedForModel","contentType","uid","stableLayoutsByModelRef","React","useRef","Map","useEffect","type","message","resolvedLayouts","useMemo","cachedLayouts","normalizedData","normalizeContentManagerLayout","edit","formatEditLayout","list","formatListLayout","listViewConversionContext","componentConfigurations","componentSchemas","contentTypeSchemas","layouts","current","set","stableLayouts","get","editLayout","layout","metadatas","options","settings","listLayout","HOOKS","MUTATE_EDIT_VIEW_LAYOUT","useDocLayout","useDoc","currentPanelIndex","panelledEditAttributes","convertEditLayoutToFieldLayouts","attributes","configurations","reduce","panels","row","some","field","push","componentEditAttributes","Object","entries","acc","configuration","componentSchema","icon","info","displayName","editMetadatas","attribute","metadata","pluginOptions","rows","map","name","fieldMetadata","component","disabled","editable","hint","description","label","getMainField","placeholder","required","size","unique","visible","filter","listMetadatas","listAttributes","convertListLayoutToFieldLayouts","columns","sortable"],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
|
|
5
|
+
function _interopNamespace(e) {
|
|
6
|
+
if (e && e.__esModule) return e;
|
|
7
|
+
var n = Object.create(null);
|
|
8
|
+
if (e) {
|
|
9
|
+
Object.keys(e).forEach(function (k) {
|
|
10
|
+
if (k !== 'default') {
|
|
11
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
12
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return e[k]; }
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
n.default = e;
|
|
20
|
+
return Object.freeze(n);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* How far outside of the scroll container an element counts as near the viewport, so scrolling
|
|
27
|
+
* doesn't reveal content that is still being mounted or loaded.
|
|
28
|
+
*/ const NEAR_VIEWPORT_MARGIN = '1200px 0px';
|
|
29
|
+
const getScrollParent = (element)=>{
|
|
30
|
+
for(let node = element?.parentElement; node; node = node.parentElement){
|
|
31
|
+
const { overflowY } = window.getComputedStyle(node);
|
|
32
|
+
if (/(auto|scroll)/.test(overflowY) && node.scrollHeight > node.clientHeight) {
|
|
33
|
+
return node;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Returns `true` once the element has come close to the viewport of its scroll container, then
|
|
40
|
+
* keeps returning `true`. Without `IntersectionObserver` (e.g. JSDOM), it always returns `true`.
|
|
41
|
+
*/ const useHasBeenNearViewport = (ref)=>{
|
|
42
|
+
const [hasBeenNearViewport, setHasBeenNearViewport] = React__namespace.useState(()=>typeof IntersectionObserver === 'undefined');
|
|
43
|
+
React__namespace.useEffect(()=>{
|
|
44
|
+
const element = ref.current;
|
|
45
|
+
if (hasBeenNearViewport || !element) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const observer = new IntersectionObserver((entries)=>{
|
|
49
|
+
if (entries.some((entry)=>entry.isIntersecting)) {
|
|
50
|
+
setHasBeenNearViewport(true);
|
|
51
|
+
}
|
|
52
|
+
}, {
|
|
53
|
+
root: getScrollParent(element),
|
|
54
|
+
rootMargin: NEAR_VIEWPORT_MARGIN
|
|
55
|
+
});
|
|
56
|
+
observer.observe(element);
|
|
57
|
+
return ()=>{
|
|
58
|
+
observer.disconnect();
|
|
59
|
+
};
|
|
60
|
+
}, [
|
|
61
|
+
hasBeenNearViewport,
|
|
62
|
+
ref
|
|
63
|
+
]);
|
|
64
|
+
return hasBeenNearViewport;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
exports.NEAR_VIEWPORT_MARGIN = NEAR_VIEWPORT_MARGIN;
|
|
68
|
+
exports.getScrollParent = getScrollParent;
|
|
69
|
+
exports.useHasBeenNearViewport = useHasBeenNearViewport;
|
|
70
|
+
//# sourceMappingURL=useHasBeenNearViewport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useHasBeenNearViewport.js","sources":["../../../admin/src/hooks/useHasBeenNearViewport.ts"],"sourcesContent":["import * as React from 'react';\n\n/**\n * How far outside of the scroll container an element counts as near the viewport, so scrolling\n * doesn't reveal content that is still being mounted or loaded.\n */\nconst NEAR_VIEWPORT_MARGIN = '1200px 0px';\n\nconst getScrollParent = (element: HTMLElement | null): HTMLElement | null => {\n for (let node = element?.parentElement; node; node = node.parentElement) {\n const { overflowY } = window.getComputedStyle(node);\n\n if (/(auto|scroll)/.test(overflowY) && node.scrollHeight > node.clientHeight) {\n return node;\n }\n }\n\n return null;\n};\n\n/**\n * Returns `true` once the element has come close to the viewport of its scroll container, then\n * keeps returning `true`. Without `IntersectionObserver` (e.g. JSDOM), it always returns `true`.\n */\nconst useHasBeenNearViewport = <TElement extends HTMLElement>(ref: React.RefObject<TElement>) => {\n const [hasBeenNearViewport, setHasBeenNearViewport] = React.useState(\n () => typeof IntersectionObserver === 'undefined'\n );\n\n React.useEffect(() => {\n const element = ref.current;\n\n if (hasBeenNearViewport || !element) {\n return;\n }\n\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries.some((entry) => entry.isIntersecting)) {\n setHasBeenNearViewport(true);\n }\n },\n { root: getScrollParent(element), rootMargin: NEAR_VIEWPORT_MARGIN }\n );\n\n observer.observe(element);\n\n return () => {\n observer.disconnect();\n };\n }, [hasBeenNearViewport, ref]);\n\n return hasBeenNearViewport;\n};\n\nexport { useHasBeenNearViewport, getScrollParent, NEAR_VIEWPORT_MARGIN };\n"],"names":["NEAR_VIEWPORT_MARGIN","getScrollParent","element","node","parentElement","overflowY","window","getComputedStyle","test","scrollHeight","clientHeight","useHasBeenNearViewport","ref","hasBeenNearViewport","setHasBeenNearViewport","React","useState","IntersectionObserver","useEffect","current","observer","entries","some","entry","isIntersecting","root","rootMargin","observe","disconnect"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAEA;;;AAGC,UACKA,oBAAAA,GAAuB;AAE7B,MAAMC,kBAAkB,CAACC,OAAAA,GAAAA;IACvB,IAAK,IAAIC,OAAOD,OAAAA,EAASE,aAAAA,EAAeD,MAAMA,IAAAA,GAAOA,IAAAA,CAAKC,aAAa,CAAE;AACvE,QAAA,MAAM,EAAEC,SAAS,EAAE,GAAGC,MAAAA,CAAOC,gBAAgB,CAACJ,IAAAA,CAAAA;QAE9C,IAAI,eAAA,CAAgBK,IAAI,CAACH,SAAAA,CAAAA,IAAcF,KAAKM,YAAY,GAAGN,IAAAA,CAAKO,YAAY,EAAE;YAC5E,OAAOP,IAAAA;AACT,QAAA;AACF,IAAA;IAEA,OAAO,IAAA;AACT;AAEA;;;IAIA,MAAMQ,yBAAyB,CAA+BC,GAAAA,GAAAA;IAC5D,MAAM,CAACC,qBAAqBC,sBAAAA,CAAuB,GAAGC,iBAAMC,QAAQ,CAClE,IAAM,OAAOC,oBAAAA,KAAyB,WAAA,CAAA;AAGxCF,IAAAA,gBAAAA,CAAMG,SAAS,CAAC,IAAA;QACd,MAAMhB,OAAAA,GAAUU,IAAIO,OAAO;QAE3B,IAAIN,mBAAAA,IAAuB,CAACX,OAAAA,EAAS;AACnC,YAAA;AACF,QAAA;QAEA,MAAMkB,QAAAA,GAAW,IAAIH,oBAAAA,CACnB,CAACI,OAAAA,GAAAA;AACC,YAAA,IAAIA,QAAQC,IAAI,CAAC,CAACC,KAAAA,GAAUA,KAAAA,CAAMC,cAAc,CAAA,EAAG;gBACjDV,sBAAAA,CAAuB,IAAA,CAAA;AACzB,YAAA;QACF,CAAA,EACA;AAAEW,YAAAA,IAAAA,EAAMxB,eAAAA,CAAgBC,OAAAA,CAAAA;YAAUwB,UAAAA,EAAY1B;AAAqB,SAAA,CAAA;AAGrEoB,QAAAA,QAAAA,CAASO,OAAO,CAACzB,OAAAA,CAAAA;QAEjB,OAAO,IAAA;AACLkB,YAAAA,QAAAA,CAASQ,UAAU,EAAA;AACrB,QAAA,CAAA;IACF,CAAA,EAAG;AAACf,QAAAA,mBAAAA;AAAqBD,QAAAA;AAAI,KAAA,CAAA;IAE7B,OAAOC,mBAAAA;AACT;;;;;;"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* How far outside of the scroll container an element counts as near the viewport, so scrolling
|
|
5
|
+
* doesn't reveal content that is still being mounted or loaded.
|
|
6
|
+
*/ const NEAR_VIEWPORT_MARGIN = '1200px 0px';
|
|
7
|
+
const getScrollParent = (element)=>{
|
|
8
|
+
for(let node = element?.parentElement; node; node = node.parentElement){
|
|
9
|
+
const { overflowY } = window.getComputedStyle(node);
|
|
10
|
+
if (/(auto|scroll)/.test(overflowY) && node.scrollHeight > node.clientHeight) {
|
|
11
|
+
return node;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return null;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Returns `true` once the element has come close to the viewport of its scroll container, then
|
|
18
|
+
* keeps returning `true`. Without `IntersectionObserver` (e.g. JSDOM), it always returns `true`.
|
|
19
|
+
*/ const useHasBeenNearViewport = (ref)=>{
|
|
20
|
+
const [hasBeenNearViewport, setHasBeenNearViewport] = React.useState(()=>typeof IntersectionObserver === 'undefined');
|
|
21
|
+
React.useEffect(()=>{
|
|
22
|
+
const element = ref.current;
|
|
23
|
+
if (hasBeenNearViewport || !element) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const observer = new IntersectionObserver((entries)=>{
|
|
27
|
+
if (entries.some((entry)=>entry.isIntersecting)) {
|
|
28
|
+
setHasBeenNearViewport(true);
|
|
29
|
+
}
|
|
30
|
+
}, {
|
|
31
|
+
root: getScrollParent(element),
|
|
32
|
+
rootMargin: NEAR_VIEWPORT_MARGIN
|
|
33
|
+
});
|
|
34
|
+
observer.observe(element);
|
|
35
|
+
return ()=>{
|
|
36
|
+
observer.disconnect();
|
|
37
|
+
};
|
|
38
|
+
}, [
|
|
39
|
+
hasBeenNearViewport,
|
|
40
|
+
ref
|
|
41
|
+
]);
|
|
42
|
+
return hasBeenNearViewport;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export { NEAR_VIEWPORT_MARGIN, getScrollParent, useHasBeenNearViewport };
|
|
46
|
+
//# sourceMappingURL=useHasBeenNearViewport.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useHasBeenNearViewport.mjs","sources":["../../../admin/src/hooks/useHasBeenNearViewport.ts"],"sourcesContent":["import * as React from 'react';\n\n/**\n * How far outside of the scroll container an element counts as near the viewport, so scrolling\n * doesn't reveal content that is still being mounted or loaded.\n */\nconst NEAR_VIEWPORT_MARGIN = '1200px 0px';\n\nconst getScrollParent = (element: HTMLElement | null): HTMLElement | null => {\n for (let node = element?.parentElement; node; node = node.parentElement) {\n const { overflowY } = window.getComputedStyle(node);\n\n if (/(auto|scroll)/.test(overflowY) && node.scrollHeight > node.clientHeight) {\n return node;\n }\n }\n\n return null;\n};\n\n/**\n * Returns `true` once the element has come close to the viewport of its scroll container, then\n * keeps returning `true`. Without `IntersectionObserver` (e.g. JSDOM), it always returns `true`.\n */\nconst useHasBeenNearViewport = <TElement extends HTMLElement>(ref: React.RefObject<TElement>) => {\n const [hasBeenNearViewport, setHasBeenNearViewport] = React.useState(\n () => typeof IntersectionObserver === 'undefined'\n );\n\n React.useEffect(() => {\n const element = ref.current;\n\n if (hasBeenNearViewport || !element) {\n return;\n }\n\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries.some((entry) => entry.isIntersecting)) {\n setHasBeenNearViewport(true);\n }\n },\n { root: getScrollParent(element), rootMargin: NEAR_VIEWPORT_MARGIN }\n );\n\n observer.observe(element);\n\n return () => {\n observer.disconnect();\n };\n }, [hasBeenNearViewport, ref]);\n\n return hasBeenNearViewport;\n};\n\nexport { useHasBeenNearViewport, getScrollParent, NEAR_VIEWPORT_MARGIN };\n"],"names":["NEAR_VIEWPORT_MARGIN","getScrollParent","element","node","parentElement","overflowY","window","getComputedStyle","test","scrollHeight","clientHeight","useHasBeenNearViewport","ref","hasBeenNearViewport","setHasBeenNearViewport","React","useState","IntersectionObserver","useEffect","current","observer","entries","some","entry","isIntersecting","root","rootMargin","observe","disconnect"],"mappings":";;AAEA;;;AAGC,UACKA,oBAAAA,GAAuB;AAE7B,MAAMC,kBAAkB,CAACC,OAAAA,GAAAA;IACvB,IAAK,IAAIC,OAAOD,OAAAA,EAASE,aAAAA,EAAeD,MAAMA,IAAAA,GAAOA,IAAAA,CAAKC,aAAa,CAAE;AACvE,QAAA,MAAM,EAAEC,SAAS,EAAE,GAAGC,MAAAA,CAAOC,gBAAgB,CAACJ,IAAAA,CAAAA;QAE9C,IAAI,eAAA,CAAgBK,IAAI,CAACH,SAAAA,CAAAA,IAAcF,KAAKM,YAAY,GAAGN,IAAAA,CAAKO,YAAY,EAAE;YAC5E,OAAOP,IAAAA;AACT,QAAA;AACF,IAAA;IAEA,OAAO,IAAA;AACT;AAEA;;;IAIA,MAAMQ,yBAAyB,CAA+BC,GAAAA,GAAAA;IAC5D,MAAM,CAACC,qBAAqBC,sBAAAA,CAAuB,GAAGC,MAAMC,QAAQ,CAClE,IAAM,OAAOC,oBAAAA,KAAyB,WAAA,CAAA;AAGxCF,IAAAA,KAAAA,CAAMG,SAAS,CAAC,IAAA;QACd,MAAMhB,OAAAA,GAAUU,IAAIO,OAAO;QAE3B,IAAIN,mBAAAA,IAAuB,CAACX,OAAAA,EAAS;AACnC,YAAA;AACF,QAAA;QAEA,MAAMkB,QAAAA,GAAW,IAAIH,oBAAAA,CACnB,CAACI,OAAAA,GAAAA;AACC,YAAA,IAAIA,QAAQC,IAAI,CAAC,CAACC,KAAAA,GAAUA,KAAAA,CAAMC,cAAc,CAAA,EAAG;gBACjDV,sBAAAA,CAAuB,IAAA,CAAA;AACzB,YAAA;QACF,CAAA,EACA;AAAEW,YAAAA,IAAAA,EAAMxB,eAAAA,CAAgBC,OAAAA,CAAAA;YAAUwB,UAAAA,EAAY1B;AAAqB,SAAA,CAAA;AAGrEoB,QAAAA,QAAAA,CAASO,OAAO,CAACzB,OAAAA,CAAAA;QAEjB,OAAO,IAAA;AACLkB,YAAAA,QAAAA,CAASQ,UAAU,EAAA;AACrB,QAAA,CAAA;IACF,CAAA,EAAG;AAACf,QAAAA,mBAAAA;AAAqBD,QAAAA;AAAI,KAAA,CAAA;IAE7B,OAAOC,mBAAAA;AACT;;;;"}
|
|
@@ -71,6 +71,75 @@ const pick = (object, keys)=>{
|
|
|
71
71
|
]);
|
|
72
72
|
return Object.fromEntries(entries);
|
|
73
73
|
};
|
|
74
|
+
/** A Media Library asset as an image block stores it. */ const toBlockImage = (asset)=>{
|
|
75
|
+
// Create an object with imageSchema defined and exclude unnecessary props coming from media library config
|
|
76
|
+
const expectedImage = pick(asset, IMAGE_SCHEMA_FIELDS);
|
|
77
|
+
return {
|
|
78
|
+
...expectedImage,
|
|
79
|
+
alternativeText: expectedImage.alternativeText || expectedImage.name,
|
|
80
|
+
url: urls.prefixFileUrlWithBackendUrl(asset.url)
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
const isEmptyParagraph = (node)=>slate.Element.isElement(node) && node.type === 'paragraph' && slate.Node.string(node) === '';
|
|
84
|
+
/**
|
|
85
|
+
* For files dropped onto the editor: returns what inserts each of them, once
|
|
86
|
+
* uploaded, as an image block below the block they were dropped on (or at the
|
|
87
|
+
* end, below the last block). An empty paragraph there is replaced instead.
|
|
88
|
+
* Each image goes below the previous one from the same drop, and a path ref
|
|
89
|
+
* keeps that position right while the content is edited during the upload.
|
|
90
|
+
*/ const createDroppedImagesInserter = (editor, event)=>{
|
|
91
|
+
let targetPath = null;
|
|
92
|
+
try {
|
|
93
|
+
const range = slateReact.ReactEditor.findEventRange(editor, event);
|
|
94
|
+
targetPath = [
|
|
95
|
+
range.anchor.path[0]
|
|
96
|
+
];
|
|
97
|
+
} catch {
|
|
98
|
+
// Dropped below the content or on its padding: no block under the pointer.
|
|
99
|
+
}
|
|
100
|
+
const lastIndex = editor.children.length - 1;
|
|
101
|
+
const target = targetPath ?? (lastIndex >= 0 ? [
|
|
102
|
+
lastIndex
|
|
103
|
+
] : null);
|
|
104
|
+
let previousRef = target ? slate.Editor.pathRef(editor, target) : null;
|
|
105
|
+
let replacesTarget = target !== null && isEmptyParagraph(slate.Node.get(editor, target));
|
|
106
|
+
return (asset)=>{
|
|
107
|
+
const imageNode = {
|
|
108
|
+
type: 'image',
|
|
109
|
+
image: toBlockImage(asset),
|
|
110
|
+
children: [
|
|
111
|
+
{
|
|
112
|
+
type: 'text',
|
|
113
|
+
text: ''
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
};
|
|
117
|
+
const previousPath = previousRef?.current;
|
|
118
|
+
let at;
|
|
119
|
+
if (previousPath && replacesTarget && isEmptyParagraph(slate.Node.get(editor, previousPath))) {
|
|
120
|
+
at = previousPath;
|
|
121
|
+
} else {
|
|
122
|
+
at = previousPath ? slate.Path.next(previousPath) : [
|
|
123
|
+
editor.children.length
|
|
124
|
+
];
|
|
125
|
+
}
|
|
126
|
+
// Same as the image dialog: normalize once the image is in, or replacing the only block
|
|
127
|
+
// leaves a paragraph after it
|
|
128
|
+
slate.Editor.withoutNormalizing(editor, ()=>{
|
|
129
|
+
if (replacesTarget && previousPath && slate.Path.equals(at, previousPath)) {
|
|
130
|
+
slate.Transforms.removeNodes(editor, {
|
|
131
|
+
at
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
slate.Transforms.insertNodes(editor, imageNode, {
|
|
135
|
+
at
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
replacesTarget = false;
|
|
139
|
+
previousRef?.unref();
|
|
140
|
+
previousRef = slate.Editor.pathRef(editor, at);
|
|
141
|
+
};
|
|
142
|
+
};
|
|
74
143
|
// Type guard to force TypeScript to narrow the type of the element in Blocks component
|
|
75
144
|
const isImage = (element)=>{
|
|
76
145
|
return element.type === 'image';
|
|
@@ -129,40 +198,34 @@ const ImageDialog = ()=>{
|
|
|
129
198
|
});
|
|
130
199
|
if (!nodeEntryBeingReplaced) return;
|
|
131
200
|
const [, pathToInsert] = nodeEntryBeingReplaced;
|
|
132
|
-
//
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
201
|
+
// Normalize once the images are in: replacing the only block would otherwise leave an empty
|
|
202
|
+
// document for a moment, which normalization fills with a paragraph that stays after the images
|
|
203
|
+
slate.Editor.withoutNormalizing(editor, ()=>{
|
|
204
|
+
// Remove the previous node that is being replaced by an image
|
|
205
|
+
slate.Transforms.removeNodes(editor);
|
|
206
|
+
// Convert images to nodes and insert them
|
|
207
|
+
const nodesToInsert = images.map((image)=>{
|
|
208
|
+
const imageNode = {
|
|
209
|
+
type: 'image',
|
|
210
|
+
image,
|
|
211
|
+
children: [
|
|
212
|
+
{
|
|
213
|
+
type: 'text',
|
|
214
|
+
text: ''
|
|
215
|
+
}
|
|
216
|
+
]
|
|
217
|
+
};
|
|
218
|
+
return imageNode;
|
|
219
|
+
});
|
|
220
|
+
slate.Transforms.insertNodes(editor, nodesToInsert, {
|
|
221
|
+
at: pathToInsert
|
|
222
|
+
});
|
|
223
|
+
// Set the selection on the image since it was cleared by calling removeNodes
|
|
224
|
+
slate.Transforms.select(editor, pathToInsert);
|
|
150
225
|
});
|
|
151
|
-
// Set the selection on the image since it was cleared by calling removeNodes
|
|
152
|
-
slate.Transforms.select(editor, pathToInsert);
|
|
153
226
|
};
|
|
154
227
|
const handleSelectAssets = (images)=>{
|
|
155
|
-
|
|
156
|
-
// Create an object with imageSchema defined and exclude unnecessary props coming from media library config
|
|
157
|
-
const expectedImage = pick(image, IMAGE_SCHEMA_FIELDS);
|
|
158
|
-
const nodeImage = {
|
|
159
|
-
...expectedImage,
|
|
160
|
-
alternativeText: expectedImage.alternativeText || expectedImage.name,
|
|
161
|
-
url: urls.prefixFileUrlWithBackendUrl(image.url)
|
|
162
|
-
};
|
|
163
|
-
return nodeImage;
|
|
164
|
-
});
|
|
165
|
-
insertImages(formattedImages);
|
|
228
|
+
insertImages(images.map(toBlockImage));
|
|
166
229
|
setIsOpen(false);
|
|
167
230
|
};
|
|
168
231
|
return /*#__PURE__*/ jsxRuntime.jsx(MediaLibraryDialog, {
|
|
@@ -197,7 +260,13 @@ const imageBlocks = {
|
|
|
197
260
|
},
|
|
198
261
|
matchNode: (node)=>node.type === 'image',
|
|
199
262
|
isInBlocksSelector: true,
|
|
200
|
-
handleBackspaceKey (editor) {
|
|
263
|
+
handleBackspaceKey (editor, event) {
|
|
264
|
+
// A selection across several blocks is Slate's own deletion to make
|
|
265
|
+
if (editor.selection && slate.Range.isExpanded(editor.selection)) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
// The image is removed here: Slate's own Backspace would then delete the block before it
|
|
269
|
+
event.preventDefault();
|
|
201
270
|
// Prevent issue where the image remains when it's the only block in the document
|
|
202
271
|
if (editor.children.length === 1) {
|
|
203
272
|
slate.Transforms.setNodes(editor, {
|
|
@@ -240,5 +309,6 @@ const imageBlocks = {
|
|
|
240
309
|
}
|
|
241
310
|
};
|
|
242
311
|
|
|
312
|
+
exports.createDroppedImagesInserter = createDroppedImagesInserter;
|
|
243
313
|
exports.imageBlocks = imageBlocks;
|
|
244
314
|
//# sourceMappingURL=Image.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Image.js","sources":["../../../../../../../../admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useStrapiApp } from '@strapi/admin/strapi-admin';\nimport { Box, Flex, FlexComponent } from '@strapi/design-system';\nimport { Image as Picture } from '@strapi/icons';\nimport { type Element, Transforms, Editor } from 'slate';\nimport { useFocused, type RenderElementProps, useSelected } from 'slate-react';\nimport { styled, css } from 'styled-components';\n\nimport { prefixFileUrlWithBackendUrl } from '../../../../../../utils/urls';\nimport { useBlocksEditorContext, type BlocksStore } from '../BlocksEditor';\nimport { type Block } from '../utils/types';\n\nimport type { Schema } from '@strapi/types';\n\nconst ImageWrapper = styled<FlexComponent>(Flex)<{ $isFocused?: boolean }>`\n transition-property: box-shadow;\n transition-duration: 0.2s;\n ${(props) =>\n props.$isFocused &&\n css`\n box-shadow: ${props.theme.colors.primary600} 0px 0px 0px 3px;\n `}\n\n & > img {\n height: auto;\n // The max-height is decided with the design team, the 56px is the height of the toolbar\n max-height: calc(512px - 56px);\n max-width: 100%;\n object-fit: contain;\n }\n`;\n\nconst IMAGE_SCHEMA_FIELDS = [\n 'name',\n 'alternativeText',\n 'url',\n 'caption',\n 'width',\n 'height',\n 'formats',\n 'hash',\n 'ext',\n 'mime',\n 'size',\n 'previewUrl',\n 'provider',\n 'provider_metadata',\n 'createdAt',\n 'updatedAt',\n];\n\nconst pick = <T extends object, K extends keyof T>(object: T, keys: K[]): Pick<T, K> => {\n const entries = keys.map((key) => [key, object[key]]);\n return Object.fromEntries(entries);\n};\n\n// Type guard to force TypeScript to narrow the type of the element in Blocks component\nconst isImage = (element: Element): element is Block<'image'> => {\n return element.type === 'image';\n};\n\n// Added a background color to the image wrapper to make it easier to recognize the image block\nconst Image = ({ attributes, children, element }: RenderElementProps) => {\n const editorIsFocused = useFocused();\n const imageIsSelected = useSelected();\n\n if (!isImage(element)) {\n return null;\n }\n const { url, alternativeText, width, height } = element.image;\n\n return (\n <Box {...attributes}>\n {children}\n <ImageWrapper\n background=\"neutral100\"\n contentEditable={false}\n justifyContent=\"center\"\n $isFocused={editorIsFocused && imageIsSelected}\n hasRadius\n >\n <img src={url} alt={alternativeText} width={width} height={height} />\n </ImageWrapper>\n </Box>\n );\n};\n\nconst ImageDialog = () => {\n const [isOpen, setIsOpen] = React.useState(true);\n const { editor } = useBlocksEditorContext('ImageDialog');\n const components = useStrapiApp('ImageDialog', (state) => state.components);\n\n if (!components || !isOpen) return null;\n\n const MediaLibraryDialog = components['media-library'] as React.ComponentType<{\n allowedTypes: Schema.Attribute.MediaKind[];\n onClose: () => void;\n onSelectAssets: (_images: Schema.Attribute.MediaValue<true>) => void;\n }>;\n\n const insertImages = (images: Block<'image'>['image'][]) => {\n // If the selection is inside a list, split the list so that the modified block is outside of it\n Transforms.unwrapNodes(editor, {\n match: (node) => !Editor.isEditor(node) && node.type === 'list',\n split: true,\n });\n\n // Save the path of the node that is being replaced by an image to insert the images there later\n // It's the closest full block node above the selection\n const nodeEntryBeingReplaced = Editor.above(editor, {\n match(node) {\n if (Editor.isEditor(node)) return false;\n\n const isInlineNode = ['text', 'link'].includes(node.type);\n\n return !isInlineNode;\n },\n });\n\n if (!nodeEntryBeingReplaced) return;\n const [, pathToInsert] = nodeEntryBeingReplaced;\n\n // Remove the previous node that is being replaced by an image\n Transforms.removeNodes(editor);\n\n // Convert images to nodes and insert them\n const nodesToInsert = images.map((image) => {\n const imageNode: Block<'image'> = {\n type: 'image',\n image,\n children: [{ type: 'text', text: '' }],\n };\n return imageNode;\n });\n Transforms.insertNodes(editor, nodesToInsert, { at: pathToInsert });\n\n // Set the selection on the image since it was cleared by calling removeNodes\n Transforms.select(editor, pathToInsert);\n };\n\n const handleSelectAssets = (images: Schema.Attribute.MediaValue<true>) => {\n const formattedImages = images.map((image) => {\n // Create an object with imageSchema defined and exclude unnecessary props coming from media library config\n const expectedImage = pick(image, IMAGE_SCHEMA_FIELDS);\n\n const nodeImage: Block<'image'>['image'] = {\n ...expectedImage,\n alternativeText: expectedImage.alternativeText || expectedImage.name,\n url: prefixFileUrlWithBackendUrl(image.url),\n };\n\n return nodeImage;\n });\n\n insertImages(formattedImages);\n setIsOpen(false);\n };\n\n return (\n <MediaLibraryDialog\n allowedTypes={['images']}\n onClose={() => setIsOpen(false)}\n onSelectAssets={handleSelectAssets}\n />\n );\n};\n\n/**\n * Images are void elements. They handle the rendering of their children instead of Slate.\n * See the Slate documentation for more information:\n * - https://docs.slatejs.org/api/nodes/element#void-vs-not-void\n * - https://docs.slatejs.org/api/nodes/element#rendering-void-elements\n */\nconst withImages = (editor: Editor) => {\n const { isVoid } = editor;\n\n editor.isVoid = (element) => {\n return element.type === 'image' ? true : isVoid(element);\n };\n\n return editor;\n};\n\nconst imageBlocks: Pick<BlocksStore, 'image'> = {\n image: {\n renderElement: (props) => <Image {...props} />,\n icon: Picture,\n label: {\n id: 'components.Blocks.blocks.image',\n defaultMessage: 'Image',\n },\n matchNode: (node) => node.type === 'image',\n isInBlocksSelector: true,\n handleBackspaceKey(editor) {\n // Prevent issue where the image remains when it's the only block in the document\n if (editor.children.length === 1) {\n Transforms.setNodes(editor, {\n type: 'paragraph',\n // @ts-expect-error we're only setting image as null so that Slate deletes it\n image: null,\n children: [{ type: 'text', text: '' }],\n });\n } else {\n Transforms.removeNodes(editor);\n }\n },\n handleEnterKey(editor) {\n Transforms.insertNodes(editor, {\n type: 'paragraph',\n children: [{ type: 'text', text: '' }],\n });\n },\n handleConvert: () => {\n /**\n * All the logic is managed inside the ImageDialog component,\n * because the blocks are only created when the user selects images in the modal and submits\n * and if he closes the modal, then no changes are made to the editor\n */\n return () => <ImageDialog />;\n },\n snippets: ['!['],\n plugin: withImages,\n },\n};\n\nexport { imageBlocks };\n"],"names":["ImageWrapper","styled","Flex","props","$isFocused","css","theme","colors","primary600","IMAGE_SCHEMA_FIELDS","pick","object","keys","entries","map","key","Object","fromEntries","isImage","element","type","Image","attributes","children","editorIsFocused","useFocused","imageIsSelected","useSelected","url","alternativeText","width","height","image","_jsxs","Box","_jsx","background","contentEditable","justifyContent","hasRadius","img","src","alt","ImageDialog","isOpen","setIsOpen","React","useState","editor","useBlocksEditorContext","components","useStrapiApp","state","MediaLibraryDialog","insertImages","images","Transforms","unwrapNodes","match","node","Editor","isEditor","split","nodeEntryBeingReplaced","above","isInlineNode","includes","pathToInsert","removeNodes","nodesToInsert","imageNode","text","insertNodes","at","select","handleSelectAssets","formattedImages","expectedImage","nodeImage","name","prefixFileUrlWithBackendUrl","allowedTypes","onClose","onSelectAssets","withImages","isVoid","imageBlocks","renderElement","icon","Picture","label","id","defaultMessage","matchNode","isInBlocksSelector","handleBackspaceKey","length","setNodes","handleEnterKey","handleConvert","snippets","plugin"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Image.js","sources":["../../../../../../../../admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useStrapiApp } from '@strapi/admin/strapi-admin';\nimport { Box, Flex, FlexComponent } from '@strapi/design-system';\nimport { Image as Picture } from '@strapi/icons';\nimport { Element, Transforms, Editor, Node, Path, Range } from 'slate';\nimport { ReactEditor, useFocused, type RenderElementProps, useSelected } from 'slate-react';\nimport { styled, css } from 'styled-components';\n\nimport { prefixFileUrlWithBackendUrl } from '../../../../../../utils/urls';\nimport { useBlocksEditorContext, type BlocksStore } from '../BlocksEditor';\nimport { type Block } from '../utils/types';\n\nimport type { Schema } from '@strapi/types';\n\nconst ImageWrapper = styled<FlexComponent>(Flex)<{ $isFocused?: boolean }>`\n transition-property: box-shadow;\n transition-duration: 0.2s;\n ${(props) =>\n props.$isFocused &&\n css`\n box-shadow: ${props.theme.colors.primary600} 0px 0px 0px 3px;\n `}\n\n & > img {\n height: auto;\n // The max-height is decided with the design team, the 56px is the height of the toolbar\n max-height: calc(512px - 56px);\n max-width: 100%;\n object-fit: contain;\n }\n`;\n\nconst IMAGE_SCHEMA_FIELDS = [\n 'name',\n 'alternativeText',\n 'url',\n 'caption',\n 'width',\n 'height',\n 'formats',\n 'hash',\n 'ext',\n 'mime',\n 'size',\n 'previewUrl',\n 'provider',\n 'provider_metadata',\n 'createdAt',\n 'updatedAt',\n];\n\nconst pick = <T extends object, K extends keyof T>(object: T, keys: K[]): Pick<T, K> => {\n const entries = keys.map((key) => [key, object[key]]);\n return Object.fromEntries(entries);\n};\n\ntype MediaAsset = Schema.Attribute.MediaValue<true>[number];\n\n/** A Media Library asset as an image block stores it. */\nconst toBlockImage = (asset: MediaAsset): Block<'image'>['image'] => {\n // Create an object with imageSchema defined and exclude unnecessary props coming from media library config\n const expectedImage = pick(asset, IMAGE_SCHEMA_FIELDS);\n\n return {\n ...expectedImage,\n alternativeText: expectedImage.alternativeText || expectedImage.name,\n url: prefixFileUrlWithBackendUrl(asset.url),\n };\n};\n\nconst isEmptyParagraph = (node: Node) =>\n Element.isElement(node) && node.type === 'paragraph' && Node.string(node) === '';\n\n/**\n * For files dropped onto the editor: returns what inserts each of them, once\n * uploaded, as an image block below the block they were dropped on (or at the\n * end, below the last block). An empty paragraph there is replaced instead.\n * Each image goes below the previous one from the same drop, and a path ref\n * keeps that position right while the content is edited during the upload.\n */\nconst createDroppedImagesInserter = (editor: Editor, event: React.DragEvent) => {\n let targetPath: Path | null = null;\n\n try {\n const range = ReactEditor.findEventRange(editor, event);\n targetPath = [range.anchor.path[0]];\n } catch {\n // Dropped below the content or on its padding: no block under the pointer.\n }\n\n const lastIndex = editor.children.length - 1;\n const target = targetPath ?? (lastIndex >= 0 ? [lastIndex] : null);\n let previousRef = target ? Editor.pathRef(editor, target) : null;\n let replacesTarget = target !== null && isEmptyParagraph(Node.get(editor, target));\n\n return (asset: MediaAsset) => {\n const imageNode: Block<'image'> = {\n type: 'image',\n image: toBlockImage(asset),\n children: [{ type: 'text', text: '' }],\n };\n\n const previousPath = previousRef?.current;\n let at: Path;\n\n if (previousPath && replacesTarget && isEmptyParagraph(Node.get(editor, previousPath))) {\n at = previousPath;\n } else {\n at = previousPath ? Path.next(previousPath) : [editor.children.length];\n }\n\n // Same as the image dialog: normalize once the image is in, or replacing the only block\n // leaves a paragraph after it\n Editor.withoutNormalizing(editor, () => {\n if (replacesTarget && previousPath && Path.equals(at, previousPath)) {\n Transforms.removeNodes(editor, { at });\n }\n\n Transforms.insertNodes(editor, imageNode, { at });\n });\n replacesTarget = false;\n\n previousRef?.unref();\n previousRef = Editor.pathRef(editor, at);\n };\n};\n\n// Type guard to force TypeScript to narrow the type of the element in Blocks component\nconst isImage = (element: Element): element is Block<'image'> => {\n return element.type === 'image';\n};\n\n// Added a background color to the image wrapper to make it easier to recognize the image block\nconst Image = ({ attributes, children, element }: RenderElementProps) => {\n const editorIsFocused = useFocused();\n const imageIsSelected = useSelected();\n\n if (!isImage(element)) {\n return null;\n }\n const { url, alternativeText, width, height } = element.image;\n\n return (\n <Box {...attributes}>\n {children}\n <ImageWrapper\n background=\"neutral100\"\n contentEditable={false}\n justifyContent=\"center\"\n $isFocused={editorIsFocused && imageIsSelected}\n hasRadius\n >\n <img src={url} alt={alternativeText} width={width} height={height} />\n </ImageWrapper>\n </Box>\n );\n};\n\nconst ImageDialog = () => {\n const [isOpen, setIsOpen] = React.useState(true);\n const { editor } = useBlocksEditorContext('ImageDialog');\n const components = useStrapiApp('ImageDialog', (state) => state.components);\n\n if (!components || !isOpen) return null;\n\n const MediaLibraryDialog = components['media-library'] as React.ComponentType<{\n allowedTypes: Schema.Attribute.MediaKind[];\n onClose: () => void;\n onSelectAssets: (_images: Schema.Attribute.MediaValue<true>) => void;\n }>;\n\n const insertImages = (images: Block<'image'>['image'][]) => {\n // If the selection is inside a list, split the list so that the modified block is outside of it\n Transforms.unwrapNodes(editor, {\n match: (node) => !Editor.isEditor(node) && node.type === 'list',\n split: true,\n });\n\n // Save the path of the node that is being replaced by an image to insert the images there later\n // It's the closest full block node above the selection\n const nodeEntryBeingReplaced = Editor.above(editor, {\n match(node) {\n if (Editor.isEditor(node)) return false;\n\n const isInlineNode = ['text', 'link'].includes(node.type);\n\n return !isInlineNode;\n },\n });\n\n if (!nodeEntryBeingReplaced) return;\n const [, pathToInsert] = nodeEntryBeingReplaced;\n\n // Normalize once the images are in: replacing the only block would otherwise leave an empty\n // document for a moment, which normalization fills with a paragraph that stays after the images\n Editor.withoutNormalizing(editor, () => {\n // Remove the previous node that is being replaced by an image\n Transforms.removeNodes(editor);\n\n // Convert images to nodes and insert them\n const nodesToInsert = images.map((image) => {\n const imageNode: Block<'image'> = {\n type: 'image',\n image,\n children: [{ type: 'text', text: '' }],\n };\n return imageNode;\n });\n Transforms.insertNodes(editor, nodesToInsert, { at: pathToInsert });\n\n // Set the selection on the image since it was cleared by calling removeNodes\n Transforms.select(editor, pathToInsert);\n });\n };\n\n const handleSelectAssets = (images: Schema.Attribute.MediaValue<true>) => {\n insertImages(images.map(toBlockImage));\n setIsOpen(false);\n };\n\n return (\n <MediaLibraryDialog\n allowedTypes={['images']}\n onClose={() => setIsOpen(false)}\n onSelectAssets={handleSelectAssets}\n />\n );\n};\n\n/**\n * Images are void elements. They handle the rendering of their children instead of Slate.\n * See the Slate documentation for more information:\n * - https://docs.slatejs.org/api/nodes/element#void-vs-not-void\n * - https://docs.slatejs.org/api/nodes/element#rendering-void-elements\n */\nconst withImages = (editor: Editor) => {\n const { isVoid } = editor;\n\n editor.isVoid = (element) => {\n return element.type === 'image' ? true : isVoid(element);\n };\n\n return editor;\n};\n\nconst imageBlocks: Pick<BlocksStore, 'image'> = {\n image: {\n renderElement: (props) => <Image {...props} />,\n icon: Picture,\n label: {\n id: 'components.Blocks.blocks.image',\n defaultMessage: 'Image',\n },\n matchNode: (node) => node.type === 'image',\n isInBlocksSelector: true,\n handleBackspaceKey(editor, event) {\n // A selection across several blocks is Slate's own deletion to make\n if (editor.selection && Range.isExpanded(editor.selection)) {\n return;\n }\n\n // The image is removed here: Slate's own Backspace would then delete the block before it\n event.preventDefault();\n\n // Prevent issue where the image remains when it's the only block in the document\n if (editor.children.length === 1) {\n Transforms.setNodes(editor, {\n type: 'paragraph',\n // @ts-expect-error we're only setting image as null so that Slate deletes it\n image: null,\n children: [{ type: 'text', text: '' }],\n });\n } else {\n Transforms.removeNodes(editor);\n }\n },\n handleEnterKey(editor) {\n Transforms.insertNodes(editor, {\n type: 'paragraph',\n children: [{ type: 'text', text: '' }],\n });\n },\n handleConvert: () => {\n /**\n * All the logic is managed inside the ImageDialog component,\n * because the blocks are only created when the user selects images in the modal and submits\n * and if he closes the modal, then no changes are made to the editor\n */\n return () => <ImageDialog />;\n },\n snippets: ['!['],\n plugin: withImages,\n },\n};\n\nexport { imageBlocks, createDroppedImagesInserter };\n"],"names":["ImageWrapper","styled","Flex","props","$isFocused","css","theme","colors","primary600","IMAGE_SCHEMA_FIELDS","pick","object","keys","entries","map","key","Object","fromEntries","toBlockImage","asset","expectedImage","alternativeText","name","url","prefixFileUrlWithBackendUrl","isEmptyParagraph","node","Element","isElement","type","Node","string","createDroppedImagesInserter","editor","event","targetPath","range","ReactEditor","findEventRange","anchor","path","lastIndex","children","length","target","previousRef","Editor","pathRef","replacesTarget","get","imageNode","image","text","previousPath","current","at","Path","next","withoutNormalizing","equals","Transforms","removeNodes","insertNodes","unref","isImage","element","Image","attributes","editorIsFocused","useFocused","imageIsSelected","useSelected","width","height","_jsxs","Box","_jsx","background","contentEditable","justifyContent","hasRadius","img","src","alt","ImageDialog","isOpen","setIsOpen","React","useState","useBlocksEditorContext","components","useStrapiApp","state","MediaLibraryDialog","insertImages","images","unwrapNodes","match","isEditor","split","nodeEntryBeingReplaced","above","isInlineNode","includes","pathToInsert","nodesToInsert","select","handleSelectAssets","allowedTypes","onClose","onSelectAssets","withImages","isVoid","imageBlocks","renderElement","icon","Picture","label","id","defaultMessage","matchNode","isInBlocksSelector","handleBackspaceKey","selection","Range","isExpanded","preventDefault","setNodes","handleEnterKey","handleConvert","snippets","plugin"],"mappings":"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"}
|