@contentful/field-editor-reference 5.19.0 → 5.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/__fixtures__/FakeSdk.js +3 -3
- package/dist/cjs/__fixtures__/asset/index.js +10 -10
- package/dist/cjs/__fixtures__/content-type/index.js +1 -1
- package/dist/cjs/__fixtures__/entry/index.js +7 -7
- package/dist/cjs/__fixtures__/fixtures.js +8 -6
- package/dist/cjs/__fixtures__/locale/index.js +2 -2
- package/dist/cjs/__fixtures__/space/index.js +1 -1
- package/dist/cjs/assets/MultipleMediaEditor.js +7 -5
- package/dist/cjs/assets/SingleMediaEditor.js +6 -4
- package/dist/cjs/assets/WrappedAssetCard/AssetCardActions.js +21 -19
- package/dist/cjs/assets/WrappedAssetCard/FetchingWrappedAssetCard.js +18 -11
- package/dist/cjs/assets/WrappedAssetCard/WrappedAssetCard.js +20 -11
- package/dist/cjs/assets/WrappedAssetCard/WrappedAssetLink.js +12 -9
- package/dist/cjs/assets/index.js +3 -3
- package/dist/cjs/common/EntityStore.js +53 -53
- package/dist/cjs/common/MultipleReferenceEditor.js +20 -11
- package/dist/cjs/common/ReferenceEditor.js +7 -5
- package/dist/cjs/common/SingleReferenceEditor.js +11 -7
- package/dist/cjs/common/SortableLinkList.js +14 -14
- package/dist/cjs/common/customCardTypes.js +4 -2
- package/dist/cjs/common/queryClient.js +102 -0
- package/dist/cjs/common/useContentTypePermissions.js +3 -1
- package/dist/cjs/common/useEditorPermissions.js +15 -3
- package/dist/cjs/common/useEditorPermissions.spec.js +13 -12
- package/dist/cjs/components/AssetThumbnail/AssetThumbnail.js +5 -3
- package/dist/cjs/components/CreateEntryLinkButton/CreateEntryLinkButton.js +13 -9
- package/dist/cjs/components/CreateEntryLinkButton/CreateEntryLinkButton.spec.js +17 -15
- package/dist/cjs/components/CreateEntryLinkButton/CreateEntryMenuTrigger.js +29 -19
- package/dist/cjs/components/CreateEntryLinkButton/CreateEntryMenuTrigger.spec.js +14 -12
- package/dist/cjs/components/LinkActions/CombinedLinkActions.js +28 -21
- package/dist/cjs/components/LinkActions/LinkActions.js +17 -15
- package/dist/cjs/components/LinkActions/LinkEntityActions.js +26 -17
- package/dist/cjs/components/LinkActions/NoLinkPermissionsInfo.js +5 -3
- package/dist/cjs/components/LinkActions/helpers.js +10 -5
- package/dist/cjs/components/LinkActions/redesignStyles.js +4 -4
- package/dist/cjs/components/LinkActions/styles.js +1 -1
- package/dist/cjs/components/MissingEntityCard/MissingEntityCard.js +11 -9
- package/dist/cjs/components/ResourceEntityErrorCard/ResourceEntityErrorCard.js +6 -4
- package/dist/cjs/components/ResourceEntityErrorCard/UnsupportedEntityCard.js +6 -4
- package/dist/cjs/components/ScheduledIconWithTooltip/ScheduleTooltip.js +10 -8
- package/dist/cjs/components/ScheduledIconWithTooltip/ScheduledIconWithTooltip.js +9 -4
- package/dist/cjs/components/ScheduledIconWithTooltip/formatDateAndTime.js +5 -4
- package/dist/cjs/components/SpaceName/SpaceName.js +9 -7
- package/dist/cjs/components/index.js +12 -12
- package/dist/cjs/entries/MultipleEntryReferenceEditor.js +9 -7
- package/dist/cjs/entries/SingleEntryReferenceEditor.js +7 -5
- package/dist/cjs/entries/WrappedEntryCard/FetchingWrappedEntryCard.js +20 -11
- package/dist/cjs/entries/WrappedEntryCard/WrappedEntryCard.js +23 -17
- package/dist/cjs/entries/index.js +3 -3
- package/dist/cjs/index.js +38 -34
- package/dist/cjs/resources/Cards/ContentfulEntryCard.js +13 -4
- package/dist/cjs/resources/Cards/ResourceCard.js +16 -12
- package/dist/cjs/resources/Cards/ResourceCard.spec.js +20 -17
- package/dist/cjs/resources/MultipleResourceReferenceEditor.js +20 -17
- package/dist/cjs/resources/MultipleResourceReferenceEditor.spec.js +34 -13
- package/dist/cjs/resources/SingleResourceReferenceEditor.js +11 -9
- package/dist/cjs/resources/SingleResourceReferenceEditor.spec.js +13 -6
- package/dist/cjs/resources/testHelpers/resourceEditorHelpers.js +12 -5
- package/dist/cjs/resources/useResourceLinkActions.js +11 -2
- package/dist/cjs/types.js +3 -3
- package/dist/cjs/utils/fromFieldValidations.js +2 -1
- package/dist/cjs/utils/useSortIDs.js +6 -4
- package/dist/esm/__fixtures__/FakeSdk.js +3 -3
- package/dist/esm/assets/MultipleMediaEditor.js +3 -3
- package/dist/esm/assets/SingleMediaEditor.js +2 -2
- package/dist/esm/assets/WrappedAssetCard/AssetCardActions.js +12 -12
- package/dist/esm/assets/WrappedAssetCard/FetchingWrappedAssetCard.js +14 -9
- package/dist/esm/assets/WrappedAssetCard/WrappedAssetCard.js +15 -7
- package/dist/esm/assets/WrappedAssetCard/WrappedAssetLink.js +7 -6
- package/dist/esm/common/EntityStore.js +40 -42
- package/dist/esm/common/MultipleReferenceEditor.js +16 -9
- package/dist/esm/common/ReferenceEditor.js +2 -2
- package/dist/esm/common/SingleReferenceEditor.js +7 -5
- package/dist/esm/common/SortableLinkList.js +12 -12
- package/dist/esm/common/queryClient.js +44 -0
- package/dist/esm/common/useContentTypePermissions.js +3 -1
- package/dist/esm/common/useEditorPermissions.js +15 -3
- package/dist/esm/common/useEditorPermissions.spec.js +13 -12
- package/dist/esm/components/AssetThumbnail/AssetThumbnail.js +1 -1
- package/dist/esm/components/CreateEntryLinkButton/CreateEntryLinkButton.js +7 -5
- package/dist/esm/components/CreateEntryLinkButton/CreateEntryLinkButton.spec.js +12 -12
- package/dist/esm/components/CreateEntryLinkButton/CreateEntryMenuTrigger.js +23 -15
- package/dist/esm/components/CreateEntryLinkButton/CreateEntryMenuTrigger.spec.js +9 -8
- package/dist/esm/components/LinkActions/CombinedLinkActions.js +30 -19
- package/dist/esm/components/LinkActions/LinkActions.js +9 -9
- package/dist/esm/components/LinkActions/LinkEntityActions.js +18 -11
- package/dist/esm/components/LinkActions/NoLinkPermissionsInfo.js +1 -1
- package/dist/esm/components/LinkActions/helpers.js +7 -2
- package/dist/esm/components/MissingEntityCard/MissingEntityCard.js +6 -6
- package/dist/esm/components/ResourceEntityErrorCard/ResourceEntityErrorCard.js +2 -2
- package/dist/esm/components/ResourceEntityErrorCard/UnsupportedEntityCard.js +2 -2
- package/dist/esm/components/ScheduledIconWithTooltip/ScheduleTooltip.js +3 -3
- package/dist/esm/components/ScheduledIconWithTooltip/ScheduledIconWithTooltip.js +5 -2
- package/dist/esm/components/ScheduledIconWithTooltip/formatDateAndTime.js +11 -2
- package/dist/esm/components/SpaceName/SpaceName.js +4 -4
- package/dist/esm/entries/MultipleEntryReferenceEditor.js +5 -5
- package/dist/esm/entries/SingleEntryReferenceEditor.js +3 -3
- package/dist/esm/entries/WrappedEntryCard/FetchingWrappedEntryCard.js +15 -8
- package/dist/esm/entries/WrappedEntryCard/WrappedEntryCard.js +18 -14
- package/dist/esm/index.js +1 -0
- package/dist/esm/resources/Cards/ContentfulEntryCard.js +9 -2
- package/dist/esm/resources/Cards/ResourceCard.js +12 -10
- package/dist/esm/resources/Cards/ResourceCard.spec.js +12 -11
- package/dist/esm/resources/MultipleResourceReferenceEditor.js +14 -13
- package/dist/esm/resources/MultipleResourceReferenceEditor.spec.js +30 -11
- package/dist/esm/resources/SingleResourceReferenceEditor.js +6 -6
- package/dist/esm/resources/SingleResourceReferenceEditor.spec.js +9 -4
- package/dist/esm/resources/testHelpers/resourceEditorHelpers.js +9 -2
- package/dist/esm/resources/useResourceLinkActions.js +11 -2
- package/dist/esm/utils/fromFieldValidations.js +1 -0
- package/dist/esm/utils/useSortIDs.js +2 -2
- package/dist/types/common/EntityStore.d.ts +1 -1
- package/dist/types/common/queryClient.d.ts +9 -0
- package/dist/types/index.d.ts +1 -0
- package/package.json +2 -2
|
@@ -19,15 +19,17 @@ const redesignStyles = {
|
|
|
19
19
|
maxWidth: '300px'
|
|
20
20
|
})
|
|
21
21
|
};
|
|
22
|
-
export const CreateEntryLinkButton = ({ contentTypes
|
|
22
|
+
export const CreateEntryLinkButton = ({ contentTypes, onSelect, customDropdownItems, text, testId, hasPlusIcon = false, useExperimentalStyles, suggestedContentTypeId, dropdownSettings, disabled = false })=>{
|
|
23
23
|
contentTypes = contentTypes.sort((a, b)=>a.name.localeCompare(b.name));
|
|
24
24
|
const suggestedContentType = contentTypes.find((ct)=>ct.sys.id === suggestedContentTypeId);
|
|
25
25
|
const buttonText = text || `Add ${get(suggestedContentType || (contentTypes.length === 1 ? contentTypes[0] : {}), 'name', 'entry')}`;
|
|
26
26
|
const hasDropdown = contentTypes.length > 1 || customDropdownItems;
|
|
27
|
-
|
|
27
|
+
// TODO: Introduce `icon: string` and remove `hasPlusIcon` or remove "Plus" if we keep new layout.
|
|
28
|
+
const plusIcon = hasPlusIcon ? /*#__PURE__*/ React.createElement(PlusIcon, null) : undefined;
|
|
29
|
+
// TODO: Always use "New content" here if we fully switch to new layout.
|
|
28
30
|
const contentTypesLabel = useExperimentalStyles ? 'New content' : undefined;
|
|
29
31
|
const styles = useExperimentalStyles ? redesignStyles : standardStyles;
|
|
30
|
-
return React.createElement(CreateEntryMenuTrigger, {
|
|
32
|
+
return /*#__PURE__*/ React.createElement(CreateEntryMenuTrigger, {
|
|
31
33
|
contentTypes: contentTypes,
|
|
32
34
|
suggestedContentTypeId: suggestedContentTypeId,
|
|
33
35
|
contentTypesLabel: contentTypesLabel,
|
|
@@ -35,8 +37,8 @@ export const CreateEntryLinkButton = ({ contentTypes , onSelect , customDropdown
|
|
|
35
37
|
testId: testId,
|
|
36
38
|
dropdownSettings: dropdownSettings,
|
|
37
39
|
customDropdownItems: customDropdownItems
|
|
38
|
-
}, ({ isSelecting
|
|
39
|
-
endIcon: hasDropdown ? React.createElement(ChevronDownIcon, null) : undefined,
|
|
40
|
+
}, ({ isSelecting })=>/*#__PURE__*/ React.createElement(Button, {
|
|
41
|
+
endIcon: hasDropdown ? /*#__PURE__*/ React.createElement(ChevronDownIcon, null) : undefined,
|
|
40
42
|
variant: "secondary",
|
|
41
43
|
className: styles.action,
|
|
42
44
|
isDisabled: disabled || isSelecting,
|
|
@@ -37,14 +37,14 @@ describe('CreateEntryLinkButton general', ()=>{
|
|
|
37
37
|
}
|
|
38
38
|
};
|
|
39
39
|
it('renders with multiple content types as list', ()=>{
|
|
40
|
-
const { getByTestId
|
|
40
|
+
const { getByTestId } = render(/*#__PURE__*/ React.createElement(CreateEntryLinkButton, props));
|
|
41
41
|
expect(getByTestId('create-entry-button-menu-trigger')).toBeDefined();
|
|
42
42
|
const link = findButton(getByTestId);
|
|
43
43
|
expect(link).toBeDefined();
|
|
44
44
|
expect(link.textContent).toBe('Add entry');
|
|
45
45
|
});
|
|
46
46
|
it('renders dropdown menu on click when with multiple content types', ()=>{
|
|
47
|
-
const { getByTestId
|
|
47
|
+
const { getByTestId } = render(/*#__PURE__*/ React.createElement(CreateEntryLinkButton, props));
|
|
48
48
|
fireEvent.click(findButton(getByTestId));
|
|
49
49
|
const menu = getByTestId('add-entry-menu');
|
|
50
50
|
expect(menu).toBeDefined();
|
|
@@ -54,7 +54,7 @@ describe('CreateEntryLinkButton general', ()=>{
|
|
|
54
54
|
});
|
|
55
55
|
it('renders suggestedContentType as text when given', ()=>{
|
|
56
56
|
const suggestedContentTypeId = 'ID_2';
|
|
57
|
-
const { getByTestId
|
|
57
|
+
const { getByTestId } = render(/*#__PURE__*/ React.createElement(CreateEntryLinkButton, {
|
|
58
58
|
...props,
|
|
59
59
|
suggestedContentTypeId: suggestedContentTypeId
|
|
60
60
|
}));
|
|
@@ -64,7 +64,7 @@ describe('CreateEntryLinkButton general', ()=>{
|
|
|
64
64
|
expect(button.textContent).toBe(`Add ${CONTENT_TYPE_2.name}`);
|
|
65
65
|
});
|
|
66
66
|
it('renders the name of the content type as part of the text if only 1 content type is given', ()=>{
|
|
67
|
-
const { getByTestId
|
|
67
|
+
const { getByTestId } = render(/*#__PURE__*/ React.createElement(CreateEntryLinkButton, {
|
|
68
68
|
onSelect: props.onSelect,
|
|
69
69
|
contentTypes: [
|
|
70
70
|
CONTENT_TYPE_1
|
|
@@ -80,7 +80,7 @@ describe('CreateEntryLinkButton general', ()=>{
|
|
|
80
80
|
text: 'CUSTOM_TEXT',
|
|
81
81
|
hasPlusIcon: true
|
|
82
82
|
};
|
|
83
|
-
const { getByTestId
|
|
83
|
+
const { getByTestId } = render(/*#__PURE__*/ React.createElement(CreateEntryLinkButton, {
|
|
84
84
|
...props,
|
|
85
85
|
...propsOverrides
|
|
86
86
|
}));
|
|
@@ -101,13 +101,13 @@ describe('CreateEntryLinkButton with multiple entries', ()=>{
|
|
|
101
101
|
}
|
|
102
102
|
};
|
|
103
103
|
it('should render dropdown items for each content type', ()=>{
|
|
104
|
-
const { getByTestId
|
|
104
|
+
const { getByTestId, getAllByTestId } = render(/*#__PURE__*/ React.createElement(CreateEntryLinkButton, props));
|
|
105
105
|
fireEvent.click(findButton(getByTestId));
|
|
106
106
|
expect(getAllByTestId('contentType')).toHaveLength(props.contentTypes.length);
|
|
107
107
|
});
|
|
108
108
|
it('calls onSelect after click on menu item', ()=>{
|
|
109
109
|
const selectSpy = jest.fn();
|
|
110
|
-
const { getByTestId
|
|
110
|
+
const { getByTestId, getAllByTestId } = render(/*#__PURE__*/ React.createElement(CreateEntryLinkButton, {
|
|
111
111
|
...props,
|
|
112
112
|
onSelect: selectSpy
|
|
113
113
|
}));
|
|
@@ -127,7 +127,7 @@ describe('CreateEntryLinkButton with a single entry', ()=>{
|
|
|
127
127
|
};
|
|
128
128
|
it('should fire the onSelect function when clicked', ()=>{
|
|
129
129
|
const onSelectStub = jest.fn();
|
|
130
|
-
const { getByTestId
|
|
130
|
+
const { getByTestId } = render(/*#__PURE__*/ React.createElement(CreateEntryLinkButton, {
|
|
131
131
|
...props,
|
|
132
132
|
onSelect: onSelectStub
|
|
133
133
|
}));
|
|
@@ -139,7 +139,7 @@ describe('CreateEntryLinkButton with a single entry', ()=>{
|
|
|
139
139
|
describe('CreateEntryLinkButton common', ()=>{
|
|
140
140
|
it('should render a spinner if onSelect returns a promise', async ()=>{
|
|
141
141
|
const onSelect = jest.fn(()=>new Promise((resolve)=>setTimeout(resolve, 1000)));
|
|
142
|
-
const { getByTestId
|
|
142
|
+
const { getByTestId, container } = render(/*#__PURE__*/ React.createElement(CreateEntryLinkButton, {
|
|
143
143
|
contentTypes: [
|
|
144
144
|
CONTENT_TYPE_1
|
|
145
145
|
],
|
|
@@ -155,7 +155,7 @@ describe('CreateEntryLinkButton common', ()=>{
|
|
|
155
155
|
});
|
|
156
156
|
it('should hide a spinner after the promise from onSelect resolves', async ()=>{
|
|
157
157
|
const onSelect = jest.fn(()=>new Promise((resolve)=>setTimeout(resolve, 500)));
|
|
158
|
-
const { getByTestId
|
|
158
|
+
const { getByTestId, container } = render(/*#__PURE__*/ React.createElement(CreateEntryLinkButton, {
|
|
159
159
|
contentTypes: [
|
|
160
160
|
CONTENT_TYPE_1
|
|
161
161
|
],
|
|
@@ -172,7 +172,7 @@ describe('CreateEntryLinkButton common', ()=>{
|
|
|
172
172
|
});
|
|
173
173
|
it('does not emit onSelect on subsequent click before the promise from onSelect resolves', async ()=>{
|
|
174
174
|
const onSelect = jest.fn(()=>new Promise((resolve)=>setTimeout(()=>resolve(undefined), 200)));
|
|
175
|
-
const { getByTestId
|
|
175
|
+
const { getByTestId } = render(/*#__PURE__*/ React.createElement(CreateEntryLinkButton, {
|
|
176
176
|
contentTypes: [
|
|
177
177
|
CONTENT_TYPE_1
|
|
178
178
|
],
|
|
@@ -188,7 +188,7 @@ describe('CreateEntryLinkButton common', ()=>{
|
|
|
188
188
|
});
|
|
189
189
|
it('emits onSelect on subsequent click after the promise from onSelect resolves', async ()=>{
|
|
190
190
|
const onSelect = jest.fn(()=>Promise.resolve());
|
|
191
|
-
const { getByTestId
|
|
191
|
+
const { getByTestId } = render(/*#__PURE__*/ React.createElement(CreateEntryLinkButton, {
|
|
192
192
|
contentTypes: [
|
|
193
193
|
CONTENT_TYPE_1
|
|
194
194
|
],
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useRef, useEffect } from 'react';
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */ import React, { useState, useRef, useEffect } from 'react';
|
|
2
2
|
import { TextInput, Menu } from '@contentful/f36-components';
|
|
3
3
|
import { SearchIcon } from '@contentful/f36-icons';
|
|
4
4
|
import tokens from '@contentful/f36-tokens';
|
|
@@ -36,16 +36,23 @@ const styles = {
|
|
|
36
36
|
borderColor: tokens.gray200
|
|
37
37
|
})
|
|
38
38
|
};
|
|
39
|
-
export const CreateEntryMenuTrigger = ({ contentTypes
|
|
39
|
+
export const CreateEntryMenuTrigger = ({ contentTypes, suggestedContentTypeId, contentTypesLabel, onSelect, testId, dropdownSettings = {
|
|
40
40
|
position: 'bottom-left'
|
|
41
|
-
}
|
|
41
|
+
}, customDropdownItems, children, menuProps })=>{
|
|
42
42
|
const [isOpen, setOpen] = useState(false);
|
|
43
43
|
const [isSelecting, setSelecting] = useState(false);
|
|
44
44
|
const [searchInput, setSearchInput] = useState('');
|
|
45
45
|
const wrapper = useRef(null);
|
|
46
46
|
const textField = useRef(null);
|
|
47
47
|
const menuListRef = useRef(null);
|
|
48
|
-
|
|
48
|
+
/*
|
|
49
|
+
By default, dropdown wraps it's content, so it's width = the width of the widest item
|
|
50
|
+
During search, menu items change, and so the widest menu item can change
|
|
51
|
+
This leads to menu always changing it's width
|
|
52
|
+
To prevent this, we get the width of the menu item after the first mount of a dropdown (when all the content is displayed)
|
|
53
|
+
And hardcode it through the class name. This way we ensure that even during search the menu will keep that max width
|
|
54
|
+
That it had on initial mount and that fits any menu item in has
|
|
55
|
+
*/ const [dropdownWidth, setDropdownWidth] = useState();
|
|
49
56
|
const hasDropdown = contentTypes.length > 1 || !!customDropdownItems;
|
|
50
57
|
const closeMenu = ()=>setOpen(false);
|
|
51
58
|
useEffect(()=>{
|
|
@@ -70,6 +77,7 @@ export const CreateEntryMenuTrigger = ({ contentTypes , suggestedContentTypeId ,
|
|
|
70
77
|
const handleSelect = (item)=>{
|
|
71
78
|
closeMenu();
|
|
72
79
|
const res = onSelect(item.sys.id);
|
|
80
|
+
// TODO: Convert to controllable component.
|
|
73
81
|
if (res && typeof res.then === 'function') {
|
|
74
82
|
setSelecting(true);
|
|
75
83
|
res.then(()=>setSelecting(false), ()=>setSelecting(false));
|
|
@@ -89,28 +97,28 @@ export const CreateEntryMenuTrigger = ({ contentTypes , suggestedContentTypeId ,
|
|
|
89
97
|
}, [
|
|
90
98
|
isOpen
|
|
91
99
|
]);
|
|
92
|
-
const renderSearchResultsCount = (resultsLength)=>resultsLength ? React.createElement(Menu.SectionTitle, {
|
|
100
|
+
const renderSearchResultsCount = (resultsLength)=>resultsLength ? /*#__PURE__*/ React.createElement(Menu.SectionTitle, {
|
|
93
101
|
testId: "add-entru-menu-search-results"
|
|
94
102
|
}, resultsLength, " result", resultsLength > 1 ? 's' : '') : null;
|
|
95
103
|
const isSearchable = contentTypes.length > MAX_ITEMS_WITHOUT_SEARCH;
|
|
96
104
|
const maxDropdownHeight = suggestedContentTypeId ? 300 : 250;
|
|
97
105
|
const suggestedContentType = contentTypes.find((ct)=>ct.sys.id === suggestedContentTypeId);
|
|
98
106
|
const filteredContentTypes = contentTypes.filter((ct)=>!searchInput || get(ct, 'name', 'Untitled').toLowerCase().includes(searchInput.toLowerCase()));
|
|
99
|
-
return React.createElement("span", {
|
|
107
|
+
return /*#__PURE__*/ React.createElement("span", {
|
|
100
108
|
className: styles.wrapper,
|
|
101
109
|
ref: wrapper,
|
|
102
110
|
"data-test-id": testId
|
|
103
|
-
}, React.createElement(Menu, {
|
|
111
|
+
}, /*#__PURE__*/ React.createElement(Menu, {
|
|
104
112
|
placement: menuPlacementMap[dropdownSettings.position],
|
|
105
113
|
isAutoalignmentEnabled: dropdownSettings.isAutoalignmentEnabled,
|
|
106
114
|
isOpen: isOpen,
|
|
107
115
|
onClose: closeMenu,
|
|
108
116
|
onOpen: handleMenuOpen,
|
|
109
117
|
...menuProps
|
|
110
|
-
}, React.createElement(Menu.Trigger, null, children({
|
|
118
|
+
}, /*#__PURE__*/ React.createElement(Menu.Trigger, null, children({
|
|
111
119
|
isOpen,
|
|
112
120
|
isSelecting
|
|
113
|
-
})), isOpen && React.createElement(Menu.List, {
|
|
121
|
+
})), isOpen && /*#__PURE__*/ React.createElement(Menu.List, {
|
|
114
122
|
className: styles.dropdownList,
|
|
115
123
|
style: {
|
|
116
124
|
width: dropdownWidth != undefined ? `${dropdownWidth}px` : undefined,
|
|
@@ -118,25 +126,25 @@ export const CreateEntryMenuTrigger = ({ contentTypes , suggestedContentTypeId ,
|
|
|
118
126
|
},
|
|
119
127
|
ref: menuListRef,
|
|
120
128
|
testId: "add-entry-menu"
|
|
121
|
-
}, Boolean(customDropdownItems) && React.createElement(React.Fragment, null, customDropdownItems, React.createElement(Menu.Divider, null)), isSearchable && React.createElement(React.Fragment, null, React.createElement("div", {
|
|
129
|
+
}, Boolean(customDropdownItems) && /*#__PURE__*/ React.createElement(React.Fragment, null, customDropdownItems, /*#__PURE__*/ React.createElement(Menu.Divider, null)), isSearchable && /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement("div", {
|
|
122
130
|
ref: textField,
|
|
123
131
|
className: styles.inputWrapper
|
|
124
|
-
}, React.createElement(TextInput, {
|
|
132
|
+
}, /*#__PURE__*/ React.createElement(TextInput, {
|
|
125
133
|
className: styles.searchInput,
|
|
126
134
|
placeholder: "Search all content types",
|
|
127
135
|
testId: "add-entry-menu-search",
|
|
128
136
|
value: searchInput,
|
|
129
137
|
onChange: (e)=>setSearchInput(e.target.value)
|
|
130
|
-
}), React.createElement(SearchIcon, {
|
|
138
|
+
}), /*#__PURE__*/ React.createElement(SearchIcon, {
|
|
131
139
|
className: styles.searchIcon
|
|
132
|
-
})), React.createElement(Menu.Divider, null)), searchInput && renderSearchResultsCount(filteredContentTypes.length), suggestedContentType && !searchInput && React.createElement(React.Fragment, null, React.createElement(Menu.SectionTitle, null, "Suggested Content Type"), React.createElement(Menu.Item, {
|
|
140
|
+
})), /*#__PURE__*/ React.createElement(Menu.Divider, null)), searchInput && renderSearchResultsCount(filteredContentTypes.length), suggestedContentType && !searchInput && /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(Menu.SectionTitle, null, "Suggested Content Type"), /*#__PURE__*/ React.createElement(Menu.Item, {
|
|
133
141
|
testId: "suggested",
|
|
134
142
|
onClick: ()=>handleSelect(suggestedContentType)
|
|
135
|
-
}, get(suggestedContentType, 'name')), React.createElement(Menu.Divider, null)), !searchInput && React.createElement(Menu.SectionTitle, null, contentTypesLabel), filteredContentTypes.length ? filteredContentTypes.map((contentType, i)
|
|
143
|
+
}, get(suggestedContentType, 'name')), /*#__PURE__*/ React.createElement(Menu.Divider, null)), !searchInput && /*#__PURE__*/ React.createElement(Menu.SectionTitle, null, contentTypesLabel), filteredContentTypes.length ? filteredContentTypes.map((contentType, i)=>/*#__PURE__*/ React.createElement(Menu.Item, {
|
|
136
144
|
testId: "contentType",
|
|
137
145
|
key: `${get(contentType, 'name')}-${i}`,
|
|
138
146
|
onClick: ()=>handleSelect(contentType)
|
|
139
|
-
}, get(contentType, 'name', 'Untitled'))) : React.createElement(Menu.Item, {
|
|
147
|
+
}, get(contentType, 'name', 'Untitled'))) : /*#__PURE__*/ React.createElement(Menu.Item, {
|
|
140
148
|
testId: "add-entru-menu-search-results"
|
|
141
149
|
}, "No results found"))));
|
|
142
150
|
};
|
|
@@ -3,6 +3,7 @@ import { Button } from '@contentful/f36-components';
|
|
|
3
3
|
import '@testing-library/jest-dom/extend-expect';
|
|
4
4
|
import { act, configure, fireEvent, render } from '@testing-library/react';
|
|
5
5
|
import noop from 'lodash/noop';
|
|
6
|
+
// eslint-disable-next-line -- TODO: describe this disable you-dont-need-lodash-underscore/fill
|
|
6
7
|
import fill from 'lodash/fill';
|
|
7
8
|
import { CreateEntryMenuTrigger } from './CreateEntryMenuTrigger';
|
|
8
9
|
configure({
|
|
@@ -39,7 +40,7 @@ describe('CreateEntryMenuTrigger general', ()=>{
|
|
|
39
40
|
};
|
|
40
41
|
let stub = jest.fn();
|
|
41
42
|
beforeEach(()=>{
|
|
42
|
-
stub = jest.fn().mockImplementation(()
|
|
43
|
+
stub = jest.fn().mockImplementation(()=>/*#__PURE__*/ React.createElement(Button, {
|
|
43
44
|
testId: "menu-trigger"
|
|
44
45
|
}));
|
|
45
46
|
});
|
|
@@ -47,13 +48,13 @@ describe('CreateEntryMenuTrigger general', ()=>{
|
|
|
47
48
|
const stub = (api)=>{
|
|
48
49
|
expect(api.isOpen).toBe(false);
|
|
49
50
|
expect(api.isSelecting).toBe(false);
|
|
50
|
-
return React.createElement("span", null);
|
|
51
|
+
return /*#__PURE__*/ React.createElement("span", null);
|
|
51
52
|
};
|
|
52
|
-
render(React.createElement(CreateEntryMenuTrigger, props, stub));
|
|
53
|
+
render(/*#__PURE__*/ React.createElement(CreateEntryMenuTrigger, props, stub));
|
|
53
54
|
});
|
|
54
55
|
it('should set isSelecting to true in case onSelect returns a promise', async ()=>{
|
|
55
56
|
const selectStub = jest.fn(()=>new Promise((resolve)=>setTimeout(resolve, 1000)));
|
|
56
|
-
const { getAllByTestId
|
|
57
|
+
const { getAllByTestId, getByTestId } = render(/*#__PURE__*/ React.createElement(CreateEntryMenuTrigger, {
|
|
57
58
|
...props,
|
|
58
59
|
onSelect: selectStub
|
|
59
60
|
}, stub));
|
|
@@ -67,7 +68,7 @@ describe('CreateEntryMenuTrigger general', ()=>{
|
|
|
67
68
|
});
|
|
68
69
|
it('should not set isSelecting to true in case onSelect is sync', async ()=>{
|
|
69
70
|
const selectStub = jest.fn();
|
|
70
|
-
const { getAllByTestId
|
|
71
|
+
const { getAllByTestId, getByTestId } = render(/*#__PURE__*/ React.createElement(CreateEntryMenuTrigger, {
|
|
71
72
|
...props,
|
|
72
73
|
onSelect: selectStub
|
|
73
74
|
}, stub));
|
|
@@ -84,7 +85,7 @@ describe('CreateEntryMenuTrigger general', ()=>{
|
|
|
84
85
|
expect(selectStub).toHaveBeenCalled();
|
|
85
86
|
});
|
|
86
87
|
it('renders text input if contentTypes.length > 20', ()=>{
|
|
87
|
-
const { getByTestId
|
|
88
|
+
const { getByTestId } = render(/*#__PURE__*/ React.createElement(CreateEntryMenuTrigger, {
|
|
88
89
|
...props,
|
|
89
90
|
contentTypes: fill(Array(21), CONTENT_TYPE_3)
|
|
90
91
|
}, stub));
|
|
@@ -95,7 +96,7 @@ describe('CreateEntryMenuTrigger general', ()=>{
|
|
|
95
96
|
});
|
|
96
97
|
it('shows the search results if typed in input', ()=>{
|
|
97
98
|
const contentTypes = fill(fill(fill(Array(21), CONTENT_TYPE_1, 0, 10), CONTENT_TYPE_2, 10, 20), CONTENT_TYPE_3, 20);
|
|
98
|
-
const { getByTestId
|
|
99
|
+
const { getByTestId, getAllByTestId } = render(/*#__PURE__*/ React.createElement(CreateEntryMenuTrigger, {
|
|
99
100
|
...props,
|
|
100
101
|
contentTypes: contentTypes
|
|
101
102
|
}, stub));
|
|
@@ -128,7 +129,7 @@ describe('CreateEntryMenuTrigger general', ()=>{
|
|
|
128
129
|
expect(getByTestId('add-entru-menu-search-results').textContent).toBe('No results found');
|
|
129
130
|
});
|
|
130
131
|
it('shows suggestedContentType in the list', ()=>{
|
|
131
|
-
const { getByTestId
|
|
132
|
+
const { getByTestId } = render(/*#__PURE__*/ React.createElement(CreateEntryMenuTrigger, {
|
|
132
133
|
...props,
|
|
133
134
|
suggestedContentTypeId: props.contentTypes[0].sys.id
|
|
134
135
|
}, stub));
|
|
@@ -9,18 +9,27 @@ const testIds = {
|
|
|
9
9
|
...sharedTextIds,
|
|
10
10
|
actionsWrapper: 'link-actions-menu-trigger'
|
|
11
11
|
};
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Alternative, experimental alternative to <LinkActions /> that is planned to
|
|
14
|
+
* replace the current default LinkActions in reference and media editors.
|
|
15
|
+
*
|
|
16
|
+
* Places both actions to create and link new, as well as link existing, behind
|
|
17
|
+
* one action dropdown and introduces new copy for action labels.
|
|
18
|
+
*/ export function CombinedLinkActions(props) {
|
|
13
19
|
if (props.isFull) {
|
|
14
|
-
return null;
|
|
20
|
+
return null; // Don't render link actions if we reached max allowed links.
|
|
15
21
|
}
|
|
22
|
+
// We don't want to render a spacious container in case there are are already
|
|
23
|
+
// assets linked (in case of entries, always show it) as the border wouldn't be
|
|
24
|
+
// nicely aligned with asset cards.
|
|
16
25
|
const hideEmptyCard = props.entityType === 'Asset' && !props.isEmpty;
|
|
17
|
-
return React.createElement("div", {
|
|
26
|
+
return /*#__PURE__*/ React.createElement("div", {
|
|
18
27
|
className: hideEmptyCard ? '' : styles.container
|
|
19
|
-
}, !props.canCreateEntity && !props.canLinkEntity && React.createElement(NoLinkPermissionsInfo, null), props.entityType === 'Entry' && React.createElement(CombinedEntryLinkActions, props), props.entityType === 'Asset' && React.createElement(CombinedAssetLinkActions, props));
|
|
28
|
+
}, !props.canCreateEntity && !props.canLinkEntity && /*#__PURE__*/ React.createElement(NoLinkPermissionsInfo, null), props.entityType === 'Entry' && /*#__PURE__*/ React.createElement(CombinedEntryLinkActions, props), props.entityType === 'Asset' && /*#__PURE__*/ React.createElement(CombinedAssetLinkActions, props));
|
|
20
29
|
}
|
|
21
30
|
function CombinedEntryLinkActions(props) {
|
|
22
31
|
if (props.canCreateEntity) {
|
|
23
|
-
return React.createElement(CreateEntryLinkButton, {
|
|
32
|
+
return /*#__PURE__*/ React.createElement(CreateEntryLinkButton, {
|
|
24
33
|
testId: testIds.actionsWrapper,
|
|
25
34
|
disabled: props.isDisabled,
|
|
26
35
|
text: props.combinedActionsLabel || 'Add content',
|
|
@@ -33,7 +42,7 @@ function CombinedEntryLinkActions(props) {
|
|
|
33
42
|
onSelect: (contentTypeId)=>{
|
|
34
43
|
return contentTypeId ? props.onCreate(contentTypeId) : Promise.resolve();
|
|
35
44
|
},
|
|
36
|
-
customDropdownItems: props.canLinkEntity ? React.createElement(Menu.Item, {
|
|
45
|
+
customDropdownItems: props.canLinkEntity ? /*#__PURE__*/ React.createElement(Menu.Item, {
|
|
37
46
|
testId: testIds.linkExisting,
|
|
38
47
|
onClick: ()=>{
|
|
39
48
|
props.onLinkExisting();
|
|
@@ -41,7 +50,7 @@ function CombinedEntryLinkActions(props) {
|
|
|
41
50
|
}, "Add existing content") : undefined
|
|
42
51
|
});
|
|
43
52
|
} else if (props.canLinkEntity) {
|
|
44
|
-
return React.createElement(Button, {
|
|
53
|
+
return /*#__PURE__*/ React.createElement(Button, {
|
|
45
54
|
isDisabled: props.isDisabled,
|
|
46
55
|
testId: testIds.linkExisting,
|
|
47
56
|
className: styles.action,
|
|
@@ -49,7 +58,7 @@ function CombinedEntryLinkActions(props) {
|
|
|
49
58
|
props.onLinkExisting();
|
|
50
59
|
},
|
|
51
60
|
variant: "secondary",
|
|
52
|
-
startIcon: React.createElement(LinkIcon, null),
|
|
61
|
+
startIcon: /*#__PURE__*/ React.createElement(LinkIcon, null),
|
|
53
62
|
size: "small"
|
|
54
63
|
}, "Add existing content");
|
|
55
64
|
}
|
|
@@ -59,7 +68,7 @@ function CombinedAssetLinkActions(props) {
|
|
|
59
68
|
const [isOpen, setOpen] = React.useState(false);
|
|
60
69
|
if (!props.canLinkEntity || !props.canCreateEntity) {
|
|
61
70
|
if (props.canLinkEntity) {
|
|
62
|
-
return React.createElement(Button, {
|
|
71
|
+
return /*#__PURE__*/ React.createElement(Button, {
|
|
63
72
|
isDisabled: props.isDisabled,
|
|
64
73
|
testId: testIds.linkExisting,
|
|
65
74
|
className: styles.action,
|
|
@@ -67,12 +76,12 @@ function CombinedAssetLinkActions(props) {
|
|
|
67
76
|
props.onLinkExisting();
|
|
68
77
|
},
|
|
69
78
|
variant: "secondary",
|
|
70
|
-
startIcon: React.createElement(PlusIcon, null),
|
|
79
|
+
startIcon: /*#__PURE__*/ React.createElement(PlusIcon, null),
|
|
71
80
|
size: "small"
|
|
72
81
|
}, "Add existing media");
|
|
73
82
|
}
|
|
74
83
|
if (props.canCreateEntity) {
|
|
75
|
-
return React.createElement(Button, {
|
|
84
|
+
return /*#__PURE__*/ React.createElement(Button, {
|
|
76
85
|
isDisabled: props.isDisabled,
|
|
77
86
|
testId: testIds.createAndLink,
|
|
78
87
|
className: styles.action,
|
|
@@ -80,13 +89,15 @@ function CombinedAssetLinkActions(props) {
|
|
|
80
89
|
props.onCreate();
|
|
81
90
|
},
|
|
82
91
|
variant: "secondary",
|
|
83
|
-
startIcon: React.createElement(PlusIcon, null),
|
|
92
|
+
startIcon: /*#__PURE__*/ React.createElement(PlusIcon, null),
|
|
84
93
|
size: "small"
|
|
85
94
|
}, "Add media");
|
|
86
95
|
}
|
|
87
96
|
return null;
|
|
88
97
|
}
|
|
89
|
-
|
|
98
|
+
// TODO: If we fully switch to this new layout, make a more generic `CreateEntityLinkButton`
|
|
99
|
+
// that works without content types to cover asset use-case.
|
|
100
|
+
return /*#__PURE__*/ React.createElement(Menu, {
|
|
90
101
|
isOpen: isOpen,
|
|
91
102
|
onClose: ()=>{
|
|
92
103
|
setOpen(false);
|
|
@@ -94,22 +105,22 @@ function CombinedAssetLinkActions(props) {
|
|
|
94
105
|
onOpen: ()=>{
|
|
95
106
|
setOpen(true);
|
|
96
107
|
}
|
|
97
|
-
}, React.createElement(Menu.Trigger, null, React.createElement(Button, {
|
|
98
|
-
endIcon: React.createElement(ChevronDownIcon, null),
|
|
108
|
+
}, /*#__PURE__*/ React.createElement(Menu.Trigger, null, /*#__PURE__*/ React.createElement(Button, {
|
|
109
|
+
endIcon: /*#__PURE__*/ React.createElement(ChevronDownIcon, null),
|
|
99
110
|
isDisabled: props.isDisabled,
|
|
100
111
|
testId: testIds.actionsWrapper,
|
|
101
112
|
className: styles.action,
|
|
102
113
|
variant: "secondary",
|
|
103
|
-
startIcon: React.createElement(PlusIcon, null),
|
|
114
|
+
startIcon: /*#__PURE__*/ React.createElement(PlusIcon, null),
|
|
104
115
|
size: "small"
|
|
105
|
-
}, "Add media")), isOpen && React.createElement(Menu.List, {
|
|
116
|
+
}, "Add media")), isOpen && /*#__PURE__*/ React.createElement(Menu.List, {
|
|
106
117
|
testId: testIds.dropdown
|
|
107
|
-
}, React.createElement(Menu.Item, {
|
|
118
|
+
}, /*#__PURE__*/ React.createElement(Menu.Item, {
|
|
108
119
|
testId: testIds.linkExisting,
|
|
109
120
|
onClick: ()=>{
|
|
110
121
|
props.onLinkExisting();
|
|
111
122
|
}
|
|
112
|
-
}, "Add existing media"), React.createElement(Menu.Item, {
|
|
123
|
+
}, "Add existing media"), /*#__PURE__*/ React.createElement(Menu.Item, {
|
|
113
124
|
testId: testIds.createAndLink,
|
|
114
125
|
onClick: ()=>{
|
|
115
126
|
props.onCreate();
|
|
@@ -20,16 +20,16 @@ export const testIds = {
|
|
|
20
20
|
};
|
|
21
21
|
export function LinkActions(props) {
|
|
22
22
|
if (props.isFull) {
|
|
23
|
-
return null;
|
|
23
|
+
return null; // Don't render link actions if we reached max allowed links.
|
|
24
24
|
}
|
|
25
25
|
const defaultLabels = props.entityType === 'Entry' ? defaultEntryLabels : defaultAssetLabels;
|
|
26
26
|
const labels = {
|
|
27
27
|
...defaultLabels,
|
|
28
28
|
...props.actionLabels
|
|
29
29
|
};
|
|
30
|
-
return React.createElement("div", {
|
|
30
|
+
return /*#__PURE__*/ React.createElement("div", {
|
|
31
31
|
className: styles.container
|
|
32
|
-
}, props.canCreateEntity && React.createElement(React.Fragment, null, props.entityType === 'Entry' && React.createElement(CreateEntryLinkButton, {
|
|
32
|
+
}, props.canCreateEntity && /*#__PURE__*/ React.createElement(React.Fragment, null, props.entityType === 'Entry' && /*#__PURE__*/ React.createElement(CreateEntryLinkButton, {
|
|
33
33
|
testId: testIds.createAndLink,
|
|
34
34
|
disabled: props.isDisabled,
|
|
35
35
|
text: labels.createNew({
|
|
@@ -40,27 +40,27 @@ export function LinkActions(props) {
|
|
|
40
40
|
onSelect: (contentTypeId)=>{
|
|
41
41
|
return contentTypeId ? props.onCreate(contentTypeId, props.itemsLength) : Promise.resolve();
|
|
42
42
|
}
|
|
43
|
-
}), props.entityType === 'Asset' && React.createElement(Button, {
|
|
43
|
+
}), props.entityType === 'Asset' && /*#__PURE__*/ React.createElement(Button, {
|
|
44
44
|
isDisabled: props.isDisabled,
|
|
45
45
|
testId: testIds.createAndLink,
|
|
46
46
|
onClick: ()=>{
|
|
47
47
|
props.onCreate(undefined, props.itemsLength);
|
|
48
48
|
},
|
|
49
49
|
variant: "secondary",
|
|
50
|
-
startIcon: React.createElement(PlusIcon, null),
|
|
50
|
+
startIcon: /*#__PURE__*/ React.createElement(PlusIcon, null),
|
|
51
51
|
size: "small"
|
|
52
|
-
}, labels.createNew()), React.createElement("span", {
|
|
52
|
+
}, labels.createNew()), /*#__PURE__*/ React.createElement("span", {
|
|
53
53
|
className: styles.separator
|
|
54
|
-
})), props.canLinkEntity && React.createElement(Button, {
|
|
54
|
+
})), props.canLinkEntity && /*#__PURE__*/ React.createElement(Button, {
|
|
55
55
|
isDisabled: props.isDisabled,
|
|
56
56
|
testId: testIds.linkExisting,
|
|
57
57
|
onClick: ()=>{
|
|
58
58
|
props.onLinkExisting();
|
|
59
59
|
},
|
|
60
60
|
variant: "secondary",
|
|
61
|
-
startIcon: React.createElement(LinkIcon, null),
|
|
61
|
+
startIcon: /*#__PURE__*/ React.createElement(LinkIcon, null),
|
|
62
62
|
size: "small"
|
|
63
63
|
}, labels.linkExisting({
|
|
64
64
|
canLinkMultiple: props.canLinkMultiple
|
|
65
|
-
})), !props.canCreateEntity && !props.canLinkEntity && React.createElement(NoLinkPermissionsInfo, null));
|
|
65
|
+
})), !props.canCreateEntity && !props.canLinkEntity && /*#__PURE__*/ React.createElement(NoLinkPermissionsInfo, null));
|
|
66
66
|
}
|
|
@@ -4,7 +4,7 @@ import { CombinedLinkActions } from './CombinedLinkActions';
|
|
|
4
4
|
import { createEntity, selectMultipleEntities, selectSingleEntity } from './helpers';
|
|
5
5
|
import { LinkActions } from './LinkActions';
|
|
6
6
|
export function useLinkActionsProps(props) {
|
|
7
|
-
const { sdk
|
|
7
|
+
const { sdk, editorPermissions, entityType, canLinkMultiple, isDisabled, actionLabels, itemsLength } = props;
|
|
8
8
|
const maxLinksCount = editorPermissions.validations.numberOfLinks?.max;
|
|
9
9
|
const value = sdk.field.getValue();
|
|
10
10
|
const linkCount = Array.isArray(value) ? value.length : value ? 1 : 0;
|
|
@@ -19,7 +19,8 @@ export function useLinkActionsProps(props) {
|
|
|
19
19
|
slide,
|
|
20
20
|
index
|
|
21
21
|
});
|
|
22
|
-
},
|
|
22
|
+
}, // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
|
|
23
|
+
[
|
|
23
24
|
entityType,
|
|
24
25
|
props.onCreate,
|
|
25
26
|
props.onAction
|
|
@@ -34,13 +35,14 @@ export function useLinkActionsProps(props) {
|
|
|
34
35
|
index: index === undefined ? undefined : index + i
|
|
35
36
|
});
|
|
36
37
|
});
|
|
37
|
-
},
|
|
38
|
+
}, // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
|
|
39
|
+
[
|
|
38
40
|
entityType,
|
|
39
41
|
props.onLink,
|
|
40
42
|
props.onAction
|
|
41
43
|
]);
|
|
42
44
|
const onCreate = React.useCallback(async (contentTypeId, index)=>{
|
|
43
|
-
const { entity
|
|
45
|
+
const { entity, slide } = await createEntity({
|
|
44
46
|
sdk,
|
|
45
47
|
entityType,
|
|
46
48
|
contentTypeId
|
|
@@ -66,7 +68,8 @@ export function useLinkActionsProps(props) {
|
|
|
66
68
|
onLinkedExisting([
|
|
67
69
|
entity
|
|
68
70
|
], index);
|
|
69
|
-
},
|
|
71
|
+
}, // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
|
|
72
|
+
[
|
|
70
73
|
sdk,
|
|
71
74
|
entityType,
|
|
72
75
|
onLinkedExisting
|
|
@@ -81,11 +84,13 @@ export function useLinkActionsProps(props) {
|
|
|
81
84
|
return;
|
|
82
85
|
}
|
|
83
86
|
onLinkedExisting(entities, index);
|
|
84
|
-
},
|
|
87
|
+
}, // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
|
|
88
|
+
[
|
|
85
89
|
sdk,
|
|
86
90
|
entityType,
|
|
87
91
|
onLinkedExisting
|
|
88
92
|
]);
|
|
93
|
+
// FIXME: The memoization might rerun every time due to the always changing callback identities above
|
|
89
94
|
return useMemo(()=>({
|
|
90
95
|
entityType,
|
|
91
96
|
canLinkMultiple,
|
|
@@ -101,7 +106,8 @@ export function useLinkActionsProps(props) {
|
|
|
101
106
|
onCreated,
|
|
102
107
|
onLinkedExisting,
|
|
103
108
|
itemsLength
|
|
104
|
-
}),
|
|
109
|
+
}), // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
|
|
110
|
+
[
|
|
105
111
|
entityType,
|
|
106
112
|
canLinkMultiple,
|
|
107
113
|
isDisabled,
|
|
@@ -110,6 +116,7 @@ export function useLinkActionsProps(props) {
|
|
|
110
116
|
editorPermissions.canCreateEntity,
|
|
111
117
|
editorPermissions.canLinkEntity,
|
|
112
118
|
actionLabels,
|
|
119
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
|
|
113
120
|
editorPermissions.creatableContentTypes.map((ct)=>ct.sys.id).join(':'),
|
|
114
121
|
onCreate,
|
|
115
122
|
onLinkExisting,
|
|
@@ -119,9 +126,9 @@ export function useLinkActionsProps(props) {
|
|
|
119
126
|
itemsLength
|
|
120
127
|
]);
|
|
121
128
|
}
|
|
122
|
-
export function LinkEntityActions({ renderCustomActions
|
|
123
|
-
return renderCustomActions ? renderCustomActions(props) : React.createElement(LinkActions, props);
|
|
129
|
+
export function LinkEntityActions({ renderCustomActions, ...props }) {
|
|
130
|
+
return renderCustomActions ? renderCustomActions(props) : /*#__PURE__*/ React.createElement(LinkActions, props);
|
|
124
131
|
}
|
|
125
|
-
export function CombinedLinkEntityActions({ renderCustomActions
|
|
126
|
-
return renderCustomActions ? renderCustomActions(props) : React.createElement(CombinedLinkActions, props);
|
|
132
|
+
export function CombinedLinkEntityActions({ renderCustomActions, ...props }) {
|
|
133
|
+
return renderCustomActions ? renderCustomActions(props) : /*#__PURE__*/ React.createElement(CombinedLinkActions, props);
|
|
127
134
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { Paragraph } from '@contentful/f36-components';
|
|
3
3
|
export function NoLinkPermissionsInfo() {
|
|
4
|
-
return React.createElement(Paragraph, null, "You don't have permission to view this content or this field is not correctly configured. Contact your administrator for help.");
|
|
4
|
+
return /*#__PURE__*/ React.createElement(Paragraph, null, "You don't have permission to view this content or this field is not correctly configured. Contact your administrator for help.");
|
|
5
5
|
}
|
|
@@ -4,7 +4,7 @@ export async function createEntity(props) {
|
|
|
4
4
|
if (!props.contentTypeId) {
|
|
5
5
|
return {};
|
|
6
6
|
}
|
|
7
|
-
const { entity
|
|
7
|
+
const { entity, slide } = await props.sdk.navigator.openNewEntry(props.contentTypeId, {
|
|
8
8
|
slideIn: true
|
|
9
9
|
});
|
|
10
10
|
return {
|
|
@@ -12,7 +12,7 @@ export async function createEntity(props) {
|
|
|
12
12
|
slide
|
|
13
13
|
};
|
|
14
14
|
} else {
|
|
15
|
-
const { entity
|
|
15
|
+
const { entity, slide } = await props.sdk.navigator.openNewAsset({
|
|
16
16
|
slideIn: true
|
|
17
17
|
});
|
|
18
18
|
return {
|
|
@@ -37,7 +37,12 @@ export async function selectSingleEntity(props) {
|
|
|
37
37
|
export async function selectMultipleEntities(props) {
|
|
38
38
|
const value = props.sdk.field.getValue();
|
|
39
39
|
const linkCount = Array.isArray(value) ? value.length : value ? 1 : 0;
|
|
40
|
+
// TODO: Why not always set `min: 1` by default? Does it make sense to enforce
|
|
41
|
+
// user to select as many entities as the field's "min" requires? What if e.g.
|
|
42
|
+
// "min" is 4 and the user wants to insert 2 entities first, then create 2 new ones?
|
|
40
43
|
const min = Math.max((props.editorPermissions.validations.numberOfLinks?.min || 1) - linkCount, 1);
|
|
44
|
+
// TODO: Consider same for max. If e.g. "max" is 4, we disable the button if the
|
|
45
|
+
// user wants to select 5 but we show no information why the button is disabled.
|
|
41
46
|
const max = (props.editorPermissions.validations.numberOfLinks?.max || +Infinity) - linkCount;
|
|
42
47
|
if (props.entityType === 'Entry') {
|
|
43
48
|
return await props.sdk.dialogs.selectMultipleEntries({
|