@contentful/field-editor-reference 6.19.3 → 6.19.4-canary.3
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 +13 -20
- package/dist/cjs/assets/WrappedAssetCard/AssetCardActions.js +11 -1
- package/dist/cjs/assets/WrappedAssetCard/FetchingWrappedAssetCard.js +10 -1
- package/dist/cjs/assets/WrappedAssetCard/WrappedAssetCard.js +4 -2
- package/dist/cjs/common/EntityStore.js +38 -25
- package/dist/cjs/common/MultipleReferenceEditor.js +6 -1
- package/dist/cjs/common/SingleReferenceEditor.js +8 -2
- package/dist/cjs/common/useContentTypePermissions.js +6 -9
- package/dist/cjs/common/useEditorPermissions.js +5 -1
- package/dist/cjs/components/LinkActions/LinkEntityActions.js +2 -0
- package/dist/cjs/entries/MultipleEntryReferenceEditor.js +2 -1
- package/dist/cjs/entries/SingleEntryReferenceEditor.js +1 -0
- package/dist/cjs/entries/WrappedEntryCard/FetchingWrappedEntryCard.js +10 -1
- package/dist/cjs/entries/WrappedEntryCard/WrappedEntryCard.js +13 -2
- package/dist/cjs/resources/Cards/ResourceCard.spec.js +28 -2
- package/dist/esm/__fixtures__/FakeSdk.js +13 -20
- package/dist/esm/assets/WrappedAssetCard/AssetCardActions.js +11 -1
- package/dist/esm/assets/WrappedAssetCard/FetchingWrappedAssetCard.js +10 -1
- package/dist/esm/assets/WrappedAssetCard/WrappedAssetCard.js +4 -2
- package/dist/esm/common/EntityStore.js +38 -25
- package/dist/esm/common/MultipleReferenceEditor.js +6 -1
- package/dist/esm/common/SingleReferenceEditor.js +8 -2
- package/dist/esm/common/useContentTypePermissions.js +6 -9
- package/dist/esm/common/useEditorPermissions.js +5 -1
- package/dist/esm/components/LinkActions/LinkEntityActions.js +2 -0
- package/dist/esm/entries/MultipleEntryReferenceEditor.js +2 -1
- package/dist/esm/entries/SingleEntryReferenceEditor.js +1 -0
- package/dist/esm/entries/WrappedEntryCard/FetchingWrappedEntryCard.js +10 -1
- package/dist/esm/entries/WrappedEntryCard/WrappedEntryCard.js +13 -2
- package/dist/esm/resources/Cards/ResourceCard.spec.js +28 -2
- package/dist/types/assets/WrappedAssetCard/AssetCardActions.d.ts +1 -0
- package/dist/types/assets/WrappedAssetCard/FetchingWrappedAssetCard.d.ts +5 -1
- package/dist/types/assets/WrappedAssetCard/WrappedAssetCard.d.ts +2 -1
- package/dist/types/common/EntityStore.d.ts +2 -0
- package/dist/types/common/ReferenceEditor.d.ts +5 -1
- package/dist/types/common/customCardTypes.d.ts +1 -0
- package/dist/types/entries/WrappedEntryCard/FetchingWrappedEntryCard.d.ts +5 -1
- package/dist/types/entries/WrappedEntryCard/WrappedEntryCard.d.ts +2 -1
- package/package.json +4 -4
|
@@ -45,15 +45,6 @@ function newReferenceEditorFakeSdk(props) {
|
|
|
45
45
|
const delay = (ms)=>{
|
|
46
46
|
return new Promise((resolve)=>setTimeout(resolve, ms));
|
|
47
47
|
};
|
|
48
|
-
const localizeContentTypes = (contentTypes)=>{
|
|
49
|
-
return contentTypes.map((contentType)=>({
|
|
50
|
-
...contentType,
|
|
51
|
-
fields: contentType.fields.map((field)=>({
|
|
52
|
-
...field,
|
|
53
|
-
localized: true
|
|
54
|
-
}))
|
|
55
|
-
}));
|
|
56
|
-
};
|
|
57
48
|
const sdk = {
|
|
58
49
|
field,
|
|
59
50
|
locales,
|
|
@@ -106,6 +97,19 @@ function newReferenceEditorFakeSdk(props) {
|
|
|
106
97
|
return _fixtures.contentTypes.published;
|
|
107
98
|
}
|
|
108
99
|
return Promise.reject({});
|
|
100
|
+
},
|
|
101
|
+
getMany: async ()=>{
|
|
102
|
+
return Promise.resolve({
|
|
103
|
+
items: [
|
|
104
|
+
_fixtures.contentTypes.published
|
|
105
|
+
],
|
|
106
|
+
total: 1,
|
|
107
|
+
skip: 0,
|
|
108
|
+
limit: 1000,
|
|
109
|
+
sys: {
|
|
110
|
+
type: 'Array'
|
|
111
|
+
}
|
|
112
|
+
});
|
|
109
113
|
}
|
|
110
114
|
},
|
|
111
115
|
Locale: {
|
|
@@ -114,17 +118,6 @@ function newReferenceEditorFakeSdk(props) {
|
|
|
114
118
|
},
|
|
115
119
|
space: {
|
|
116
120
|
...space,
|
|
117
|
-
getCachedContentTypes () {
|
|
118
|
-
return localizeContentTypes(space.getCachedContentTypes());
|
|
119
|
-
},
|
|
120
|
-
getContentTypes () {
|
|
121
|
-
return Promise.resolve(space.getContentTypes().then((response)=>{
|
|
122
|
-
return {
|
|
123
|
-
...response,
|
|
124
|
-
items: localizeContentTypes(response.items)
|
|
125
|
-
};
|
|
126
|
-
}));
|
|
127
|
-
},
|
|
128
121
|
async getEntityScheduledActions () {
|
|
129
122
|
return [];
|
|
130
123
|
}
|
|
@@ -18,6 +18,7 @@ _export(exports, {
|
|
|
18
18
|
});
|
|
19
19
|
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
|
|
20
20
|
const _f36components = require("@contentful/f36-components");
|
|
21
|
+
const _f36icons = require("@contentful/f36-icons");
|
|
21
22
|
const _f36tokens = /*#__PURE__*/ _interop_require_default(require("@contentful/f36-tokens"));
|
|
22
23
|
const _fieldeditorshared = require("@contentful/field-editor-shared");
|
|
23
24
|
const _emotion = require("emotion");
|
|
@@ -134,7 +135,7 @@ function renderAssetInfo(props) {
|
|
|
134
135
|
];
|
|
135
136
|
}
|
|
136
137
|
function renderActions(props) {
|
|
137
|
-
const { entityFile, isDisabled, onEdit, onRemove } = props;
|
|
138
|
+
const { entityFile, isDisabled, onEdit, onRemove, onAddToReleaseAction } = props;
|
|
138
139
|
return [
|
|
139
140
|
/*#__PURE__*/ _react.createElement(_f36components.MenuSectionTitle, {
|
|
140
141
|
key: "section-title"
|
|
@@ -144,6 +145,15 @@ function renderActions(props) {
|
|
|
144
145
|
onClick: onEdit,
|
|
145
146
|
testId: "card-action-edit"
|
|
146
147
|
}, "Edit") : null,
|
|
148
|
+
onAddToReleaseAction ? /*#__PURE__*/ _react.createElement(_f36components.MenuItem, {
|
|
149
|
+
key: "add-to-release",
|
|
150
|
+
testId: "add-to-release",
|
|
151
|
+
onClick: ()=>{
|
|
152
|
+
onAddToReleaseAction();
|
|
153
|
+
}
|
|
154
|
+
}, /*#__PURE__*/ _react.createElement(_f36icons.PlusIcon, {
|
|
155
|
+
size: "tiny"
|
|
156
|
+
}), "Add to release") : null,
|
|
147
157
|
entityFile ? /*#__PURE__*/ _react.createElement(_f36components.MenuItem, {
|
|
148
158
|
key: "download",
|
|
149
159
|
onClick: ()=>{
|
|
@@ -72,6 +72,14 @@ function FetchingWrappedAssetCard(props) {
|
|
|
72
72
|
locales: props.sdk.locales,
|
|
73
73
|
isReference: true
|
|
74
74
|
});
|
|
75
|
+
const onAddToRelease = ()=>{
|
|
76
|
+
if (asset && props.addReferenceToRelease) {
|
|
77
|
+
void props.addReferenceToRelease(asset, props.sdk.field.locale, {
|
|
78
|
+
openModalForVersionSelection: true,
|
|
79
|
+
skipNestedReferencesPrompt: true
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
};
|
|
75
83
|
_react.useEffect(()=>{
|
|
76
84
|
if (asset) {
|
|
77
85
|
props.onAction && props.onAction({
|
|
@@ -138,7 +146,8 @@ function FetchingWrappedAssetCard(props) {
|
|
|
138
146
|
activeLocales,
|
|
139
147
|
releaseStatusMap,
|
|
140
148
|
release: props.sdk.release,
|
|
141
|
-
releaseEntityStatus
|
|
149
|
+
releaseEntityStatus,
|
|
150
|
+
onAddToRelease
|
|
142
151
|
};
|
|
143
152
|
if (status === 'loading') {
|
|
144
153
|
return props.viewType === 'link' ? /*#__PURE__*/ _react.createElement(_f36components.EntryCard, {
|
|
@@ -87,7 +87,7 @@ function getFileType(file) {
|
|
|
87
87
|
return groupToIconMap[groupName] || 'archive';
|
|
88
88
|
}
|
|
89
89
|
const THUMBNAIL_SIZE = 150;
|
|
90
|
-
const WrappedAssetCard = ({ asset, className, size, localeCode, defaultLocaleCode, activeLocales, localesStatusMap, isDisabled, isSelected, isClickable, useLocalizedEntityStatus, renderDragHandle, getEntityScheduledActions, onEdit, getAssetUrl, onRemove, releaseEntityStatus, releaseStatusMap, release })=>{
|
|
90
|
+
const WrappedAssetCard = ({ asset, className, size, localeCode, defaultLocaleCode, activeLocales, localesStatusMap, isDisabled, isSelected, isClickable, useLocalizedEntityStatus, renderDragHandle, getEntityScheduledActions, onEdit, getAssetUrl, onRemove, releaseEntityStatus, releaseStatusMap, release, onAddToRelease })=>{
|
|
91
91
|
const status = _fieldeditorshared.entityHelpers.getEntityStatus(asset.sys, useLocalizedEntityStatus ? localeCode : undefined);
|
|
92
92
|
const entityFile = asset.fields.file ? asset.fields.file[localeCode] || asset.fields.file[defaultLocaleCode] : undefined;
|
|
93
93
|
const imageUrl = _react.useMemo(()=>{
|
|
@@ -120,6 +120,7 @@ const WrappedAssetCard = ({ asset, className, size, localeCode, defaultLocaleCod
|
|
|
120
120
|
defaultTitle: 'Untitled'
|
|
121
121
|
});
|
|
122
122
|
const href = getAssetUrl ? getAssetUrl(asset.sys.id) : undefined;
|
|
123
|
+
const onAddToReleaseAction = releaseEntityStatus === 'notInRelease' && release !== undefined && onAddToRelease !== undefined && !isDisabled ? onAddToRelease : undefined;
|
|
123
124
|
return /*#__PURE__*/ _react.createElement(_f36components.AssetCard, {
|
|
124
125
|
as: isClickable && href ? 'a' : 'article',
|
|
125
126
|
type: getFileType(entityFile),
|
|
@@ -158,7 +159,8 @@ const WrappedAssetCard = ({ asset, className, size, localeCode, defaultLocaleCod
|
|
|
158
159
|
entityFile,
|
|
159
160
|
isDisabled: isDisabled,
|
|
160
161
|
onEdit,
|
|
161
|
-
onRemove
|
|
162
|
+
onRemove,
|
|
163
|
+
onAddToReleaseAction
|
|
162
164
|
}),
|
|
163
165
|
...entityFile ? (0, _AssetCardActions.renderAssetInfo)({
|
|
164
166
|
entityFile
|
|
@@ -41,10 +41,10 @@ _export(exports, {
|
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
|
|
44
|
+
const _fieldeditorshared = require("@contentful/field-editor-shared");
|
|
44
45
|
const _constate = /*#__PURE__*/ _interop_require_default(require("constate"));
|
|
45
46
|
const _contentfulmanagement = require("contentful-management");
|
|
46
47
|
const _lodash = require("lodash");
|
|
47
|
-
const _moment = /*#__PURE__*/ _interop_require_default(require("moment"));
|
|
48
48
|
const _pqueue = /*#__PURE__*/ _interop_require_default(require("p-queue"));
|
|
49
49
|
const _queryClient = require("./queryClient");
|
|
50
50
|
function _define_property(obj, key, value) {
|
|
@@ -163,18 +163,10 @@ async function fetchContentfulEntry({ urn, fetch, options }) {
|
|
|
163
163
|
const environmentId = resourceIdMatch?.groups?.environmentId || 'master';
|
|
164
164
|
const entryId = resourceIdMatch.groups.entityId;
|
|
165
165
|
const [space, entry] = await Promise.all([
|
|
166
|
-
fetch(
|
|
167
|
-
'space',
|
|
168
|
-
spaceId
|
|
169
|
-
], ({ cmaClient })=>cmaClient.space.get({
|
|
166
|
+
fetch((0, _fieldeditorshared.createGetSpaceKey)(spaceId), ({ cmaClient })=>cmaClient.space.get({
|
|
170
167
|
spaceId
|
|
171
168
|
}), options),
|
|
172
|
-
fetch(
|
|
173
|
-
'entry',
|
|
174
|
-
spaceId,
|
|
175
|
-
environmentId,
|
|
176
|
-
entryId
|
|
177
|
-
], ({ cmaClient })=>cmaClient.entry.get({
|
|
169
|
+
fetch((0, _fieldeditorshared.createGetEntryKey)(spaceId, environmentId, entryId), ({ cmaClient })=>cmaClient.entry.get({
|
|
178
170
|
spaceId,
|
|
179
171
|
environmentId,
|
|
180
172
|
entryId
|
|
@@ -182,12 +174,7 @@ async function fetchContentfulEntry({ urn, fetch, options }) {
|
|
|
182
174
|
]);
|
|
183
175
|
const contentTypeId = entry.sys.contentType.sys.id;
|
|
184
176
|
const [contentType, defaultLocaleCode] = await Promise.all([
|
|
185
|
-
fetch(
|
|
186
|
-
'contentType',
|
|
187
|
-
spaceId,
|
|
188
|
-
environmentId,
|
|
189
|
-
contentTypeId
|
|
190
|
-
], ({ cmaClient })=>cmaClient.contentType.get({
|
|
177
|
+
fetch((0, _fieldeditorshared.createGetContentTypeKey)(spaceId, environmentId, contentTypeId), ({ cmaClient })=>cmaClient.contentType.get({
|
|
191
178
|
contentTypeId,
|
|
192
179
|
spaceId,
|
|
193
180
|
environmentId
|
|
@@ -399,7 +386,6 @@ const [InternalServiceProvider, useFetch, useEntityLoader, useCurrentIds] = (0,
|
|
|
399
386
|
const query = {
|
|
400
387
|
'environment.sys.id': environmentId,
|
|
401
388
|
'sys.status': 'scheduled',
|
|
402
|
-
'scheduledFor.datetime[gte]': (0, _moment.default)().startOf('hour').toISOString(),
|
|
403
389
|
'entity.sys.linkType[in]': 'Entry,Asset',
|
|
404
390
|
order: '-scheduledFor.datetime',
|
|
405
391
|
limit: maxScheduledActions
|
|
@@ -473,17 +459,41 @@ const [InternalServiceProvider, useFetch, useEntityLoader, useCurrentIds] = (0,
|
|
|
473
459
|
(0, _react.useEffect)(()=>{
|
|
474
460
|
function findSameSpaceQueries() {
|
|
475
461
|
const queries = queryCache.findAll({
|
|
476
|
-
type: 'active',
|
|
477
462
|
predicate: (query)=>isSameSpaceEntityQueryKey(query.queryKey)
|
|
478
463
|
});
|
|
479
464
|
return queries;
|
|
480
465
|
}
|
|
481
466
|
if (typeof onEntityChanged !== 'function') {
|
|
482
|
-
return onSlideInNavigation(({ oldSlideLevel, newSlideLevel })=>{
|
|
467
|
+
return onSlideInNavigation(async ({ oldSlideLevel, newSlideLevel })=>{
|
|
483
468
|
if (oldSlideLevel > newSlideLevel) {
|
|
484
|
-
findSameSpaceQueries()
|
|
485
|
-
|
|
486
|
-
|
|
469
|
+
const queries = findSameSpaceQueries();
|
|
470
|
+
await Promise.all(queries.map(async (query)=>{
|
|
471
|
+
const [entityType, entityId, spaceId, environmentId, releaseId] = query.queryKey;
|
|
472
|
+
try {
|
|
473
|
+
let freshData;
|
|
474
|
+
if (entityType === 'Entry') {
|
|
475
|
+
freshData = await cmaClient.entry.get({
|
|
476
|
+
entryId: entityId,
|
|
477
|
+
spaceId: spaceId,
|
|
478
|
+
environmentId: environmentId,
|
|
479
|
+
releaseId: releaseId
|
|
480
|
+
});
|
|
481
|
+
} else if (entityType === 'Asset') {
|
|
482
|
+
freshData = await cmaClient.asset.get({
|
|
483
|
+
assetId: entityId,
|
|
484
|
+
spaceId: spaceId,
|
|
485
|
+
environmentId: environmentId,
|
|
486
|
+
releaseId: releaseId
|
|
487
|
+
});
|
|
488
|
+
} else {
|
|
489
|
+
await queryClient.invalidateQueries(query.queryKey);
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
queryClient.setQueryData(query.queryKey, freshData);
|
|
493
|
+
} catch (error) {
|
|
494
|
+
await queryClient.invalidateQueries(query.queryKey);
|
|
495
|
+
}
|
|
496
|
+
}));
|
|
487
497
|
}
|
|
488
498
|
});
|
|
489
499
|
}
|
|
@@ -526,7 +536,8 @@ const [InternalServiceProvider, useFetch, useEntityLoader, useCurrentIds] = (0,
|
|
|
526
536
|
isSameSpaceEntityQueryKey,
|
|
527
537
|
queryClient,
|
|
528
538
|
getEntity,
|
|
529
|
-
onSlideInNavigation
|
|
539
|
+
onSlideInNavigation,
|
|
540
|
+
cmaClient
|
|
530
541
|
]);
|
|
531
542
|
const getResourceProvider = (0, _react.useCallback)(function getResourceProvider(organizationId, appDefinitionId) {
|
|
532
543
|
const queryKey = [
|
|
@@ -632,5 +643,7 @@ function useResourceProvider(organizationId, appDefinitionId) {
|
|
|
632
643
|
};
|
|
633
644
|
}
|
|
634
645
|
function EntityProvider({ children, ...props }) {
|
|
635
|
-
return /*#__PURE__*/ _react.default.createElement(_queryClient.SharedQueryClientProvider,
|
|
646
|
+
return /*#__PURE__*/ _react.default.createElement(_queryClient.SharedQueryClientProvider, {
|
|
647
|
+
client: props.queryClient
|
|
648
|
+
}, /*#__PURE__*/ _react.default.createElement(InternalServiceProvider, props, children));
|
|
636
649
|
}
|
|
@@ -9,10 +9,12 @@ Object.defineProperty(exports, "MultipleReferenceEditor", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
|
|
12
|
+
const _fieldeditorshared = require("@contentful/field-editor-shared");
|
|
12
13
|
const _sortable = require("@dnd-kit/sortable");
|
|
13
14
|
const _components = require("../components");
|
|
14
15
|
const _LinkEntityActions = require("../components/LinkActions/LinkEntityActions");
|
|
15
16
|
const _useSortIDs = require("../utils/useSortIDs");
|
|
17
|
+
const _queryClient = require("./queryClient");
|
|
16
18
|
const _ReferenceEditor = require("./ReferenceEditor");
|
|
17
19
|
const _useEditorPermissions = require("./useEditorPermissions");
|
|
18
20
|
function _getRequireWildcardCache(nodeInterop) {
|
|
@@ -145,7 +147,10 @@ function Editor(props) {
|
|
|
145
147
|
}));
|
|
146
148
|
}
|
|
147
149
|
function MultipleReferenceEditor(props) {
|
|
148
|
-
|
|
150
|
+
return /*#__PURE__*/ _react.createElement(_queryClient.SharedQueryClientProvider, null, /*#__PURE__*/ _react.createElement(MultipleReferenceEditorInner, props));
|
|
151
|
+
}
|
|
152
|
+
function MultipleReferenceEditorInner(props) {
|
|
153
|
+
const { contentTypes: allContentTypes } = (0, _fieldeditorshared.useContentTypes)(props.sdk);
|
|
149
154
|
return /*#__PURE__*/ _react.createElement(_ReferenceEditor.ReferenceEditor, props, ({ value, disabled, setValue, externalReset })=>{
|
|
150
155
|
return /*#__PURE__*/ _react.createElement(Editor, {
|
|
151
156
|
...props,
|
|
@@ -9,8 +9,10 @@ Object.defineProperty(exports, "SingleReferenceEditor", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
|
|
12
|
+
const _fieldeditorshared = require("@contentful/field-editor-shared");
|
|
12
13
|
const _components = require("../components");
|
|
13
14
|
const _LinkEntityActions = require("../components/LinkActions/LinkEntityActions");
|
|
15
|
+
const _queryClient = require("./queryClient");
|
|
14
16
|
const _ReferenceEditor = require("./ReferenceEditor");
|
|
15
17
|
const _useEditorPermissions = require("./useEditorPermissions");
|
|
16
18
|
function _getRequireWildcardCache(nodeInterop) {
|
|
@@ -98,11 +100,15 @@ function Editor(props) {
|
|
|
98
100
|
}
|
|
99
101
|
return props.children({
|
|
100
102
|
...props,
|
|
101
|
-
renderCustomCard: props.renderCustomCard && customCardRenderer
|
|
103
|
+
renderCustomCard: props.renderCustomCard && customCardRenderer,
|
|
104
|
+
addReferenceToRelease: props.addReferenceToRelease
|
|
102
105
|
});
|
|
103
106
|
}
|
|
104
107
|
function SingleReferenceEditor(props) {
|
|
105
|
-
|
|
108
|
+
return /*#__PURE__*/ _react.createElement(_queryClient.SharedQueryClientProvider, null, /*#__PURE__*/ _react.createElement(SingleReferenceEditorInner, props));
|
|
109
|
+
}
|
|
110
|
+
function SingleReferenceEditorInner(props) {
|
|
111
|
+
const { contentTypes: allContentTypes } = (0, _fieldeditorshared.useContentTypes)(props.sdk);
|
|
106
112
|
return /*#__PURE__*/ _react.createElement(_ReferenceEditor.ReferenceEditor, props, ({ value, setValue, disabled, externalReset })=>{
|
|
107
113
|
return /*#__PURE__*/ _react.createElement(Editor, {
|
|
108
114
|
...props,
|
|
@@ -26,6 +26,9 @@ function useContentTypePermissions({ entityType, validations, sdk, allContentTyp
|
|
|
26
26
|
if (entityType === 'Asset') {
|
|
27
27
|
return [];
|
|
28
28
|
}
|
|
29
|
+
if (validations.contentTypes && allContentTypes.length === 0) {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
29
32
|
if (validations.contentTypes) {
|
|
30
33
|
return allContentTypes.filter((ct)=>validations.contentTypes?.includes(ct.sys.id));
|
|
31
34
|
}
|
|
@@ -38,21 +41,15 @@ function useContentTypePermissions({ entityType, validations, sdk, allContentTyp
|
|
|
38
41
|
const [creatableContentTypes, setCreatableContentTypes] = (0, _react.useState)(availableContentTypes);
|
|
39
42
|
const { canPerformActionOnEntryOfType } = (0, _useAccessApi.useAccessApi)(sdk.access);
|
|
40
43
|
(0, _react.useEffect)(()=>{
|
|
41
|
-
function getContentTypes(action) {
|
|
42
|
-
return filter(availableContentTypes, (ct)=>canPerformActionOnEntryOfType(action, ct.sys.id));
|
|
43
|
-
}
|
|
44
44
|
async function checkContentTypeAccess() {
|
|
45
|
-
const creatable = await
|
|
46
|
-
|
|
47
|
-
setCreatableContentTypes(creatable);
|
|
48
|
-
}
|
|
45
|
+
const creatable = await filter(availableContentTypes, (ct)=>canPerformActionOnEntryOfType('create', ct.sys.id));
|
|
46
|
+
setCreatableContentTypes((creatableContentTypes)=>(0, _isEqual.default)(creatable, creatableContentTypes) ? creatableContentTypes : creatable);
|
|
49
47
|
}
|
|
50
48
|
if (availableContentTypes.length > 0) {
|
|
51
49
|
void checkContentTypeAccess();
|
|
52
50
|
}
|
|
53
51
|
}, [
|
|
54
|
-
availableContentTypes
|
|
55
|
-
creatableContentTypes
|
|
52
|
+
availableContentTypes
|
|
56
53
|
]);
|
|
57
54
|
return {
|
|
58
55
|
creatableContentTypes,
|
|
@@ -13,8 +13,12 @@ const _fromFieldValidations = require("../utils/fromFieldValidations");
|
|
|
13
13
|
const _useAccessApi = require("./useAccessApi");
|
|
14
14
|
const _useContentTypePermissions = require("./useContentTypePermissions");
|
|
15
15
|
function useEditorPermissions({ sdk, entityType, parameters, allContentTypes }) {
|
|
16
|
+
const fieldValidations = sdk.field.validations;
|
|
17
|
+
const itemsValidations = sdk.field.type === 'Array' ? sdk.field.items?.validations : undefined;
|
|
16
18
|
const validations = (0, _react.useMemo)(()=>(0, _fromFieldValidations.fromFieldValidations)(sdk.field), [
|
|
17
|
-
sdk.field
|
|
19
|
+
sdk.field,
|
|
20
|
+
JSON.stringify(fieldValidations),
|
|
21
|
+
JSON.stringify(itemsValidations)
|
|
18
22
|
]);
|
|
19
23
|
const [canCreateEntity, setCanCreateEntity] = (0, _react.useState)(true);
|
|
20
24
|
const [canLinkEntity, setCanLinkEntity] = (0, _react.useState)(true);
|
|
@@ -130,6 +130,7 @@ function useLinkActionsProps(props) {
|
|
|
130
130
|
}, [
|
|
131
131
|
sdk,
|
|
132
132
|
entityType,
|
|
133
|
+
editorPermissions,
|
|
133
134
|
onLinkedExisting
|
|
134
135
|
]);
|
|
135
136
|
const onLinkSeveralExisting = _react.useCallback(async (index)=>{
|
|
@@ -145,6 +146,7 @@ function useLinkActionsProps(props) {
|
|
|
145
146
|
}, [
|
|
146
147
|
sdk,
|
|
147
148
|
entityType,
|
|
149
|
+
editorPermissions,
|
|
148
150
|
onLinkedExisting
|
|
149
151
|
]);
|
|
150
152
|
return (0, _react.useMemo)(()=>({
|
|
@@ -85,7 +85,8 @@ function MultipleEntryReferenceEditor(props) {
|
|
|
85
85
|
onMoveTop: index !== 0 ? ()=>childrenProps.onMove(index, 0) : undefined,
|
|
86
86
|
onMoveBottom: index !== lastIndex ? ()=>childrenProps.onMove(index, lastIndex) : undefined,
|
|
87
87
|
renderDragHandle: DragHandle,
|
|
88
|
-
isBeingDragged: index === indexToUpdate
|
|
88
|
+
isBeingDragged: index === indexToUpdate,
|
|
89
|
+
addReferenceToRelease: props.addReferenceToRelease
|
|
89
90
|
});
|
|
90
91
|
}));
|
|
91
92
|
}
|
|
@@ -68,6 +68,7 @@ function SingleEntryReferenceEditor(props) {
|
|
|
68
68
|
hasCardEditActions: hasCardEditActions,
|
|
69
69
|
hasCardRemoveActions: hasCardRemoveActions,
|
|
70
70
|
activeLocales: activeLocales,
|
|
71
|
+
addReferenceToRelease: props.addReferenceToRelease,
|
|
71
72
|
onRemove: ()=>{
|
|
72
73
|
setValue(null);
|
|
73
74
|
}
|
|
@@ -114,6 +114,14 @@ function FetchingWrappedEntryCard(props) {
|
|
|
114
114
|
contentTypeId: entry?.sys?.contentType?.sys?.id ?? ''
|
|
115
115
|
});
|
|
116
116
|
};
|
|
117
|
+
const onAddToRelease = ()=>{
|
|
118
|
+
if (entry && props.addReferenceToRelease) {
|
|
119
|
+
void props.addReferenceToRelease(entry, props.sdk.field.locale, {
|
|
120
|
+
openModalForVersionSelection: true,
|
|
121
|
+
skipNestedReferencesPrompt: true
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
};
|
|
117
125
|
_react.useEffect(()=>{
|
|
118
126
|
if (entry) {
|
|
119
127
|
props.onAction?.({
|
|
@@ -168,7 +176,8 @@ function FetchingWrappedEntryCard(props) {
|
|
|
168
176
|
activeLocales: props.activeLocales,
|
|
169
177
|
releaseStatusMap,
|
|
170
178
|
release: props.sdk.release,
|
|
171
|
-
releaseEntityStatus
|
|
179
|
+
releaseEntityStatus,
|
|
180
|
+
onAddToRelease
|
|
172
181
|
};
|
|
173
182
|
const { hasCardEditActions, hasCardMoveActions, hasCardRemoveActions } = props;
|
|
174
183
|
function renderDefaultCard(props) {
|
|
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "WrappedEntryCard", {
|
|
|
10
10
|
});
|
|
11
11
|
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
|
|
12
12
|
const _f36components = require("@contentful/f36-components");
|
|
13
|
+
const _f36icons = require("@contentful/f36-icons");
|
|
13
14
|
const _fieldeditorshared = require("@contentful/field-editor-shared");
|
|
14
15
|
const _components = require("../../components");
|
|
15
16
|
const _SpaceName = require("../../components/SpaceName/SpaceName");
|
|
@@ -61,7 +62,7 @@ const defaultProps = {
|
|
|
61
62
|
hasCardMoveActions: true,
|
|
62
63
|
hasCardRemoveActions: true
|
|
63
64
|
};
|
|
64
|
-
function WrappedEntryCard({ entry, entryUrl, contentType, activeLocales, localeCode, defaultLocaleCode, localesStatusMap, useLocalizedEntityStatus, size, spaceName, isClickable, isDisabled, isSelected, hasCardMoveActions, hasCardEditActions, hasCardRemoveActions, renderDragHandle, getAsset, getEntityScheduledActions, onClick, onEdit, onRemove, onMoveTop, onMoveBottom, releaseEntityStatus, releaseStatusMap, release }) {
|
|
65
|
+
function WrappedEntryCard({ entry, entryUrl, contentType, activeLocales, localeCode, defaultLocaleCode, localesStatusMap, useLocalizedEntityStatus, size, spaceName, isClickable, isDisabled, isSelected, hasCardMoveActions, hasCardEditActions, hasCardRemoveActions, renderDragHandle, getAsset, getEntityScheduledActions, onClick, onEdit, onRemove, onMoveTop, onMoveBottom, releaseEntityStatus, releaseStatusMap, release, onAddToRelease }) {
|
|
65
66
|
const [file, setFile] = _react.useState(null);
|
|
66
67
|
_react.useEffect(()=>{
|
|
67
68
|
let mounted = true;
|
|
@@ -112,6 +113,7 @@ function WrappedEntryCard({ entry, entryUrl, contentType, activeLocales, localeC
|
|
|
112
113
|
localeCode,
|
|
113
114
|
defaultLocaleCode
|
|
114
115
|
});
|
|
116
|
+
const showAddToReleaseAction = releaseEntityStatus === 'notInRelease' && release !== undefined && onAddToRelease !== undefined && !isDisabled;
|
|
115
117
|
return /*#__PURE__*/ _react.createElement(_f36components.EntryCard, {
|
|
116
118
|
as: isClickable && entryUrl ? 'a' : 'article',
|
|
117
119
|
href: isClickable ? entryUrl : undefined,
|
|
@@ -142,7 +144,7 @@ function WrappedEntryCard({ entry, entryUrl, contentType, activeLocales, localeC
|
|
|
142
144
|
dragHandleRender: renderDragHandle,
|
|
143
145
|
withDragHandle: !!renderDragHandle && !isDisabled,
|
|
144
146
|
draggable: !!renderDragHandle && !isDisabled,
|
|
145
|
-
actions: onEdit || onRemove ? [
|
|
147
|
+
actions: onEdit || onRemove || showAddToReleaseAction ? [
|
|
146
148
|
hasCardEditActions && onEdit ? /*#__PURE__*/ _react.createElement(_f36components.MenuItem, {
|
|
147
149
|
key: "edit",
|
|
148
150
|
testId: "edit",
|
|
@@ -157,6 +159,15 @@ function WrappedEntryCard({ entry, entryUrl, contentType, activeLocales, localeC
|
|
|
157
159
|
onRemove && onRemove();
|
|
158
160
|
}
|
|
159
161
|
}, "Remove") : null,
|
|
162
|
+
showAddToReleaseAction ? /*#__PURE__*/ _react.createElement(_f36components.MenuItem, {
|
|
163
|
+
key: "add-to-release",
|
|
164
|
+
testId: "add-to-release",
|
|
165
|
+
onClick: ()=>{
|
|
166
|
+
onAddToRelease();
|
|
167
|
+
}
|
|
168
|
+
}, /*#__PURE__*/ _react.createElement(_f36icons.PlusIcon, {
|
|
169
|
+
size: "tiny"
|
|
170
|
+
}), "Add to release") : null,
|
|
160
171
|
hasCardMoveActions && (onMoveTop || onMoveBottom) && !isDisabled ? /*#__PURE__*/ _react.createElement(_f36components.MenuDivider, {
|
|
161
172
|
key: "divider"
|
|
162
173
|
}) : null,
|
|
@@ -4,6 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
});
|
|
5
5
|
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
|
|
6
6
|
require("@testing-library/jest-dom");
|
|
7
|
+
const _fieldeditorshared = require("@contentful/field-editor-shared");
|
|
8
|
+
const _fieldeditortestutils = require("@contentful/field-editor-test-utils");
|
|
7
9
|
const _react1 = require("@testing-library/react");
|
|
8
10
|
const _published_content_typejson = /*#__PURE__*/ _interop_require_default(require("../../__fixtures__/content-type/published_content_type.json"));
|
|
9
11
|
const _published_entry_non_masterjson = /*#__PURE__*/ _interop_require_default(require("../../__fixtures__/entry/published_entry_non_master.json"));
|
|
@@ -217,9 +219,33 @@ describe('ResourceCard', ()=>{
|
|
|
217
219
|
_react1.fireEvent.mouseEnter(getByText(_indifferent_spacejson.default.name));
|
|
218
220
|
await (0, _react1.waitFor)(()=>expect(getByText(tooltipContent)).toBeDefined());
|
|
219
221
|
});
|
|
220
|
-
it('renders skeleton
|
|
221
|
-
const
|
|
222
|
+
it('renders skeleton while data is loading', async ()=>{
|
|
223
|
+
const queryClient = (0, _fieldeditortestutils.createTestQueryClient)();
|
|
224
|
+
let resolveEntry;
|
|
225
|
+
const pendingPromise = new Promise((resolve)=>{
|
|
226
|
+
resolveEntry = resolve;
|
|
227
|
+
});
|
|
228
|
+
sdk.cma.entry.get.mockReturnValueOnce(pendingPromise);
|
|
229
|
+
const { getByTestId, queryByTestId } = (0, _react1.render)(/*#__PURE__*/ _react.createElement(_fieldeditorshared.SharedQueryClientProvider, {
|
|
230
|
+
client: queryClient
|
|
231
|
+
}, /*#__PURE__*/ _react.createElement(_EntityStore.EntityProvider, {
|
|
232
|
+
sdk: sdk
|
|
233
|
+
}, /*#__PURE__*/ _react.createElement(_ResourceCard.ResourceCard, {
|
|
234
|
+
isDisabled: false,
|
|
235
|
+
getEntryRouteHref: ()=>'',
|
|
236
|
+
resourceLink: {
|
|
237
|
+
sys: {
|
|
238
|
+
type: 'ResourceLink',
|
|
239
|
+
linkType: 'Contentful:Entry',
|
|
240
|
+
urn: resolvableEntryUrn
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}))));
|
|
222
244
|
expect(getByTestId('cf-ui-skeleton-form')).toBeDefined();
|
|
245
|
+
expect(queryByTestId('cf-ui-entry-card')).toBeNull();
|
|
246
|
+
resolveEntry(_published_entryjson.default);
|
|
247
|
+
await (0, _react1.waitFor)(()=>expect(getByTestId('cf-ui-entry-card')).toBeDefined());
|
|
248
|
+
expect(queryByTestId('cf-ui-skeleton-form')).toBeNull();
|
|
223
249
|
});
|
|
224
250
|
it('renders unsupported entity card when resource type is unknown', async ()=>{
|
|
225
251
|
const { getByText } = renderResourceCard({
|
|
@@ -35,15 +35,6 @@ export function newReferenceEditorFakeSdk(props) {
|
|
|
35
35
|
const delay = (ms)=>{
|
|
36
36
|
return new Promise((resolve)=>setTimeout(resolve, ms));
|
|
37
37
|
};
|
|
38
|
-
const localizeContentTypes = (contentTypes)=>{
|
|
39
|
-
return contentTypes.map((contentType)=>({
|
|
40
|
-
...contentType,
|
|
41
|
-
fields: contentType.fields.map((field)=>({
|
|
42
|
-
...field,
|
|
43
|
-
localized: true
|
|
44
|
-
}))
|
|
45
|
-
}));
|
|
46
|
-
};
|
|
47
38
|
const sdk = {
|
|
48
39
|
field,
|
|
49
40
|
locales,
|
|
@@ -96,6 +87,19 @@ export function newReferenceEditorFakeSdk(props) {
|
|
|
96
87
|
return contentTypes.published;
|
|
97
88
|
}
|
|
98
89
|
return Promise.reject({});
|
|
90
|
+
},
|
|
91
|
+
getMany: async ()=>{
|
|
92
|
+
return Promise.resolve({
|
|
93
|
+
items: [
|
|
94
|
+
contentTypes.published
|
|
95
|
+
],
|
|
96
|
+
total: 1,
|
|
97
|
+
skip: 0,
|
|
98
|
+
limit: 1000,
|
|
99
|
+
sys: {
|
|
100
|
+
type: 'Array'
|
|
101
|
+
}
|
|
102
|
+
});
|
|
99
103
|
}
|
|
100
104
|
},
|
|
101
105
|
Locale: {
|
|
@@ -104,17 +108,6 @@ export function newReferenceEditorFakeSdk(props) {
|
|
|
104
108
|
},
|
|
105
109
|
space: {
|
|
106
110
|
...space,
|
|
107
|
-
getCachedContentTypes () {
|
|
108
|
-
return localizeContentTypes(space.getCachedContentTypes());
|
|
109
|
-
},
|
|
110
|
-
getContentTypes () {
|
|
111
|
-
return Promise.resolve(space.getContentTypes().then((response)=>{
|
|
112
|
-
return {
|
|
113
|
-
...response,
|
|
114
|
-
items: localizeContentTypes(response.items)
|
|
115
|
-
};
|
|
116
|
-
}));
|
|
117
|
-
},
|
|
118
111
|
async getEntityScheduledActions () {
|
|
119
112
|
return [];
|
|
120
113
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { MenuItem, Text, MenuSectionTitle } from '@contentful/f36-components';
|
|
3
|
+
import { PlusIcon } from '@contentful/f36-icons';
|
|
3
4
|
import tokens from '@contentful/f36-tokens';
|
|
4
5
|
import { shortenStorageUnit } from '@contentful/field-editor-shared';
|
|
5
6
|
import { css } from 'emotion';
|
|
@@ -70,7 +71,7 @@ export function renderAssetInfo(props) {
|
|
|
70
71
|
];
|
|
71
72
|
}
|
|
72
73
|
export function renderActions(props) {
|
|
73
|
-
const { entityFile, isDisabled, onEdit, onRemove } = props;
|
|
74
|
+
const { entityFile, isDisabled, onEdit, onRemove, onAddToReleaseAction } = props;
|
|
74
75
|
return [
|
|
75
76
|
/*#__PURE__*/ React.createElement(MenuSectionTitle, {
|
|
76
77
|
key: "section-title"
|
|
@@ -80,6 +81,15 @@ export function renderActions(props) {
|
|
|
80
81
|
onClick: onEdit,
|
|
81
82
|
testId: "card-action-edit"
|
|
82
83
|
}, "Edit") : null,
|
|
84
|
+
onAddToReleaseAction ? /*#__PURE__*/ React.createElement(MenuItem, {
|
|
85
|
+
key: "add-to-release",
|
|
86
|
+
testId: "add-to-release",
|
|
87
|
+
onClick: ()=>{
|
|
88
|
+
onAddToReleaseAction();
|
|
89
|
+
}
|
|
90
|
+
}, /*#__PURE__*/ React.createElement(PlusIcon, {
|
|
91
|
+
size: "tiny"
|
|
92
|
+
}), "Add to release") : null,
|
|
83
93
|
entityFile ? /*#__PURE__*/ React.createElement(MenuItem, {
|
|
84
94
|
key: "download",
|
|
85
95
|
onClick: ()=>{
|
|
@@ -21,6 +21,14 @@ export function FetchingWrappedAssetCard(props) {
|
|
|
21
21
|
locales: props.sdk.locales,
|
|
22
22
|
isReference: true
|
|
23
23
|
});
|
|
24
|
+
const onAddToRelease = ()=>{
|
|
25
|
+
if (asset && props.addReferenceToRelease) {
|
|
26
|
+
void props.addReferenceToRelease(asset, props.sdk.field.locale, {
|
|
27
|
+
openModalForVersionSelection: true,
|
|
28
|
+
skipNestedReferencesPrompt: true
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
24
32
|
React.useEffect(()=>{
|
|
25
33
|
if (asset) {
|
|
26
34
|
props.onAction && props.onAction({
|
|
@@ -87,7 +95,8 @@ export function FetchingWrappedAssetCard(props) {
|
|
|
87
95
|
activeLocales,
|
|
88
96
|
releaseStatusMap,
|
|
89
97
|
release: props.sdk.release,
|
|
90
|
-
releaseEntityStatus
|
|
98
|
+
releaseEntityStatus,
|
|
99
|
+
onAddToRelease
|
|
91
100
|
};
|
|
92
101
|
if (status === 'loading') {
|
|
93
102
|
return props.viewType === 'link' ? /*#__PURE__*/ React.createElement(EntryCard, {
|
|
@@ -31,7 +31,7 @@ function getFileType(file) {
|
|
|
31
31
|
return groupToIconMap[groupName] || 'archive';
|
|
32
32
|
}
|
|
33
33
|
const THUMBNAIL_SIZE = 150;
|
|
34
|
-
export const WrappedAssetCard = ({ asset, className, size, localeCode, defaultLocaleCode, activeLocales, localesStatusMap, isDisabled, isSelected, isClickable, useLocalizedEntityStatus, renderDragHandle, getEntityScheduledActions, onEdit, getAssetUrl, onRemove, releaseEntityStatus, releaseStatusMap, release })=>{
|
|
34
|
+
export const WrappedAssetCard = ({ asset, className, size, localeCode, defaultLocaleCode, activeLocales, localesStatusMap, isDisabled, isSelected, isClickable, useLocalizedEntityStatus, renderDragHandle, getEntityScheduledActions, onEdit, getAssetUrl, onRemove, releaseEntityStatus, releaseStatusMap, release, onAddToRelease })=>{
|
|
35
35
|
const status = entityHelpers.getEntityStatus(asset.sys, useLocalizedEntityStatus ? localeCode : undefined);
|
|
36
36
|
const entityFile = asset.fields.file ? asset.fields.file[localeCode] || asset.fields.file[defaultLocaleCode] : undefined;
|
|
37
37
|
const imageUrl = React.useMemo(()=>{
|
|
@@ -64,6 +64,7 @@ export const WrappedAssetCard = ({ asset, className, size, localeCode, defaultLo
|
|
|
64
64
|
defaultTitle: 'Untitled'
|
|
65
65
|
});
|
|
66
66
|
const href = getAssetUrl ? getAssetUrl(asset.sys.id) : undefined;
|
|
67
|
+
const onAddToReleaseAction = releaseEntityStatus === 'notInRelease' && release !== undefined && onAddToRelease !== undefined && !isDisabled ? onAddToRelease : undefined;
|
|
67
68
|
return /*#__PURE__*/ React.createElement(AssetCard, {
|
|
68
69
|
as: isClickable && href ? 'a' : 'article',
|
|
69
70
|
type: getFileType(entityFile),
|
|
@@ -102,7 +103,8 @@ export const WrappedAssetCard = ({ asset, className, size, localeCode, defaultLo
|
|
|
102
103
|
entityFile,
|
|
103
104
|
isDisabled: isDisabled,
|
|
104
105
|
onEdit,
|
|
105
|
-
onRemove
|
|
106
|
+
onRemove,
|
|
107
|
+
onAddToReleaseAction
|
|
106
108
|
}),
|
|
107
109
|
...entityFile ? renderAssetInfo({
|
|
108
110
|
entityFile
|
|
@@ -12,10 +12,10 @@ function _define_property(obj, key, value) {
|
|
|
12
12
|
return obj;
|
|
13
13
|
}
|
|
14
14
|
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
15
|
+
import { createGetContentTypeKey, createGetEntryKey, createGetSpaceKey } from '@contentful/field-editor-shared';
|
|
15
16
|
import constate from 'constate';
|
|
16
17
|
import { fetchAll } from 'contentful-management';
|
|
17
18
|
import { get } from 'lodash';
|
|
18
|
-
import moment from 'moment';
|
|
19
19
|
import PQueue from 'p-queue';
|
|
20
20
|
import { SharedQueryClientProvider, useQuery, useQueryClient } from './queryClient';
|
|
21
21
|
export function isContentfulResourceInfo(info) {
|
|
@@ -75,18 +75,10 @@ async function fetchContentfulEntry({ urn, fetch, options }) {
|
|
|
75
75
|
const environmentId = resourceIdMatch?.groups?.environmentId || 'master';
|
|
76
76
|
const entryId = resourceIdMatch.groups.entityId;
|
|
77
77
|
const [space, entry] = await Promise.all([
|
|
78
|
-
fetch(
|
|
79
|
-
'space',
|
|
80
|
-
spaceId
|
|
81
|
-
], ({ cmaClient })=>cmaClient.space.get({
|
|
78
|
+
fetch(createGetSpaceKey(spaceId), ({ cmaClient })=>cmaClient.space.get({
|
|
82
79
|
spaceId
|
|
83
80
|
}), options),
|
|
84
|
-
fetch(
|
|
85
|
-
'entry',
|
|
86
|
-
spaceId,
|
|
87
|
-
environmentId,
|
|
88
|
-
entryId
|
|
89
|
-
], ({ cmaClient })=>cmaClient.entry.get({
|
|
81
|
+
fetch(createGetEntryKey(spaceId, environmentId, entryId), ({ cmaClient })=>cmaClient.entry.get({
|
|
90
82
|
spaceId,
|
|
91
83
|
environmentId,
|
|
92
84
|
entryId
|
|
@@ -94,12 +86,7 @@ async function fetchContentfulEntry({ urn, fetch, options }) {
|
|
|
94
86
|
]);
|
|
95
87
|
const contentTypeId = entry.sys.contentType.sys.id;
|
|
96
88
|
const [contentType, defaultLocaleCode] = await Promise.all([
|
|
97
|
-
fetch(
|
|
98
|
-
'contentType',
|
|
99
|
-
spaceId,
|
|
100
|
-
environmentId,
|
|
101
|
-
contentTypeId
|
|
102
|
-
], ({ cmaClient })=>cmaClient.contentType.get({
|
|
89
|
+
fetch(createGetContentTypeKey(spaceId, environmentId, contentTypeId), ({ cmaClient })=>cmaClient.contentType.get({
|
|
103
90
|
contentTypeId,
|
|
104
91
|
spaceId,
|
|
105
92
|
environmentId
|
|
@@ -311,7 +298,6 @@ const [InternalServiceProvider, useFetch, useEntityLoader, useCurrentIds] = cons
|
|
|
311
298
|
const query = {
|
|
312
299
|
'environment.sys.id': environmentId,
|
|
313
300
|
'sys.status': 'scheduled',
|
|
314
|
-
'scheduledFor.datetime[gte]': moment().startOf('hour').toISOString(),
|
|
315
301
|
'entity.sys.linkType[in]': 'Entry,Asset',
|
|
316
302
|
order: '-scheduledFor.datetime',
|
|
317
303
|
limit: maxScheduledActions
|
|
@@ -385,17 +371,41 @@ const [InternalServiceProvider, useFetch, useEntityLoader, useCurrentIds] = cons
|
|
|
385
371
|
useEffect(()=>{
|
|
386
372
|
function findSameSpaceQueries() {
|
|
387
373
|
const queries = queryCache.findAll({
|
|
388
|
-
type: 'active',
|
|
389
374
|
predicate: (query)=>isSameSpaceEntityQueryKey(query.queryKey)
|
|
390
375
|
});
|
|
391
376
|
return queries;
|
|
392
377
|
}
|
|
393
378
|
if (typeof onEntityChanged !== 'function') {
|
|
394
|
-
return onSlideInNavigation(({ oldSlideLevel, newSlideLevel })=>{
|
|
379
|
+
return onSlideInNavigation(async ({ oldSlideLevel, newSlideLevel })=>{
|
|
395
380
|
if (oldSlideLevel > newSlideLevel) {
|
|
396
|
-
findSameSpaceQueries()
|
|
397
|
-
|
|
398
|
-
|
|
381
|
+
const queries = findSameSpaceQueries();
|
|
382
|
+
await Promise.all(queries.map(async (query)=>{
|
|
383
|
+
const [entityType, entityId, spaceId, environmentId, releaseId] = query.queryKey;
|
|
384
|
+
try {
|
|
385
|
+
let freshData;
|
|
386
|
+
if (entityType === 'Entry') {
|
|
387
|
+
freshData = await cmaClient.entry.get({
|
|
388
|
+
entryId: entityId,
|
|
389
|
+
spaceId: spaceId,
|
|
390
|
+
environmentId: environmentId,
|
|
391
|
+
releaseId: releaseId
|
|
392
|
+
});
|
|
393
|
+
} else if (entityType === 'Asset') {
|
|
394
|
+
freshData = await cmaClient.asset.get({
|
|
395
|
+
assetId: entityId,
|
|
396
|
+
spaceId: spaceId,
|
|
397
|
+
environmentId: environmentId,
|
|
398
|
+
releaseId: releaseId
|
|
399
|
+
});
|
|
400
|
+
} else {
|
|
401
|
+
await queryClient.invalidateQueries(query.queryKey);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
queryClient.setQueryData(query.queryKey, freshData);
|
|
405
|
+
} catch (error) {
|
|
406
|
+
await queryClient.invalidateQueries(query.queryKey);
|
|
407
|
+
}
|
|
408
|
+
}));
|
|
399
409
|
}
|
|
400
410
|
});
|
|
401
411
|
}
|
|
@@ -438,7 +448,8 @@ const [InternalServiceProvider, useFetch, useEntityLoader, useCurrentIds] = cons
|
|
|
438
448
|
isSameSpaceEntityQueryKey,
|
|
439
449
|
queryClient,
|
|
440
450
|
getEntity,
|
|
441
|
-
onSlideInNavigation
|
|
451
|
+
onSlideInNavigation,
|
|
452
|
+
cmaClient
|
|
442
453
|
]);
|
|
443
454
|
const getResourceProvider = useCallback(function getResourceProvider(organizationId, appDefinitionId) {
|
|
444
455
|
const queryKey = [
|
|
@@ -544,6 +555,8 @@ export function useResourceProvider(organizationId, appDefinitionId) {
|
|
|
544
555
|
};
|
|
545
556
|
}
|
|
546
557
|
function EntityProvider({ children, ...props }) {
|
|
547
|
-
return /*#__PURE__*/ React.createElement(SharedQueryClientProvider,
|
|
558
|
+
return /*#__PURE__*/ React.createElement(SharedQueryClientProvider, {
|
|
559
|
+
client: props.queryClient
|
|
560
|
+
}, /*#__PURE__*/ React.createElement(InternalServiceProvider, props, children));
|
|
548
561
|
}
|
|
549
562
|
export { EntityProvider, useEntityLoader };
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { useCallback } from 'react';
|
|
3
|
+
import { useContentTypes } from '@contentful/field-editor-shared';
|
|
3
4
|
import { arrayMove } from '@dnd-kit/sortable';
|
|
4
5
|
import { LinkEntityActions } from '../components';
|
|
5
6
|
import { useLinkActionsProps } from '../components/LinkActions/LinkEntityActions';
|
|
6
7
|
import { useSortIDs } from '../utils/useSortIDs';
|
|
8
|
+
import { SharedQueryClientProvider } from './queryClient';
|
|
7
9
|
import { ReferenceEditor } from './ReferenceEditor';
|
|
8
10
|
import { useEditorPermissions } from './useEditorPermissions';
|
|
9
11
|
function onLinkOrCreate(setValue, entityType, items, ids, index = items.length) {
|
|
@@ -95,7 +97,10 @@ function Editor(props) {
|
|
|
95
97
|
}));
|
|
96
98
|
}
|
|
97
99
|
export function MultipleReferenceEditor(props) {
|
|
98
|
-
|
|
100
|
+
return /*#__PURE__*/ React.createElement(SharedQueryClientProvider, null, /*#__PURE__*/ React.createElement(MultipleReferenceEditorInner, props));
|
|
101
|
+
}
|
|
102
|
+
function MultipleReferenceEditorInner(props) {
|
|
103
|
+
const { contentTypes: allContentTypes } = useContentTypes(props.sdk);
|
|
99
104
|
return /*#__PURE__*/ React.createElement(ReferenceEditor, props, ({ value, disabled, setValue, externalReset })=>{
|
|
100
105
|
return /*#__PURE__*/ React.createElement(Editor, {
|
|
101
106
|
...props,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { useCallback } from 'react';
|
|
3
|
+
import { useContentTypes } from '@contentful/field-editor-shared';
|
|
3
4
|
import { LinkEntityActions } from '../components';
|
|
4
5
|
import { useLinkActionsProps } from '../components/LinkActions/LinkEntityActions';
|
|
6
|
+
import { SharedQueryClientProvider } from './queryClient';
|
|
5
7
|
import { ReferenceEditor } from './ReferenceEditor';
|
|
6
8
|
import { useEditorPermissions } from './useEditorPermissions';
|
|
7
9
|
function Editor(props) {
|
|
@@ -48,11 +50,15 @@ function Editor(props) {
|
|
|
48
50
|
}
|
|
49
51
|
return props.children({
|
|
50
52
|
...props,
|
|
51
|
-
renderCustomCard: props.renderCustomCard && customCardRenderer
|
|
53
|
+
renderCustomCard: props.renderCustomCard && customCardRenderer,
|
|
54
|
+
addReferenceToRelease: props.addReferenceToRelease
|
|
52
55
|
});
|
|
53
56
|
}
|
|
54
57
|
export function SingleReferenceEditor(props) {
|
|
55
|
-
|
|
58
|
+
return /*#__PURE__*/ React.createElement(SharedQueryClientProvider, null, /*#__PURE__*/ React.createElement(SingleReferenceEditorInner, props));
|
|
59
|
+
}
|
|
60
|
+
function SingleReferenceEditorInner(props) {
|
|
61
|
+
const { contentTypes: allContentTypes } = useContentTypes(props.sdk);
|
|
56
62
|
return /*#__PURE__*/ React.createElement(ReferenceEditor, props, ({ value, setValue, disabled, externalReset })=>{
|
|
57
63
|
return /*#__PURE__*/ React.createElement(Editor, {
|
|
58
64
|
...props,
|
|
@@ -11,6 +11,9 @@ export function useContentTypePermissions({ entityType, validations, sdk, allCon
|
|
|
11
11
|
if (entityType === 'Asset') {
|
|
12
12
|
return [];
|
|
13
13
|
}
|
|
14
|
+
if (validations.contentTypes && allContentTypes.length === 0) {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
14
17
|
if (validations.contentTypes) {
|
|
15
18
|
return allContentTypes.filter((ct)=>validations.contentTypes?.includes(ct.sys.id));
|
|
16
19
|
}
|
|
@@ -23,21 +26,15 @@ export function useContentTypePermissions({ entityType, validations, sdk, allCon
|
|
|
23
26
|
const [creatableContentTypes, setCreatableContentTypes] = useState(availableContentTypes);
|
|
24
27
|
const { canPerformActionOnEntryOfType } = useAccessApi(sdk.access);
|
|
25
28
|
useEffect(()=>{
|
|
26
|
-
function getContentTypes(action) {
|
|
27
|
-
return filter(availableContentTypes, (ct)=>canPerformActionOnEntryOfType(action, ct.sys.id));
|
|
28
|
-
}
|
|
29
29
|
async function checkContentTypeAccess() {
|
|
30
|
-
const creatable = await
|
|
31
|
-
|
|
32
|
-
setCreatableContentTypes(creatable);
|
|
33
|
-
}
|
|
30
|
+
const creatable = await filter(availableContentTypes, (ct)=>canPerformActionOnEntryOfType('create', ct.sys.id));
|
|
31
|
+
setCreatableContentTypes((creatableContentTypes)=>isEqual(creatable, creatableContentTypes) ? creatableContentTypes : creatable);
|
|
34
32
|
}
|
|
35
33
|
if (availableContentTypes.length > 0) {
|
|
36
34
|
void checkContentTypeAccess();
|
|
37
35
|
}
|
|
38
36
|
}, [
|
|
39
|
-
availableContentTypes
|
|
40
|
-
creatableContentTypes
|
|
37
|
+
availableContentTypes
|
|
41
38
|
]);
|
|
42
39
|
return {
|
|
43
40
|
creatableContentTypes,
|
|
@@ -3,8 +3,12 @@ import { fromFieldValidations } from '../utils/fromFieldValidations';
|
|
|
3
3
|
import { useAccessApi } from './useAccessApi';
|
|
4
4
|
import { useContentTypePermissions } from './useContentTypePermissions';
|
|
5
5
|
export function useEditorPermissions({ sdk, entityType, parameters, allContentTypes }) {
|
|
6
|
+
const fieldValidations = sdk.field.validations;
|
|
7
|
+
const itemsValidations = sdk.field.type === 'Array' ? sdk.field.items?.validations : undefined;
|
|
6
8
|
const validations = useMemo(()=>fromFieldValidations(sdk.field), [
|
|
7
|
-
sdk.field
|
|
9
|
+
sdk.field,
|
|
10
|
+
JSON.stringify(fieldValidations),
|
|
11
|
+
JSON.stringify(itemsValidations)
|
|
8
12
|
]);
|
|
9
13
|
const [canCreateEntity, setCanCreateEntity] = useState(true);
|
|
10
14
|
const [canLinkEntity, setCanLinkEntity] = useState(true);
|
|
@@ -69,6 +69,7 @@ export function useLinkActionsProps(props) {
|
|
|
69
69
|
}, [
|
|
70
70
|
sdk,
|
|
71
71
|
entityType,
|
|
72
|
+
editorPermissions,
|
|
72
73
|
onLinkedExisting
|
|
73
74
|
]);
|
|
74
75
|
const onLinkSeveralExisting = React.useCallback(async (index)=>{
|
|
@@ -84,6 +85,7 @@ export function useLinkActionsProps(props) {
|
|
|
84
85
|
}, [
|
|
85
86
|
sdk,
|
|
86
87
|
entityType,
|
|
88
|
+
editorPermissions,
|
|
87
89
|
onLinkedExisting
|
|
88
90
|
]);
|
|
89
91
|
return useMemo(()=>({
|
|
@@ -34,7 +34,8 @@ export function MultipleEntryReferenceEditor(props) {
|
|
|
34
34
|
onMoveTop: index !== 0 ? ()=>childrenProps.onMove(index, 0) : undefined,
|
|
35
35
|
onMoveBottom: index !== lastIndex ? ()=>childrenProps.onMove(index, lastIndex) : undefined,
|
|
36
36
|
renderDragHandle: DragHandle,
|
|
37
|
-
isBeingDragged: index === indexToUpdate
|
|
37
|
+
isBeingDragged: index === indexToUpdate,
|
|
38
|
+
addReferenceToRelease: props.addReferenceToRelease
|
|
38
39
|
});
|
|
39
40
|
}));
|
|
40
41
|
}
|
|
@@ -17,6 +17,7 @@ export function SingleEntryReferenceEditor(props) {
|
|
|
17
17
|
hasCardEditActions: hasCardEditActions,
|
|
18
18
|
hasCardRemoveActions: hasCardRemoveActions,
|
|
19
19
|
activeLocales: activeLocales,
|
|
20
|
+
addReferenceToRelease: props.addReferenceToRelease,
|
|
20
21
|
onRemove: ()=>{
|
|
21
22
|
setValue(null);
|
|
22
23
|
}
|
|
@@ -63,6 +63,14 @@ export function FetchingWrappedEntryCard(props) {
|
|
|
63
63
|
contentTypeId: entry?.sys?.contentType?.sys?.id ?? ''
|
|
64
64
|
});
|
|
65
65
|
};
|
|
66
|
+
const onAddToRelease = ()=>{
|
|
67
|
+
if (entry && props.addReferenceToRelease) {
|
|
68
|
+
void props.addReferenceToRelease(entry, props.sdk.field.locale, {
|
|
69
|
+
openModalForVersionSelection: true,
|
|
70
|
+
skipNestedReferencesPrompt: true
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
};
|
|
66
74
|
React.useEffect(()=>{
|
|
67
75
|
if (entry) {
|
|
68
76
|
props.onAction?.({
|
|
@@ -117,7 +125,8 @@ export function FetchingWrappedEntryCard(props) {
|
|
|
117
125
|
activeLocales: props.activeLocales,
|
|
118
126
|
releaseStatusMap,
|
|
119
127
|
release: props.sdk.release,
|
|
120
|
-
releaseEntityStatus
|
|
128
|
+
releaseEntityStatus,
|
|
129
|
+
onAddToRelease
|
|
121
130
|
};
|
|
122
131
|
const { hasCardEditActions, hasCardMoveActions, hasCardRemoveActions } = props;
|
|
123
132
|
function renderDefaultCard(props) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { EntryCard, MenuDivider, MenuItem } from '@contentful/f36-components';
|
|
3
|
+
import { PlusIcon } from '@contentful/f36-icons';
|
|
3
4
|
import { entityHelpers, isValidImage } from '@contentful/field-editor-shared';
|
|
4
5
|
import { AssetThumbnail, MissingEntityCard, EntityStatusBadge } from '../../components';
|
|
5
6
|
import { SpaceName } from '../../components/SpaceName/SpaceName';
|
|
@@ -10,7 +11,7 @@ const defaultProps = {
|
|
|
10
11
|
hasCardMoveActions: true,
|
|
11
12
|
hasCardRemoveActions: true
|
|
12
13
|
};
|
|
13
|
-
export function WrappedEntryCard({ entry, entryUrl, contentType, activeLocales, localeCode, defaultLocaleCode, localesStatusMap, useLocalizedEntityStatus, size, spaceName, isClickable, isDisabled, isSelected, hasCardMoveActions, hasCardEditActions, hasCardRemoveActions, renderDragHandle, getAsset, getEntityScheduledActions, onClick, onEdit, onRemove, onMoveTop, onMoveBottom, releaseEntityStatus, releaseStatusMap, release }) {
|
|
14
|
+
export function WrappedEntryCard({ entry, entryUrl, contentType, activeLocales, localeCode, defaultLocaleCode, localesStatusMap, useLocalizedEntityStatus, size, spaceName, isClickable, isDisabled, isSelected, hasCardMoveActions, hasCardEditActions, hasCardRemoveActions, renderDragHandle, getAsset, getEntityScheduledActions, onClick, onEdit, onRemove, onMoveTop, onMoveBottom, releaseEntityStatus, releaseStatusMap, release, onAddToRelease }) {
|
|
14
15
|
const [file, setFile] = React.useState(null);
|
|
15
16
|
React.useEffect(()=>{
|
|
16
17
|
let mounted = true;
|
|
@@ -61,6 +62,7 @@ export function WrappedEntryCard({ entry, entryUrl, contentType, activeLocales,
|
|
|
61
62
|
localeCode,
|
|
62
63
|
defaultLocaleCode
|
|
63
64
|
});
|
|
65
|
+
const showAddToReleaseAction = releaseEntityStatus === 'notInRelease' && release !== undefined && onAddToRelease !== undefined && !isDisabled;
|
|
64
66
|
return /*#__PURE__*/ React.createElement(EntryCard, {
|
|
65
67
|
as: isClickable && entryUrl ? 'a' : 'article',
|
|
66
68
|
href: isClickable ? entryUrl : undefined,
|
|
@@ -91,7 +93,7 @@ export function WrappedEntryCard({ entry, entryUrl, contentType, activeLocales,
|
|
|
91
93
|
dragHandleRender: renderDragHandle,
|
|
92
94
|
withDragHandle: !!renderDragHandle && !isDisabled,
|
|
93
95
|
draggable: !!renderDragHandle && !isDisabled,
|
|
94
|
-
actions: onEdit || onRemove ? [
|
|
96
|
+
actions: onEdit || onRemove || showAddToReleaseAction ? [
|
|
95
97
|
hasCardEditActions && onEdit ? /*#__PURE__*/ React.createElement(MenuItem, {
|
|
96
98
|
key: "edit",
|
|
97
99
|
testId: "edit",
|
|
@@ -106,6 +108,15 @@ export function WrappedEntryCard({ entry, entryUrl, contentType, activeLocales,
|
|
|
106
108
|
onRemove && onRemove();
|
|
107
109
|
}
|
|
108
110
|
}, "Remove") : null,
|
|
111
|
+
showAddToReleaseAction ? /*#__PURE__*/ React.createElement(MenuItem, {
|
|
112
|
+
key: "add-to-release",
|
|
113
|
+
testId: "add-to-release",
|
|
114
|
+
onClick: ()=>{
|
|
115
|
+
onAddToRelease();
|
|
116
|
+
}
|
|
117
|
+
}, /*#__PURE__*/ React.createElement(PlusIcon, {
|
|
118
|
+
size: "tiny"
|
|
119
|
+
}), "Add to release") : null,
|
|
109
120
|
hasCardMoveActions && (onMoveTop || onMoveBottom) && !isDisabled ? /*#__PURE__*/ React.createElement(MenuDivider, {
|
|
110
121
|
key: "divider"
|
|
111
122
|
}) : null,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import '@testing-library/jest-dom';
|
|
3
|
+
import { SharedQueryClientProvider } from '@contentful/field-editor-shared';
|
|
4
|
+
import { createTestQueryClient } from '@contentful/field-editor-test-utils';
|
|
3
5
|
import { configure, fireEvent, render, waitFor } from '@testing-library/react';
|
|
4
6
|
import publishedCT from '../../__fixtures__/content-type/published_content_type.json';
|
|
5
7
|
import publishedEntryNonMasterEnvironment from '../../__fixtures__/entry/published_entry_non_master.json';
|
|
@@ -167,9 +169,33 @@ describe('ResourceCard', ()=>{
|
|
|
167
169
|
fireEvent.mouseEnter(getByText(space.name));
|
|
168
170
|
await waitFor(()=>expect(getByText(tooltipContent)).toBeDefined());
|
|
169
171
|
});
|
|
170
|
-
it('renders skeleton
|
|
171
|
-
const
|
|
172
|
+
it('renders skeleton while data is loading', async ()=>{
|
|
173
|
+
const queryClient = createTestQueryClient();
|
|
174
|
+
let resolveEntry;
|
|
175
|
+
const pendingPromise = new Promise((resolve)=>{
|
|
176
|
+
resolveEntry = resolve;
|
|
177
|
+
});
|
|
178
|
+
sdk.cma.entry.get.mockReturnValueOnce(pendingPromise);
|
|
179
|
+
const { getByTestId, queryByTestId } = render(/*#__PURE__*/ React.createElement(SharedQueryClientProvider, {
|
|
180
|
+
client: queryClient
|
|
181
|
+
}, /*#__PURE__*/ React.createElement(EntityProvider, {
|
|
182
|
+
sdk: sdk
|
|
183
|
+
}, /*#__PURE__*/ React.createElement(ResourceCard, {
|
|
184
|
+
isDisabled: false,
|
|
185
|
+
getEntryRouteHref: ()=>'',
|
|
186
|
+
resourceLink: {
|
|
187
|
+
sys: {
|
|
188
|
+
type: 'ResourceLink',
|
|
189
|
+
linkType: 'Contentful:Entry',
|
|
190
|
+
urn: resolvableEntryUrn
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}))));
|
|
172
194
|
expect(getByTestId('cf-ui-skeleton-form')).toBeDefined();
|
|
195
|
+
expect(queryByTestId('cf-ui-entry-card')).toBeNull();
|
|
196
|
+
resolveEntry(publishedEntry);
|
|
197
|
+
await waitFor(()=>expect(getByTestId('cf-ui-entry-card')).toBeDefined());
|
|
198
|
+
expect(queryByTestId('cf-ui-skeleton-form')).toBeNull();
|
|
173
199
|
});
|
|
174
200
|
it('renders unsupported entity card when resource type is unknown', async ()=>{
|
|
175
201
|
const { getByText } = renderResourceCard({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { CustomCardRenderer, RenderCustomMissingEntityCard } from '../../common/customCardTypes';
|
|
3
|
-
import { Action, FieldAppSDK, ViewType, RenderDragFn } from '../../types';
|
|
3
|
+
import { Action, Asset, FieldAppSDK, ViewType, RenderDragFn } from '../../types';
|
|
4
4
|
type FetchingWrappedAssetCardProps = {
|
|
5
5
|
assetId: string;
|
|
6
6
|
isDisabled: boolean;
|
|
@@ -12,6 +12,10 @@ type FetchingWrappedAssetCardProps = {
|
|
|
12
12
|
renderDragHandle?: RenderDragFn;
|
|
13
13
|
renderCustomCard?: CustomCardRenderer;
|
|
14
14
|
renderCustomMissingEntityCard?: RenderCustomMissingEntityCard;
|
|
15
|
+
addReferenceToRelease?: (reference: Asset, localeCode?: string, options?: {
|
|
16
|
+
openModalForVersionSelection?: boolean;
|
|
17
|
+
skipNestedReferencesPrompt?: boolean;
|
|
18
|
+
}) => Promise<void>;
|
|
15
19
|
};
|
|
16
20
|
export declare function FetchingWrappedAssetCard(props: FetchingWrappedAssetCardProps): React.JSX.Element;
|
|
17
21
|
export {};
|
|
@@ -23,9 +23,10 @@ export interface WrappedAssetCardProps {
|
|
|
23
23
|
releaseEntityStatus?: ReleaseEntityStatus;
|
|
24
24
|
releaseStatusMap?: ReleaseStatusMap;
|
|
25
25
|
release?: ReleaseV2Props;
|
|
26
|
+
onAddToRelease?: () => void;
|
|
26
27
|
}
|
|
27
28
|
export declare const WrappedAssetCard: {
|
|
28
|
-
({ asset, className, size, localeCode, defaultLocaleCode, activeLocales, localesStatusMap, isDisabled, isSelected, isClickable, useLocalizedEntityStatus, renderDragHandle, getEntityScheduledActions, onEdit, getAssetUrl, onRemove, releaseEntityStatus, releaseStatusMap, release, }: WrappedAssetCardProps): React.JSX.Element;
|
|
29
|
+
({ asset, className, size, localeCode, defaultLocaleCode, activeLocales, localesStatusMap, isDisabled, isSelected, isClickable, useLocalizedEntityStatus, renderDragHandle, getEntityScheduledActions, onEdit, getAssetUrl, onRemove, releaseEntityStatus, releaseStatusMap, release, onAddToRelease, }: WrappedAssetCardProps): React.JSX.Element;
|
|
29
30
|
defaultProps: {
|
|
30
31
|
isClickable: boolean;
|
|
31
32
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { BaseAppSDK } from '@contentful/app-sdk';
|
|
3
|
+
import { QueryClient } from '@tanstack/react-query';
|
|
3
4
|
import { ResourceProvider } from 'contentful-management';
|
|
4
5
|
import { Asset, ContentType, Entry, ExternalResource, Resource, ResourceType, ScheduledAction, Space } from '../types';
|
|
5
6
|
export type ContentfulResourceInfo = {
|
|
@@ -17,6 +18,7 @@ export declare function isContentfulResourceInfo(info: ResourceInfo): info is Co
|
|
|
17
18
|
type EntityStoreProps = {
|
|
18
19
|
sdk: BaseAppSDK;
|
|
19
20
|
queryConcurrency?: number;
|
|
21
|
+
queryClient?: QueryClient;
|
|
20
22
|
};
|
|
21
23
|
type GetOptions = {
|
|
22
24
|
priority?: number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { FieldConnector } from '@contentful/field-editor-shared';
|
|
3
3
|
import type { LinkActionsProps } from '../components';
|
|
4
|
-
import { Action, ActionLabels, FieldAppSDK, ViewType } from '../types';
|
|
4
|
+
import { Action, ActionLabels, FieldAppSDK, ViewType, Entry, Asset } from '../types';
|
|
5
5
|
import { CustomCardRenderer, RenderCustomMissingEntityCard } from './customCardTypes';
|
|
6
6
|
export interface ReferenceEditorProps {
|
|
7
7
|
/**
|
|
@@ -33,6 +33,10 @@ export interface ReferenceEditorProps {
|
|
|
33
33
|
oldIndex: number;
|
|
34
34
|
newIndex: number;
|
|
35
35
|
}) => void;
|
|
36
|
+
addReferenceToRelease?: (reference: Entry | Asset, localeCode?: string, options?: {
|
|
37
|
+
openModalForVersionSelection?: boolean;
|
|
38
|
+
skipNestedReferencesPrompt?: boolean;
|
|
39
|
+
}) => Promise<void>;
|
|
36
40
|
}
|
|
37
41
|
export type CustomActionProps = LinkActionsProps;
|
|
38
42
|
export declare function ReferenceEditor<T>(props: ReferenceEditorProps & {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { RenderCustomMissingEntityCard } from '../../common/customCardTypes';
|
|
3
3
|
import { ReferenceEditorProps } from '../../common/ReferenceEditor';
|
|
4
|
-
import { ContentType, RenderDragFn } from '../../types';
|
|
4
|
+
import { ContentType, Entry, RenderDragFn } from '../../types';
|
|
5
5
|
export type EntryCardReferenceEditorProps = ReferenceEditorProps & {
|
|
6
6
|
entryId: string;
|
|
7
7
|
index?: number;
|
|
@@ -17,5 +17,9 @@ export type EntryCardReferenceEditorProps = ReferenceEditorProps & {
|
|
|
17
17
|
activeLocales?: {
|
|
18
18
|
code: string;
|
|
19
19
|
}[];
|
|
20
|
+
addReferenceToRelease?: (reference: Entry, localeCode?: string, options?: {
|
|
21
|
+
openModalForVersionSelection?: boolean;
|
|
22
|
+
skipNestedReferencesPrompt?: boolean;
|
|
23
|
+
}) => Promise<void>;
|
|
20
24
|
};
|
|
21
25
|
export declare function FetchingWrappedEntryCard(props: EntryCardReferenceEditorProps): React.JSX.Element;
|
|
@@ -31,8 +31,9 @@ export interface WrappedEntryCardProps {
|
|
|
31
31
|
releaseEntityStatus?: ReleaseEntityStatus;
|
|
32
32
|
releaseStatusMap?: ReleaseStatusMap;
|
|
33
33
|
release?: ReleaseV2Props;
|
|
34
|
+
onAddToRelease?: () => void;
|
|
34
35
|
}
|
|
35
|
-
export declare function WrappedEntryCard({ entry, entryUrl, contentType, activeLocales, localeCode, defaultLocaleCode, localesStatusMap, useLocalizedEntityStatus, size, spaceName, isClickable, isDisabled, isSelected, hasCardMoveActions, hasCardEditActions, hasCardRemoveActions, renderDragHandle, getAsset, getEntityScheduledActions, onClick, onEdit, onRemove, onMoveTop, onMoveBottom, releaseEntityStatus, releaseStatusMap, release, }: WrappedEntryCardProps): React.JSX.Element;
|
|
36
|
+
export declare function WrappedEntryCard({ entry, entryUrl, contentType, activeLocales, localeCode, defaultLocaleCode, localesStatusMap, useLocalizedEntityStatus, size, spaceName, isClickable, isDisabled, isSelected, hasCardMoveActions, hasCardEditActions, hasCardRemoveActions, renderDragHandle, getAsset, getEntityScheduledActions, onClick, onEdit, onRemove, onMoveTop, onMoveBottom, releaseEntityStatus, releaseStatusMap, release, onAddToRelease, }: WrappedEntryCardProps): React.JSX.Element;
|
|
36
37
|
export declare namespace WrappedEntryCard {
|
|
37
38
|
var defaultProps: {
|
|
38
39
|
isClickable: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/field-editor-reference",
|
|
3
|
-
"version": "6.19.3",
|
|
3
|
+
"version": "6.19.4-canary.3+91057409",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
5
|
"module": "dist/esm/index.js",
|
|
6
6
|
"types": "dist/types/index.d.ts",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"@contentful/f36-components": "^5.8.1",
|
|
40
40
|
"@contentful/f36-icons": "^5.8.1",
|
|
41
41
|
"@contentful/f36-tokens": "^5.1.0",
|
|
42
|
-
"@contentful/field-editor-shared": "^2.17.
|
|
42
|
+
"@contentful/field-editor-shared": "^2.17.2-canary.5+91057409",
|
|
43
43
|
"@contentful/mimetype": "^2.2.29",
|
|
44
44
|
"@dnd-kit/core": "^6.0.8",
|
|
45
45
|
"@dnd-kit/sortable": "^8.0.0",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@contentful/app-sdk": "^4.42.0",
|
|
59
|
-
"@contentful/field-editor-test-utils": "^1.7.
|
|
59
|
+
"@contentful/field-editor-test-utils": "^1.7.1-canary.80+91057409",
|
|
60
60
|
"@lingui/core": "5.3.0",
|
|
61
61
|
"@testing-library/react-hooks": "^8.0.1"
|
|
62
62
|
},
|
|
@@ -68,5 +68,5 @@
|
|
|
68
68
|
"publishConfig": {
|
|
69
69
|
"registry": "https://npm.pkg.github.com/"
|
|
70
70
|
},
|
|
71
|
-
"gitHead": "
|
|
71
|
+
"gitHead": "91057409eff77b4928882406258a35549f14e88d"
|
|
72
72
|
}
|