@contentful/field-editor-reference 5.30.14 → 5.31.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. package/dist/cjs/assets/WrappedAssetCard/FetchingWrappedAssetCard.js +4 -0
  2. package/dist/cjs/assets/WrappedAssetCard/WrappedAssetCard.js +5 -5
  3. package/dist/cjs/assets/WrappedAssetCard/WrappedAssetLink.js +5 -2
  4. package/dist/cjs/components/CreateEntryLinkButton/CreateEntryMenuTrigger.js +11 -5
  5. package/dist/cjs/components/CreateEntryLinkButton/CreateEntryMenuTrigger.spec.js +41 -0
  6. package/dist/cjs/components/EntityStatusBadge/EntityStatusBadge.js +12 -2
  7. package/dist/cjs/entries/WrappedEntryCard/FetchingWrappedEntryCard.js +4 -0
  8. package/dist/cjs/entries/WrappedEntryCard/WrappedEntryCard.js +6 -5
  9. package/dist/esm/assets/WrappedAssetCard/FetchingWrappedAssetCard.js +4 -0
  10. package/dist/esm/assets/WrappedAssetCard/WrappedAssetCard.js +6 -6
  11. package/dist/esm/assets/WrappedAssetCard/WrappedAssetLink.js +5 -2
  12. package/dist/esm/components/CreateEntryLinkButton/CreateEntryMenuTrigger.js +12 -6
  13. package/dist/esm/components/CreateEntryLinkButton/CreateEntryMenuTrigger.spec.js +41 -0
  14. package/dist/esm/components/EntityStatusBadge/EntityStatusBadge.js +12 -2
  15. package/dist/esm/entries/WrappedEntryCard/FetchingWrappedEntryCard.js +4 -0
  16. package/dist/esm/entries/WrappedEntryCard/WrappedEntryCard.js +7 -6
  17. package/dist/types/assets/WrappedAssetCard/WrappedAssetCard.d.ts +4 -0
  18. package/dist/types/assets/WrappedAssetCard/WrappedAssetLink.d.ts +4 -1
  19. package/dist/types/common/customCardTypes.d.ts +4 -0
  20. package/dist/types/components/EntityStatusBadge/EntityStatusBadge.d.ts +8 -2
  21. package/dist/types/entries/WrappedEntryCard/WrappedEntryCard.d.ts +4 -0
  22. package/package.json +2 -2
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "FetchingWrappedAssetCard", {
10
10
  });
11
11
  const _react = _interop_require_wildcard(require("react"));
12
12
  const _f36components = require("@contentful/f36-components");
13
+ const _fieldeditorshared = require("@contentful/field-editor-shared");
13
14
  const _EntityStore = require("../../common/EntityStore");
14
15
  const _components = require("../../components");
15
16
  const _WrappedAssetCard = require("./WrappedAssetCard");
@@ -62,6 +63,7 @@ function FetchingWrappedAssetCard(props) {
62
63
  getEntityScheduledActions,
63
64
  props.assetId
64
65
  ]);
