@strapi/content-manager 0.0.0-next.d9724d67b33363354d7171a9f2265e1c42485e13 → 0.0.0-next.da19c0501ff87d14fb664b55b8e0630d3c548485
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/components/ConfigurationForm/EditFieldForm.js +1 -1
- package/dist/admin/components/ConfigurationForm/EditFieldForm.js.map +1 -1
- package/dist/admin/components/ConfigurationForm/EditFieldForm.mjs +1 -1
- package/dist/admin/components/ConfigurationForm/EditFieldForm.mjs.map +1 -1
- package/dist/admin/components/ConfigurationForm/Fields.js +4 -1
- package/dist/admin/components/ConfigurationForm/Fields.js.map +1 -1
- package/dist/admin/components/ConfigurationForm/Fields.mjs +5 -2
- package/dist/admin/components/ConfigurationForm/Fields.mjs.map +1 -1
- package/dist/admin/components/ConfigurationForm/Form.js +1 -1
- package/dist/admin/components/ConfigurationForm/Form.js.map +1 -1
- package/dist/admin/components/ConfigurationForm/Form.mjs +3 -3
- package/dist/admin/components/ConfigurationForm/Form.mjs.map +1 -1
- package/dist/admin/components/DragPreviews/CardDragPreview.js +3 -1
- package/dist/admin/components/DragPreviews/CardDragPreview.js.map +1 -1
- package/dist/admin/components/DragPreviews/CardDragPreview.mjs +3 -1
- package/dist/admin/components/DragPreviews/CardDragPreview.mjs.map +1 -1
- package/dist/admin/components/DragPreviews/ComponentDragPreview.js +3 -1
- package/dist/admin/components/DragPreviews/ComponentDragPreview.js.map +1 -1
- package/dist/admin/components/DragPreviews/ComponentDragPreview.mjs +3 -1
- package/dist/admin/components/DragPreviews/ComponentDragPreview.mjs.map +1 -1
- package/dist/admin/components/DragPreviews/RelationDragPreview.js +3 -1
- package/dist/admin/components/DragPreviews/RelationDragPreview.js.map +1 -1
- package/dist/admin/components/DragPreviews/RelationDragPreview.mjs +3 -1
- package/dist/admin/components/DragPreviews/RelationDragPreview.mjs.map +1 -1
- package/dist/admin/components/LeftMenu.js +90 -48
- package/dist/admin/components/LeftMenu.js.map +1 -1
- package/dist/admin/components/LeftMenu.mjs +92 -50
- package/dist/admin/components/LeftMenu.mjs.map +1 -1
- package/dist/admin/components/Widgets.js +22 -6
- package/dist/admin/components/Widgets.js.map +1 -1
- package/dist/admin/components/Widgets.mjs +22 -6
- package/dist/admin/components/Widgets.mjs.map +1 -1
- package/dist/admin/history/components/VersionHeader.js +1 -0
- package/dist/admin/history/components/VersionHeader.js.map +1 -1
- package/dist/admin/history/components/VersionHeader.mjs +1 -0
- package/dist/admin/history/components/VersionHeader.mjs.map +1 -1
- package/dist/admin/history/components/VersionsList.js +1 -1
- package/dist/admin/history/components/VersionsList.js.map +1 -1
- package/dist/admin/history/components/VersionsList.mjs +1 -1
- package/dist/admin/history/components/VersionsList.mjs.map +1 -1
- package/dist/admin/history/pages/History.js +7 -7
- package/dist/admin/history/pages/History.js.map +1 -1
- package/dist/admin/history/pages/History.mjs +7 -7
- package/dist/admin/history/pages/History.mjs.map +1 -1
- package/dist/admin/layout.js +27 -6
- package/dist/admin/layout.js.map +1 -1
- package/dist/admin/layout.mjs +28 -7
- package/dist/admin/layout.mjs.map +1 -1
- package/dist/admin/pages/EditView/EditViewPage.js +7 -3
- package/dist/admin/pages/EditView/EditViewPage.js.map +1 -1
- package/dist/admin/pages/EditView/EditViewPage.mjs +8 -4
- package/dist/admin/pages/EditView/EditViewPage.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/DocumentActions.js +6 -0
- package/dist/admin/pages/EditView/components/DocumentActions.js.map +1 -1
- package/dist/admin/pages/EditView/components/DocumentActions.mjs +6 -0
- package/dist/admin/pages/EditView/components/DocumentActions.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.js +66 -2
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.mjs +66 -2
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.js +2 -2
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.mjs +2 -2
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/utils/links.js +7 -3
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/utils/links.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/utils/links.mjs +7 -3
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/utils/links.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js +2 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs +3 -2
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.js +1 -2
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.mjs +1 -2
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js +4 -3
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs +5 -4
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +2 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs +3 -2
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/UID.js +2 -1
- package/dist/admin/pages/EditView/components/FormInputs/UID.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/UID.mjs +2 -1
- package/dist/admin/pages/EditView/components/FormInputs/UID.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.js +2 -2
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.mjs +2 -2
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormLayout.js +13 -8
- package/dist/admin/pages/EditView/components/FormLayout.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormLayout.mjs +14 -8
- package/dist/admin/pages/EditView/components/FormLayout.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/Header.js +85 -25
- package/dist/admin/pages/EditView/components/Header.js.map +1 -1
- package/dist/admin/pages/EditView/components/Header.mjs +87 -27
- package/dist/admin/pages/EditView/components/Header.mjs.map +1 -1
- package/dist/admin/pages/ListConfiguration/ListConfigurationPage.js +1 -0
- package/dist/admin/pages/ListConfiguration/ListConfigurationPage.js.map +1 -1
- package/dist/admin/pages/ListConfiguration/ListConfigurationPage.mjs +1 -0
- package/dist/admin/pages/ListConfiguration/ListConfigurationPage.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/Filters.js +4 -1
- package/dist/admin/pages/ListView/components/Filters.js.map +1 -1
- package/dist/admin/pages/ListView/components/Filters.mjs +4 -1
- package/dist/admin/pages/ListView/components/Filters.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/ViewSettingsMenu.js +5 -2
- package/dist/admin/pages/ListView/components/ViewSettingsMenu.js.map +1 -1
- package/dist/admin/pages/ListView/components/ViewSettingsMenu.mjs +5 -2
- package/dist/admin/pages/ListView/components/ViewSettingsMenu.mjs.map +1 -1
- package/dist/admin/preview/components/InputPopover.js +29 -9
- package/dist/admin/preview/components/InputPopover.js.map +1 -1
- package/dist/admin/preview/components/InputPopover.mjs +31 -11
- package/dist/admin/preview/components/InputPopover.mjs.map +1 -1
- package/dist/admin/preview/pages/Preview.js +6 -6
- package/dist/admin/preview/pages/Preview.js.map +1 -1
- package/dist/admin/preview/pages/Preview.mjs +6 -6
- package/dist/admin/preview/pages/Preview.mjs.map +1 -1
- package/dist/admin/preview/utils/constants.js +34 -0
- package/dist/admin/preview/utils/constants.js.map +1 -1
- package/dist/admin/preview/utils/constants.mjs +34 -1
- package/dist/admin/preview/utils/constants.mjs.map +1 -1
- package/dist/admin/preview/utils/fieldUtils.js +13 -4
- package/dist/admin/preview/utils/fieldUtils.js.map +1 -1
- package/dist/admin/preview/utils/fieldUtils.mjs +13 -5
- package/dist/admin/preview/utils/fieldUtils.mjs.map +1 -1
- package/dist/admin/preview/utils/previewScript.js +120 -44
- package/dist/admin/preview/utils/previewScript.js.map +1 -1
- package/dist/admin/preview/utils/previewScript.mjs +120 -44
- package/dist/admin/preview/utils/previewScript.mjs.map +1 -1
- package/dist/admin/services/api.js +2 -1
- package/dist/admin/services/api.js.map +1 -1
- package/dist/admin/services/api.mjs +2 -1
- package/dist/admin/services/api.mjs.map +1 -1
- package/dist/admin/services/documents.js +19 -3
- package/dist/admin/services/documents.js.map +1 -1
- package/dist/admin/services/documents.mjs +19 -3
- package/dist/admin/services/documents.mjs.map +1 -1
- package/dist/admin/src/components/LeftMenu.d.ts +3 -1
- package/dist/admin/src/components/Widgets.d.ts +6 -2
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/links.d.ts +2 -0
- package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +0 -3
- package/dist/admin/src/pages/EditView/components/Header.d.ts +4 -0
- package/dist/admin/src/preview/services/preview.d.ts +1 -1
- package/dist/admin/src/preview/utils/constants.d.ts +35 -0
- package/dist/admin/src/preview/utils/fieldUtils.d.ts +6 -0
- package/dist/admin/src/preview/utils/previewScript.d.ts +1 -0
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +3 -3
- package/dist/admin/src/services/documents.d.ts +16 -16
- package/dist/admin/src/services/homepage.d.ts +1 -1
- package/dist/admin/src/services/init.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/translations/en.json.js +5 -0
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +5 -0
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/server/controllers/collection-types.js +2 -1
- package/dist/server/controllers/collection-types.js.map +1 -1
- package/dist/server/controllers/collection-types.mjs +2 -1
- package/dist/server/controllers/collection-types.mjs.map +1 -1
- package/dist/server/controllers/relations.js +6 -4
- package/dist/server/controllers/relations.js.map +1 -1
- package/dist/server/controllers/relations.mjs +6 -4
- package/dist/server/controllers/relations.mjs.map +1 -1
- package/dist/server/controllers/single-types.js.map +1 -1
- package/dist/server/controllers/single-types.mjs.map +1 -1
- package/dist/server/preview/services/preview-config.js +8 -33
- package/dist/server/preview/services/preview-config.js.map +1 -1
- package/dist/server/preview/services/preview-config.mjs +9 -34
- package/dist/server/preview/services/preview-config.mjs.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/single-types.d.ts.map +1 -1
- package/dist/server/src/preview/services/preview-config.d.ts.map +1 -1
- package/package.json +7 -7
|
@@ -16,7 +16,41 @@ const scriptResponse = previewScript.previewScript(false);
|
|
|
16
16
|
STRAPI_UPDATE: 'strapiUpdate',
|
|
17
17
|
STRAPI_SCRIPT: 'strapiScript'
|
|
18
18
|
};
|
|
19
|
+
/**
|
|
20
|
+
* Error messages for preview field operations.
|
|
21
|
+
* This information is used to trigger notifications.
|
|
22
|
+
*/ const PREVIEW_ERROR_MESSAGES = {
|
|
23
|
+
INVALID_FIELD_PATH: {
|
|
24
|
+
type: 'danger',
|
|
25
|
+
message: {
|
|
26
|
+
id: 'content-manager.preview.error.invalid-field-path',
|
|
27
|
+
defaultMessage: 'Could not locate this field in the current document'
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
RELATIONS_NOT_HANDLED: {
|
|
31
|
+
type: 'info',
|
|
32
|
+
message: {
|
|
33
|
+
id: 'content-manager.preview.error.relations-not-handled',
|
|
34
|
+
defaultMessage: 'Inline editing for relations is not currently supported.'
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
INCOMPLETE_STRAPI_SOURCE: {
|
|
38
|
+
type: 'danger',
|
|
39
|
+
message: {
|
|
40
|
+
id: 'content-manager.preview.error.incomplete-strapi-source',
|
|
41
|
+
defaultMessage: 'This field is missing some required preview information'
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
DIFFERENT_DOCUMENT: {
|
|
45
|
+
type: 'info',
|
|
46
|
+
message: {
|
|
47
|
+
id: 'content-manager.preview.error.different-document',
|
|
48
|
+
defaultMessage: 'This field comes from a different document'
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
19
52
|
|
|
20
53
|
exports.INTERNAL_EVENTS = INTERNAL_EVENTS;
|
|
54
|
+
exports.PREVIEW_ERROR_MESSAGES = PREVIEW_ERROR_MESSAGES;
|
|
21
55
|
exports.PUBLIC_EVENTS = PUBLIC_EVENTS;
|
|
22
56
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sources":["../../../../admin/src/preview/utils/constants.ts"],"sourcesContent":["import { previewScript } from './previewScript';\n\nconst scriptResponse = previewScript(false);\n\n/**\n * These events can be changed safely. They're used by the content manager admin on one side, and by\n * the preview script on the other. We own both ends, and they're not documented to users, so we can\n * do what we want with them.\n */\nexport const INTERNAL_EVENTS = scriptResponse!.INTERNAL_EVENTS;\n\n/**\n * These events are documented to users, and will be hardcoded in their frontends.\n * Changing any of these would be a breaking change.\n */\nexport const PUBLIC_EVENTS = {\n PREVIEW_READY: 'previewReady',\n STRAPI_UPDATE: 'strapiUpdate',\n STRAPI_SCRIPT: 'strapiScript',\n} as const;\n"],"names":["scriptResponse","previewScript","INTERNAL_EVENTS","PUBLIC_EVENTS","PREVIEW_READY","STRAPI_UPDATE","STRAPI_SCRIPT"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"constants.js","sources":["../../../../admin/src/preview/utils/constants.ts"],"sourcesContent":["import { NotificationConfig } from '@strapi/admin/strapi-admin';\nimport { MessageDescriptor } from 'react-intl';\n\nimport { previewScript } from './previewScript';\n\nconst scriptResponse = previewScript(false);\n\n/**\n * These events can be changed safely. They're used by the content manager admin on one side, and by\n * the preview script on the other. We own both ends, and they're not documented to users, so we can\n * do what we want with them.\n */\nexport const INTERNAL_EVENTS = scriptResponse!.INTERNAL_EVENTS;\n\n/**\n * These events are documented to users, and will be hardcoded in their frontends.\n * Changing any of these would be a breaking change.\n */\nexport const PUBLIC_EVENTS = {\n PREVIEW_READY: 'previewReady',\n STRAPI_UPDATE: 'strapiUpdate',\n STRAPI_SCRIPT: 'strapiScript',\n} as const;\n\n/**\n * Error messages for preview field operations.\n * This information is used to trigger notifications.\n */\nexport const PREVIEW_ERROR_MESSAGES = {\n INVALID_FIELD_PATH: {\n type: 'danger',\n message: {\n id: 'content-manager.preview.error.invalid-field-path',\n defaultMessage: 'Could not locate this field in the current document',\n },\n },\n RELATIONS_NOT_HANDLED: {\n type: 'info',\n message: {\n id: 'content-manager.preview.error.relations-not-handled',\n defaultMessage: 'Inline editing for relations is not currently supported.',\n },\n },\n INCOMPLETE_STRAPI_SOURCE: {\n type: 'danger',\n message: {\n id: 'content-manager.preview.error.incomplete-strapi-source',\n defaultMessage: 'This field is missing some required preview information',\n },\n },\n DIFFERENT_DOCUMENT: {\n type: 'info',\n message: {\n id: 'content-manager.preview.error.different-document',\n defaultMessage: 'This field comes from a different document',\n },\n },\n} as const satisfies Record<\n string,\n { message: MessageDescriptor; type: NonNullable<NotificationConfig['type']> }\n>;\n"],"names":["scriptResponse","previewScript","INTERNAL_EVENTS","PUBLIC_EVENTS","PREVIEW_READY","STRAPI_UPDATE","STRAPI_SCRIPT","PREVIEW_ERROR_MESSAGES","INVALID_FIELD_PATH","type","message","id","defaultMessage","RELATIONS_NOT_HANDLED","INCOMPLETE_STRAPI_SOURCE","DIFFERENT_DOCUMENT"],"mappings":";;;;AAKA,MAAMA,iBAAiBC,2BAAc,CAAA,KAAA,CAAA;AAErC;;;;AAIC,IACM,MAAMC,eAAkBF,GAAAA,cAAAA,CAAgBE;AAE/C;;;UAIaC,aAAgB,GAAA;IAC3BC,aAAe,EAAA,cAAA;IACfC,aAAe,EAAA,cAAA;IACfC,aAAe,EAAA;AACjB;AAEA;;;UAIaC,sBAAyB,GAAA;IACpCC,kBAAoB,EAAA;QAClBC,IAAM,EAAA,QAAA;QACNC,OAAS,EAAA;YACPC,EAAI,EAAA,kDAAA;YACJC,cAAgB,EAAA;AAClB;AACF,KAAA;IACAC,qBAAuB,EAAA;QACrBJ,IAAM,EAAA,MAAA;QACNC,OAAS,EAAA;YACPC,EAAI,EAAA,qDAAA;YACJC,cAAgB,EAAA;AAClB;AACF,KAAA;IACAE,wBAA0B,EAAA;QACxBL,IAAM,EAAA,QAAA;QACNC,OAAS,EAAA;YACPC,EAAI,EAAA,wDAAA;YACJC,cAAgB,EAAA;AAClB;AACF,KAAA;IACAG,kBAAoB,EAAA;QAClBN,IAAM,EAAA,MAAA;QACNC,OAAS,EAAA;YACPC,EAAI,EAAA,kDAAA;YACJC,cAAgB,EAAA;AAClB;AACF;AACF;;;;;;"}
|
|
@@ -14,6 +14,39 @@ const scriptResponse = previewScript(false);
|
|
|
14
14
|
STRAPI_UPDATE: 'strapiUpdate',
|
|
15
15
|
STRAPI_SCRIPT: 'strapiScript'
|
|
16
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Error messages for preview field operations.
|
|
19
|
+
* This information is used to trigger notifications.
|
|
20
|
+
*/ const PREVIEW_ERROR_MESSAGES = {
|
|
21
|
+
INVALID_FIELD_PATH: {
|
|
22
|
+
type: 'danger',
|
|
23
|
+
message: {
|
|
24
|
+
id: 'content-manager.preview.error.invalid-field-path',
|
|
25
|
+
defaultMessage: 'Could not locate this field in the current document'
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
RELATIONS_NOT_HANDLED: {
|
|
29
|
+
type: 'info',
|
|
30
|
+
message: {
|
|
31
|
+
id: 'content-manager.preview.error.relations-not-handled',
|
|
32
|
+
defaultMessage: 'Inline editing for relations is not currently supported.'
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
INCOMPLETE_STRAPI_SOURCE: {
|
|
36
|
+
type: 'danger',
|
|
37
|
+
message: {
|
|
38
|
+
id: 'content-manager.preview.error.incomplete-strapi-source',
|
|
39
|
+
defaultMessage: 'This field is missing some required preview information'
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
DIFFERENT_DOCUMENT: {
|
|
43
|
+
type: 'info',
|
|
44
|
+
message: {
|
|
45
|
+
id: 'content-manager.preview.error.different-document',
|
|
46
|
+
defaultMessage: 'This field comes from a different document'
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
};
|
|
17
50
|
|
|
18
|
-
export { INTERNAL_EVENTS, PUBLIC_EVENTS };
|
|
51
|
+
export { INTERNAL_EVENTS, PREVIEW_ERROR_MESSAGES, PUBLIC_EVENTS };
|
|
19
52
|
//# sourceMappingURL=constants.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.mjs","sources":["../../../../admin/src/preview/utils/constants.ts"],"sourcesContent":["import { previewScript } from './previewScript';\n\nconst scriptResponse = previewScript(false);\n\n/**\n * These events can be changed safely. They're used by the content manager admin on one side, and by\n * the preview script on the other. We own both ends, and they're not documented to users, so we can\n * do what we want with them.\n */\nexport const INTERNAL_EVENTS = scriptResponse!.INTERNAL_EVENTS;\n\n/**\n * These events are documented to users, and will be hardcoded in their frontends.\n * Changing any of these would be a breaking change.\n */\nexport const PUBLIC_EVENTS = {\n PREVIEW_READY: 'previewReady',\n STRAPI_UPDATE: 'strapiUpdate',\n STRAPI_SCRIPT: 'strapiScript',\n} as const;\n"],"names":["scriptResponse","previewScript","INTERNAL_EVENTS","PUBLIC_EVENTS","PREVIEW_READY","STRAPI_UPDATE","STRAPI_SCRIPT"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"constants.mjs","sources":["../../../../admin/src/preview/utils/constants.ts"],"sourcesContent":["import { NotificationConfig } from '@strapi/admin/strapi-admin';\nimport { MessageDescriptor } from 'react-intl';\n\nimport { previewScript } from './previewScript';\n\nconst scriptResponse = previewScript(false);\n\n/**\n * These events can be changed safely. They're used by the content manager admin on one side, and by\n * the preview script on the other. We own both ends, and they're not documented to users, so we can\n * do what we want with them.\n */\nexport const INTERNAL_EVENTS = scriptResponse!.INTERNAL_EVENTS;\n\n/**\n * These events are documented to users, and will be hardcoded in their frontends.\n * Changing any of these would be a breaking change.\n */\nexport const PUBLIC_EVENTS = {\n PREVIEW_READY: 'previewReady',\n STRAPI_UPDATE: 'strapiUpdate',\n STRAPI_SCRIPT: 'strapiScript',\n} as const;\n\n/**\n * Error messages for preview field operations.\n * This information is used to trigger notifications.\n */\nexport const PREVIEW_ERROR_MESSAGES = {\n INVALID_FIELD_PATH: {\n type: 'danger',\n message: {\n id: 'content-manager.preview.error.invalid-field-path',\n defaultMessage: 'Could not locate this field in the current document',\n },\n },\n RELATIONS_NOT_HANDLED: {\n type: 'info',\n message: {\n id: 'content-manager.preview.error.relations-not-handled',\n defaultMessage: 'Inline editing for relations is not currently supported.',\n },\n },\n INCOMPLETE_STRAPI_SOURCE: {\n type: 'danger',\n message: {\n id: 'content-manager.preview.error.incomplete-strapi-source',\n defaultMessage: 'This field is missing some required preview information',\n },\n },\n DIFFERENT_DOCUMENT: {\n type: 'info',\n message: {\n id: 'content-manager.preview.error.different-document',\n defaultMessage: 'This field comes from a different document',\n },\n },\n} as const satisfies Record<\n string,\n { message: MessageDescriptor; type: NonNullable<NotificationConfig['type']> }\n>;\n"],"names":["scriptResponse","previewScript","INTERNAL_EVENTS","PUBLIC_EVENTS","PREVIEW_READY","STRAPI_UPDATE","STRAPI_SCRIPT","PREVIEW_ERROR_MESSAGES","INVALID_FIELD_PATH","type","message","id","defaultMessage","RELATIONS_NOT_HANDLED","INCOMPLETE_STRAPI_SOURCE","DIFFERENT_DOCUMENT"],"mappings":";;AAKA,MAAMA,iBAAiBC,aAAc,CAAA,KAAA,CAAA;AAErC;;;;AAIC,IACM,MAAMC,eAAkBF,GAAAA,cAAAA,CAAgBE;AAE/C;;;UAIaC,aAAgB,GAAA;IAC3BC,aAAe,EAAA,cAAA;IACfC,aAAe,EAAA,cAAA;IACfC,aAAe,EAAA;AACjB;AAEA;;;UAIaC,sBAAyB,GAAA;IACpCC,kBAAoB,EAAA;QAClBC,IAAM,EAAA,QAAA;QACNC,OAAS,EAAA;YACPC,EAAI,EAAA,kDAAA;YACJC,cAAgB,EAAA;AAClB;AACF,KAAA;IACAC,qBAAuB,EAAA;QACrBJ,IAAM,EAAA,MAAA;QACNC,OAAS,EAAA;YACPC,EAAI,EAAA,qDAAA;YACJC,cAAgB,EAAA;AAClB;AACF,KAAA;IACAE,wBAA0B,EAAA;QACxBL,IAAM,EAAA,QAAA;QACNC,OAAS,EAAA;YACPC,EAAI,EAAA,wDAAA;YACJC,cAAgB,EAAA;AAClB;AACF,KAAA;IACAG,kBAAoB,EAAA;QAClBN,IAAM,EAAA,MAAA;QACNC,OAAS,EAAA;YACPC,EAAI,EAAA,kDAAA;YACJC,cAAgB,EAAA;AAClB;AACF;AACF;;;;"}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
// Generic error class for preview field operations
|
|
4
|
+
class PreviewFieldError extends Error {
|
|
5
|
+
constructor(messageKey){
|
|
6
|
+
super(messageKey);
|
|
7
|
+
this.name = 'PreviewFieldError';
|
|
8
|
+
this.messageKey = messageKey;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
3
11
|
// Helper function to parse path with array indices and return clean attribute names
|
|
4
12
|
const parsePathWithIndices = (path)=>{
|
|
5
13
|
// Split by dots, then parse array indices from each part. For example:
|
|
@@ -40,17 +48,17 @@ function getAttributeSchemaFromPath({ path, schema, components, document }) {
|
|
|
40
48
|
// Get the data and schema for the current path
|
|
41
49
|
const currentAttribute = currentAttributes[currentPart.name];
|
|
42
50
|
if (!currentAttribute) {
|
|
43
|
-
throw new
|
|
51
|
+
throw new PreviewFieldError('INVALID_FIELD_PATH');
|
|
44
52
|
}
|
|
45
53
|
if (currentAttribute.type === 'relation') {
|
|
46
|
-
throw new
|
|
54
|
+
throw new PreviewFieldError('RELATIONS_NOT_HANDLED');
|
|
47
55
|
}
|
|
48
56
|
if (currentAttribute.type === 'component') {
|
|
49
57
|
const componentAttributes = components[currentAttribute.component].attributes;
|
|
50
58
|
if (currentAttribute.repeatable) {
|
|
51
59
|
// We must have the index, otherwise we don't know what data to use
|
|
52
60
|
if (currentPart.index === undefined) {
|
|
53
|
-
throw new
|
|
61
|
+
throw new PreviewFieldError('INVALID_FIELD_PATH');
|
|
54
62
|
}
|
|
55
63
|
return visitor(remainingParts, componentAttributes, currentData[currentPart.name][currentPart.index]);
|
|
56
64
|
}
|
|
@@ -60,7 +68,7 @@ function getAttributeSchemaFromPath({ path, schema, components, document }) {
|
|
|
60
68
|
if (currentAttribute.type === 'dynamiczone') {
|
|
61
69
|
// We must have the index, otherwise we don't know what component we're dealing with
|
|
62
70
|
if (currentPart.index === undefined) {
|
|
63
|
-
throw new
|
|
71
|
+
throw new PreviewFieldError('INVALID_FIELD_PATH');
|
|
64
72
|
}
|
|
65
73
|
const componentData = currentData[currentPart.name][currentPart.index];
|
|
66
74
|
const componentAttributes = components[componentData.__component].attributes;
|
|
@@ -92,6 +100,7 @@ function parseFieldMetaData(strapiSource) {
|
|
|
92
100
|
};
|
|
93
101
|
}
|
|
94
102
|
|
|
103
|
+
exports.PreviewFieldError = PreviewFieldError;
|
|
95
104
|
exports.getAttributeSchemaFromPath = getAttributeSchemaFromPath;
|
|
96
105
|
exports.parseFieldMetaData = parseFieldMetaData;
|
|
97
106
|
exports.parsePathWithIndices = parsePathWithIndices;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fieldUtils.js","sources":["../../../../admin/src/preview/utils/fieldUtils.ts"],"sourcesContent":["import { type FieldContentSourceMap } from '@strapi/admin/strapi-admin';\n\nimport type { PreviewContextValue } from '../pages/Preview';\nimport type { Modules, Schema, Struct, UID } from '@strapi/types';\n\ntype PathPart = { name: string; index?: number };\n\n// Helper function to parse path with array indices and return clean attribute names\nexport const parsePathWithIndices = (path: string): PathPart[] => {\n // Split by dots, then parse array indices from each part. For example:\n // input \"components.4.field.relations.2.name\"\n // output [{name: \"components\", index: 4}, {name: \"field\"}, {name: \"relations\", index: 2}, {name: \"name\"}]\n return path\n .split('.')\n .map((part) => {\n const numericIndex = parseInt(part, 10);\n if (!isNaN(numericIndex) && part === numericIndex.toString()) {\n // This part is a pure numeric index, return it as an index for the previous part\n return { name: '', index: numericIndex };\n }\n return { name: part };\n })\n .reduce((acc: PathPart[], part) => {\n if (part.name === '' && part.index !== undefined) {\n // This is an index, attach it to the previous part\n if (acc.length > 0) {\n acc[acc.length - 1].index = part.index;\n }\n } else {\n acc.push(part);\n }\n return acc;\n }, []);\n};\n\nexport function getAttributeSchemaFromPath({\n path,\n schema,\n components,\n document,\n}: {\n path: string;\n schema: PreviewContextValue['schema'] | PreviewContextValue['components'][string];\n components: PreviewContextValue['components'];\n document: Modules.Documents.AnyDocument;\n}): Schema.Attribute.AnyAttribute {\n /**\n * Create the function that will be recursively called.\n * We don't do recursion on getAttributeSchemaFromPath itself because:\n * - it takes a path string, not the parsed array that's better for recursion\n * - even when several levels deep, we still need access to the root schema and components\n */\n const visitor = (\n currentPathParts: PathPart[],\n currentAttributes: Schema.Attributes,\n currentData: any\n ): Schema.Attribute.AnyAttribute => {\n const [currentPart, ...remainingParts] = currentPathParts;\n\n // Get the data and schema for the current path\n const currentAttribute = currentAttributes[currentPart.name];\n\n if (!currentAttribute) {\n throw new
|
|
1
|
+
{"version":3,"file":"fieldUtils.js","sources":["../../../../admin/src/preview/utils/fieldUtils.ts"],"sourcesContent":["import { type FieldContentSourceMap } from '@strapi/admin/strapi-admin';\n\nimport type { PREVIEW_ERROR_MESSAGES } from './constants';\nimport type { PreviewContextValue } from '../pages/Preview';\nimport type { Modules, Schema, Struct, UID } from '@strapi/types';\n\ntype PreviewErrorMessage = keyof typeof PREVIEW_ERROR_MESSAGES;\n\n// Generic error class for preview field operations\nexport class PreviewFieldError extends Error {\n public readonly messageKey: PreviewErrorMessage;\n\n constructor(messageKey: PreviewErrorMessage) {\n super(messageKey);\n this.name = 'PreviewFieldError';\n this.messageKey = messageKey;\n }\n}\n\ntype PathPart = { name: string; index?: number };\n\n// Helper function to parse path with array indices and return clean attribute names\nexport const parsePathWithIndices = (path: string): PathPart[] => {\n // Split by dots, then parse array indices from each part. For example:\n // input \"components.4.field.relations.2.name\"\n // output [{name: \"components\", index: 4}, {name: \"field\"}, {name: \"relations\", index: 2}, {name: \"name\"}]\n return path\n .split('.')\n .map((part) => {\n const numericIndex = parseInt(part, 10);\n if (!isNaN(numericIndex) && part === numericIndex.toString()) {\n // This part is a pure numeric index, return it as an index for the previous part\n return { name: '', index: numericIndex };\n }\n return { name: part };\n })\n .reduce((acc: PathPart[], part) => {\n if (part.name === '' && part.index !== undefined) {\n // This is an index, attach it to the previous part\n if (acc.length > 0) {\n acc[acc.length - 1].index = part.index;\n }\n } else {\n acc.push(part);\n }\n return acc;\n }, []);\n};\n\nexport function getAttributeSchemaFromPath({\n path,\n schema,\n components,\n document,\n}: {\n path: string;\n schema: PreviewContextValue['schema'] | PreviewContextValue['components'][string];\n components: PreviewContextValue['components'];\n document: Modules.Documents.AnyDocument;\n}): Schema.Attribute.AnyAttribute {\n /**\n * Create the function that will be recursively called.\n * We don't do recursion on getAttributeSchemaFromPath itself because:\n * - it takes a path string, not the parsed array that's better for recursion\n * - even when several levels deep, we still need access to the root schema and components\n */\n const visitor = (\n currentPathParts: PathPart[],\n currentAttributes: Schema.Attributes,\n currentData: any\n ): Schema.Attribute.AnyAttribute => {\n const [currentPart, ...remainingParts] = currentPathParts;\n\n // Get the data and schema for the current path\n const currentAttribute = currentAttributes[currentPart.name];\n\n if (!currentAttribute) {\n throw new PreviewFieldError('INVALID_FIELD_PATH');\n }\n\n if (currentAttribute.type === 'relation') {\n throw new PreviewFieldError('RELATIONS_NOT_HANDLED');\n }\n\n if (currentAttribute.type === 'component') {\n const componentAttributes = components[currentAttribute.component].attributes;\n if (currentAttribute.repeatable) {\n // We must have the index, otherwise we don't know what data to use\n if (currentPart.index === undefined) {\n throw new PreviewFieldError('INVALID_FIELD_PATH');\n }\n return visitor(\n remainingParts,\n componentAttributes,\n currentData[currentPart.name][currentPart.index]\n );\n }\n\n // Non repeatable component\n return visitor(remainingParts, componentAttributes, currentData[currentPart.name]);\n }\n\n if (currentAttribute.type === 'dynamiczone') {\n // We must have the index, otherwise we don't know what component we're dealing with\n if (currentPart.index === undefined) {\n throw new PreviewFieldError('INVALID_FIELD_PATH');\n }\n\n const componentData = currentData[currentPart.name][currentPart.index];\n const componentAttributes = components[componentData.__component].attributes;\n return visitor(remainingParts, componentAttributes, componentData);\n }\n\n // Plain regular field. It ends the recursion\n return currentAttributes[currentPart.name];\n };\n\n return visitor(parsePathWithIndices(path), schema.attributes, document);\n}\n\nexport function parseFieldMetaData(strapiSource: string): FieldContentSourceMap | null {\n const searchParams = new URLSearchParams(strapiSource);\n const path = searchParams.get('path');\n const type = searchParams.get('type');\n const documentId = searchParams.get('documentId');\n const locale = searchParams.get('locale');\n const model = searchParams.get('model');\n const kind = searchParams.get('kind');\n\n if (!path || !type || !documentId || !model) {\n return null;\n }\n\n return {\n path,\n type: type as Schema.Attribute.AnyAttribute['type'],\n documentId,\n locale: locale ?? null,\n model: model as UID.Schema | undefined,\n kind: kind ? (kind as Struct.ContentTypeKind) : undefined,\n };\n}\n"],"names":["PreviewFieldError","Error","constructor","messageKey","name","parsePathWithIndices","path","split","map","part","numericIndex","parseInt","isNaN","toString","index","reduce","acc","undefined","length","push","getAttributeSchemaFromPath","schema","components","document","visitor","currentPathParts","currentAttributes","currentData","currentPart","remainingParts","currentAttribute","type","componentAttributes","component","attributes","repeatable","componentData","__component","parseFieldMetaData","strapiSource","searchParams","URLSearchParams","get","documentId","locale","model","kind"],"mappings":"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"}
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
// Generic error class for preview field operations
|
|
2
|
+
class PreviewFieldError extends Error {
|
|
3
|
+
constructor(messageKey){
|
|
4
|
+
super(messageKey);
|
|
5
|
+
this.name = 'PreviewFieldError';
|
|
6
|
+
this.messageKey = messageKey;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
1
9
|
// Helper function to parse path with array indices and return clean attribute names
|
|
2
10
|
const parsePathWithIndices = (path)=>{
|
|
3
11
|
// Split by dots, then parse array indices from each part. For example:
|
|
@@ -38,17 +46,17 @@ function getAttributeSchemaFromPath({ path, schema, components, document }) {
|
|
|
38
46
|
// Get the data and schema for the current path
|
|
39
47
|
const currentAttribute = currentAttributes[currentPart.name];
|
|
40
48
|
if (!currentAttribute) {
|
|
41
|
-
throw new
|
|
49
|
+
throw new PreviewFieldError('INVALID_FIELD_PATH');
|
|
42
50
|
}
|
|
43
51
|
if (currentAttribute.type === 'relation') {
|
|
44
|
-
throw new
|
|
52
|
+
throw new PreviewFieldError('RELATIONS_NOT_HANDLED');
|
|
45
53
|
}
|
|
46
54
|
if (currentAttribute.type === 'component') {
|
|
47
55
|
const componentAttributes = components[currentAttribute.component].attributes;
|
|
48
56
|
if (currentAttribute.repeatable) {
|
|
49
57
|
// We must have the index, otherwise we don't know what data to use
|
|
50
58
|
if (currentPart.index === undefined) {
|
|
51
|
-
throw new
|
|
59
|
+
throw new PreviewFieldError('INVALID_FIELD_PATH');
|
|
52
60
|
}
|
|
53
61
|
return visitor(remainingParts, componentAttributes, currentData[currentPart.name][currentPart.index]);
|
|
54
62
|
}
|
|
@@ -58,7 +66,7 @@ function getAttributeSchemaFromPath({ path, schema, components, document }) {
|
|
|
58
66
|
if (currentAttribute.type === 'dynamiczone') {
|
|
59
67
|
// We must have the index, otherwise we don't know what component we're dealing with
|
|
60
68
|
if (currentPart.index === undefined) {
|
|
61
|
-
throw new
|
|
69
|
+
throw new PreviewFieldError('INVALID_FIELD_PATH');
|
|
62
70
|
}
|
|
63
71
|
const componentData = currentData[currentPart.name][currentPart.index];
|
|
64
72
|
const componentAttributes = components[componentData.__component].attributes;
|
|
@@ -90,5 +98,5 @@ function parseFieldMetaData(strapiSource) {
|
|
|
90
98
|
};
|
|
91
99
|
}
|
|
92
100
|
|
|
93
|
-
export { getAttributeSchemaFromPath, parseFieldMetaData, parsePathWithIndices };
|
|
101
|
+
export { PreviewFieldError, getAttributeSchemaFromPath, parseFieldMetaData, parsePathWithIndices };
|
|
94
102
|
//# sourceMappingURL=fieldUtils.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fieldUtils.mjs","sources":["../../../../admin/src/preview/utils/fieldUtils.ts"],"sourcesContent":["import { type FieldContentSourceMap } from '@strapi/admin/strapi-admin';\n\nimport type { PreviewContextValue } from '../pages/Preview';\nimport type { Modules, Schema, Struct, UID } from '@strapi/types';\n\ntype PathPart = { name: string; index?: number };\n\n// Helper function to parse path with array indices and return clean attribute names\nexport const parsePathWithIndices = (path: string): PathPart[] => {\n // Split by dots, then parse array indices from each part. For example:\n // input \"components.4.field.relations.2.name\"\n // output [{name: \"components\", index: 4}, {name: \"field\"}, {name: \"relations\", index: 2}, {name: \"name\"}]\n return path\n .split('.')\n .map((part) => {\n const numericIndex = parseInt(part, 10);\n if (!isNaN(numericIndex) && part === numericIndex.toString()) {\n // This part is a pure numeric index, return it as an index for the previous part\n return { name: '', index: numericIndex };\n }\n return { name: part };\n })\n .reduce((acc: PathPart[], part) => {\n if (part.name === '' && part.index !== undefined) {\n // This is an index, attach it to the previous part\n if (acc.length > 0) {\n acc[acc.length - 1].index = part.index;\n }\n } else {\n acc.push(part);\n }\n return acc;\n }, []);\n};\n\nexport function getAttributeSchemaFromPath({\n path,\n schema,\n components,\n document,\n}: {\n path: string;\n schema: PreviewContextValue['schema'] | PreviewContextValue['components'][string];\n components: PreviewContextValue['components'];\n document: Modules.Documents.AnyDocument;\n}): Schema.Attribute.AnyAttribute {\n /**\n * Create the function that will be recursively called.\n * We don't do recursion on getAttributeSchemaFromPath itself because:\n * - it takes a path string, not the parsed array that's better for recursion\n * - even when several levels deep, we still need access to the root schema and components\n */\n const visitor = (\n currentPathParts: PathPart[],\n currentAttributes: Schema.Attributes,\n currentData: any\n ): Schema.Attribute.AnyAttribute => {\n const [currentPart, ...remainingParts] = currentPathParts;\n\n // Get the data and schema for the current path\n const currentAttribute = currentAttributes[currentPart.name];\n\n if (!currentAttribute) {\n throw new
|
|
1
|
+
{"version":3,"file":"fieldUtils.mjs","sources":["../../../../admin/src/preview/utils/fieldUtils.ts"],"sourcesContent":["import { type FieldContentSourceMap } from '@strapi/admin/strapi-admin';\n\nimport type { PREVIEW_ERROR_MESSAGES } from './constants';\nimport type { PreviewContextValue } from '../pages/Preview';\nimport type { Modules, Schema, Struct, UID } from '@strapi/types';\n\ntype PreviewErrorMessage = keyof typeof PREVIEW_ERROR_MESSAGES;\n\n// Generic error class for preview field operations\nexport class PreviewFieldError extends Error {\n public readonly messageKey: PreviewErrorMessage;\n\n constructor(messageKey: PreviewErrorMessage) {\n super(messageKey);\n this.name = 'PreviewFieldError';\n this.messageKey = messageKey;\n }\n}\n\ntype PathPart = { name: string; index?: number };\n\n// Helper function to parse path with array indices and return clean attribute names\nexport const parsePathWithIndices = (path: string): PathPart[] => {\n // Split by dots, then parse array indices from each part. For example:\n // input \"components.4.field.relations.2.name\"\n // output [{name: \"components\", index: 4}, {name: \"field\"}, {name: \"relations\", index: 2}, {name: \"name\"}]\n return path\n .split('.')\n .map((part) => {\n const numericIndex = parseInt(part, 10);\n if (!isNaN(numericIndex) && part === numericIndex.toString()) {\n // This part is a pure numeric index, return it as an index for the previous part\n return { name: '', index: numericIndex };\n }\n return { name: part };\n })\n .reduce((acc: PathPart[], part) => {\n if (part.name === '' && part.index !== undefined) {\n // This is an index, attach it to the previous part\n if (acc.length > 0) {\n acc[acc.length - 1].index = part.index;\n }\n } else {\n acc.push(part);\n }\n return acc;\n }, []);\n};\n\nexport function getAttributeSchemaFromPath({\n path,\n schema,\n components,\n document,\n}: {\n path: string;\n schema: PreviewContextValue['schema'] | PreviewContextValue['components'][string];\n components: PreviewContextValue['components'];\n document: Modules.Documents.AnyDocument;\n}): Schema.Attribute.AnyAttribute {\n /**\n * Create the function that will be recursively called.\n * We don't do recursion on getAttributeSchemaFromPath itself because:\n * - it takes a path string, not the parsed array that's better for recursion\n * - even when several levels deep, we still need access to the root schema and components\n */\n const visitor = (\n currentPathParts: PathPart[],\n currentAttributes: Schema.Attributes,\n currentData: any\n ): Schema.Attribute.AnyAttribute => {\n const [currentPart, ...remainingParts] = currentPathParts;\n\n // Get the data and schema for the current path\n const currentAttribute = currentAttributes[currentPart.name];\n\n if (!currentAttribute) {\n throw new PreviewFieldError('INVALID_FIELD_PATH');\n }\n\n if (currentAttribute.type === 'relation') {\n throw new PreviewFieldError('RELATIONS_NOT_HANDLED');\n }\n\n if (currentAttribute.type === 'component') {\n const componentAttributes = components[currentAttribute.component].attributes;\n if (currentAttribute.repeatable) {\n // We must have the index, otherwise we don't know what data to use\n if (currentPart.index === undefined) {\n throw new PreviewFieldError('INVALID_FIELD_PATH');\n }\n return visitor(\n remainingParts,\n componentAttributes,\n currentData[currentPart.name][currentPart.index]\n );\n }\n\n // Non repeatable component\n return visitor(remainingParts, componentAttributes, currentData[currentPart.name]);\n }\n\n if (currentAttribute.type === 'dynamiczone') {\n // We must have the index, otherwise we don't know what component we're dealing with\n if (currentPart.index === undefined) {\n throw new PreviewFieldError('INVALID_FIELD_PATH');\n }\n\n const componentData = currentData[currentPart.name][currentPart.index];\n const componentAttributes = components[componentData.__component].attributes;\n return visitor(remainingParts, componentAttributes, componentData);\n }\n\n // Plain regular field. It ends the recursion\n return currentAttributes[currentPart.name];\n };\n\n return visitor(parsePathWithIndices(path), schema.attributes, document);\n}\n\nexport function parseFieldMetaData(strapiSource: string): FieldContentSourceMap | null {\n const searchParams = new URLSearchParams(strapiSource);\n const path = searchParams.get('path');\n const type = searchParams.get('type');\n const documentId = searchParams.get('documentId');\n const locale = searchParams.get('locale');\n const model = searchParams.get('model');\n const kind = searchParams.get('kind');\n\n if (!path || !type || !documentId || !model) {\n return null;\n }\n\n return {\n path,\n type: type as Schema.Attribute.AnyAttribute['type'],\n documentId,\n locale: locale ?? null,\n model: model as UID.Schema | undefined,\n kind: kind ? (kind as Struct.ContentTypeKind) : undefined,\n };\n}\n"],"names":["PreviewFieldError","Error","constructor","messageKey","name","parsePathWithIndices","path","split","map","part","numericIndex","parseInt","isNaN","toString","index","reduce","acc","undefined","length","push","getAttributeSchemaFromPath","schema","components","document","visitor","currentPathParts","currentAttributes","currentData","currentPart","remainingParts","currentAttribute","type","componentAttributes","component","attributes","repeatable","componentData","__component","parseFieldMetaData","strapiSource","searchParams","URLSearchParams","get","documentId","locale","model","kind"],"mappings":"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"}
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
* ---------------------------------------------------------------------------------------------*/ const HIGHLIGHT_PADDING = 2; // in pixels
|
|
13
13
|
const HIGHLIGHT_HOVER_COLOR = window.STRAPI_HIGHLIGHT_HOVER_COLOR ?? '#4945ff'; // dark primary500
|
|
14
14
|
const HIGHLIGHT_ACTIVE_COLOR = window.STRAPI_HIGHLIGHT_ACTIVE_COLOR ?? '#7b79ff'; // dark primary600
|
|
15
|
+
const HIGHLIGHT_STYLES_ID = 'strapi-preview-highlight-styles';
|
|
16
|
+
const DOUBLE_CLICK_TIMEOUT = 300; // milliseconds to wait for potential double-click
|
|
15
17
|
const DISABLE_STEGA_DECODING = window.STRAPI_DISABLE_STEGA_DECODING ?? false;
|
|
16
18
|
const SOURCE_ATTRIBUTE = 'data-strapi-source';
|
|
17
19
|
const OVERLAY_ID = 'strapi-preview-overlay';
|
|
@@ -19,7 +21,8 @@
|
|
|
19
21
|
STRAPI_FIELD_FOCUS: 'strapiFieldFocus',
|
|
20
22
|
STRAPI_FIELD_BLUR: 'strapiFieldBlur',
|
|
21
23
|
STRAPI_FIELD_CHANGE: 'strapiFieldChange',
|
|
22
|
-
STRAPI_FIELD_FOCUS_INTENT: 'strapiFieldFocusIntent'
|
|
24
|
+
STRAPI_FIELD_FOCUS_INTENT: 'strapiFieldFocusIntent',
|
|
25
|
+
STRAPI_FIELD_SINGLE_CLICK_HINT: 'strapiFieldSingleClickHint'
|
|
23
26
|
};
|
|
24
27
|
/**
|
|
25
28
|
* Calling the function in no-run mode lets us retrieve the constants from other files and keep
|
|
@@ -104,6 +107,37 @@
|
|
|
104
107
|
});
|
|
105
108
|
return observer;
|
|
106
109
|
};
|
|
110
|
+
const createHighlightStyles = ()=>{
|
|
111
|
+
const existingStyles = document.getElementById(HIGHLIGHT_STYLES_ID);
|
|
112
|
+
// Remove existing styles to avoid duplicates
|
|
113
|
+
if (existingStyles) {
|
|
114
|
+
existingStyles.remove();
|
|
115
|
+
}
|
|
116
|
+
const styleElement = document.createElement('style');
|
|
117
|
+
styleElement.id = HIGHLIGHT_STYLES_ID;
|
|
118
|
+
styleElement.textContent = `
|
|
119
|
+
.strapi-highlight {
|
|
120
|
+
position: absolute;
|
|
121
|
+
outline: 2px solid transparent;
|
|
122
|
+
pointer-events: auto;
|
|
123
|
+
border-radius: 2px;
|
|
124
|
+
background-color: transparent;
|
|
125
|
+
will-change: transform;
|
|
126
|
+
transition: outline-color 0.1s ease-in-out;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.strapi-highlight:hover {
|
|
130
|
+
outline-color: ${HIGHLIGHT_HOVER_COLOR} !important;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.strapi-highlight.strapi-highlight-focused {
|
|
134
|
+
outline-color: ${HIGHLIGHT_ACTIVE_COLOR} !important;
|
|
135
|
+
outline-width: 3px !important;
|
|
136
|
+
}
|
|
137
|
+
`;
|
|
138
|
+
document.head.appendChild(styleElement);
|
|
139
|
+
return styleElement;
|
|
140
|
+
};
|
|
107
141
|
const createOverlaySystem = ()=>{
|
|
108
142
|
// Clean up before creating a new overlay so we can safely call previewScript multiple times
|
|
109
143
|
window.__strapi_previewCleanup?.();
|
|
@@ -126,6 +160,7 @@
|
|
|
126
160
|
const elementsToHighlight = new Map();
|
|
127
161
|
const eventListeners = [];
|
|
128
162
|
const focusedHighlights = [];
|
|
163
|
+
const pendingClicks = new Map(); // number is timeout id
|
|
129
164
|
let focusedField = null;
|
|
130
165
|
const drawHighlight = (target, highlight)=>{
|
|
131
166
|
if (!highlight) return;
|
|
@@ -145,27 +180,57 @@
|
|
|
145
180
|
return;
|
|
146
181
|
}
|
|
147
182
|
const highlight = document.createElement('div');
|
|
148
|
-
highlight.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
background-color: transparent;
|
|
154
|
-
will-change: transform;
|
|
155
|
-
transition: outline-color 0.1s ease-in-out;
|
|
156
|
-
`;
|
|
157
|
-
// Move hover detection to the underlying element
|
|
158
|
-
const mouseEnterHandler = ()=>{
|
|
159
|
-
if (!focusedHighlights.includes(highlight)) {
|
|
160
|
-
highlight.style.outlineColor = HIGHLIGHT_HOVER_COLOR;
|
|
183
|
+
highlight.className = 'strapi-highlight';
|
|
184
|
+
const clickHandler = (event)=>{
|
|
185
|
+
// Skip if this is a re-dispatched event from our delayed handler to avoid infinite loops
|
|
186
|
+
if (event.__strapi_redispatched) {
|
|
187
|
+
return;
|
|
161
188
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
189
|
+
// Prevent the immediate action for interactive elements
|
|
190
|
+
event.preventDefault();
|
|
191
|
+
event.stopPropagation();
|
|
192
|
+
// Clear any existing timeout for this element
|
|
193
|
+
const existingTimeout = pendingClicks.get(element);
|
|
194
|
+
if (existingTimeout) {
|
|
195
|
+
window.clearTimeout(existingTimeout);
|
|
196
|
+
pendingClicks.delete(element);
|
|
166
197
|
}
|
|
198
|
+
// Set up a delayed single-click handler
|
|
199
|
+
const timeout = window.setTimeout(()=>{
|
|
200
|
+
pendingClicks.delete(element);
|
|
201
|
+
// Send single-click hint notification
|
|
202
|
+
sendMessage(INTERNAL_EVENTS.STRAPI_FIELD_SINGLE_CLICK_HINT, null);
|
|
203
|
+
// Re-trigger the click on the underlying element after the double-click timeout
|
|
204
|
+
// Create a new event to dispatch with a marker to prevent re-handling
|
|
205
|
+
const newEvent = new MouseEvent('click', {
|
|
206
|
+
bubbles: true,
|
|
207
|
+
cancelable: true,
|
|
208
|
+
view: window,
|
|
209
|
+
detail: 1,
|
|
210
|
+
button: event.button,
|
|
211
|
+
buttons: event.buttons,
|
|
212
|
+
clientX: event.clientX,
|
|
213
|
+
clientY: event.clientY,
|
|
214
|
+
ctrlKey: event.ctrlKey,
|
|
215
|
+
altKey: event.altKey,
|
|
216
|
+
shiftKey: event.shiftKey,
|
|
217
|
+
metaKey: event.metaKey
|
|
218
|
+
});
|
|
219
|
+
newEvent.__strapi_redispatched = true;
|
|
220
|
+
element.dispatchEvent(newEvent);
|
|
221
|
+
}, DOUBLE_CLICK_TIMEOUT);
|
|
222
|
+
pendingClicks.set(element, timeout);
|
|
167
223
|
};
|
|
168
|
-
const doubleClickHandler = ()=>{
|
|
224
|
+
const doubleClickHandler = (event)=>{
|
|
225
|
+
// Prevent the default behavior on double-click
|
|
226
|
+
event.preventDefault();
|
|
227
|
+
event.stopPropagation();
|
|
228
|
+
// Clear any pending single-click action
|
|
229
|
+
const existingTimeout = pendingClicks.get(element);
|
|
230
|
+
if (existingTimeout) {
|
|
231
|
+
clearTimeout(existingTimeout);
|
|
232
|
+
pendingClicks.delete(element);
|
|
233
|
+
}
|
|
169
234
|
const sourceAttribute = element.getAttribute(SOURCE_ATTRIBUTE);
|
|
170
235
|
if (sourceAttribute) {
|
|
171
236
|
const rect = element.getBoundingClientRect();
|
|
@@ -188,25 +253,20 @@
|
|
|
188
253
|
event.preventDefault();
|
|
189
254
|
}
|
|
190
255
|
};
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
element.addEventListener('mousedown', mouseDownHandler);
|
|
256
|
+
highlight.addEventListener('click', clickHandler);
|
|
257
|
+
highlight.addEventListener('dblclick', doubleClickHandler);
|
|
258
|
+
highlight.addEventListener('mousedown', mouseDownHandler);
|
|
195
259
|
// Store event listeners for cleanup
|
|
196
260
|
eventListeners.push({
|
|
197
|
-
element,
|
|
198
|
-
type: '
|
|
199
|
-
handler:
|
|
200
|
-
}, {
|
|
201
|
-
element,
|
|
202
|
-
type: 'mouseleave',
|
|
203
|
-
handler: mouseLeaveHandler
|
|
261
|
+
element: highlight,
|
|
262
|
+
type: 'click',
|
|
263
|
+
handler: clickHandler
|
|
204
264
|
}, {
|
|
205
|
-
element,
|
|
265
|
+
element: highlight,
|
|
206
266
|
type: 'dblclick',
|
|
207
267
|
handler: doubleClickHandler
|
|
208
268
|
}, {
|
|
209
|
-
element,
|
|
269
|
+
element: highlight,
|
|
210
270
|
type: 'mousedown',
|
|
211
271
|
handler: mouseDownHandler
|
|
212
272
|
});
|
|
@@ -217,15 +277,21 @@
|
|
|
217
277
|
const removeHighlightForElement = (element)=>{
|
|
218
278
|
const highlight = elementsToHighlight.get(element);
|
|
219
279
|
if (!highlight) return;
|
|
280
|
+
// Clear any pending click timeout for this element
|
|
281
|
+
const pendingTimeout = pendingClicks.get(element);
|
|
282
|
+
if (pendingTimeout) {
|
|
283
|
+
window.clearTimeout(pendingTimeout);
|
|
284
|
+
pendingClicks.delete(element);
|
|
285
|
+
}
|
|
220
286
|
highlight.remove();
|
|
221
287
|
elementsToHighlight.delete(element);
|
|
222
|
-
// Remove event listeners for this
|
|
223
|
-
const listenersToRemove = eventListeners.filter((listener)=>listener.element ===
|
|
288
|
+
// Remove event listeners for this highlight
|
|
289
|
+
const listenersToRemove = eventListeners.filter((listener)=>listener.element === highlight);
|
|
224
290
|
listenersToRemove.forEach(({ element, type, handler })=>{
|
|
225
291
|
element.removeEventListener(type, handler);
|
|
226
292
|
});
|
|
227
|
-
// Mutate eventListeners to remove listeners for this
|
|
228
|
-
eventListeners.splice(0, eventListeners.length, ...eventListeners.filter((listener)=>listener.element !==
|
|
293
|
+
// Mutate eventListeners to remove listeners for this highlight
|
|
294
|
+
eventListeners.splice(0, eventListeners.length, ...eventListeners.filter((listener)=>listener.element !== highlight));
|
|
229
295
|
};
|
|
230
296
|
// Process all existing elements with source attributes
|
|
231
297
|
const initialElements = window.document.querySelectorAll(`[${SOURCE_ATTRIBUTE}]`);
|
|
@@ -249,7 +315,11 @@
|
|
|
249
315
|
setFocusedField: (field)=>{
|
|
250
316
|
focusedField = field;
|
|
251
317
|
},
|
|
252
|
-
getFocusedField: ()=>focusedField
|
|
318
|
+
getFocusedField: ()=>focusedField,
|
|
319
|
+
clearAllPendingClicks: ()=>{
|
|
320
|
+
pendingClicks.forEach((timeout)=>clearTimeout(timeout));
|
|
321
|
+
pendingClicks.clear();
|
|
322
|
+
}
|
|
253
323
|
};
|
|
254
324
|
};
|
|
255
325
|
/**
|
|
@@ -383,7 +453,7 @@
|
|
|
383
453
|
if (!field) return;
|
|
384
454
|
// Clear existing focused highlights
|
|
385
455
|
highlightManager.focusedHighlights.forEach((highlight)=>{
|
|
386
|
-
highlight.
|
|
456
|
+
highlight.classList.remove('strapi-highlight-focused');
|
|
387
457
|
});
|
|
388
458
|
highlightManager.focusedHighlights.length = 0;
|
|
389
459
|
// Set new focused field and highlight matching elements
|
|
@@ -397,8 +467,7 @@
|
|
|
397
467
|
}
|
|
398
468
|
const highlight = highlightManager.highlights[Array.from(highlightManager.elements).indexOf(element)];
|
|
399
469
|
if (highlight) {
|
|
400
|
-
highlight.
|
|
401
|
-
highlight.style.outlineWidth = '3px';
|
|
470
|
+
highlight.classList.add('strapi-highlight-focused');
|
|
402
471
|
highlightManager.focusedHighlights.push(highlight);
|
|
403
472
|
}
|
|
404
473
|
});
|
|
@@ -409,8 +478,7 @@
|
|
|
409
478
|
const { field } = event.data.payload;
|
|
410
479
|
if (field !== highlightManager.getFocusedField()) return;
|
|
411
480
|
highlightManager.focusedHighlights.forEach((highlight)=>{
|
|
412
|
-
highlight.
|
|
413
|
-
highlight.style.outlineWidth = '2px';
|
|
481
|
+
highlight.classList.remove('strapi-highlight-focused');
|
|
414
482
|
});
|
|
415
483
|
highlightManager.focusedHighlights.length = 0;
|
|
416
484
|
highlightManager.setFocusedField(null);
|
|
@@ -428,29 +496,37 @@
|
|
|
428
496
|
messageEventListener
|
|
429
497
|
];
|
|
430
498
|
};
|
|
431
|
-
const createCleanupSystem = (overlay, observers, scrollManager, eventHandlers)=>{
|
|
499
|
+
const createCleanupSystem = (overlay, observers, scrollManager, eventHandlers, highlightManager)=>{
|
|
432
500
|
window.__strapi_previewCleanup = ()=>{
|
|
433
501
|
observers.resizeObserver.disconnect();
|
|
434
502
|
observers.highlightObserver.disconnect();
|
|
435
503
|
observers.stegaObserver?.disconnect();
|
|
436
504
|
// Clean up scroll listeners
|
|
437
505
|
scrollManager.cleanup();
|
|
506
|
+
// Clear all pending click timeouts
|
|
507
|
+
highlightManager.clearAllPendingClicks();
|
|
438
508
|
// Remove highlight event listeners
|
|
439
509
|
eventHandlers.forEach(({ element, type, handler })=>{
|
|
440
510
|
element.removeEventListener(type, handler);
|
|
441
511
|
});
|
|
512
|
+
// Clean up CSS styles
|
|
513
|
+
const existingStyles = document.getElementById(HIGHLIGHT_STYLES_ID);
|
|
514
|
+
if (existingStyles) {
|
|
515
|
+
existingStyles.remove();
|
|
516
|
+
}
|
|
442
517
|
overlay.remove();
|
|
443
518
|
};
|
|
444
519
|
};
|
|
445
520
|
/* -----------------------------------------------------------------------------------------------
|
|
446
521
|
* Orchestration
|
|
447
522
|
* ---------------------------------------------------------------------------------------------*/ setupStegaDOMObserver().then((stegaObserver)=>{
|
|
523
|
+
createHighlightStyles();
|
|
448
524
|
const overlay = createOverlaySystem();
|
|
449
525
|
const highlightManager = createHighlightManager(overlay);
|
|
450
526
|
const observers = setupObservers(highlightManager, stegaObserver);
|
|
451
527
|
const scrollManager = setupScrollManagement(highlightManager);
|
|
452
528
|
const eventHandlers = setupEventHandlers(highlightManager);
|
|
453
|
-
createCleanupSystem(overlay, observers, scrollManager, eventHandlers);
|
|
529
|
+
createCleanupSystem(overlay, observers, scrollManager, eventHandlers, highlightManager);
|
|
454
530
|
});
|
|
455
531
|
};
|
|
456
532
|
|