@contentful/field-editor-shared 2.4.2 → 2.5.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 (28) hide show
  1. package/dist/cjs/ReleaseEntityStatusBadge/Banner.js +44 -0
  2. package/dist/cjs/ReleaseEntityStatusBadge/ReleaseEntityStatusBadge.js +39 -0
  3. package/dist/cjs/ReleaseEntityStatusBadge/ReleaseEntityStatusLocale.js +49 -0
  4. package/dist/cjs/ReleaseEntityStatusBadge/ReleaseEntityStatusLocalesList.js +85 -0
  5. package/dist/cjs/ReleaseEntityStatusBadge/ReleaseEntityStatusPopover.js +277 -0
  6. package/dist/cjs/ReleaseEntityStatusBadge/constants.js +46 -0
  7. package/dist/cjs/ReleaseEntityStatusBadge/index.js +20 -0
  8. package/dist/cjs/ReleaseEntityStatusBadge/types.js +4 -0
  9. package/dist/cjs/index.js +1 -0
  10. package/dist/esm/ReleaseEntityStatusBadge/Banner.js +29 -0
  11. package/dist/esm/ReleaseEntityStatusBadge/ReleaseEntityStatusBadge.js +24 -0
  12. package/dist/esm/ReleaseEntityStatusBadge/ReleaseEntityStatusLocale.js +34 -0
  13. package/dist/esm/ReleaseEntityStatusBadge/ReleaseEntityStatusLocalesList.js +70 -0
  14. package/dist/esm/ReleaseEntityStatusBadge/ReleaseEntityStatusPopover.js +221 -0
  15. package/dist/esm/ReleaseEntityStatusBadge/constants.js +31 -0
  16. package/dist/esm/ReleaseEntityStatusBadge/index.js +3 -0
  17. package/dist/esm/ReleaseEntityStatusBadge/types.js +1 -0
  18. package/dist/esm/index.js +1 -0
  19. package/dist/types/ReleaseEntityStatusBadge/Banner.d.ts +5 -0
  20. package/dist/types/ReleaseEntityStatusBadge/ReleaseEntityStatusBadge.d.ts +8 -0
  21. package/dist/types/ReleaseEntityStatusBadge/ReleaseEntityStatusLocale.d.ts +10 -0
  22. package/dist/types/ReleaseEntityStatusBadge/ReleaseEntityStatusLocalesList.d.ts +9 -0
  23. package/dist/types/ReleaseEntityStatusBadge/ReleaseEntityStatusPopover.d.ts +10 -0
  24. package/dist/types/ReleaseEntityStatusBadge/constants.d.ts +30 -0
  25. package/dist/types/ReleaseEntityStatusBadge/index.d.ts +3 -0
  26. package/dist/types/ReleaseEntityStatusBadge/types.d.ts +11 -0
  27. package/dist/types/index.d.ts +1 -0
  28. package/package.json +2 -2
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "Banner", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return Banner;
9
+ }
10
+ });
11
+ const _react = /*#__PURE__*/ _interop_require_default(require("react"));
12
+ const _f36components = require("@contentful/f36-components");
13
+ const _f36tokens = /*#__PURE__*/ _interop_require_default(require("@contentful/f36-tokens"));
14
+ const _emotion = require("emotion");
15
+ function _interop_require_default(obj) {
16
+ return obj && obj.__esModule ? obj : {
17
+ default: obj
18
+ };
19
+ }
20
+ const styles = {
21
+ content: (0, _emotion.css)({
22
+ display: 'block'
23
+ }),
24
+ banner: (0, _emotion.css)({
25
+ background: _f36tokens.default.gray100,
26
+ padding: _f36tokens.default.spacingXs,
27
+ margin: `${_f36tokens.default.spacingXs} ${_f36tokens.default.spacingS}`,
28
+ borderRadius: _f36tokens.default.borderRadiusSmall
29
+ })
30
+ };
31
+ function Banner({ content, highlight }) {
32
+ return _react.default.createElement("div", {
33
+ className: styles.banner
34
+ }, _react.default.createElement(_f36components.Text, {
35
+ fontSize: "fontSizeS",
36
+ fontColor: "gray700",
37
+ className: styles.content
38
+ }, content), highlight && _react.default.createElement(_f36components.Text, {
39
+ fontSize: "fontSizeS",
40
+ fontColor: "gray700",
41
+ as: "strong",
42
+ fontWeight: "fontWeightDemiBold"
43
+ }, highlight));
44
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "ReleaseEntityStatusBadge", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return ReleaseEntityStatusBadge;
9
+ }
10
+ });
11
+ const _react = /*#__PURE__*/ _interop_require_default(require("react"));
12
+ const _f36components = require("@contentful/f36-components");
13
+ function _interop_require_default(obj) {
14
+ return obj && obj.__esModule ? obj : {
15
+ default: obj
16
+ };
17
+ }
18
+ const config = {
19
+ publish: {
20
+ label: 'Will publish',
21
+ variant: 'positive'
22
+ },
23
+ unpublish: {
24
+ label: 'Becomes draft',
25
+ variant: 'warning'
26
+ },
27
+ 'not-in-release': {
28
+ label: 'Not in release',
29
+ variant: 'secondary'
30
+ }
31
+ };
32
+ function ReleaseEntityStatusBadge({ className, action }) {
33
+ const badgeConfig = config[action];
34
+ return _react.default.createElement(_f36components.Badge, {
35
+ testId: "release-entity-action-status",
36
+ className: className,
37
+ variant: badgeConfig.variant
38
+ }, badgeConfig.label);
39
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "ReleaseEntityStatusLocale", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return ReleaseEntityStatusLocale;
9
+ }
10
+ });
11
+ const _react = /*#__PURE__*/ _interop_require_default(require("react"));
12
+ const _f36components = require("@contentful/f36-components");
13
+ const _f36tokens = /*#__PURE__*/ _interop_require_default(require("@contentful/f36-tokens"));
14
+ const _emotion = require("emotion");
15
+ function _interop_require_default(obj) {
16
+ return obj && obj.__esModule ? obj : {
17
+ default: obj
18
+ };
19
+ }
20
+ const styles = {
21
+ locale: (0, _emotion.css)({
22
+ textOverflow: 'ellipsis',
23
+ overflow: 'hidden',
24
+ whiteSpace: 'nowrap'
25
+ }),
26
+ status: (0, _emotion.css)({
27
+ flexShrink: 0
28
+ }),
29
+ localePublishStatus: (0, _emotion.css)({
30
+ display: 'flex',
31
+ gap: _f36tokens.default.spacingXs,
32
+ justifyContent: 'space-between',
33
+ padding: `${_f36tokens.default.spacingXs} ${_f36tokens.default.spacingS}`
34
+ })
35
+ };
36
+ function ReleaseEntityStatusLocale({ locale, label, variant }) {
37
+ return _react.default.createElement("div", {
38
+ className: styles.localePublishStatus,
39
+ "data-test-id": "locale-publishing-status"
40
+ }, _react.default.createElement(_f36components.Text, {
41
+ className: styles.locale,
42
+ fontColor: "gray700"
43
+ }, locale.name, ' ', _react.default.createElement(_f36components.Text, {
44
+ fontColor: "gray500"
45
+ }, "(", locale.code, ")", locale.default && ', Default')), _react.default.createElement(_f36components.Badge, {
46
+ className: styles.status,
47
+ variant: variant
48
+ }, label));
49
+ }
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "ReleaseEntityStatusLocalesList", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return ReleaseEntityStatusLocalesList;
9
+ }
10
+ });
11
+ const _react = /*#__PURE__*/ _interop_require_default(require("react"));
12
+ const _f36components = require("@contentful/f36-components");
13
+ const _lodash = require("lodash");
14
+ const _Banner = require("./Banner");
15
+ const _ReleaseEntityStatusLocale = require("./ReleaseEntityStatusLocale");
16
+ function _interop_require_default(obj) {
17
+ return obj && obj.__esModule ? obj : {
18
+ default: obj
19
+ };
20
+ }
21
+ function groupAndSortLocales(entries, activeLocales) {
22
+ const { selected, nonSelected } = entries.reduce((prev, [localeCode, localeStatusType])=>{
23
+ return activeLocales?.some((sl)=>sl.code === localeCode) ? {
24
+ ...prev,
25
+ selected: [
26
+ ...prev.selected,
27
+ localeStatusType
28
+ ]
29
+ } : {
30
+ ...prev,
31
+ nonSelected: [
32
+ ...prev.nonSelected,
33
+ localeStatusType
34
+ ]
35
+ };
36
+ }, {
37
+ selected: [],
38
+ nonSelected: []
39
+ });
40
+ return {
41
+ selected: (0, _lodash.sortBy)(selected, 'locale.name'),
42
+ nonSelected: nonSelected.sort((a, b)=>{
43
+ if (a.status === b.status) {
44
+ return a.locale.name.localeCompare(b.locale.name);
45
+ }
46
+ if (a.status === 'becomesDraft' || a.status === 'willPublish' && b.status === 'remainsDraft') {
47
+ return -1;
48
+ }
49
+ return 1;
50
+ })
51
+ };
52
+ }
53
+ function ReleaseEntityStatusLocalesList({ statusMap, activeLocales }) {
54
+ const entries = [
55
+ ...statusMap.entries()
56
+ ];
57
+ const counters = entries.reduce((prev, [, { status }])=>({
58
+ becomesDraft: prev.becomesDraft + (status === 'becomesDraft' ? 1 : 0),
59
+ willPublish: prev.willPublish + (status === 'willPublish' ? 1 : 0),
60
+ remainsDraft: prev.remainsDraft + (status === 'remainsDraft' ? 1 : 0)
61
+ }), {
62
+ willPublish: 0,
63
+ becomesDraft: 0,
64
+ remainsDraft: 0
65
+ });
66
+ const { selected, nonSelected } = groupAndSortLocales(entries, activeLocales);
67
+ return _react.default.createElement(_react.default.Fragment, null, _react.default.createElement(_Banner.Banner, {
68
+ content: "The statuses of the locales for this content:",
69
+ highlight: `${counters.becomesDraft} becomes draft, ${counters.willPublish} will publish, ${counters.remainsDraft} remains draft`
70
+ }), _react.default.createElement("div", {
71
+ "data-test-id": "locale-publishing-selected"
72
+ }, _react.default.createElement(_f36components.MenuSectionTitle, null, "Locales in the entry editor:"), selected.map(({ locale, label, variant })=>_react.default.createElement(_ReleaseEntityStatusLocale.ReleaseEntityStatusLocale, {
73
+ key: `selected-${locale.code}`,
74
+ label: label,
75
+ variant: variant,
76
+ locale: locale
77
+ }))), nonSelected.length > 0 && _react.default.createElement("div", {
78
+ "data-test-id": "locale-publishing-others"
79
+ }, _react.default.createElement(_f36components.MenuSectionTitle, null, "Other locales:"), nonSelected.map(({ locale, label, variant })=>_react.default.createElement(_ReleaseEntityStatusLocale.ReleaseEntityStatusLocale, {
80
+ key: `others-${locale.code}`,
81
+ label: label,
82
+ variant: variant,
83
+ locale: locale
84
+ }))));
85
+ }
@@ -0,0 +1,277 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "ReleaseEntityStatusPopover", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return ReleaseEntityStatusPopover;
9
+ }
10
+ });
11
+ const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
12
+ const _f36components = require("@contentful/f36-components");
13
+ const _f36tokens = /*#__PURE__*/ _interop_require_default(require("@contentful/f36-tokens"));
14
+ const _emotion = require("emotion");
15
+ const _constants = require("./constants");
16
+ const _ReleaseEntityStatusLocalesList = require("./ReleaseEntityStatusLocalesList");
17
+ function _interop_require_default(obj) {
18
+ return obj && obj.__esModule ? obj : {
19
+ default: obj
20
+ };
21
+ }
22
+ function _getRequireWildcardCache(nodeInterop) {
23
+ if (typeof WeakMap !== "function") return null;
24
+ var cacheBabelInterop = new WeakMap();
25
+ var cacheNodeInterop = new WeakMap();
26
+ return (_getRequireWildcardCache = function(nodeInterop) {
27
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
28
+ })(nodeInterop);
29
+ }
30
+ function _interop_require_wildcard(obj, nodeInterop) {
31
+ if (!nodeInterop && obj && obj.__esModule) {
32
+ return obj;
33
+ }
34
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
35
+ return {
36
+ default: obj
37
+ };
38
+ }
39
+ var cache = _getRequireWildcardCache(nodeInterop);
40
+ if (cache && cache.has(obj)) {
41
+ return cache.get(obj);
42
+ }
43
+ var newObj = {
44
+ __proto__: null
45
+ };
46
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
47
+ for(var key in obj){
48
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
49
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
50
+ if (desc && (desc.get || desc.set)) {
51
+ Object.defineProperty(newObj, key, desc);
52
+ } else {
53
+ newObj[key] = obj[key];
54
+ }
55
+ }
56
+ }
57
+ newObj.default = obj;
58
+ if (cache) {
59
+ cache.set(obj, newObj);
60
+ }
61
+ return newObj;
62
+ }
63
+ const getColor = ({ secondary, tertiary, isHover })=>{
64
+ const status = secondary || tertiary;
65
+ return isHover ? _constants.RELEASE_BADGES[status]?.hover : _constants.RELEASE_BADGES[status]?.default;
66
+ };
67
+ const generateDynamicStyles = (status)=>{
68
+ const wrapperClass = (0, _emotion.css)({
69
+ '& svg[data-status="secondary"]': {
70
+ fill: getColor({
71
+ secondary: status?.secondary,
72
+ isHover: false
73
+ })
74
+ },
75
+ '& svg[data-status="tertiary"]': {
76
+ fill: getColor({
77
+ tertiary: status?.tertiary,
78
+ isHover: false
79
+ })
80
+ },
81
+ '&:hover svg[data-status="secondary"]': {
82
+ fill: getColor({
83
+ secondary: status?.secondary,
84
+ isHover: true
85
+ })
86
+ },
87
+ '&:hover svg[data-status="tertiary"]': {
88
+ fill: getColor({
89
+ tertiary: status?.tertiary,
90
+ isHover: true
91
+ })
92
+ }
93
+ });
94
+ return wrapperClass;
95
+ };
96
+ const styles = {
97
+ badge: (0, _emotion.css)({
98
+ '&:focus': {
99
+ outline: 'none',
100
+ boxShadow: `inset ${_f36tokens.default.glowPrimary}`
101
+ }
102
+ }),
103
+ wrapper: (0, _emotion.css)({
104
+ '& svg': {
105
+ transition: 'fill 0.2s ease-in-out'
106
+ },
107
+ '& svg[data-status="tertiary"]': {
108
+ marginLeft: '-1px'
109
+ }
110
+ }),
111
+ popoverContent: (0, _emotion.css)({
112
+ maxWidth: '336px',
113
+ maxHeight: '368px',
114
+ overflowY: 'auto',
115
+ padding: `${_f36tokens.default.spacing2Xs} 0`
116
+ }),
117
+ skeletonBadge: (0, _emotion.css)({
118
+ flexShrink: 0,
119
+ display: 'block',
120
+ height: '20px',
121
+ width: '65px'
122
+ })
123
+ };
124
+ const determineBadgeStatus = (localesStatusMap, activeLocales)=>{
125
+ if (activeLocales && activeLocales.length === 1) {
126
+ const activeLocale = activeLocales.find((locale)=>localesStatusMap.has(locale.code));
127
+ return {
128
+ primary: localesStatusMap.get(activeLocale.code).status
129
+ };
130
+ }
131
+ let becomesDraftCount = 0, willPublishCount = 0, remainsDraftCount = 0;
132
+ for (const [localeCode, localeStatus] of localesStatusMap.entries()){
133
+ if (!activeLocales || activeLocales.find((selectedLocale)=>selectedLocale.code === localeCode)) {
134
+ switch(localeStatus.status){
135
+ case 'remainsDraft':
136
+ remainsDraftCount += 1;
137
+ break;
138
+ case 'becomesDraft':
139
+ becomesDraftCount += 1;
140
+ break;
141
+ case 'willPublish':
142
+ willPublishCount += 1;
143
+ break;
144
+ }
145
+ }
146
+ }
147
+ const hasRemainsDraft = remainsDraftCount > 0;
148
+ const hasWillPublish = willPublishCount > 0;
149
+ const hasBecomesDraft = becomesDraftCount > 0;
150
+ switch(true){
151
+ case hasRemainsDraft && hasWillPublish && hasBecomesDraft:
152
+ return {
153
+ primary: 'becomesDraft',
154
+ secondary: 'willPublish',
155
+ tertiary: 'remainsDraft'
156
+ };
157
+ case hasRemainsDraft && hasWillPublish:
158
+ return {
159
+ primary: 'willPublish',
160
+ secondary: 'remainsDraft'
161
+ };
162
+ case hasRemainsDraft && hasBecomesDraft:
163
+ return {
164
+ primary: 'becomesDraft',
165
+ secondary: 'remainsDraft'
166
+ };
167
+ case hasWillPublish && hasBecomesDraft:
168
+ return {
169
+ primary: 'becomesDraft',
170
+ secondary: 'willPublish'
171
+ };
172
+ case hasWillPublish:
173
+ return {
174
+ primary: 'willPublish',
175
+ secondary: 'willPublish'
176
+ };
177
+ case hasBecomesDraft:
178
+ return {
179
+ primary: 'becomesDraft',
180
+ secondary: 'becomesDraft'
181
+ };
182
+ case hasRemainsDraft:
183
+ return {
184
+ primary: 'remainsDraft',
185
+ secondary: 'remainsDraft'
186
+ };
187
+ default:
188
+ return {
189
+ primary: 'notInRelease',
190
+ secondary: 'notInRelease'
191
+ };
192
+ }
193
+ };
194
+ function ReleaseEntityStatusPopover({ ReleaseLocalesStatusMap, activeLocales, isLoading = false }) {
195
+ const [isOpen, setIsOpen] = (0, _react.useState)(false);
196
+ const timeoutRef = (0, _react.useRef)();
197
+ const onMouseEnter = (0, _react.useCallback)(()=>{
198
+ clearTimeout(timeoutRef.current);
199
+ timeoutRef.current = setTimeout(()=>{
200
+ setIsOpen(true);
201
+ }, 300);
202
+ }, []);
203
+ const onMouseLeave = (0, _react.useCallback)(()=>{
204
+ clearTimeout(timeoutRef.current);
205
+ timeoutRef.current = setTimeout(()=>{
206
+ setIsOpen(false);
207
+ }, 300);
208
+ }, []);
209
+ const status = determineBadgeStatus(ReleaseLocalesStatusMap, activeLocales);
210
+ const ariaLabel = status.secondary ? 'Multiple statuses' : status.primary;
211
+ const wrapperClass = generateDynamicStyles(status);
212
+ const ArrowDownIcon = (0, _f36components.generateIcon)({
213
+ name: 'ArrowDownIcon',
214
+ viewBox: '0 0 12 20',
215
+ path: _react.default.createElement("path", {
216
+ d: "M3.03076 8C2.20109 8 1.73228 8.95209 2.23814 9.60971L5.20727 13.4696C5.60757 13.99 6.39223 13.99 6.79252 13.4696L9.76166 9.60971C10.2675 8.95209 9.79871 8 8.96904 8L3.03076 8Z",
217
+ fill: "currentColor"
218
+ })
219
+ });
220
+ if (isLoading) {
221
+ return _react.default.createElement(_f36components.Skeleton.Container, {
222
+ className: styles.skeletonBadge
223
+ }, _react.default.createElement(_f36components.Skeleton.Image, {
224
+ testId: `Release-entity-locale-status-badge-skeleton`,
225
+ width: "65px",
226
+ height: "20px"
227
+ }));
228
+ }
229
+ return _react.default.createElement(_f36components.Popover, {
230
+ isOpen: ReleaseLocalesStatusMap && isOpen,
231
+ onClose: ()=>setIsOpen(false),
232
+ autoFocus: false,
233
+ placement: "bottom-end"
234
+ }, _react.default.createElement(_f36components.Popover.Trigger, null, _react.default.createElement(_f36components.Flex, {
235
+ "aria-label": ariaLabel,
236
+ alignItems: "center",
237
+ className: (0, _emotion.cx)(styles.wrapper, wrapperClass)
238
+ }, _react.default.createElement(_f36components.Badge, {
239
+ tabIndex: 0,
240
+ variant: _constants.RELEASE_BADGES[status.primary].variant,
241
+ onFocus: ()=>setIsOpen(true),
242
+ onBlur: ()=>setIsOpen(false),
243
+ endIcon: _react.default.createElement(ArrowDownIcon, {
244
+ color: _constants.RELEASE_BADGES[status.primary].icon
245
+ }),
246
+ onMouseOver: onMouseEnter,
247
+ onMouseEnter: onMouseEnter,
248
+ onMouseLeave: onMouseLeave
249
+ }, _constants.RELEASE_BADGES[status.primary].label), status.secondary && _react.default.createElement("svg", {
250
+ "data-status": "secondary",
251
+ "aria-hidden": "true",
252
+ width: "4",
253
+ height: "18",
254
+ viewBox: "0 0 4 18"
255
+ }, _react.default.createElement("path", {
256
+ fillRule: "evenodd",
257
+ clipRule: "evenodd",
258
+ d: "M1.45942e-06 18H0.00296171C2.2121 18 4.00296 16.2091 4.00296 14V4C4.00296 1.79086 2.2121 0 0.00295914 0H0C0.830421 0.732944 1.35418 1.80531 1.35418 3V15C1.35418 16.1947 0.830422 17.2671 1.45942e-06 18Z"
259
+ })), status.tertiary && _react.default.createElement("svg", {
260
+ "data-status": "tertiary",
261
+ "aria-hidden": "true",
262
+ width: "5",
263
+ height: "16",
264
+ viewBox: "0 0 5 16"
265
+ }, _react.default.createElement("path", {
266
+ fillRule: "evenodd",
267
+ clipRule: "evenodd",
268
+ d: "M0.673828 16.0055H0.675391C2.88453 16.0055 4.67539 14.2146 4.67539 12.0055V3.9955C4.67539 1.88216 3.03648 0.151608 0.960312 0.00549316C1.78382 0.738158 2.30257 1.80597 2.30257 2.99493V12.7838C2.30257 14.1053 1.66172 15.2771 0.673828 16.0055Z"
269
+ })))), _react.default.createElement(_f36components.Popover.Content, {
270
+ className: styles.popoverContent,
271
+ onMouseEnter: onMouseEnter,
272
+ onMouseLeave: onMouseLeave
273
+ }, !!ReleaseLocalesStatusMap && _react.default.createElement(_react.default.Fragment, null, _react.default.createElement(_ReleaseEntityStatusLocalesList.ReleaseEntityStatusLocalesList, {
274
+ statusMap: ReleaseLocalesStatusMap,
275
+ activeLocales: activeLocales
276
+ }))));
277
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "RELEASE_BADGES", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return RELEASE_BADGES;
9
+ }
10
+ });
11
+ const _f36tokens = /*#__PURE__*/ _interop_require_default(require("@contentful/f36-tokens"));
12
+ function _interop_require_default(obj) {
13
+ return obj && obj.__esModule ? obj : {
14
+ default: obj
15
+ };
16
+ }
17
+ const RELEASE_BADGES = {
18
+ willPublish: {
19
+ label: 'Will publish',
20
+ variant: 'positive',
21
+ default: _f36tokens.default.green300,
22
+ hover: _f36tokens.default.green400,
23
+ icon: _f36tokens.default.green400
24
+ },
25
+ becomesDraft: {
26
+ label: 'Becomes draft',
27
+ variant: 'warning',
28
+ default: _f36tokens.default.orange300,
29
+ hover: _f36tokens.default.orange400,
30
+ icon: _f36tokens.default.orange400
31
+ },
32
+ remainsDraft: {
33
+ label: 'Remains draft',
34
+ variant: 'secondary',
35
+ default: _f36tokens.default.gray300,
36
+ hover: _f36tokens.default.gray400,
37
+ icon: _f36tokens.default.gray400
38
+ },
39
+ notInRelease: {
40
+ label: 'Not in release',
41
+ variant: 'secondary',
42
+ default: _f36tokens.default.gray300,
43
+ hover: _f36tokens.default.gray400,
44
+ icon: _f36tokens.default.gray400
45
+ }
46
+ };
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ _export_star(require("./ReleaseEntityStatusPopover"), exports);
6
+ _export_star(require("./ReleaseEntityStatusBadge"), exports);
7
+ _export_star(require("./types"), exports);
8
+ function _export_star(from, to) {
9
+ Object.keys(from).forEach(function(k) {
10
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
11
+ Object.defineProperty(to, k, {
12
+ enumerable: true,
13
+ get: function() {
14
+ return from[k];
15
+ }
16
+ });
17
+ }
18
+ });
19
+ return from;
20
+ }
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
package/dist/cjs/index.js CHANGED
@@ -114,6 +114,7 @@ const _shortenStorageUnit = require("./utils/shortenStorageUnit");
114
114
  _export_star(require("./hooks/useLocalePublishStatus"), exports);
