@strapi/content-manager 0.0.0-next.e3eb76a86aff89979cc9098aec129d2ffa600c56 → 0.0.0-next.e5d4b412da0d932b61b2fa5012d16513fda6de04

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/Widgets.js +267 -9
  2. package/dist/admin/components/Widgets.js.map +1 -1
  3. package/dist/admin/components/Widgets.mjs +250 -12
  4. package/dist/admin/components/Widgets.mjs.map +1 -1
  5. package/dist/admin/history/components/VersionContent.js +24 -3
  6. package/dist/admin/history/components/VersionContent.js.map +1 -1
  7. package/dist/admin/history/components/VersionContent.mjs +25 -4
  8. package/dist/admin/history/components/VersionContent.mjs.map +1 -1
  9. package/dist/admin/hooks/useDocumentActions.js +0 -3
  10. package/dist/admin/hooks/useDocumentActions.js.map +1 -1
  11. package/dist/admin/hooks/useDocumentActions.mjs +1 -4
  12. package/dist/admin/hooks/useDocumentActions.mjs.map +1 -1
  13. package/dist/admin/index.js +47 -8
  14. package/dist/admin/index.js.map +1 -1
  15. package/dist/admin/index.mjs +47 -9
  16. package/dist/admin/index.mjs.map +1 -1
  17. package/dist/admin/layout.js +1 -27
  18. package/dist/admin/layout.js.map +1 -1
  19. package/dist/admin/layout.mjs +2 -9
  20. package/dist/admin/layout.mjs.map +1 -1
  21. package/dist/admin/pages/EditView/EditViewPage.js +24 -6
  22. package/dist/admin/pages/EditView/EditViewPage.js.map +1 -1
  23. package/dist/admin/pages/EditView/EditViewPage.mjs +26 -8
  24. package/dist/admin/pages/EditView/EditViewPage.mjs.map +1 -1
  25. package/dist/admin/pages/EditView/components/DocumentActions.js +69 -20
  26. package/dist/admin/pages/EditView/components/DocumentActions.js.map +1 -1
  27. package/dist/admin/pages/EditView/components/DocumentActions.mjs +70 -21
  28. package/dist/admin/pages/EditView/components/DocumentActions.mjs.map +1 -1
  29. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js +12 -1
  30. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js.map +1 -1
  31. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs +13 -2
  32. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs.map +1 -1
  33. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js +13 -2
  34. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js.map +1 -1
  35. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs +14 -3
  36. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs.map +1 -1
  37. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js +16 -3
  38. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js.map +1 -1
  39. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs +17 -4
  40. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs.map +1 -1
  41. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js +1 -0
  42. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js.map +1 -1
  43. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs +1 -0
  44. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs.map +1 -1
  45. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +4 -1
  46. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
  47. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs +4 -1
  48. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs.map +1 -1
  49. package/dist/admin/pages/EditView/components/FormLayout.js +27 -3
  50. package/dist/admin/pages/EditView/components/FormLayout.js.map +1 -1
  51. package/dist/admin/pages/EditView/components/FormLayout.mjs +27 -3
  52. package/dist/admin/pages/EditView/components/FormLayout.mjs.map +1 -1
  53. package/dist/admin/pages/EditView/utils/data.js +109 -0
  54. package/dist/admin/pages/EditView/utils/data.js.map +1 -1
  55. package/dist/admin/pages/EditView/utils/data.mjs +109 -1
  56. package/dist/admin/pages/EditView/utils/data.mjs.map +1 -1
  57. package/dist/admin/pages/ListView/ListViewPage.js +221 -203
  58. package/dist/admin/pages/ListView/ListViewPage.js.map +1 -1
  59. package/dist/admin/pages/ListView/ListViewPage.mjs +222 -204
  60. package/dist/admin/pages/ListView/ListViewPage.mjs.map +1 -1
  61. package/dist/admin/pages/ListView/components/BulkActions/PublishAction.js +12 -2
  62. package/dist/admin/pages/ListView/components/BulkActions/PublishAction.js.map +1 -1
  63. package/dist/admin/pages/ListView/components/BulkActions/PublishAction.mjs +12 -2
  64. package/dist/admin/pages/ListView/components/BulkActions/PublishAction.mjs.map +1 -1
  65. package/dist/admin/pages/ListView/components/Filters.js +3 -1
  66. package/dist/admin/pages/ListView/components/Filters.js.map +1 -1
  67. package/dist/admin/pages/ListView/components/Filters.mjs +3 -1
  68. package/dist/admin/pages/ListView/components/Filters.mjs.map +1 -1
  69. package/dist/admin/preview/components/PreviewSidePanel.js +31 -4
  70. package/dist/admin/preview/components/PreviewSidePanel.js.map +1 -1
  71. package/dist/admin/preview/components/PreviewSidePanel.mjs +32 -5
  72. package/dist/admin/preview/components/PreviewSidePanel.mjs.map +1 -1
  73. package/dist/admin/preview/pages/Preview.js +136 -35
  74. package/dist/admin/preview/pages/Preview.js.map +1 -1
  75. package/dist/admin/preview/pages/Preview.mjs +137 -36
  76. package/dist/admin/preview/pages/Preview.mjs.map +1 -1
  77. package/dist/admin/preview/utils/constants.js +21 -0
  78. package/dist/admin/preview/utils/constants.js.map +1 -0
  79. package/dist/admin/preview/utils/constants.mjs +19 -0
  80. package/dist/admin/preview/utils/constants.mjs.map +1 -0
  81. package/dist/admin/preview/utils/previewScript.js +203 -0
  82. package/dist/admin/preview/utils/previewScript.js.map +1 -0
  83. package/dist/admin/preview/utils/previewScript.mjs +201 -0
  84. package/dist/admin/preview/utils/previewScript.mjs.map +1 -0
  85. package/dist/admin/services/api.js +4 -1
  86. package/dist/admin/services/api.js.map +1 -1
  87. package/dist/admin/services/api.mjs +4 -1
  88. package/dist/admin/services/api.mjs.map +1 -1
  89. package/dist/admin/services/documents.js +40 -14
  90. package/dist/admin/services/documents.js.map +1 -1
  91. package/dist/admin/services/documents.mjs +40 -14
  92. package/dist/admin/services/documents.mjs.map +1 -1
  93. package/dist/admin/src/components/Widgets.d.ts +2 -1
  94. package/dist/admin/src/exports.d.ts +1 -0
  95. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  96. package/dist/admin/src/pages/EditView/utils/data.d.ts +19 -1
  97. package/dist/admin/src/preview/services/preview.d.ts +1 -1
  98. package/dist/admin/src/preview/utils/constants.d.ts +17 -0
  99. package/dist/admin/src/preview/utils/previewScript.d.ts +18 -0
  100. package/dist/admin/src/services/api.d.ts +1 -1
  101. package/dist/admin/src/services/components.d.ts +2 -2
  102. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  103. package/dist/admin/src/services/documents.d.ts +16 -16
  104. package/dist/admin/src/services/homepage.d.ts +1 -1
  105. package/dist/admin/src/services/init.d.ts +1 -1
  106. package/dist/admin/src/services/relations.d.ts +2 -2
  107. package/dist/admin/src/services/uid.d.ts +3 -3
  108. package/dist/admin/src/utils/api.d.ts +1 -1
  109. package/dist/admin/src/utils/validation.d.ts +1 -0
  110. package/dist/admin/translations/en.json.js +6 -0
  111. package/dist/admin/translations/en.json.js.map +1 -1
  112. package/dist/admin/translations/en.json.mjs +6 -0
  113. package/dist/admin/translations/en.json.mjs.map +1 -1
  114. package/dist/admin/translations/es.json.js +5 -2
  115. package/dist/admin/translations/es.json.js.map +1 -1
  116. package/dist/admin/translations/es.json.mjs +5 -2
  117. package/dist/admin/translations/es.json.mjs.map +1 -1
  118. package/dist/admin/translations/fr.json.js +10 -2
  119. package/dist/admin/translations/fr.json.js.map +1 -1
  120. package/dist/admin/translations/fr.json.mjs +10 -2
  121. package/dist/admin/translations/fr.json.mjs.map +1 -1
  122. package/dist/admin/utils/api.js +1 -1
  123. package/dist/admin/utils/api.js.map +1 -1
  124. package/dist/admin/utils/api.mjs +1 -1
  125. package/dist/admin/utils/api.mjs.map +1 -1
  126. package/dist/admin/utils/validation.js +18 -6
  127. package/dist/admin/utils/validation.js.map +1 -1
  128. package/dist/admin/utils/validation.mjs +18 -6
  129. package/dist/admin/utils/validation.mjs.map +1 -1
  130. package/dist/server/controllers/relations.js +2 -2
  131. package/dist/server/controllers/relations.js.map +1 -1
  132. package/dist/server/controllers/relations.mjs +2 -2
  133. package/dist/server/controllers/relations.mjs.map +1 -1
  134. package/dist/server/history/services/lifecycles.js +20 -19
  135. package/dist/server/history/services/lifecycles.js.map +1 -1
  136. package/dist/server/history/services/lifecycles.mjs +20 -19
  137. package/dist/server/history/services/lifecycles.mjs.map +1 -1
  138. package/dist/server/homepage/controllers/homepage.js +5 -0
  139. package/dist/server/homepage/controllers/homepage.js.map +1 -1
  140. package/dist/server/homepage/controllers/homepage.mjs +5 -0
  141. package/dist/server/homepage/controllers/homepage.mjs.map +1 -1
  142. package/dist/server/homepage/routes/homepage.js +11 -0
  143. package/dist/server/homepage/routes/homepage.js.map +1 -1
  144. package/dist/server/homepage/routes/homepage.mjs +11 -0
  145. package/dist/server/homepage/routes/homepage.mjs.map +1 -1
  146. package/dist/server/homepage/services/homepage.js +86 -46
  147. package/dist/server/homepage/services/homepage.js.map +1 -1
  148. package/dist/server/homepage/services/homepage.mjs +86 -46
  149. package/dist/server/homepage/services/homepage.mjs.map +1 -1
  150. package/dist/server/preview/services/preview-config.js +5 -1
  151. package/dist/server/preview/services/preview-config.js.map +1 -1
  152. package/dist/server/preview/services/preview-config.mjs +5 -1
  153. package/dist/server/preview/services/preview-config.mjs.map +1 -1
  154. package/dist/server/preview/services/preview.js +4 -0
  155. package/dist/server/preview/services/preview.js.map +1 -1
  156. package/dist/server/preview/services/preview.mjs +4 -0
  157. package/dist/server/preview/services/preview.mjs.map +1 -1
  158. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  159. package/dist/server/src/homepage/controllers/homepage.d.ts +2 -1
  160. package/dist/server/src/homepage/controllers/homepage.d.ts.map +1 -1
  161. package/dist/server/src/homepage/index.d.ts +7 -0
  162. package/dist/server/src/homepage/index.d.ts.map +1 -1
  163. package/dist/server/src/homepage/routes/homepage.d.ts.map +1 -1
  164. package/dist/server/src/homepage/services/homepage.d.ts +4 -1
  165. package/dist/server/src/homepage/services/homepage.d.ts.map +1 -1
  166. package/dist/server/src/homepage/services/index.d.ts +7 -0
  167. package/dist/server/src/homepage/services/index.d.ts.map +1 -1
  168. package/dist/server/src/index.d.ts +7 -0
  169. package/dist/server/src/index.d.ts.map +1 -1
  170. package/dist/server/src/preview/services/index.d.ts +1 -0
  171. package/dist/server/src/preview/services/index.d.ts.map +1 -1
  172. package/dist/server/src/preview/services/preview-config.d.ts +1 -0
  173. package/dist/server/src/preview/services/preview-config.d.ts.map +1 -1
  174. package/dist/server/src/preview/services/preview.d.ts.map +1 -1
  175. package/dist/server/src/preview/utils.d.ts +1 -0
  176. package/dist/server/src/preview/utils.d.ts.map +1 -1
  177. package/dist/server/src/services/index.d.ts +7 -0
  178. package/dist/server/src/services/index.d.ts.map +1 -1
  179. package/dist/shared/contracts/homepage.d.ts +13 -0
  180. package/dist/shared/contracts/homepage.d.ts.map +1 -1
  181. package/package.json +7 -8
