@contentful/field-editor-reference 5.19.0 → 5.20.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 (115) hide show
  1. package/dist/cjs/__fixtures__/FakeSdk.js +3 -3
  2. package/dist/cjs/__fixtures__/asset/index.js +10 -10
  3. package/dist/cjs/__fixtures__/content-type/index.js +1 -1
  4. package/dist/cjs/__fixtures__/entry/index.js +7 -7
  5. package/dist/cjs/__fixtures__/fixtures.js +8 -6
  6. package/dist/cjs/__fixtures__/locale/index.js +2 -2
  7. package/dist/cjs/__fixtures__/space/index.js +1 -1
  8. package/dist/cjs/assets/MultipleMediaEditor.js +7 -5
  9. package/dist/cjs/assets/SingleMediaEditor.js +6 -4
  10. package/dist/cjs/assets/WrappedAssetCard/AssetCardActions.js +21 -19
  11. package/dist/cjs/assets/WrappedAssetCard/FetchingWrappedAssetCard.js +18 -11
  12. package/dist/cjs/assets/WrappedAssetCard/WrappedAssetCard.js +20 -11
  13. package/dist/cjs/assets/WrappedAssetCard/WrappedAssetLink.js +12 -9
  14. package/dist/cjs/assets/index.js +3 -3
  15. package/dist/cjs/common/EntityStore.js +53 -53
  16. package/dist/cjs/common/MultipleReferenceEditor.js +20 -11
  17. package/dist/cjs/common/ReferenceEditor.js +7 -5
  18. package/dist/cjs/common/SingleReferenceEditor.js +11 -7
  19. package/dist/cjs/common/SortableLinkList.js +14 -14
  20. package/dist/cjs/common/customCardTypes.js +4 -2
  21. package/dist/cjs/common/queryClient.js +102 -0
  22. package/dist/cjs/common/useContentTypePermissions.js +3 -1
  23. package/dist/cjs/common/useEditorPermissions.js +15 -3
  24. package/dist/cjs/common/useEditorPermissions.spec.js +13 -12
  25. package/dist/cjs/components/AssetThumbnail/AssetThumbnail.js +5 -3
  26. package/dist/cjs/components/CreateEntryLinkButton/CreateEntryLinkButton.js +13 -9
  27. package/dist/cjs/components/CreateEntryLinkButton/CreateEntryLinkButton.spec.js +17 -15
  28. package/dist/cjs/components/CreateEntryLinkButton/CreateEntryMenuTrigger.js +29 -19
  29. package/dist/cjs/components/CreateEntryLinkButton/CreateEntryMenuTrigger.spec.js +14 -12
  30. package/dist/cjs/components/LinkActions/CombinedLinkActions.js +28 -21
  31. package/dist/cjs/components/LinkActions/LinkActions.js +17 -15
  32. package/dist/cjs/components/LinkActions/LinkEntityActions.js +26 -17
  33. package/dist/cjs/components/LinkActions/NoLinkPermissionsInfo.js +5 -3
  34. package/dist/cjs/components/LinkActions/helpers.js +10 -5
  35. package/dist/cjs/components/LinkActions/redesignStyles.js +4 -4
  36. package/dist/cjs/components/LinkActions/styles.js +1 -1
  37. package/dist/cjs/components/MissingEntityCard/MissingEntityCard.js +11 -9
  38. package/dist/cjs/components/ResourceEntityErrorCard/ResourceEntityErrorCard.js +6 -4
  39. package/dist/cjs/components/ResourceEntityErrorCard/UnsupportedEntityCard.js +6 -4
  40. package/dist/cjs/components/ScheduledIconWithTooltip/ScheduleTooltip.js +10 -8
  41. package/dist/cjs/components/ScheduledIconWithTooltip/ScheduledIconWithTooltip.js +9 -4
  42. package/dist/cjs/components/ScheduledIconWithTooltip/formatDateAndTime.js +5 -4
  43. package/dist/cjs/components/SpaceName/SpaceName.js +9 -7
  44. package/dist/cjs/components/index.js +12 -12
  45. package/dist/cjs/entries/MultipleEntryReferenceEditor.js +9 -7
  46. package/dist/cjs/entries/SingleEntryReferenceEditor.js +7 -5
  47. package/dist/cjs/entries/WrappedEntryCard/FetchingWrappedEntryCard.js +20 -11
  48. package/dist/cjs/entries/WrappedEntryCard/WrappedEntryCard.js +23 -17
  49. package/dist/cjs/entries/index.js +3 -3
  50. package/dist/cjs/index.js +38 -34
  51. package/dist/cjs/resources/Cards/ContentfulEntryCard.js +13 -4
  52. package/dist/cjs/resources/Cards/ResourceCard.js +16 -12
  53. package/dist/cjs/resources/Cards/ResourceCard.spec.js +20 -17
  54. package/dist/cjs/resources/MultipleResourceReferenceEditor.js +20 -17
  55. package/dist/cjs/resources/MultipleResourceReferenceEditor.spec.js +34 -13
  56. package/dist/cjs/resources/SingleResourceReferenceEditor.js +11 -9
  57. package/dist/cjs/resources/SingleResourceReferenceEditor.spec.js +13 -6
  58. package/dist/cjs/resources/testHelpers/resourceEditorHelpers.js +12 -5
  59. package/dist/cjs/resources/useResourceLinkActions.js +11 -2
  60. package/dist/cjs/types.js +3 -3
  61. package/dist/cjs/utils/fromFieldValidations.js +2 -1
  62. package/dist/cjs/utils/useSortIDs.js +6 -4
  63. package/dist/esm/__fixtures__/FakeSdk.js +3 -3
  64. package/dist/esm/assets/MultipleMediaEditor.js +3 -3
  65. package/dist/esm/assets/SingleMediaEditor.js +2 -2
  66. package/dist/esm/assets/WrappedAssetCard/AssetCardActions.js +12 -12
  67. package/dist/esm/assets/WrappedAssetCard/FetchingWrappedAssetCard.js +14 -9
  68. package/dist/esm/assets/WrappedAssetCard/WrappedAssetCard.js +15 -7
  69. package/dist/esm/assets/WrappedAssetCard/WrappedAssetLink.js +7 -6
  70. package/dist/esm/common/EntityStore.js +40 -42
  71. package/dist/esm/common/MultipleReferenceEditor.js +16 -9
  72. package/dist/esm/common/ReferenceEditor.js +2 -2
  73. package/dist/esm/common/SingleReferenceEditor.js +7 -5
  74. package/dist/esm/common/SortableLinkList.js +12 -12
  75. package/dist/esm/common/queryClient.js +44 -0
  76. package/dist/esm/common/useContentTypePermissions.js +3 -1
  77. package/dist/esm/common/useEditorPermissions.js +15 -3
  78. package/dist/esm/common/useEditorPermissions.spec.js +13 -12
  79. package/dist/esm/components/AssetThumbnail/AssetThumbnail.js +1 -1
  80. package/dist/esm/components/CreateEntryLinkButton/CreateEntryLinkButton.js +7 -5
  81. package/dist/esm/components/CreateEntryLinkButton/CreateEntryLinkButton.spec.js +12 -12
  82. package/dist/esm/components/CreateEntryLinkButton/CreateEntryMenuTrigger.js +23 -15
  83. package/dist/esm/components/CreateEntryLinkButton/CreateEntryMenuTrigger.spec.js +9 -8
  84. package/dist/esm/components/LinkActions/CombinedLinkActions.js +30 -19
  85. package/dist/esm/components/LinkActions/LinkActions.js +9 -9
  86. package/dist/esm/components/LinkActions/LinkEntityActions.js +18 -11
  87. package/dist/esm/components/LinkActions/NoLinkPermissionsInfo.js +1 -1
  88. package/dist/esm/components/LinkActions/helpers.js +7 -2
  89. package/dist/esm/components/MissingEntityCard/MissingEntityCard.js +6 -6
  90. package/dist/esm/components/ResourceEntityErrorCard/ResourceEntityErrorCard.js +2 -2
  91. package/dist/esm/components/ResourceEntityErrorCard/UnsupportedEntityCard.js +2 -2
  92. package/dist/esm/components/ScheduledIconWithTooltip/ScheduleTooltip.js +3 -3
  93. package/dist/esm/components/ScheduledIconWithTooltip/ScheduledIconWithTooltip.js +5 -2
  94. package/dist/esm/components/ScheduledIconWithTooltip/formatDateAndTime.js +11 -2
  95. package/dist/esm/components/SpaceName/SpaceName.js +4 -4
  96. package/dist/esm/entries/MultipleEntryReferenceEditor.js +5 -5
  97. package/dist/esm/entries/SingleEntryReferenceEditor.js +3 -3
  98. package/dist/esm/entries/WrappedEntryCard/FetchingWrappedEntryCard.js +15 -8
  99. package/dist/esm/entries/WrappedEntryCard/WrappedEntryCard.js +18 -14
  100. package/dist/esm/index.js +1 -0
  101. package/dist/esm/resources/Cards/ContentfulEntryCard.js +9 -2
  102. package/dist/esm/resources/Cards/ResourceCard.js +12 -10
  103. package/dist/esm/resources/Cards/ResourceCard.spec.js +12 -11
  104. package/dist/esm/resources/MultipleResourceReferenceEditor.js +14 -13
  105. package/dist/esm/resources/MultipleResourceReferenceEditor.spec.js +30 -11
  106. package/dist/esm/resources/SingleResourceReferenceEditor.js +6 -6
  107. package/dist/esm/resources/SingleResourceReferenceEditor.spec.js +9 -4
  108. package/dist/esm/resources/testHelpers/resourceEditorHelpers.js +9 -2
  109. package/dist/esm/resources/useResourceLinkActions.js +11 -2
  110. package/dist/esm/utils/fromFieldValidations.js +1 -0
  111. package/dist/esm/utils/useSortIDs.js +2 -2
  112. package/dist/types/common/EntityStore.d.ts +1 -1
  113. package/dist/types/common/queryClient.d.ts +9 -0
  114. package/dist/types/index.d.ts +1 -0
  115. package/package.json +2 -2