115
115
  _export_star(require("./hooks/useActiveLocales"), exports);
116
116
  _export_star(require("./LocalePublishingEntityStatusBadge"), exports);
117
+ _export_star(require("./ReleaseEntityStatusBadge"), exports);
117
118
  const _ModalDialogLauncher = /*#__PURE__*/ _interop_require_wildcard(require("./ModalDialogLauncher"));
118
119
  const _constraints = /*#__PURE__*/ _interop_require_wildcard(require("./utils/constraints"));
119
120
  const _entityHelpers = /*#__PURE__*/ _interop_require_wildcard(require("./utils/entityHelpers"));
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+ import { Text } from '@contentful/f36-components';
3
+ import tokens from '@contentful/f36-tokens';
4
+ import { css } from 'emotion';
5
+ const styles = {
6
+ content: css({
7
+ display: 'block'
8
+ }),
9
+ banner: css({
10
+ background: tokens.gray100,
11
+ padding: tokens.spacingXs,
12
+ margin: `${tokens.spacingXs} ${tokens.spacingS}`,
13
+ borderRadius: tokens.borderRadiusSmall
14
+ })
15
+ };
16
+ export function Banner({ content, highlight }) {
17
+ return React.createElement("div", {
18
+ className: styles.banner
19
+ }, React.createElement(Text, {
20
+ fontSize: "fontSizeS",
21
+ fontColor: "gray700",
22
+ className: styles.content
23
+ }, content), highlight && React.createElement(Text, {
24
+ fontSize: "fontSizeS",
25
+ fontColor: "gray700",
26
+ as: "strong",
27
+ fontWeight: "fontWeightDemiBold"
28
+ }, highlight));
29
+ }
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { Badge } from '@contentful/f36-components';
3
+ const config = {
4
+ publish: {
5
+ label: 'Will publish',
6
+ variant: 'positive'
7
+ },
8
+ unpublish: {
9
+ label: 'Becomes draft',
10
+ variant: 'warning'
11
+ },
12
+ 'not-in-release': {
13
+ label: 'Not in release',
14
+ variant: 'secondary'
15
+ }
16
+ };
17
+ export function ReleaseEntityStatusBadge({ className, action }) {
18
+ const badgeConfig = config[action];
19
+ return React.createElement(Badge, {
20
+ testId: "release-entity-action-status",
21
+ className: className,
22
+ variant: badgeConfig.variant
23
+ }, badgeConfig.label);
24
+ }
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import { Badge, Text } from '@contentful/f36-components';
3
+ import tokens from '@contentful/f36-tokens';
4
+ import { css } from 'emotion';
5
+ const styles = {
6
+ locale: css({
7
+ textOverflow: 'ellipsis',
8
+ overflow: 'hidden',
9
+ whiteSpace: 'nowrap'
10
+ }),
11
+ status: css({
12
+ flexShrink: 0
13
+ }),
14
+ localePublishStatus: css({
15
+ display: 'flex',
16
+ gap: tokens.spacingXs,
17
+ justifyContent: 'space-between',
18
+ padding: `${tokens.spacingXs} ${tokens.spacingS}`
19
+ })
20
+ };
21
+ export function ReleaseEntityStatusLocale({ locale, label, variant }) {
22
+ return React.createElement("div", {
23
+ className: styles.localePublishStatus,
24
+ "data-test-id": "locale-publishing-status"
25
+ }, React.createElement(Text, {
26
+ className: styles.locale,
27
+ fontColor: "gray700"
28
+ }, locale.name, ' ', React.createElement(Text, {
29
+ fontColor: "gray500"
30
+ }, "(", locale.code, ")", locale.default && ', Default')), React.createElement(Badge, {
31
+ className: styles.status,
32
+ variant: variant
33
+ }, label));
34
+ }
@@ -0,0 +1,70 @@
1
+ import React from 'react';
2
+ import { MenuSectionTitle } from '@contentful/f36-components';
3
+ import { sortBy } from 'lodash';
4
+ import { Banner } from './Banner';
5
+ import { ReleaseEntityStatusLocale } from './ReleaseEntityStatusLocale';
6
+ function groupAndSortLocales(entries, activeLocales) {
7
+ const { selected, nonSelected } = entries.reduce((prev, [localeCode, localeStatusType])=>{
8
+ return activeLocales?.some((sl)=>sl.code === localeCode) ? {
9
+ ...prev,
10
+ selected: [
11
+ ...prev.selected,
12
+ localeStatusType
13
+ ]
14
+ } : {
15
+ ...prev,
16
+ nonSelected: [
17
+ ...prev.nonSelected,
18
+ localeStatusType
19
+ ]
20
+ };
21
+ }, {
22
+ selected: [],
23
+ nonSelected: []
24
+ });
25
+ return {
26
+ selected: sortBy(selected, 'locale.name'),
27
+ nonSelected: nonSelected.sort((a, b)=>{
28
+ if (a.status === b.status) {
29
+ return a.locale.name.localeCompare(b.locale.name);
30
+ }
31
+ if (a.status === 'becomesDraft' || a.status === 'willPublish' && b.status === 'remainsDraft') {
32
+ return -1;
33
+ }
34
+ return 1;
35
+ })
36
+ };
37
+ }
38
+ export function ReleaseEntityStatusLocalesList({ statusMap, activeLocales }) {
39
+ const entries = [
40
+ ...statusMap.entries()
41
+ ];
42
+ const counters = entries.reduce((prev, [, { status }])=>({
43
+ becomesDraft: prev.becomesDraft + (status === 'becomesDraft' ? 1 : 0),
44
+ willPublish: prev.willPublish + (status === 'willPublish' ? 1 : 0),
45
+ remainsDraft: prev.remainsDraft + (status === 'remainsDraft' ? 1 : 0)
46
+ }), {
47
+ willPublish: 0,
48
+ becomesDraft: 0,
49
+ remainsDraft: 0
50
+ });
51
+ const { selected, nonSelected } = groupAndSortLocales(entries, activeLocales);
52
+ return React.createElement(React.Fragment, null, React.createElement(Banner, {
53
+ content: "The statuses of the locales for this content:",
54
+ highlight: `${counters.becomesDraft} becomes draft, ${counters.willPublish} will publish, ${counters.remainsDraft} remains draft`
55
+ }), React.createElement("div", {
56
+ "data-test-id": "locale-publishing-selected"
57
+ }, React.createElement(MenuSectionTitle, null, "Locales in the entry editor:"), selected.map(({ locale, label, variant })=>React.createElement(ReleaseEntityStatusLocale, {
58
+ key: `selected-${locale.code}`,
59
+ label: label,
60
+ variant: variant,
61
+ locale: locale
62
+ }))), nonSelected.length > 0 && React.createElement("div", {
63
+ "data-test-id": "locale-publishing-others"
64
+ }, React.createElement(MenuSectionTitle, null, "Other locales:"), nonSelected.map(({ locale, label, variant })=>React.createElement(ReleaseEntityStatusLocale, {
65
+ key: `others-${locale.code}`,
66
+ label: label,
67
+ variant: variant,
68
+ locale: locale
69
+ }))));
70
+ }
@@ -0,0 +1,221 @@
1
+ import React, { useCallback, useRef, useState } from 'react';
2
+ import { Badge, Flex, generateIcon, Popover, Skeleton } from '@contentful/f36-components';
3
+ import tokens from '@contentful/f36-tokens';
4
+ import { cx, css } from 'emotion';
5
+ import { RELEASE_BADGES } from './constants';
6
+ import { ReleaseEntityStatusLocalesList } from './ReleaseEntityStatusLocalesList';
7
+ const getColor = ({ secondary, tertiary, isHover })=>{
8
+ const status = secondary || tertiary;
9
+ return isHover ? RELEASE_BADGES[status]?.hover : RELEASE_BADGES[status]?.default;
10
+ };
11
+ const generateDynamicStyles = (status)=>{
12
+ const wrapperClass = css({
13
+ '& svg[data-status="secondary"]': {
14
+ fill: getColor({
15
+ secondary: status?.secondary,
16
+ isHover: false
17
+ })
18
+ },
19
+ '& svg[data-status="tertiary"]': {
20
+ fill: getColor({
21
+ tertiary: status?.tertiary,
22
+ isHover: false
23
+ })
24
+ },
25
+ '&:hover svg[data-status="secondary"]': {
26
+ fill: getColor({
27
+ secondary: status?.secondary,
28
+ isHover: true
29
+ })
30
+ },
31
+ '&:hover svg[data-status="tertiary"]': {
32
+ fill: getColor({
33
+ tertiary: status?.tertiary,
34
+ isHover: true
35
+ })
36
+ }
37
+ });
38
+ return wrapperClass;
39
+ };
40
+ const styles = {
41
+ badge: css({
42
+ '&:focus': {
43
+ outline: 'none',
44
+ boxShadow: `inset ${tokens.glowPrimary}`
45
+ }
46
+ }),
47
+ wrapper: css({
48
+ '& svg': {
49
+ transition: 'fill 0.2s ease-in-out'
50
+ },
51
+ '& svg[data-status="tertiary"]': {
52
+ marginLeft: '-1px'
53
+ }
54
+ }),
55
+ popoverContent: css({
56
+ maxWidth: '336px',
57
+ maxHeight: '368px',
58
+ overflowY: 'auto',
59
+ padding: `${tokens.spacing2Xs} 0`
60
+ }),
61
+ skeletonBadge: css({
62
+ flexShrink: 0,
63
+ display: 'block',
64
+ height: '20px',
65
+ width: '65px'
66
+ })
67
+ };
68
+ const determineBadgeStatus = (localesStatusMap, activeLocales)=>{
69
+ if (activeLocales && activeLocales.length === 1) {
70
+ const activeLocale = activeLocales.find((locale)=>localesStatusMap.has(locale.code));
71
+ return {
72
+ primary: localesStatusMap.get(activeLocale.code).status
73
+ };
74
+ }
75
+ let becomesDraftCount = 0, willPublishCount = 0, remainsDraftCount = 0;
76
+ for (const [localeCode, localeStatus] of localesStatusMap.entries()){
77
+ if (!activeLocales || activeLocales.find((selectedLocale)=>selectedLocale.code === localeCode)) {
78
+ switch(localeStatus.status){
79
+ case 'remainsDraft':
80
+ remainsDraftCount += 1;
81
+ break;
82
+ case 'becomesDraft':
83
+ becomesDraftCount += 1;
84
+ break;
85
+ case 'willPublish':
86
+ willPublishCount += 1;
87
+ break;
88
+ }
89
+ }
90
+ }
91
+ const hasRemainsDraft = remainsDraftCount > 0;
92
+ const hasWillPublish = willPublishCount > 0;
93
+ const hasBecomesDraft = becomesDraftCount > 0;
94
+ switch(true){
95
+ case hasRemainsDraft && hasWillPublish && hasBecomesDraft:
96
+ return {
97
+ primary: 'becomesDraft',
98
+ secondary: 'willPublish',
99
+ tertiary: 'remainsDraft'
100
+ };
101
+ case hasRemainsDraft && hasWillPublish:
102
+ return {
103
+ primary: 'willPublish',
104
+ secondary: 'remainsDraft'
105
+ };
106
+ case hasRemainsDraft && hasBecomesDraft:
107
+ return {
108
+ primary: 'becomesDraft',
109
+ secondary: 'remainsDraft'
110
+ };
111
+ case hasWillPublish && hasBecomesDraft:
112
+ return {
113
+ primary: 'becomesDraft',
114
+ secondary: 'willPublish'
115
+ };
116
+ case hasWillPublish:
117
+ return {
118
+ primary: 'willPublish',
119
+ secondary: 'willPublish'
120
+ };
121
+ case hasBecomesDraft:
122
+ return {
123
+ primary: 'becomesDraft',
124
+ secondary: 'becomesDraft'
125
+ };
126
+ case hasRemainsDraft:
127
+ return {
128
+ primary: 'remainsDraft',
129
+ secondary: 'remainsDraft'
130
+ };
131
+ default:
132
+ return {
133
+ primary: 'notInRelease',
134
+ secondary: 'notInRelease'
135
+ };
136
+ }
137
+ };
138
+ export function ReleaseEntityStatusPopover({ ReleaseLocalesStatusMap, activeLocales, isLoading = false }) {
139
+ const [isOpen, setIsOpen] = useState(false);
140
+ const timeoutRef = useRef();
141
+ const onMouseEnter = useCallback(()=>{
142
+ clearTimeout(timeoutRef.current);
143
+ timeoutRef.current = setTimeout(()=>{
144
+ setIsOpen(true);
145
+ }, 300);
146
+ }, []);
147
+ const onMouseLeave = useCallback(()=>{
148
+ clearTimeout(timeoutRef.current);
149
+ timeoutRef.current = setTimeout(()=>{
150
+ setIsOpen(false);
151
+ }, 300);
152
+ }, []);
153
+ const status = determineBadgeStatus(ReleaseLocalesStatusMap, activeLocales);
154
+ const ariaLabel = status.secondary ? 'Multiple statuses' : status.primary;
155
+ const wrapperClass = generateDynamicStyles(status);
156
+ const ArrowDownIcon = generateIcon({
157
+ name: 'ArrowDownIcon',
158
+ viewBox: '0 0 12 20',
159
+ path: React.createElement("path", {
160
+ d: "M3.03076 8C2.20109 8 1.73228 8.95209 2.23814 9.60971L5.20727 13.4696C5.60757 13.99 6.39223 13.99 6.79252 13.4696L9.76166 9.60971C10.2675 8.95209 9.79871 8 8.96904 8L3.03076 8Z",
161
+ fill: "currentColor"
162
+ })
163
+ });
164
+ if (isLoading) {
165
+ return React.createElement(Skeleton.Container, {
166
+ className: styles.skeletonBadge
167
+ }, React.createElement(Skeleton.Image, {
168
+ testId: `Release-entity-locale-status-badge-skeleton`,
169
+ width: "65px",
170
+ height: "20px"
171
+ }));
172
+ }
173
+ return React.createElement(Popover, {
174
+ isOpen: ReleaseLocalesStatusMap && isOpen,
175
+ onClose: ()=>setIsOpen(false),
176
+ autoFocus: false,
177
+ placement: "bottom-end"
178
+ }, React.createElement(Popover.Trigger, null, React.createElement(Flex, {
179
+ "aria-label": ariaLabel,
180
+ alignItems: "center",
181
+ className: cx(styles.wrapper, wrapperClass)
182
+ }, React.createElement(Badge, {
183
+ tabIndex: 0,
184
+ variant: RELEASE_BADGES[status.primary].variant,
185
+ onFocus: ()=>setIsOpen(true),
186
+ onBlur: ()=>setIsOpen(false),
187
+ endIcon: React.createElement(ArrowDownIcon, {
188
+ color: RELEASE_BADGES[status.primary].icon
189
+ }),
190
+ onMouseOver: onMouseEnter,
191
+ onMouseEnter: onMouseEnter,
192
+ onMouseLeave: onMouseLeave
193
+ }, RELEASE_BADGES[status.primary].label), status.secondary && React.createElement("svg", {
194
+ "data-status": "secondary",
195
+ "aria-hidden": "true",
196
+ width: "4",
197
+ height: "18",
198
+ viewBox: "0 0 4 18"
199
+ }, React.createElement("path", {
200
+ fillRule: "evenodd",
201
+ clipRule: "evenodd",
202
+ d: "M1.45942e-06 18H0.00296171C2.2121 18 4.00296 16.2091 4.00296 14V4C4.00296 1.79086 2.2121 0 0.00295914 0H0C0.830421 0.732944 1.35418 1.80531 1.35418 3V15C1.35418 16.1947 0.830422 17.2671 1.45942e-06 18Z"
203
+ })), status.tertiary && React.createElement("svg", {
204
+ "data-status": "tertiary",
205
+ "aria-hidden": "true",
206
+ width: "5",
207
+ height: "16",
208
+ viewBox: "0 0 5 16"
209
+ }, React.createElement("path", {
210
+ fillRule: "evenodd",
211
+ clipRule: "evenodd",
212
+ d: "M0.673828 16.0055H0.675391C2.88453 16.0055 4.67539 14.2146 4.67539 12.0055V3.9955C4.67539 1.88216 3.03648 0.151608 0.960312 0.00549316C1.78382 0.738158 2.30257 1.80597 2.30257 2.99493V12.7838C2.30257 14.1053 1.66172 15.2771 0.673828 16.0055Z"
213
+ })))), React.createElement(Popover.Content, {
214
+ className: styles.popoverContent,
215
+ onMouseEnter: onMouseEnter,
216
+ onMouseLeave: onMouseLeave
217
+ }, !!ReleaseLocalesStatusMap && React.createElement(React.Fragment, null, React.createElement(ReleaseEntityStatusLocalesList, {
218
+ statusMap: ReleaseLocalesStatusMap,
219
+ activeLocales: activeLocales
220
+ }))));
221
+ }
@@ -0,0 +1,31 @@
1
+ import tokens from '@contentful/f36-tokens';
2
+ export const RELEASE_BADGES = {
3
+ willPublish: {
4
+ label: 'Will publish',
5
+ variant: 'positive',
6
+ default: tokens.green300,
7
+ hover: tokens.green400,
8
+ icon: tokens.green400
9
+ },
10
+ becomesDraft: {
11
+ label: 'Becomes draft',
12
+ variant: 'warning',
13
+ default: tokens.orange300,
14
+ hover: tokens.orange400,
15
+ icon: tokens.orange400
16
+ },
17
+ remainsDraft: {
18
+ label: 'Remains draft',
19
+ variant: 'secondary',
20
+ default: tokens.gray300,
21
+ hover: tokens.gray400,
22
+ icon: tokens.gray400
23
+ },
24
+ notInRelease: {
25
+ label: 'Not in release',
26
+ variant: 'secondary',
27
+ default: tokens.gray300,
28
+ hover: tokens.gray400,
29
+ icon: tokens.gray400
30
+ }
31
+ };
@@ -0,0 +1,3 @@
1
+ export * from './ReleaseEntityStatusPopover';
2
+ export * from './ReleaseEntityStatusBadge';
3
+ export * from './types';
@@ -0,0 +1 @@
1
+ export { };
package/dist/esm/index.js CHANGED
@@ -12,6 +12,7 @@ export { ModalDialogLauncher };
12
12
  export { entityHelpers };