66
+ const localesStatusMap = (0, _fieldeditorshared.useAsyncLocalePublishStatus)(asset, props.sdk.parameters.instance.privateLocales);
65
67
  _react.useEffect(()=>{
66
68
  if (asset) {
67
69
  props.onAction && props.onAction({
@@ -124,6 +126,8 @@ function FetchingWrappedAssetCard(props) {
124
126
  onEdit,
125
127
  onRemove,
126
128
  useLocalizedEntityStatus: props.sdk.parameters.instance.useLocalizedEntityStatus,
129
+ localesStatusMap,
130
+ activeLocales: props.sdk.parameters.instance.activeLocales,
127
131
  isLocalized: !!('localized' in props.sdk.field && props.sdk.field.localized)
128
132
  };
129
133
  if (props.viewType === 'link') {
@@ -114,12 +114,12 @@ const WrappedAssetCard = (props)=>{
114
114
  badge: _react.createElement(_components.EntityStatusBadge, {
115
115
  getEntityScheduledActions: props.getEntityScheduledActions,
116
116
  entityType: "Asset",
117
- entityId: props.asset.sys.id,
118
- status: status
117
+ status: status,
118
+ useLocalizedEntityStatus: props.useLocalizedEntityStatus,
119
+ entity: props.asset,
120
+ localesStatusMap: props.localesStatusMap,
121
+ activeLocales: props.activeLocales
119
122
  }),
120
- icon: !props.isLocalized && props.useLocalizedEntityStatus ? _react.createElement(_f36components.Badge, {
121
- variant: "secondary"
122
- }, "Default") : null,
123
123
  src: entityFile && entityFile.url ? size === 'small' ? `${entityFile.url}?w=150&h=150&fit=thumb` : `${entityFile.url}?h=300` : '',
124
124
  onClick: isClickable ? (e)=>{
125
125
  e.preventDefault();
@@ -80,8 +80,11 @@ const WrappedAssetLink = (props)=>{
80
80
  badge: _react.createElement(_components.EntityStatusBadge, {
81
81
  getEntityScheduledActions: props.getEntityScheduledActions,
82
82
  entityType: "Asset",
83
- entityId: props.asset.sys.id,
84
- status: status
83
+ status: status,
84
+ useLocalizedEntityStatus: props.useLocalizedEntityStatus,
85
+ entity: props.asset,
86
+ localesStatusMap: props.localesStatusMap,
87
+ activeLocales: props.activeLocales
85
88
  }),
86
89
  thumbnailElement: entityFile && (0, _fieldeditorshared.isValidImage)(entityFile) ? _react.createElement(_components.AssetThumbnail, {
87
90
  file: entityFile
@@ -102,6 +102,12 @@ const CreateEntryMenuTrigger = ({ contentTypes, suggestedContentTypeId, contentT
102
102
  const textField = (0, _react.useRef)(null);
103
103
  const menuListRef = (0, _react.useRef)(null);
104
104
  const [dropdownWidth, setDropdownWidth] = (0, _react.useState)();
105
+ const filteredContentTypes = (0, _react.useMemo)(()=>contentTypes.filter((contentType)=>{
106
+ const annotations = (0, _get.default)(contentType, 'metadata.annotations.ContentType', []);
107
+ return !annotations.some((annotation)=>(0, _get.default)(annotation, 'sys.id') === 'Contentful:ExperienceType');
108
+ }), [
109
+ contentTypes
110
+ ]);
105
111
  const hasDropdown = contentTypes.length > 1 || !!customDropdownItems;
106
112
  const closeMenu = ()=>setOpen(false);
107
113
  (0, _react.useEffect)(()=>{
@@ -148,10 +154,10 @@ const CreateEntryMenuTrigger = ({ contentTypes, suggestedContentTypeId, contentT
148
154
  const renderSearchResultsCount = (resultsLength)=>resultsLength ? _react.default.createElement(_f36components.Menu.SectionTitle, {
149
155
  testId: "add-entru-menu-search-results"
150
156
  }, resultsLength, " result", resultsLength > 1 ? 's' : '') : null;
151
- const isSearchable = contentTypes.length > MAX_ITEMS_WITHOUT_SEARCH;
157
+ const isSearchable = filteredContentTypes.length > MAX_ITEMS_WITHOUT_SEARCH;
152
158
  const maxDropdownHeight = suggestedContentTypeId ? 300 : 250;
153
- const suggestedContentType = contentTypes.find((ct)=>ct.sys.id === suggestedContentTypeId);
154
- const filteredContentTypes = contentTypes.filter((ct)=>!searchInput || (0, _get.default)(ct, 'name', 'Untitled').toLowerCase().includes(searchInput.toLowerCase()));
159
+ const suggestedContentType = filteredContentTypes.find((ct)=>ct.sys.id === suggestedContentTypeId);
160
+ const searchFilteredContentTypes = filteredContentTypes.filter((ct)=>!searchInput || (0, _get.default)(ct, 'name', 'Untitled').toLowerCase().includes(searchInput.toLowerCase()));
155
161
  return _react.default.createElement("span", {
156
162
  className: styles.wrapper,
157
163
  ref: wrapper,
@@ -185,10 +191,10 @@ const CreateEntryMenuTrigger = ({ contentTypes, suggestedContentTypeId, contentT
185
191
  onChange: (e)=>setSearchInput(e.target.value)
186
192
  }), _react.default.createElement(_f36icons.SearchIcon, {
187
193
  className: styles.searchIcon
188
- })), _react.default.createElement(_f36components.Menu.Divider, null)), searchInput && renderSearchResultsCount(filteredContentTypes.length), suggestedContentType && !searchInput && _react.default.createElement(_react.default.Fragment, null, _react.default.createElement(_f36components.Menu.SectionTitle, null, "Suggested Content Type"), _react.default.createElement(_f36components.Menu.Item, {
194
+ })), _react.default.createElement(_f36components.Menu.Divider, null)), searchInput && renderSearchResultsCount(searchFilteredContentTypes.length), suggestedContentType && !searchInput && _react.default.createElement(_react.default.Fragment, null, _react.default.createElement(_f36components.Menu.SectionTitle, null, "Suggested Content Type"), _react.default.createElement(_f36components.Menu.Item, {
189
195
  testId: "suggested",
190
196
  onClick: ()=>handleSelect(suggestedContentType)
191
- }, (0, _get.default)(suggestedContentType, 'name')), _react.default.createElement(_f36components.Menu.Divider, null)), !searchInput && _react.default.createElement(_f36components.Menu.SectionTitle, null, contentTypesLabel), filteredContentTypes.length ? filteredContentTypes.map((contentType, i)=>_react.default.createElement(_f36components.Menu.Item, {
197
+ }, (0, _get.default)(suggestedContentType, 'name')), _react.default.createElement(_f36components.Menu.Divider, null)), !searchInput && _react.default.createElement(_f36components.Menu.SectionTitle, null, contentTypesLabel), searchFilteredContentTypes.length ? searchFilteredContentTypes.map((contentType, i)=>_react.default.createElement(_f36components.Menu.Item, {
192
198
  testId: "contentType",
193
199
  key: `${(0, _get.default)(contentType, 'name')}-${i}`,
194
200
  onClick: ()=>handleSelect(contentType)
@@ -76,6 +76,25 @@ const CONTENT_TYPE_3 = {
76
76
  id: 'ID_3'
77
77
  }
78
78
  };
79
+ const EXPERIENCE_TYPE = {
80
+ name: 'experience-type',
81
+ sys: {
82
+ id: 'ID_4'
83
+ },
84
+ metadata: {
85
+ annotations: {
86
+ ContentType: [
87
+ {
88
+ sys: {
89
+ id: 'Contentful:ExperienceType',
90
+ type: 'Link',
91
+ linkType: 'Annotation'
92
+ }
93
+ }
94
+ ]
95
+ }
96
+ }
97
+ };
79
98
  describe('CreateEntryMenuTrigger general', ()=>{
80
99
  const props = {
81
100
  contentTypes: [
@@ -189,4 +208,26 @@ describe('CreateEntryMenuTrigger general', ()=>{
189
208
  expect(suggestedContentType).toBeDefined();
190
209
  expect(suggestedContentType.textContent).toBe(props.contentTypes[0].name);
191
210
  });
211
+ it('filters out content types with Contentful:ExperienceType annotation', ()=>{
212
+ const contentTypesWithExperience = [
213
+ CONTENT_TYPE_1,
214
+ CONTENT_TYPE_2,
215
+ CONTENT_TYPE_3,
216
+ EXPERIENCE_TYPE
217
+ ];
218
+ const { getByTestId, getAllByTestId } = (0, _react1.render)(_react.createElement(_CreateEntryMenuTrigger.CreateEntryMenuTrigger, {
219
+ ...props,
220
+ contentTypes: contentTypesWithExperience
221
+ }, stub));
222
+ (0, _react1.act)(()=>{
223
+ _react1.fireEvent.click(getByTestId('menu-trigger'));
224
+ });
225
+ const contentTypeItems = getAllByTestId('contentType');
226
+ expect(contentTypeItems).toHaveLength(3);
227
+ expect(contentTypeItems[0].textContent).toBe('name-1');
228
+ expect(contentTypeItems[1].textContent).toBe('name-2');
229
+ expect(contentTypeItems[2].textContent).toBe('name-3');
230
+ const experienceTypeItem = contentTypeItems.find((item)=>item.textContent === 'experience-type');
231
+ expect(experienceTypeItem).toBeUndefined();
232
+ });
192
233
  });
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "EntityStatusBadge", {
10
10
  });
11
11
  const _react = _interop_require_default(require("react"));
12
12
  const _f36components = require("@contentful/f36-components");
13
+ const _fieldeditorshared = require("@contentful/field-editor-shared");
13
14
  const _ScheduledIconWithTooltip = require("../ScheduledIconWithTooltip/ScheduledIconWithTooltip");
14
15
  const _ScheduleTooltip = require("../ScheduledIconWithTooltip/ScheduleTooltip");
15
16
  function _interop_require_default(obj) {
@@ -17,12 +18,21 @@ function _interop_require_default(obj) {
17
18
  default: obj
18
19
  };
19
20
  }
20
- function EntityStatusBadge({ entityId, entityType, getEntityScheduledActions, status, ...props }) {
21
+ function EntityStatusBadge({ entityType, getEntityScheduledActions, status, useLocalizedEntityStatus, localesStatusMap, activeLocales, entity, ...props }) {
21
22
  const { isError, isLoading, jobs } = (0, _ScheduledIconWithTooltip.useScheduledActions)({
22
- entityId,
23
+ entityId: entity.sys.id,
23
24
  entityType,
24
25
  getEntityScheduledActions
25
26
  });
27
+ if (useLocalizedEntityStatus && activeLocales && localesStatusMap) {
28
+ return _react.default.createElement(_fieldeditorshared.LocalePublishingPopover, {
29
+ entity: entity,
30
+ jobs: jobs,
31
+ isScheduled: jobs.length !== 0,
32
+ localesStatusMap: localesStatusMap,
33
+ activeLocales: activeLocales
34
+ });
35
+ }
26
36
  if (isError || isLoading || jobs.length === 0) {
27
37
  return _react.default.createElement(_f36components.EntityStatusBadge, {
28
38
  ...props,
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "FetchingWrappedEntryCard", {
10
10
  });
11
11
  const _react = _interop_require_wildcard(require("react"));
12
12
  const _f36components = require("@contentful/f36-components");
13
+ const _fieldeditorshared = require("@contentful/field-editor-shared");
13
14
  const _get = _interop_require_default(require("lodash/get"));
14
15
  const _EntityStore = require("../../common/EntityStore");
15
16
  const _components = require("../../components");
@@ -86,6 +87,7 @@ function FetchingWrappedEntryCard(props) {
86
87
  getEntityScheduledActions,
87
88
  props.entryId
88
89
  ]);
90
+ const localesStatusMap = (0, _fieldeditorshared.useAsyncLocalePublishStatus)(entry, props.sdk.parameters.instance.privateLocales);
89
91
  const size = props.viewType === 'link' ? 'small' : 'default';
90
92
  const { getEntity } = (0, _EntityStore.useEntityLoader)();
91
93
  const getAsset = (assetId)=>getEntity('Asset', assetId);
@@ -161,6 +163,8 @@ function FetchingWrappedEntryCard(props) {
161
163
  onMoveBottom: props.onMoveBottom,
162
164
  isBeingDragged: props.isBeingDragged,
163
165
  useLocalizedEntityStatus: props.sdk.parameters.instance.useLocalizedEntityStatus,
166
+ localesStatusMap,
167
+ activeLocales: props.sdk.parameters.instance.activeLocales,
164
168
  isLocalized: !!('localized' in props.sdk.field && props.sdk.field.localized)
165
169
  };
166
170
  const { hasCardEditActions, hasCardMoveActions, hasCardRemoveActions } = props;
@@ -123,16 +123,17 @@ function WrappedEntryCard(props) {
123
123
  isSelected: props.isSelected,
124
124
  badge: _react.createElement(_components.EntityStatusBadge, {
125
125
  status: status,
126
- entityId: props.entry.sys.id,
127
126
  entityType: "Entry",
128
- getEntityScheduledActions: props.getEntityScheduledActions
127
+ getEntityScheduledActions: props.getEntityScheduledActions,
128
+ useLocalizedEntityStatus: props.useLocalizedEntityStatus,
129
+ entity: props.entry,
130
+ localesStatusMap: props.localesStatusMap,
131
+ activeLocales: props.activeLocales
129
132
  }),
130
133
  icon: props.spaceName ? _react.createElement(_SpaceName.SpaceName, {
131
134
  spaceName: props.spaceName,
132
135
  environmentName: props.entry.sys.environment.sys.id
133
- }) : !props.isLocalized && props.useLocalizedEntityStatus ? _react.createElement(_f36components.Badge, {
134
- variant: "secondary"
135
- }, "Default") : null,
136
+ }) : null,
136
137
  thumbnailElement: file && (0, _fieldeditorshared.isValidImage)(file) ? _react.createElement(_components.AssetThumbnail, {
137
138
  file: file
138
139
  }) : undefined,
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { AssetCard, EntryCard } from '@contentful/f36-components';
3
+ import { useAsyncLocalePublishStatus } from '@contentful/field-editor-shared';
3
4
  import { useEntity, useEntityLoader } from '../../common/EntityStore';
4
5
  import { MissingAssetCard } from '../../components';
5
6
  import { WrappedAssetCard } from './WrappedAssetCard';
@@ -11,6 +12,7 @@ export function FetchingWrappedAssetCard(props) {
11
12
  getEntityScheduledActions,
12
13
  props.assetId
13
14
  ]);
15
+ const localesStatusMap = useAsyncLocalePublishStatus(asset, props.sdk.parameters.instance.privateLocales);
14
16
  React.useEffect(()=>{
15
17
  if (asset) {
16
18
  props.onAction && props.onAction({
@@ -73,6 +75,8 @@ export function FetchingWrappedAssetCard(props) {
73
75
  onEdit,
74
76
  onRemove,
75
77
  useLocalizedEntityStatus: props.sdk.parameters.instance.useLocalizedEntityStatus,
78
+ localesStatusMap,
79
+ activeLocales: props.sdk.parameters.instance.activeLocales,
76
80
  isLocalized: !!('localized' in props.sdk.field && props.sdk.field.localized)
77
81
  };
78
82
  if (props.viewType === 'link') {
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { AssetCard, Badge } from '@contentful/f36-components';
2
+ import { AssetCard } from '@contentful/f36-components';
3
3
  import { entityHelpers } from '@contentful/field-editor-shared';
4
4
  import mimetype from '@contentful/mimetype';
5
5
  import { EntityStatusBadge, MissingAssetCard } from '../../components';
@@ -58,12 +58,12 @@ export const WrappedAssetCard = (props)=>{
58
58
  badge: React.createElement(EntityStatusBadge, {
59
59
  getEntityScheduledActions: props.getEntityScheduledActions,
60
60
  entityType: "Asset",
61
- entityId: props.asset.sys.id,
62
- status: status
61
+ status: status,
62
+ useLocalizedEntityStatus: props.useLocalizedEntityStatus,
63
+ entity: props.asset,
64
+ localesStatusMap: props.localesStatusMap,
65
+ activeLocales: props.activeLocales
63
66
  }),
64
- icon: !props.isLocalized && props.useLocalizedEntityStatus ? React.createElement(Badge, {
65
- variant: "secondary"
66
- }, "Default") : null,
67
67
  src: entityFile && entityFile.url ? size === 'small' ? `${entityFile.url}?w=150&h=150&fit=thumb` : `${entityFile.url}?h=300` : '',
68
68
  onClick: isClickable ? (e)=>{
69
69
  e.preventDefault();
@@ -29,8 +29,11 @@ export const WrappedAssetLink = (props)=>{
29
29
  badge: React.createElement(EntityStatusBadge, {
30
30
  getEntityScheduledActions: props.getEntityScheduledActions,
31
31
  entityType: "Asset",
32
- entityId: props.asset.sys.id,
33
- status: status
32
+ status: status,
33
+ useLocalizedEntityStatus: props.useLocalizedEntityStatus,
34
+ entity: props.asset,
35
+ localesStatusMap: props.localesStatusMap,
36
+ activeLocales: props.activeLocales
34
37
  }),
35
38
  thumbnailElement: entityFile && isValidImage(entityFile) ? React.createElement(AssetThumbnail, {
36
39
  file: entityFile
@@ -1,4 +1,4 @@
1
- import React, { useState, useRef, useEffect } from 'react';
1
+ import React, { useState, useRef, useEffect, useMemo } 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';
@@ -46,6 +46,12 @@ export const CreateEntryMenuTrigger = ({ contentTypes, suggestedContentTypeId, c
46
46
  const textField = useRef(null);
47
47
  const menuListRef = useRef(null);
48
48
  const [dropdownWidth, setDropdownWidth] = useState();
49
+ const filteredContentTypes = useMemo(()=>contentTypes.filter((contentType)=>{
50
+ const annotations = get(contentType, 'metadata.annotations.ContentType', []);
51
+ return !annotations.some((annotation)=>get(annotation, 'sys.id') === 'Contentful:ExperienceType');
52
+ }), [
53
+ contentTypes
54
+ ]);
49
55
  const hasDropdown = contentTypes.length > 1 || !!customDropdownItems;
50
56
  const closeMenu = ()=>setOpen(false);
51
57
  useEffect(()=>{
@@ -92,10 +98,10 @@ export const CreateEntryMenuTrigger = ({ contentTypes, suggestedContentTypeId, c
92
98
  const renderSearchResultsCount = (resultsLength)=>resultsLength ? React.createElement(Menu.SectionTitle, {
93
99
  testId: "add-entru-menu-search-results"
94
100
  }, resultsLength, " result", resultsLength > 1 ? 's' : '') : null;
95
- const isSearchable = contentTypes.length > MAX_ITEMS_WITHOUT_SEARCH;
101
+ const isSearchable = filteredContentTypes.length > MAX_ITEMS_WITHOUT_SEARCH;
96
102
  const maxDropdownHeight = suggestedContentTypeId ? 300 : 250;
97
- const suggestedContentType = contentTypes.find((ct)=>ct.sys.id === suggestedContentTypeId);
98
- const filteredContentTypes = contentTypes.filter((ct)=>!searchInput || get(ct, 'name', 'Untitled').toLowerCase().includes(searchInput.toLowerCase()));
103
+ const suggestedContentType = filteredContentTypes.find((ct)=>ct.sys.id === suggestedContentTypeId);
104
+ const searchFilteredContentTypes = filteredContentTypes.filter((ct)=>!searchInput || get(ct, 'name', 'Untitled').toLowerCase().includes(searchInput.toLowerCase()));
99
105
  return React.createElement("span", {
100
106
  className: styles.wrapper,
101
107
  ref: wrapper,
@@ -129,10 +135,10 @@ export const CreateEntryMenuTrigger = ({ contentTypes, suggestedContentTypeId, c
129
135
  onChange: (e)=>setSearchInput(e.target.value)
130
136
  }), React.createElement(SearchIcon, {
131
137
  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, {
138
+ })), React.createElement(Menu.Divider, null)), searchInput && renderSearchResultsCount(searchFilteredContentTypes.length), suggestedContentType && !searchInput && React.createElement(React.Fragment, null, React.createElement(Menu.SectionTitle, null, "Suggested Content Type"), React.createElement(Menu.Item, {
133
139
  testId: "suggested",
134
140
  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)=>React.createElement(Menu.Item, {
141
+ }, get(suggestedContentType, 'name')), React.createElement(Menu.Divider, null)), !searchInput && React.createElement(Menu.SectionTitle, null, contentTypesLabel), searchFilteredContentTypes.length ? searchFilteredContentTypes.map((contentType, i)=>React.createElement(Menu.Item, {
136
142
  testId: "contentType",
137
143
  key: `${get(contentType, 'name')}-${i}`,
138
144
  onClick: ()=>handleSelect(contentType)
@@ -26,6 +26,25 @@ const CONTENT_TYPE_3 = {
26
26
  id: 'ID_3'
27
27
  }
28
28
  };
29
+ const EXPERIENCE_TYPE = {
30
+ name: 'experience-type',
31
+ sys: {
32
+ id: 'ID_4'
33
+ },
34
+ metadata: {
35
+ annotations: {
36
+ ContentType: [
37
+ {
38
+ sys: {
39
+ id: 'Contentful:ExperienceType',
40
+ type: 'Link',
41
+ linkType: 'Annotation'
42
+ }
43
+ }
44
+ ]
45
+ }
46
+ }
47
+ };
29
48
  describe('CreateEntryMenuTrigger general', ()=>{
30
49
  const props = {
31
50
  contentTypes: [
@@ -139,4 +158,26 @@ describe('CreateEntryMenuTrigger general', ()=>{
139
158
  expect(suggestedContentType).toBeDefined();
140
159
  expect(suggestedContentType.textContent).toBe(props.contentTypes[0].name);
141
160
  });
161
+ it('filters out content types with Contentful:ExperienceType annotation', ()=>{
162
+ const contentTypesWithExperience = [
163
+ CONTENT_TYPE_1,
164
+ CONTENT_TYPE_2,
165
+ CONTENT_TYPE_3,
166
+ EXPERIENCE_TYPE
167
+ ];
168
+ const { getByTestId, getAllByTestId } = render(React.createElement(CreateEntryMenuTrigger, {
169
+ ...props,
170
+ contentTypes: contentTypesWithExperience
171
+ }, stub));
172
+ act(()=>{
173
+ fireEvent.click(getByTestId('menu-trigger'));
174
+ });
175
+ const contentTypeItems = getAllByTestId('contentType');
176
+ expect(contentTypeItems).toHaveLength(3);
177
+ expect(contentTypeItems[0].textContent).toBe('name-1');
178
+ expect(contentTypeItems[1].textContent).toBe('name-2');
179
+ expect(contentTypeItems[2].textContent).toBe('name-3');
180
+ const experienceTypeItem = contentTypeItems.find((item)=>item.textContent === 'experience-type');
181
+ expect(experienceTypeItem).toBeUndefined();
182
+ });
142
183
  });
@@ -1,13 +1,23 @@
1
1
  import React from 'react';
2
2
  import { EntityStatusBadge as StatusBadge } from '@contentful/f36-components';
3
+ import { LocalePublishingPopover } from '@contentful/field-editor-shared';
3
4
  import { useScheduledActions } from '../ScheduledIconWithTooltip/ScheduledIconWithTooltip';
4
5
  import { ScheduleTooltip } from '../ScheduledIconWithTooltip/ScheduleTooltip';
5
- export function EntityStatusBadge({ entityId, entityType, getEntityScheduledActions, status, ...props }) {
6
+ export function EntityStatusBadge({ entityType, getEntityScheduledActions, status, useLocalizedEntityStatus, localesStatusMap, activeLocales, entity, ...props }) {
6
7
  const { isError, isLoading, jobs } = useScheduledActions({
7
- entityId,
8
+ entityId: entity.sys.id,
8
9
  entityType,
9
10
  getEntityScheduledActions
10
11
  });
12
+ if (useLocalizedEntityStatus && activeLocales && localesStatusMap) {
13
+ return React.createElement(LocalePublishingPopover, {
14
+ entity: entity,
15
+ jobs: jobs,
16
+ isScheduled: jobs.length !== 0,
17
+ localesStatusMap: localesStatusMap,
18
+ activeLocales: activeLocales
19
+ });
20
+ }
11
21
  if (isError || isLoading || jobs.length === 0) {
12
22
  return React.createElement(StatusBadge, {
13
23
  ...props,
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { EntryCard } from '@contentful/f36-components';
3
+ import { useAsyncLocalePublishStatus } from '@contentful/field-editor-shared';
3
4
  import get from 'lodash/get';
4
5
  import { useEntity, useEntityLoader } from '../../common/EntityStore';
5
6
  import { MissingEntityCard } from '../../components';
@@ -30,6 +31,7 @@ export function FetchingWrappedEntryCard(props) {
30
31
  getEntityScheduledActions,
31
32
  props.entryId
32
33
  ]);
34
+ const localesStatusMap = useAsyncLocalePublishStatus(entry, props.sdk.parameters.instance.privateLocales);
33
35
  const size = props.viewType === 'link' ? 'small' : 'default';
34
36
  const { getEntity } = useEntityLoader();
35
37
  const getAsset = (assetId)=>getEntity('Asset', assetId);
@@ -105,6 +107,8 @@ export function FetchingWrappedEntryCard(props) {
105
107
  onMoveBottom: props.onMoveBottom,
106
108
  isBeingDragged: props.isBeingDragged,
107
109
  useLocalizedEntityStatus: props.sdk.parameters.instance.useLocalizedEntityStatus,
110
+ localesStatusMap,
111
+ activeLocales: props.sdk.parameters.instance.activeLocales,
108
112
  isLocalized: !!('localized' in props.sdk.field && props.sdk.field.localized)
109
113
  };
110
114
  const { hasCardEditActions, hasCardMoveActions, hasCardRemoveActions } = props;
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { EntryCard, MenuItem, MenuDivider, Badge } from '@contentful/f36-components';
2
+ import { EntryCard, MenuItem, MenuDivider } from '@contentful/f36-components';
3
3
  import { entityHelpers, isValidImage } from '@contentful/field-editor-shared';
4
4
  import { AssetThumbnail, MissingEntityCard, EntityStatusBadge } from '../../components';
5
5
  import { SpaceName } from '../../components/SpaceName/SpaceName';
@@ -72,16 +72,17 @@ export function WrappedEntryCard(props) {
72
72
  isSelected: props.isSelected,
73
73
  badge: React.createElement(EntityStatusBadge, {
74
74
  status: status,
75
- entityId: props.entry.sys.id,
76
75
  entityType: "Entry",
77
- getEntityScheduledActions: props.getEntityScheduledActions
76
+ getEntityScheduledActions: props.getEntityScheduledActions,
77
+ useLocalizedEntityStatus: props.useLocalizedEntityStatus,
78
+ entity: props.entry,
79
+ localesStatusMap: props.localesStatusMap,
80
+ activeLocales: props.activeLocales
78
81
  }),
79
82
  icon: props.spaceName ? React.createElement(SpaceName, {
80
83
  spaceName: props.spaceName,
81
84
  environmentName: props.entry.sys.environment.sys.id
82
- }) : !props.isLocalized && props.useLocalizedEntityStatus ? React.createElement(Badge, {
83
- variant: "secondary"
84
- }, "Default") : null,
85
+ }) : null,
85
86
  thumbnailElement: file && isValidImage(file) ? React.createElement(AssetThumbnail, {
86
87
  file: file
87
88
  }) : undefined,
@@ -1,5 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { SpaceAPI } from '@contentful/app-sdk';
3
+ import { LocalePublishStatusMap } from '@contentful/field-editor-shared';
4
+ import { LocaleProps } from 'contentful-management';
3
5
  import { Asset, RenderDragFn } from '../../types';
4
6
  export interface WrappedAssetCardProps {
5
7
  getEntityScheduledActions: SpaceAPI['getEntityScheduledActions'];
@@ -17,6 +19,8 @@ export interface WrappedAssetCardProps {
17
19
  isClickable: boolean;
18
20
  useLocalizedEntityStatus?: boolean;
19
21
  isLocalized?: boolean;
22
+ localesStatusMap?: LocalePublishStatusMap;
23
+ activeLocales?: LocaleProps[];
20
24
  }
21
25
  export declare const WrappedAssetCard: {
22
26
  (props: WrappedAssetCardProps): React.JSX.Element;
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
- import { SpaceAPI } from '@contentful/field-editor-shared';
2
+ import { LocalePublishStatusMap, SpaceAPI } from '@contentful/field-editor-shared';
3
+ import { LocaleProps } from 'contentful-management';
3
4
  import { Asset, RenderDragFn } from '../../types';
4
5
  export interface WrappedAssetLinkProps {
5
6
  getEntityScheduledActions: SpaceAPI['getEntityScheduledActions'];
@@ -13,5 +14,7 @@ export interface WrappedAssetLinkProps {
13
14
  onRemove: () => void;
14
15
  renderDragHandle?: RenderDragFn;
15
16
  useLocalizedEntityStatus?: boolean;
17
+ localesStatusMap?: LocalePublishStatusMap;
18
+ activeLocales?: LocaleProps[];
16
19
  }
17
20
  export declare const WrappedAssetLink: (props: WrappedAssetLinkProps) => React.JSX.Element;
@@ -1,4 +1,6 @@
1
1
  import * as React from 'react';
2
+ import { LocalePublishStatusMap } from '@contentful/field-editor-shared';
3
+ import { LocaleProps } from 'contentful-management';
2
4
  import { Asset, ContentType, Entry, RenderDragFn } from '../types';
3
5
  import { CustomActionProps } from './ReferenceEditor';
4
6
  export type MissingEntityCardProps = {
@@ -28,4 +30,6 @@ export type CustomEntityCardProps = {
28
30
  isBeingDragged?: boolean;
29
31
  isLocalized?: boolean;
30
32
  useLocalizedEntityStatus?: boolean;
33
+ localesStatusMap?: LocalePublishStatusMap;
34
+ activeLocales?: LocaleProps[];
31
35
  };
@@ -1,8 +1,14 @@
1
1
  import React from 'react';
2
2
  import { type EntityStatus } from '@contentful/f36-components';
3
+ import { LocalePublishStatusMap } from '@contentful/field-editor-shared';
4
+ import { EntryProps, LocaleProps, AssetProps } from 'contentful-management';
3
5
  import { type UseScheduledActionsProps } from '../ScheduledIconWithTooltip/ScheduledIconWithTooltip';
4
- type EntityStatusBadgeProps = UseScheduledActionsProps & {
6
+ type EntityStatusBadgeProps = Omit<UseScheduledActionsProps, 'entityId'> & {
5
7
  status: EntityStatus;
8
+ entity: EntryProps | AssetProps;
9
+ useLocalizedEntityStatus?: boolean;
10
+ localesStatusMap?: LocalePublishStatusMap;
11
+ activeLocales?: LocaleProps[];
6
12
  };
7
- export declare function EntityStatusBadge({ entityId, entityType, getEntityScheduledActions, status, ...props }: EntityStatusBadgeProps): React.JSX.Element;
13
+ export declare function EntityStatusBadge({ entityType, getEntityScheduledActions, status, useLocalizedEntityStatus, localesStatusMap, activeLocales, entity, ...props }: EntityStatusBadgeProps): React.JSX.Element;
8
14
  export {};
@@ -1,5 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { SpaceAPI } from '@contentful/app-sdk';
3
+ import { LocalePublishStatusMap } from '@contentful/field-editor-shared';
4
+ import { LocaleProps } from 'contentful-management';
3
5
  import { ContentType, Entry, RenderDragFn } from '../../types';
4
6
  export interface WrappedEntryCardProps {
5
7
  getEntityScheduledActions: SpaceAPI['getEntityScheduledActions'];
@@ -25,6 +27,8 @@ export interface WrappedEntryCardProps {
25
27
  hasCardRemoveActions?: boolean;
26
28
  isLocalized?: boolean;
27
29
  useLocalizedEntityStatus?: boolean;
30
+ localesStatusMap?: LocalePublishStatusMap;
31
+ activeLocales?: LocaleProps[];
28
32
  }
29
33
  export declare function WrappedEntryCard(props: WrappedEntryCardProps): React.JSX.Element;
30
34
  export declare namespace WrappedEntryCard {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/field-editor-reference",
3
- "version": "5.30.14",
3
+ "version": "5.31.1",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "types": "dist/types/index.d.ts",
@@ -64,5 +64,5 @@
64
64
  "publishConfig": {
65
65
  "registry": "https://npm.pkg.github.com/"
66
66
  },
67
- "gitHead": "afd5e2f336925d0b1eefbf19b716d66abc37f672"
67
+ "gitHead": "05beff8083e711ec10c00a95e49ce0ea6135db08"
68
68
  }