@contentful/field-editor-reference 5.13.3 → 5.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/common/EntityStore.js +8 -2
- package/dist/cjs/components/SpaceName/SpaceName.js +6 -4
- package/dist/cjs/entries/WrappedEntryCard/WrappedEntryCard.js +2 -1
- package/dist/cjs/resources/Cards/ResourceCard.spec.js +40 -3
- package/dist/esm/common/EntityStore.js +8 -2
- package/dist/esm/components/SpaceName/SpaceName.js +6 -4
- package/dist/esm/entries/WrappedEntryCard/WrappedEntryCard.js +2 -1
- package/dist/esm/resources/Cards/ResourceCard.spec.js +41 -4
- package/dist/types/components/SpaceName/SpaceName.d.ts +3 -2
- package/package.json +2 -2
|
@@ -109,8 +109,14 @@ const isEntityQueryKey = (queryKey)=>{
|
|
|
109
109
|
async function fetchContentfulEntry(params) {
|
|
110
110
|
const { urn , fetch , options } = params;
|
|
111
111
|
const resourceId = urn.split(':', 6)[5];
|
|
112
|
-
const
|
|
113
|
-
const
|
|
112
|
+
const ENTITY_RESOURCE_ID_REGEX = RegExp("^spaces\\/(?<spaceId>[^/]+)(?:\\/environments\\/(?<environmentId>[^/]+))?\\/entries\\/(?<entityId>[^/]+)$");
|
|
113
|
+
const resourceIdMatch = resourceId.match(ENTITY_RESOURCE_ID_REGEX);
|
|
114
|
+
if (!resourceIdMatch || !resourceIdMatch?.groups?.spaceId || !resourceIdMatch?.groups?.entityId) {
|
|
115
|
+
throw new Error('Not a valid crn');
|
|
116
|
+
}
|
|
117
|
+
const spaceId = resourceIdMatch.groups.spaceId;
|
|
118
|
+
const environmentId = resourceIdMatch?.groups?.environmentId || 'master';
|
|
119
|
+
const entryId = resourceIdMatch.groups.entityId;
|
|
114
120
|
const [space, entry] = await Promise.all([
|
|
115
121
|
fetch([
|
|
116
122
|
'space',
|
|
@@ -60,12 +60,12 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
60
60
|
const styles = {
|
|
61
61
|
spaceIcon: (0, _emotion.css)({
|
|
62
62
|
flexShrink: 0,
|
|
63
|
-
fill: _f36tokens.default.
|
|
63
|
+
fill: _f36tokens.default.gray600
|
|
64
64
|
}),
|
|
65
65
|
spaceName: (0, _emotion.css)({
|
|
66
|
-
color: _f36tokens.default.
|
|
66
|
+
color: _f36tokens.default.gray600,
|
|
67
67
|
fontSize: _f36tokens.default.fontSizeS,
|
|
68
|
-
fontWeight: _f36tokens.default.
|
|
68
|
+
fontWeight: _f36tokens.default.fontWeightMedium,
|
|
69
69
|
maxWidth: '80px',
|
|
70
70
|
textOverflow: 'ellipsis',
|
|
71
71
|
overflow: 'hidden',
|
|
@@ -73,10 +73,12 @@ const styles = {
|
|
|
73
73
|
})
|
|
74
74
|
};
|
|
75
75
|
function SpaceName(props) {
|
|
76
|
+
let content = `Space: ${props.spaceName}`;
|
|
77
|
+
if (props.environmentName) content += ` (Env.: ${props.environmentName})`;
|
|
76
78
|
return _react.createElement(_f36components.Tooltip, {
|
|
77
79
|
placement: "top",
|
|
78
80
|
as: "div",
|
|
79
|
-
content:
|
|
81
|
+
content: content
|
|
80
82
|
}, _react.createElement(_f36components.Flex, {
|
|
81
83
|
alignItems: "center",
|
|
82
84
|
gap: "spacingXs",
|
|
@@ -126,7 +126,8 @@ function WrappedEntryCard(props) {
|
|
|
126
126
|
isSelected: props.isSelected,
|
|
127
127
|
status: status,
|
|
128
128
|
icon: props.spaceName ? _react.createElement(_SpaceName.SpaceName, {
|
|
129
|
-
spaceName: props.spaceName
|
|
129
|
+
spaceName: props.spaceName,
|
|
130
|
+
environmentName: props.entry.sys.environment.sys.id
|
|
130
131
|
}) : _react.createElement(_components.ScheduledIconWithTooltip, {
|
|
131
132
|
getEntityScheduledActions: props.getEntityScheduledActions,
|
|
132
133
|
entityType: "Entry",
|
|
@@ -7,6 +7,7 @@ require("@testing-library/jest-dom");
|
|
|
7
7
|
const _fieldeditortestutils = require("@contentful/field-editor-test-utils");
|
|
8
8
|
const _react1 = require("@testing-library/react");
|
|
9
9
|
const _published_content_typejson = _interop_require_default(require("../../__fixtures__/content-type/published_content_type.json"));
|
|
10
|
+
const _published_entry_non_masterjson = _interop_require_default(require("../../__fixtures__/entry/published_entry_non_master.json"));
|
|
10
11
|
const _published_entryjson = _interop_require_default(require("../../__fixtures__/entry/published_entry.json"));
|
|
11
12
|
const _indifferent_spacejson = _interop_require_default(require("../../__fixtures__/space/indifferent_space.json"));
|
|
12
13
|
const _EntityStore = require("../../common/EntityStore");
|
|
@@ -62,6 +63,8 @@ jest.mock('react-intersection-observer', ()=>({
|
|
|
62
63
|
useInView: jest.fn().mockReturnValue({})
|
|
63
64
|
}));
|
|
64
65
|
const resolvableEntryUrn = 'crn:contentful:::content:spaces/space-id/entries/linked-entry-urn';
|
|
66
|
+
const resolvableEntryUrnWithExplicitMaster = 'crn:contentful:::content:spaces/space-id/environments/master/entries/linked-entry-urn';
|
|
67
|
+
const resolvableEntryUrnWithAnotherEnvironment = 'crn:contentful:::content:spaces/space-id/environments/my-test-environment/entries/linked-entry-urn';
|
|
65
68
|
const unknownEntryUrn = 'crn:contentful:::content:spaces/space-id/entries/unknown-entry-urn';
|
|
66
69
|
const sdk = {
|
|
67
70
|
locales: {
|
|
@@ -72,10 +75,13 @@ const sdk = {
|
|
|
72
75
|
get: jest.fn().mockReturnValue(_published_content_typejson.default)
|
|
73
76
|
},
|
|
74
77
|
Entry: {
|
|
75
|
-
get: jest.fn().mockImplementation(({ entryId })=>{
|
|
76
|
-
if (entryId === 'linked-entry-urn') {
|
|
78
|
+
get: jest.fn().mockImplementation(({ spaceId , environmentId , entryId })=>{
|
|
79
|
+
if (spaceId === 'space-id' && environmentId === 'master' && entryId === 'linked-entry-urn') {
|
|
77
80
|
return Promise.resolve(_published_entryjson.default);
|
|
78
81
|
}
|
|
82
|
+
if (spaceId === 'space-id' && environmentId === 'my-test-environment' && entryId === 'linked-entry-urn') {
|
|
83
|
+
return Promise.resolve(_published_entry_non_masterjson.default);
|
|
84
|
+
}
|
|
79
85
|
return Promise.reject(new Error());
|
|
80
86
|
})
|
|
81
87
|
},
|
|
@@ -124,11 +130,36 @@ function renderResourceCard({ linkType ='Contentful:Entry' , entryUrn =resolvabl
|
|
|
124
130
|
})));
|
|
125
131
|
}
|
|
126
132
|
describe('ResourceCard', ()=>{
|
|
127
|
-
it('renders entry card', async ()=>{
|
|
133
|
+
it('renders entry card with implicit master crn', async ()=>{
|
|
128
134
|
const { getByTestId , getByText } = renderResourceCard();
|
|
135
|
+
const tooltipContent = `Space: ${_indifferent_spacejson.default.name} (Env.: ${_published_entryjson.default.sys.environment.sys.id})`;
|
|
129
136
|
await (0, _react1.waitFor)(()=>expect(getByTestId('cf-ui-entry-card')).toBeDefined());
|
|
130
137
|
expect(getByText(_published_entryjson.default.fields.exField['en-US'])).toBeDefined();
|
|
131
138
|
expect(getByText(_indifferent_spacejson.default.name)).toBeDefined();
|
|
139
|
+
_react1.fireEvent.mouseEnter(getByText(_indifferent_spacejson.default.name));
|
|
140
|
+
await (0, _react1.waitFor)(()=>expect(getByText(tooltipContent)).toBeDefined());
|
|
141
|
+
});
|
|
142
|
+
it('renders entry card with explicit master crn', async ()=>{
|
|
143
|
+
const { getByTestId , getByText } = renderResourceCard({
|
|
144
|
+
entryUrn: resolvableEntryUrnWithExplicitMaster
|
|
145
|
+
});
|
|
146
|
+
const tooltipContent = `Space: ${_indifferent_spacejson.default.name} (Env.: ${_published_entryjson.default.sys.environment.sys.id})`;
|
|
147
|
+
await (0, _react1.waitFor)(()=>expect(getByTestId('cf-ui-entry-card')).toBeDefined());
|
|
148
|
+
expect(getByText(_published_entryjson.default.fields.exField['en-US'])).toBeDefined();
|
|
149
|
+
expect(getByText(_indifferent_spacejson.default.name)).toBeDefined();
|
|
150
|
+
_react1.fireEvent.mouseEnter(getByText(_indifferent_spacejson.default.name));
|
|
151
|
+
await (0, _react1.waitFor)(()=>expect(getByText(tooltipContent)).toBeDefined());
|
|
152
|
+
});
|
|
153
|
+
it('renders entry card with a non master environment', async ()=>{
|
|
154
|
+
const { getByTestId , getByText } = renderResourceCard({
|
|
155
|
+
entryUrn: resolvableEntryUrnWithAnotherEnvironment
|
|
156
|
+
});
|
|
157
|
+
await (0, _react1.waitFor)(()=>expect(getByTestId('cf-ui-entry-card')).toBeDefined());
|
|
158
|
+
const tooltipContent = `Space: ${_indifferent_spacejson.default.name} (Env.: ${_published_entry_non_masterjson.default.sys.environment.sys.id})`;
|
|
159
|
+
expect(getByText(_published_entry_non_masterjson.default.fields.exField['en-US'])).toBeDefined();
|
|
160
|
+
expect(getByText(_indifferent_spacejson.default.name)).toBeDefined();
|
|
161
|
+
_react1.fireEvent.mouseEnter(getByText(_indifferent_spacejson.default.name));
|
|
162
|
+
await (0, _react1.waitFor)(()=>expect(getByText(tooltipContent)).toBeDefined());
|
|
132
163
|
});
|
|
133
164
|
it('renders skeleton when no data is provided', ()=>{
|
|
134
165
|
const { getByTestId } = renderResourceCard();
|
|
@@ -146,4 +177,10 @@ describe('ResourceCard', ()=>{
|
|
|
146
177
|
});
|
|
147
178
|
await (0, _react1.waitFor)(()=>expect(getByTestId('cf-ui-missing-entry-card')).toBeDefined());
|
|
148
179
|
});
|
|
180
|
+
it('renders missing entity card when crn is invalid', async ()=>{
|
|
181
|
+
const { getByTestId } = renderResourceCard({
|
|
182
|
+
entryUrn: ''
|
|
183
|
+
});
|
|
184
|
+
await (0, _react1.waitFor)(()=>expect(getByTestId('cf-ui-missing-entry-card')).toBeDefined());
|
|
185
|
+
});
|
|
149
186
|
});
|
|
@@ -35,8 +35,14 @@ const isEntityQueryKey = (queryKey)=>{
|
|
|
35
35
|
async function fetchContentfulEntry(params) {
|
|
36
36
|
const { urn , fetch , options } = params;
|
|
37
37
|
const resourceId = urn.split(':', 6)[5];
|
|
38
|
-
const
|
|
39
|
-
const
|
|
38
|
+
const ENTITY_RESOURCE_ID_REGEX = RegExp("^spaces\\/(?<spaceId>[^/]+)(?:\\/environments\\/(?<environmentId>[^/]+))?\\/entries\\/(?<entityId>[^/]+)$");
|
|
39
|
+
const resourceIdMatch = resourceId.match(ENTITY_RESOURCE_ID_REGEX);
|
|
40
|
+
if (!resourceIdMatch || !resourceIdMatch?.groups?.spaceId || !resourceIdMatch?.groups?.entityId) {
|
|
41
|
+
throw new Error('Not a valid crn');
|
|
42
|
+
}
|
|
43
|
+
const spaceId = resourceIdMatch.groups.spaceId;
|
|
44
|
+
const environmentId = resourceIdMatch?.groups?.environmentId || 'master';
|
|
45
|
+
const entryId = resourceIdMatch.groups.entityId;
|
|
40
46
|
const [space, entry] = await Promise.all([
|
|
41
47
|
fetch([
|
|
42
48
|
'space',
|
|
@@ -6,12 +6,12 @@ import { css } from 'emotion';
|
|
|
6
6
|
const styles = {
|
|
7
7
|
spaceIcon: css({
|
|
8
8
|
flexShrink: 0,
|
|
9
|
-
fill: tokens.
|
|
9
|
+
fill: tokens.gray600
|
|
10
10
|
}),
|
|
11
11
|
spaceName: css({
|
|
12
|
-
color: tokens.
|
|
12
|
+
color: tokens.gray600,
|
|
13
13
|
fontSize: tokens.fontSizeS,
|
|
14
|
-
fontWeight: tokens.
|
|
14
|
+
fontWeight: tokens.fontWeightMedium,
|
|
15
15
|
maxWidth: '80px',
|
|
16
16
|
textOverflow: 'ellipsis',
|
|
17
17
|
overflow: 'hidden',
|
|
@@ -19,10 +19,12 @@ const styles = {
|
|
|
19
19
|
})
|
|
20
20
|
};
|
|
21
21
|
export function SpaceName(props) {
|
|
22
|
+
let content = `Space: ${props.spaceName}`;
|
|
23
|
+
if (props.environmentName) content += ` (Env.: ${props.environmentName})`;
|
|
22
24
|
return React.createElement(Tooltip, {
|
|
23
25
|
placement: "top",
|
|
24
26
|
as: "div",
|
|
25
|
-
content:
|
|
27
|
+
content: content
|
|
26
28
|
}, React.createElement(Flex, {
|
|
27
29
|
alignItems: "center",
|
|
28
30
|
gap: "spacingXs",
|
|
@@ -72,7 +72,8 @@ export function WrappedEntryCard(props) {
|
|
|
72
72
|
isSelected: props.isSelected,
|
|
73
73
|
status: status,
|
|
74
74
|
icon: props.spaceName ? React.createElement(SpaceName, {
|
|
75
|
-
spaceName: props.spaceName
|
|
75
|
+
spaceName: props.spaceName,
|
|
76
|
+
environmentName: props.entry.sys.environment.sys.id
|
|
76
77
|
}) : React.createElement(ScheduledIconWithTooltip, {
|
|
77
78
|
getEntityScheduledActions: props.getEntityScheduledActions,
|
|
78
79
|
entityType: "Entry",
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import '@testing-library/jest-dom';
|
|
3
3
|
import { createFakeCMAAdapter } from '@contentful/field-editor-test-utils';
|
|
4
|
-
import { configure, render, waitFor } from '@testing-library/react';
|
|
4
|
+
import { configure, fireEvent, render, waitFor } from '@testing-library/react';
|
|
5
5
|
import publishedCT from '../../__fixtures__/content-type/published_content_type.json';
|
|
6
|
+
import publishedEntryNonMasterEnvironment from '../../__fixtures__/entry/published_entry_non_master.json';
|
|
6
7
|
import publishedEntry from '../../__fixtures__/entry/published_entry.json';
|
|
7
8
|
import space from '../../__fixtures__/space/indifferent_space.json';
|
|
8
9
|
import { EntityProvider } from '../../common/EntityStore';
|
|
@@ -14,6 +15,8 @@ jest.mock('react-intersection-observer', ()=>({
|
|
|
14
15
|
useInView: jest.fn().mockReturnValue({})
|
|
15
16
|
}));
|
|
16
17
|
const resolvableEntryUrn = 'crn:contentful:::content:spaces/space-id/entries/linked-entry-urn';
|
|
18
|
+
const resolvableEntryUrnWithExplicitMaster = 'crn:contentful:::content:spaces/space-id/environments/master/entries/linked-entry-urn';
|
|
19
|
+
const resolvableEntryUrnWithAnotherEnvironment = 'crn:contentful:::content:spaces/space-id/environments/my-test-environment/entries/linked-entry-urn';
|
|
17
20
|
const unknownEntryUrn = 'crn:contentful:::content:spaces/space-id/entries/unknown-entry-urn';
|
|
18
21
|
const sdk = {
|
|
19
22
|
locales: {
|
|
@@ -24,10 +27,13 @@ const sdk = {
|
|
|
24
27
|
get: jest.fn().mockReturnValue(publishedCT)
|
|
25
28
|
},
|
|
26
29
|
Entry: {
|
|
27
|
-
get: jest.fn().mockImplementation(({ entryId })=>{
|
|
28
|
-
if (entryId === 'linked-entry-urn') {
|
|
30
|
+
get: jest.fn().mockImplementation(({ spaceId , environmentId , entryId })=>{
|
|
31
|
+
if (spaceId === 'space-id' && environmentId === 'master' && entryId === 'linked-entry-urn') {
|
|
29
32
|
return Promise.resolve(publishedEntry);
|
|
30
33
|
}
|
|
34
|
+
if (spaceId === 'space-id' && environmentId === 'my-test-environment' && entryId === 'linked-entry-urn') {
|
|
35
|
+
return Promise.resolve(publishedEntryNonMasterEnvironment);
|
|
36
|
+
}
|
|
31
37
|
return Promise.reject(new Error());
|
|
32
38
|
})
|
|
33
39
|
},
|
|
@@ -76,11 +82,36 @@ function renderResourceCard({ linkType ='Contentful:Entry' , entryUrn =resolvabl
|
|
|
76
82
|
})));
|
|
77
83
|
}
|
|
78
84
|
describe('ResourceCard', ()=>{
|
|
79
|
-
it('renders entry card', async ()=>{
|
|
85
|
+
it('renders entry card with implicit master crn', async ()=>{
|
|
80
86
|
const { getByTestId , getByText } = renderResourceCard();
|
|
87
|
+
const tooltipContent = `Space: ${space.name} (Env.: ${publishedEntry.sys.environment.sys.id})`;
|
|
81
88
|
await waitFor(()=>expect(getByTestId('cf-ui-entry-card')).toBeDefined());
|
|
82
89
|
expect(getByText(publishedEntry.fields.exField['en-US'])).toBeDefined();
|
|
83
90
|
expect(getByText(space.name)).toBeDefined();
|
|
91
|
+
fireEvent.mouseEnter(getByText(space.name));
|
|
92
|
+
await waitFor(()=>expect(getByText(tooltipContent)).toBeDefined());
|
|
93
|
+
});
|
|
94
|
+
it('renders entry card with explicit master crn', async ()=>{
|
|
95
|
+
const { getByTestId , getByText } = renderResourceCard({
|
|
96
|
+
entryUrn: resolvableEntryUrnWithExplicitMaster
|
|
97
|
+
});
|
|
98
|
+
const tooltipContent = `Space: ${space.name} (Env.: ${publishedEntry.sys.environment.sys.id})`;
|
|
99
|
+
await waitFor(()=>expect(getByTestId('cf-ui-entry-card')).toBeDefined());
|
|
100
|
+
expect(getByText(publishedEntry.fields.exField['en-US'])).toBeDefined();
|
|
101
|
+
expect(getByText(space.name)).toBeDefined();
|
|
102
|
+
fireEvent.mouseEnter(getByText(space.name));
|
|
103
|
+
await waitFor(()=>expect(getByText(tooltipContent)).toBeDefined());
|
|
104
|
+
});
|
|
105
|
+
it('renders entry card with a non master environment', async ()=>{
|
|
106
|
+
const { getByTestId , getByText } = renderResourceCard({
|
|
107
|
+
entryUrn: resolvableEntryUrnWithAnotherEnvironment
|
|
108
|
+
});
|
|
109
|
+
await waitFor(()=>expect(getByTestId('cf-ui-entry-card')).toBeDefined());
|
|
110
|
+
const tooltipContent = `Space: ${space.name} (Env.: ${publishedEntryNonMasterEnvironment.sys.environment.sys.id})`;
|
|
111
|
+
expect(getByText(publishedEntryNonMasterEnvironment.fields.exField['en-US'])).toBeDefined();
|
|
112
|
+
expect(getByText(space.name)).toBeDefined();
|
|
113
|
+
fireEvent.mouseEnter(getByText(space.name));
|
|
114
|
+
await waitFor(()=>expect(getByText(tooltipContent)).toBeDefined());
|
|
84
115
|
});
|
|
85
116
|
it('renders skeleton when no data is provided', ()=>{
|
|
86
117
|
const { getByTestId } = renderResourceCard();
|
|
@@ -98,4 +129,10 @@ describe('ResourceCard', ()=>{
|
|
|
98
129
|
});
|
|
99
130
|
await waitFor(()=>expect(getByTestId('cf-ui-missing-entry-card')).toBeDefined());
|
|
100
131
|
});
|
|
132
|
+
it('renders missing entity card when crn is invalid', async ()=>{
|
|
133
|
+
const { getByTestId } = renderResourceCard({
|
|
134
|
+
entryUrn: ''
|
|
135
|
+
});
|
|
136
|
+
await waitFor(()=>expect(getByTestId('cf-ui-missing-entry-card')).toBeDefined());
|
|
137
|
+
});
|
|
101
138
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
interface
|
|
2
|
+
interface SourceProps {
|
|
3
3
|
spaceName: string;
|
|
4
|
+
environmentName?: string;
|
|
4
5
|
}
|
|
5
|
-
export declare function SpaceName(props:
|
|
6
|
+
export declare function SpaceName(props: SourceProps): React.JSX.Element;
|
|
6
7
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/field-editor-reference",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.14.0",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
5
|
"module": "dist/esm/index.js",
|
|
6
6
|
"types": "dist/types/index.d.ts",
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"@contentful/app-sdk": "^4.2.0",
|
|
64
64
|
"react": ">=16.8.0"
|
|
65
65
|
},
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "538cc684c7cea792773969ab12cff42301c4ab9e"
|
|
67
67
|
}
|