@@ -3,20 +3,20 @@ import { Card, Flex, IconButton, SectionHeading } from '@contentful/f36-componen
3
3
  import { CloseIcon } from '@contentful/f36-icons';
4
4
  import * as styles from './styles';
5
5
  export function MissingEntityCard(props) {
6
- return React.createElement(Card, {
6
+ return /*#__PURE__*/ React.createElement(Card, {
7
7
  className: styles.card,
8
8
  testId: "cf-ui-missing-entry-card",
9
9
  isSelected: props.isSelected
10
- }, React.createElement(Flex, {
10
+ }, /*#__PURE__*/ React.createElement(Flex, {
11
11
  alignItems: "center",
12
12
  justifyContent: "space-between"
13
- }, React.createElement("div", {
13
+ }, /*#__PURE__*/ React.createElement("div", {
14
14
  className: props.asSquare ? styles.squareCard : ''
15
- }, React.createElement(SectionHeading, {
15
+ }, /*#__PURE__*/ React.createElement(SectionHeading, {
16
16
  marginBottom: "none"
17
- }, props.entityType, " is missing or inaccessible")), !props.isDisabled && props.onRemove && React.createElement(IconButton, {
17
+ }, props.entityType, " is missing or inaccessible")), !props.isDisabled && props.onRemove && /*#__PURE__*/ React.createElement(IconButton, {
18
18
  variant: "transparent",
19
- icon: React.createElement(CloseIcon, {
19
+ icon: /*#__PURE__*/ React.createElement(CloseIcon, {
20
20
  variant: "muted"
21
21
  }),
22
22
  "aria-label": "Delete",
@@ -4,12 +4,12 @@ import { MissingEntityCard } from '../MissingEntityCard/MissingEntityCard';
4
4
  import { UnsupportedEntityCard } from './UnsupportedEntityCard';
5
5
  export function ResourceEntityErrorCard(props) {
6
6
  if (isUnsupportedError(props.error)) {
7
- return React.createElement(UnsupportedEntityCard, {
7
+ return /*#__PURE__*/ React.createElement(UnsupportedEntityCard, {
8
8
  linkType: props.linkType,
9
9
  isSelected: props.isSelected
10
10
  });
11
11
  }
12
- return React.createElement(MissingEntityCard, {
12
+ return /*#__PURE__*/ React.createElement(MissingEntityCard, {
13
13
  entityType: "Entry",
14
14
  isDisabled: props.isDisabled,
15
15
  isSelected: props.isSelected,
@@ -7,10 +7,10 @@ const styles = {
7
7
  })
8
8
  };
9
9
  export function UnsupportedEntityCard(props) {
10
- return React.createElement(Card, {
10
+ return /*#__PURE__*/ React.createElement(Card, {
11
11
  className: styles.card,
12
12
  isSelected: props.isSelected
13
- }, React.createElement(SectionHeading, {
13
+ }, /*#__PURE__*/ React.createElement(SectionHeading, {
14
14
  marginBottom: "none"
15
15
  }, "Resource type ", props.linkType, " is currently not supported"));
16
16
  }
@@ -1,12 +1,12 @@
1
1
  import * as React from 'react';
2
2
  import { Tooltip } from '@contentful/f36-components';
3
3
  import { formatDateAndTime } from './formatDateAndTime';
4
- export const getScheduleTooltipContent = ({ job , jobsCount })=>{
4
+ export const getScheduleTooltipContent = ({ job, jobsCount })=>{
5
5
  return `Will ${job.action.toLowerCase()} ${formatDateAndTime(job.scheduledFor.datetime).toLowerCase()}
6
6
  ${jobsCount > 1 ? `+ ${jobsCount - 1} more` : ''}`;
7
7
  };
8
- export const ScheduleTooltip = ({ job , jobsCount , children })=>{
9
- return React.createElement(Tooltip, {
8
+ export const ScheduleTooltip = ({ job, jobsCount, children })=>{
9
+ return /*#__PURE__*/ React.createElement(Tooltip, {
10
10
  placement: "top",
11
11
  testId: job.sys.id,
12
12
  as: "div",
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { ScheduleTooltip } from './ScheduleTooltip';
3
- export const ScheduledIconWithTooltip = ({ entityType , entityId , getEntityScheduledActions , children })=>{
3
+ export const ScheduledIconWithTooltip = ({ entityType, entityId, getEntityScheduledActions, children })=>{
4
4
  const [status, setStatus] = React.useState({
5
5
  type: 'loading'
6
6
  });
@@ -16,6 +16,9 @@ export const ScheduledIconWithTooltip = ({ entityType , entityId , getEntitySche
16
16
  error: e
17
17
  });
18
18
  });
19
+ // This should only be ever called once. Following the eslint hint to add used
20
+ // dependencies will cause page freeze (infinite loop)
21
+ // eslint-disable-next-line -- TODO: describe this disable
19
22
  }, []);
20
23
  if (status.type === 'loading' || status.type === 'error') {
21
24
  return null;
@@ -25,7 +28,7 @@ export const ScheduledIconWithTooltip = ({ entityType , entityId , getEntitySche
25
28
  return null;
26
29
  }
27
30
  const mostRelevantJob = jobs[0];
28
- return React.createElement(ScheduleTooltip, {
31
+ return /*#__PURE__*/ React.createElement(ScheduleTooltip, {
29
32
  job: mostRelevantJob,
30
33
  jobsCount: jobs.length
31
34
  }, children);
@@ -1,5 +1,9 @@
1
+ // eslint-disable-next-line -- TODO: describe this disable no-restricted-imports
1
2
  import moment from 'moment';
2
- export const formatDate = (date, short)=>{
3
+ /**
4
+ * @param {Date|string} date A valid constructor argument for moment()
5
+ * @param {boolean=} short Render only Today/Tomorrow/Yesterday if valid. Defaults to false
6
+ */ export const formatDate = (date, short)=>{
3
7
  switch(moment().startOf('day').diff(moment(date).startOf('day'), 'days')){
4
8
  case 0:
5
9
  return short ? 'Today' : `Today, ${moment(date).format('DD MMM YYYY')}`;
@@ -11,7 +15,12 @@ export const formatDate = (date, short)=>{
11
15
  return moment(date).format('ddd, DD MMM YYYY');
12
16
  }
13
17
  };
14
- export const formatTime = (date)=>{
18
+ /**
19
+ * Returns the time portion of a date in the local time in the format H:MM AM/PM
20
+ *
21
+ * == Examples
22
+ * * `T15:36:45.000Z` => 3:36 PM (if in +0:00 offset)
23
+ */ export const formatTime = (date)=>{
15
24
  return moment.utc(date).local().format('h:mm A');
16
25
  };
17
26
  export const formatDateAndTime = (date, short)=>{
@@ -21,19 +21,19 @@ const styles = {
21
21
  export function SpaceName(props) {
22
22
  let content = `Space: ${props.spaceName}`;
23
23
  if (props.environmentName) content += ` (Env.: ${props.environmentName})`;
24
- return React.createElement(Tooltip, {
24
+ return /*#__PURE__*/ React.createElement(Tooltip, {
25
25
  placement: "top",
26
26
  as: "div",
27
27
  content: content
28
- }, React.createElement(Flex, {
28
+ }, /*#__PURE__*/ React.createElement(Flex, {
29
29
  alignItems: "center",
30
30
  gap: "spacingXs",
31
31
  marginRight: "spacingS"
32
- }, React.createElement(FolderOpenTrimmedIcon, {
32
+ }, /*#__PURE__*/ React.createElement(FolderOpenTrimmedIcon, {
33
33
  className: styles.spaceIcon,
34
34
  size: "tiny",
35
35
  "aria-label": "Source space"
36
- }), React.createElement(Text, {
36
+ }), /*#__PURE__*/ React.createElement(Text, {
37
37
  className: styles.spaceName
38
38
  }, props.spaceName)));
39
39
  }
@@ -5,20 +5,20 @@ import { SortableLinkList } from '../common/SortableLinkList';
5
5
  import { FetchingWrappedEntryCard } from './WrappedEntryCard/FetchingWrappedEntryCard';
6
6
  export function MultipleEntryReferenceEditor(props) {
7
7
  const [indexToUpdate, setIndexToUpdate] = React.useState(undefined);
8
- const updateBeforeSortStart = ({ index })=>{
8
+ const updateBeforeSortStart = ({ index })=>{
9
9
  setIndexToUpdate(index);
10
10
  };
11
- return React.createElement(MultipleReferenceEditor, {
11
+ return /*#__PURE__*/ React.createElement(MultipleReferenceEditor, {
12
12
  ...props,
13
13
  entityType: "Entry",
14
14
  setIndexToUpdate: setIndexToUpdate
15
- }, (childrenProps)=>React.createElement(SortableLinkList, {
15
+ }, (childrenProps)=>/*#__PURE__*/ React.createElement(SortableLinkList, {
16
16
  ...childrenProps,
17
17
  sortingStrategy: verticalListSortingStrategy,
18
18
  updateBeforeSortStart: updateBeforeSortStart
19
- }, ({ items , item , index , isDisabled , DragHandle })=>{
19
+ }, ({ items, item, index, isDisabled, DragHandle })=>{
20
20
  const lastIndex = items.length - 1;
21
- return React.createElement(FetchingWrappedEntryCard, {
21
+ return /*#__PURE__*/ React.createElement(FetchingWrappedEntryCard, {
22
22
  ...childrenProps,
23
23
  key: `${item.sys.id}-${index}`,
24
24
  index: index,
@@ -2,11 +2,11 @@ import * as React from 'react';
2
2
  import { SingleReferenceEditor } from '../common/SingleReferenceEditor';
3
3
  import { FetchingWrappedEntryCard } from './WrappedEntryCard/FetchingWrappedEntryCard';
4
4
  export function SingleEntryReferenceEditor(props) {
5
- return React.createElement(SingleReferenceEditor, {
5
+ return /*#__PURE__*/ React.createElement(SingleReferenceEditor, {
6
6
  ...props,
7
7
  entityType: "Entry"
8
- }, ({ allContentTypes , isDisabled , entityId , setValue , renderCustomCard , hasCardRemoveActions , hasCardEditActions })=>{
9
- return React.createElement(FetchingWrappedEntryCard, {
8
+ }, ({ allContentTypes, isDisabled, entityId, setValue, renderCustomCard, hasCardRemoveActions, hasCardEditActions })=>{
9
+ return /*#__PURE__*/ React.createElement(FetchingWrappedEntryCard, {
10
10
  ...props,
11
11
  allContentTypes: allContentTypes,
12
12
  isDisabled: isDisabled,
@@ -15,7 +15,10 @@ async function openEntry(sdk, entryId, options) {
15
15
  });
16
16
  slide = result.slide;
17
17
  return slide;
18
- } catch (e) {}
18
+ } catch (e) {
19
+ // we don't allow to open multiple bulk editors for performance reasons
20
+ // proceed with a default openEntry
21
+ }
19
22
  }
20
23
  const result = await sdk.navigator.openEntry(entryId, {
21
24
  slideIn: true
@@ -24,14 +27,14 @@ async function openEntry(sdk, entryId, options) {
24
27
  return slide;
25
28
  }
26
29
  export function FetchingWrappedEntryCard(props) {
27
- const { data: entry , status } = useEntity('Entry', props.entryId);
28
- const { getEntityScheduledActions } = useEntityLoader();
30
+ const { data: entry, status } = useEntity('Entry', props.entryId);
31
+ const { getEntityScheduledActions } = useEntityLoader();
29
32
  const loadEntityScheduledActions = React.useCallback(()=>getEntityScheduledActions('Entry', props.entryId), [
30
33
  getEntityScheduledActions,
31
34
  props.entryId
32
35
  ]);
33
36
  const size = props.viewType === 'link' ? 'small' : 'default';
34
- const { getEntity } = useEntityLoader();
37
+ const { getEntity } = useEntityLoader();
35
38
  const getAsset = (assetId)=>getEntity('Asset', assetId);
36
39
  const onEdit = async ()=>{
37
40
  const slide = await openEntry(props.sdk, props.entryId, {
@@ -62,12 +65,13 @@ export function FetchingWrappedEntryCard(props) {
62
65
  entity: 'Entry'
63
66
  });
64
67
  }
68
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
65
69
  }, [
66
70
  entry
67
71
  ]);
68
72
  return React.useMemo(()=>{
69
73
  if (status === 'error') {
70
- const card = React.createElement(MissingEntityCard, {
74
+ const card = /*#__PURE__*/ React.createElement(MissingEntityCard, {
71
75
  entityType: "Entry",
72
76
  isDisabled: props.isDisabled,
73
77
  onRemove: onRemoveEntry
@@ -84,7 +88,7 @@ export function FetchingWrappedEntryCard(props) {
84
88
  return card;
85
89
  }
86
90
  if (status === 'loading') {
87
- return React.createElement(EntryCard, {
91
+ return /*#__PURE__*/ React.createElement(EntryCard, {
88
92
  size: size,
89
93
  isLoading: true
90
94
  });
@@ -105,7 +109,7 @@ export function FetchingWrappedEntryCard(props) {
105
109
  onMoveBottom: props.onMoveBottom,
106
110
  isBeingDragged: props.isBeingDragged
107
111
  };
108
- const { hasCardEditActions , hasCardMoveActions , hasCardRemoveActions } = props;
112
+ const { hasCardEditActions, hasCardMoveActions, hasCardRemoveActions } = props;
109
113
  function renderDefaultCard(props) {
110
114
  const builtinCardProps = {
111
115
  ...sharedCardProps,
@@ -118,15 +122,18 @@ export function FetchingWrappedEntryCard(props) {
118
122
  entry: (props?.entity) || sharedCardProps.entity,
119
123
  entryUrl: props?.entityUrl || sharedCardProps.entityUrl
120
124
  };
121
- return React.createElement(WrappedEntryCard, builtinCardProps);
125
+ return /*#__PURE__*/ React.createElement(WrappedEntryCard, builtinCardProps);
122
126
  }
123
127
  if (props.renderCustomCard) {
128
+ // LinkActionsProps are injected higher SingleReferenceEditor/MultipleReferenceEditor
124
129
  const renderedCustomCard = props.renderCustomCard(sharedCardProps, {}, renderDefaultCard);
130
+ // Only `false` indicates to render the original card. E.g. `null` would result in no card.
125
131
  if (renderedCustomCard !== false) {
126
132
  return renderedCustomCard;
127
133
  }
128
134
  }
129
135
  return renderDefaultCard();
136
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
130
137
  }, [
131
138
  props,
132
139
  status,
@@ -6,7 +6,7 @@ import { entityHelpers, isValidImage } from '@contentful/field-editor-shared';
6
6
  import { css } from 'emotion';
7
7
  import { AssetThumbnail, MissingEntityCard, ScheduledIconWithTooltip } from '../../components';
8
8
  import { SpaceName } from '../../components/SpaceName/SpaceName';
9
- const { getEntryTitle , getEntityDescription , getEntryStatus , getEntryImage } = entityHelpers;
9
+ const { getEntryTitle, getEntityDescription, getEntryStatus, getEntryImage } = entityHelpers;
10
10
  const styles = {
11
11
  scheduleIcon: css({
12
12
  marginRight: tokens.spacing2Xs
@@ -20,7 +20,7 @@ const defaultProps = {
20
20
  };
21
21
  export function WrappedEntryCard(props) {
22
22
  const [file, setFile] = React.useState(null);
23
- const { contentType } = props;
23
+ const { contentType } = props;
24
24
  React.useEffect(()=>{
25
25
  if (props.entry) {
26
26
  getEntryImage({
@@ -43,7 +43,7 @@ export function WrappedEntryCard(props) {
43
43
  ]);
44
44
  const status = getEntryStatus(props.entry?.sys);
45
45
  if (status === 'deleted') {
46
- return React.createElement(MissingEntityCard, {
46
+ return /*#__PURE__*/ React.createElement(MissingEntityCard, {
47
47
  entityType: "Entry",
48
48
  isDisabled: props.isDisabled,
49
49
  onRemove: props.onRemove
@@ -62,7 +62,7 @@ export function WrappedEntryCard(props) {
62
62
  localeCode: props.localeCode,
63
63
  defaultLocaleCode: props.defaultLocaleCode
64
64
  });
65
- return React.createElement(EntryCard, {
65
+ return /*#__PURE__*/ React.createElement(EntryCard, {
66
66
  as: props.entryUrl ? 'a' : 'article',
67
67
  href: props.entryUrl,
68
68
  title: title,
@@ -71,54 +71,58 @@ export function WrappedEntryCard(props) {
71
71
  size: props.size,
72
72
  isSelected: props.isSelected,
73
73
  status: status,
74
- icon: props.spaceName ? React.createElement(SpaceName, {
74
+ icon: props.spaceName ? /*#__PURE__*/ React.createElement(SpaceName, {
75
75
  spaceName: props.spaceName,
76
76
  environmentName: props.entry.sys.environment.sys.id
77
- }) : React.createElement(ScheduledIconWithTooltip, {
77
+ }) : /*#__PURE__*/ React.createElement(ScheduledIconWithTooltip, {
78
78
  getEntityScheduledActions: props.getEntityScheduledActions,
79
79
  entityType: "Entry",
80
80
  entityId: props.entry.sys.id
81
- }, React.createElement(ClockIcon, {
81
+ }, /*#__PURE__*/ React.createElement(ClockIcon, {
82
82
  className: styles.scheduleIcon,
83
83
  size: "small",
84
84
  variant: "muted",
85
85
  testId: "schedule-icon"
86
86
  })),
87
- thumbnailElement: file && isValidImage(file) ? React.createElement(AssetThumbnail, {
87
+ thumbnailElement: file && isValidImage(file) ? /*#__PURE__*/ React.createElement(AssetThumbnail, {
88
88
  file: file
89
89
  }) : undefined,
90
90
  dragHandleRender: props.renderDragHandle,
91
91
  withDragHandle: !!props.renderDragHandle,
92
92
  actions: props.onEdit || props.onRemove ? [
93
- props.hasCardEditActions && props.onEdit ? React.createElement(MenuItem, {
93
+ props.hasCardEditActions && props.onEdit ? /*#__PURE__*/ React.createElement(MenuItem, {
94
94
  key: "edit",
95
95
  testId: "edit",
96
96
  onClick: ()=>{
97
97
  props.onEdit && props.onEdit();
98
98
  }
99
99
  }, "Edit") : null,
100
- props.hasCardRemoveActions && props.onRemove ? React.createElement(MenuItem, {
100
+ props.hasCardRemoveActions && props.onRemove ? /*#__PURE__*/ React.createElement(MenuItem, {
101
101
  key: "delete",
102
102
  testId: "delete",
103
103
  onClick: ()=>{
104
104
  props.onRemove && props.onRemove();
105
105
  }
106
106
  }, "Remove") : null,
107
- props.hasCardMoveActions && (props.onMoveTop || props.onMoveBottom) ? React.createElement(MenuDivider, {
107
+ props.hasCardMoveActions && (props.onMoveTop || props.onMoveBottom) ? /*#__PURE__*/ React.createElement(MenuDivider, {
108
108
  key: "divider"
109
109
  }) : null,
110
- props.hasCardMoveActions && props.onMoveTop ? React.createElement(MenuItem, {
110
+ props.hasCardMoveActions && props.onMoveTop ? /*#__PURE__*/ React.createElement(MenuItem, {
111
111
  key: "move-top",
112
112
  onClick: ()=>props.onMoveTop && props.onMoveTop(),
113
113
  testId: "move-top"
114
114
  }, "Move to top") : null,
115
- props.hasCardMoveActions && props.onMoveBottom ? React.createElement(MenuItem, {
115
+ props.hasCardMoveActions && props.onMoveBottom ? /*#__PURE__*/ React.createElement(MenuItem, {
116
116
  key: "move-bottom",
117
117
  onClick: ()=>props.onMoveBottom && props.onMoveBottom(),
118
118
  testId: "move-bottom"
119
119
  }, "Move to bottom") : null
120
120
  ].filter((item)=>item) : [],
121
- onClick: props.isClickable ? (e)=>{
121
+ onClick: // Providing an onClick handler messes up with some rich text
122
+ // features e.g. pressing ENTER on a card to add a new paragraph
123
+ // underneath. It's crucial not to pass a custom handler when
124
+ // isClickable is disabled which in the case of RT it's.
125
+ props.isClickable ? (e)=>{
122
126
  e.preventDefault();
123
127
  if (props.onClick) return props.onClick(e);
124
128
  props.onEdit && props.onEdit();
package/dist/esm/index.js CHANGED
@@ -3,5 +3,6 @@ export { SingleEntryReferenceEditor, MultipleEntryReferenceEditor, WrappedEntryC
3
3
  export { SingleMediaEditor, MultipleMediaEditor, WrappedAssetCard } from './assets';
4
4
  export { SortableLinkList } from './common/SortableLinkList';
5
5
  export { EntityProvider, useEntityLoader, useEntity, useResource } from './common/EntityStore';
6
+ export { SharedQueryClientProvider as EntityCacheProvider } from './common/queryClient';
6
7
  export { SingleResourceReferenceEditor, MultipleResourceReferenceEditor } from './resources';
7
8
  export * from './types';
@@ -1,8 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import { WrappedEntryCard } from '../../entries';
3
+ // assets are not shown for small cards (which we hardcode currently)
3
4
  const resolveAsset = ()=>Promise.resolve();
5
+ // we don't want to show scheduled actions for resources
4
6
  const resolveScheduledActions = ()=>Promise.resolve([]);
5
- export function ContentfulEntryCard({ info , isDisabled , renderDragHandle , onRemove , onMoveTop , onMoveBottom , getEntryRouteHref }) {
7
+ export function ContentfulEntryCard({ info, isDisabled, renderDragHandle, onRemove, onMoveTop, onMoveBottom, getEntryRouteHref }) {
6
8
  const resourceSys = info.resource.sys;
7
9
  const spaceId = resourceSys.space.sys.id;
8
10
  const environmentId = resourceSys.environment.sys.id;
@@ -12,14 +14,19 @@ export function ContentfulEntryCard({ info , isDisabled , renderDragHandle , onR
12
14
  environmentId,
13
15
  entryId
14
16
  });
17
+ // TODO: move this into `sdk.navigator.openEntry()`, note that it's signature only include the entry id (not a space or environment)
15
18
  const openEntryDetail = ()=>{
16
19
  window.open(resourceHref, '_blank', 'noopener,noreferrer');
17
20
  };
18
- return React.createElement(WrappedEntryCard, {
21
+ return /*#__PURE__*/ React.createElement(WrappedEntryCard, {
19
22
  entry: info.resource,
20
23
  isDisabled: isDisabled,
21
24
  hasCardEditActions: false,
22
25
  contentType: info.contentType,
26
+ // we use the default locale from the space the entry belongs to
27
+ // as we assume this gives a more consistent behaviour.
28
+ // locales will inevitably differ from space to space, so it's likely
29
+ // that the current locale does not exist in the "remote" space
23
30
  localeCode: info.defaultLocaleCode,
24
31
  defaultLocaleCode: info.defaultLocaleCode,
25
32
  size: "small",
@@ -5,28 +5,29 @@ import { useResource } from '../../common/EntityStore';
5
5
  import { ResourceEntityErrorCard } from '../../components';
6
6
  import { ContentfulEntryCard } from './ContentfulEntryCard';
7
7
  function ResourceCardSkeleton() {
8
- return React.createElement(EntryCard, {
8
+ return /*#__PURE__*/ React.createElement(EntryCard, {
9
9
  size: "small",
10
10
  isLoading: true
11
11
  });
12
12
  }
13
13
  function ExistingResourceCard(props) {
14
- const { resourceLink , inView , index =0 } = props;
14
+ const { resourceLink, inView, index = 0 } = props;
15
15
  const resourceOptions = {
16
16
  priority: index * -1,
17
17
  enabled: inView
18
18
  };
19
- const { data , error } = useResource(resourceLink.sys.linkType, resourceLink.sys.urn, resourceOptions);
19
+ const { data, error } = useResource(resourceLink.sys.linkType, resourceLink.sys.urn, resourceOptions);
20
20
  if (!data && !error) {
21
- return React.createElement(ResourceCardSkeleton, null);
21
+ return /*#__PURE__*/ React.createElement(ResourceCardSkeleton, null);
22
22
  }
23
23
  if (data) {
24
- return React.createElement(ContentfulEntryCard, {
24
+ // @ts-expect-error
25
+ return /*#__PURE__*/ React.createElement(ContentfulEntryCard, {
25
26
  info: data,
26
27
  ...props
27
28
  });
28
29
  }
29
- return React.createElement(ResourceEntityErrorCard, {
30
+ return /*#__PURE__*/ React.createElement(ResourceEntityErrorCard, {
30
31
  linkType: resourceLink.sys.linkType,
31
32
  error: error,
32
33
  isDisabled: props.isDisabled,
@@ -37,20 +38,21 @@ function ResourceCardWrapper(props) {
37
38
  if (!props.resourceLink) {
38
39
  return null;
39
40
  }
40
- return React.createElement(ExistingResourceCard, {
41
+ return /*#__PURE__*/ React.createElement(ExistingResourceCard, {
41
42
  ...props,
42
43
  resourceLink: props.resourceLink,
43
44
  getEntryRouteHref: props.getEntryRouteHref
44
45
  });
45
46
  }
46
47
  export function ResourceCard(props) {
47
- const { ref , inView } = useInView({
48
+ const { ref, inView } = useInView({
48
49
  triggerOnce: true,
49
50
  rootMargin: '300px 0px 0px 300px'
50
51
  });
51
- return React.createElement("div", {
52
+ // Forma does not offer us to pass refs, so we need an additional wrapper here
53
+ return /*#__PURE__*/ React.createElement("div", {
52
54
  ref: ref
53
- }, React.createElement(ResourceCardWrapper, {
55
+ }, /*#__PURE__*/ React.createElement(ResourceCardWrapper, {
54
56
  ...props,
55
57
  inView: inView
56
58
  }));
@@ -14,6 +14,7 @@ configure({
14
14
  jest.mock('react-intersection-observer', ()=>({
15
15
  useInView: jest.fn().mockReturnValue({})
16
16
  }));
17
+ // explicit master
17
18
  const resolvableEntryUrn = 'crn:contentful:::content:spaces/space-id/entries/linked-entry-urn';
18
19
  const resolvableEntryUrnWithExplicitMaster = 'crn:contentful:::content:spaces/space-id/environments/master/entries/linked-entry-urn';
19
20
  const resolvableEntryUrnWithAnotherEnvironment = 'crn:contentful:::content:spaces/space-id/environments/my-test-environment/entries/linked-entry-urn';
@@ -27,7 +28,7 @@ const sdk = {
27
28
  get: jest.fn().mockReturnValue(publishedCT)
28
29
  },
29
30
  Entry: {
30
- get: jest.fn().mockImplementation(({ spaceId , environmentId , entryId })=>{
31
+ get: jest.fn().mockImplementation(({ spaceId, environmentId, entryId })=>{
31
32
  if (spaceId === 'space-id' && environmentId === 'master' && entryId === 'linked-entry-urn') {
32
33
  return Promise.resolve(publishedEntry);
33
34
  }
@@ -66,10 +67,10 @@ const sdk = {
66
67
  environment: 'environment-id'
67
68
  }
68
69
  };
69
- function renderResourceCard({ linkType ='Contentful:Entry' , entryUrn =resolvableEntryUrn } = {}) {
70
- return render(React.createElement(EntityProvider, {
70
+ function renderResourceCard({ linkType = 'Contentful:Entry', entryUrn = resolvableEntryUrn } = {}) {
71
+ return render(/*#__PURE__*/ React.createElement(EntityProvider, {
71
72
  sdk: sdk
72
- }, React.createElement(ResourceCard, {
73
+ }, /*#__PURE__*/ React.createElement(ResourceCard, {
73
74
  isDisabled: false,
74
75
  getEntryRouteHref: ()=>'',
75
76
  resourceLink: {
@@ -83,7 +84,7 @@ function renderResourceCard({ linkType ='Contentful:Entry' , entryUrn =resolvabl
83
84
  }
84
85
  describe('ResourceCard', ()=>{
85
86
  it('renders entry card with implicit master crn', async ()=>{
86
- const { getByTestId , getByText } = renderResourceCard();
87
+ const { getByTestId, getByText } = renderResourceCard();
87
88
  const tooltipContent = `Space: ${space.name} (Env.: ${publishedEntry.sys.environment.sys.id})`;
88
89
  await waitFor(()=>expect(getByTestId('cf-ui-entry-card')).toBeDefined());
89
90
  expect(getByText(publishedEntry.fields.exField['en-US'])).toBeDefined();
@@ -92,7 +93,7 @@ describe('ResourceCard', ()=>{
92
93
  await waitFor(()=>expect(getByText(tooltipContent)).toBeDefined());
93
94
  });
94
95
  it('renders entry card with explicit master crn', async ()=>{
95
- const { getByTestId , getByText } = renderResourceCard({
96
+ const { getByTestId, getByText } = renderResourceCard({
96
97
  entryUrn: resolvableEntryUrnWithExplicitMaster
97
98
  });
98
99
  const tooltipContent = `Space: ${space.name} (Env.: ${publishedEntry.sys.environment.sys.id})`;
@@ -103,7 +104,7 @@ describe('ResourceCard', ()=>{
103
104
  await waitFor(()=>expect(getByText(tooltipContent)).toBeDefined());
104
105
  });
105
106
  it('renders entry card with a non master environment', async ()=>{
106
- const { getByTestId , getByText } = renderResourceCard({
107
+ const { getByTestId, getByText } = renderResourceCard({
107
108
  entryUrn: resolvableEntryUrnWithAnotherEnvironment
108
109
  });
109
110
  await waitFor(()=>expect(getByTestId('cf-ui-entry-card')).toBeDefined());
@@ -114,23 +115,23 @@ describe('ResourceCard', ()=>{
114
115
  await waitFor(()=>expect(getByText(tooltipContent)).toBeDefined());
115
116
  });
116
117
  it('renders skeleton when no data is provided', ()=>{
117
- const { getByTestId } = renderResourceCard();
118
+ const { getByTestId } = renderResourceCard();
118
119
  expect(getByTestId('cf-ui-skeleton-form')).toBeDefined();
119
120
  });
120
121
  it('renders unsupported entity card when unsupported link is passed', async ()=>{
121
- const { getByText } = renderResourceCard({
122
+ const { getByText } = renderResourceCard({
122
123
  linkType: 'Contentful:UnsupportedLink'
123
124
  });
124
125
  await waitFor(()=>expect(getByText('Resource type Contentful:UnsupportedLink is currently not supported')).toBeDefined());
125
126
  });
126
127
  it('renders missing entity card when unknown error is returned', async ()=>{
127
- const { getByTestId } = renderResourceCard({
128
+ const { getByTestId } = renderResourceCard({
128
129
  entryUrn: unknownEntryUrn
129
130
  });
130
131
  await waitFor(()=>expect(getByTestId('cf-ui-missing-entry-card')).toBeDefined());
131
132
  });
132
133
  it('renders missing entity card when crn is invalid', async ()=>{
133
- const { getByTestId } = renderResourceCard({
134
+ const { getByTestId } = renderResourceCard({
134
135
  entryUrn: ''
135
136
  });
136
137
  await waitFor(()=>expect(getByTestId('cf-ui-missing-entry-card')).toBeDefined());