@strapi/content-manager 5.16.1 → 5.17.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/admin/history/components/VersionContent.js +24 -3
  2. package/dist/admin/history/components/VersionContent.js.map +1 -1
  3. package/dist/admin/history/components/VersionContent.mjs +25 -4
  4. package/dist/admin/history/components/VersionContent.mjs.map +1 -1
  5. package/dist/admin/pages/EditView/EditViewPage.js +11 -1
  6. package/dist/admin/pages/EditView/EditViewPage.js.map +1 -1
  7. package/dist/admin/pages/EditView/EditViewPage.mjs +11 -1
  8. package/dist/admin/pages/EditView/EditViewPage.mjs.map +1 -1
  9. package/dist/admin/pages/EditView/components/DocumentActions.js +28 -4
  10. package/dist/admin/pages/EditView/components/DocumentActions.js.map +1 -1
  11. package/dist/admin/pages/EditView/components/DocumentActions.mjs +28 -4
  12. package/dist/admin/pages/EditView/components/DocumentActions.mjs.map +1 -1
  13. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js +12 -1
  14. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js.map +1 -1
  15. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs +13 -2
  16. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs.map +1 -1
  17. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js +13 -2
  18. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js.map +1 -1
  19. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs +14 -3
  20. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs.map +1 -1
  21. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js +16 -3
  22. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js.map +1 -1
  23. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs +17 -4
  24. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs.map +1 -1
  25. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +105 -153
  26. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
  27. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs +108 -156
  28. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs.map +1 -1
  29. package/dist/admin/pages/EditView/components/FormLayout.js +27 -3
  30. package/dist/admin/pages/EditView/components/FormLayout.js.map +1 -1
  31. package/dist/admin/pages/EditView/components/FormLayout.mjs +27 -3
  32. package/dist/admin/pages/EditView/components/FormLayout.mjs.map +1 -1
  33. package/dist/admin/pages/EditView/utils/data.js +103 -0
  34. package/dist/admin/pages/EditView/utils/data.js.map +1 -1
  35. package/dist/admin/pages/EditView/utils/data.mjs +103 -1
  36. package/dist/admin/pages/EditView/utils/data.mjs.map +1 -1
  37. package/dist/admin/src/pages/EditView/utils/data.d.ts +19 -1
  38. package/dist/admin/src/utils/validation.d.ts +1 -0
  39. package/dist/admin/utils/validation.js +16 -5
  40. package/dist/admin/utils/validation.js.map +1 -1
  41. package/dist/admin/utils/validation.mjs +16 -5
  42. package/dist/admin/utils/validation.mjs.map +1 -1
  43. package/package.json +7 -7
@@ -1,8 +1,8 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import { useForm, useField, useNotification, useRBAC, useFocusInputField } from '@strapi/admin/strapi-admin';
4
- import { Flex, Box, Link, TextButton, EmptyStateLayout, Field, Combobox, ComboboxOption, Typography, VisuallyHidden, useComposedRefs, IconButton } from '@strapi/design-system';
5
- import { ArrowClockwise, WarningCircle, Plus, Link as Link$1, Drag, Cross } from '@strapi/icons';
3
+ import { useForm, useField, useNotification, useFocusInputField } from '@strapi/admin/strapi-admin';
4
+ import { Flex, Box, Link, TextButton, Field, Combobox, ComboboxOption, Typography, VisuallyHidden, useComposedRefs, IconButton } from '@strapi/design-system';
5
+ import { ArrowClockwise, Plus, Link as Link$1, Drag, Cross } from '@strapi/icons';
6
6
  import { generateNKeysBetween } from 'fractional-indexing';
7
7
  import pipe from 'lodash/fp/pipe';
8
8
  import { getEmptyImage } from 'react-dnd-html5-backend';
@@ -11,8 +11,6 @@ import { FixedSizeList } from 'react-window';
11
11
  import { styled } from 'styled-components';
12
12
  import { COLLECTION_TYPES } from '../../../../../constants/collections.mjs';
13
13
  import { ItemTypes } from '../../../../../constants/dragAndDrop.mjs';