@@ -1,7 +1,7 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
  import { createContext, useRBAC, Page, useQueryParams, Form, Blocker } from '@strapi/admin/strapi-admin';
4
- import { Portal, FocusTrap, Box, Flex, IconButton } from '@strapi/design-system';
4
+ import { Portal, FocusTrap, Box, Flex, IconButton, SingleSelect, SingleSelectOption } from '@strapi/design-system';
5
5
  import { ArrowLineLeft } from '@strapi/icons';
6
6
  import { useIntl } from 'react-intl';
7
7
  import { useParams, useLocation } from 'react-router-dom';
@@ -11,19 +11,61 @@ import { DocumentRBAC } from '../../features/DocumentRBAC.mjs';
11
11
  import { useDocument } from '../../hooks/useDocument.mjs';
12
12
  import { useDocumentLayout } from '../../hooks/useDocumentLayout.mjs';
13
13
  import { FormLayout } from '../../pages/EditView/components/FormLayout.mjs';
14
+ import { handleInvisibleAttributes } from '../../pages/EditView/utils/data.mjs';
14
15
  import { buildValidParams } from '../../utils/api.mjs';
15
16
  import { createYupSchema } from '../../utils/validation.mjs';
16
17
  import { PreviewHeader } from '../components/PreviewHeader.mjs';
17
18
  import { useGetPreviewUrlQuery } from '../services/preview.mjs';
19
+ import { PUBLIC_EVENTS } from '../utils/constants.mjs';
20
+ import { previewScript } from '../utils/previewScript.mjs';
18
21
 
22
+ /* -------------------------------------------------------------------------------------------------
23
+ * Constants
24
+ * -----------------------------------------------------------------------------------------------*/ const DEVICES = [
25
+ {
26
+ name: 'desktop',
27
+ label: {
28
+ id: 'content-manager.preview.device.desktop',
29
+ defaultMessage: 'Desktop'
30
+ },
31
+ width: '100%',
32
+ height: '100%'
33
+ },
34
+ {
35
+ name: 'mobile',
36
+ label: {
37
+ id: 'content-manager.preview.device.mobile',
38
+ defaultMessage: 'Mobile'
39
+ },
40
+ width: '375px',
41
+ height: '667px'
42
+ }
43
+ ];
19
44
  const [PreviewProvider, usePreviewContext] = createContext('PreviewPage');
20
45
  /* -------------------------------------------------------------------------------------------------
21
46
  * PreviewPage
22
47
  * -----------------------------------------------------------------------------------------------*/ const AnimatedArrow = styled(ArrowLineLeft)`
23
48
  will-change: transform;
24
- rotate: ${(props)=>props.isSideEditorOpen ? '0deg' : '180deg'};
49
+ rotate: ${(props)=>props.$isSideEditorOpen ? '0deg' : '180deg'};
25
50
  transition: rotate 0.2s ease-in-out;
26
51
  `;
