@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.
Files changed (181) hide show
  1. package/dist/admin/components/ConfigurationForm/EditFieldForm.js +1 -1
  2. package/dist/admin/components/ConfigurationForm/EditFieldForm.js.map +1 -1
  3. package/dist/admin/components/ConfigurationForm/EditFieldForm.mjs +1 -1
  4. package/dist/admin/components/ConfigurationForm/EditFieldForm.mjs.map +1 -1
  5. package/dist/admin/components/ConfigurationForm/Fields.js +4 -1
  6. package/dist/admin/components/ConfigurationForm/Fields.js.map +1 -1
  7. package/dist/admin/components/ConfigurationForm/Fields.mjs +5 -2
  8. package/dist/admin/components/ConfigurationForm/Fields.mjs.map +1 -1
  9. package/dist/admin/components/ConfigurationForm/Form.js +1 -1
  10. package/dist/admin/components/ConfigurationForm/Form.js.map +1 -1
  11. package/dist/admin/components/ConfigurationForm/Form.mjs +3 -3
  12. package/dist/admin/components/ConfigurationForm/Form.mjs.map +1 -1
  13. package/dist/admin/components/DragPreviews/CardDragPreview.js +3 -1
  14. package/dist/admin/components/DragPreviews/CardDragPreview.js.map +1 -1
  15. package/dist/admin/components/DragPreviews/CardDragPreview.mjs +3 -1
  16. package/dist/admin/components/DragPreviews/CardDragPreview.mjs.map +1 -1
  17. package/dist/admin/components/DragPreviews/ComponentDragPreview.js +3 -1
  18. package/dist/admin/components/DragPreviews/ComponentDragPreview.js.map +1 -1
  19. package/dist/admin/components/DragPreviews/ComponentDragPreview.mjs +3 -1
  20. package/dist/admin/components/DragPreviews/ComponentDragPreview.mjs.map +1 -1
  21. package/dist/admin/components/DragPreviews/RelationDragPreview.js +3 -1
  22. package/dist/admin/components/DragPreviews/RelationDragPreview.js.map +1 -1
  23. package/dist/admin/components/DragPreviews/RelationDragPreview.mjs +3 -1
  24. package/dist/admin/components/DragPreviews/RelationDragPreview.mjs.map +1 -1
  25. package/dist/admin/components/LeftMenu.js +90 -48
  26. package/dist/admin/components/LeftMenu.js.map +1 -1
  27. package/dist/admin/components/LeftMenu.mjs +92 -50
  28. package/dist/admin/components/LeftMenu.mjs.map +1 -1
  29. package/dist/admin/components/Widgets.js +22 -6
  30. package/dist/admin/components/Widgets.js.map +1 -1
  31. package/dist/admin/components/Widgets.mjs +22 -6
  32. package/dist/admin/components/Widgets.mjs.map +1 -1
  33. package/dist/admin/history/components/VersionHeader.js +1 -0
  34. package/dist/admin/history/components/VersionHeader.js.map +1 -1
  35. package/dist/admin/history/components/VersionHeader.mjs +1 -0
  36. package/dist/admin/history/components/VersionHeader.mjs.map +1 -1
  37. package/dist/admin/history/components/VersionsList.js +1 -1
  38. package/dist/admin/history/components/VersionsList.js.map +1 -1
  39. package/dist/admin/history/components/VersionsList.mjs +1 -1
  40. package/dist/admin/history/components/VersionsList.mjs.map +1 -1
  41. package/dist/admin/history/pages/History.js +7 -7
  42. package/dist/admin/history/pages/History.js.map +1 -1
  43. package/dist/admin/history/pages/History.mjs +7 -7
  44. package/dist/admin/history/pages/History.mjs.map +1 -1
  45. package/dist/admin/layout.js +27 -6
  46. package/dist/admin/layout.js.map +1 -1
  47. package/dist/admin/layout.mjs +28 -7
  48. package/dist/admin/layout.mjs.map +1 -1
  49. package/dist/admin/pages/EditView/EditViewPage.js +7 -3
  50. package/dist/admin/pages/EditView/EditViewPage.js.map +1 -1
  51. package/dist/admin/pages/EditView/EditViewPage.mjs +8 -4
  52. package/dist/admin/pages/EditView/EditViewPage.mjs.map +1 -1
  53. package/dist/admin/pages/EditView/components/DocumentActions.js +6 -0
  54. package/dist/admin/pages/EditView/components/DocumentActions.js.map +1 -1
  55. package/dist/admin/pages/EditView/components/DocumentActions.mjs +6 -0
  56. package/dist/admin/pages/EditView/components/DocumentActions.mjs.map +1 -1
  57. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.js +66 -2
  58. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.js.map +1 -1
  59. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.mjs +66 -2
  60. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.mjs.map +1 -1
  61. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.js +2 -2
  62. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.js.map +1 -1
  63. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.mjs +2 -2
  64. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.mjs.map +1 -1
  65. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/utils/links.js +7 -3
  66. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/utils/links.js.map +1 -1
  67. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/utils/links.mjs +7 -3
  68. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/utils/links.mjs.map +1 -1
  69. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js +2 -1
  70. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js.map +1 -1
  71. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs +3 -2
  72. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs.map +1 -1
  73. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.js +1 -2
  74. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.js.map +1 -1
  75. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.mjs +1 -2
  76. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.mjs.map +1 -1
  77. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js +4 -3
  78. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js.map +1 -1
  79. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs +5 -4
  80. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs.map +1 -1
  81. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +2 -1
  82. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
  83. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs +3 -2
  84. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs.map +1 -1
  85. package/dist/admin/pages/EditView/components/FormInputs/UID.js +2 -1
  86. package/dist/admin/pages/EditView/components/FormInputs/UID.js.map +1 -1
  87. package/dist/admin/pages/EditView/components/FormInputs/UID.mjs +2 -1
  88. package/dist/admin/pages/EditView/components/FormInputs/UID.mjs.map +1 -1
  89. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.js +2 -2
  90. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.js.map +1 -1
  91. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.mjs +2 -2
  92. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.mjs.map +1 -1
  93. package/dist/admin/pages/EditView/components/FormLayout.js +13 -8
  94. package/dist/admin/pages/EditView/components/FormLayout.js.map +1 -1
  95. package/dist/admin/pages/EditView/components/FormLayout.mjs +14 -8
  96. package/dist/admin/pages/EditView/components/FormLayout.mjs.map +1 -1
  97. package/dist/admin/pages/EditView/components/Header.js +85 -25
  98. package/dist/admin/pages/EditView/components/Header.js.map +1 -1
  99. package/dist/admin/pages/EditView/components/Header.mjs +87 -27
  100. package/dist/admin/pages/EditView/components/Header.mjs.map +1 -1
  101. package/dist/admin/pages/ListConfiguration/ListConfigurationPage.js +1 -0
  102. package/dist/admin/pages/ListConfiguration/ListConfigurationPage.js.map +1 -1
  103. package/dist/admin/pages/ListConfiguration/ListConfigurationPage.mjs +1 -0
  104. package/dist/admin/pages/ListConfiguration/ListConfigurationPage.mjs.map +1 -1
  105. package/dist/admin/pages/ListView/components/Filters.js +4 -1
  106. package/dist/admin/pages/ListView/components/Filters.js.map +1 -1
  107. package/dist/admin/pages/ListView/components/Filters.mjs +4 -1
  108. package/dist/admin/pages/ListView/components/Filters.mjs.map +1 -1
  109. package/dist/admin/pages/ListView/components/ViewSettingsMenu.js +5 -2
  110. package/dist/admin/pages/ListView/components/ViewSettingsMenu.js.map +1 -1
  111. package/dist/admin/pages/ListView/components/ViewSettingsMenu.mjs +5 -2
  112. package/dist/admin/pages/ListView/components/ViewSettingsMenu.mjs.map +1 -1
  113. package/dist/admin/preview/components/InputPopover.js +29 -9
  114. package/dist/admin/preview/components/InputPopover.js.map +1 -1
  115. package/dist/admin/preview/components/InputPopover.mjs +31 -11
  116. package/dist/admin/preview/components/InputPopover.mjs.map +1 -1
  117. package/dist/admin/preview/pages/Preview.js +6 -6
  118. package/dist/admin/preview/pages/Preview.js.map +1 -1
  119. package/dist/admin/preview/pages/Preview.mjs +6 -6
  120. package/dist/admin/preview/pages/Preview.mjs.map +1 -1
  121. package/dist/admin/preview/utils/constants.js +34 -0
  122. package/dist/admin/preview/utils/constants.js.map +1 -1
  123. package/dist/admin/preview/utils/constants.mjs +34 -1
  124. package/dist/admin/preview/utils/constants.mjs.map +1 -1
  125. package/dist/admin/preview/utils/fieldUtils.js +13 -4
  126. package/dist/admin/preview/utils/fieldUtils.js.map +1 -1
  127. package/dist/admin/preview/utils/fieldUtils.mjs +13 -5
  128. package/dist/admin/preview/utils/fieldUtils.mjs.map +1 -1
  129. package/dist/admin/preview/utils/previewScript.js +120 -44
  130. package/dist/admin/preview/utils/previewScript.js.map +1 -1
  131. package/dist/admin/preview/utils/previewScript.mjs +120 -44
  132. package/dist/admin/preview/utils/previewScript.mjs.map +1 -1
  133. package/dist/admin/services/api.js +2 -1
  134. package/dist/admin/services/api.js.map +1 -1
  135. package/dist/admin/services/api.mjs +2 -1
  136. package/dist/admin/services/api.mjs.map +1 -1
  137. package/dist/admin/services/documents.js +19 -3
  138. package/dist/admin/services/documents.js.map +1 -1
  139. package/dist/admin/services/documents.mjs +19 -3
  140. package/dist/admin/services/documents.mjs.map +1 -1
  141. package/dist/admin/src/components/LeftMenu.d.ts +3 -1
  142. package/dist/admin/src/components/Widgets.d.ts +6 -2
  143. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  144. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/links.d.ts +2 -0
  145. package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +0 -3
  146. package/dist/admin/src/pages/EditView/components/Header.d.ts +4 -0
  147. package/dist/admin/src/preview/services/preview.d.ts +1 -1
  148. package/dist/admin/src/preview/utils/constants.d.ts +35 -0
  149. package/dist/admin/src/preview/utils/fieldUtils.d.ts +6 -0
  150. package/dist/admin/src/preview/utils/previewScript.d.ts +1 -0
  151. package/dist/admin/src/services/api.d.ts +1 -1
  152. package/dist/admin/src/services/components.d.ts +2 -2
  153. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  154. package/dist/admin/src/services/documents.d.ts +16 -16
  155. package/dist/admin/src/services/homepage.d.ts +1 -1
  156. package/dist/admin/src/services/init.d.ts +1 -1
  157. package/dist/admin/src/services/relations.d.ts +2 -2
  158. package/dist/admin/src/services/uid.d.ts +3 -3
  159. package/dist/admin/translations/en.json.js +5 -0
  160. package/dist/admin/translations/en.json.js.map +1 -1
  161. package/dist/admin/translations/en.json.mjs +5 -0
  162. package/dist/admin/translations/en.json.mjs.map +1 -1
  163. package/dist/server/controllers/collection-types.js +2 -1
  164. package/dist/server/controllers/collection-types.js.map +1 -1
  165. package/dist/server/controllers/collection-types.mjs +2 -1
  166. package/dist/server/controllers/collection-types.mjs.map +1 -1
  167. package/dist/server/controllers/relations.js +6 -4
  168. package/dist/server/controllers/relations.js.map +1 -1
  169. package/dist/server/controllers/relations.mjs +6 -4
  170. package/dist/server/controllers/relations.mjs.map +1 -1
  171. package/dist/server/controllers/single-types.js.map +1 -1
  172. package/dist/server/controllers/single-types.mjs.map +1 -1
  173. package/dist/server/preview/services/preview-config.js +8 -33
  174. package/dist/server/preview/services/preview-config.js.map +1 -1
  175. package/dist/server/preview/services/preview-config.mjs +9 -34
  176. package/dist/server/preview/services/preview-config.mjs.map +1 -1
  177. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  178. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  179. package/dist/server/src/controllers/single-types.d.ts.map +1 -1
  180. package/dist/server/src/preview/services/preview-config.d.ts.map +1 -1
  181. 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":";;;;AAEA,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;;;;;"}
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":";;AAEA,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;;;;"}
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 Error('Invalid field path');
51
+ throw new PreviewFieldError('INVALID_FIELD_PATH');
44
52
  }
