@contentful/field-editor-shared 2.5.1 → 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.
Files changed (26) hide show
  1. package/dist/cjs/ReleaseEntityStatusBadge/index.js +0 -1
  2. package/dist/cjs/hooks/useActiveReleaseLocalesStatuses.js +109 -0
  3. package/dist/cjs/hooks/useActiveReleaseLocalesStatuses.spec.js +329 -0
  4. package/dist/cjs/index.js +3 -0
  5. package/dist/cjs/utils/getPreviousReleaseEntryVersion.js +32 -0
  6. package/dist/cjs/utils/parseReleaseParameters.js +33 -0
  7. package/dist/esm/ReleaseEntityStatusBadge/index.js +0 -1
  8. package/dist/esm/hooks/useActiveReleaseLocalesStatuses.js +99 -0
  9. package/dist/esm/hooks/useActiveReleaseLocalesStatuses.spec.js +325 -0
  10. package/dist/esm/index.js +3 -0
  11. package/dist/esm/utils/getPreviousReleaseEntryVersion.js +22 -0
  12. package/dist/esm/utils/parseReleaseParameters.js +23 -0
  13. package/dist/types/ReleaseEntityStatusBadge/ReleaseEntityStatusBadge.d.ts +1 -1
  14. package/dist/types/ReleaseEntityStatusBadge/ReleaseEntityStatusLocalesList.d.ts +1 -1
  15. package/dist/types/ReleaseEntityStatusBadge/ReleaseEntityStatusPopover.d.ts +1 -1
  16. package/dist/types/ReleaseEntityStatusBadge/index.d.ts +0 -1
  17. package/dist/types/hooks/useActiveReleaseLocalesStatuses.d.ts +13 -0
  18. package/dist/types/hooks/useActiveReleaseLocalesStatuses.spec.d.ts +1 -0
  19. package/dist/types/index.d.ts +3 -0
  20. package/dist/types/types.d.ts +48 -0
  21. package/dist/types/utils/getPreviousReleaseEntryVersion.d.ts +11 -0
  22. package/dist/types/utils/parseReleaseParameters.d.ts +11 -0
  23. package/package.json +2 -2
  24. package/dist/cjs/ReleaseEntityStatusBadge/types.js +0 -4
  25. package/dist/esm/ReleaseEntityStatusBadge/types.js +0 -1
  26. package/dist/types/ReleaseEntityStatusBadge/types.d.ts +0 -11
@@ -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
+ }
@@ -1,3 +1,2 @@
1
1
  export * from './ReleaseEntityStatusPopover';
2
2
  export * from './ReleaseEntityStatusBadge';
3
- export * from './types';
@@ -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,5 +1,5 @@
1
1
  import React from 'react';
2
- import type { ReleaseAction } from './types';
2
+ import type { ReleaseAction } from '../types';
3
3
  type ReleaseEntityActionBadgeProps = {
4
4
  action: ReleaseAction;
5
5
  className?: string;
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { LocaleProps } from 'contentful-management';
3
- import { ReleaseLocalesStatusMap } from './types';
3
+ import { ReleaseLocalesStatusMap } from '../types';
4
4
  type ReleaseEntityStatusLocalesListProps = {
5
5
  statusMap: ReleaseLocalesStatusMap;
6
6
  activeLocales?: Pick<LocaleProps, 'code'>[];
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { LocaleProps } from 'contentful-management';
3
- import type { ReleaseLocalesStatusMap } from './types';
3
+ import type { ReleaseLocalesStatusMap } from '../types';
4
4
  type ReleaseLocalePublishingPopoverProps = {
5
5
  releaseLocalesStatusMap: ReleaseLocalesStatusMap;
6
6
  activeLocales: Pick<LocaleProps, 'code'>[];
@@ -1,3 +1,2 @@
1
1
  export * from './ReleaseEntityStatusPopover';
2
2
  export * from './ReleaseEntityStatusBadge';
3
- export * from './types';
@@ -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
+ };
@@ -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';
@@ -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.5.1",
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": "5228c3bb1871807c1832459f03d17477e8beb75b"
58
+ "gitHead": "07bbbf610db4000897fa8e6f38e3ab6ace7e02cf"
59
59
  }
@@ -1,4 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
@@ -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>;