@contentful/field-editor-shared 2.5.0 → 2.6.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/ReleaseEntityStatusBadge/ReleaseEntityStatusPopover.js +5 -5
- package/dist/cjs/ReleaseEntityStatusBadge/index.js +0 -1
- package/dist/cjs/hooks/useActiveReleaseLocalesStatuses.js +109 -0
- package/dist/cjs/hooks/useActiveReleaseLocalesStatuses.spec.js +329 -0
- package/dist/cjs/index.js +3 -0
- package/dist/cjs/utils/getPreviousReleaseEntryVersion.js +32 -0
- package/dist/cjs/utils/parseReleaseParameters.js +33 -0
- package/dist/esm/ReleaseEntityStatusBadge/ReleaseEntityStatusPopover.js +5 -5
- package/dist/esm/ReleaseEntityStatusBadge/index.js +0 -1
- package/dist/esm/hooks/useActiveReleaseLocalesStatuses.js +99 -0
- package/dist/esm/hooks/useActiveReleaseLocalesStatuses.spec.js +325 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/utils/getPreviousReleaseEntryVersion.js +22 -0
- package/dist/esm/utils/parseReleaseParameters.js +23 -0
- package/dist/types/ReleaseEntityStatusBadge/ReleaseEntityStatusBadge.d.ts +1 -1
- package/dist/types/ReleaseEntityStatusBadge/ReleaseEntityStatusLocalesList.d.ts +1 -1
- package/dist/types/ReleaseEntityStatusBadge/ReleaseEntityStatusPopover.d.ts +3 -3
- package/dist/types/ReleaseEntityStatusBadge/index.d.ts +0 -1
- package/dist/types/hooks/useActiveReleaseLocalesStatuses.d.ts +13 -0
- package/dist/types/hooks/useActiveReleaseLocalesStatuses.spec.d.ts +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/types.d.ts +48 -0
- package/dist/types/utils/getPreviousReleaseEntryVersion.d.ts +11 -0
- package/dist/types/utils/parseReleaseParameters.d.ts +11 -0
- package/package.json +2 -2
- package/dist/cjs/ReleaseEntityStatusBadge/types.js +0 -4
- package/dist/esm/ReleaseEntityStatusBadge/types.js +0 -1
- package/dist/types/ReleaseEntityStatusBadge/types.d.ts +0 -11
|
@@ -191,7 +191,7 @@ const determineBadgeStatus = (localesStatusMap, activeLocales)=>{
|
|
|
191
191
|
};
|
|
192
192
|
}
|
|
193
193
|
};
|
|
194
|
-
function ReleaseEntityStatusPopover({
|
|
194
|
+
function ReleaseEntityStatusPopover({ releaseLocalesStatusMap, activeLocales, isLoading = false }) {
|
|
195
195
|
const [isOpen, setIsOpen] = (0, _react.useState)(false);
|
|
196
196
|
const timeoutRef = (0, _react.useRef)();
|
|
197
197
|
const onMouseEnter = (0, _react.useCallback)(()=>{
|
|
@@ -206,7 +206,7 @@ function ReleaseEntityStatusPopover({ ReleaseLocalesStatusMap, activeLocales, is
|
|
|
206
206
|
setIsOpen(false);
|
|
207
207
|
}, 300);
|
|
208
208
|
}, []);
|
|
209
|
-
const status = determineBadgeStatus(
|
|
209
|
+
const status = determineBadgeStatus(releaseLocalesStatusMap, activeLocales);
|
|
210
210
|
const ariaLabel = status.secondary ? 'Multiple statuses' : status.primary;
|
|
211
211
|
const wrapperClass = generateDynamicStyles(status);
|
|
212
212
|
const ArrowDownIcon = (0, _f36components.generateIcon)({
|
|
@@ -227,7 +227,7 @@ function ReleaseEntityStatusPopover({ ReleaseLocalesStatusMap, activeLocales, is
|
|
|
227
227
|
}));
|
|
228
228
|
}
|
|
229
229
|
return _react.default.createElement(_f36components.Popover, {
|
|
230
|
-
isOpen:
|
|
230
|
+
isOpen: releaseLocalesStatusMap && isOpen,
|
|
231
231
|
onClose: ()=>setIsOpen(false),
|
|
232
232
|
autoFocus: false,
|
|
233
233
|
placement: "bottom-end"
|
|
@@ -270,8 +270,8 @@ function ReleaseEntityStatusPopover({ ReleaseLocalesStatusMap, activeLocales, is
|
|
|
270
270
|
className: styles.popoverContent,
|
|
271
271
|
onMouseEnter: onMouseEnter,
|
|
272
272
|
onMouseLeave: onMouseLeave
|
|
273
|
-
}, !!
|
|
274
|
-
statusMap:
|
|
273
|
+
}, !!releaseLocalesStatusMap && _react.default.createElement(_react.default.Fragment, null, _react.default.createElement(_ReleaseEntityStatusLocalesList.ReleaseEntityStatusLocalesList, {
|
|
274
|
+
statusMap: releaseLocalesStatusMap,
|
|
275
275
|
activeLocales: activeLocales
|
|
276
276
|
}))));
|
|
277
277
|
}
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
});
|
|
5
5
|
_export_star(require("./ReleaseEntityStatusPopover"), exports);
|
|
6
6
|
_export_star(require("./ReleaseEntityStatusBadge"), exports);
|
|
7
|
-
_export_star(require("./types"), exports);
|
|
8
7
|
function _export_star(from, to) {
|
|
9
8
|
Object.keys(from).forEach(function(k) {
|
|
10
9
|
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "useActiveReleaseLocalesStatuses", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return useActiveReleaseLocalesStatuses;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _react = require("react");
|
|
12
|
+
const _getPreviousReleaseEntryVersion = require("../utils/getPreviousReleaseEntryVersion");
|
|
13
|
+
const useActiveReleaseLocalesStatuses = ({ currentEntryDraft, entryId, releaseVersionMap, locales, activeRelease, releases })=>{
|
|
14
|
+
const previousReleaseEntity = (0, _react.useMemo)(()=>(0, _getPreviousReleaseEntryVersion.getPreviousReleaseEntryVersion)({
|
|
15
|
+
entryId,
|
|
16
|
+
releaseVersionMap,
|
|
17
|
+
activeRelease,
|
|
18
|
+
releases
|
|
19
|
+
}).previousReleaseEntity, [
|
|
20
|
+
entryId,
|
|
21
|
+
releaseVersionMap,
|
|
22
|
+
activeRelease,
|
|
23
|
+
releases
|
|
24
|
+
]);
|
|
25
|
+
const activeReleaseReleaseEntity = (0, _react.useMemo)(()=>activeRelease?.entities.items.find((entity)=>entity.entity.sys.id === entryId), [
|
|
26
|
+
activeRelease?.entities.items,
|
|
27
|
+
entryId
|
|
28
|
+
]);
|
|
29
|
+
const getLocaleStatus = (0, _react.useCallback)((localeCode)=>{
|
|
30
|
+
if (!activeReleaseReleaseEntity) {
|
|
31
|
+
return 'Not in release';
|
|
32
|
+
}
|
|
33
|
+
return activeReleaseReleaseEntity?.action === 'publish' || activeReleaseReleaseEntity?.add?.fields['*'].includes(localeCode) ? 'published' : 'draft';
|
|
34
|
+
}, [
|
|
35
|
+
activeReleaseReleaseEntity
|
|
36
|
+
]);
|
|
37
|
+
const releaseLocalesStatusMap = (0, _react.useMemo)(()=>{
|
|
38
|
+
return locales.reduce((acc, locale)=>{
|
|
39
|
+
acc.set(locale.code, {
|
|
40
|
+
variant: 'secondary',
|
|
41
|
+
status: 'remainsDraft',
|
|
42
|
+
label: 'Remains draft',
|
|
43
|
+
locale
|
|
44
|
+
});
|
|
45
|
+
if (!activeReleaseReleaseEntity) {
|
|
46
|
+
acc.set(locale.code, {
|
|
47
|
+
variant: 'secondary',
|
|
48
|
+
status: 'notInRelease',
|
|
49
|
+
label: 'Not in release',
|
|
50
|
+
locale
|
|
51
|
+
});
|
|
52
|
+
return acc;
|
|
53
|
+
}
|
|
54
|
+
if (getLocaleStatus(locale.code) === 'draft') {
|
|
55
|
+
if (currentEntryDraft?.sys.fieldStatus) {
|
|
56
|
+
const previousStatus = currentEntryDraft.sys.fieldStatus['*'][locale.code];
|
|
57
|
+
if (previousStatus === 'published' || previousStatus === 'changed') {
|
|
58
|
+
acc.set(locale.code, {
|
|
59
|
+
status: 'becomesDraft',
|
|
60
|
+
variant: 'warning',
|
|
61
|
+
label: 'Becomes draft',
|
|
62
|
+
locale
|
|
63
|
+
});
|
|
64
|
+
} else {
|
|
65
|
+
acc.set(locale.code, {
|
|
66
|
+
status: 'remainsDraft',
|
|
67
|
+
variant: 'secondary',
|
|
68
|
+
label: 'Remains draft',
|
|
69
|
+
locale
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
} else if (previousReleaseEntity) {
|
|
73
|
+
if (previousReleaseEntity.action === 'publish' || previousReleaseEntity.add.fields['*'].includes(locale.code)) {
|
|
74
|
+
acc.set(locale.code, {
|
|
75
|
+
status: 'becomesDraft',
|
|
76
|
+
variant: 'warning',
|
|
77
|
+
label: 'Becomes draft',
|
|
78
|
+
locale
|
|
79
|
+
});
|
|
80
|
+
} else {
|
|
81
|
+
acc.set(locale.code, {
|
|
82
|
+
status: 'remainsDraft',
|
|
83
|
+
variant: 'secondary',
|
|
84
|
+
label: 'Remains draft',
|
|
85
|
+
locale
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
} else if (getLocaleStatus(locale.code) === 'published') {
|
|
90
|
+
acc.set(locale.code, {
|
|
91
|
+
variant: 'positive',
|
|
92
|
+
status: 'willPublish',
|
|
93
|
+
label: 'Will publish',
|
|
94
|
+
locale
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
return acc;
|
|
98
|
+
}, new Map());
|
|
99
|
+
}, [
|
|
100
|
+
locales,
|
|
101
|
+
activeReleaseReleaseEntity,
|
|
102
|
+
getLocaleStatus,
|
|
103
|
+
currentEntryDraft?.sys.fieldStatus,
|
|
104
|
+
previousReleaseEntity
|
|
105
|
+
]);
|
|
106
|
+
return {
|
|
107
|
+
releaseLocalesStatusMap
|
|
108
|
+
};
|
|
109
|
+
};
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
const _react = require("@testing-library/react");
|
|
6
|
+
const _getPreviousReleaseEntryVersion = require("../utils/getPreviousReleaseEntryVersion");
|
|
7
|
+
const _useActiveReleaseLocalesStatuses = require("./useActiveReleaseLocalesStatuses");
|
|
8
|
+
const buildEntry = (status)=>({
|
|
9
|
+
sys: {
|
|
10
|
+
fieldStatus: {
|
|
11
|
+
'*': {
|
|
12
|
+
'en-US': status
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
const createEntryBasedReleaseEntity = ({ entryId = 'entry-1', action = 'publish' })=>({
|
|
18
|
+
entity: {
|
|
19
|
+
sys: {
|
|
20
|
+
type: 'Link',
|
|
21
|
+
linkType: 'Entry',
|
|
22
|
+
id: entryId
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
action
|
|
26
|
+
});
|
|
27
|
+
const createEntryBasedRelease = ({ entryId, action } = {})=>({
|
|
28
|
+
title: 'Release 1',
|
|
29
|
+
sys: {
|
|
30
|
+
id: 'release-1',
|
|
31
|
+
type: 'Release',
|
|
32
|
+
schemaVersion: 'Release.v2'
|
|
33
|
+
},
|
|
34
|
+
entities: {
|
|
35
|
+
items: [
|
|
36
|
+
createEntryBasedReleaseEntity({
|
|
37
|
+
entryId,
|
|
38
|
+
action
|
|
39
|
+
})
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
const createLocaleBasedReleaseEntity = ({ entryId = 'entry-1', verb = 'add' })=>({
|
|
44
|
+
entity: {
|
|
45
|
+
sys: {
|
|
46
|
+
type: 'Link',
|
|
47
|
+
linkType: 'Entry',
|
|
48
|
+
id: entryId
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
[verb]: {
|
|
52
|
+
fields: {
|
|
53
|
+
'*': [
|
|
54
|
+
'en-US'
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
const createLocaleBasedRelease = ({ entryId, verb } = {})=>({
|
|
60
|
+
title: 'Release 1',
|
|
61
|
+
sys: {
|
|
62
|
+
id: 'release-1',
|
|
63
|
+
type: 'Release',
|
|
64
|
+
schemaVersion: 'Release.v2'
|
|
65
|
+
},
|
|
66
|
+
entities: {
|
|
67
|
+
items: [
|
|
68
|
+
createLocaleBasedReleaseEntity({
|
|
69
|
+
entryId,
|
|
70
|
+
verb
|
|
71
|
+
})
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
jest.mock('../utils/getPreviousReleaseEntryVersion', ()=>({
|
|
76
|
+
getPreviousReleaseEntryVersion: jest.fn()
|
|
77
|
+
}));
|
|
78
|
+
const baseParams = {
|
|
79
|
+
entryId: 'entry-1',
|
|
80
|
+
locales: [
|
|
81
|
+
{
|
|
82
|
+
code: 'en-US'
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
isActiveReleaseLoading: false,
|
|
86
|
+
releaseVersionMap: new Map(),
|
|
87
|
+
releases: {
|
|
88
|
+
items: []
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
describe('useActiveReleaseLocalesStatuses', ()=>{
|
|
92
|
+
beforeEach(()=>{
|
|
93
|
+
jest.clearAllMocks();
|
|
94
|
+
});
|
|
95
|
+
describe('with entry based publishing', ()=>{
|
|
96
|
+
it('returns Will publish status when active release has publish action', ()=>{
|
|
97
|
+
_getPreviousReleaseEntryVersion.getPreviousReleaseEntryVersion.mockReturnValue({
|
|
98
|
+
previousReleaseEntity: createEntryBasedReleaseEntity({
|
|
99
|
+
entryId: 'entry-1',
|
|
100
|
+
action: 'unpublish'
|
|
101
|
+
}),
|
|
102
|
+
previousEntryVersion: {
|
|
103
|
+
sys: {
|
|
104
|
+
fieldStatus: {
|
|
105
|
+
'*': {
|
|
106
|
+
'en-US': 'draft'
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
const { result } = (0, _react.renderHook)(()=>(0, _useActiveReleaseLocalesStatuses.useActiveReleaseLocalesStatuses)({
|
|
113
|
+
...baseParams,
|
|
114
|
+
activeRelease: createEntryBasedRelease(),
|
|
115
|
+
currentEntryDraft: buildEntry('draft')
|
|
116
|
+
}));
|
|
117
|
+
expect(result.current.releaseLocalesStatusMap.get('en-US')).toEqual({
|
|
118
|
+
variant: 'positive',
|
|
119
|
+
status: 'willPublish',
|
|
120
|
+
label: 'Will publish',
|
|
121
|
+
locale: {
|
|
122
|
+
code: 'en-US'
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
it('returns Becomes draft status when previous version has published locales and active version has unpublish action', ()=>{
|
|
127
|
+
_getPreviousReleaseEntryVersion.getPreviousReleaseEntryVersion.mockReturnValue({
|
|
128
|
+
previousReleaseEntity: createEntryBasedReleaseEntity({
|
|
129
|
+
entryId: 'entry-1',
|
|
130
|
+
action: 'publish'
|
|
131
|
+
}),
|
|
132
|
+
previousEntryVersion: {
|
|
133
|
+
sys: {
|
|
134
|
+
fieldStatus: {
|
|
135
|
+
'*': {
|
|
136
|
+
'en-US': 'published'
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
const { result } = (0, _react.renderHook)(()=>(0, _useActiveReleaseLocalesStatuses.useActiveReleaseLocalesStatuses)({
|
|
143
|
+
...baseParams,
|
|
144
|
+
activeRelease: createEntryBasedRelease({
|
|
145
|
+
action: 'unpublish'
|
|
146
|
+
}),
|
|
147
|
+
currentEntryDraft: buildEntry('published')
|
|
148
|
+
}));
|
|
149
|
+
expect(result.current.releaseLocalesStatusMap.get('en-US')).toEqual({
|
|
150
|
+
variant: 'warning',
|
|
151
|
+
status: 'becomesDraft',
|
|
152
|
+
label: 'Becomes draft',
|
|
153
|
+
locale: {
|
|
154
|
+
code: 'en-US'
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
it('returns Remains draft status when previous version has draft locales and active version has unpublish action', ()=>{
|
|
159
|
+
_getPreviousReleaseEntryVersion.getPreviousReleaseEntryVersion.mockReturnValue({
|
|
160
|
+
previousReleaseEntity: createEntryBasedReleaseEntity({
|
|
161
|
+
action: 'unpublish'
|
|
162
|
+
}),
|
|
163
|
+
previousEntryVersion: {
|
|
164
|
+
sys: {
|
|
165
|
+
fieldStatus: {
|
|
166
|
+
'*': {
|
|
167
|
+
'en-US': 'draft'
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
const { result } = (0, _react.renderHook)(()=>(0, _useActiveReleaseLocalesStatuses.useActiveReleaseLocalesStatuses)({
|
|
174
|
+
...baseParams,
|
|
175
|
+
activeRelease: createEntryBasedRelease({
|
|
176
|
+
action: 'unpublish'
|
|
177
|
+
}),
|
|
178
|
+
currentEntryDraft: buildEntry('draft')
|
|
179
|
+
}));
|
|
180
|
+
expect(result.current.releaseLocalesStatusMap.get('en-US')).toEqual({
|
|
181
|
+
variant: 'secondary',
|
|
182
|
+
status: 'remainsDraft',
|
|
183
|
+
label: 'Remains draft',
|
|
184
|
+
locale: {
|
|
185
|
+
code: 'en-US'
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
it('returns Not in release status when entry is not in the release', ()=>{
|
|
190
|
+
_getPreviousReleaseEntryVersion.getPreviousReleaseEntryVersion.mockReturnValue({
|
|
191
|
+
previousReleaseEntity: undefined,
|
|
192
|
+
previousEntryVersion: undefined
|
|
193
|
+
});
|
|
194
|
+
const { result } = (0, _react.renderHook)(()=>(0, _useActiveReleaseLocalesStatuses.useActiveReleaseLocalesStatuses)({
|
|
195
|
+
...baseParams,
|
|
196
|
+
activeRelease: createEntryBasedRelease({
|
|
197
|
+
entryId: 'entry-2',
|
|
198
|
+
action: 'publish'
|
|
199
|
+
}),
|
|
200
|
+
currentEntryDraft: buildEntry('draft')
|
|
201
|
+
}));
|
|
202
|
+
expect(result.current.releaseLocalesStatusMap.get('en-US')).toEqual({
|
|
203
|
+
variant: 'secondary',
|
|
204
|
+
status: 'notInRelease',
|
|
205
|
+
label: 'Not in release',
|
|
206
|
+
locale: {
|
|
207
|
+
code: 'en-US'
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
describe('with locale based publishing', ()=>{
|
|
213
|
+
it('returns Will publish status when active release has publish action', ()=>{
|
|
214
|
+
_getPreviousReleaseEntryVersion.getPreviousReleaseEntryVersion.mockReturnValue({
|
|
215
|
+
previousReleaseEntity: createLocaleBasedReleaseEntity({
|
|
216
|
+
entryId: 'entry-1',
|
|
217
|
+
verb: 'remove'
|
|
218
|
+
}),
|
|
219
|
+
previousEntryVersion: {
|
|
220
|
+
sys: {
|
|
221
|
+
fieldStatus: {
|
|
222
|
+
'*': {
|
|
223
|
+
'en-US': 'draft'
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
const { result } = (0, _react.renderHook)(()=>(0, _useActiveReleaseLocalesStatuses.useActiveReleaseLocalesStatuses)({
|
|
230
|
+
...baseParams,
|
|
231
|
+
activeRelease: createLocaleBasedRelease(),
|
|
232
|
+
currentEntryDraft: buildEntry('draft')
|
|
233
|
+
}));
|
|
234
|
+
expect(result.current.releaseLocalesStatusMap.get('en-US')).toEqual({
|
|
235
|
+
variant: 'positive',
|
|
236
|
+
status: 'willPublish',
|
|
237
|
+
label: 'Will publish',
|
|
238
|
+
locale: {
|
|
239
|
+
code: 'en-US'
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
it('returns Becomes draft status when previous version has published locales and active version has unpublish action', ()=>{
|
|
244
|
+
_getPreviousReleaseEntryVersion.getPreviousReleaseEntryVersion.mockReturnValue({
|
|
245
|
+
previousReleaseEntity: createLocaleBasedReleaseEntity({
|
|
246
|
+
entryId: 'entry-1',
|
|
247
|
+
verb: 'add'
|
|
248
|
+
}),
|
|
249
|
+
previousEntryVersion: {
|
|
250
|
+
sys: {
|
|
251
|
+
fieldStatus: {
|
|
252
|
+
'*': {
|
|
253
|
+
'en-US': 'published'
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
const { result } = (0, _react.renderHook)(()=>(0, _useActiveReleaseLocalesStatuses.useActiveReleaseLocalesStatuses)({
|
|
260
|
+
...baseParams,
|
|
261
|
+
activeRelease: createLocaleBasedRelease({
|
|
262
|
+
verb: 'remove'
|
|
263
|
+
}),
|
|
264
|
+
currentEntryDraft: buildEntry('published')
|
|
265
|
+
}));
|
|
266
|
+
expect(result.current.releaseLocalesStatusMap.get('en-US')).toEqual({
|
|
267
|
+
variant: 'warning',
|
|
268
|
+
status: 'becomesDraft',
|
|
269
|
+
label: 'Becomes draft',
|
|
270
|
+
locale: {
|
|
271
|
+
code: 'en-US'
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
it('returns Remains draft status when previous version has draft locales and active version has unpublish action', ()=>{
|
|
276
|
+
_getPreviousReleaseEntryVersion.getPreviousReleaseEntryVersion.mockReturnValue({
|
|
277
|
+
previousReleaseEntity: createLocaleBasedReleaseEntity({
|
|
278
|
+
verb: 'remove'
|
|
279
|
+
}),
|
|
280
|
+
previousEntryVersion: {
|
|
281
|
+
sys: {
|
|
282
|
+
fieldStatus: {
|
|
283
|
+
'*': {
|
|
284
|
+
'en-US': 'draft'
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
const { result } = (0, _react.renderHook)(()=>(0, _useActiveReleaseLocalesStatuses.useActiveReleaseLocalesStatuses)({
|
|
291
|
+
...baseParams,
|
|
292
|
+
activeRelease: createLocaleBasedRelease({
|
|
293
|
+
verb: 'remove'
|
|
294
|
+
}),
|
|
295
|
+
currentEntryDraft: buildEntry('draft')
|
|
296
|
+
}));
|
|
297
|
+
expect(result.current.releaseLocalesStatusMap.get('en-US')).toEqual({
|
|
298
|
+
variant: 'secondary',
|
|
299
|
+
status: 'remainsDraft',
|
|
300
|
+
label: 'Remains draft',
|
|
301
|
+
locale: {
|
|
302
|
+
code: 'en-US'
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
it('returns Not in release status when entry is not in the release', ()=>{
|
|
307
|
+
_getPreviousReleaseEntryVersion.getPreviousReleaseEntryVersion.mockReturnValue({
|
|
308
|
+
previousReleaseEntity: undefined,
|
|
309
|
+
previousEntryVersion: undefined
|
|
310
|
+
});
|
|
311
|
+
const { result } = (0, _react.renderHook)(()=>(0, _useActiveReleaseLocalesStatuses.useActiveReleaseLocalesStatuses)({
|
|
312
|
+
...baseParams,
|
|
313
|
+
activeRelease: createLocaleBasedRelease({
|
|
314
|
+
entryId: 'entry-2',
|
|
315
|
+
verb: 'add'
|
|
316
|
+
}),
|
|
317
|
+
currentEntryDraft: buildEntry('draft')
|
|
318
|
+
}));
|
|
319
|
+
expect(result.current.releaseLocalesStatusMap.get('en-US')).toEqual({
|
|
320
|
+
variant: 'secondary',
|
|
321
|
+
status: 'notInRelease',
|
|
322
|
+
label: 'Not in release',
|
|
323
|
+
locale: {
|
|
324
|
+
code: 'en-US'
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
});
|
package/dist/cjs/index.js
CHANGED
|
@@ -111,8 +111,11 @@ const _PredefinedValuesError = require("./PredefinedValuesError");
|
|
|
111
111
|
const _typesEntity = require("./typesEntity");
|
|
112
112
|
const _isValidImage = require("./utils/isValidImage");
|
|
113
113
|
const _shortenStorageUnit = require("./utils/shortenStorageUnit");
|
|
114
|
+
_export_star(require("./utils/parseReleaseParameters"), exports);
|
|
114
115
|
_export_star(require("./hooks/useLocalePublishStatus"), exports);
|
|
115
116
|
_export_star(require("./hooks/useActiveLocales"), exports);
|
|
117
|
+
_export_star(require("./types"), exports);
|
|
118
|
+
_export_star(require("./hooks/useActiveReleaseLocalesStatuses"), exports);
|
|
116
119
|
_export_star(require("./LocalePublishingEntityStatusBadge"), exports);
|
|
117
120
|
_export_star(require("./ReleaseEntityStatusBadge"), exports);
|
|
118
121
|
const _ModalDialogLauncher = /*#__PURE__*/ _interop_require_wildcard(require("./ModalDialogLauncher"));
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "getPreviousReleaseEntryVersion", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return getPreviousReleaseEntryVersion;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _datefns = require("date-fns");
|
|
12
|
+
function getPreviousReleaseEntryVersion({ entryId, releaseVersionMap, activeRelease, releases }) {
|
|
13
|
+
const orderedScheduledReleases = releases?.items.filter((r)=>r.startDate).sort((a, b)=>(0, _datefns.compareAsc)(new Date(a.startDate), new Date(b.startDate)));
|
|
14
|
+
const indexOfActive = orderedScheduledReleases?.findIndex((r)=>r.sys.id === activeRelease?.sys.id);
|
|
15
|
+
let previousRelease;
|
|
16
|
+
let previousReleaseEntity;
|
|
17
|
+
if (indexOfActive && indexOfActive > 0) {
|
|
18
|
+
for(let i = indexOfActive - 1; i >= 0; i--){
|
|
19
|
+
const release = orderedScheduledReleases[i];
|
|
20
|
+
const action = releaseVersionMap.get(entryId)?.get(release.sys.id);
|
|
21
|
+
if (action !== 'not-in-release') {
|
|
22
|
+
previousRelease = release;
|
|
23
|
+
previousReleaseEntity = release.entities.items.find((e)=>e.entity.sys.id === entryId);
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
previousRelease,
|
|
30
|
+
previousReleaseEntity
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "parseReleaseParams", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return parseReleaseParams;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
function parseReleaseParams(raw) {
|
|
12
|
+
let parsedRaw;
|
|
13
|
+
try {
|
|
14
|
+
parsedRaw = JSON.parse(raw);
|
|
15
|
+
} catch (e) {
|
|
16
|
+
throw new Error('Failed to parse release parameters: invalid JSON');
|
|
17
|
+
}
|
|
18
|
+
const releaseVersionMap = new Map();
|
|
19
|
+
for (const [entryId, innerObj] of Object.entries(parsedRaw.releaseVersionMap)){
|
|
20
|
+
const innerMap = new Map();
|
|
21
|
+
for (const [localeKey, actionData] of Object.entries(innerObj)){
|
|
22
|
+
innerMap.set(localeKey, actionData);
|
|
23
|
+
}
|
|
24
|
+
releaseVersionMap.set(entryId, innerMap);
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
releaseVersionMap,
|
|
28
|
+
locales: parsedRaw.locales,
|
|
29
|
+
activeRelease: parsedRaw.activeRelease,
|
|
30
|
+
isActiveReleaseLoading: parsedRaw.isActiveReleaseLoading,
|
|
31
|
+
releases: parsedRaw.releases
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -135,7 +135,7 @@ const determineBadgeStatus = (localesStatusMap, activeLocales)=>{
|
|
|
135
135
|
};
|
|
136
136
|
}
|
|
137
137
|
};
|
|
138
|
-
export function ReleaseEntityStatusPopover({
|
|
138
|
+
export function ReleaseEntityStatusPopover({ releaseLocalesStatusMap, activeLocales, isLoading = false }) {
|
|
139
139
|
const [isOpen, setIsOpen] = useState(false);
|
|
140
140
|
const timeoutRef = useRef();
|
|
141
141
|
const onMouseEnter = useCallback(()=>{
|
|
@@ -150,7 +150,7 @@ export function ReleaseEntityStatusPopover({ ReleaseLocalesStatusMap, activeLoca
|
|
|
150
150
|
setIsOpen(false);
|
|
151
151
|
}, 300);
|
|
152
152
|
}, []);
|
|
153
|
-
const status = determineBadgeStatus(
|
|
153
|
+
const status = determineBadgeStatus(releaseLocalesStatusMap, activeLocales);
|
|
154
154
|
const ariaLabel = status.secondary ? 'Multiple statuses' : status.primary;
|
|
155
155
|
const wrapperClass = generateDynamicStyles(status);
|
|
156
156
|
const ArrowDownIcon = generateIcon({
|
|
@@ -171,7 +171,7 @@ export function ReleaseEntityStatusPopover({ ReleaseLocalesStatusMap, activeLoca
|
|
|
171
171
|
}));
|
|
172
172
|
}
|
|
173
173
|
return React.createElement(Popover, {
|
|
174
|
-
isOpen:
|
|
174
|
+
isOpen: releaseLocalesStatusMap && isOpen,
|
|
175
175
|
onClose: ()=>setIsOpen(false),
|
|
176
176
|
autoFocus: false,
|
|
177
177
|
placement: "bottom-end"
|
|
@@ -214,8 +214,8 @@ export function ReleaseEntityStatusPopover({ ReleaseLocalesStatusMap, activeLoca
|
|
|
214
214
|
className: styles.popoverContent,
|
|
215
215
|
onMouseEnter: onMouseEnter,
|
|
216
216
|
onMouseLeave: onMouseLeave
|
|
217
|
-
}, !!
|
|
218
|
-
statusMap:
|
|
217
|
+
}, !!releaseLocalesStatusMap && React.createElement(React.Fragment, null, React.createElement(ReleaseEntityStatusLocalesList, {
|
|
218
|
+
statusMap: releaseLocalesStatusMap,
|
|
219
219
|
activeLocales: activeLocales
|
|
220
220
|
}))));
|
|
221
221
|
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
|
2
|
+
import { getPreviousReleaseEntryVersion } from '../utils/getPreviousReleaseEntryVersion';
|
|
3
|
+
export const useActiveReleaseLocalesStatuses = ({ currentEntryDraft, entryId, releaseVersionMap, locales, activeRelease, releases })=>{
|
|
4
|
+
const previousReleaseEntity = useMemo(()=>getPreviousReleaseEntryVersion({
|
|
5
|
+
entryId,
|
|
6
|
+
releaseVersionMap,
|
|
7
|
+
activeRelease,
|
|
8
|
+
releases
|
|
9
|
+
}).previousReleaseEntity, [
|
|
10
|
+
entryId,
|
|
11
|
+
releaseVersionMap,
|
|
12
|
+
activeRelease,
|
|
13
|
+
releases
|
|
14
|
+
]);
|
|
15
|
+
const activeReleaseReleaseEntity = useMemo(()=>activeRelease?.entities.items.find((entity)=>entity.entity.sys.id === entryId), [
|
|
16
|
+
activeRelease?.entities.items,
|
|
17
|
+
entryId
|
|
18
|
+
]);
|
|
19
|
+
const getLocaleStatus = useCallback((localeCode)=>{
|
|
20
|
+
if (!activeReleaseReleaseEntity) {
|
|
21
|
+
return 'Not in release';
|
|
22
|
+
}
|
|
23
|
+
return activeReleaseReleaseEntity?.action === 'publish' || activeReleaseReleaseEntity?.add?.fields['*'].includes(localeCode) ? 'published' : 'draft';
|
|
24
|
+
}, [
|
|
25
|
+
activeReleaseReleaseEntity
|
|
26
|
+
]);
|
|
27
|
+
const releaseLocalesStatusMap = useMemo(()=>{
|
|
28
|
+
return locales.reduce((acc, locale)=>{
|
|
29
|
+
acc.set(locale.code, {
|
|
30
|
+
variant: 'secondary',
|
|
31
|
+
status: 'remainsDraft',
|
|
32
|
+
label: 'Remains draft',
|
|
33
|
+
locale
|
|
34
|
+
});
|
|
35
|
+
if (!activeReleaseReleaseEntity) {
|
|
36
|
+
acc.set(locale.code, {
|
|
37
|
+
variant: 'secondary',
|
|
38
|
+
status: 'notInRelease',
|
|
39
|
+
label: 'Not in release',
|
|
40
|
+
locale
|
|
41
|
+
});
|
|
42
|
+
return acc;
|
|
43
|
+
}
|
|
44
|
+
if (getLocaleStatus(locale.code) === 'draft') {
|
|
45
|
+
if (currentEntryDraft?.sys.fieldStatus) {
|
|
46
|
+
const previousStatus = currentEntryDraft.sys.fieldStatus['*'][locale.code];
|
|
47
|
+
if (previousStatus === 'published' || previousStatus === 'changed') {
|
|
48
|
+
acc.set(locale.code, {
|
|
49
|
+
status: 'becomesDraft',
|
|
50
|
+
variant: 'warning',
|
|
51
|
+
label: 'Becomes draft',
|
|
52
|
+
locale
|
|
53
|
+
});
|
|
54
|
+
} else {
|
|
55
|
+
acc.set(locale.code, {
|
|
56
|
+
status: 'remainsDraft',
|
|
57
|
+
variant: 'secondary',
|
|
58
|
+
label: 'Remains draft',
|
|
59
|
+
locale
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
} else if (previousReleaseEntity) {
|
|
63
|
+
if (previousReleaseEntity.action === 'publish' || previousReleaseEntity.add.fields['*'].includes(locale.code)) {
|
|
64
|
+
acc.set(locale.code, {
|
|
65
|
+
status: 'becomesDraft',
|
|
66
|
+
variant: 'warning',
|
|
67
|
+
label: 'Becomes draft',
|
|
68
|
+
locale
|
|
69
|
+
});
|
|
70
|
+
} else {
|
|
71
|
+
acc.set(locale.code, {
|
|
72
|
+
status: 'remainsDraft',
|
|
73
|
+
variant: 'secondary',
|
|
74
|
+
label: 'Remains draft',
|
|
75
|
+
locale
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
} else if (getLocaleStatus(locale.code) === 'published') {
|
|
80
|
+
acc.set(locale.code, {
|
|
81
|
+
variant: 'positive',
|
|
82
|
+
status: 'willPublish',
|
|
83
|
+
label: 'Will publish',
|
|
84
|
+
locale
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return acc;
|
|
88
|
+
}, new Map());
|
|
89
|
+
}, [
|
|
90
|
+
locales,
|
|
91
|
+
activeReleaseReleaseEntity,
|
|
92
|
+
getLocaleStatus,
|
|
93
|
+
currentEntryDraft?.sys.fieldStatus,
|
|
94
|
+
previousReleaseEntity
|
|
95
|
+
]);
|
|
96
|
+
return {
|
|
97
|
+
releaseLocalesStatusMap
|
|
98
|
+
};
|
|
99
|
+
};
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { renderHook } from '@testing-library/react';
|
|
2
|
+
import { getPreviousReleaseEntryVersion } from '../utils/getPreviousReleaseEntryVersion';
|
|
3
|
+
import { useActiveReleaseLocalesStatuses } from './useActiveReleaseLocalesStatuses';
|
|
4
|
+
const buildEntry = (status)=>({
|
|
5
|
+
sys: {
|
|
6
|
+
fieldStatus: {
|
|
7
|
+
'*': {
|
|
8
|
+
'en-US': status
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
const createEntryBasedReleaseEntity = ({ entryId = 'entry-1', action = 'publish' })=>({
|
|
14
|
+
entity: {
|
|
15
|
+
sys: {
|
|
16
|
+
type: 'Link',
|
|
17
|
+
linkType: 'Entry',
|
|
18
|
+
id: entryId
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
action
|
|
22
|
+
});
|
|
23
|
+
const createEntryBasedRelease = ({ entryId, action } = {})=>({
|
|
24
|
+
title: 'Release 1',
|
|
25
|
+
sys: {
|
|
26
|
+
id: 'release-1',
|
|
27
|
+
type: 'Release',
|
|
28
|
+
schemaVersion: 'Release.v2'
|
|
29
|
+
},
|
|
30
|
+
entities: {
|
|
31
|
+
items: [
|
|
32
|
+
createEntryBasedReleaseEntity({
|
|
33
|
+
entryId,
|
|
34
|
+
action
|
|
35
|
+
})
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
const createLocaleBasedReleaseEntity = ({ entryId = 'entry-1', verb = 'add' })=>({
|
|
40
|
+
entity: {
|
|
41
|
+
sys: {
|
|
42
|
+
type: 'Link',
|
|
43
|
+
linkType: 'Entry',
|
|
44
|
+
id: entryId
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
[verb]: {
|
|
48
|
+
fields: {
|
|
49
|
+
'*': [
|
|
50
|
+
'en-US'
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
const createLocaleBasedRelease = ({ entryId, verb } = {})=>({
|
|
56
|
+
title: 'Release 1',
|
|
57
|
+
sys: {
|
|
58
|
+
id: 'release-1',
|
|
59
|
+
type: 'Release',
|
|
60
|
+
schemaVersion: 'Release.v2'
|
|
61
|
+
},
|
|
62
|
+
entities: {
|
|
63
|
+
items: [
|
|
64
|
+
createLocaleBasedReleaseEntity({
|
|
65
|
+
entryId,
|
|
66
|
+
verb
|
|
67
|
+
})
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
jest.mock('../utils/getPreviousReleaseEntryVersion', ()=>({
|
|
72
|
+
getPreviousReleaseEntryVersion: jest.fn()
|
|
73
|
+
}));
|
|
74
|
+
const baseParams = {
|
|
75
|
+
entryId: 'entry-1',
|
|
76
|
+
locales: [
|
|
77
|
+
{
|
|
78
|
+
code: 'en-US'
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
isActiveReleaseLoading: false,
|
|
82
|
+
releaseVersionMap: new Map(),
|
|
83
|
+
releases: {
|
|
84
|
+
items: []
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
describe('useActiveReleaseLocalesStatuses', ()=>{
|
|
88
|
+
beforeEach(()=>{
|
|
89
|
+
jest.clearAllMocks();
|
|
90
|
+
});
|
|
91
|
+
describe('with entry based publishing', ()=>{
|
|
92
|
+
it('returns Will publish status when active release has publish action', ()=>{
|
|
93
|
+
getPreviousReleaseEntryVersion.mockReturnValue({
|
|
94
|
+
previousReleaseEntity: createEntryBasedReleaseEntity({
|
|
95
|
+
entryId: 'entry-1',
|
|
96
|
+
action: 'unpublish'
|
|
97
|
+
}),
|
|
98
|
+
previousEntryVersion: {
|
|
99
|
+
sys: {
|
|
100
|
+
fieldStatus: {
|
|
101
|
+
'*': {
|
|
102
|
+
'en-US': 'draft'
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
const { result } = renderHook(()=>useActiveReleaseLocalesStatuses({
|
|
109
|
+
...baseParams,
|
|
110
|
+
activeRelease: createEntryBasedRelease(),
|
|
111
|
+
currentEntryDraft: buildEntry('draft')
|
|
112
|
+
}));
|
|
113
|
+
expect(result.current.releaseLocalesStatusMap.get('en-US')).toEqual({
|
|
114
|
+
variant: 'positive',
|
|
115
|
+
status: 'willPublish',
|
|
116
|
+
label: 'Will publish',
|
|
117
|
+
locale: {
|
|
118
|
+
code: 'en-US'
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
it('returns Becomes draft status when previous version has published locales and active version has unpublish action', ()=>{
|
|
123
|
+
getPreviousReleaseEntryVersion.mockReturnValue({
|
|
124
|
+
previousReleaseEntity: createEntryBasedReleaseEntity({
|
|
125
|
+
entryId: 'entry-1',
|
|
126
|
+
action: 'publish'
|
|
127
|
+
}),
|
|
128
|
+
previousEntryVersion: {
|
|
129
|
+
sys: {
|
|
130
|
+
fieldStatus: {
|
|
131
|
+
'*': {
|
|
132
|
+
'en-US': 'published'
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
const { result } = renderHook(()=>useActiveReleaseLocalesStatuses({
|
|
139
|
+
...baseParams,
|
|
140
|
+
activeRelease: createEntryBasedRelease({
|
|
141
|
+
action: 'unpublish'
|
|
142
|
+
}),
|
|
143
|
+
currentEntryDraft: buildEntry('published')
|
|
144
|
+
}));
|
|
145
|
+
expect(result.current.releaseLocalesStatusMap.get('en-US')).toEqual({
|
|
146
|
+
variant: 'warning',
|
|
147
|
+
status: 'becomesDraft',
|
|
148
|
+
label: 'Becomes draft',
|
|
149
|
+
locale: {
|
|
150
|
+
code: 'en-US'
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
it('returns Remains draft status when previous version has draft locales and active version has unpublish action', ()=>{
|
|
155
|
+
getPreviousReleaseEntryVersion.mockReturnValue({
|
|
156
|
+
previousReleaseEntity: createEntryBasedReleaseEntity({
|
|
157
|
+
action: 'unpublish'
|
|
158
|
+
}),
|
|
159
|
+
previousEntryVersion: {
|
|
160
|
+
sys: {
|
|
161
|
+
fieldStatus: {
|
|
162
|
+
'*': {
|
|
163
|
+
'en-US': 'draft'
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
const { result } = renderHook(()=>useActiveReleaseLocalesStatuses({
|
|
170
|
+
...baseParams,
|
|
171
|
+
activeRelease: createEntryBasedRelease({
|
|
172
|
+
action: 'unpublish'
|
|
173
|
+
}),
|
|
174
|
+
currentEntryDraft: buildEntry('draft')
|
|
175
|
+
}));
|
|
176
|
+
expect(result.current.releaseLocalesStatusMap.get('en-US')).toEqual({
|
|
177
|
+
variant: 'secondary',
|
|
178
|
+
status: 'remainsDraft',
|
|
179
|
+
label: 'Remains draft',
|
|
180
|
+
locale: {
|
|
181
|
+
code: 'en-US'
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
it('returns Not in release status when entry is not in the release', ()=>{
|
|
186
|
+
getPreviousReleaseEntryVersion.mockReturnValue({
|
|
187
|
+
previousReleaseEntity: undefined,
|
|
188
|
+
previousEntryVersion: undefined
|
|
189
|
+
});
|
|
190
|
+
const { result } = renderHook(()=>useActiveReleaseLocalesStatuses({
|
|
191
|
+
...baseParams,
|
|
192
|
+
activeRelease: createEntryBasedRelease({
|
|
193
|
+
entryId: 'entry-2',
|
|
194
|
+
action: 'publish'
|
|
195
|
+
}),
|
|
196
|
+
currentEntryDraft: buildEntry('draft')
|
|
197
|
+
}));
|
|
198
|
+
expect(result.current.releaseLocalesStatusMap.get('en-US')).toEqual({
|
|
199
|
+
variant: 'secondary',
|
|
200
|
+
status: 'notInRelease',
|
|
201
|
+
label: 'Not in release',
|
|
202
|
+
locale: {
|
|
203
|
+
code: 'en-US'
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
describe('with locale based publishing', ()=>{
|
|
209
|
+
it('returns Will publish status when active release has publish action', ()=>{
|
|
210
|
+
getPreviousReleaseEntryVersion.mockReturnValue({
|
|
211
|
+
previousReleaseEntity: createLocaleBasedReleaseEntity({
|
|
212
|
+
entryId: 'entry-1',
|
|
213
|
+
verb: 'remove'
|
|
214
|
+
}),
|
|
215
|
+
previousEntryVersion: {
|
|
216
|
+
sys: {
|
|
217
|
+
fieldStatus: {
|
|
218
|
+
'*': {
|
|
219
|
+
'en-US': 'draft'
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
const { result } = renderHook(()=>useActiveReleaseLocalesStatuses({
|
|
226
|
+
...baseParams,
|
|
227
|
+
activeRelease: createLocaleBasedRelease(),
|
|
228
|
+
currentEntryDraft: buildEntry('draft')
|
|
229
|
+
}));
|
|
230
|
+
expect(result.current.releaseLocalesStatusMap.get('en-US')).toEqual({
|
|
231
|
+
variant: 'positive',
|
|
232
|
+
status: 'willPublish',
|
|
233
|
+
label: 'Will publish',
|
|
234
|
+
locale: {
|
|
235
|
+
code: 'en-US'
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
it('returns Becomes draft status when previous version has published locales and active version has unpublish action', ()=>{
|
|
240
|
+
getPreviousReleaseEntryVersion.mockReturnValue({
|
|
241
|
+
previousReleaseEntity: createLocaleBasedReleaseEntity({
|
|
242
|
+
entryId: 'entry-1',
|
|
243
|
+
verb: 'add'
|
|
244
|
+
}),
|
|
245
|
+
previousEntryVersion: {
|
|
246
|
+
sys: {
|
|
247
|
+
fieldStatus: {
|
|
248
|
+
'*': {
|
|
249
|
+
'en-US': 'published'
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
const { result } = renderHook(()=>useActiveReleaseLocalesStatuses({
|
|
256
|
+
...baseParams,
|
|
257
|
+
activeRelease: createLocaleBasedRelease({
|
|
258
|
+
verb: 'remove'
|
|
259
|
+
}),
|
|
260
|
+
currentEntryDraft: buildEntry('published')
|
|
261
|
+
}));
|
|
262
|
+
expect(result.current.releaseLocalesStatusMap.get('en-US')).toEqual({
|
|
263
|
+
variant: 'warning',
|
|
264
|
+
status: 'becomesDraft',
|
|
265
|
+
label: 'Becomes draft',
|
|
266
|
+
locale: {
|
|
267
|
+
code: 'en-US'
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
it('returns Remains draft status when previous version has draft locales and active version has unpublish action', ()=>{
|
|
272
|
+
getPreviousReleaseEntryVersion.mockReturnValue({
|
|
273
|
+
previousReleaseEntity: createLocaleBasedReleaseEntity({
|
|
274
|
+
verb: 'remove'
|
|
275
|
+
}),
|
|
276
|
+
previousEntryVersion: {
|
|
277
|
+
sys: {
|
|
278
|
+
fieldStatus: {
|
|
279
|
+
'*': {
|
|
280
|
+
'en-US': 'draft'
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
const { result } = renderHook(()=>useActiveReleaseLocalesStatuses({
|
|
287
|
+
...baseParams,
|
|
288
|
+
activeRelease: createLocaleBasedRelease({
|
|
289
|
+
verb: 'remove'
|
|
290
|
+
}),
|
|
291
|
+
currentEntryDraft: buildEntry('draft')
|
|
292
|
+
}));
|
|
293
|
+
expect(result.current.releaseLocalesStatusMap.get('en-US')).toEqual({
|
|
294
|
+
variant: 'secondary',
|
|
295
|
+
status: 'remainsDraft',
|
|
296
|
+
label: 'Remains draft',
|
|
297
|
+
locale: {
|
|
298
|
+
code: 'en-US'
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
it('returns Not in release status when entry is not in the release', ()=>{
|
|
303
|
+
getPreviousReleaseEntryVersion.mockReturnValue({
|
|
304
|
+
previousReleaseEntity: undefined,
|
|
305
|
+
previousEntryVersion: undefined
|
|
306
|
+
});
|
|
307
|
+
const { result } = renderHook(()=>useActiveReleaseLocalesStatuses({
|
|
308
|
+
...baseParams,
|
|
309
|
+
activeRelease: createLocaleBasedRelease({
|
|
310
|
+
entryId: 'entry-2',
|
|
311
|
+
verb: 'add'
|
|
312
|
+
}),
|
|
313
|
+
currentEntryDraft: buildEntry('draft')
|
|
314
|
+
}));
|
|
315
|
+
expect(result.current.releaseLocalesStatusMap.get('en-US')).toEqual({
|
|
316
|
+
variant: 'secondary',
|
|
317
|
+
status: 'notInRelease',
|
|
318
|
+
label: 'Not in release',
|
|
319
|
+
locale: {
|
|
320
|
+
code: 'en-US'
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
});
|
package/dist/esm/index.js
CHANGED
|
@@ -6,11 +6,14 @@ export { PredefinedValuesError } from './PredefinedValuesError';
|
|
|
6
6
|
export { Asset, Entry, File } from './typesEntity';
|
|
7
7
|
export { isValidImage } from './utils/isValidImage';
|
|
8
8
|
export { shortenStorageUnit, toLocaleString } from './utils/shortenStorageUnit';
|
|
9
|
+
export * from './utils/parseReleaseParameters';
|
|
9
10
|
export * from './hooks/useLocalePublishStatus';
|
|
10
11
|
export * from './hooks/useActiveLocales';
|
|
11
12
|
export { ModalDialogLauncher };
|
|
12
13
|
export { entityHelpers };
|
|
13
14
|
export { ConstraintsUtils };
|
|
15
|
+
export * from './types';
|
|
16
|
+
export * from './hooks/useActiveReleaseLocalesStatuses';
|
|
14
17
|
export * from './LocalePublishingEntityStatusBadge';
|
|
15
18
|
export * from './ReleaseEntityStatusBadge';
|
|
16
19
|
import * as ModalDialogLauncher from './ModalDialogLauncher';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { compareAsc } from 'date-fns';
|
|
2
|
+
export function getPreviousReleaseEntryVersion({ entryId, releaseVersionMap, activeRelease, releases }) {
|
|
3
|
+
const orderedScheduledReleases = releases?.items.filter((r)=>r.startDate).sort((a, b)=>compareAsc(new Date(a.startDate), new Date(b.startDate)));
|
|
4
|
+
const indexOfActive = orderedScheduledReleases?.findIndex((r)=>r.sys.id === activeRelease?.sys.id);
|
|
5
|
+
let previousRelease;
|
|
6
|
+
let previousReleaseEntity;
|
|
7
|
+
if (indexOfActive && indexOfActive > 0) {
|
|
8
|
+
for(let i = indexOfActive - 1; i >= 0; i--){
|
|
9
|
+
const release = orderedScheduledReleases[i];
|
|
10
|
+
const action = releaseVersionMap.get(entryId)?.get(release.sys.id);
|
|
11
|
+
if (action !== 'not-in-release') {
|
|
12
|
+
previousRelease = release;
|
|
13
|
+
previousReleaseEntity = release.entities.items.find((e)=>e.entity.sys.id === entryId);
|
|
14
|
+
break;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
previousRelease,
|
|
20
|
+
previousReleaseEntity
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function parseReleaseParams(raw) {
|
|
2
|
+
let parsedRaw;
|
|
3
|
+
try {
|
|
4
|
+
parsedRaw = JSON.parse(raw);
|
|
5
|
+
} catch (e) {
|
|
6
|
+
throw new Error('Failed to parse release parameters: invalid JSON');
|
|
7
|
+
}
|
|
8
|
+
const releaseVersionMap = new Map();
|
|
9
|
+
for (const [entryId, innerObj] of Object.entries(parsedRaw.releaseVersionMap)){
|
|
10
|
+
const innerMap = new Map();
|
|
11
|
+
for (const [localeKey, actionData] of Object.entries(innerObj)){
|
|
12
|
+
innerMap.set(localeKey, actionData);
|
|
13
|
+
}
|
|
14
|
+
releaseVersionMap.set(entryId, innerMap);
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
releaseVersionMap,
|
|
18
|
+
locales: parsedRaw.locales,
|
|
19
|
+
activeRelease: parsedRaw.activeRelease,
|
|
20
|
+
isActiveReleaseLoading: parsedRaw.isActiveReleaseLoading,
|
|
21
|
+
releases: parsedRaw.releases
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { LocaleProps } from 'contentful-management';
|
|
3
|
-
import { ReleaseLocalesStatusMap } from '
|
|
3
|
+
import { ReleaseLocalesStatusMap } from '../types';
|
|
4
4
|
type ReleaseEntityStatusLocalesListProps = {
|
|
5
5
|
statusMap: ReleaseLocalesStatusMap;
|
|
6
6
|
activeLocales?: Pick<LocaleProps, 'code'>[];
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { LocaleProps } from 'contentful-management';
|
|
3
|
-
import type { ReleaseLocalesStatusMap } from '
|
|
3
|
+
import type { ReleaseLocalesStatusMap } from '../types';
|
|
4
4
|
type ReleaseLocalePublishingPopoverProps = {
|
|
5
|
-
|
|
5
|
+
releaseLocalesStatusMap: ReleaseLocalesStatusMap;
|
|
6
6
|
activeLocales: Pick<LocaleProps, 'code'>[];
|
|
7
7
|
isLoading?: boolean;
|
|
8
8
|
};
|
|
9
|
-
export declare function ReleaseEntityStatusPopover({
|
|
9
|
+
export declare function ReleaseEntityStatusPopover({ releaseLocalesStatusMap, activeLocales, isLoading, }: ReleaseLocalePublishingPopoverProps): React.JSX.Element;
|
|
10
10
|
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ReleaseAction, ReleaseLocalesStatusMap } from '@contentful/field-editor-shared';
|
|
2
|
+
import type { CollectionProp, EntryProps, LocaleProps } from 'contentful-management/types';
|
|
3
|
+
import type { ReleaseV2Props } from '../types';
|
|
4
|
+
export declare const useActiveReleaseLocalesStatuses: ({ currentEntryDraft, entryId, releaseVersionMap, locales, activeRelease, releases, }: {
|
|
5
|
+
currentEntryDraft: EntryProps;
|
|
6
|
+
entryId: string;
|
|
7
|
+
releaseVersionMap: Map<string, Map<string, ReleaseAction>>;
|
|
8
|
+
locales: LocaleProps[];
|
|
9
|
+
activeRelease: ReleaseV2Props;
|
|
10
|
+
releases: CollectionProp<ReleaseV2Props>;
|
|
11
|
+
}) => {
|
|
12
|
+
releaseLocalesStatusMap: ReleaseLocalesStatusMap;
|
|
13
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -7,11 +7,14 @@ export { PredefinedValuesError } from './PredefinedValuesError';
|
|
|
7
7
|
export { Asset, Entry, File } from './typesEntity';
|
|
8
8
|
export { isValidImage } from './utils/isValidImage';
|
|
9
9
|
export { shortenStorageUnit, toLocaleString } from './utils/shortenStorageUnit';
|
|
10
|
+
export * from './utils/parseReleaseParameters';
|
|
10
11
|
export * from './hooks/useLocalePublishStatus';
|
|
11
12
|
export * from './hooks/useActiveLocales';
|
|
12
13
|
export { ModalDialogLauncher };
|
|
13
14
|
export { entityHelpers };
|
|
14
15
|
export { ConstraintsUtils };
|
|
16
|
+
export * from './types';
|
|
17
|
+
export * from './hooks/useActiveReleaseLocalesStatuses';
|
|
15
18
|
export * from './LocalePublishingEntityStatusBadge';
|
|
16
19
|
export * from './ReleaseEntityStatusBadge';
|
|
17
20
|
import * as ModalDialogLauncher from './ModalDialogLauncher';
|
package/dist/types/types.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { BadgeVariant } from '@contentful/f36-components';
|
|
2
|
+
import type { CollectionProp, ReleaseProps } from 'contentful-management/types';
|
|
3
|
+
import type { LocaleProps } from 'contentful-management/types';
|
|
1
4
|
export type ValidationType = {
|
|
2
5
|
type: 'max';
|
|
3
6
|
max: number;
|
|
@@ -9,3 +12,48 @@ export type ValidationType = {
|
|
|
9
12
|
min: number;
|
|
10
13
|
max: number;
|
|
11
14
|
};
|
|
15
|
+
export type ReleaseV2Entity = {
|
|
16
|
+
entity: {
|
|
17
|
+
sys: {
|
|
18
|
+
type: 'Link';
|
|
19
|
+
linkType: 'Entry';
|
|
20
|
+
id: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
action: 'publish' | 'unpublish';
|
|
24
|
+
};
|
|
25
|
+
export type ReleaseV2EntityWithLocales = {
|
|
26
|
+
entity: {
|
|
27
|
+
sys: {
|
|
28
|
+
type: 'Link';
|
|
29
|
+
linkType: 'Entry';
|
|
30
|
+
id: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
add: {
|
|
34
|
+
fields: {
|
|
35
|
+
'*': string[];
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
remove: {
|
|
39
|
+
fields: {
|
|
40
|
+
'*': string[];
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
export type ReleaseV2Props = Omit<ReleaseProps, 'entities' | 'sys'> & {
|
|
45
|
+
sys: ReleaseProps['sys'] & {
|
|
46
|
+
schemaVersion: 'Release.v2';
|
|
47
|
+
};
|
|
48
|
+
entities: CollectionProp<ReleaseV2Entity | ReleaseV2EntityWithLocales>;
|
|
49
|
+
startDate?: string;
|
|
50
|
+
};
|
|
51
|
+
export type ReleaseAction = 'publish' | 'unpublish' | 'not-in-release';
|
|
52
|
+
export type ReleaseEntityStatus = 'willPublish' | 'becomesDraft' | 'remainsDraft' | 'notInRelease';
|
|
53
|
+
export type ReleaseLocalesStatus = {
|
|
54
|
+
status: ReleaseEntityStatus;
|
|
55
|
+
variant: BadgeVariant;
|
|
56
|
+
label: string;
|
|
57
|
+
locale: LocaleProps;
|
|
58
|
+
};
|
|
59
|
+
export type ReleaseLocalesStatusMap = Map<string, ReleaseLocalesStatus>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CollectionProp } from 'contentful-management/types';
|
|
2
|
+
import type { ReleaseAction, ReleaseV2Entity, ReleaseV2EntityWithLocales, ReleaseV2Props } from '../types';
|
|
3
|
+
export declare function getPreviousReleaseEntryVersion({ entryId, releaseVersionMap, activeRelease, releases, }: {
|
|
4
|
+
entryId: string;
|
|
5
|
+
releaseVersionMap: Map<string, Map<string, ReleaseAction>>;
|
|
6
|
+
activeRelease: ReleaseV2Props | undefined;
|
|
7
|
+
releases: CollectionProp<ReleaseV2Props> | undefined;
|
|
8
|
+
}): {
|
|
9
|
+
previousReleaseEntity: ReleaseV2Entity | ReleaseV2EntityWithLocales | undefined;
|
|
10
|
+
previousRelease: ReleaseV2Props | undefined;
|
|
11
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ReleaseV2Props } from '@contentful/field-editor-shared';
|
|
2
|
+
import type { CollectionProp, LocaleProps } from 'contentful-management';
|
|
3
|
+
import type { ReleaseAction } from '../types';
|
|
4
|
+
export type ParsedReleaseParams = {
|
|
5
|
+
releaseVersionMap: Map<string, Map<string, ReleaseAction>>;
|
|
6
|
+
locales: LocaleProps[];
|
|
7
|
+
activeRelease: ReleaseV2Props;
|
|
8
|
+
isActiveReleaseLoading: boolean;
|
|
9
|
+
releases: CollectionProp<ReleaseV2Props>;
|
|
10
|
+
};
|
|
11
|
+
export declare function parseReleaseParams(raw: string): ParsedReleaseParams;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/field-editor-shared",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
5
|
"module": "dist/esm/index.js",
|
|
6
6
|
"types": "dist/types/index.d.ts",
|
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
"publishConfig": {
|
|
56
56
|
"registry": "https://npm.pkg.github.com/"
|
|
57
57
|
},
|
|
58
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "07bbbf610db4000897fa8e6f38e3ab6ace7e02cf"
|
|
59
59
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { };
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { BadgeVariant } from '@contentful/f36-components';
|
|
2
|
-
import { LocaleProps } from 'contentful-management/types';
|
|
3
|
-
export type ReleaseAction = 'publish' | 'unpublish' | 'not-in-release';
|
|
4
|
-
export type ReleaseEntityStatus = 'willPublish' | 'becomesDraft' | 'remainsDraft' | 'notInRelease';
|
|
5
|
-
export type ReleaseLocalesStatus = {
|
|
6
|
-
status: ReleaseEntityStatus;
|
|
7
|
-
variant: BadgeVariant;
|
|
8
|
-
label: string;
|
|
9
|
-
locale: LocaleProps;
|
|
10
|
-
};
|
|
11
|
-
export type ReleaseLocalesStatusMap = Map<string, ReleaseLocalesStatus>;
|