45
53
  if (currentAttribute.type === 'relation') {
46
- throw new Error('Relations not handled');
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 Error('Invalid field path');
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 Error('Invalid field path');
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 Error('Invalid field path');\n }\n\n if (currentAttribute.type === 'relation') {\n throw new Error('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 Error('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 Error('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":["parsePathWithIndices","path","split","map","part","numericIndex","parseInt","isNaN","toString","name","index","reduce","acc","undefined","length","push","getAttributeSchemaFromPath","schema","components","document","visitor","currentPathParts","currentAttributes","currentData","currentPart","remainingParts","currentAttribute","Error","type","componentAttributes","component","attributes","repeatable","componentData","__component","parseFieldMetaData","strapiSource","searchParams","URLSearchParams","get","documentId","locale","model","kind"],"mappings":"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"}
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 Error('Invalid field path');
49
+ throw new PreviewFieldError('INVALID_FIELD_PATH');
42
50
  }
43
51
  if (currentAttribute.type === 'relation') {
44
- throw new Error('Relations not handled');
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 Error('Invalid field path');
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 Error('Invalid field path');
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 Error('Invalid field path');\n }\n\n if (currentAttribute.type === 'relation') {\n throw new Error('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 Error('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 Error('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":["parsePathWithIndices","path","split","map","part","numericIndex","parseInt","isNaN","toString","name","index","reduce","acc","undefined","length","push","getAttributeSchemaFromPath","schema","components","document","visitor","currentPathParts","currentAttributes","currentData","currentPart","remainingParts","currentAttribute","Error","type","componentAttributes","component","attributes","repeatable","componentData","__component","parseFieldMetaData","strapiSource","searchParams","URLSearchParams","get","documentId","locale","model","kind"],"mappings":"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"}
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.style.cssText = `
149
- position: absolute;
150
- outline: 2px solid transparent;
151
- pointer-events: none;
152
- border-radius: 2px;
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
- const mouseLeaveHandler = ()=>{
164
- if (!focusedHighlights.includes(highlight)) {
165
- highlight.style.outlineColor = 'transparent';
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
- element.addEventListener('mouseenter', mouseEnterHandler);
192
- element.addEventListener('mouseleave', mouseLeaveHandler);
193
- element.addEventListener('dblclick', doubleClickHandler);
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: 'mouseenter',
199
- handler: mouseEnterHandler
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 element
223
- const listenersToRemove = eventListeners.filter((listener)=>listener.element === 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 element
228
- eventListeners.splice(0, eventListeners.length, ...eventListeners.filter((listener)=>listener.element !== 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.style.outlineColor = 'transparent';
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.style.outlineColor = HIGHLIGHT_ACTIVE_COLOR;
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.style.outlineColor = 'transparent';
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