13
13
  export { ConstraintsUtils };
14
14
  export * from './LocalePublishingEntityStatusBadge';
15
+ export * from './ReleaseEntityStatusBadge';
15
16
  import * as ModalDialogLauncher from './ModalDialogLauncher';
16
17
  import * as ConstraintsUtils from './utils/constraints';
17
18
  import * as entityHelpers from './utils/entityHelpers';
@@ -0,0 +1,5 @@
1
+ import React, { ReactNode } from 'react';
2
+ export declare function Banner({ content, highlight }: {
3
+ content: ReactNode;
4
+ highlight?: ReactNode;
5
+ }): React.JSX.Element;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import type { ReleaseAction } from './types';
3
+ type ReleaseEntityActionBadgeProps = {
4
+ action: ReleaseAction;
5
+ className?: string;
6
+ };
7
+ export declare function ReleaseEntityStatusBadge({ className, action }: ReleaseEntityActionBadgeProps): React.JSX.Element;
8
+ export {};
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { BadgeVariant } from '@contentful/f36-components';
3
+ import type { LocaleProps } from 'contentful-management';
4
+ type ReleaseEntityStatusLocaleProps = {
5
+ locale: Pick<LocaleProps, 'code' | 'default' | 'name'>;
6
+ label: string;
7
+ variant: BadgeVariant;
8
+ };
9
+ export declare function ReleaseEntityStatusLocale({ locale, label, variant, }: ReleaseEntityStatusLocaleProps): React.JSX.Element;
10
+ export {};
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import type { LocaleProps } from 'contentful-management';
3
+ import { ReleaseLocalesStatusMap } from './types';
4
+ type ReleaseEntityStatusLocalesListProps = {
5
+ statusMap: ReleaseLocalesStatusMap;
6
+ activeLocales?: Pick<LocaleProps, 'code'>[];
7
+ };
8
+ export declare function ReleaseEntityStatusLocalesList({ statusMap, activeLocales, }: ReleaseEntityStatusLocalesListProps): React.JSX.Element;
9
+ export {};
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import type { LocaleProps } from 'contentful-management';
3
+ import type { ReleaseLocalesStatusMap } from './types';
4
+ type ReleaseLocalePublishingPopoverProps = {
5
+ ReleaseLocalesStatusMap: ReleaseLocalesStatusMap;
6
+ activeLocales: Pick<LocaleProps, 'code'>[];
7
+ isLoading?: boolean;
8
+ };
9
+ export declare function ReleaseEntityStatusPopover({ ReleaseLocalesStatusMap, activeLocales, isLoading, }: ReleaseLocalePublishingPopoverProps): React.JSX.Element;
10
+ export {};
@@ -0,0 +1,30 @@
1
+ export declare const RELEASE_BADGES: {
2
+ readonly willPublish: {
3
+ readonly label: "Will publish";
4
+ readonly variant: "positive";
5
+ readonly default: string;
6
+ readonly hover: string;
7
+ readonly icon: string;
8
+ };
9
+ readonly becomesDraft: {
10
+ readonly label: "Becomes draft";
11
+ readonly variant: "warning";
12
+ readonly default: string;
13
+ readonly hover: string;
14
+ readonly icon: string;
15
+ };
16
+ readonly remainsDraft: {
17
+ readonly label: "Remains draft";
18
+ readonly variant: "secondary";
19
+ readonly default: string;
20
+ readonly hover: string;
21
+ readonly icon: string;
22
+ };
23
+ readonly notInRelease: {
24
+ readonly label: "Not in release";
25
+ readonly variant: "secondary";
26
+ readonly default: string;
27
+ readonly hover: string;
28
+ readonly icon: string;
29
+ };
30
+ };
@@ -0,0 +1,3 @@
1
+ export * from './ReleaseEntityStatusPopover';
2
+ export * from './ReleaseEntityStatusBadge';
3
+ export * from './types';
@@ -0,0 +1,11 @@
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>;
@@ -13,6 +13,7 @@ export { ModalDialogLauncher };
13
13
  export { entityHelpers };
14
14
  export { ConstraintsUtils };
15
15
  export * from './LocalePublishingEntityStatusBadge';
16
+ export * from './ReleaseEntityStatusBadge';
16
17
  import * as ModalDialogLauncher from './ModalDialogLauncher';
17
18
  import * as ConstraintsUtils from './utils/constraints';
18
19
  import * as entityHelpers from './utils/entityHelpers';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/field-editor-shared",
3
- "version": "2.4.2",
3
+ "version": "2.5.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": "6bee4a59a3c19a95d2cadde3ef0c78112788626e"
58
+ "gitHead": "4d6650d34ceb61f6445e0734a7ac53ff37c20529"
59
59
  }