@contentful/field-editor-reference 5.9.0 → 5.11.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 (199) hide show
  1. package/dist/cjs/__fixtures__/FakeSdk.js +183 -0
  2. package/dist/cjs/__fixtures__/asset/index.js +37 -0
  3. package/dist/cjs/__fixtures__/content-type/index.js +16 -0
  4. package/dist/cjs/__fixtures__/entry/index.js +33 -0
  5. package/dist/cjs/__fixtures__/fixtures.js +71 -0
  6. package/dist/cjs/__fixtures__/locale/index.js +40 -0
  7. package/dist/cjs/__fixtures__/space/index.js +16 -0
  8. package/dist/cjs/assets/MultipleMediaEditor.js +86 -0
  9. package/dist/cjs/assets/SingleMediaEditor.js +69 -0
  10. package/dist/cjs/assets/WrappedAssetCard/AssetCardActions.js +125 -0
  11. package/dist/cjs/assets/WrappedAssetCard/FetchingWrappedAssetCard.js +171 -0
  12. package/dist/cjs/assets/WrappedAssetCard/WrappedAssetCard.js +159 -0
  13. package/dist/cjs/assets/WrappedAssetCard/WrappedAssetLink.js +130 -0
  14. package/dist/cjs/assets/index.js +24 -0
  15. package/dist/cjs/common/EntityStore.js +420 -0
  16. package/dist/cjs/common/MultipleReferenceEditor.js +164 -0
  17. package/dist/cjs/common/ReferenceEditor.js +74 -0
  18. package/dist/cjs/common/SingleReferenceEditor.js +118 -0
  19. package/dist/cjs/common/SortableLinkList.js +95 -0
  20. package/dist/cjs/common/customCardTypes.js +44 -0
  21. package/dist/cjs/common/useAccessApi.js +19 -0
  22. package/dist/cjs/common/useContentTypePermissions.js +54 -0
  23. package/dist/cjs/common/useEditorPermissions.js +77 -0
  24. package/dist/cjs/common/useEditorPermissions.spec.js +205 -0
  25. package/dist/cjs/components/AssetThumbnail/AssetThumbnail.js +62 -0
  26. package/dist/cjs/components/CreateEntryLinkButton/CreateEntryLinkButton.js +102 -0
  27. package/dist/cjs/components/CreateEntryLinkButton/CreateEntryLinkButton.spec.js +254 -0
  28. package/dist/cjs/components/CreateEntryLinkButton/CreateEntryMenuTrigger.js +199 -0
  29. package/dist/cjs/components/CreateEntryLinkButton/CreateEntryMenuTrigger.spec.js +190 -0
  30. package/dist/cjs/components/CreateEntryLinkButton/useGlobalMouseUp.js +19 -0
  31. package/dist/cjs/components/LinkActions/CombinedLinkActions.js +167 -0
  32. package/dist/cjs/components/LinkActions/LinkActions.js +123 -0
  33. package/dist/cjs/components/LinkActions/LinkEntityActions.js +186 -0
  34. package/dist/cjs/components/LinkActions/NoLinkPermissionsInfo.js +54 -0
  35. package/dist/cjs/components/LinkActions/helpers.js +78 -0
  36. package/dist/cjs/components/LinkActions/redesignStyles.js +44 -0
  37. package/dist/cjs/components/LinkActions/styles.js +33 -0
  38. package/dist/cjs/components/MissingEntityCard/MissingEntityCard.js +75 -0
  39. package/dist/cjs/components/MissingEntityCard/styles.js +29 -0
  40. package/dist/cjs/components/ScheduledIconWithTooltip/ScheduleTooltip.js +75 -0
  41. package/dist/cjs/components/ScheduledIconWithTooltip/ScheduledIconWithTooltip.js +81 -0
  42. package/dist/cjs/components/ScheduledIconWithTooltip/formatDateAndTime.js +45 -0
  43. package/dist/cjs/components/SpaceName/SpaceName.js +91 -0
  44. package/dist/cjs/components/index.js +44 -0
  45. package/dist/cjs/entries/MultipleEntryReferenceEditor.js +86 -0
  46. package/dist/cjs/entries/SingleEntryReferenceEditor.js +74 -0
  47. package/dist/cjs/entries/WrappedEntryCard/FetchingWrappedEntryCard.js +189 -0
  48. package/dist/cjs/entries/WrappedEntryCard/WrappedEntryCard.js +181 -0
  49. package/dist/cjs/entries/index.js +24 -0
  50. package/dist/cjs/index.js +92 -0
  51. package/dist/cjs/resources/Cards/ContentfulEntryCard.js +87 -0
  52. package/dist/cjs/resources/Cards/ResourceCard.js +111 -0
  53. package/dist/cjs/resources/Cards/UnsupportedEntityCard.js +64 -0
  54. package/dist/cjs/resources/MultipleResourceReferenceEditor.js +157 -0
  55. package/dist/cjs/resources/MultipleResourceReferenceEditor.spec.js +297 -0
  56. package/dist/cjs/resources/SingleResourceReferenceEditor.js +87 -0
  57. package/dist/cjs/resources/SingleResourceReferenceEditor.spec.js +161 -0
  58. package/dist/cjs/resources/index.js +19 -0
  59. package/dist/cjs/resources/testHelpers/resourceEditorHelpers.js +121 -0
  60. package/dist/cjs/resources/useResourceLinkActions.js +88 -0
  61. package/dist/cjs/types.js +22 -0
  62. package/dist/cjs/utils/fromFieldValidations.js +54 -0
  63. package/dist/esm/__fixtures__/FakeSdk.js +173 -0
  64. package/dist/esm/__fixtures__/asset/index.js +6 -0
  65. package/dist/esm/__fixtures__/content-type/index.js +2 -0
  66. package/dist/esm/__fixtures__/entry/index.js +5 -0
  67. package/dist/esm/__fixtures__/fixtures.js +6 -0
  68. package/dist/esm/__fixtures__/locale/index.js +15 -0
  69. package/dist/esm/__fixtures__/space/index.js +2 -0
  70. package/dist/esm/assets/MultipleMediaEditor.js +37 -0
  71. package/dist/esm/assets/SingleMediaEditor.js +20 -0
  72. package/dist/esm/assets/WrappedAssetCard/AssetCardActions.js +63 -0
  73. package/dist/esm/assets/WrappedAssetCard/FetchingWrappedAssetCard.js +122 -0
  74. package/dist/esm/assets/WrappedAssetCard/WrappedAssetCard.js +105 -0
  75. package/dist/esm/assets/WrappedAssetCard/WrappedAssetLink.js +76 -0
  76. package/dist/esm/assets/index.js +3 -0
  77. package/dist/esm/common/EntityStore.js +347 -0
  78. package/dist/esm/common/MultipleReferenceEditor.js +111 -0
  79. package/dist/esm/common/ReferenceEditor.js +20 -0
  80. package/dist/esm/common/SingleReferenceEditor.js +70 -0
  81. package/dist/esm/common/SortableLinkList.js +41 -0
  82. package/dist/esm/common/customCardTypes.js +1 -0
  83. package/dist/esm/common/useAccessApi.js +9 -0
  84. package/dist/esm/common/useContentTypePermissions.js +44 -0
  85. package/dist/esm/common/useEditorPermissions.js +67 -0
  86. package/dist/esm/common/useEditorPermissions.spec.js +201 -0
  87. package/dist/esm/components/AssetThumbnail/AssetThumbnail.js +13 -0
  88. package/dist/esm/components/CreateEntryLinkButton/CreateEntryLinkButton.js +48 -0
  89. package/dist/esm/components/CreateEntryLinkButton/CreateEntryLinkButton.spec.js +206 -0
  90. package/dist/esm/components/CreateEntryLinkButton/CreateEntryMenuTrigger.js +145 -0
  91. package/dist/esm/components/CreateEntryLinkButton/CreateEntryMenuTrigger.spec.js +142 -0
  92. package/dist/esm/components/CreateEntryLinkButton/useGlobalMouseUp.js +9 -0
  93. package/dist/esm/components/LinkActions/CombinedLinkActions.js +118 -0
  94. package/dist/esm/components/LinkActions/LinkActions.js +66 -0
  95. package/dist/esm/components/LinkActions/LinkEntityActions.js +127 -0
  96. package/dist/esm/components/LinkActions/NoLinkPermissionsInfo.js +5 -0
  97. package/dist/esm/components/LinkActions/helpers.js +57 -0
  98. package/dist/esm/components/LinkActions/redesignStyles.js +18 -0
  99. package/dist/esm/components/LinkActions/styles.js +10 -0
  100. package/dist/esm/components/MissingEntityCard/MissingEntityCard.js +26 -0
  101. package/dist/esm/components/MissingEntityCard/styles.js +11 -0
  102. package/dist/esm/components/ScheduledIconWithTooltip/ScheduleTooltip.js +18 -0
  103. package/dist/esm/components/ScheduledIconWithTooltip/ScheduledIconWithTooltip.js +32 -0
  104. package/dist/esm/components/ScheduledIconWithTooltip/formatDateAndTime.js +19 -0
  105. package/dist/esm/components/SpaceName/SpaceName.js +37 -0
  106. package/dist/esm/components/index.js +8 -0
  107. package/dist/esm/entries/MultipleEntryReferenceEditor.js +37 -0
  108. package/dist/esm/entries/SingleEntryReferenceEditor.js +25 -0
  109. package/dist/esm/entries/WrappedEntryCard/FetchingWrappedEntryCard.js +135 -0
  110. package/dist/esm/entries/WrappedEntryCard/WrappedEntryCard.js +127 -0
  111. package/dist/esm/entries/index.js +3 -0
  112. package/dist/esm/index.js +7 -0
  113. package/dist/esm/resources/Cards/ContentfulEntryCard.js +38 -0
  114. package/dist/esm/resources/Cards/ResourceCard.js +62 -0
  115. package/dist/esm/resources/Cards/UnsupportedEntityCard.js +15 -0
  116. package/dist/esm/resources/MultipleResourceReferenceEditor.js +104 -0
  117. package/dist/esm/resources/MultipleResourceReferenceEditor.spec.js +254 -0
  118. package/dist/esm/resources/SingleResourceReferenceEditor.js +33 -0
  119. package/dist/esm/resources/SingleResourceReferenceEditor.spec.js +118 -0
  120. package/dist/esm/resources/index.js +2 -0
  121. package/dist/esm/resources/testHelpers/resourceEditorHelpers.js +103 -0
  122. package/dist/esm/resources/useResourceLinkActions.js +78 -0
  123. package/dist/esm/types.js +1 -0
  124. package/dist/esm/utils/fromFieldValidations.js +39 -0
  125. package/dist/{__fixtures__ → types/__fixtures__}/FakeSdk.d.ts +8 -8
  126. package/dist/{__fixtures__ → types/__fixtures__}/asset/index.d.ts +6 -6
  127. package/dist/{__fixtures__ → types/__fixtures__}/content-type/index.d.ts +2 -2
  128. package/dist/{__fixtures__ → types/__fixtures__}/entry/index.d.ts +5 -5
  129. package/dist/{__fixtures__ → types/__fixtures__}/fixtures.d.ts +6 -6
  130. package/dist/{__fixtures__ → types/__fixtures__}/locale/index.d.ts +42 -42
  131. package/dist/{__fixtures__ → types/__fixtures__}/space/index.d.ts +2 -2
  132. package/dist/{assets → types/assets}/MultipleMediaEditor.d.ts +10 -10
  133. package/dist/types/assets/SingleMediaEditor.d.ts +10 -0
  134. package/dist/{assets → types/assets}/WrappedAssetCard/AssetCardActions.d.ts +11 -11
  135. package/dist/{assets → types/assets}/WrappedAssetCard/FetchingWrappedAssetCard.d.ts +17 -17
  136. package/dist/{assets → types/assets}/WrappedAssetCard/WrappedAssetCard.d.ts +24 -24
  137. package/dist/{assets → types/assets}/WrappedAssetCard/WrappedAssetLink.d.ts +16 -16
  138. package/dist/{assets → types/assets}/index.d.ts +3 -3
  139. package/dist/{common → types/common}/EntityStore.d.ts +62 -62
  140. package/dist/{common → types/common}/MultipleReferenceEditor.d.ts +25 -25
  141. package/dist/{common → types/common}/ReferenceEditor.d.ts +46 -46
  142. package/dist/{common → types/common}/SingleReferenceEditor.d.ts +24 -24
  143. package/dist/{common → types/common}/SortableLinkList.d.ts +19 -19
  144. package/dist/{common → types/common}/customCardTypes.d.ts +29 -29
  145. package/dist/types/common/useAccessApi.d.ts +16 -0
  146. package/dist/{common → types/common}/useContentTypePermissions.d.ts +17 -17
  147. package/dist/{common → types/common}/useEditorPermissions.d.ts +17 -17
  148. package/dist/types/common/useEditorPermissions.spec.d.ts +1 -0
  149. package/dist/{components → types/components}/AssetThumbnail/AssetThumbnail.d.ts +7 -7
  150. package/dist/{components → types/components}/CreateEntryLinkButton/CreateEntryLinkButton.d.ts +19 -19
  151. package/dist/types/components/CreateEntryLinkButton/CreateEntryLinkButton.spec.d.ts +1 -0
  152. package/dist/{components → types/components}/CreateEntryLinkButton/CreateEntryMenuTrigger.d.ts +31 -31
  153. package/dist/types/components/CreateEntryLinkButton/CreateEntryMenuTrigger.spec.d.ts +1 -0
  154. package/dist/{components → types/components}/CreateEntryLinkButton/useGlobalMouseUp.d.ts +1 -1
  155. package/dist/{components → types/components}/LinkActions/CombinedLinkActions.d.ts +10 -10
  156. package/dist/{components → types/components}/LinkActions/LinkActions.d.ts +26 -26
  157. package/dist/{components → types/components}/LinkActions/LinkEntityActions.d.ts +24 -24
  158. package/dist/types/components/LinkActions/NoLinkPermissionsInfo.d.ts +2 -0
  159. package/dist/{components → types/components}/LinkActions/helpers.d.ts +26 -26
  160. package/dist/{components → types/components}/LinkActions/redesignStyles.d.ts +3 -3
  161. package/dist/{components → types/components}/LinkActions/styles.d.ts +2 -2
  162. package/dist/{components → types/components}/MissingEntityCard/MissingEntityCard.d.ts +8 -8
  163. package/dist/{components → types/components}/MissingEntityCard/styles.d.ts +2 -2
  164. package/dist/{components → types/components}/ScheduledIconWithTooltip/ScheduleTooltip.d.ts +11 -11
  165. package/dist/{components → types/components}/ScheduledIconWithTooltip/ScheduledIconWithTooltip.d.ts +10 -10
  166. package/dist/{components → types/components}/ScheduledIconWithTooltip/formatDateAndTime.d.ts +15 -15
  167. package/dist/types/components/SpaceName/SpaceName.d.ts +6 -0
  168. package/dist/{components → types/components}/index.d.ts +9 -9
  169. package/dist/{entries → types/entries}/MultipleEntryReferenceEditor.d.ts +3 -3
  170. package/dist/{entries → types/entries}/SingleEntryReferenceEditor.d.ts +8 -8
  171. package/dist/{entries → types/entries}/WrappedEntryCard/FetchingWrappedEntryCard.d.ts +18 -18
  172. package/dist/{entries → types/entries}/WrappedEntryCard/WrappedEntryCard.d.ts +35 -35
  173. package/dist/{entries → types/entries}/index.d.ts +3 -3
  174. package/dist/{index.d.ts → types/index.d.ts} +10 -8
  175. package/dist/{resources → types/resources}/Cards/ContentfulEntryCard.d.ts +21 -21
  176. package/dist/{resources → types/resources}/Cards/ResourceCard.d.ts +12 -12
  177. package/dist/{resources → types/resources}/Cards/UnsupportedEntityCard.d.ts +4 -4
  178. package/dist/{resources → types/resources}/MultipleResourceReferenceEditor.d.ts +7 -7
  179. package/dist/types/resources/MultipleResourceReferenceEditor.spec.d.ts +1 -0
  180. package/dist/{resources → types/resources}/SingleResourceReferenceEditor.d.ts +7 -7
  181. package/dist/types/resources/SingleResourceReferenceEditor.spec.d.ts +1 -0
  182. package/dist/{resources → types/resources}/index.d.ts +2 -2
  183. package/dist/{resources → types/resources}/testHelpers/resourceEditorHelpers.d.ts +50 -50
  184. package/dist/{resources → types/resources}/useResourceLinkActions.d.ts +7 -7
  185. package/dist/{types.d.ts → types/types.d.ts} +104 -104
  186. package/dist/{utils → types/utils}/fromFieldValidations.d.ts +21 -21
  187. package/package.json +25 -11
  188. package/CHANGELOG.md +0 -860
  189. package/dist/assets/SingleMediaEditor.d.ts +0 -10
  190. package/dist/common/useAccessApi.d.ts +0 -16
  191. package/dist/components/LinkActions/NoLinkPermissionsInfo.d.ts +0 -2
  192. package/dist/components/SpaceName/SpaceName.d.ts +0 -6
  193. package/dist/field-editor-reference.cjs.development.js +0 -2753
  194. package/dist/field-editor-reference.cjs.development.js.map +0 -1
  195. package/dist/field-editor-reference.cjs.production.min.js +0 -2
  196. package/dist/field-editor-reference.cjs.production.min.js.map +0 -1
  197. package/dist/field-editor-reference.esm.js +0 -2727
  198. package/dist/field-editor-reference.esm.js.map +0 -1
  199. package/dist/index.js +0 -8
