@strapi/content-manager 5.13.0-beta.0 → 5.13.0-beta.1

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 (41) hide show
  1. package/dist/admin/components/LeftMenu.js +34 -30
  2. package/dist/admin/components/LeftMenu.js.map +1 -1
  3. package/dist/admin/components/LeftMenu.mjs +36 -32
  4. package/dist/admin/components/LeftMenu.mjs.map +1 -1
  5. package/dist/admin/hooks/useDocumentActions.js +1 -5
  6. package/dist/admin/hooks/useDocumentActions.js.map +1 -1
  7. package/dist/admin/hooks/useDocumentActions.mjs +1 -5
  8. package/dist/admin/hooks/useDocumentActions.mjs.map +1 -1
  9. package/dist/admin/hooks/useDocumentContext.js.map +1 -1
  10. package/dist/admin/hooks/useDocumentContext.mjs.map +1 -1
  11. package/dist/admin/pages/EditView/components/DocumentActions.js +21 -206
  12. package/dist/admin/pages/EditView/components/DocumentActions.js.map +1 -1
  13. package/dist/admin/pages/EditView/components/DocumentActions.mjs +23 -208
  14. package/dist/admin/pages/EditView/components/DocumentActions.mjs.map +1 -1
  15. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js +137 -199
  16. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js.map +1 -1
  17. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs +137 -199
  18. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs.map +1 -1
  19. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +50 -89
  20. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
  21. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs +52 -91
  22. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs.map +1 -1
  23. package/dist/admin/pages/ListView/ListViewPage.js +77 -0
  24. package/dist/admin/pages/ListView/ListViewPage.js.map +1 -1
  25. package/dist/admin/pages/ListView/ListViewPage.mjs +78 -1
  26. package/dist/admin/pages/ListView/ListViewPage.mjs.map +1 -1
  27. package/dist/admin/src/hooks/useDocumentContext.d.ts +1 -1
  28. package/dist/admin/src/pages/EditView/components/FormInputs/Relations/RelationModal.d.ts +5 -26
  29. package/dist/admin/translations/en.json.js +1 -2
  30. package/dist/admin/translations/en.json.js.map +1 -1
  31. package/dist/admin/translations/en.json.mjs +1 -2
  32. package/dist/admin/translations/en.json.mjs.map +1 -1
  33. package/dist/server/src/index.d.ts +1 -0
  34. package/dist/server/src/index.d.ts.map +1 -1
  35. package/dist/server/src/services/data-mapper.d.ts +1 -0
  36. package/dist/server/src/services/data-mapper.d.ts.map +1 -1
  37. package/dist/server/src/services/homepage.d.ts +11 -0
  38. package/dist/server/src/services/homepage.d.ts.map +1 -0
  39. package/dist/server/src/services/index.d.ts +1 -0
  40. package/dist/server/src/services/index.d.ts.map +1 -1
  41. package/package.json +5 -5
@@ -30,37 +30,23 @@ const StyledModalContent = styled(Modal.Content)`
30
30
  height: 90%;
31
31
  max-height: 100%;
32
32
  `;