14
- import { PERMISSIONS } from '../../../../../constants/plugin.mjs';
15
- import { DocumentRBAC, useDocumentRBAC } from '../../../../../features/DocumentRBAC.mjs';
16
14
  import { useDebounce } from '../../../../../hooks/useDebounce.mjs';
17
15
  import { useDocument } from '../../../../../hooks/useDocument.mjs';
18
16
  import { useDocumentContext } from '../../../../../hooks/useDocumentContext.mjs';
@@ -309,6 +307,7 @@ const ONE_WAY_RELATIONS = [
309
307
  * @description Contains all the logic for the combobox that can search
310
308
  * for relations and then add them to the field's connect array.
311
309
  */ const RelationsInput = ({ hint, id, model, label, labelAction, name, mainField, placeholder, required, unique: _unique, 'aria-label': _ariaLabel, onChange, isRelatedToCurrentDocument, ...props })=>{
310
+ const [textValue, setTextValue] = React.useState('');
312
311
  const [searchParams, setSearchParams] = React.useState({
313
312
  _q: '',
314
313
  page: 1
@@ -316,6 +315,7 @@ const ONE_WAY_RELATIONS = [
316
315
  const { toggleNotification } = useNotification();
317
316
  const { currentDocumentMeta } = useDocumentContext('RelationsInput');
318
317
  const { formatMessage } = useIntl();
318
+ const fieldRef = useFocusInputField(name);
319
319
  const field = useField(name);
320
320
  const searchParamsDebounced = useDebounce(searchParams, 300);
321
321
  const [searchForTrigger, { data, isLoading }] = useLazySearchRelationsQuery();
@@ -356,6 +356,13 @@ const ONE_WAY_RELATIONS = [
356
356
  isRelatedToCurrentDocument,
357
357
  currentDocumentMeta.params
358
358
  ]);
359
+ const handleSearch = async (search)=>{
360
+ setSearchParams((s)=>({
361
+ ...s,
362
+ _q: search,
363
+ page: 1
364
+ }));
365
+ };
359
366
  const hasNextPage = data?.pagination ? data.pagination.page < data.pagination.pageCount : false;
360
367
  const options = data?.results ?? [];
361
368
  const handleChange = (relationId)=>{
@@ -383,6 +390,21 @@ const ONE_WAY_RELATIONS = [
383
390
  *
384
391
  */ onChange(relation);
385
392
  };
393
+ const handleLoadMore = ()=>{
394
+ if (!data || !data.pagination) {
395
+ return;
396
+ } else if (data.pagination.page < data.pagination.pageCount) {
397
+ setSearchParams((s)=>({
398
+ ...s,
399
+ page: s.page + 1
400
+ }));
401
+ }
402
+ };
403
+ React.useLayoutEffect(()=>{
404
+ setTextValue('');
405
+ }, [
406
+ field.value
407
+ ]);
386
408
  const relation = {
387
409
  collectionType: COLLECTION_TYPES,
388
410
  // @ts-expect-error – targetModel does exist on the attribute. But it's not typed.
@@ -390,26 +412,9 @@ const ONE_WAY_RELATIONS = [
390
412
  documentId: '',
391
413
  params: currentDocumentMeta.params
392
414
  };
393
- const { permissions = [], isLoading: isLoadingPermissions, error } = useRBAC(PERMISSIONS.map((action)=>({
394
- action,
395
- subject: relation.model
396
- })));
397
- if (error) {
398
- return /*#__PURE__*/ jsx(Flex, {
399
- alignItems: "center",
400
- height: "100%",
401
- justifyContent: "center",
402
- children: /*#__PURE__*/ jsx(EmptyStateLayout, {
403
- icon: /*#__PURE__*/ jsx(WarningCircle, {
404
- width: "16rem"
405
- }),
406
- content: formatMessage({
407
- id: 'anErrorOccurred',
408
- defaultMessage: 'Whoops! Something went wrong. Please, try again.'
409
- })
410
- })
411
- });
412
- }
415
+ const { componentUID } = useComponent('RelationsField', ({ uid })=>({
416
+ componentUID: uid
417
+ }));
413
418
  return /*#__PURE__*/ jsxs(Field.Root, {
414
419
  error: field.error,
415
420
  hint: hint,
@@ -420,143 +425,90 @@ const ONE_WAY_RELATIONS = [
420
425
  action: labelAction,
421
426
  children: label
422
427
  }),
423
- /*#__PURE__*/ jsx(DocumentRBAC, {
424
- permissions: permissions,
425
- model: relation.model,
426
- children: /*#__PURE__*/ jsx(RelationModalWithContext, {
427
- relation: relation,
428
- name: name,
429
- placeholder: placeholder,
430
- hasNextPage: hasNextPage,
431
- isLoadingPermissions: isLoadingPermissions,
432
- isLoadingSearchRelations: isLoading,
433
- handleChange: handleChange,
434
- setSearchParams: setSearchParams,
435
- data: data,
436
- mainField: mainField,
437
- fieldValue: field.value,
438
- ...props
439
- })
440
- }),
441
- /*#__PURE__*/ jsx(Field.Error, {}),
442
- /*#__PURE__*/ jsx(Field.Hint, {})
443
- ]
444
- });
445
- };
446
- const RelationModalWithContext = ({ relation, name, placeholder, hasNextPage, isLoadingSearchRelations, isLoadingPermissions, handleChange, mainField, setSearchParams, fieldValue, data, ...props })=>{
447
- const [textValue, setTextValue] = React.useState('');
448
- const { formatMessage } = useIntl();
449
- const canCreate = useDocumentRBAC('RelationModalWrapper', (state)=>state.canCreate);
450
- const fieldRef = useFocusInputField(name);
451
- const { componentUID } = useComponent('RelationsField', ({ uid })=>({
452
- componentUID: uid
453
- }));
454
- const handleLoadMore = ()=>{
455
- if (!data || !data.pagination) {
456
- return;
457
- } else if (data.pagination.page < data.pagination.pageCount) {
458
- setSearchParams((s)=>({
459
- ...s,
460
- page: s.page + 1
461
- }));
462
- }
463
- };
464
- const options = data?.results ?? [];
465
- React.useLayoutEffect(()=>{
466
- setTextValue('');
467
- }, [
468
- fieldValue
469
- ]);
470
- const handleSearch = async (search)=>{
471
- setSearchParams((s)=>({
472
- ...s,
473
- _q: search,
474
- page: 1
475
- }));
476
- };
477
- return /*#__PURE__*/ jsx(RelationModalRenderer, {
478
- children: ({ dispatch })=>/*#__PURE__*/ jsx(Combobox, {
479
- ref: fieldRef,
480
- creatable: "visible",
481
- creatableDisabled: !canCreate,
482
- createMessage: ()=>formatMessage({
483
- id: getTranslation('relation.create'),
484
- defaultMessage: 'Create a relation'
485
- }),
486
- onCreateOption: ()=>{
487
- if (canCreate) {
488
- dispatch({
489
- type: 'GO_TO_RELATION',
490
- payload: {
491
- document: relation,
492
- shouldBypassConfirmation: false,
493
- fieldToConnect: name,
494
- fieldToConnectUID: componentUID
495
- }
496
- });
497
- }
498
- },
499
- creatableStartIcon: /*#__PURE__*/ jsx(Plus, {
500
- fill: "neutral500"
501
- }),
502
- name: name,
503
- autocomplete: "list",
504
- placeholder: placeholder || formatMessage({
505
- id: getTranslation('relation.add'),
506
- defaultMessage: 'Add relation'
507
- }),
508
- hasMoreItems: hasNextPage,
509
- loading: isLoadingSearchRelations || isLoadingPermissions,
510
- onOpenChange: ()=>{
511
- handleSearch(textValue ?? '');
512
- },
513
- noOptionsMessage: ()=>formatMessage({
514
- id: getTranslation('relation.notAvailable'),
515
- defaultMessage: 'No relations available'
516
- }),
517
- loadingMessage: formatMessage({
518
- id: getTranslation('relation.isLoading'),
519
- defaultMessage: 'Relations are loading'
520
- }),
521
- onLoadMore: handleLoadMore,
522
- textValue: textValue,
523
- onChange: handleChange,
524
- onTextValueChange: (text)=>{
525
- setTextValue(text);
526
- },
527
- onInputChange: (event)=>{
528
- handleSearch(event.currentTarget.value);
529
- },
530
- ...props,
531
- children: options?.map((opt)=>{
532
- const textValue = getRelationLabel(opt, mainField);
533
- return /*#__PURE__*/ jsx(ComboboxOption, {
534
- value: opt.id.toString(),
428
+ /*#__PURE__*/ jsx(RelationModalRenderer, {
429
+ children: ({ dispatch })=>/*#__PURE__*/ jsx(Combobox, {
430
+ ref: fieldRef,
431
+ creatable: "visible",
432
+ createMessage: ()=>formatMessage({
433
+ id: getTranslation('relation.create'),
434
+ defaultMessage: 'Create a relation'
435
+ }),
436
+ onCreateOption: ()=>{
437
+ dispatch({
438
+ type: 'GO_TO_RELATION',
439
+ payload: {
440
+ document: relation,
441
+ shouldBypassConfirmation: false,
442
+ fieldToConnect: name,
443
+ fieldToConnectUID: componentUID
444
+ }
445
+ });
446
+ },
447
+ creatableStartIcon: /*#__PURE__*/ jsx(Plus, {
448
+ fill: "neutral500"
449
+ }),
450
+ name: name,
451
+ autocomplete: "list",
452
+ placeholder: placeholder || formatMessage({
453
+ id: getTranslation('relation.add'),
454
+ defaultMessage: 'Add relation'
455
+ }),
456
+ hasMoreItems: hasNextPage,
457
+ loading: isLoading,
458
+ onOpenChange: ()=>{
459
+ handleSearch(textValue ?? '');
460
+ },
461
+ noOptionsMessage: ()=>formatMessage({
462
+ id: getTranslation('relation.notAvailable'),
463
+ defaultMessage: 'No relations available'
464
+ }),
465
+ loadingMessage: formatMessage({
466
+ id: getTranslation('relation.isLoading'),
467
+ defaultMessage: 'Relations are loading'
468
+ }),
469
+ onLoadMore: handleLoadMore,
535
470
  textValue: textValue,
536
- children: /*#__PURE__*/ jsxs(Flex, {
537
- gap: 2,
538
- justifyContent: "space-between",
539
- children: [
540
- /*#__PURE__*/ jsxs(Flex, {
471
+ onChange: handleChange,
472
+ onTextValueChange: (text)=>{
473
+ setTextValue(text);
474
+ },
475
+ onInputChange: (event)=>{
476
+ handleSearch(event.currentTarget.value);
477
+ },
478
+ ...props,
479
+ children: options.map((opt)=>{
480
+ const textValue = getRelationLabel(opt, mainField);
481
+ return /*#__PURE__*/ jsx(ComboboxOption, {
482
+ value: opt.id.toString(),
483
+ textValue: textValue,
484
+ children: /*#__PURE__*/ jsxs(Flex, {
541
485
  gap: 2,
486
+ justifyContent: "space-between",
542
487
  children: [
543
- /*#__PURE__*/ jsx(Link$1, {
544
- fill: "neutral500"
488
+ /*#__PURE__*/ jsxs(Flex, {
489
+ gap: 2,
490
+ children: [
491
+ /*#__PURE__*/ jsx(Link$1, {
492
+ fill: "neutral500"
493
+ }),
494
+ /*#__PURE__*/ jsx(Typography, {
495
+ ellipsis: true,
496
+ children: textValue
497
+ })
498
+ ]
545
499
  }),
546
- /*#__PURE__*/ jsx(Typography, {
547
- ellipsis: true,
548
- children: textValue
549
- })
500
+ opt.status ? /*#__PURE__*/ jsx(DocumentStatus, {
501
+ status: opt.status
502
+ }) : null
550
503
  ]
551
- }),
552
- opt.status ? /*#__PURE__*/ jsx(DocumentStatus, {
553
- status: opt.status
554
- }) : null
555
- ]
504
+ })
505
+ }, opt.id);
556
506
  })
557
- }, opt.id);
558
- })
559
- })
507
+ })
508
+ }),
509
+ /*#__PURE__*/ jsx(Field.Error, {}),
510
+ /*#__PURE__*/ jsx(Field.Hint, {})
511
+ ]
560
512
  });
561
513
  };
562
514
  /* -------------------------------------------------------------------------------------------------