@@ -1,2753 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
-
7
- var React = require('react');
8
- var React__default = _interopDefault(React);
9
- var f36Components = require('@contentful/f36-components');
10
- var f36Icons = require('@contentful/f36-icons');
11
- var tokens = _interopDefault(require('@contentful/f36-tokens'));
12
- var emotion = require('emotion');
13
- var get = _interopDefault(require('lodash/get'));
14
- var moment = _interopDefault(require('moment'));
15
- var fieldEditorShared = require('@contentful/field-editor-shared');
16
- var deepEqual = _interopDefault(require('deep-equal'));
17
- var reactQuery = require('@tanstack/react-query');
18
- var constate = _interopDefault(require('constate'));
19
- var contentfulManagement = require('contentful-management');
20
- var PQueue = _interopDefault(require('p-queue'));
21
- var isNumber = _interopDefault(require('lodash/isNumber'));
22
- var arrayMove = _interopDefault(require('array-move'));
23
- var reactSortableHoc = require('react-sortable-hoc');
24
- var mimetype = _interopDefault(require('@contentful/mimetype'));
25
- var reactIntersectionObserver = require('react-intersection-observer');
26
-
27
- /* eslint-disable @typescript-eslint/no-explicit-any */
28
- const MAX_ITEMS_WITHOUT_SEARCH = 5;
29
- const menuPlacementMap = {
30
- 'bottom-left': 'bottom-start',
31
- 'bottom-right': 'bottom-end'
32
- };
33
- const styles = {
34
- wrapper: /*#__PURE__*/emotion.css({
35
- position: 'relative'
36
- }),
37
- inputWrapper: /*#__PURE__*/emotion.css({
38
- position: 'relative',
39
- padding: `0 ${tokens.spacing2Xs}`
40
- }),
41
- searchInput: /*#__PURE__*/emotion.css({
42
- paddingRight: tokens.spacingXl,
43
- textOverflow: 'ellipsis'
44
- }),
45
- searchIcon: /*#__PURE__*/emotion.css({
46
- position: 'absolute',
47
- right: tokens.spacingM,
48
- top: tokens.spacingS,
49
- zIndex: /*#__PURE__*/Number(tokens.zIndexDefault),
50
- fill: tokens.gray600
51
- }),
52
- separator: /*#__PURE__*/emotion.css({
53
- background: tokens.gray200,
54
- margin: '10px 0'
55
- }),
56
- dropdownList: /*#__PURE__*/emotion.css({
57
- borderColor: tokens.gray200
58
- })
59
- };
60
- const CreateEntryMenuTrigger = ({
61
- contentTypes,
62
- suggestedContentTypeId,
63
- contentTypesLabel,
64
- onSelect,
65
- testId,
66
- dropdownSettings = {
67
- position: 'bottom-left'
68
- },
69
- customDropdownItems,
70
- children
71
- }) => {
72
- const [isOpen, setOpen] = React.useState(false);
73
- const [isSelecting, setSelecting] = React.useState(false);
74
- const [searchInput, setSearchInput] = React.useState('');
75
- const wrapper = React.useRef(null);
76
- const textField = React.useRef(null);
77
- const menuListRef = React.useRef(null);
78
- /*
79
- By default, dropdown wraps it's content, so it's width = the width of the widest item
80
- During search, menu items change, and so the widest menu item can change
81
- This leads to menu always changing it's width
82
- To prevent this, we get the width of the menu item after the first mount of a dropdown (when all the content is displayed)
83
- And hardcode it through the class name. This way we ensure that even during search the menu will keep that max width
84
- That it had on initial mount and that fits any menu item in has
85
- */
86
-
87
- const [dropdownWidth, setDropdownWidth] = React.useState();
88
- const hasDropdown = contentTypes.length > 1 || !!customDropdownItems;
89
-
90
- const closeMenu = () => setOpen(false);
91
-
92
- React.useEffect(() => {
93
- if (isOpen) {
94
- setTimeout(() => {
95
- var _textField$current, _textField$current$qu;
96
-
97
- (_textField$current = textField.current) == null ? void 0 : (_textField$current$qu = _textField$current.querySelector('input')) == null ? void 0 : _textField$current$qu.focus({
98
- preventScroll: true
99
- });
100
- }, 200);
101
- }
102
- }, [isOpen]);
103
- React.useEffect(() => {
104
- if (isOpen && !dropdownWidth) {
105
- var _menuListRef$current;
106
-
107
- setDropdownWidth((_menuListRef$current = menuListRef.current) == null ? void 0 : _menuListRef$current.clientWidth);
108
- }
109
- }, [isOpen, dropdownWidth]);
110
-
111
- const handleSelect = item => {
112
- closeMenu();
113
- const res = onSelect(item.sys.id); // TODO: Convert to controllable component.
114
-
115
- if (res && typeof res.then === 'function') {
116
- setSelecting(true);
117
- res.then(() => setSelecting(false), () => setSelecting(false));
118
- }
119
- };
120
-
121
- const handleMenuOpen = () => {
122
- if (hasDropdown) {
123
- setOpen(true);
124
- } else {
125
- handleSelect(contentTypes[0]);
126
- }
127
- };
128
-
129
- React.useEffect(() => {
130
- if (!isOpen) {
131
- setSearchInput('');
132
- }
133
- }, [isOpen]);
134
-
135
- const renderSearchResultsCount = resultsLength => resultsLength ? React__default.createElement(f36Components.Menu.SectionTitle, {
136
- testId: "add-entru-menu-search-results"
137
- }, resultsLength, " result", resultsLength > 1 ? 's' : '') : null;
138
-
139
- const isSearchable = contentTypes.length > MAX_ITEMS_WITHOUT_SEARCH;
140
- const maxDropdownHeight = suggestedContentTypeId ? 300 : 250;
141
- const suggestedContentType = contentTypes.find(ct => ct.sys.id === suggestedContentTypeId);
142
- const filteredContentTypes = contentTypes.filter(ct => !searchInput || get(ct, 'name', 'Untitled').toLowerCase().includes(searchInput.toLowerCase()));
143
- return React__default.createElement("span", {
144
- className: styles.wrapper,
145
- ref: wrapper,
146
- "data-test-id": testId
147
- }, React__default.createElement(f36Components.Menu, {
148
- placement: menuPlacementMap[dropdownSettings.position],
149
- isAutoalignmentEnabled: dropdownSettings.isAutoalignmentEnabled,
150
- isOpen: isOpen,
151
- onClose: closeMenu,
152
- onOpen: handleMenuOpen
153
- }, React__default.createElement(f36Components.Menu.Trigger, null, children({
154
- isOpen,
155
- isSelecting
156
- })), isOpen && React__default.createElement(f36Components.Menu.List, {
157
- className: styles.dropdownList,
158
- style: {
159
- width: dropdownWidth != undefined ? `${dropdownWidth}px` : undefined,
160
- maxHeight: `${maxDropdownHeight}px`
161
- },
162
- ref: menuListRef,
163
- testId: "add-entry-menu"
164
- }, Boolean(customDropdownItems) && React__default.createElement(React__default.Fragment, null, customDropdownItems, React__default.createElement(f36Components.Menu.Divider, null)), isSearchable && React__default.createElement(React__default.Fragment, null, React__default.createElement("div", {
165
- ref: textField,
166
- className: styles.inputWrapper
167
- }, React__default.createElement(f36Components.TextInput, {
168
- className: styles.searchInput,
169
- placeholder: "Search all content types",
170
- testId: "add-entry-menu-search",
171
- value: searchInput,
172
- onChange: e => setSearchInput(e.target.value)
173
- }), React__default.createElement(f36Icons.SearchIcon, {
174
- className: styles.searchIcon
175
- })), React__default.createElement(f36Components.Menu.Divider, null)), searchInput && renderSearchResultsCount(filteredContentTypes.length), suggestedContentType && !searchInput && React__default.createElement(React__default.Fragment, null, React__default.createElement(f36Components.Menu.SectionTitle, null, "Suggested Content Type"), React__default.createElement(f36Components.Menu.Item, {
176
- testId: "suggested",
177
- onClick: () => handleSelect(suggestedContentType)
178
- }, get(suggestedContentType, 'name')), React__default.createElement(f36Components.Menu.Divider, null)), !searchInput && React__default.createElement(f36Components.Menu.SectionTitle, null, contentTypesLabel), filteredContentTypes.length ? filteredContentTypes.map((contentType, i) => React__default.createElement(f36Components.Menu.Item, {
179
- testId: "contentType",
180
- key: `${get(contentType, 'name')}-${i}`,
181
- onClick: () => handleSelect(contentType)
182
- }, get(contentType, 'name', 'Untitled'))) : React__default.createElement(f36Components.Menu.Item, {
183
- testId: "add-entru-menu-search-results"
184
- }, "No results found"))));
185
- };
186
- CreateEntryMenuTrigger.defaultProps = {
187
- testId: 'create-entry-button-menu-trigger',
188
- contentTypesLabel: 'All Content Types'
189
- };
190
-
191
- const standardStyles = {
192
- spinnerMargin: /*#__PURE__*/emotion.css({
193
- marginRight: tokens.spacingXs
194
- }),
195
- action: undefined
196
- };
197
- const redesignStyles = { ...standardStyles,
198
- action: /*#__PURE__*/emotion.css({
199
- textDecoration: 'none',
200
- fontWeight: 'bold',
201
- maxWidth: '300px'
202
- })
203
- };
204
- const CreateEntryLinkButton = ({
205
- contentTypes,
206
- onSelect,
207
- customDropdownItems,
208
- text,
209
- testId,
210
- hasPlusIcon = false,
211
- useExperimentalStyles,
212
- suggestedContentTypeId,
213
- dropdownSettings,
214
- disabled = false
215
- }) => {
216
- contentTypes = contentTypes.sort((a, b) => a.name.localeCompare(b.name));
217
- const suggestedContentType = contentTypes.find(ct => ct.sys.id === suggestedContentTypeId);
218
- const buttonText = text || `Add ${get(suggestedContentType || (contentTypes.length === 1 ? contentTypes[0] : {}), 'name', 'entry')}`;
219
- const hasDropdown = contentTypes.length > 1 || customDropdownItems; // TODO: Introduce `icon: string` and remove `hasPlusIcon` or remove "Plus" if we keep new layout.
220
-
221
- const plusIcon = hasPlusIcon ? React__default.createElement(f36Icons.PlusIcon, null) : undefined; // TODO: Always use "New content" here if we fully switch to new layout.
222
-
223
- const contentTypesLabel = useExperimentalStyles ? 'New content' : undefined;
224
- const styles = useExperimentalStyles ? redesignStyles : standardStyles;
225
- return React__default.createElement(CreateEntryMenuTrigger, {
226
- contentTypes: contentTypes,
227
- suggestedContentTypeId: suggestedContentTypeId,
228
- contentTypesLabel: contentTypesLabel,
229
- onSelect: onSelect,
230
- testId: testId,
231
- dropdownSettings: dropdownSettings,
232
- customDropdownItems: customDropdownItems
233
- }, ({
234
- isSelecting
235
- }) => React__default.createElement(f36Components.Button, {
236
- endIcon: hasDropdown ? React__default.createElement(f36Icons.ChevronDownIcon, null) : undefined,
237
- variant: "secondary",
238
- className: styles.action,
239
- isDisabled: disabled || isSelecting,
240
- startIcon: isSelecting ? undefined : plusIcon,
241
- size: "small",
242
- testId: "create-entry-link-button",
243
- isLoading: isSelecting
244
- }, buttonText));
245
- };
246
-
247
- function NoLinkPermissionsInfo() {
248
- return React__default.createElement(f36Components.Paragraph, null, "You don't have permission to view this content or this field is not correctly configured. Contact your administrator for help.");
249
- }
250
-
251
- const container = /*#__PURE__*/emotion.css({
252
- display: 'flex',
253
- width: '100%',
254
- marginTop: tokens.spacingS
255
- });
256
- const separator = /*#__PURE__*/emotion.css({
257
- marginRight: tokens.spacingXl
258
- });
259
-
260
- const defaultEntryLabels = {
261
- createNew: props => props != null && props.contentType ? `Create new ${props.contentType} and link` : 'Create new entry and link',
262
- linkExisting: props => props != null && props.canLinkMultiple ? 'Link existing entries' : 'Link existing entry'
263
- };
264
- const defaultAssetLabels = {
265
- createNew: () => `Create new asset and link`,
266
- linkExisting: props => props != null && props.canLinkMultiple ? 'Link existing assets' : 'Link existing asset'
267
- };
268
- const testIds = {
269
- dropdown: 'linkEditor.dropdown',
270
- createAndLink: 'linkEditor.createAndLink',
271
- createAndLinkWrapper: 'create-entry-button-menu-trigger',
272
- linkExisting: 'linkEditor.linkExisting'
273
- };
274
- function LinkActions(props) {
275
- if (props.isFull) {
276
- return null; // Don't render link actions if we reached max allowed links.
277
- }
278
-
279
- const defaultLabels = props.entityType === 'Entry' ? defaultEntryLabels : defaultAssetLabels;
280
- const labels = { ...defaultLabels,
281
- ...props.actionLabels
282
- };
283
- return React.createElement("div", {
284
- className: container
285
- }, props.canCreateEntity && React.createElement(React.Fragment, null, props.entityType === 'Entry' && React.createElement(CreateEntryLinkButton, {
286
- testId: testIds.createAndLink,
287
- disabled: props.isDisabled,
288
- text: labels.createNew({
289
- contentType: props.contentTypes.length === 1 ? props.contentTypes[0].name : undefined
290
- }),
291
- contentTypes: props.contentTypes,
292
- hasPlusIcon: true,
293
- onSelect: contentTypeId => {
294
- return contentTypeId ? props.onCreate(contentTypeId, props.itemsLength) : Promise.resolve();
295
- }
296
- }), props.entityType === 'Asset' && React.createElement(f36Components.Button, {
297
- isDisabled: props.isDisabled,
298
- testId: testIds.createAndLink,
299
- onClick: () => {
300
- props.onCreate(undefined, props.itemsLength);
301
- },
302
- variant: "secondary",
303
- startIcon: React.createElement(f36Icons.PlusIcon, null),
304
- size: "small"
305
- }, labels.createNew()), React.createElement("span", {
306
- className: separator
307
- })), props.canLinkEntity && React.createElement(f36Components.Button, {
308
- isDisabled: props.isDisabled,
309
- testId: testIds.linkExisting,
310
- onClick: () => {
311
- props.onLinkExisting();
312
- },
313
- variant: "secondary",
314
- startIcon: React.createElement(f36Icons.LinkIcon, null),
315
- size: "small"
316
- }, labels.linkExisting({
317
- canLinkMultiple: props.canLinkMultiple
318
- })), !props.canCreateEntity && !props.canLinkEntity && React.createElement(NoLinkPermissionsInfo, null));
319
- }
320
-
321
- const container$1 = /*#__PURE__*/emotion.css({
322
- display: 'flex',
323
- border: `1px dashed ${tokens.gray500}`,
324
- borderRadius: tokens.borderRadiusMedium,
325
- justifyContent: 'center',
326
- padding: tokens.spacingXl
327
- });
328
- const action = /*#__PURE__*/emotion.css({
329
- textDecoration: 'none',
330
- fontWeight: 'bold'
331
- });
332
-
333
- const testIds$1 = { ...testIds,
334
- actionsWrapper: 'link-actions-menu-trigger'
335
- };
336
- /**
337
- * Alternative, experimental alternative to <LinkActions /> that is planned to
338
- * replace the current default LinkActions in reference and media editors.
339
- *
340
- * Places both actions to create and link new, as well as link existing, behind
341
- * one action dropdown and introduces new copy for action labels.
342
- */
343
-
344
- function CombinedLinkActions(props) {
345
- if (props.isFull) {
346
- return null; // Don't render link actions if we reached max allowed links.
347
- } // We don't want to render a spacious container in case there are are already
348
- // assets linked (in case of entries, always show it) as the border wouldn't be
349
- // nicely aligned with asset cards.
350
-
351
-
352
- const hideEmptyCard = props.entityType === 'Asset' && !props.isEmpty;
353
- return React.createElement("div", {
354
- className: hideEmptyCard ? '' : container$1
355
- }, !props.canCreateEntity && !props.canLinkEntity && React.createElement(NoLinkPermissionsInfo, null), props.entityType === 'Entry' && React.createElement(CombinedEntryLinkActions, { ...props
356
- }), props.entityType === 'Asset' && React.createElement(CombinedAssetLinkActions, { ...props
357
- }));
358
- }
359
-
360
- function CombinedEntryLinkActions(props) {
361
- if (props.canCreateEntity) {
362
- return React.createElement(CreateEntryLinkButton, {
363
- testId: testIds$1.actionsWrapper,
364
- disabled: props.isDisabled,
365
- text: props.combinedActionsLabel || 'Add content',
366
- contentTypes: props.contentTypes,
367
- hasPlusIcon: true,
368
- useExperimentalStyles: true,
369
- dropdownSettings: {
370
- position: 'bottom-left'
371
- },
372
- onSelect: contentTypeId => {
373
- return contentTypeId ? props.onCreate(contentTypeId) : Promise.resolve();
374
- },
375
- customDropdownItems: props.canLinkEntity ? React.createElement(f36Components.Menu.Item, {
376
- testId: testIds$1.linkExisting,
377
- onClick: () => {
378
- props.onLinkExisting();
379
- }
380
- }, "Add existing content") : undefined
381
- });
382
- } else if (props.canLinkEntity) {
383
- return React.createElement(f36Components.Button, {
384
- isDisabled: props.isDisabled,
385
- testId: testIds$1.linkExisting,
386
- className: action,
387
- onClick: () => {
388
- props.onLinkExisting();
389
- },
390
- variant: "secondary",
391
- startIcon: React.createElement(f36Icons.LinkIcon, null),
392
- size: "small"
393
- }, "Add existing content");
394
- }
395
-
396
- return null;
397
- }
398
-
399
- function CombinedAssetLinkActions(props) {
400
- const [isOpen, setOpen] = React.useState(false);
401
-
402
- if (!props.canLinkEntity || !props.canCreateEntity) {
403
- if (props.canLinkEntity) {
404
- return React.createElement(f36Components.Button, {
405
- isDisabled: props.isDisabled,
406
- testId: testIds$1.linkExisting,
407
- className: action,
408
- onClick: () => {
409
- props.onLinkExisting();
410
- },
411
- variant: "secondary",
412
- startIcon: React.createElement(f36Icons.PlusIcon, null),
413
- size: "small"
414
- }, "Add existing media");
415
- }
416
-
417
- if (props.canCreateEntity) {
418
- return React.createElement(f36Components.Button, {
419
- isDisabled: props.isDisabled,
420
- testId: testIds$1.createAndLink,
421
- className: action,
422
- onClick: () => {
423
- props.onCreate();
424
- },
425
- variant: "secondary",
426
- startIcon: React.createElement(f36Icons.PlusIcon, null),
427
- size: "small"
428
- }, "Add media");
429
- }
430
-
431
- return null;
432
- } // TODO: If we fully switch to this new layout, make a more generic `CreateEntityLinkButton`
433
- // that works without content types to cover asset use-case.
434
-
435
-
436
- return React.createElement(f36Components.Menu, {
437
- isOpen: isOpen,
438
- onClose: () => {
439
- setOpen(false);
440
- },
441
- onOpen: () => {
442
- setOpen(true);
443
- }
444
- }, React.createElement(f36Components.Menu.Trigger, null, React.createElement(f36Components.Button, {
445
- endIcon: React.createElement(f36Icons.ChevronDownIcon, null),
446
- isDisabled: props.isDisabled,
447
- testId: testIds$1.actionsWrapper,
448
- className: action,
449
- variant: "secondary",
450
- startIcon: React.createElement(f36Icons.PlusIcon, null),
451
- size: "small"
452
- }, "Add media")), isOpen && React.createElement(f36Components.Menu.List, {
453
- testId: testIds$1.dropdown
454
- }, React.createElement(f36Components.Menu.Item, {
455
- testId: testIds$1.linkExisting,
456
- onClick: () => {
457
- props.onLinkExisting();
458
- }
459
- }, "Add existing media"), React.createElement(f36Components.Menu.Item, {
460
- testId: testIds$1.createAndLink,
461
- onClick: () => {
462
- props.onCreate();
463
- }
464
- }, "Add new media")));
465
- }
466
-
467
- const card = /*#__PURE__*/emotion.css({
468
- position: 'relative'
469
- });
470
- const squareCard = /*#__PURE__*/emotion.css({
471
- display: 'flex',
472
- alignItems: 'center',
473
- width: '135px',
474
- height: '160px',
475
- textAlign: 'center'
476
- });
477
-
478
- function MissingEntityCard(props) {
479
- return React__default.createElement(f36Components.Card, {
480
- className: card,
481
- testId: "cf-ui-missing-entry-card"
482
- }, React__default.createElement(f36Components.Flex, {
483
- alignItems: "center",
484
- justifyContent: "space-between"
485
- }, React__default.createElement("div", {
486
- className: props.asSquare ? squareCard : ''
487
- }, React__default.createElement(f36Components.SectionHeading, {
488
- marginBottom: "none"
489
- }, props.entityType, " is missing or inaccessible")), !props.isDisabled && props.onRemove && React__default.createElement(f36Components.IconButton, {
490
- variant: "transparent",
491
- icon: React__default.createElement(f36Icons.CloseIcon, {
492
- variant: "muted"
493
- }),
494
- "aria-label": "Delete",
495
- onClick: () => {
496
- props.onRemove && props.onRemove();
497
- }
498
- })));
499
- }
500
-
501
- const getContentTypeIds = contentTypes => contentTypes.map(ct => ct.sys.id);
502
-
503
- async function createEntity(props) {
504
- if (props.entityType === 'Entry') {
505
- if (!props.contentTypeId) {
506
- return {};
507
- }
508
-
509
- const {
510
- entity,
511
- slide
512
- } = await props.sdk.navigator.openNewEntry(props.contentTypeId, {
513
- slideIn: true
514
- });
515
- return {
516
- entity,
517
- slide
518
- };
519
- } else {
520
- const {
521
- entity,
522
- slide
523
- } = await props.sdk.navigator.openNewAsset({
524
- slideIn: true
525
- });
526
- return {
527
- entity,
528
- slide
529
- };
530
- }
531
- }
532
- async function selectSingleEntity(props) {
533
- if (props.entityType === 'Entry') {
534
- return await props.sdk.dialogs.selectSingleEntry({
535
- locale: props.sdk.field.locale,
536
- contentTypes: getContentTypeIds(props.editorPermissions.readableContentTypes)
537
- });
538
- } else {
539
- return props.sdk.dialogs.selectSingleAsset({
540
- locale: props.sdk.field.locale,
541
- mimetypeGroups: props.editorPermissions.validations.mimetypeGroups
542
- });
543
- }
544
- }
545
- async function selectMultipleEntities(props) {
546
- var _props$editorPermissi, _props$editorPermissi2;
547
-
548
- const value = props.sdk.field.getValue();
549
- const linkCount = Array.isArray(value) ? value.length : value ? 1 : 0; // TODO: Why not always set `min: 1` by default? Does it make sense to enforce
550
- // user to select as many entities as the field's "min" requires? What if e.g.
551
- // "min" is 4 and the user wants to insert 2 entities first, then create 2 new ones?
552
-
553
- const min = Math.max((((_props$editorPermissi = props.editorPermissions.validations.numberOfLinks) == null ? void 0 : _props$editorPermissi.min) || 1) - linkCount, 1); // TODO: Consider same for max. If e.g. "max" is 4, we disable the button if the
554
- // user wants to select 5 but we show no information why the button is disabled.
555
-
556
- const max = (((_props$editorPermissi2 = props.editorPermissions.validations.numberOfLinks) == null ? void 0 : _props$editorPermissi2.max) || +Infinity) - linkCount;
557
-
558
- if (props.entityType === 'Entry') {
559
- return await props.sdk.dialogs.selectMultipleEntries({
560
- locale: props.sdk.field.locale,
561
- contentTypes: getContentTypeIds(props.editorPermissions.readableContentTypes),
562
- min,
563
- max
564
- });
565
- } else {
566
- return props.sdk.dialogs.selectMultipleAssets({
567
- locale: props.sdk.field.locale,
568
- mimetypeGroups: props.editorPermissions.validations.mimetypeGroups,
569
- min,
570
- max
571
- });
572
- }
573
- }
574
-
575
- function useLinkActionsProps(props) {
576
- var _editorPermissions$va;
577
-
578
- const {
579
- sdk,
580
- editorPermissions,
581
- entityType,
582
- canLinkMultiple,
583
- isDisabled,
584
- actionLabels,
585
- itemsLength
586
- } = props;
587
- const maxLinksCount = (_editorPermissions$va = editorPermissions.validations.numberOfLinks) == null ? void 0 : _editorPermissions$va.max;
588
- const value = sdk.field.getValue();
589
- const linkCount = Array.isArray(value) ? value.length : value ? 1 : 0;
590
- const isFull = !!maxLinksCount && maxLinksCount <= linkCount;
591
- const isEmpty = linkCount === 0;
592
- const onCreated = React.useCallback((entity, index = itemsLength, slide) => {
593
- props.onCreate(entity.sys.id, index);
594
- props.onAction && props.onAction({
595
- type: 'create_and_link',
596
- entity: entityType,
597
- entityData: entity,
598
- slide,
599
- index
600
- });
601
- }, // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
602
- [entityType, props.onCreate, props.onAction]);
603
- const onLinkedExisting = React.useCallback((entities, index = itemsLength) => {
604
- props.onLink(entities.map(item => item.sys.id), index);
605
- entities.forEach((entity, i) => {
606
- props.onAction && props.onAction({
607
- type: 'select_and_link',
608
- entity: entityType,
609
- entityData: entity,
610
- index: index === undefined ? undefined : index + i
611
- });
612
- });
613
- }, // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
614
- [entityType, props.onLink, props.onAction]);
615
- const onCreate = React.useCallback(async (contentTypeId, index) => {
616
- const {
617
- entity,
618
- slide
619
- } = await createEntity({
620
- sdk,
621
- entityType,
622
- contentTypeId
623
- });
624
-
625
- if (!entity) {
626
- return;
627
- }
628
-
629
- onCreated(entity, index, slide);
630
- }, [sdk, entityType, onCreated]);
631
- const onLinkExisting = React.useCallback(async index => {
632
- const entity = await selectSingleEntity({
633
- sdk,
634
- entityType,
635
- editorPermissions
636
- });
637
-
638
- if (!entity) {
639
- return;
640
- }
641
-
642
- onLinkedExisting([entity], index);
643
- }, // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
644
- [sdk, entityType, onLinkedExisting]);
645
- const onLinkSeveralExisting = React.useCallback(async index => {
646
- const entities = await selectMultipleEntities({
647
- sdk,
648
- entityType,
649
- editorPermissions
650
- });
651
-
652
- if (!entities || entities.length === 0) {
653
- return;
654
- }
655
-
656
- onLinkedExisting(entities, index);
657
- }, // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
658
- [sdk, entityType, onLinkedExisting]); // FIXME: The memoization might rerun every time due to the always changing callback identities above
659
-
660
- return React.useMemo(() => ({
661
- entityType,
662
- canLinkMultiple,
663
- isDisabled,
664
- isEmpty,
665
- isFull,
666
- canCreateEntity: editorPermissions.canCreateEntity,
667
- canLinkEntity: editorPermissions.canLinkEntity,
668
- contentTypes: editorPermissions.creatableContentTypes,
669
- onCreate,
670
- onLinkExisting: canLinkMultiple ? onLinkSeveralExisting : onLinkExisting,
671
- actionLabels,
672
- onCreated,
673
- onLinkedExisting,
674
- itemsLength
675
- }), // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
676
- [entityType, canLinkMultiple, isDisabled, isEmpty, isFull, editorPermissions.canCreateEntity, editorPermissions.canLinkEntity, actionLabels, // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
677
- editorPermissions.creatableContentTypes.map(ct => ct.sys.id).join(':'), onCreate, onLinkExisting, onLinkSeveralExisting, onCreated, onLinkedExisting, itemsLength]);
678
- }
679
- function LinkEntityActions({
680
- renderCustomActions,
681
- ...props
682
- }) {
683
- return renderCustomActions ? renderCustomActions(props) : React.createElement(LinkActions, { ...props
684
- });
685
- }
686
- function CombinedLinkEntityActions({
687
- renderCustomActions,
688
- ...props
689
- }) {
690
- return renderCustomActions ? renderCustomActions(props) : React.createElement(CombinedLinkActions, { ...props
691
- });
692
- }
693
-
694
- // eslint-disable-next-line -- TODO: describe this disable no-restricted-imports
695
- /**
696
- * @param {Date|string} date A valid constructor argument for moment()
697
- * @param {boolean=} short Render only Today/Tomorrow/Yesterday if valid. Defaults to false
698
- */
699
-
700
- const formatDate = (date, short) => {
701
- switch (moment().startOf('day').diff(moment(date).startOf('day'), 'days')) {
702
- case 0:
703
- return short ? 'Today' : `Today, ${moment(date).format('DD MMM YYYY')}`;
704
-
705
- case -1:
706
- return short ? 'Tomorrow' : `Tomorrow, ${moment(date).format('DD MMM YYYY')}`;
707
-
708
- case 1:
709
- return short ? 'Yesterday' : `Yesterday, ${moment(date).format('DD MMM YYYY')}`;
710
-
711
- default:
712
- return moment(date).format('ddd, DD MMM YYYY');
713
- }
714
- };
715
- /**
716
- * Returns the time portion of a date in the local time in the format H:MM AM/PM
717
- *
718
- * == Examples
719
- * * `T15:36:45.000Z` => 3:36 PM (if in +0:00 offset)
720
- */
721
-
722
- const formatTime = date => {
723
- return moment.utc(date).local().format('h:mm A');
724
- };
725
- const formatDateAndTime = (date, short) => {
726
- return `${formatDate(date, short)} at ${formatTime(date)}`;
727
- };
728
-
729
- const getScheduleTooltipContent = ({
730
- job,
731
- jobsCount
732
- }) => {
733
- return `Will ${job.action.toLowerCase()} ${formatDateAndTime(job.scheduledFor.datetime).toLowerCase()}
734
- ${jobsCount > 1 ? `+ ${jobsCount - 1} more` : ''}`;
735
- };
736
- const ScheduleTooltip = ({
737
- job,
738
- jobsCount,
739
- children
740
- }) => {
741
- return React__default.createElement(f36Components.Tooltip, {
742
- placement: "top",
743
- testId: job.sys.id,
744
- as: "div",
745
- content: getScheduleTooltipContent({
746
- job,
747
- jobsCount
748
- })
749
- }, children);
750
- };
751
-
752
- const ScheduledIconWithTooltip = ({
753
- entityType,
754
- entityId,
755
- getEntityScheduledActions,
756
- children
757
- }) => {
758
- const [status, setStatus] = React__default.useState({
759
- type: 'loading'
760
- });
761
- React__default.useEffect(() => {
762
- getEntityScheduledActions(entityType, entityId).then(data => {
763
- setStatus({
764
- type: 'loaded',
765
- jobs: data
766
- });
767
- }).catch(e => {
768
- setStatus({
769
- type: 'error',
770
- error: e
771
- });
772
- }); // This should only be ever called once. Following the eslint hint to add used
773
- // dependencies will cause page freeze (infinite loop)
774
- // eslint-disable-next-line -- TODO: describe this disable
775
- }, []);
776
-
777
- if (status.type === 'loading' || status.type === 'error') {
778
- return null;
779
- }
780
-
781
- const jobs = status.jobs ?? [];
782
-
783
- if (jobs.length === 0) {
784
- return null;
785
- }
786
-
787
- const mostRelevantJob = jobs[0];
788
- return React__default.createElement(ScheduleTooltip, {
789
- job: mostRelevantJob,
790
- jobsCount: jobs.length
791
- }, children);
792
- };
793
-
794
- const dimensions = {
795
- width: 70,
796
- height: 70
797
- };
798
- function AssetThumbnail(props) {
799
- return React__default.createElement("img", {
800
- alt: props.file.fileName,
801
- src: `${props.file.url}?w=${dimensions.width}&h=${dimensions.height}&fit=thumb`,
802
- height: dimensions.height,
803
- width: dimensions.width
804
- });
805
- }
806
-
807
- const globalQueue = /*#__PURE__*/new PQueue({
808
- concurrency: 50
809
- });
810
- class UnsupportedError extends Error {
811
- constructor(message) {
812
- super(message);
813
- this.isUnsupportedError = void 0;
814
- this.isUnsupportedError = true;
815
- }
816
-
817
- }
818
- function isUnsupportedError(value) {
819
- return typeof value === 'object' && (value == null ? void 0 : value.isUnsupportedError) === true;
820
- }
821
-
822
- const isEntityQueryKey = queryKey => {
823
- return Array.isArray(queryKey) && (queryKey[0] === 'Entry' || queryKey[0] === 'Asset') && queryKey.length === 4;
824
- };
825
-
826
- async function fetchContentfulEntry(params) {
827
- const {
828
- urn,
829
- fetch,
830
- options
831
- } = params;
832
- const resourceId = urn.split(':', 6)[5];
833
- const [, spaceId,, entryId] = resourceId.split('/');
834
- const environmentId = 'master';
835
- const [space, entry] = await Promise.all([fetch(['space', spaceId], ({
836
- cmaClient
837
- }) => cmaClient.space.get({
838
- spaceId
839
- }), options), fetch(['entry', spaceId, environmentId, entryId], ({
840
- cmaClient
841
- }) => cmaClient.entry.get({
842
- spaceId,
843
- environmentId,
844
- entryId
845
- }), options)]);
846
- const contentTypeId = entry.sys.contentType.sys.id;
847
- const [contentType, defaultLocaleCode] = await Promise.all([fetch(['contentType', spaceId, environmentId, contentTypeId], ({
848
- cmaClient
849
- }) => cmaClient.contentType.get({
850
- contentTypeId,
851
- spaceId,
852
- environmentId
853
- }), options), fetch(['defaultLocale', spaceId, environmentId], async ({
854
- cmaClient
855
- }) => {
856
- var _locales$items$find;
857
-
858
- const locales = await cmaClient.locale.getMany({
859
- spaceId,
860
- environmentId,
861
- query: {
862
- limit: 100
863
- }
864
- });
865
- const defaultLocaleCode = (_locales$items$find = locales.items.find(locale => locale.default)) == null ? void 0 : _locales$items$find.code;
866
- return defaultLocaleCode;
867
- }, options)]);
868
- return {
869
- defaultLocaleCode,
870
- resource: entry,
871
- space: space,
872
- contentType: contentType
873
- };
874
- }
875
-
876
- const [InternalServiceProvider, useFetch, useEntityLoader, useCurrentIds] = /*#__PURE__*/constate(function useInitServices(props) {
877
- const currentSpaceId = props.sdk.ids.space;
878
- const currentEnvironmentId = props.sdk.ids.environmentAlias ?? props.sdk.ids.environment;
879
- const environmentIds = React.useMemo(() => [props.sdk.ids.environmentAlias, props.sdk.ids.environment], [props.sdk.ids.environmentAlias, props.sdk.ids.environment]);
880
- const queryClient = reactQuery.useQueryClient();
881
- const queryCache = queryClient.getQueryCache();
882
- const entityChangeUnsubscribers = React.useRef({});
883
- const cmaClient = React.useMemo(() => contentfulManagement.createClient({
884
- apiAdapter: props.sdk.cmaAdapter
885
- }, {
886
- type: 'plain'
887
- }), [props.sdk.cmaAdapter]);
888
- const queryQueue = React.useMemo(() => {
889
- if (props.queryConcurrency) {
890
- return new PQueue({
891
- concurrency: props.queryConcurrency
892
- });
893
- }
894
-
895
- return globalQueue;
896
- }, [props.queryConcurrency]);
897
- const fetch = React.useCallback(function fetch(queryKey, fn, options = {}) {
898
- const {
899
- priority,
900
- ...queryOptions
901
- } = options;
902
- return queryClient.fetchQuery(queryKey, () => queryQueue.add(() => fn({
903
- cmaClient
904
- }), {
905
- priority
906
- }), queryOptions);
907
- }, [queryClient, queryQueue, cmaClient]);
908
- const getEntity = React.useCallback(function getEntity(entityType, entityId, options) {
909
- const spaceId = (options == null ? void 0 : options.spaceId) ?? currentSpaceId;
910
- const environmentId = (options == null ? void 0 : options.environmentId) ?? currentEnvironmentId;
911
- const queryKey = [entityType, entityId, spaceId, environmentId];
912
- return fetch(queryKey, ({
913
- cmaClient
914
- }) => {
915
- if (entityType === 'Entry') {
916
- return cmaClient.entry.get({
917
- entryId: entityId,
918
- spaceId,
919
- environmentId
920
- });
921
- }
922
-
923
- if (entityType === 'Asset') {
924
- return cmaClient.asset.get({
925
- assetId: entityId,
926
- spaceId,
927
- environmentId
928
- });
929
- }
930
-
931
- throw new UnsupportedError('Unsupported entity type');
932
- }, options);
933
- }, [fetch, currentSpaceId, currentEnvironmentId]);
934
- /**
935
- * Fetch all scheduled actions for a given entity.
936
- * This function fetches all schedules for all entries and then returns
937
- * a filtered result based on the entityID provided.
938
- *
939
- * The result is then reused/cached for subsequent calls to this function.
940
- */
941
-
942
- const getEntityScheduledActions = React.useCallback(function getEntityScheduledActions(entityType, entityId, options) {
943
- // This is fixed to force the cache to reuse previous results
944
- const fixedEntityCacheId = 'scheduledActionEntityId'; // A space+environment combo can only have up to 500 scheduled actions
945
- // With this request we fetch all schedules and can reuse the results.
946
- // See https://www.contentful.com/developers/docs/references/content-management-api/#/reference/scheduled-actions/limitations
947
-
948
- const maxScheduledActions = 500;
949
- const spaceId = (options == null ? void 0 : options.spaceId) ?? currentSpaceId;
950
- const environmentId = (options == null ? void 0 : options.environmentId) ?? currentEnvironmentId;
951
- const queryKey = ['scheduled-actions', entityType, fixedEntityCacheId, spaceId, environmentId]; // Fetch + Filter by entity ID in the end
952
-
953
- return fetch(queryKey, async ({
954
- cmaClient
955
- }) => {
956
- const response = await cmaClient.scheduledActions.getMany({
957
- spaceId,
958
- query: {
959
- 'environment.sys.id': environmentId,
960
- 'sys.status[in]': 'scheduled',
961
- order: 'scheduledFor.datetime',
962
- limit: maxScheduledActions
963
- }
964
- });
965
- return response.items;
966
- }, options).then(items => items.filter(action => action.entity.sys.id === entityId));
967
- }, [fetch, currentSpaceId, currentEnvironmentId]);
968
- const getResource = React.useCallback(function getResource(resourceType, urn, options) {
969
- const queryKey = ['Resource', resourceType, urn];
970
- return fetch(queryKey, () => {
971
- if (resourceType === 'Contentful:Entry') {
972
- return fetchContentfulEntry({
973
- fetch,
974
- urn,
975
- options
976
- });
977
- }
978
-
979
- throw new UnsupportedError('Unsupported resource type');
980
- }, options);
981
- }, [fetch]);
982
- const isSameSpaceEntityQueryKey = React.useCallback(queryKey => {
983
- const isEntityKey = isEntityQueryKey(queryKey);
984
- const isSameSpaceEntityKey = isEntityKey && queryKey[2] === currentSpaceId && environmentIds.includes(queryKey[3]);
985
- return isSameSpaceEntityKey;
986
- }, [currentSpaceId, environmentIds]); // @ts-expect-error ...
987
-
988
- const onEntityChanged = props.sdk.space.onEntityChanged;
989
- const onSlideInNavigation = props.sdk.navigator.onSlideInNavigation;
990
- React.useEffect(() => {
991
- function findSameSpaceQueries() {
992
- return queryCache.findAll({
993
- type: 'active',
994
- predicate: query => isSameSpaceEntityQueryKey(query.queryKey)
995
- });
996
- }
997
-
998
- if (typeof onEntityChanged !== 'function') {
999
- return onSlideInNavigation(({
1000
- oldSlideLevel,
1001
- newSlideLevel
1002
- }) => {
1003
- if (oldSlideLevel > newSlideLevel) {
1004
- findSameSpaceQueries().forEach(query => {
1005
- // automatically refetches the query
1006
- void queryClient.invalidateQueries(query.queryKey);
1007
- });
1008
- }
1009
- });
1010
- }
1011
-
1012
- const subscribeQuery = ({
1013
- queryKey,
1014
- queryHash
1015
- }) => {
1016
- const [entityType, entityId] = queryKey;
1017
- entityChangeUnsubscribers.current[queryHash] = onEntityChanged(entityType, entityId, data => {
1018
- queryClient.setQueryData(queryKey, data);
1019
- });
1020
- };
1021
-
1022
- findSameSpaceQueries().forEach(subscribeQuery);
1023
- const unsubscribe = queryCache.subscribe(event => {
1024
- if (!event) {
1025
- return;
1026
- }
1027
-
1028
- const {
1029
- type,
1030
- query
1031
- } = event;
1032
- const {
1033
- queryKey,
1034
- queryHash
1035
- } = query;
1036
-
1037
- if (!isSameSpaceEntityQueryKey(queryKey)) {
1038
- return;
1039
- }
1040
-
1041
- if (type === 'added') {
1042
- subscribeQuery(query);
1043
- }
1044
-
1045
- if (type === 'removed') {
1046
- var _entityChangeUnsubscr, _entityChangeUnsubscr2;
1047
-
1048
- // calling unsubscribe
1049
- (_entityChangeUnsubscr = (_entityChangeUnsubscr2 = entityChangeUnsubscribers.current)[queryHash]) == null ? void 0 : _entityChangeUnsubscr.call(_entityChangeUnsubscr2);
1050
- }
1051
- });
1052
- return () => {
1053
- unsubscribe();
1054
- Object.values(entityChangeUnsubscribers.current).forEach(off => off());
1055
- entityChangeUnsubscribers.current = {};
1056
- };
1057
- }, [onEntityChanged, queryCache, isSameSpaceEntityQueryKey, queryClient, getEntity, onSlideInNavigation]);
1058
- return {
1059
- ids: props.sdk.ids,
1060
- cmaClient,
1061
- fetch,
1062
- getResource,
1063
- getEntity,
1064
- getEntityScheduledActions
1065
- };
1066
- }, ({
1067
- fetch
1068
- }) => fetch, ({
1069
- getResource,
1070
- getEntity,
1071
- getEntityScheduledActions
1072
- }) => ({
1073
- getResource,
1074
- getEntity,
1075
- getEntityScheduledActions
1076
- }), ({
1077
- ids
1078
- }) => ({
1079
- environment: ids.environmentAlias ?? ids.environment,
1080
- space: ids.space
1081
- }));
1082
- function useEntity(entityType, entityId, options) {
1083
- const {
1084
- space,
1085
- environment
1086
- } = useCurrentIds();
1087
- const {
1088
- getEntity
1089
- } = useEntityLoader();
1090
- const queryKey = [entityType, entityId, (options == null ? void 0 : options.spaceId) ?? space, (options == null ? void 0 : options.environmentId) ?? environment];
1091
- const {
1092
- status,
1093
- data
1094
- } = reactQuery.useQuery(queryKey, () => getEntity(entityType, entityId, options), {
1095
- enabled: options == null ? void 0 : options.enabled
1096
- });
1097
- return {
1098
- status,
1099
- data
1100
- };
1101
- }
1102
- function useResource(resourceType, urn, options) {
1103
- const queryKey = ['Resource', resourceType, urn];
1104
- const {
1105
- getResource
1106
- } = useEntityLoader();
1107
- const {
1108
- status,
1109
- data,
1110
- error
1111
- } = reactQuery.useQuery(queryKey, () => getResource(resourceType, urn, options), {
1112
- enabled: options == null ? void 0 : options.enabled
1113
- });
1114
- return {
1115
- status,
1116
- data,
1117
- error
1118
- };
1119
- }
1120
-
1121
- function EntityProvider({
1122
- children,
1123
- ...props
1124
- }) {
1125
- const reactQueryClient = React.useMemo(() => {
1126
- const queryCache = new reactQuery.QueryCache();
1127
- const queryClient = new reactQuery.QueryClient({
1128
- queryCache,
1129
- defaultOptions: {
1130
- queries: {
1131
- useErrorBoundary: false,
1132
- refetchOnWindowFocus: false,
1133
- refetchOnReconnect: true,
1134
- refetchOnMount: false,
1135
- staleTime: Infinity,
1136
- retry: false
1137
- }
1138
- }
1139
- });
1140
- return queryClient;
1141
- }, []);
1142
- return React__default.createElement(reactQuery.QueryClientProvider, {
1143
- client: reactQueryClient
1144
- }, React__default.createElement(InternalServiceProvider, { ...props
1145
- }, children));
1146
- }
1147
-
1148
- function ReferenceEditor(props) {
1149
- return React.createElement(EntityProvider, {
1150
- sdk: props.sdk
1151
- }, React.createElement(fieldEditorShared.FieldConnector, {
1152
- throttle: 0,
1153
- field: props.sdk.field,
1154
- isInitiallyDisabled: props.isInitiallyDisabled,
1155
- isEqualValues: (value1, value2) => {
1156
- return deepEqual(value1, value2);
1157
- }
1158
- }, props.children));
1159
- }
1160
- ReferenceEditor.defaultProps = {
1161
- isInitiallyDisabled: true,
1162
- hasCardEditActions: true
1163
- };
1164
-
1165
- function fromFieldValidations(field) {
1166
- var _field$items;
1167
-
1168
- // eslint-disable-next-line -- TODO: describe this disable @typescript-eslint/no-explicit-any
1169
- const validations = [...field.validations, ...(((_field$items = field.items) == null ? void 0 : _field$items.validations) ?? [])];
1170
- const linkContentTypeValidations = validations.find(v => 'linkContentType' in v);
1171
- const linkMimetypeGroupValidations = validations.find(v => 'linkMimetypeGroup' in v);
1172
- const sizeValidations = validations.find(v => 'size' in v);
1173
- const size = sizeValidations && sizeValidations.size || {};
1174
- const min = size.min;
1175
- const max = size.max;
1176
- let numberOfLinks = undefined;
1177
-
1178
- if (isNumber(min) && isNumber(max)) {
1179
- numberOfLinks = {
1180
- type: 'min-max',
1181
- min,
1182
- max
1183
- };
1184
- } else if (isNumber(min)) {
1185
- numberOfLinks = {
1186
- type: 'min',
1187
- min,
1188
- max: undefined
1189
- };
1190
- } else if (isNumber(max)) {
1191
- numberOfLinks = {
1192
- type: 'max',
1193
- max,
1194
- min: undefined
1195
- };
1196
- }
1197
-
1198
- const result = {
1199
- contentTypes: (linkContentTypeValidations == null ? void 0 : linkContentTypeValidations.linkContentType) ?? undefined,
1200
- mimetypeGroups: (linkMimetypeGroupValidations == null ? void 0 : linkMimetypeGroupValidations.linkMimetypeGroup) ?? undefined,
1201
- numberOfLinks // todo: there are multiple BE problems that need to be solved first, for now we don't want to apply size constraints
1202
- // linkedFileSize: findValidation(field, 'assetFileSize', {}),
1203
- // linkedImageDimensions: findValidation(field, 'assetImageDimensions', {})
1204
-
1205
- };
1206
- return result;
1207
- }
1208
-
1209
- const AllowActionsOnContentType = () => Promise.resolve(true);
1210
-
1211
- function useAccessApi(accessApi) {
1212
- const canPerformAction = accessApi.can;
1213
- const canPerformActionOnEntryOfType = accessApi.canPerformActionOnEntryOfType ?? AllowActionsOnContentType;
1214
- return {
1215
- canPerformAction,
1216
- canPerformActionOnEntryOfType
1217
- };
1218
- }
1219
-
1220
- async function filter(arr, predicate) {
1221
- // intentionally parallel as we assume it's cached in the implementation of the access api
1222
- const fail = Symbol();
1223
- const results = await Promise.all(arr.map(async item => (await predicate(item)) ? item : fail));
1224
- return results.filter(x => x !== fail);
1225
- }
1226
-
1227
- function useContentTypePermissions(props) {
1228
- const availableContentTypes = React.useMemo(() => {
1229
- if (props.entityType === 'Asset') {
1230
- return [];
1231
- }
1232
-
1233
- if (props.validations.contentTypes) {
1234
- return props.allContentTypes.filter(ct => {
1235
- var _props$validations$co;
1236
-
1237
- return (_props$validations$co = props.validations.contentTypes) == null ? void 0 : _props$validations$co.includes(ct.sys.id);
1238
- });
1239
- }
1240
-
1241
- return props.allContentTypes;
1242
- }, [props.allContentTypes, props.validations.contentTypes, props.entityType]);
1243
- const [creatableContentTypes, setCreatableContentTypes] = React.useState(availableContentTypes);
1244
- const [readableContentTypes, setReadableContentTypes] = React.useState(availableContentTypes);
1245
- const {
1246
- canPerformActionOnEntryOfType
1247
- } = useAccessApi(props.sdk.access);
1248
- React.useEffect(() => {
1249
- function getContentTypes(action) {
1250
- return filter(availableContentTypes, ct => canPerformActionOnEntryOfType(action, ct.sys.id));
1251
- }
1252
-
1253
- async function checkContentTypeAccess() {
1254
- const creatable = await getContentTypes('create');
1255
- const readable = await getContentTypes('read');
1256
- setCreatableContentTypes(creatable);
1257
- setReadableContentTypes(readable);
1258
- }
1259
-
1260
- void checkContentTypeAccess(); // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
1261
- }, [availableContentTypes]);
1262
- return {
1263
- creatableContentTypes,
1264
- readableContentTypes,
1265
- availableContentTypes
1266
- };
1267
- }
1268
-
1269
- function useEditorPermissions(props) {
1270
- const {
1271
- sdk,
1272
- entityType,
1273
- parameters
1274
- } = props;
1275
- const validations = React.useMemo(() => fromFieldValidations(props.sdk.field), [props.sdk.field]);
1276
- const [canCreateEntity, setCanCreateEntity] = React.useState(true);
1277
- const [canLinkEntity, setCanLinkEntity] = React.useState(true);
1278
- const {
1279
- creatableContentTypes,
1280
- readableContentTypes,
1281
- availableContentTypes
1282
- } = useContentTypePermissions({ ...props,
1283
- validations
1284
- });
1285
- const {
1286
- canPerformAction
1287
- } = useAccessApi(sdk.access);
1288
- React.useEffect(() => {
1289
- if (parameters.instance.showCreateEntityAction === false) {
1290
- setCanCreateEntity(false);
1291
- return;
1292
- }
1293
-
1294
- async function checkCreateAccess() {
1295
- if (entityType === 'Asset') {
1296
- // Hardcoded `true` value following https://contentful.atlassian.net/browse/DANTE-486
1297
- // TODO: refine permissions check in order to account for tags in rules
1298
- const canCreate = (await canPerformAction('create', 'Asset')) || true;
1299
- setCanCreateEntity(canCreate);
1300
- }
1301
-
1302
- if (entityType === 'Entry') {
1303
- // Hardcoded `true` value following https://contentful.atlassian.net/browse/DANTE-486
1304
- // TODO: refine permissions check in order to account for tags in rules
1305
- const canCreate = creatableContentTypes.length > 0 || true;
1306
- setCanCreateEntity(canCreate);
1307
- }
1308
- }
1309
-
1310
- void checkCreateAccess(); // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
1311
- }, [entityType, parameters.instance, creatableContentTypes]);
1312
- React.useEffect(() => {
1313
- if (parameters.instance.showLinkEntityAction === false) {
1314
- setCanLinkEntity(false);
1315
- return;
1316
- }
1317
-
1318
- async function checkLinkAccess() {
1319
- if (entityType === 'Asset') {
1320
- // Hardcoded `true` value following https://contentful.atlassian.net/browse/DANTE-486
1321
- // TODO: refine permissions check in order to account for tags in rules
1322
- const canRead = (await canPerformAction('read', 'Asset')) || true;
1323
- setCanLinkEntity(canRead);
1324
- }
1325
-
1326
- if (entityType === 'Entry') {
1327
- // Hardcoded `true` value following https://contentful.atlassian.net/browse/DANTE-486
1328
- // TODO: refine permissions check in order to account for tags in rules
1329
- // TODO: always show every content type (it's just a filter) to avoid people not seeing
1330
- // their (partly limited) content types
1331
- const canRead = true;
1332
- setCanLinkEntity(canRead);
1333
- }
1334
- }
1335
-
1336
- void checkLinkAccess(); // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
1337
- }, [entityType, parameters.instance, readableContentTypes]);
1338
- return {
1339
- canCreateEntity,
1340
- canLinkEntity,
1341
- creatableContentTypes,
1342
- readableContentTypes,
1343
- availableContentTypes,
1344
- validations
1345
- };
1346
- }
1347
-
1348
- function Editor(props) {
1349
- const {
1350
- setValue,
1351
- entityType
1352
- } = props;
1353
- const editorPermissions = useEditorPermissions(props);
1354
- const onCreate = React.useCallback(id => void setValue({
1355
- sys: {
1356
- type: 'Link',
1357
- linkType: entityType,
1358
- id
1359
- }
1360
- }), [setValue, entityType]);
1361
- const onLink = React.useCallback(ids => {
1362
- const [id] = ids;
1363
- setValue({
1364
- sys: {
1365
- type: 'Link',
1366
- linkType: entityType,
1367
- id
1368
- }
1369
- });
1370
- }, [setValue, entityType]);
1371
- const linkActionsProps = useLinkActionsProps({ ...props,
1372
- canLinkMultiple: false,
1373
- editorPermissions,
1374
- onCreate,
1375
- onLink
1376
- }); // Inject card actions props into the given custom card renderer
1377
-
1378
- const customCardRenderer = React.useCallback((cardProps, _, renderDefaultCard) => props.renderCustomCard ? props.renderCustomCard(cardProps, linkActionsProps, renderDefaultCard) : false, // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
1379
- [linkActionsProps]);
1380
-
1381
- if (!props.entityId) {
1382
- return React.createElement(LinkEntityActions, {
1383
- renderCustomActions: props.renderCustomActions,
1384
- ...linkActionsProps
1385
- });
1386
- }
1387
-
1388
- return props.children({ ...props,
1389
- renderCustomCard: props.renderCustomCard && customCardRenderer
1390
- });
1391
- }
1392
-
1393
- function SingleReferenceEditor(props) {
1394
- const allContentTypes = props.sdk.space.getCachedContentTypes();
1395
- return React.createElement(ReferenceEditor, { ...props
1396
- }, ({
1397
- value,
1398
- setValue,
1399
- disabled,
1400
- externalReset
1401
- }) => {
1402
- return React.createElement(Editor, { ...props,
1403
- key: `${externalReset}-reference`,
1404
- entityId: value ? value.sys.id : '',
1405
- isDisabled: disabled,
1406
- setValue: setValue,
1407
- allContentTypes: allContentTypes
1408
- });
1409
- });
1410
- }
1411
- SingleReferenceEditor.defaultProps = {
1412
- hasCardEditActions: true,
1413
- hasCardRemoveActions: true
1414
- };
1415
-
1416
- const styles$1 = {
1417
- spaceIcon: /*#__PURE__*/emotion.css({
1418
- flexShrink: 0,
1419
- fill: tokens.purple600
1420
- }),
1421
- spaceName: /*#__PURE__*/emotion.css({
1422
- color: tokens.gray700,
1423
- fontSize: tokens.fontSizeS,
1424
- fontWeight: tokens.fontWeightDemiBold,
1425
- maxWidth: '80px',
1426
- textOverflow: 'ellipsis',
1427
- overflow: 'hidden',
1428
- whiteSpace: 'nowrap'
1429
- })
1430
- };
1431
- function SpaceName(props) {
1432
- return React.createElement(f36Components.Tooltip, {
1433
- placement: "top",
1434
- as: "div",
1435
- content: `Space: ${props.spaceName}`
1436
- }, React.createElement(f36Components.Flex, {
1437
- alignItems: "center",
1438
- gap: "spacingXs",
1439
- marginRight: "spacingS"
1440
- }, React.createElement(f36Icons.FolderOpenTrimmedIcon, {
1441
- className: styles$1.spaceIcon,
1442
- size: "tiny",
1443
- "aria-label": "Source space"
1444
- }), React.createElement(f36Components.Text, {
1445
- className: styles$1.spaceName
1446
- }, props.spaceName)));
1447
- }
1448
-
1449
- const {
1450
- getEntryTitle,
1451
- getEntityDescription,
1452
- getEntryStatus,
1453
- getEntryImage
1454
- } = fieldEditorShared.entityHelpers;
1455
- const styles$2 = {
1456
- scheduleIcon: /*#__PURE__*/emotion.css({
1457
- marginRight: tokens.spacing2Xs
1458
- })
1459
- };
1460
- const defaultProps = {
1461
- isClickable: true,
1462
- hasCardEditActions: true,
1463
- hasCardMoveActions: true,
1464
- hasCardRemoveActions: true
1465
- };
1466
- function WrappedEntryCard(props) {
1467
- var _props$entry;
1468
-
1469
- const [file, setFile] = React.useState(null);
1470
- const {
1471
- contentType
1472
- } = props;
1473
- React.useEffect(() => {
1474
- if (props.entry) {
1475
- getEntryImage({
1476
- entry: props.entry,
1477
- contentType,
1478
- localeCode: props.localeCode,
1479
- defaultLocaleCode: props.defaultLocaleCode
1480
- }, props.getAsset).then(file => {
1481
- setFile(file);
1482
- }).catch(() => {
1483
- setFile(null);
1484
- });
1485
- }
1486
- }, [props.entry, props.getAsset, contentType, props.localeCode, props.defaultLocaleCode]);
1487
- const status = getEntryStatus((_props$entry = props.entry) == null ? void 0 : _props$entry.sys);
1488
-
1489
- if (status === 'deleted') {
1490
- return React.createElement(MissingEntityCard, {
1491
- entityType: "Entry",
1492
- isDisabled: props.isDisabled,
1493
- onRemove: props.onRemove
1494
- });
1495
- }
1496
-
1497
- const title = getEntryTitle({
1498
- entry: props.entry,
1499
- contentType,
1500
- localeCode: props.localeCode,
1501
- defaultLocaleCode: props.defaultLocaleCode,
1502
- defaultTitle: 'Untitled'
1503
- });
1504
- const description = getEntityDescription({
1505
- entity: props.entry,
1506
- contentType,
1507
- localeCode: props.localeCode,
1508
- defaultLocaleCode: props.defaultLocaleCode
1509
- });
1510
- return React.createElement(f36Components.EntryCard, {
1511
- as: props.entryUrl ? 'a' : 'article',
1512
- href: props.entryUrl,
1513
- title: title,
1514
- description: description,
1515
- contentType: contentType == null ? void 0 : contentType.name,
1516
- size: props.size,
1517
- isSelected: props.isSelected,
1518
- status: status,
1519
- icon: props.spaceName ? React.createElement(SpaceName, {
1520
- spaceName: props.spaceName
1521
- }) : React.createElement(ScheduledIconWithTooltip, {
1522
- getEntityScheduledActions: props.getEntityScheduledActions,
1523
- entityType: "Entry",
1524
- entityId: props.entry.sys.id
1525
- }, React.createElement(f36Icons.ClockIcon, {
1526
- className: styles$2.scheduleIcon,
1527
- size: "small",
1528
- variant: "muted",
1529
- testId: "schedule-icon"
1530
- })),
1531
- thumbnailElement: file && fieldEditorShared.isValidImage(file) ? React.createElement(AssetThumbnail, {
1532
- file: file
1533
- }) : undefined,
1534
- dragHandleRender: props.renderDragHandle,
1535
- withDragHandle: !!props.renderDragHandle,
1536
- actions: props.onEdit || props.onRemove ? [props.hasCardEditActions && props.onEdit ? React.createElement(f36Components.MenuItem, {
1537
- key: "edit",
1538
- testId: "edit",
1539
- onClick: () => {
1540
- props.onEdit && props.onEdit();
1541
- }
1542
- }, "Edit") : null, props.hasCardRemoveActions && props.onRemove ? React.createElement(f36Components.MenuItem, {
1543
- key: "delete",
1544
- testId: "delete",
1545
- onClick: () => {
1546
- props.onRemove && props.onRemove();
1547
- }
1548
- }, "Remove") : null, props.hasCardMoveActions && (props.onMoveTop || props.onMoveBottom) ? React.createElement(f36Components.MenuDivider, {
1549
- key: "divider"
1550
- }) : null, props.hasCardMoveActions && props.onMoveTop ? React.createElement(f36Components.MenuItem, {
1551
- key: "move-top",
1552
- onClick: () => props.onMoveTop && props.onMoveTop(),
1553
- testId: "move-top"
1554
- }, "Move to top") : null, props.hasCardMoveActions && props.onMoveBottom ? React.createElement(f36Components.MenuItem, {
1555
- key: "move-bottom",
1556
- onClick: () => props.onMoveBottom && props.onMoveBottom(),
1557
- testId: "move-bottom"
1558
- }, "Move to bottom") : null].filter(item => item) : [],
1559
- onClick: // Providing an onClick handler messes up with some rich text
1560
- // features e.g. pressing ENTER on a card to add a new paragraph
1561
- // underneath. It's crucial not to pass a custom handler when
1562
- // isClickable is disabled which in the case of RT it's.
1563
- props.isClickable ? e => {
1564
- e.preventDefault();
1565
- if (props.onClick) return props.onClick(e);
1566
- props.onEdit && props.onEdit();
1567
- } : undefined
1568
- });
1569
- }
1570
- WrappedEntryCard.defaultProps = defaultProps;
1571
-
1572
- async function openEntry(sdk, entryId, options) {
1573
- let slide;
1574
-
1575
- if (options.bulkEditing) {
1576
- try {
1577
- const result = await sdk.navigator.openBulkEditor(sdk.entry.getSys().id, {
1578
- fieldId: sdk.field.id,
1579
- locale: sdk.field.locale,
1580
- index: options.index ?? 0
1581
- });
1582
- slide = result.slide;
1583
- return slide;
1584
- } catch (e) {// we don't allow to open multiple bulk editors for performance reasons
1585
- // proceed with a default openEntry
1586
- }
1587
- }
1588
-
1589
- const result = await sdk.navigator.openEntry(entryId, {
1590
- slideIn: true
1591
- });
1592
- slide = result.slide;
1593
- return slide;
1594
- }
1595
-
1596
- function FetchingWrappedEntryCard(props) {
1597
- const {
1598
- data: entry,
1599
- status
1600
- } = useEntity('Entry', props.entryId);
1601
- const {
1602
- getEntityScheduledActions
1603
- } = useEntityLoader();
1604
- const loadEntityScheduledActions = React.useCallback(() => getEntityScheduledActions('Entry', props.entryId), [getEntityScheduledActions, props.entryId]);
1605
- const size = props.viewType === 'link' ? 'small' : 'default';
1606
- const {
1607
- getEntity
1608
- } = useEntityLoader();
1609
-
1610
- const getAsset = assetId => getEntity('Asset', assetId);
1611
-
1612
- const onEdit = async () => {
1613
- const slide = await openEntry(props.sdk, props.entryId, {
1614
- bulkEditing: props.parameters.instance.bulkEditing,
1615
- index: props.index
1616
- });
1617
- props.onAction && props.onAction({
1618
- entity: 'Entry',
1619
- type: 'edit',
1620
- id: props.entryId,
1621
- contentTypeId: get(entry, 'sys.contentType.sys.id'),
1622
- slide
1623
- });
1624
- };
1625
-
1626
- const onRemoveEntry = () => {
1627
- props.onRemove();
1628
- props.onAction && props.onAction({
1629
- entity: 'Entry',
1630
- type: 'delete',
1631
- id: props.entryId,
1632
- contentTypeId: get(entry, 'sys.contentType.sys.id')
1633
- });
1634
- };
1635
-
1636
- React.useEffect(() => {
1637
- if (entry) {
1638
- props.onAction && props.onAction({
1639
- type: 'rendered',
1640
- entity: 'Entry'
1641
- });
1642
- } // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
1643
-
1644
- }, [entry]);
1645
- return React.useMemo(() => {
1646
- if (status === 'error') {
1647
- const card = React.createElement(MissingEntityCard, {
1648
- entityType: "Entry",
1649
- isDisabled: props.isDisabled,
1650
- onRemove: onRemoveEntry
1651
- });
1652
-
1653
- if (props.renderCustomMissingEntityCard) {
1654
- return props.renderCustomMissingEntityCard({
1655
- defaultCard: card,
1656
- entity: {
1657
- id: props.entryId,
1658
- type: 'Entry'
1659
- }
1660
- });
1661
- }
1662
-
1663
- return card;
1664
- }
1665
-
1666
- if (status === 'loading') {
1667
- return React.createElement(f36Components.EntryCard, {
1668
- size: size,
1669
- isLoading: true
1670
- });
1671
- }
1672
-
1673
- const sharedCardProps = {
1674
- index: props.index,
1675
- entity: entry,
1676
- entityUrl: props.getEntityUrl && props.getEntityUrl(entry.sys.id),
1677
- contentType: props.allContentTypes.find(contentType => contentType.sys.id === entry.sys.contentType.sys.id),
1678
- isDisabled: props.isDisabled,
1679
- size,
1680
- localeCode: props.sdk.field.locale,
1681
- defaultLocaleCode: props.sdk.locales.default,
1682
- renderDragHandle: props.renderDragHandle,
1683
- onEdit,
1684
- onRemove: onRemoveEntry,
1685
- onMoveTop: props.onMoveTop,
1686
- onMoveBottom: props.onMoveBottom,
1687
- isBeingDragged: props.isBeingDragged
1688
- };
1689
- const {
1690
- hasCardEditActions,
1691
- hasCardMoveActions,
1692
- hasCardRemoveActions
1693
- } = props;
1694
-
1695
- function renderDefaultCard(props) {
1696
- const builtinCardProps = { ...sharedCardProps,
1697
- ...props,
1698
- hasCardEditActions,
1699
- hasCardMoveActions,
1700
- hasCardRemoveActions,
1701
- getAsset,
1702
- getEntityScheduledActions: loadEntityScheduledActions,
1703
- entry: (props == null ? void 0 : props.entity) || sharedCardProps.entity,
1704
- entryUrl: (props == null ? void 0 : props.entityUrl) || sharedCardProps.entityUrl
1705
- };
1706
- return React.createElement(WrappedEntryCard, { ...builtinCardProps
1707
- });
1708
- }
1709
-
1710
- if (props.renderCustomCard) {
1711
- // LinkActionsProps are injected higher SingleReferenceEditor/MultipleReferenceEditor
1712
- const renderedCustomCard = props.renderCustomCard(sharedCardProps, {}, renderDefaultCard); // Only `false` indicates to render the original card. E.g. `null` would result in no card.
1713
-
1714
- if (renderedCustomCard !== false) {
1715
- return renderedCustomCard;
1716
- }
1717
- }
1718
-
1719
- return renderDefaultCard(); // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
1720
- }, [props, status, entry]);
1721
- }
1722
-
1723
- function SingleEntryReferenceEditor(props) {
1724
- return React.createElement(SingleReferenceEditor, { ...props,
1725
- entityType: "Entry"
1726
- }, ({
1727
- allContentTypes,
1728
- isDisabled,
1729
- entityId,
1730
- setValue,
1731
- renderCustomCard,
1732
- hasCardRemoveActions,
1733
- hasCardEditActions
1734
- }) => {
1735
- return React.createElement(FetchingWrappedEntryCard, { ...props,
1736
- allContentTypes: allContentTypes,
1737
- isDisabled: isDisabled,
1738
- entryId: entityId,
1739
- renderCustomCard: renderCustomCard,
1740
- hasCardEditActions: hasCardEditActions,
1741
- hasCardRemoveActions: hasCardRemoveActions,
1742
- onRemove: () => {
1743
- setValue(null);
1744
- }
1745
- });
1746
- });
1747
- }
1748
- SingleEntryReferenceEditor.defaultProps = {
1749
- isInitiallyDisabled: true
1750
- };
1751
-
1752
- function onLinkOrCreate(setValue, entityType, items, ids, index = items.length) {
1753
- const links = ids.map(id => ({
1754
- sys: {
1755
- type: 'Link',
1756
- linkType: entityType,
1757
- id
1758
- }
1759
- }));
1760
- const newItems = Array.from(items);
1761
- newItems.splice(index, 0, ...links);
1762
- setValue(newItems);
1763
- }
1764
-
1765
- const emptyArray = [];
1766
- const nullableValue = {
1767
- sys: {
1768
- id: 'null-value'
1769
- }
1770
- };
1771
-
1772
- function Editor$1(props) {
1773
- const {
1774
- setValue,
1775
- entityType,
1776
- setIndexToUpdate
1777
- } = props;
1778
- const editorPermissions = useEditorPermissions(props);
1779
- const items = React.useMemo(() => {
1780
- return (props.items || []). // If null values have found their way into the persisted
1781
- // value for the multiref field, replace them with an object
1782
- // that has the shape of a Link to make the missing entry/asset
1783
- // card render
1784
- map(link => link || nullableValue);
1785
- }, [props.items]);
1786
- const onSortStart = React.useCallback((_, event) => {
1787
- if (event instanceof MouseEvent) {
1788
- document.body.classList.add('grabbing');
1789
- }
1790
-
1791
- event.preventDefault();
1792
- }, []);
1793
- const onSortEnd = React.useCallback(({
1794
- oldIndex,
1795
- newIndex
1796
- }) => {
1797
- // custom callback that is invoked *before* we sort the array
1798
- // e.g. in Compose we want to sort the references in the referenceMap before re-rendering drag and drop
1799
- props.onSortingEnd && props.onSortingEnd({
1800
- oldIndex,
1801
- newIndex
1802
- });
1803
- const newItems = arrayMove(items, oldIndex, newIndex);
1804
- setValue(newItems);
1805
- setIndexToUpdate && setIndexToUpdate(undefined);
1806
- document.body.classList.remove('grabbing');
1807
- }, [items, props, setIndexToUpdate, setValue]);
1808
- const onMove = React.useCallback((oldIndex, newIndex) => {
1809
- const newItems = arrayMove(items, oldIndex, newIndex);
1810
- setValue(newItems);
1811
- }, [items, setValue]);
1812
- const onCreate = React.useCallback((id, index) => onLinkOrCreate(setValue, entityType, items, [id], index), [setValue, items, entityType]);
1813
- const onLink = React.useCallback((ids, index) => onLinkOrCreate(setValue, entityType, items, ids, index), [setValue, items, entityType]);
1814
- const linkActionsProps = useLinkActionsProps({ ...props,
1815
- canLinkMultiple: true,
1816
- editorPermissions,
1817
- onCreate,
1818
- onLink,
1819
- itemsLength: items.length
1820
- });
1821
- const customCardRenderer = React.useCallback((cardProps, _, renderDefaultCard) => props.renderCustomCard ? props.renderCustomCard(cardProps, linkActionsProps, renderDefaultCard) : false, // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
1822
- [linkActionsProps]);
1823
- return React.createElement(React.Fragment, null, props.children({ ...props,
1824
- onSortStart: onSortStart,
1825
- onSortEnd: onSortEnd,
1826
- onMove,
1827
- renderCustomCard: props.renderCustomCard && customCardRenderer
1828
- }), React.createElement(LinkEntityActions, {
1829
- renderCustomActions: props.renderCustomActions,
1830
- ...linkActionsProps
1831
- }));
1832
- }
1833
-
1834
- function MultipleReferenceEditor(props) {
1835
- const allContentTypes = props.sdk.space.getCachedContentTypes();
1836
- return React.createElement(ReferenceEditor, { ...props
1837
- }, ({
1838
- value,
1839
- disabled,
1840
- setValue,
1841
- externalReset
1842
- }) => {
1843
- return React.createElement(Editor$1, { ...props,
1844
- items: value || emptyArray,
1845
- isDisabled: disabled,
1846
- setValue: setValue,
1847
- key: `${externalReset}-list`,
1848
- allContentTypes: allContentTypes
1849
- });
1850
- });
1851
- }
1852
- MultipleReferenceEditor.defaultProps = {
1853
- hasCardEditActions: true
1854
- };
1855
-
1856
- const styles$3 = {
1857
- container: /*#__PURE__*/emotion.css({
1858
- position: 'relative'
1859
- }),
1860
- item: /*#__PURE__*/emotion.css({
1861
- marginBottom: tokens.spacingM,
1862
- zIndex: tokens.zIndexModal // setting this to an index above 99 fixes dragged item disappearing issue. Should not be higher than 100 so it does not overlap the asset modal.
1863
-
1864
- })
1865
- };
1866
-
1867
- const DragHandle = props => {
1868
- const SortableDragHandle = reactSortableHoc.SortableHandle(() => props.drag);
1869
- return React__default.createElement(SortableDragHandle, null);
1870
- };
1871
-
1872
- const SortableLink = /*#__PURE__*/reactSortableHoc.SortableElement(props => React__default.createElement("div", {
1873
- className: styles$3.item
1874
- }, props.children));
1875
- const SortableLinkListInternal = /*#__PURE__*/reactSortableHoc.SortableContainer(props => {
1876
- return React__default.createElement("div", {
1877
- className: emotion.cx(styles$3.container, props.className)
1878
- }, props.items.map((item, index) => React__default.createElement(SortableLink, {
1879
- disabled: props.isDisabled,
1880
- key: `${item.sys.urn ?? item.sys.id}-${index}`,
1881
- index: index
1882
- }, props.children({
1883
- items: props.items,
1884
- isDisabled: props.isDisabled,
1885
- item,
1886
- index,
1887
- DragHandle: props.isDisabled ? undefined : DragHandle
1888
- }))));
1889
- }); // HOC does not support generics, so we mimic it via additional component
1890
-
1891
- function SortableLinkList(props) {
1892
- // with the default distance of 0 the drag start event is "confused" with the click event,
1893
- // so the latter one isn't fired and click handlers on child elements don't work
1894
- return React__default.createElement(SortableLinkListInternal, {
1895
- distance: 1,
1896
- ...props
1897
- }, props.children);
1898
- }
1899
-
1900
- function MultipleEntryReferenceEditor(props) {
1901
- const [indexToUpdate, setIndexToUpdate] = React.useState(undefined);
1902
-
1903
- const updateBeforeSortStart = ({
1904
- index
1905
- }) => {
1906
- setIndexToUpdate(index);
1907
- };
1908
-
1909
- return React.createElement(MultipleReferenceEditor, { ...props,
1910
- entityType: "Entry",
1911
- setIndexToUpdate: setIndexToUpdate
1912
- }, childrenProps => React.createElement(SortableLinkList, { ...childrenProps,
1913
- axis: "y",
1914
- useDragHandle: true,
1915
- updateBeforeSortStart: updateBeforeSortStart
1916
- }, ({
1917
- items,
1918
- item,
1919
- index,
1920
- isDisabled,
1921
- DragHandle
1922
- }) => {
1923
- const lastIndex = items.length - 1;
1924
- return React.createElement(FetchingWrappedEntryCard, { ...childrenProps,
1925
- key: `${item.sys.id}-${index}`,
1926
- index: index,
1927
- allContentTypes: childrenProps.allContentTypes,
1928
- isDisabled: isDisabled,
1929
- entryId: item.sys.id,
1930
- onRemove: () => {
1931
- childrenProps.setValue(items.filter((_value, i) => i !== index));
1932
- },
1933
- onMoveTop: index !== 0 ? () => childrenProps.onMove(index, 0) : undefined,
1934
- onMoveBottom: index !== lastIndex ? () => childrenProps.onMove(index, lastIndex) : undefined,
1935
- renderDragHandle: DragHandle,
1936
- isBeingDragged: index === indexToUpdate
1937
- });
1938
- }));
1939
- }
1940
-
1941
- function downloadAsset(url) {
1942
- window.open(url, '_blank', 'noopener,noreferrer');
1943
- }
1944
-
1945
- function renderAssetInfo(props) {
1946
- const {
1947
- entityFile
1948
- } = props;
1949
- const fileName = get(entityFile, 'fileName');
1950
- const mimeType = get(entityFile, 'contentType');
1951
- const fileSize = get(entityFile, 'details.size');
1952
- const image = get(entityFile, 'details.image');
1953
- return [React__default.createElement(f36Components.Menu.SectionTitle, {
1954
- key: "file-section"
1955
- }, "File info"), fileName && React__default.createElement(f36Components.Menu.Item, {
1956
- key: "file-name"
1957
- }, React__default.createElement(f36Components.Text, {
1958
- isTruncated: true
1959
- }, fileName)), mimeType && React__default.createElement(f36Components.Menu.Item, {
1960
- key: "file-type"
1961
- }, React__default.createElement(f36Components.Text, {
1962
- isTruncated: true
1963
- }, mimeType)), fileSize && React__default.createElement(f36Components.Menu.Item, {
1964
- key: "file-size"
1965
- }, fieldEditorShared.shortenStorageUnit(fileSize, 'B')), image && React__default.createElement(f36Components.Menu.Item, {
1966
- key: "file-dimentions"
1967
- }, `${image.width} × ${image.height}`)].filter(item => item);
1968
- }
1969
- function renderActions(props) {
1970
- const {
1971
- entityFile,
1972
- isDisabled,
1973
- onEdit,
1974
- onRemove
1975
- } = props;
1976
- return [React__default.createElement(f36Components.Menu.SectionTitle, {
1977
- key: "section-title"
1978
- }, "Actions"), onEdit ? React__default.createElement(f36Components.Menu.Item, {
1979
- key: "edit",
1980
- onClick: onEdit,
1981
- testId: "card-action-edit"
1982
- }, "Edit") : null, entityFile ? React__default.createElement(f36Components.Menu.Item, {
1983
- key: "download",
1984
- onClick: () => {
1985
- if (typeof entityFile.url === 'string') {
1986
- downloadAsset(entityFile.url);
1987
- }
1988
- },
1989
- testId: "card-action-download"
1990
- }, "Download") : null, onRemove ? React__default.createElement(f36Components.Menu.Item, {
1991
- key: "remove",
1992
- disabled: isDisabled,
1993
- onClick: onRemove,
1994
- testId: "card-action-remove"
1995
- }, "Remove") : null].filter(item => item);
1996
- }
1997
-
1998
- const groupToIconMap = {
1999
- image: 'image',
2000
- video: 'video',
2001
- audio: 'audio',
2002
- richtext: 'richtext',
2003
- presentation: 'presentation',
2004
- spreadsheet: 'spreadsheet',
2005
- pdfdocument: 'pdf',
2006
- archive: 'archive',
2007
- plaintext: 'plaintext',
2008
- code: 'code',
2009
- markup: 'markup'
2010
- };
2011
- const styles$4 = {
2012
- scheduleIcon: /*#__PURE__*/emotion.css({
2013
- marginRight: tokens.spacing2Xs
2014
- })
2015
- };
2016
- const defaultProps$1 = {
2017
- isClickable: true
2018
- }; // eslint-disable-next-line -- TODO: describe this disable @typescript-eslint/no-explicit-any
2019
-
2020
- function getFileType(file) {
2021
- if (!file) {
2022
- return 'archive';
2023
- }
2024
-
2025
- const groupName = mimetype.getGroupLabel({
2026
- type: file.contentType,
2027
- fallbackFileName: file.fileName
2028
- });
2029
- return groupToIconMap[groupName] || 'archive';
2030
- }
2031
-
2032
- const WrappedAssetCard = props => {
2033
- const {
2034
- className,
2035
- onEdit,
2036
- getAssetUrl,
2037
- onRemove,
2038
- size,
2039
- isDisabled,
2040
- isSelected,
2041
- isClickable
2042
- } = props;
2043
- const status = fieldEditorShared.entityHelpers.getEntryStatus(props.asset.sys);
2044
-
2045
- if (status === 'deleted') {
2046
- return React__default.createElement(MissingEntityCard, {
2047
- entityType: "Asset",
2048
- asSquare: true,
2049
- isDisabled: props.isDisabled,
2050
- onRemove: props.onRemove
2051
- });
2052
- }
2053
-
2054
- const entityTitle = fieldEditorShared.entityHelpers.getAssetTitle({
2055
- asset: props.asset,
2056
- localeCode: props.localeCode,
2057
- defaultLocaleCode: props.defaultLocaleCode,
2058
- defaultTitle: 'Untitled'
2059
- });
2060
- const entityFile = props.asset.fields.file ? props.asset.fields.file[props.localeCode] || props.asset.fields.file[props.defaultLocaleCode] : undefined;
2061
- const href = getAssetUrl ? getAssetUrl(props.asset.sys.id) : undefined;
2062
- return React__default.createElement(f36Components.AssetCard, {
2063
- as: href ? 'a' : 'article',
2064
- type: getFileType(entityFile),
2065
- title: entityTitle,
2066
- className: className,
2067
- isSelected: isSelected,
2068
- href: href,
2069
- status: status,
2070
- icon: React__default.createElement(ScheduledIconWithTooltip, {
2071
- getEntityScheduledActions: props.getEntityScheduledActions,
2072
- entityType: "Asset",
2073
- entityId: props.asset.sys.id
2074
- }, React__default.createElement(f36Icons.ClockIcon, {
2075
- className: styles$4.scheduleIcon,
2076
- size: "small",
2077
- variant: "muted",
2078
- testId: "schedule-icon"
2079
- })),
2080
- src: entityFile && entityFile.url ? size === 'small' ? `${entityFile.url}?w=150&h=150&fit=thumb` : `${entityFile.url}?h=300` : '',
2081
- onClick: // Providing an onClick handler messes up with some rich text
2082
- // features e.g. pressing ENTER on a card to add a new paragraph
2083
- // underneath. It's crucial not to pass a custom handler when
2084
- // isClickable is disabled which in the case of RT it's.
2085
- isClickable ? e => {
2086
- e.preventDefault();
2087
- onEdit && onEdit();
2088
- } : undefined,
2089
-
2090
- /* todo - remove this when onKeyDown is allowed as a prop for BaseCard in forma 36
2091
- // @ts-expect-error */
2092
- onKeyDown: isClickable ? e => {
2093
- if (e.key === 'Enter' && onEdit) {
2094
- e.preventDefault();
2095
- onEdit();
2096
- }
2097
- } : undefined,
2098
- dragHandleRender: props.renderDragHandle,
2099
- withDragHandle: !!props.renderDragHandle,
2100
- actions: [...renderActions({
2101
- entityFile,
2102
- isDisabled: isDisabled,
2103
- onEdit,
2104
- onRemove
2105
- }), ...(entityFile ? renderAssetInfo({
2106
- entityFile
2107
- }) : [])].filter(item => item),
2108
- size: size
2109
- });
2110
- };
2111
- WrappedAssetCard.defaultProps = defaultProps$1;
2112
-
2113
- const styles$5 = {
2114
- scheduleIcon: /*#__PURE__*/emotion.css({
2115
- marginRight: tokens.spacing2Xs
2116
- })
2117
- };
2118
- const WrappedAssetLink = props => {
2119
- const {
2120
- className,
2121
- href,
2122
- onEdit,
2123
- onRemove,
2124
- isDisabled
2125
- } = props;
2126
- const status = fieldEditorShared.entityHelpers.getEntryStatus(props.asset.sys);
2127
-
2128
- if (status === 'deleted') {
2129
- return React__default.createElement(MissingEntityCard, {
2130
- entityType: "Asset",
2131
- isDisabled: props.isDisabled,
2132
- onRemove: props.onRemove
2133
- });
2134
- }
2135
-
2136
- const entityTitle = fieldEditorShared.entityHelpers.getAssetTitle({
2137
- asset: props.asset,
2138
- localeCode: props.localeCode,
2139
- defaultLocaleCode: props.defaultLocaleCode,
2140
- defaultTitle: 'Untitled'
2141
- });
2142
- const entityFile = props.asset.fields.file ? props.asset.fields.file[props.localeCode] || props.asset.fields.file[props.defaultLocaleCode] : undefined;
2143
- return React__default.createElement(f36Components.EntryCard, {
2144
- as: href ? 'a' : 'article',
2145
- contentType: "Asset",
2146
- title: entityTitle,
2147
- className: className,
2148
- href: href,
2149
- size: "small",
2150
- status: status,
2151
- thumbnailElement: entityFile && fieldEditorShared.isValidImage(entityFile) ? React__default.createElement(AssetThumbnail, {
2152
- file: entityFile
2153
- }) : undefined,
2154
- icon: React__default.createElement(ScheduledIconWithTooltip, {
2155
- getEntityScheduledActions: props.getEntityScheduledActions,
2156
- entityType: "Asset",
2157
- entityId: props.asset.sys.id
2158
- }, React__default.createElement(f36Icons.ClockIcon, {
2159
- className: styles$5.scheduleIcon,
2160
- size: "small",
2161
- variant: "muted",
2162
- testId: "schedule-icon"
2163
- })),
2164
- onClick: e => {
2165
- e.preventDefault();
2166
- onEdit();
2167
- },
2168
- onKeyDown: e => {
2169
- if (e.key === 'Enter' && onEdit) {
2170
- e.preventDefault();
2171
- onEdit();
2172
- }
2173
- },
2174
- dragHandleRender: props.renderDragHandle,
2175
- withDragHandle: !!props.renderDragHandle,
2176
- actions: [renderActions({
2177
- entityFile,
2178
- isDisabled: isDisabled,
2179
- onEdit,
2180
- onRemove
2181
- }), entityFile ? renderAssetInfo({
2182
- entityFile
2183
- }) : null].filter(item => item)
2184
- });
2185
- };
2186
-
2187
- function FetchingWrappedAssetCard(props) {
2188
- const {
2189
- data: asset,
2190
- status
2191
- } = useEntity('Asset', props.assetId);
2192
- const {
2193
- getEntityScheduledActions
2194
- } = useEntityLoader();
2195
- const loadEntityScheduledActions = React.useCallback(() => getEntityScheduledActions('Asset', props.assetId), [getEntityScheduledActions, props.assetId]);
2196
- React.useEffect(() => {
2197
- if (asset) {
2198
- props.onAction && props.onAction({
2199
- type: 'rendered',
2200
- entity: 'Asset'
2201
- });
2202
- } // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
2203
-
2204
- }, [asset]);
2205
-
2206
- const onEdit = async () => {
2207
- const {
2208
- slide
2209
- } = await props.sdk.navigator.openAsset(props.assetId, {
2210
- slideIn: true
2211
- });
2212
- props.onAction && props.onAction({
2213
- entity: 'Asset',
2214
- type: 'edit',
2215
- id: props.assetId,
2216
- contentTypeId: '',
2217
- slide
2218
- });
2219
- };
2220
-
2221
- const onRemove = () => {
2222
- props.onRemove();
2223
- props.onAction && props.onAction({
2224
- entity: 'Asset',
2225
- type: 'delete',
2226
- id: props.assetId,
2227
- contentTypeId: ''
2228
- });
2229
- };
2230
-
2231
- return React.useMemo(() => {
2232
- if (status === 'error') {
2233
- const card = React.createElement(MissingEntityCard, {
2234
- entityType: "Asset",
2235
- asSquare: props.viewType !== 'link',
2236
- isDisabled: props.isDisabled,
2237
- onRemove: onRemove
2238
- });
2239
-
2240
- if (props.renderCustomMissingEntityCard) {
2241
- return props.renderCustomMissingEntityCard({
2242
- defaultCard: card,
2243
- entity: {
2244
- id: props.assetId,
2245
- type: 'Asset'
2246
- }
2247
- });
2248
- }
2249
-
2250
- return card;
2251
- }
2252
-
2253
- const {
2254
- getEntityUrl
2255
- } = props;
2256
- const size = props.viewType === 'big_card' ? 'default' : 'small';
2257
- const commonProps = {
2258
- asset,
2259
- entityUrl: getEntityUrl && getEntityUrl(props.assetId),
2260
- size: size,
2261
- isDisabled: props.isDisabled,
2262
- localeCode: props.sdk.field.locale,
2263
- defaultLocaleCode: props.sdk.locales.default,
2264
- renderDragHandle: props.renderDragHandle,
2265
- onEdit,
2266
- onRemove
2267
- };
2268
-
2269
- if (props.viewType === 'link') {
2270
- if (status === 'loading') {
2271
- return React.createElement(f36Components.EntryCard, {
2272
- size: "small",
2273
- isLoading: true
2274
- });
2275
- }
2276
-
2277
- return React.createElement(WrappedAssetLink, { ...commonProps,
2278
- href: commonProps.entityUrl,
2279
- getEntityScheduledActions: loadEntityScheduledActions
2280
- });
2281
- }
2282
-
2283
- if (status === 'loading') {
2284
- return React.createElement(f36Components.AssetCard, {
2285
- size: size,
2286
- isLoading: true
2287
- });
2288
- }
2289
-
2290
- function renderDefaultCard(props) {
2291
- // isClickable has a default value, so omit it from the props
2292
- const builtinCardProps = { ...commonProps,
2293
- ...props,
2294
- getEntityScheduledActions: loadEntityScheduledActions,
2295
- asset: (props == null ? void 0 : props.entity) || commonProps.asset,
2296
- getAssetUrl: getEntityUrl
2297
- };
2298
- return React.createElement(WrappedAssetCard, { ...builtinCardProps
2299
- });
2300
- }
2301
-
2302
- if (props.renderCustomCard) {
2303
- const customProps = { ...commonProps,
2304
- entity: commonProps.asset
2305
- }; // LinkActionsProps are injected higher SingleReferenceEditor/MultipleReferenceEditor
2306
-
2307
- const renderedCustomCard = props.renderCustomCard(customProps, {}, renderDefaultCard); // Only `false` indicates to render the original card. E.g. `null` would result in no card.
2308
-
2309
- if (renderedCustomCard !== false) {
2310
- return renderedCustomCard;
2311
- }
2312
- }
2313
-
2314
- return renderDefaultCard(); // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
2315
- }, [props, status, asset]);
2316
- }
2317
-
2318
- function SingleMediaEditor(props) {
2319
- return React.createElement(SingleReferenceEditor, { ...props,
2320
- entityType: "Asset"
2321
- }, ({
2322
- entityId,
2323
- isDisabled,
2324
- setValue
2325
- }) => React.createElement(FetchingWrappedAssetCard, { ...props,
2326
- viewType: "big_card",
2327
- assetId: entityId,
2328
- isDisabled: isDisabled,
2329
- onRemove: () => {
2330
- setValue(null);
2331
- }
2332
- }));
2333
- }
2334
- SingleMediaEditor.defaultProps = {
2335
- isInitiallyDisabled: true
2336
- };
2337
-
2338
- const styles$6 = {
2339
- gridContainer: /*#__PURE__*/emotion.css({
2340
- position: 'relative',
2341
- display: 'flex',
2342
- flexWrap: 'wrap'
2343
- })
2344
- };
2345
- function MultipleMediaEditor(props) {
2346
- return React.createElement(MultipleReferenceEditor, { ...props,
2347
- entityType: "Asset"
2348
- }, childrenProps => React.createElement(SortableLinkList, { ...childrenProps,
2349
- className: emotion.cx({
2350
- [styles$6.gridContainer]: childrenProps.viewType === 'card'
2351
- }),
2352
- axis: childrenProps.viewType === 'card' ? 'xy' : 'y',
2353
- useDragHandle: true
2354
- }, ({
2355
- items,
2356
- item,
2357
- index,
2358
- isDisabled,
2359
- DragHandle
2360
- }) => React.createElement(FetchingWrappedAssetCard, { ...childrenProps,
2361
- isDisabled: isDisabled,
2362
- key: `${item.sys.id}-${index}`,
2363
- assetId: item.sys.id,
2364
- onRemove: () => {
2365
- childrenProps.setValue(items.filter((_value, i) => i !== index));
2366
- },
2367
- renderDragHandle: DragHandle
2368
- })));
2369
- }
2370
- MultipleMediaEditor.defaultProps = {
2371
- isInitiallyDisabled: true
2372
- };
2373
-
2374
- const resolveAsset = () => Promise.resolve(); // we don't want to show scheduled actions for resources
2375
-
2376
-
2377
- const resolveScheduledActions = () => Promise.resolve([]);
2378
-
2379
- function ContentfulEntryCard({
2380
- info,
2381
- isDisabled,
2382
- renderDragHandle,
2383
- onRemove,
2384
- onMoveTop,
2385
- onMoveBottom,
2386
- getEntryRouteHref
2387
- }) {
2388
- const resourceSys = info.resource.sys;
2389
- const spaceId = resourceSys.space.sys.id;
2390
- const environmentId = resourceSys.environment.sys.id;
2391
- const entryId = resourceSys.id;
2392
- const resourceHref = getEntryRouteHref({
2393
- spaceId,
2394
- environmentId,
2395
- entryId
2396
- }); // TODO: move this into `sdk.navigator.openEntry()`, note that it's signature only include the entry id (not a space or environment)
2397
-
2398
- const openEntryDetail = () => {
2399
- window.open(resourceHref, '_blank', 'noopener,noreferrer');
2400
- };
2401
-
2402
- return React.createElement(WrappedEntryCard, {
2403
- entry: info.resource,
2404
- isDisabled: isDisabled,
2405
- hasCardEditActions: false,
2406
- contentType: info.contentType,
2407
- // we use the default locale from the space the entry belongs to
2408
- // as we assume this gives a more consistent behaviour.
2409
- // locales will inevitably differ from space to space, so it's likely
2410
- // that the current locale does not exist in the "remote" space
2411
- localeCode: info.defaultLocaleCode,
2412
- defaultLocaleCode: info.defaultLocaleCode,
2413
- size: "small",
2414
- getAsset: resolveAsset,
2415
- getEntityScheduledActions: resolveScheduledActions,
2416
- spaceName: info.space.name,
2417
- renderDragHandle: renderDragHandle,
2418
- isClickable: true,
2419
- onEdit: openEntryDetail,
2420
- hasCardRemoveActions: Boolean(onRemove),
2421
- onRemove: onRemove,
2422
- onMoveBottom: onMoveBottom,
2423
- onMoveTop: onMoveTop,
2424
- entryUrl: resourceHref
2425
- });
2426
- }
2427
-
2428
- const styles$7 = {
2429
- card: /*#__PURE__*/emotion.css({
2430
- position: 'relative'
2431
- })
2432
- };
2433
- function UnsupportedEntityCard(props) {
2434
- return React__default.createElement(f36Components.Card, {
2435
- className: styles$7.card
2436
- }, React__default.createElement(f36Components.SectionHeading, {
2437
- marginBottom: "none"
2438
- }, "Resource type ", props.entityType, " is currently not supported"));
2439
- }
2440
-
2441
- function ResourceCardSkeleton() {
2442
- return React.createElement(f36Components.EntryCard, {
2443
- size: "small",
2444
- isLoading: true
2445
- });
2446
- }
2447
-
2448
- function ExistingResourceCard(props) {
2449
- const {
2450
- resourceLink,
2451
- inView,
2452
- index = 0
2453
- } = props;
2454
- const resourceOptions = {
2455
- priority: index * -1,
2456
- enabled: inView
2457
- };
2458
- const {
2459
- data,
2460
- error
2461
- } = useResource(resourceLink.sys.linkType, resourceLink.sys.urn, resourceOptions);
2462
-
2463
- if (!data && !error) {
2464
- return React.createElement(ResourceCardSkeleton, null);
2465
- }
2466
-
2467
- if (data) {
2468
- return React.createElement(ContentfulEntryCard, {
2469
- info: data,
2470
- ...props
2471
- });
2472
- }
2473
-
2474
- if (isUnsupportedError(error)) {
2475
- return React.createElement(UnsupportedEntityCard, {
2476
- entityType: resourceLink.sys.linkType
2477
- });
2478
- }
2479
-
2480
- return React.createElement(MissingEntityCard, {
2481
- entityType: "Entry",
2482
- isDisabled: props.isDisabled,
2483
- onRemove: props.onRemove
2484
- });
2485
- }
2486
-
2487
- function ResourceCardWrapper(props) {
2488
- if (!props.resourceLink) {
2489
- return null;
2490
- }
2491
-
2492
- return React.createElement(ExistingResourceCard, { ...props,
2493
- resourceLink: props.resourceLink,
2494
- getEntryRouteHref: props.getEntryRouteHref
2495
- });
2496
- }
2497
-
2498
- function ResourceCard(props) {
2499
- const {
2500
- ref,
2501
- inView
2502
- } = reactIntersectionObserver.useInView({
2503
- triggerOnce: true,
2504
- rootMargin: '300px 0px 0px 300px'
2505
- }); // Forma does not offer us to pass refs, so we need an additional wrapper here
2506
-
2507
- return React.createElement("div", {
2508
- ref: ref
2509
- }, React.createElement(ResourceCardWrapper, { ...props,
2510
- inView: inView
2511
- }));
2512
- }
2513
-
2514
- const toLinkItem = (entry, apiUrl) => ({
2515
- sys: {
2516
- type: 'ResourceLink',
2517
- linkType: 'Contentful:Entry',
2518
- urn: entry.sys.urn ?? `crn:${apiUrl}:::content:spaces/${entry.sys.space.sys.id}/entries/${entry.sys.id}`
2519
- }
2520
- });
2521
-
2522
- const getUpdatedValue = (field, entries, apiUrl) => {
2523
- const multiple = field.type === 'Array';
2524
-
2525
- if (multiple) {
2526
- const linkItems = entries.map(entry => toLinkItem(entry, apiUrl));
2527
- const prevValue = field.getValue() || [];
2528
- return [...prevValue, ...linkItems];
2529
- } else {
2530
- return toLinkItem(entries[0], apiUrl);
2531
- }
2532
- };
2533
-
2534
- function useResourceLinkActions({
2535
- dialogs,
2536
- field,
2537
- onAfterLink,
2538
- apiUrl
2539
- }) {
2540
- const handleAfterLink = React.useCallback(entries => {
2541
- if (!onAfterLink) {
2542
- return;
2543
- }
2544
-
2545
- entries.forEach(onAfterLink);
2546
- }, [onAfterLink]);
2547
- const onLinkedExisting = React.useMemo(() => {
2548
- return entries => {
2549
- const updatedValue = getUpdatedValue(field, entries, apiUrl);
2550
- field.setValue(updatedValue);
2551
- handleAfterLink(entries);
2552
- };
2553
- }, [field, handleAfterLink, apiUrl]);
2554
- const multiple = field.type === 'Array';
2555
- const onLinkExisting = React.useMemo(() => {
2556
- const promptSelection = multiple ? async () => // @ts-expect-error wait for update of app-sdk version
2557
- await dialogs.selectMultipleResourceEntries({
2558
- // @ts-expect-error wait for update of app-sdk version
2559
- allowedResources: field.allowedResources
2560
- }) : async () => [// @ts-expect-error wait for update of app-sdk version
2561
- await dialogs.selectSingleResourceEntry({
2562
- // @ts-expect-error wait for update of app-sdk version
2563
- allowedResources: field.allowedResources
2564
- })];
2565
- return async () => {
2566
- const res = await promptSelection();
2567
-
2568
- if (!res) {
2569
- return;
2570
- }
2571
-
2572
- onLinkedExisting(res);
2573
- }; // @ts-expect-error wait for update of app-sdk version
2574
- }, [dialogs, field.allowedResources, multiple, onLinkedExisting]);
2575
- return {
2576
- onLinkExisting,
2577
- onLinkedExisting,
2578
- // hardcoded values to match interface for standard reference field actions
2579
- entityType: 'Entry',
2580
- contentTypes: [],
2581
- canCreateEntity: false,
2582
- canLinkMultiple: multiple,
2583
- canLinkEntity: true,
2584
- isDisabled: false,
2585
- isEmpty: false,
2586
- isFull: false,
2587
- // eslint-disable-next-line -- hardcoded values to match interface for standard reference field actions
2588
- onCreate: async () => {},
2589
- // eslint-disable-next-line -- hardcoded values to match interface for standard reference field actions
2590
- onCreated: () => {}
2591
- };
2592
- }
2593
-
2594
- function ResourceEditor(props) {
2595
- const {
2596
- setValue,
2597
- items,
2598
- apiUrl
2599
- } = props;
2600
- const onSortStart = React.useCallback((_, event) => event.preventDefault(), []);
2601
- const onSortEnd = React.useCallback(({
2602
- oldIndex,
2603
- newIndex
2604
- }) => {
2605
- const newItems = arrayMove(items, oldIndex, newIndex);
2606
- setValue(newItems);
2607
- }, [items, setValue]);
2608
- const onMove = React.useCallback((oldIndex, newIndex) => {
2609
- const newItems = arrayMove(items, oldIndex, newIndex);
2610
- setValue(newItems);
2611
- }, [items, setValue]);
2612
- const onRemoteItemAtIndex = React.useCallback(index => {
2613
- setValue(items.filter((_v, i) => i !== index));
2614
- }, [items, setValue]);
2615
- const {
2616
- dialogs,
2617
- field
2618
- } = props.sdk;
2619
- const linkActionsProps = useResourceLinkActions({
2620
- dialogs,
2621
- field,
2622
- apiUrl
2623
- });
2624
- return React.createElement(React.Fragment, null, props.children({ ...props,
2625
- onSortStart,
2626
- onSortEnd,
2627
- onMove,
2628
- onRemoteItemAtIndex
2629
- }), React.createElement(CombinedLinkEntityActions, { ...linkActionsProps,
2630
- renderCustomActions: props.renderCustomActions
2631
- }));
2632
- } // provides memoized callbacks bound to a given item
2633
-
2634
-
2635
- function WithPerItemCallbacks({
2636
- listLength,
2637
- index,
2638
- onMove,
2639
- onRemoteItemAtIndex,
2640
- children
2641
- }) {
2642
- const handleMoveTop = React.useMemo(() => index > 0 ? () => onMove(index, 0) : undefined, [index, onMove]);
2643
- const handleMoveBottom = React.useMemo(() => index < listLength - 1 ? () => onMove(index, listLength - 1) : undefined, [index, onMove, listLength]);
2644
- const handleRemove = React.useCallback(() => onRemoteItemAtIndex(index), [index, onRemoteItemAtIndex]);
2645
- return React.createElement(React.Fragment, null, children({
2646
- onMoveBottom: handleMoveBottom,
2647
- onMoveTop: handleMoveTop,
2648
- onRemove: handleRemove
2649
- }));
2650
- }
2651
-
2652
- const EMPTY_ARRAY = [];
2653
- function MultipleResourceReferenceEditor(props) {
2654
- return React.createElement(EntityProvider, {
2655
- sdk: props.sdk
2656
- }, React.createElement(fieldEditorShared.FieldConnector, {
2657
- throttle: 0,
2658
- field: props.sdk.field,
2659
- isInitiallyDisabled: props.isInitiallyDisabled,
2660
- isEqualValues: deepEqual
2661
- }, ({
2662
- value,
2663
- disabled,
2664
- setValue,
2665
- externalReset
2666
- }) => {
2667
- return React.createElement(ResourceEditor, { ...props,
2668
- items: value || EMPTY_ARRAY,
2669
- isDisabled: disabled,
2670
- setValue: setValue,
2671
- renderCustomActions: props.renderCustomActions,
2672
- key: `${externalReset}-list`
2673
- }, editorProps => React.createElement(SortableLinkList, { ...editorProps
2674
- }, ({
2675
- item,
2676
- isDisabled,
2677
- DragHandle,
2678
- index
2679
- }) => React.createElement(WithPerItemCallbacks, {
2680
- index: index,
2681
- onMove: editorProps.onMove,
2682
- onRemoteItemAtIndex: editorProps.onRemoteItemAtIndex,
2683
- listLength: (value == null ? void 0 : value.length) || 0
2684
- }, ({
2685
- onMoveBottom,
2686
- onMoveTop,
2687
- onRemove
2688
- }) => React.createElement(ResourceCard, {
2689
- index: index,
2690
- resourceLink: item,
2691
- isDisabled: isDisabled,
2692
- renderDragHandle: DragHandle,
2693
- onMoveTop: onMoveTop,
2694
- onMoveBottom: onMoveBottom,
2695
- onRemove: onRemove,
2696
- getEntryRouteHref: props.getEntryRouteHref
2697
- }))));
2698
- }));
2699
- }
2700
-
2701
- function SingleResourceReferenceEditor(props) {
2702
- const {
2703
- dialogs,
2704
- field
2705
- } = props.sdk;
2706
- const linkActionsProps = useResourceLinkActions({
2707
- dialogs,
2708
- field,
2709
- apiUrl: props.apiUrl
2710
- });
2711
- return React.createElement(EntityProvider, {
2712
- sdk: props.sdk
2713
- }, React.createElement(fieldEditorShared.FieldConnector, {
2714
- throttle: 0,
2715
- field: props.sdk.field,
2716
- isInitiallyDisabled: props.isInitiallyDisabled,
2717
- isEqualValues: deepEqual
2718
- }, ({
2719
- value,
2720
- disabled
2721
- }) => {
2722
- return value ? React.createElement(ResourceCard, {
2723
- onRemove: () => props.sdk.field.removeValue(),
2724
- resourceLink: value,
2725
- isDisabled: disabled,
2726
- getEntryRouteHref: props.getEntryRouteHref
2727
- }) : React.createElement(CombinedLinkEntityActions, { ...linkActionsProps,
2728
- renderCustomActions: props.renderCustomActions
2729
- });
2730
- }));
2731
- }
2732
-
2733
- exports.AssetThumbnail = AssetThumbnail;
2734
- exports.CombinedLinkActions = CombinedLinkActions;
2735
- exports.CreateEntryLinkButton = CreateEntryLinkButton;
2736
- exports.CreateEntryMenuTrigger = CreateEntryMenuTrigger;
2737
- exports.EntityProvider = EntityProvider;
2738
- exports.MissingEntityCard = MissingEntityCard;
2739
- exports.MultipleEntryReferenceEditor = MultipleEntryReferenceEditor;
2740
- exports.MultipleMediaEditor = MultipleMediaEditor;
2741
- exports.MultipleResourceReferenceEditor = MultipleResourceReferenceEditor;
2742
- exports.ScheduledIconWithTooltip = ScheduledIconWithTooltip;
2743
- exports.SingleEntryReferenceEditor = SingleEntryReferenceEditor;
2744
- exports.SingleMediaEditor = SingleMediaEditor;
2745
- exports.SingleResourceReferenceEditor = SingleResourceReferenceEditor;
2746
- exports.SortableLinkList = SortableLinkList;
2747
- exports.WrappedAssetCard = WrappedAssetCard;
2748
- exports.WrappedEntryCard = WrappedEntryCard;
2749
- exports.getScheduleTooltipContent = getScheduleTooltipContent;
2750
- exports.useEntity = useEntity;
2751
- exports.useEntityLoader = useEntityLoader;
2752
- exports.useResource = useResource;
2753
- //# sourceMappingURL=field-editor-reference.cjs.development.js.map