33
- const getFullPageUrl = (currentDocumentMeta)=>{
34
- const isSingleType = currentDocumentMeta.collectionType === SINGLE_TYPES;
35
- const queryParams = currentDocumentMeta.params?.locale ? `?plugins[i18n][locale]=${currentDocumentMeta.params.locale}` : '';
36
- return `/content-manager/${currentDocumentMeta.collectionType}/${currentDocumentMeta.model}${isSingleType ? '' : '/' + currentDocumentMeta.documentId}${queryParams}`;
37
- };
38
33
  function reducer(state, action) {
39
34
  switch(action.type){
40
35
  case 'GO_TO_RELATION':
41
36
  if (state.hasUnsavedChanges && !action.payload.shouldBypassConfirmation) {
42
37
  return {
43
38
  ...state,
44
- confirmDialogIntent: action.payload.document,
45
- fieldToConnect: action.payload.fieldToConnect,
46
- fieldToConnectUID: action.payload.fieldToConnectUID
39
+ confirmDialogIntent: action.payload.document
47
40
  };
48
41
  }
49
- const lastItemDocumentHistory = state.documentHistory.at(-1);
50
- const hasToResetDocumentHistory = lastItemDocumentHistory && !lastItemDocumentHistory.documentId;
51
42
  return {
52
43
  ...state,
53
- // Reset document history if the last item has documentId undefined
54
- documentHistory: hasToResetDocumentHistory ? [
55
- action.payload.document
56
- ] : [
44
+ documentHistory: [
57
45
  ...state.documentHistory,
58
46
  action.payload.document
59
47
  ],
60
48
  confirmDialogIntent: null,
61
- isModalOpen: true,
62
- fieldToConnect: hasToResetDocumentHistory ? undefined : action.payload.fieldToConnect,
63
- fieldToConnectUID: hasToResetDocumentHistory ? undefined : action.payload.fieldToConnectUID
49
+ isModalOpen: true
64
50
  };
65
51
  case 'GO_BACK':
66
52
  if (state.hasUnsavedChanges && !action.payload.shouldBypassConfirmation) {
@@ -88,21 +74,6 @@ function reducer(state, action) {
88
74
  isModalOpen: false,
89
75
  confirmDialogIntent: null
90
76
  };
91
- case 'GO_TO_CREATED_RELATION':
92
- return {
93
- ...state,
94
- // Reset document history if the last item has documentId undefined
95
- documentHistory: state.documentHistory ? [
96
- ...state.documentHistory.slice(0, -1),
97
- action.payload.document
98
- ] : [
99
- action.payload.document
100
- ],
101
- confirmDialogIntent: null,
102
- isModalOpen: true,
103
- fieldToConnect: undefined,
104
- fieldToConnectUID: undefined
105
- };
106
77
  case 'CANCEL_CONFIRM_DIALOG':
107
78
  return {
108
79
  ...state,
@@ -132,17 +103,21 @@ function reducer(state, action) {
132
103
  }
133
104
  }
134
105
  const [RelationModalProvider, useRelationModal] = createContext('RelationModal');
135
- function isRenderProp(children) {
136
- return typeof children === 'function';
137
- }
138
- const RootRelationRenderer = (props)=>{
139
- const { children } = props;
106
+ const getFullPageUrl = (currentDocumentMeta)=>{
107
+ const isSingleType = currentDocumentMeta.collectionType === SINGLE_TYPES;
108
+ const queryParams = currentDocumentMeta.params?.locale ? `?plugins[i18n][locale]=${currentDocumentMeta.params.locale}` : '';
109
+ return `/content-manager/${currentDocumentMeta.collectionType}/${currentDocumentMeta.model}${isSingleType ? '' : '/' + currentDocumentMeta.documentId}${queryParams}`;
110
+ };
111
+ /**
112
+ * Component responsible of rendering its children wrapped in a modal, form and context if needed
113
+ */ const RelationModalRenderer = ({ children, trigger, relation })=>{
114
+ const { formatMessage } = useIntl();
115
+ const navigate = useNavigate();
140
116
  const [state, dispatch] = React.useReducer(reducer, {
141
117
  documentHistory: [],
142
118
  confirmDialogIntent: null,
143
119
  isModalOpen: false,
144
- hasUnsavedChanges: false,
145
- fieldToConnect: undefined
120
+ hasUnsavedChanges: false
146
121
  });
147
122
  const rootDocument = useDoc();
148
123
  const [{ query }] = useQueryParams();
@@ -157,9 +132,11 @@ const RootRelationRenderer = (props)=>{
157
132
  };
158
133
  const currentDocumentMeta = state.documentHistory.at(-1) ?? rootDocumentMeta;
159
134
  const currentDocument = useDocument(currentDocumentMeta);
160
- // TODO: check if we can remove the single type check
161
- const isSingleType = currentDocumentMeta.collectionType === SINGLE_TYPES;
162
- const isCreating = !currentDocumentMeta.documentId && !isSingleType;
135
+ const parentContextValue = useRelationModal('RelationContextWrapper', (state)=>state, false);
136
+ // A parent relation is already rendering a modal. In this case simply render the trigger
137
+ if (parentContextValue) {
138
+ return trigger;
139
+ }
163
140
  /**
164
141
  * There is no parent relation, so the relation modal doesn't exist. Create it and set up all the
165
142
  * pieces that will be used by potential child relations: the context, header, form, and footer.
@@ -169,156 +146,113 @@ const RootRelationRenderer = (props)=>{
169
146
  rootDocumentMeta: rootDocumentMeta,
170
147
  currentDocumentMeta: currentDocumentMeta,
171
148
  currentDocument: currentDocument,
172
- isCreating: isCreating,
173
- children: /*#__PURE__*/ jsx(RelationModal, {
174
- children: isRenderProp(children) ? children({
175
- dispatch
176
- }) : props.relation && /*#__PURE__*/ jsx(RelationModalTrigger, {
177
- relation: props.relation,
178
- children: children
179
- })
180
- })
181
- });
182
- };
183
- const NestedRelationRenderer = (props)=>{
184
- const { children } = props;
185
- const dispatch = useRelationModal('NestedRelation', (state)=>state.dispatch);
186
- return isRenderProp(children) ? children({
187
- dispatch
188
- }) : props.relation && /*#__PURE__*/ jsx(RelationModalTrigger, {
189
- relation: props.relation,
190
- children: children
191
- }); /* This is the trigger that will be rendered in the parent relation */
192
- };
193
- /**
194
- * Component responsible for rendering its children wrapped in a modal, form and context if needed
195
- */ const RelationModalRenderer = (props)=>{
196
- // We're in a nested relation if the relation modal context is not undefined
197
- const isNested = useRelationModal('RelationContextWrapper', (state)=>state != undefined, false);
198
- return isNested ? /*#__PURE__*/ jsx(NestedRelationRenderer, {
199
- ...props
200
- }) : /*#__PURE__*/ jsx(RootRelationRenderer, {
201
- ...props
202
- });
203
- };
204
- /* -------------------------------------------------------------------------------------------------
205
- * RelationModal
206
- * -----------------------------------------------------------------------------------------------*/ const generateCreateUrl = (currentDocumentMeta)=>{
207
- return `/content-manager/${currentDocumentMeta.collectionType}/${currentDocumentMeta.model}/create${currentDocumentMeta.params?.locale ? `?plugins[i18n][locale]=${currentDocumentMeta.params.locale}` : ''}`;
208
- };
209
- const RelationModal = ({ children })=>{
210
- const { formatMessage } = useIntl();
211
- const navigate = useNavigate();
212
- const state = useRelationModal('RelationModalForm', (state)=>state.state);
213
- const dispatch = useRelationModal('RelationModalForm', (state)=>state.dispatch);
214
- const currentDocumentMeta = useRelationModal('RelationModalForm', (state)=>state.currentDocumentMeta);
215
- const currentDocument = useRelationModal('RelationModalForm', (state)=>state.currentDocument);
216
- const isCreating = useRelationModal('RelationModalForm', (state)=>state.isCreating);
217
- return /*#__PURE__*/ jsxs(Modal.Root, {
218
- open: state.isModalOpen,
219
- onOpenChange: (open)=>{
220
- if (!open) {
221
- dispatch({
222
- type: 'CLOSE_MODAL',
223
- payload: {
224
- shouldBypassConfirmation: false
225
- }
226
- });
227
- }
228
- },
229
- children: [
230
- children,
231
- /*#__PURE__*/ jsxs(StyledModalContent, {
232
- children: [
233
- /*#__PURE__*/ jsx(Modal.Header, {
234
- gap: 2,
235
- children: /*#__PURE__*/ jsxs(Flex, {
236
- justifyContent: "space-between",
237
- alignItems: "center",
238
- width: "100%",
239
- children: [
240
- /*#__PURE__*/ jsxs(Flex, {
241
- gap: 2,
242
- children: [
243
- /*#__PURE__*/ jsx(IconButton, {
244
- withTooltip: false,
245
- label: formatMessage({
246
- id: 'global.back',
247
- defaultMessage: 'Back'
149
+ children: /*#__PURE__*/ jsxs(Modal.Root, {
150
+ open: state.isModalOpen,
151
+ onOpenChange: (open)=>{
152
+ if (open) {
153
+ dispatch({
154
+ type: 'GO_TO_RELATION',
155
+ payload: {
156
+ document: relation,
157
+ shouldBypassConfirmation: false
158
+ }
159
+ });
160
+ } else {
161
+ dispatch({
162
+ type: 'CLOSE_MODAL',
163
+ payload: {
164
+ shouldBypassConfirmation: false
165
+ }
166
+ });
167
+ }
168
+ },
169
+ children: [
170
+ trigger,
171
+ /*#__PURE__*/ jsxs(StyledModalContent, {
172
+ children: [
173
+ /*#__PURE__*/ jsx(Modal.Header, {
174
+ gap: 2,
175
+ children: /*#__PURE__*/ jsxs(Flex, {
176
+ justifyContent: "space-between",
177
+ alignItems: "center",
178
+ width: "100%",
179
+ children: [
180
+ /*#__PURE__*/ jsxs(Flex, {
181
+ gap: 2,
182
+ children: [
183
+ /*#__PURE__*/ jsx(IconButton, {
184
+ withTooltip: false,
185
+ label: formatMessage({
186
+ id: 'global.back',
187
+ defaultMessage: 'Back'
188
+ }),
189
+ variant: "ghost",
190
+ disabled: state.documentHistory.length < 2,
191
+ onClick: ()=>{
192
+ dispatch({
193
+ type: 'GO_BACK',
194
+ payload: {
195
+ shouldBypassConfirmation: false
196
+ }
197
+ });
198
+ },
199
+ marginRight: 1,
200
+ children: /*#__PURE__*/ jsx(ArrowLeft, {})
248
201
  }),
249
- variant: "ghost",
250
- disabled: state.documentHistory.length < 2,
251
- onClick: ()=>{
252
- dispatch({
253
- type: 'GO_BACK',
254
- payload: {
255
- shouldBypassConfirmation: false
256
- }
257
- });
258
- },
259
- marginRight: 1,
260
- children: /*#__PURE__*/ jsx(ArrowLeft, {})
261
- }),
262
- /*#__PURE__*/ jsx(Typography, {
263
- tag: "span",
264
- fontWeight: 600,
265
- children: isCreating ? formatMessage({
266
- id: 'content-manager.relation.create',
267
- defaultMessage: 'Create a relation'
268
- }) : formatMessage({
269
- id: 'content-manager.components.RelationInputModal.modal-title',
270
- defaultMessage: 'Edit a relation'
202
+ /*#__PURE__*/ jsx(Typography, {
203
+ tag: "span",
204
+ fontWeight: 600,
205
+ children: formatMessage({
206
+ id: 'content-manager.components.RelationInputModal.modal-title',
207
+ defaultMessage: 'Edit a relation'
208
+ })
271
209
  })
272
- })
273
- ]
274
- }),
275
- /*#__PURE__*/ jsx(IconButton, {
276
- onClick: ()=>{
277
- dispatch({
278
- type: 'GO_FULL_PAGE'
279
- });
280
- if (!state.hasUnsavedChanges) {
281
- if (isCreating) {
282
- navigate(generateCreateUrl(currentDocumentMeta));
283
- } else {
210
+ ]
211
+ }),
212
+ /*#__PURE__*/ jsx(IconButton, {
213
+ onClick: ()=>{
214
+ dispatch({
215
+ type: 'GO_FULL_PAGE'
216
+ });
217
+ if (!state.hasUnsavedChanges) {
284
218
  navigate(getFullPageUrl(currentDocumentMeta));
285
219
  }
286
- }
287
- },
288
- variant: "tertiary",
289
- label: formatMessage({
290
- id: 'content-manager.components.RelationInputModal.button-fullpage',
291
- defaultMessage: 'Go to entry'
292
- }),
293
- children: /*#__PURE__*/ jsx(ArrowsOut, {})
294
- })
295
- ]
296
- })
297
- }),
298
- /*#__PURE__*/ jsx(Modal.Body, {
299
- children: /*#__PURE__*/ jsx(Form, {
300
- method: isCreating ? 'POST' : 'PUT',
301
- initialValues: currentDocument.getInitialFormValues(isCreating),
302
- validate: (values, options)=>{
303
- const yupSchema = createYupSchema(currentDocument.schema?.attributes, currentDocument.components, {
304
- status: currentDocument.document?.status,
305
- ...options
306
- });
307
- return yupSchema.validate(values, {
308
- abortEarly: false
309
- });
310
- },
311
- children: /*#__PURE__*/ jsx(RelationModalBody, {})
220
+ },
221
+ variant: "tertiary",
222
+ label: formatMessage({
223
+ id: 'content-manager.components.RelationInputModal.button-fullpage',
224
+ defaultMessage: 'Go to entry'
225
+ }),
226
+ children: /*#__PURE__*/ jsx(ArrowsOut, {})
227
+ })
228
+ ]
229
+ })
230
+ }),
231
+ /*#__PURE__*/ jsx(Modal.Body, {
232
+ children: /*#__PURE__*/ jsx(Form, {
233
+ method: "PUT",
234
+ initialValues: currentDocument.getInitialFormValues(),
235
+ validate: (values, options)=>{
236
+ const yupSchema = createYupSchema(currentDocument.schema?.attributes, currentDocument.components, {
237
+ status: currentDocument.document?.status,
238
+ ...options
239
+ });
240
+ return yupSchema.validate(values, {
241
+ abortEarly: false
242
+ });
243
+ },
244
+ children: children
245
+ })
312
246
  })
313
- })
314
- ]
315
- })
316
- ]
247
+ ]
248
+ })
249
+ ]
250
+ })
317
251
  });
318
252
  };
319
253
  /**
320
254
  * All the main content (not header and footer) of the relation modal, plus the confirmation dialog.
321
- * Will be wrapped in a Modal.Body by the RelationModal component.
255
+ * Will be wrapped in a Modal.Body by the RelationModalRenderer.
322
256
  * Cannot be moved directly inside RelationModal because it needs access to the context via hooks.
323
257
  */ const RelationModalBody = ()=>{
324
258
  const navigate = useNavigate();
@@ -329,7 +263,6 @@ const RelationModal = ({ children })=>{
329
263
  const dispatch = useRelationModal('RelationModalForm', (state)=>state.dispatch);
330
264
  const rootDocumentMeta = useRelationModal('RelationModalForm', (state)=>state.rootDocumentMeta);
331
265
  const currentDocumentMeta = useRelationModal('RelationModalForm', (state)=>state.currentDocumentMeta);
332
- const isCreating = useRelationModal('RelationModalForm', (state)=>state.isCreating);
333
266
  /**
334
267
  * One-way sync the modified state from the form to the modal state.
335
268
  * It is needed because we need to consume state from the form context in order to lift it up
@@ -371,11 +304,7 @@ const RelationModal = ({ children })=>{
371
304
  if (isRootDocumentUrl) {
372
305
  handleCloseModal(true);
373
306
  } else {
374
- if (isCreating) {
375
- navigate(generateCreateUrl(currentDocumentMeta));
376
- } else {
377
- navigate(fullPageUrl);
378
- }
307
+ navigate(fullPageUrl);
379
308
  }
380
309
  };
381
310
  const handleConfirm = ()=>{
@@ -405,7 +334,7 @@ const RelationModal = ({ children })=>{
405
334
  };
406
335
  return /*#__PURE__*/ jsxs(Fragment, {
407
336
  children: [
408
- /*#__PURE__*/ jsx(RelationModalForm, {}),
337
+ /*#__PURE__*/ jsx(RelationEditView, {}),
409
338
  /*#__PURE__*/ jsx(Dialog.Root, {
410
339
  open: state.confirmDialogIntent != null,
411
340
  children: /*#__PURE__*/ jsx(ConfirmDialog, {
@@ -423,7 +352,7 @@ const RelationModal = ({ children })=>{
423
352
  ]
424
353
  });
425
354
  };
426
- const RelationModalTrigger = ({ children, relation })=>{
355
+ const ModalTrigger = ({ children, relation })=>{
427
356
  const dispatch = useRelationModal('ModalTrigger', (state)=>state.dispatch);
428
357
  return /*#__PURE__*/ jsx(StyledTextButton, {
429
358
  onClick: ()=>{
@@ -438,6 +367,16 @@ const RelationModalTrigger = ({ children, relation })=>{
438
367
  children: children
439
368
  });
440
369
  };
370
+ const RelationModal = /*#__PURE__*/ React.memo(({ relation, children })=>{
371
+ return /*#__PURE__*/ jsx(RelationModalRenderer, {
372
+ relation: relation,
373
+ trigger: /*#__PURE__*/ jsx(ModalTrigger, {
374
+ relation: relation,
375
+ children: children
376
+ }),
377
+ children: /*#__PURE__*/ jsx(RelationModalBody, {})
378
+ });
379
+ });
441
380
  const StyledTextButton = styled(TextButton)`
442
381
  max-width: 100%;
443
382
  & > span {
@@ -451,14 +390,13 @@ const StyledTextButton = styled(TextButton)`
451
390
  /**
452
391
  * The mini edit view for a relation that is displayed inside a modal.
453
392
  * It's complete with its header, document actions and form layout.
454
- */ const RelationModalForm = ()=>{
393
+ */ const RelationEditView = ()=>{
455
394
  const { formatMessage } = useIntl();
456
- const currentDocumentMeta = useRelationModal('RelationModalForm', (state)=>state.currentDocumentMeta);
457
- const isCreating = useRelationModal('RelationModalForm', (state)=>state.isCreating);
458
- const currentDocument = useRelationModal('RelationModalForm', (state)=>state.currentDocument);
395
+ const currentDocumentMeta = useRelationModal('RelationModalBody', (state)=>state.currentDocumentMeta);
396
+ const currentDocument = useRelationModal('RelationModalBody', (state)=>state.currentDocument);
459
397
  const documentLayoutResponse = useDocumentLayout(currentDocumentMeta.model);
460
- const plugins = useStrapiApp('RelationModalForm', (state)=>state.plugins);
461
- const initialValues = isCreating ? currentDocument.getInitialFormValues(isCreating) : currentDocument.getInitialFormValues();
398
+ const plugins = useStrapiApp('RelationModalBody', (state)=>state.plugins);
399
+ const initialValues = currentDocument.getInitialFormValues();
462
400
  const { permissions = [], isLoading: isLoadingPermissions, error } = useRBAC(PERMISSIONS.map((action)=>({
463
401
  action,
464
402
  subject: currentDocumentMeta.model
@@ -473,7 +411,7 @@ const StyledTextButton = styled(TextButton)`
473
411
  })
474
412
  });
475
413
  }
476
- if (error || !currentDocumentMeta.model || documentLayoutResponse.error || !isCreating && !currentDocument.document || !isCreating && !currentDocument.meta || !currentDocument.schema || !initialValues) {
414
+ if (error || !currentDocumentMeta.model || documentLayoutResponse.error || !currentDocument.document || !currentDocument.meta || !currentDocument.schema || !initialValues) {
477
415
  return /*#__PURE__*/ jsx(Flex, {
478
416
  alignItems: "center",
479
417
  height: "100%",
@@ -582,5 +520,5 @@ const StyledTextButton = styled(TextButton)`
582
520
  });
583
521
  };
584
522
 
585
- export { RelationModalRenderer, getCollectionType, reducer, useRelationModal };
523
+ export { RelationModal, getCollectionType, reducer, useRelationModal };
586
524
  //# sourceMappingURL=RelationModal.mjs.map