52
+ /**
53
+ * A function factory so we can generate a new sendMessage everytime we need one.
54
+ * We can't store and reuse a single sendMessage because it needs to have a stable identity
55
+ * as it used in a useEffect function. And we can't rely on useCallback because we need the
56
+ * up-to-date iframe ref, and this would make it stale (refs don't trigger callback reevaluations).
57
+ */ function getSendMessage(iframe) {
58
+ return (type, payload)=>{
59
+ if (!iframe.current) return;
60
+ const { origin } = new URL(iframe.current.src);
61
+ iframe.current.contentWindow?.postMessage({
62
+ type,
63
+ ...payload !== undefined && {
64
+ payload
65
+ }
66
+ }, origin);
67
+ };
68
+ }
27
69
  const PreviewPage = ()=>{
28
70
  const location = useLocation();
29
71
  const { formatMessage } = useIntl();
@@ -35,6 +77,24 @@ const PreviewPage = ()=>{
35
77
  const params = React.useMemo(()=>buildValidParams(query), [
36
78
  query
37
79
  ]);
80
+ const [deviceName, setDeviceName] = React.useState(DEVICES[0].name);
81
+ const device = DEVICES.find((d)=>d.name === deviceName) ?? DEVICES[0];
82
+ // Listen for ready message from iframe before injecting script
83
+ React.useEffect(()=>{
84
+ const handleMessage = (event)=>{
85
+ if (event.data?.type === PUBLIC_EVENTS.PREVIEW_READY) {
86
+ const script = `(${previewScript.toString()})()`;
87
+ const sendMessage = getSendMessage(iframeRef);
88
+ sendMessage(PUBLIC_EVENTS.STRAPI_SCRIPT, {
89
+ script
90
+ });
91
+ }
92
+ };
93
+ window.addEventListener('message', handleMessage);
94
+ return ()=>{
95
+ window.removeEventListener('message', handleMessage);
96
+ };
97
+ }, []);
38
98
  if (!collectionType) {
39
99
  throw new Error('Could not find collectionType in url params');
40
100
  }
@@ -63,7 +123,7 @@ const PreviewPage = ()=>{
63
123
  });
64
124
  const documentLayoutResponse = useDocumentLayout(model);
65
125
  const isLoading = previewUrlResponse.isLoading || documentLayoutResponse.isLoading || documentResponse.isLoading;
66
- if (isLoading && !documentResponse.document?.documentId) {
126
+ if (isLoading && (!documentResponse.document?.documentId || previewUrlResponse.isLoading)) {
67
127
  return /*#__PURE__*/ jsx(Page.Loading, {});
68
128
  }
69
129
  const initialValues = documentResponse.getInitialFormValues();
@@ -75,11 +135,17 @@ const PreviewPage = ()=>{
75
135
  }
76
136
  const documentTitle = documentResponse.getTitle(documentLayoutResponse.edit.settings.mainField);
77
137
  const validateSync = (values, options)=>{
138
+ const { data: cleanedValues, removedAttributes } = handleInvisibleAttributes(values, {
139
+ schema: documentResponse.schema,
140
+ initialValues,
141
+ components: documentResponse.components
142
+ });
78
143
  const yupSchema = createYupSchema(documentResponse.schema?.attributes, documentResponse.components, {
79
144
  status: documentResponse.document?.status,
145
+ removedAttributes,
80
146
  ...options
81
147
  });
82
- return yupSchema.validateSync(values, {
148
+ return yupSchema.validateSync(cleanedValues, {
83
149
  abortEarly: false
84
150
  });
85
151
  };
@@ -116,11 +182,17 @@ const PreviewPage = ()=>{
116
182
  initialErrors: location?.state?.forceValidation ? validateSync(initialValues, {}) : {},
117
183
  height: "100%",
118
184
  validate: (values, options)=>{
185
+ const { data: cleanedValues, removedAttributes } = handleInvisibleAttributes(values, {
186
+ schema: documentResponse.schema,
187
+ initialValues,
188
+ components: documentResponse.components
189
+ });
119
190
  const yupSchema = createYupSchema(documentResponse.schema?.attributes, documentResponse.components, {
120
191
  status: documentResponse.document?.status,
192
+ removedAttributes,
121
193
  ...options
122
194
  });
123
- return yupSchema.validate(values, {
195
+ return yupSchema.validate(cleanedValues, {
124
196
  abortEarly: false
125
197
  });
126
198
  },
@@ -155,41 +227,70 @@ const PreviewPage = ()=>{
155
227
  hasBackground: false
156
228
  })
157
229
  }),
158
- /*#__PURE__*/ jsxs(Box, {
159
- position: "relative",
230
+ /*#__PURE__*/ jsxs(Flex, {
231
+ direction: "column",
232
+ alignItems: "stretch",
160
233
  flex: 1,
161
234
  height: "100%",
162
235
  overflow: "hidden",
163
236
  children: [
164
- /*#__PURE__*/ jsx(Box, {
165
- "data-testid": "preview-iframe",
166
- ref: iframeRef,
167
- src: previewUrl,
168
- title: formatMessage({
169
- id: 'content-manager.preview.panel.title',
170
- defaultMessage: 'Preview'
171
- }),
172
- width: "100%",
173
- height: "100%",
174
- borderWidth: 0,
175
- tag: "iframe"
176
- }, previewUrl),
177
- hasAdvancedPreview && /*#__PURE__*/ jsx(IconButton, {
178
- variant: "tertiary",
179
- label: formatMessage(isSideEditorOpen ? {
180
- id: 'content-manager.preview.content.close-editor',
181
- defaultMessage: 'Close editor'
182
- } : {
183
- id: 'content-manager.preview.content.open-editor',
184
- defaultMessage: 'Open editor'
185
- }),
186
- onClick: ()=>setIsSideEditorOpen((prev)=>!prev),
187
- position: "absolute",
188
- top: 2,
189
- left: 2,
190
- children: /*#__PURE__*/ jsx(AnimatedArrow, {
191
- isSideEditorOpen: isSideEditorOpen
192
- })
237
+ /*#__PURE__*/ jsxs(Flex, {
238
+ direction: "row",
239
+ background: "neutral0",
240
+ padding: 2,
241
+ borderWidth: "0 0 1px 0",
242
+ borderColor: "neutral150",
243
+ children: [
244
+ hasAdvancedPreview && /*#__PURE__*/ jsx(IconButton, {
245
+ variant: "ghost",
246
+ label: formatMessage(isSideEditorOpen ? {
247
+ id: 'content-manager.preview.content.close-editor',
248
+ defaultMessage: 'Close editor'
249
+ } : {
250
+ id: 'content-manager.preview.content.open-editor',
251
+ defaultMessage: 'Open editor'
252
+ }),
253
+ onClick: ()=>setIsSideEditorOpen((prev)=>!prev),
254
+ children: /*#__PURE__*/ jsx(AnimatedArrow, {
255
+ $isSideEditorOpen: isSideEditorOpen
256
+ })
257
+ }),
258
+ /*#__PURE__*/ jsx(Flex, {
259
+ justifyContent: "center",
260
+ flex: 1,
261
+ children: /*#__PURE__*/ jsx(SingleSelect, {
262
+ value: deviceName,
263
+ onChange: (name)=>setDeviceName(name.toString()),
264
+ "aria-label": formatMessage({
265
+ id: 'content-manager.preview.device.select',
266
+ defaultMessage: 'Select device type'
267
+ }),
268
+ children: DEVICES.map((deviceOption)=>/*#__PURE__*/ jsx(SingleSelectOption, {
269
+ value: deviceOption.name,
270
+ children: formatMessage(deviceOption.label)
271
+ }, deviceOption.name))
272
+ })
273
+ })
274
+ ]
275
+ }),
276
+ /*#__PURE__*/ jsx(Flex, {
277
+ direction: "column",
278
+ justifyContent: "center",
279
+ background: "neutral0",
280
+ flex: 1,
281
+ children: /*#__PURE__*/ jsx(Box, {
282
+ "data-testid": "preview-iframe",
283
+ ref: iframeRef,
284
+ src: previewUrl,
285
+ title: formatMessage({
286
+ id: 'content-manager.preview.panel.title',
287
+ defaultMessage: 'Preview'
288
+ }),
289
+ width: device.width,
290
+ height: device.height,
291
+ borderWidth: 0,
292
+ tag: "iframe"
293
+ }, previewUrl)
193
294
  })
194
295
  ]
195
296
  })
@@ -1 +1 @@
1
- {"version":3,"file":"Preview.mjs","sources":["../../../../admin/src/preview/pages/Preview.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Page,\n useQueryParams,\n useRBAC,\n createContext,\n Form as FormContext,\n Blocker,\n} from '@strapi/admin/strapi-admin';\nimport { Box, Flex, FocusTrap, IconButton, Portal } from '@strapi/design-system';\nimport { ArrowLineLeft } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { useLocation, useParams } from 'react-router-dom';\nimport { styled } from 'styled-components';\n\nimport { GetPreviewUrl } from '../../../../shared/contracts/preview';\nimport { COLLECTION_TYPES } from '../../constants/collections';\nimport { DocumentRBAC } from '../../features/DocumentRBAC';\nimport { type UseDocument, useDocument } from '../../hooks/useDocument';\nimport { type EditLayout, useDocumentLayout } from '../../hooks/useDocumentLayout';\nimport { FormLayout } from '../../pages/EditView/components/FormLayout';\nimport { buildValidParams } from '../../utils/api';\nimport { createYupSchema } from '../../utils/validation';\nimport { PreviewHeader } from '../components/PreviewHeader';\nimport { useGetPreviewUrlQuery } from '../services/preview';\n\nimport type { UID } from '@strapi/types';\n\n/* -------------------------------------------------------------------------------------------------\n * PreviewProvider\n * -----------------------------------------------------------------------------------------------*/\n\ninterface PreviewContextValue {\n url: string;\n title: string;\n document: NonNullable<ReturnType<UseDocument>['document']>;\n meta: NonNullable<ReturnType<UseDocument>['meta']>;\n schema: NonNullable<ReturnType<UseDocument>['schema']>;\n layout: EditLayout;\n onPreview: () => void;\n}\n\nconst [PreviewProvider, usePreviewContext] = createContext<PreviewContextValue>('PreviewPage');\n\n/* -------------------------------------------------------------------------------------------------\n * PreviewPage\n * -----------------------------------------------------------------------------------------------*/\n\nconst AnimatedArrow = styled(ArrowLineLeft)<{ isSideEditorOpen: boolean }>`\n will-change: transform;\n rotate: ${(props) => (props.isSideEditorOpen ? '0deg' : '180deg')};\n transition: rotate 0.2s ease-in-out;\n`;\n\nconst PreviewPage = () => {\n const location = useLocation();\n const { formatMessage } = useIntl();\n\n const iframeRef = React.useRef<HTMLIFrameElement>(null);\n const [isSideEditorOpen, setIsSideEditorOpen] = React.useState(true);\n\n // Read all the necessary data from the URL to find the right preview URL\n const {\n slug: model,\n id: documentId,\n collectionType,\n } = useParams<{\n slug: UID.ContentType;\n id: string;\n collectionType: string;\n }>();\n const [{ query }] = useQueryParams<{\n plugins?: Record<string, unknown>;\n status?: string;\n }>();\n\n const params = React.useMemo(() => buildValidParams(query), [query]);\n\n if (!collectionType) {\n throw new Error('Could not find collectionType in url params');\n }\n\n if (!model) {\n throw new Error('Could not find model in url params');\n }\n\n // Only collection types must have a documentId\n if (collectionType === COLLECTION_TYPES && !documentId) {\n throw new Error('Could not find documentId in url params');\n }\n\n const previewUrlResponse = useGetPreviewUrlQuery({\n params: {\n contentType: model,\n },\n query: {\n documentId,\n locale: params.locale,\n status: params.status as GetPreviewUrl.Request['query']['status'],\n },\n });\n const documentResponse = useDocument({\n model,\n collectionType,\n documentId,\n params,\n });\n const documentLayoutResponse = useDocumentLayout(model);\n\n const isLoading =\n previewUrlResponse.isLoading || documentLayoutResponse.isLoading || documentResponse.isLoading;\n if (isLoading && !documentResponse.document?.documentId) {\n return <Page.Loading />;\n }\n\n const initialValues = documentResponse.getInitialFormValues();\n\n if (\n previewUrlResponse.error ||\n documentLayoutResponse.error ||\n !documentResponse.document ||\n !documentResponse.meta ||\n !documentResponse.schema ||\n !initialValues\n ) {\n return <Page.Error />;\n }\n\n if (!previewUrlResponse.data?.data?.url) {\n return <Page.NoData />;\n }\n\n const documentTitle = documentResponse.getTitle(documentLayoutResponse.edit.settings.mainField);\n\n const validateSync = (values: Record<string, unknown>, options: Record<string, string>) => {\n const yupSchema = createYupSchema(\n documentResponse.schema?.attributes,\n documentResponse.components,\n {\n status: documentResponse.document?.status,\n ...options,\n }\n );\n\n return yupSchema.validateSync(values, { abortEarly: false });\n };\n\n const previewUrl = previewUrlResponse.data.data.url;\n\n const onPreview = () => {\n iframeRef?.current?.contentWindow?.postMessage(\n { type: 'strapiUpdate' },\n // The iframe origin is safe to use since it must be provided through the allowedOrigins config\n new URL(iframeRef.current.src).origin\n );\n };\n\n const hasAdvancedPreview = window.strapi.features.isEnabled('cms-advanced-preview');\n\n return (\n <>\n <Page.Title>\n {formatMessage(\n {\n id: 'content-manager.preview.page-title',\n defaultMessage: '{contentType} preview',\n },\n {\n contentType: documentTitle,\n }\n )}\n </Page.Title>\n <PreviewProvider\n url={previewUrl}\n document={documentResponse.document}\n title={documentTitle}\n meta={documentResponse.meta}\n schema={documentResponse.schema}\n layout={documentLayoutResponse.edit}\n onPreview={onPreview}\n >\n <FormContext\n method=\"PUT\"\n disabled={\n query.status === 'published' &&\n documentResponse &&\n documentResponse.document.status !== 'draft'\n }\n initialValues={documentResponse.getInitialFormValues()}\n initialErrors={location?.state?.forceValidation ? validateSync(initialValues, {}) : {}}\n height=\"100%\"\n validate={(values: Record<string, unknown>, options: Record<string, string>) => {\n const yupSchema = createYupSchema(\n documentResponse.schema?.attributes,\n documentResponse.components,\n {\n status: documentResponse.document?.status,\n ...options,\n }\n );\n\n return yupSchema.validate(values, { abortEarly: false });\n }}\n >\n {({ resetForm }) => (\n <Flex direction=\"column\" height=\"100%\" alignItems=\"stretch\">\n <Blocker onProceed={resetForm} />\n <PreviewHeader />\n <Flex flex={1} overflow=\"auto\" alignItems=\"stretch\">\n {hasAdvancedPreview && (\n <Box\n overflow=\"auto\"\n width={isSideEditorOpen ? '50%' : 0}\n borderWidth=\"0 1px 0 0\"\n borderColor=\"neutral150\"\n paddingTop={6}\n paddingBottom={6}\n // Remove horizontal padding when the editor is closed or it won't fully disappear\n paddingLeft={isSideEditorOpen ? 6 : 0}\n paddingRight={isSideEditorOpen ? 6 : 0}\n transition=\"all 0.2s ease-in-out\"\n >\n <FormLayout\n layout={documentLayoutResponse.edit.layout}\n document={documentResponse}\n hasBackground={false}\n />\n </Box>\n )}\n\n <Box position=\"relative\" flex={1} height=\"100%\" overflow=\"hidden\">\n <Box\n data-testid=\"preview-iframe\"\n ref={iframeRef}\n src={previewUrl}\n /**\n * For some reason, changing an iframe's src tag causes the browser to add a new item in the\n * history stack. This is an issue for us as it means clicking the back button will not let us\n * go back to the edit view. To fix it, we need to trick the browser into thinking this is a\n * different iframe when the preview URL changes. So we set a key prop to force React\n * to mount a different node when the src changes.\n */\n key={previewUrl}\n title={formatMessage({\n id: 'content-manager.preview.panel.title',\n defaultMessage: 'Preview',\n })}\n width=\"100%\"\n height=\"100%\"\n borderWidth={0}\n tag=\"iframe\"\n />\n {hasAdvancedPreview && (\n <IconButton\n variant=\"tertiary\"\n label={formatMessage(\n isSideEditorOpen\n ? {\n id: 'content-manager.preview.content.close-editor',\n defaultMessage: 'Close editor',\n }\n : {\n id: 'content-manager.preview.content.open-editor',\n defaultMessage: 'Open editor',\n }\n )}\n onClick={() => setIsSideEditorOpen((prev) => !prev)}\n position=\"absolute\"\n top={2}\n left={2}\n >\n <AnimatedArrow isSideEditorOpen={isSideEditorOpen} />\n </IconButton>\n )}\n </Box>\n </Flex>\n </Flex>\n )}\n </FormContext>\n </PreviewProvider>\n </>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ProtectedPreviewPage\n * -----------------------------------------------------------------------------------------------*/\n\nconst ProtectedPreviewPageImpl = () => {\n const { slug: model } = useParams<{\n slug: string;\n }>();\n const {\n permissions = [],\n isLoading,\n error,\n } = useRBAC([\n { action: 'plugin::content-manager.explorer.read', subject: model },\n { action: 'plugin::content-manager.explorer.update', subject: model },\n { action: 'plugin::content-manager.explorer.publish', subject: model },\n ]);\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n if (error || !model) {\n return (\n <Box\n height=\"100vh\"\n width=\"100vw\"\n position=\"fixed\"\n top={0}\n left={0}\n zIndex={2}\n background=\"neutral0\"\n >\n <Page.Error />\n </Box>\n );\n }\n\n return (\n <Box\n height=\"100vh\"\n width=\"100vw\"\n position=\"fixed\"\n top={0}\n left={0}\n zIndex={2}\n background=\"neutral0\"\n >\n <Page.Protect\n permissions={permissions.filter((permission) =>\n permission.action.includes('explorer.read')\n )}\n >\n <DocumentRBAC permissions={permissions}>\n <PreviewPage />\n </DocumentRBAC>\n </Page.Protect>\n </Box>\n );\n};\n\nconst ProtectedPreviewPage = () => {\n return (\n <Portal>\n <FocusTrap>\n <ProtectedPreviewPageImpl />\n </FocusTrap>\n </Portal>\n );\n};\n\nexport { ProtectedPreviewPage, usePreviewContext };\n"],"names":["PreviewProvider","usePreviewContext","createContext","AnimatedArrow","styled","ArrowLineLeft","props","isSideEditorOpen","PreviewPage","location","useLocation","formatMessage","useIntl","iframeRef","React","useRef","setIsSideEditorOpen","useState","slug","model","id","documentId","collectionType","useParams","query","useQueryParams","params","useMemo","buildValidParams","Error","COLLECTION_TYPES","previewUrlResponse","useGetPreviewUrlQuery","contentType","locale","status","documentResponse","useDocument","documentLayoutResponse","useDocumentLayout","isLoading","document","_jsx","Page","Loading","initialValues","getInitialFormValues","error","meta","schema","data","url","NoData","documentTitle","getTitle","edit","settings","mainField","validateSync","values","options","yupSchema","createYupSchema","attributes","components","abortEarly","previewUrl","onPreview","current","contentWindow","postMessage","type","URL","src","origin","hasAdvancedPreview","window","strapi","features","isEnabled","_jsxs","_Fragment","Title","defaultMessage","title","layout","FormContext","method","disabled","initialErrors","state","forceValidation","height","validate","resetForm","Flex","direction","alignItems","Blocker","onProceed","PreviewHeader","flex","overflow","Box","width","borderWidth","borderColor","paddingTop","paddingBottom","paddingLeft","paddingRight","transition","FormLayout","hasBackground","position","data-testid","ref","tag","IconButton","variant","label","onClick","prev","top","left","ProtectedPreviewPageImpl","permissions","useRBAC","action","subject","zIndex","background","Protect","filter","permission","includes","DocumentRBAC","ProtectedPreviewPage","Portal","FocusTrap"],"mappings":"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"}
1
+ {"version":3,"file":"Preview.mjs","sources":["../../../../admin/src/preview/pages/Preview.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Page,\n useQueryParams,\n useRBAC,\n createContext,\n Form as FormContext,\n Blocker,\n} from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Flex,\n FocusTrap,\n IconButton,\n Portal,\n SingleSelect,\n SingleSelectOption,\n} from '@strapi/design-system';\nimport { ArrowLineLeft } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { useLocation, useParams } from 'react-router-dom';\nimport { styled } from 'styled-components';\n\nimport { GetPreviewUrl } from '../../../../shared/contracts/preview';\nimport { COLLECTION_TYPES } from '../../constants/collections';\nimport { DocumentRBAC } from '../../features/DocumentRBAC';\nimport { type UseDocument, useDocument } from '../../hooks/useDocument';\nimport { type EditLayout, useDocumentLayout } from '../../hooks/useDocumentLayout';\nimport { FormLayout } from '../../pages/EditView/components/FormLayout';\nimport { handleInvisibleAttributes } from '../../pages/EditView/utils/data';\nimport { buildValidParams } from '../../utils/api';\nimport { createYupSchema } from '../../utils/validation';\nimport { PreviewHeader } from '../components/PreviewHeader';\nimport { useGetPreviewUrlQuery } from '../services/preview';\nimport { INTERNAL_EVENTS, PUBLIC_EVENTS } from '../utils/constants';\nimport { previewScript } from '../utils/previewScript';\n\nimport type { UID } from '@strapi/types';\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * -----------------------------------------------------------------------------------------------*/\n\nconst DEVICES = [\n {\n name: 'desktop',\n label: {\n id: 'content-manager.preview.device.desktop',\n defaultMessage: 'Desktop',\n },\n width: '100%',\n height: '100%',\n },\n {\n name: 'mobile',\n label: {\n id: 'content-manager.preview.device.mobile',\n defaultMessage: 'Mobile',\n },\n width: '375px',\n height: '667px',\n },\n];\n\n/* -------------------------------------------------------------------------------------------------\n * PreviewProvider\n * -----------------------------------------------------------------------------------------------*/\n\ninterface PreviewContextValue {\n url: string;\n title: string;\n document: NonNullable<ReturnType<UseDocument>['document']>;\n meta: NonNullable<ReturnType<UseDocument>['meta']>;\n schema: NonNullable<ReturnType<UseDocument>['schema']>;\n layout: EditLayout;\n onPreview: () => void;\n}\n\nconst [PreviewProvider, usePreviewContext] = createContext<PreviewContextValue>('PreviewPage');\n\n/* -------------------------------------------------------------------------------------------------\n * PreviewPage\n * -----------------------------------------------------------------------------------------------*/\n\nconst AnimatedArrow = styled(ArrowLineLeft)<{ $isSideEditorOpen: boolean }>`\n will-change: transform;\n rotate: ${(props) => (props.$isSideEditorOpen ? '0deg' : '180deg')};\n transition: rotate 0.2s ease-in-out;\n`;\n\ntype MessageType =\n | (typeof INTERNAL_EVENTS)[keyof typeof INTERNAL_EVENTS]\n | (typeof PUBLIC_EVENTS)[keyof typeof PUBLIC_EVENTS];\n\n/**\n * A function factory so we can generate a new sendMessage everytime we need one.\n * We can't store and reuse a single sendMessage because it needs to have a stable identity\n * as it used in a useEffect function. And we can't rely on useCallback because we need the\n * up-to-date iframe ref, and this would make it stale (refs don't trigger callback reevaluations).\n */\nfunction getSendMessage(iframe: React.RefObject<HTMLIFrameElement>) {\n return (type: MessageType, payload?: unknown) => {\n if (!iframe.current) return;\n\n const { origin } = new URL(iframe.current.src);\n\n iframe.current.contentWindow?.postMessage(\n {\n type,\n ...(payload !== undefined && { payload }),\n },\n origin\n );\n };\n}\n\nconst PreviewPage = () => {\n const location = useLocation();\n const { formatMessage } = useIntl();\n\n const iframeRef = React.useRef<HTMLIFrameElement>(null);\n const [isSideEditorOpen, setIsSideEditorOpen] = React.useState(true);\n\n // Read all the necessary data from the URL to find the right preview URL\n const {\n slug: model,\n id: documentId,\n collectionType,\n } = useParams<{\n slug: UID.ContentType;\n id: string;\n collectionType: string;\n }>();\n const [{ query }] = useQueryParams<{\n plugins?: Record<string, unknown>;\n status?: string;\n }>();\n\n const params = React.useMemo(() => buildValidParams(query), [query]);\n\n const [deviceName, setDeviceName] = React.useState<(typeof DEVICES)[number]['name']>(\n DEVICES[0].name\n );\n const device = DEVICES.find((d) => d.name === deviceName) ?? DEVICES[0];\n\n // Listen for ready message from iframe before injecting script\n React.useEffect(() => {\n const handleMessage = (event: MessageEvent) => {\n if (event.data?.type === PUBLIC_EVENTS.PREVIEW_READY) {\n const script = `(${previewScript.toString()})()`;\n const sendMessage = getSendMessage(iframeRef);\n sendMessage(PUBLIC_EVENTS.STRAPI_SCRIPT, { script });\n }\n };\n\n window.addEventListener('message', handleMessage);\n\n return () => {\n window.removeEventListener('message', handleMessage);\n };\n }, []);\n\n if (!collectionType) {\n throw new Error('Could not find collectionType in url params');\n }\n\n if (!model) {\n throw new Error('Could not find model in url params');\n }\n\n // Only collection types must have a documentId\n if (collectionType === COLLECTION_TYPES && !documentId) {\n throw new Error('Could not find documentId in url params');\n }\n\n const previewUrlResponse = useGetPreviewUrlQuery({\n params: {\n contentType: model,\n },\n query: {\n documentId,\n locale: params.locale,\n status: params.status as GetPreviewUrl.Request['query']['status'],\n },\n });\n const documentResponse = useDocument({\n model,\n collectionType,\n documentId,\n params,\n });\n const documentLayoutResponse = useDocumentLayout(model);\n\n const isLoading =\n previewUrlResponse.isLoading || documentLayoutResponse.isLoading || documentResponse.isLoading;\n if (isLoading && (!documentResponse.document?.documentId || previewUrlResponse.isLoading)) {\n return <Page.Loading />;\n }\n\n const initialValues = documentResponse.getInitialFormValues();\n\n if (\n previewUrlResponse.error ||\n documentLayoutResponse.error ||\n !documentResponse.document ||\n !documentResponse.meta ||\n !documentResponse.schema ||\n !initialValues\n ) {\n return <Page.Error />;\n }\n\n if (!previewUrlResponse.data?.data?.url) {\n return <Page.NoData />;\n }\n\n const documentTitle = documentResponse.getTitle(documentLayoutResponse.edit.settings.mainField);\n\n const validateSync = (values: Record<string, unknown>, options: Record<string, string>) => {\n const { data: cleanedValues, removedAttributes } = handleInvisibleAttributes(values, {\n schema: documentResponse.schema,\n initialValues,\n components: documentResponse.components,\n });\n\n const yupSchema = createYupSchema(\n documentResponse.schema?.attributes,\n documentResponse.components,\n {\n status: documentResponse.document?.status,\n removedAttributes,\n ...options,\n }\n );\n\n return yupSchema.validateSync(cleanedValues, { abortEarly: false });\n };\n\n const previewUrl = previewUrlResponse.data.data.url;\n\n const onPreview = () => {\n iframeRef?.current?.contentWindow?.postMessage(\n { type: 'strapiUpdate' },\n // The iframe origin is safe to use since it must be provided through the allowedOrigins config\n new URL(iframeRef.current.src).origin\n );\n };\n\n const hasAdvancedPreview = window.strapi.features.isEnabled('cms-advanced-preview');\n\n return (\n <>\n <Page.Title>\n {formatMessage(\n {\n id: 'content-manager.preview.page-title',\n defaultMessage: '{contentType} preview',\n },\n {\n contentType: documentTitle,\n }\n )}\n </Page.Title>\n <PreviewProvider\n url={previewUrl}\n document={documentResponse.document}\n title={documentTitle}\n meta={documentResponse.meta}\n schema={documentResponse.schema}\n layout={documentLayoutResponse.edit}\n onPreview={onPreview}\n >\n <FormContext\n method=\"PUT\"\n disabled={\n query.status === 'published' &&\n documentResponse &&\n documentResponse.document.status !== 'draft'\n }\n initialValues={documentResponse.getInitialFormValues()}\n initialErrors={location?.state?.forceValidation ? validateSync(initialValues, {}) : {}}\n height=\"100%\"\n validate={(values: Record<string, unknown>, options: Record<string, string>) => {\n const { data: cleanedValues, removedAttributes } = handleInvisibleAttributes(values, {\n schema: documentResponse.schema,\n initialValues,\n components: documentResponse.components,\n });\n\n const yupSchema = createYupSchema(\n documentResponse.schema?.attributes,\n documentResponse.components,\n {\n status: documentResponse.document?.status,\n removedAttributes,\n ...options,\n }\n );\n\n return yupSchema.validate(cleanedValues, { abortEarly: false });\n }}\n >\n {({ resetForm }) => (\n <Flex direction=\"column\" height=\"100%\" alignItems=\"stretch\">\n <Blocker onProceed={resetForm} />\n <PreviewHeader />\n <Flex flex={1} overflow=\"auto\" alignItems=\"stretch\">\n {hasAdvancedPreview && (\n <Box\n overflow=\"auto\"\n width={isSideEditorOpen ? '50%' : 0}\n borderWidth=\"0 1px 0 0\"\n borderColor=\"neutral150\"\n paddingTop={6}\n paddingBottom={6}\n // Remove horizontal padding when the editor is closed or it won't fully disappear\n paddingLeft={isSideEditorOpen ? 6 : 0}\n paddingRight={isSideEditorOpen ? 6 : 0}\n transition=\"all 0.2s ease-in-out\"\n >\n <FormLayout\n layout={documentLayoutResponse.edit.layout}\n document={documentResponse}\n hasBackground={false}\n />\n </Box>\n )}\n <Flex\n direction=\"column\"\n alignItems=\"stretch\"\n flex={1}\n height=\"100%\"\n overflow=\"hidden\"\n >\n <Flex\n direction=\"row\"\n background=\"neutral0\"\n padding={2}\n borderWidth=\"0 0 1px 0\"\n borderColor=\"neutral150\"\n >\n {hasAdvancedPreview && (\n <IconButton\n variant=\"ghost\"\n label={formatMessage(\n isSideEditorOpen\n ? {\n id: 'content-manager.preview.content.close-editor',\n defaultMessage: 'Close editor',\n }\n : {\n id: 'content-manager.preview.content.open-editor',\n defaultMessage: 'Open editor',\n }\n )}\n onClick={() => setIsSideEditorOpen((prev) => !prev)}\n >\n <AnimatedArrow $isSideEditorOpen={isSideEditorOpen} />\n </IconButton>\n )}\n <Flex justifyContent=\"center\" flex={1}>\n <SingleSelect\n value={deviceName}\n onChange={(name) => setDeviceName(name.toString())}\n aria-label={formatMessage({\n id: 'content-manager.preview.device.select',\n defaultMessage: 'Select device type',\n })}\n >\n {DEVICES.map((deviceOption) => (\n <SingleSelectOption key={deviceOption.name} value={deviceOption.name}>\n {formatMessage(deviceOption.label)}\n </SingleSelectOption>\n ))}\n </SingleSelect>\n </Flex>\n </Flex>\n <Flex direction=\"column\" justifyContent=\"center\" background=\"neutral0\" flex={1}>\n <Box\n data-testid=\"preview-iframe\"\n ref={iframeRef}\n src={previewUrl}\n /**\n * For some reason, changing an iframe's src tag causes the browser to add a new item in the\n * history stack. This is an issue for us as it means clicking the back button will not let us\n * go back to the edit view. To fix it, we need to trick the browser into thinking this is a\n * different iframe when the preview URL changes. So we set a key prop to force React\n * to mount a different node when the src changes.\n */\n key={previewUrl}\n title={formatMessage({\n id: 'content-manager.preview.panel.title',\n defaultMessage: 'Preview',\n })}\n width={device.width}\n height={device.height}\n borderWidth={0}\n tag=\"iframe\"\n />\n </Flex>\n </Flex>\n </Flex>\n </Flex>\n )}\n </FormContext>\n </PreviewProvider>\n </>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ProtectedPreviewPage\n * -----------------------------------------------------------------------------------------------*/\n\nconst ProtectedPreviewPageImpl = () => {\n const { slug: model } = useParams<{\n slug: string;\n }>();\n const {\n permissions = [],\n isLoading,\n error,\n } = useRBAC([\n { action: 'plugin::content-manager.explorer.read', subject: model },\n { action: 'plugin::content-manager.explorer.update', subject: model },\n { action: 'plugin::content-manager.explorer.publish', subject: model },\n ]);\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n if (error || !model) {\n return (\n <Box\n height=\"100vh\"\n width=\"100vw\"\n position=\"fixed\"\n top={0}\n left={0}\n zIndex={2}\n background=\"neutral0\"\n >\n <Page.Error />\n </Box>\n );\n }\n\n return (\n <Box\n height=\"100vh\"\n width=\"100vw\"\n position=\"fixed\"\n top={0}\n left={0}\n zIndex={2}\n background=\"neutral0\"\n >\n <Page.Protect\n permissions={permissions.filter((permission) =>\n permission.action.includes('explorer.read')\n )}\n >\n <DocumentRBAC permissions={permissions}>\n <PreviewPage />\n </DocumentRBAC>\n </Page.Protect>\n </Box>\n );\n};\n\nconst ProtectedPreviewPage = () => {\n return (\n <Portal>\n <FocusTrap>\n <ProtectedPreviewPageImpl />\n </FocusTrap>\n </Portal>\n );\n};\n\nexport { ProtectedPreviewPage, usePreviewContext };\n"],"names":["DEVICES","name","label","id","defaultMessage","width","height","PreviewProvider","usePreviewContext","createContext","AnimatedArrow","styled","ArrowLineLeft","props","$isSideEditorOpen","getSendMessage","iframe","type","payload","current","origin","URL","src","contentWindow","postMessage","undefined","PreviewPage","location","useLocation","formatMessage","useIntl","iframeRef","React","useRef","isSideEditorOpen","setIsSideEditorOpen","useState","slug","model","documentId","collectionType","useParams","query","useQueryParams","params","useMemo","buildValidParams","deviceName","setDeviceName","device","find","d","useEffect","handleMessage","event","data","PUBLIC_EVENTS","PREVIEW_READY","script","previewScript","toString","sendMessage","STRAPI_SCRIPT","window","addEventListener","removeEventListener","Error","COLLECTION_TYPES","previewUrlResponse","useGetPreviewUrlQuery","contentType","locale","status","documentResponse","useDocument","documentLayoutResponse","useDocumentLayout","isLoading","document","_jsx","Page","Loading","initialValues","getInitialFormValues","error","meta","schema","url","NoData","documentTitle","getTitle","edit","settings","mainField","validateSync","values","options","cleanedValues","removedAttributes","handleInvisibleAttributes","components","yupSchema","createYupSchema","attributes","abortEarly","previewUrl","onPreview","hasAdvancedPreview","strapi","features","isEnabled","_jsxs","_Fragment","Title","title","layout","FormContext","method","disabled","initialErrors","state","forceValidation","validate","resetForm","Flex","direction","alignItems","Blocker","onProceed","PreviewHeader","flex","overflow","Box","borderWidth","borderColor","paddingTop","paddingBottom","paddingLeft","paddingRight","transition","FormLayout","hasBackground","background","padding","IconButton","variant","onClick","prev","justifyContent","SingleSelect","value","onChange","aria-label","map","deviceOption","SingleSelectOption","data-testid","ref","tag","ProtectedPreviewPageImpl","permissions","useRBAC","action","subject","position","top","left","zIndex","Protect","filter","permission","includes","DocumentRBAC","ProtectedPreviewPage","Portal","FocusTrap"],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ 'use strict';
2
+
3
+ var previewScript = require('./previewScript.js');
4
+
5
+ const scriptResponse = previewScript.previewScript(false);
6
+ /**
7
+ * These events can be changed safely. They're used by the content manager admin on one side, and by
8
+ * the preview script on the other. We own both ends, and they're not documented to users, so we can
9
+ * do what we want with them.
10
+ */ scriptResponse.INTERNAL_EVENTS;
11
+ /**
12
+ * These events are documented to users, and will be hardcoded in their frontends.
13
+ * Changing any of these would be a breaking change.
14
+ */ const PUBLIC_EVENTS = {
15
+ PREVIEW_READY: 'previewReady',
16
+ STRAPI_UPDATE: 'strapiUpdate',
17
+ STRAPI_SCRIPT: 'strapiScript'
18
+ };
19
+
20
+ exports.PUBLIC_EVENTS = PUBLIC_EVENTS;
21
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +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,IAC8BD,cAAAA,CAAgBE;AAE/C;;;UAIaC,aAAgB,GAAA;IAC3BC,aAAe,EAAA,cAAA;IACfC,aAAe,EAAA,cAAA;IACfC,aAAe,EAAA;AACjB;;;;"}
@@ -0,0 +1,19 @@
1
+ import { previewScript } from './previewScript.mjs';
2
+
3
+ const scriptResponse = previewScript(false);
4
+ /**
5
+ * These events can be changed safely. They're used by the content manager admin on one side, and by
6
+ * the preview script on the other. We own both ends, and they're not documented to users, so we can
7
+ * do what we want with them.
8
+ */ scriptResponse.INTERNAL_EVENTS;
9
+ /**
10
+ * These events are documented to users, and will be hardcoded in their frontends.
11
+ * Changing any of these would be a breaking change.
12
+ */ const PUBLIC_EVENTS = {
13
+ PREVIEW_READY: 'previewReady',
14
+ STRAPI_UPDATE: 'strapiUpdate',
15
+ STRAPI_SCRIPT: 'strapiScript'
16
+ };
17
+
18
+ export { PUBLIC_EVENTS };
19
+ //# sourceMappingURL=constants.mjs.map
@@ -0,0 +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,IAC8BD,cAAAA,CAAgBE;AAE/C;;;UAIaC,aAAgB,GAAA;IAC3BC,aAAe,EAAA,cAAA;IACfC,aAAe,EAAA,cAAA;IACfC,aAAe,EAAA;AACjB;;;;"}
@@ -0,0 +1,203 @@
1
+ 'use strict';
2
+
3
+ // NOTE: This override is for the properties on _user's site_, it's not about Strapi Admin.
4
+ /**
5
+ * previewScript will be injected into the preview iframe after being stringified.
6
+ * Therefore it CANNOT use any imports, or refer to any variables outside of its own scope.
7
+ * It's why many functions are defined within previewScript, it's the only way to avoid going full spaghetti.
8
+ * To get a better overview of everything previewScript does, go to the orchestration part at its end.
9
+ */ const previewScript = (shouldRun = true)=>{
10
+ /* -----------------------------------------------------------------------------------------------
11
+ * Params
12
+ * ---------------------------------------------------------------------------------------------*/ const HIGHLIGHT_PADDING = 2; // in pixels
13
+ const HIGHLIGHT_HOVER_COLOR = window.STRAPI_HIGHLIGHT_HOVER_COLOR ?? '#4945ff'; // dark primary500
14
+ const SOURCE_ATTRIBUTE = 'data-strapi-source';
15
+ const OVERLAY_ID = 'strapi-preview-overlay';
16
+ const INTERNAL_EVENTS = {
17
+ DUMMY_EVENT: 'dummyEvent'
18
+ };
19
+ /**
20
+ * Calling the function in no-run mode lets us retrieve the constants from other files and keep
21
+ * a single source of truth for them. It's the only way to do this because this script can't
22
+ * refer to any variables outside of its own scope, because it's stringified before it's run.
23
+ */ if (!shouldRun) {
24
+ return {
25
+ INTERNAL_EVENTS
26
+ };
27
+ }
28
+ /* -----------------------------------------------------------------------------------------------
29
+ * Functionality pieces
30
+ * ---------------------------------------------------------------------------------------------*/ const createOverlaySystem = ()=>{
31
+ // Clean up before creating a new overlay so we can safely call previewScript multiple times
32
+ window.__strapi_previewCleanup?.();
33
+ document.getElementById(OVERLAY_ID)?.remove();
34
+ const overlay = document.createElement('div');
35
+ overlay.id = OVERLAY_ID;
36
+ overlay.style.cssText = `
37
+ position: fixed;
38
+ top: 0;
39
+ left: 0;
40
+ width: 100%;
41
+ height: 100%;
42
+ pointer-events: none;
43
+ z-index: 9999;
44
+ `;
45
+ window.document.body.appendChild(overlay);
46
+ return overlay;
47
+ };
48
+ const createHighlightManager = (overlay)=>{
49
+ const elements = window.document.querySelectorAll(`[${SOURCE_ATTRIBUTE}]`);
50
+ const highlights = [];
51
+ const eventListeners = [];
52
+ const drawHighlight = (target, highlight)=>{
53
+ if (!highlight) return;
54
+ const rect = target.getBoundingClientRect();
55
+ highlight.style.width = `${rect.width + HIGHLIGHT_PADDING * 2}px`;
56
+ highlight.style.height = `${rect.height + HIGHLIGHT_PADDING * 2}px`;
57
+ highlight.style.transform = `translate(${rect.left - HIGHLIGHT_PADDING}px, ${rect.top - HIGHLIGHT_PADDING}px)`;
58
+ };
59
+ const updateAllHighlights = ()=>{
60
+ highlights.forEach((highlight, index)=>{
61
+ const element = elements[index];
62
+ if (element && highlight) {
63
+ drawHighlight(element, highlight);
64
+ }
65
+ });
66
+ };
67
+ elements.forEach((element)=>{
68
+ if (element instanceof HTMLElement) {
69
+ const highlight = document.createElement('div');
70
+ highlight.style.cssText = `
71
+ position: absolute;
72
+ outline: 2px solid transparent;
73
+ pointer-events: none;
74
+ border-radius: 2px;
75
+ background-color: transparent;
76
+ will-change: transform;
77
+ transition: outline-color 0.1s ease-in-out;
78
+ `;
79
+ // Move hover detection to the underlying element
80
+ const mouseEnterHandler = ()=>{
81
+ highlight.style.outlineColor = HIGHLIGHT_HOVER_COLOR;
82
+ };
83
+ const mouseLeaveHandler = ()=>{
84
+ highlight.style.outlineColor = 'transparent';
85
+ };
86
+ const doubleClickHandler = ()=>{
87
+ // TODO: handle for real
88
+ // eslint-disable-next-line no-console
89
+ console.log('Double click on highlight', element);
90
+ };
91
+ const mouseDownHandler = (event)=>{
92
+ // Prevent default multi click to select behavior
93
+ if (event.detail >= 2) {
94
+ event.preventDefault();
95
+ }
96
+ };
97
+ element.addEventListener('mouseenter', mouseEnterHandler);
98
+ element.addEventListener('mouseleave', mouseLeaveHandler);
99
+ element.addEventListener('dblclick', doubleClickHandler);
100
+ element.addEventListener('mousedown', mouseDownHandler);
101
+ // Store event listeners for cleanup
102
+ eventListeners.push({
103
+ element,
104
+ type: 'mouseenter',
105
+ handler: mouseEnterHandler
106
+ }, {
107
+ element,
108
+ type: 'mouseleave',
109
+ handler: mouseLeaveHandler
110
+ }, {
111
+ element,
112
+ type: 'dblclick',
113
+ handler: doubleClickHandler
114
+ }, {
115
+ element,
116
+ type: 'mousedown',
117
+ handler: mouseDownHandler
118
+ });
119
+ highlights.push(highlight);
120
+ overlay.appendChild(highlight);
121
+ drawHighlight(element, highlight);
122
+ }
123
+ });
124
+ return {
125
+ elements,
126
+ updateAllHighlights,
127
+ eventListeners
128
+ };
129
+ };
130
+ const setupObservers = (highlightManager)=>{
131
+ const resizeObserver = new ResizeObserver(()=>{
132
+ highlightManager.updateAllHighlights();
133
+ });
134
+ highlightManager.elements.forEach((element)=>{
135
+ resizeObserver.observe(element);
136
+ });
137
+ resizeObserver.observe(document.documentElement);
138
+ const updateOnScroll = ()=>{
139
+ highlightManager.updateAllHighlights();
140
+ };
141
+ const scrollableElements = new Set();
142
+ scrollableElements.add(window);
143
+ // Find all scrollable ancestors for all tracked elements
144
+ highlightManager.elements.forEach((element)=>{
145
+ let parent = element.parentElement;
146
+ while(parent){
147
+ const computedStyle = window.getComputedStyle(parent);
148
+ const overflow = computedStyle.overflow + computedStyle.overflowX + computedStyle.overflowY;
149
+ if (overflow.includes('scroll') || overflow.includes('auto')) {
150
+ scrollableElements.add(parent);
151
+ }
152
+ parent = parent.parentElement;
153
+ }
154
+ });
155
+ // Add scroll listeners to all scrollable elements
156
+ scrollableElements.forEach((element)=>{
157
+ if (element === window) {
158
+ window.addEventListener('scroll', updateOnScroll);
159
+ window.addEventListener('resize', updateOnScroll);
160
+ } else {
161
+ element.addEventListener('scroll', updateOnScroll);
162
+ }
163
+ });
164
+ return {
165
+ resizeObserver,
166
+ updateOnScroll,
167
+ scrollableElements
168
+ };
169
+ };
170
+ const setupEventHandlers = (highlightManager)=>{
171
+ // TODO: The listeners for postMessage events will go here
172
+ return highlightManager.eventListeners;
173
+ };
174
+ const createCleanupSystem = (overlay, observers, eventHandlers)=>{
175
+ window.__strapi_previewCleanup = ()=>{
176
+ observers.resizeObserver.disconnect();
177
+ // Remove all scroll listeners
178
+ observers.scrollableElements.forEach((element)=>{
179
+ if (element === window) {
180
+ window.removeEventListener('scroll', observers.updateOnScroll);
181
+ window.removeEventListener('resize', observers.updateOnScroll);
182
+ } else {
183
+ element.removeEventListener('scroll', observers.updateOnScroll);
184
+ }
185
+ });
186
+ // Remove highlight event listeners
187
+ eventHandlers.forEach(({ element, type, handler })=>{
188
+ element.removeEventListener(type, handler);
189
+ });
190
+ overlay.remove();
191
+ };
192
+ };
193
+ /* -----------------------------------------------------------------------------------------------
194
+ * Orchestration
195
+ * ---------------------------------------------------------------------------------------------*/ const overlay = createOverlaySystem();
196
+ const highlightManager = createHighlightManager(overlay);
197
+ const observers = setupObservers(highlightManager);
198
+ const eventHandlers = setupEventHandlers(highlightManager);
199
+ createCleanupSystem(overlay, observers, eventHandlers);
200
+ };
201
+
202
+ exports.previewScript = previewScript;
203
+ //# sourceMappingURL=previewScript.js.map