@contentful/field-editor-shared 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/CharCounter.js +75 -0
- package/dist/cjs/CharValidation.js +60 -0
- package/dist/cjs/FieldConnector.js +167 -0
- package/dist/cjs/FieldConnector.test.js +81 -0
- package/dist/cjs/ModalDialogLauncher.js +132 -0
- package/dist/cjs/PredefinedValuesError.js +57 -0
- package/dist/cjs/index.js +155 -0
- package/dist/cjs/types.js +4 -0
- package/dist/cjs/typesEntity.js +31 -0
- package/dist/cjs/utils/constraints.js +63 -0
- package/dist/cjs/utils/entityHelpers.js +214 -0
- package/dist/cjs/utils/isValidImage.js +26 -0
- package/dist/cjs/utils/shortenStorageUnit.js +55 -0
- package/dist/esm/CharCounter.js +21 -0
- package/dist/esm/CharValidation.js +11 -0
- package/dist/esm/FieldConnector.js +113 -0
- package/dist/esm/FieldConnector.test.js +33 -0
- package/dist/esm/ModalDialogLauncher.js +67 -0
- package/dist/esm/PredefinedValuesError.js +8 -0
- package/dist/esm/index.js +14 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/typesEntity.js +1 -0
- package/dist/esm/utils/constraints.js +40 -0
- package/dist/esm/utils/entityHelpers.js +170 -0
- package/dist/esm/utils/isValidImage.js +16 -0
- package/dist/esm/utils/shortenStorageUnit.js +37 -0
- package/dist/types/CharCounter.d.ts +7 -0
- package/dist/{CharValidation.d.ts → types/CharValidation.d.ts} +7 -7
- package/dist/{FieldConnector.d.ts → types/FieldConnector.d.ts} +48 -48
- package/dist/types/FieldConnector.test.d.ts +1 -0
- package/dist/{ModalDialogLauncher.d.ts → types/ModalDialogLauncher.d.ts} +13 -13
- package/dist/types/PredefinedValuesError.d.ts +2 -0
- package/dist/{index.d.ts → types/index.d.ts} +15 -15
- package/dist/{types.d.ts → types/types.d.ts} +11 -11
- package/dist/{typesEntity.d.ts → types/typesEntity.d.ts} +9 -9
- package/dist/{utils → types/utils}/constraints.d.ts +3 -3
- package/dist/{utils → types/utils}/entityHelpers.d.ts +68 -68
- package/dist/{utils → types/utils}/isValidImage.d.ts +5 -5
- package/dist/{utils → types/utils}/shortenStorageUnit.d.ts +17 -17
- package/package.json +26 -12
- package/CHANGELOG.md +0 -196
- package/dist/CharCounter.d.ts +0 -7
- package/dist/PredefinedValuesError.d.ts +0 -2
- package/dist/field-editor-shared.cjs.development.js +0 -634
- package/dist/field-editor-shared.cjs.development.js.map +0 -1
- package/dist/field-editor-shared.cjs.production.min.js +0 -2
- package/dist/field-editor-shared.cjs.production.min.js.map +0 -1
- package/dist/field-editor-shared.esm.js +0 -619
- package/dist/field-editor-shared.esm.js.map +0 -1
- package/dist/index.js +0 -8
|
@@ -1,634 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
|
6
|
-
|
|
7
|
-
var React = _interopDefault(require('react'));
|
|
8
|
-
var isEqual = _interopDefault(require('lodash/isEqual'));
|
|
9
|
-
var throttle = _interopDefault(require('lodash/throttle'));
|
|
10
|
-
var f36Note = require('@contentful/f36-note');
|
|
11
|
-
var tokens = _interopDefault(require('@contentful/f36-tokens'));
|
|
12
|
-
var emotion = require('emotion');
|
|
13
|
-
var ReactDOM = _interopDefault(require('react-dom'));
|
|
14
|
-
var f36Components = require('@contentful/f36-components');
|
|
15
|
-
var isNumber = _interopDefault(require('lodash/isNumber'));
|
|
16
|
-
var get = _interopDefault(require('lodash/get'));
|
|
17
|
-
var isObject = _interopDefault(require('lodash/isObject'));
|
|
18
|
-
var isString = _interopDefault(require('lodash/isString'));
|
|
19
|
-
|
|
20
|
-
class FieldConnector extends React.Component {
|
|
21
|
-
constructor(props) {
|
|
22
|
-
super(props);
|
|
23
|
-
this.unsubscribeErrors = null;
|
|
24
|
-
this.unsubscribeDisabled = null;
|
|
25
|
-
this.unsubscribeValue = null;
|
|
26
|
-
|
|
27
|
-
this.setValue = async value => {
|
|
28
|
-
if (this.props.isEmptyValue(value ?? null)) {
|
|
29
|
-
this.setState({
|
|
30
|
-
value: undefined
|
|
31
|
-
});
|
|
32
|
-
} else {
|
|
33
|
-
this.setState({
|
|
34
|
-
value
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
await this.triggerSetValueCallbacks(value);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
this.triggerSetValueCallbacks = throttle(value => {
|
|
42
|
-
return new Promise((resolve, reject) => {
|
|
43
|
-
if (this.props.isEmptyValue(value ?? null)) {
|
|
44
|
-
this.props.field.removeValue().then(resolve).catch(reject);
|
|
45
|
-
} else {
|
|
46
|
-
this.props.field.setValue(value).then(resolve).catch(reject);
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
}, this.props.throttle, {
|
|
50
|
-
leading: this.props.throttle === 0
|
|
51
|
-
});
|
|
52
|
-
const initialValue = props.field.getValue();
|
|
53
|
-
this.state = {
|
|
54
|
-
isLocalValueChange: false,
|
|
55
|
-
externalReset: 0,
|
|
56
|
-
value: initialValue,
|
|
57
|
-
lastRemoteValue: initialValue,
|
|
58
|
-
disabled: props.isInitiallyDisabled ?? false,
|
|
59
|
-
errors: []
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
componentDidMount() {
|
|
64
|
-
const {
|
|
65
|
-
field
|
|
66
|
-
} = this.props;
|
|
67
|
-
this.unsubscribeErrors = field.onSchemaErrorsChanged(errors => {
|
|
68
|
-
this.setState({
|
|
69
|
-
errors: errors || []
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
this.unsubscribeDisabled = field.onIsDisabledChanged(disabled => {
|
|
73
|
-
this.setState({
|
|
74
|
-
disabled
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
this.unsubscribeValue = field.onValueChanged(value => {
|
|
78
|
-
this.setState(currentState => {
|
|
79
|
-
const isLocalValueChange = this.props.isEqualValues(value, currentState.value);
|
|
80
|
-
const lastRemoteValue = isLocalValueChange ? currentState.lastRemoteValue : value;
|
|
81
|
-
const externalReset = currentState.externalReset + (isLocalValueChange ? 0 : 1);
|
|
82
|
-
return {
|
|
83
|
-
value,
|
|
84
|
-
lastRemoteValue,
|
|
85
|
-
isLocalValueChange,
|
|
86
|
-
externalReset
|
|
87
|
-
};
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
componentWillUnmount() {
|
|
93
|
-
if (typeof this.unsubscribeErrors === 'function') {
|
|
94
|
-
this.unsubscribeErrors();
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (typeof this.unsubscribeDisabled === 'function') {
|
|
98
|
-
this.unsubscribeDisabled();
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (typeof this.unsubscribeValue === 'function') {
|
|
102
|
-
this.unsubscribeValue();
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
render() {
|
|
107
|
-
return this.props.children({ ...this.state,
|
|
108
|
-
setValue: this.setValue,
|
|
109
|
-
disabled: this.props.isDisabled || this.state.disabled
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
FieldConnector.defaultProps = {
|
|
115
|
-
children: () => {
|
|
116
|
-
return null;
|
|
117
|
-
},
|
|
118
|
-
// eslint-disable-next-line -- TODO: describe this disable
|
|
119
|
-
isEmptyValue: value => {
|
|
120
|
-
return value === null || value === '';
|
|
121
|
-
},
|
|
122
|
-
// eslint-disable-next-line -- TODO: describe this disable
|
|
123
|
-
isEqualValues: (value1, value2) => {
|
|
124
|
-
return isEqual(value1, value2);
|
|
125
|
-
},
|
|
126
|
-
throttle: 300
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
function PredefinedValuesError() {
|
|
130
|
-
return React.createElement(f36Note.Note, {
|
|
131
|
-
variant: "warning",
|
|
132
|
-
testId: "predefined-values-warning"
|
|
133
|
-
}, "The widget failed to initialize. You can fix the problem by providing predefined values under the validations tab in the field settings.");
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const styles = {
|
|
137
|
-
invalid: /*#__PURE__*/emotion.css({
|
|
138
|
-
color: tokens.red600
|
|
139
|
-
})
|
|
140
|
-
};
|
|
141
|
-
function CharCounter(props) {
|
|
142
|
-
let count = 0;
|
|
143
|
-
|
|
144
|
-
if (props.value) {
|
|
145
|
-
count = props.value.length;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const valid = count === 0 || props.checkConstraint(count);
|
|
149
|
-
return React.createElement("span", {
|
|
150
|
-
"data-status-code": valid ? null : 'invalid-size',
|
|
151
|
-
className: emotion.cx({
|
|
152
|
-
[styles.invalid]: !valid
|
|
153
|
-
})
|
|
154
|
-
}, count, " characters");
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function CharValidation(props) {
|
|
158
|
-
const {
|
|
159
|
-
constraints
|
|
160
|
-
} = props;
|
|
161
|
-
|
|
162
|
-
if (constraints.type === 'max') {
|
|
163
|
-
return React.createElement("span", null, "Maximum ", constraints.max, " characters");
|
|
164
|
-
} else if (constraints.type === 'min') {
|
|
165
|
-
return React.createElement("span", null, "Requires at least ", constraints.min, " characters");
|
|
166
|
-
} else {
|
|
167
|
-
return React.createElement("span", null, "Requires between ", constraints.min, " and ", constraints.max, " characters");
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-use-before-define */
|
|
172
|
-
function open(componentRenderer) {
|
|
173
|
-
let rootDom = null;
|
|
174
|
-
|
|
175
|
-
const getRoot = () => {
|
|
176
|
-
if (rootDom === null) {
|
|
177
|
-
rootDom = document.createElement('div');
|
|
178
|
-
rootDom.setAttribute('id', 'field-editor-modal-root');
|
|
179
|
-
document.body.appendChild(rootDom);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return rootDom;
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
return new Promise(resolve => {
|
|
186
|
-
let currentConfig = {
|
|
187
|
-
onClose,
|
|
188
|
-
isShown: true
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
function render({
|
|
192
|
-
onClose,
|
|
193
|
-
isShown
|
|
194
|
-
}) {
|
|
195
|
-
ReactDOM.render(componentRenderer({
|
|
196
|
-
onClose,
|
|
197
|
-
isShown
|
|
198
|
-
}), getRoot());
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
function onClose(...args) {
|
|
202
|
-
currentConfig = { ...currentConfig,
|
|
203
|
-
isShown: false
|
|
204
|
-
};
|
|
205
|
-
render(currentConfig); // eslint-disable-next-line -- TODO: describe this disable @typescript-eslint/ban-ts-comment
|
|
206
|
-
// @ts-ignore
|
|
207
|
-
|
|
208
|
-
resolve(...args);
|
|
209
|
-
getRoot().remove();
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
render(currentConfig);
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
function openDialog(options, Component) {
|
|
216
|
-
const key = Date.now();
|
|
217
|
-
const size = isNumber(options.width) ? `${options.width}px` : options.width;
|
|
218
|
-
return open(({
|
|
219
|
-
isShown,
|
|
220
|
-
onClose
|
|
221
|
-
}) => {
|
|
222
|
-
const onCloseHandler = () => onClose();
|
|
223
|
-
|
|
224
|
-
return React.createElement(f36Components.Modal, {
|
|
225
|
-
key: key,
|
|
226
|
-
shouldCloseOnOverlayClick: options.shouldCloseOnOverlayClick || false,
|
|
227
|
-
shouldCloseOnEscapePress: options.shouldCloseOnEscapePress || false,
|
|
228
|
-
allowHeightOverflow: options.allowHeightOverflow || false,
|
|
229
|
-
position: options.position || 'center',
|
|
230
|
-
isShown: isShown,
|
|
231
|
-
onClose: onCloseHandler,
|
|
232
|
-
size: size || '700px'
|
|
233
|
-
}, () => React.createElement(React.Fragment, null, options.title && React.createElement(f36Components.ModalHeader, {
|
|
234
|
-
testId: "dialog-title",
|
|
235
|
-
title: options.title,
|
|
236
|
-
onClose: onCloseHandler
|
|
237
|
-
}), React.createElement("div", {
|
|
238
|
-
style: {
|
|
239
|
-
minHeight: options.minHeight || 'auto'
|
|
240
|
-
}
|
|
241
|
-
}, React.createElement(Component, {
|
|
242
|
-
onClose: onClose
|
|
243
|
-
}))));
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
var ModalDialogLauncher = {
|
|
247
|
-
openDialog
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
var ModalDialogLauncher$1 = {
|
|
251
|
-
__proto__: null,
|
|
252
|
-
open: open,
|
|
253
|
-
openDialog: openDialog,
|
|
254
|
-
'default': ModalDialogLauncher
|
|
255
|
-
};
|
|
256
|
-
|
|
257
|
-
function titleOrDefault(title, defaultTitle) {
|
|
258
|
-
if (!isString(title)) {
|
|
259
|
-
return defaultTitle;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
if (title) {
|
|
263
|
-
const trimmedTitle = title.trim();
|
|
264
|
-
|
|
265
|
-
if (trimmedTitle.length === 0) {
|
|
266
|
-
return defaultTitle;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
return trimmedTitle;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
return defaultTitle;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
function getFieldValue({
|
|
276
|
-
/**
|
|
277
|
-
* Expects an entity fetched with a flag Skip-Transformation: true
|
|
278
|
-
*/
|
|
279
|
-
entity,
|
|
280
|
-
fieldId,
|
|
281
|
-
localeCode,
|
|
282
|
-
defaultLocaleCode
|
|
283
|
-
}) {
|
|
284
|
-
const values = get(entity, ['fields', fieldId]);
|
|
285
|
-
|
|
286
|
-
if (!isObject(values)) {
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
const firstLocaleCode = Object.keys(values)[0];
|
|
291
|
-
return values[localeCode] || values[defaultLocaleCode] || values[firstLocaleCode];
|
|
292
|
-
}
|
|
293
|
-
function getAssetTitle({
|
|
294
|
-
asset,
|
|
295
|
-
localeCode,
|
|
296
|
-
defaultLocaleCode,
|
|
297
|
-
defaultTitle
|
|
298
|
-
}) {
|
|
299
|
-
var _asset$fields;
|
|
300
|
-
|
|
301
|
-
const title = getFieldValue({
|
|
302
|
-
entity: {
|
|
303
|
-
fields: {
|
|
304
|
-
title: (_asset$fields = asset.fields) == null ? void 0 : _asset$fields.title
|
|
305
|
-
}
|
|
306
|
-
},
|
|
307
|
-
fieldId: 'title',
|
|
308
|
-
localeCode,
|
|
309
|
-
defaultLocaleCode
|
|
310
|
-
});
|
|
311
|
-
return titleOrDefault(title, defaultTitle);
|
|
312
|
-
}
|
|
313
|
-
/**
|
|
314
|
-
* Returns true if field is an Asset
|
|
315
|
-
*
|
|
316
|
-
* @param field
|
|
317
|
-
* @returns {boolean}
|
|
318
|
-
*/
|
|
319
|
-
|
|
320
|
-
const isAssetField = field => field.type === 'Link' && field.linkType === 'Asset';
|
|
321
|
-
/**
|
|
322
|
-
* Returns true if field is a Title
|
|
323
|
-
*/
|
|
324
|
-
|
|
325
|
-
function isDisplayField({
|
|
326
|
-
field,
|
|
327
|
-
contentType
|
|
328
|
-
}) {
|
|
329
|
-
return field.id === contentType.displayField;
|
|
330
|
-
}
|
|
331
|
-
/**
|
|
332
|
-
* Returns true if field is a short Description
|
|
333
|
-
*/
|
|
334
|
-
|
|
335
|
-
function isDescriptionField({
|
|
336
|
-
field,
|
|
337
|
-
contentType
|
|
338
|
-
}) {
|
|
339
|
-
const isTextField = field => ['Symbol', 'Text'].includes(field.type);
|
|
340
|
-
|
|
341
|
-
const isMaybeSlugField = field => /\bslug\b/.test(field.name);
|
|
342
|
-
|
|
343
|
-
return isTextField(field) && !isDisplayField({
|
|
344
|
-
field,
|
|
345
|
-
contentType
|
|
346
|
-
}) && !isMaybeSlugField(field);
|
|
347
|
-
}
|
|
348
|
-
function getEntityDescription({
|
|
349
|
-
entity,
|
|
350
|
-
contentType,
|
|
351
|
-
localeCode,
|
|
352
|
-
defaultLocaleCode
|
|
353
|
-
}) {
|
|
354
|
-
if (!contentType) {
|
|
355
|
-
return '';
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
const descriptionField = contentType.fields.find(field => isDescriptionField({
|
|
359
|
-
field,
|
|
360
|
-
contentType
|
|
361
|
-
}));
|
|
362
|
-
|
|
363
|
-
if (!descriptionField) {
|
|
364
|
-
return '';
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
return getFieldValue({
|
|
368
|
-
entity,
|
|
369
|
-
fieldId: descriptionField.id,
|
|
370
|
-
localeCode,
|
|
371
|
-
defaultLocaleCode
|
|
372
|
-
}) || '';
|
|
373
|
-
}
|
|
374
|
-
function getEntryTitle({
|
|
375
|
-
entry,
|
|
376
|
-
contentType,
|
|
377
|
-
localeCode,
|
|
378
|
-
defaultLocaleCode,
|
|
379
|
-
defaultTitle
|
|
380
|
-
}) {
|
|
381
|
-
let title;
|
|
382
|
-
|
|
383
|
-
if (!contentType) {
|
|
384
|
-
return defaultTitle;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
const displayField = contentType.displayField;
|
|
388
|
-
|
|
389
|
-
if (!displayField) {
|
|
390
|
-
return defaultTitle;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
const displayFieldInfo = contentType.fields.find(field => field.id === displayField);
|
|
394
|
-
|
|
395
|
-
if (!displayFieldInfo) {
|
|
396
|
-
return defaultTitle;
|
|
397
|
-
} // when localization for a field is "turned off",
|
|
398
|
-
// we don't clean up the "old" localized data, so it is still in the response.
|
|
399
|
-
// Therefore, we're checking if displayField is localizable.
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
if (displayFieldInfo.localized) {
|
|
403
|
-
title = getFieldValue({
|
|
404
|
-
entity: entry,
|
|
405
|
-
fieldId: displayField,
|
|
406
|
-
localeCode,
|
|
407
|
-
defaultLocaleCode
|
|
408
|
-
});
|
|
409
|
-
|
|
410
|
-
if (!title) {
|
|
411
|
-
// Older content types may return id/apiName, but some entry lookup paths do not fetch raw data
|
|
412
|
-
// In order to still return a title in this case, look for displayField as apiName in content type,
|
|
413
|
-
// ...but still look for displayField as a field in the entry
|
|
414
|
-
title = getFieldValue({
|
|
415
|
-
entity: entry,
|
|
416
|
-
fieldId: displayFieldInfo.id,
|
|
417
|
-
localeCode,
|
|
418
|
-
defaultLocaleCode
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
} else {
|
|
422
|
-
title = getFieldValue({
|
|
423
|
-
entity: entry,
|
|
424
|
-
fieldId: displayField,
|
|
425
|
-
defaultLocaleCode,
|
|
426
|
-
localeCode: ''
|
|
427
|
-
});
|
|
428
|
-
|
|
429
|
-
if (!title) {
|
|
430
|
-
title = getFieldValue({
|
|
431
|
-
entity: entry,
|
|
432
|
-
fieldId: displayFieldInfo.id,
|
|
433
|
-
defaultLocaleCode,
|
|
434
|
-
localeCode: ''
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
return titleOrDefault(title, defaultTitle);
|
|
440
|
-
}
|
|
441
|
-
function getEntryStatus(sys) {
|
|
442
|
-
if (!sys || sys.type !== 'Entry' && sys.type !== 'Asset') {
|
|
443
|
-
throw new TypeError('Invalid entity metadata object');
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
if (sys.deletedVersion) {
|
|
447
|
-
return 'deleted';
|
|
448
|
-
} else if (sys.archivedVersion) {
|
|
449
|
-
return 'archived';
|
|
450
|
-
} else if (sys.publishedVersion) {
|
|
451
|
-
if (sys.version > sys.publishedVersion + 1) {
|
|
452
|
-
return 'changed';
|
|
453
|
-
} else {
|
|
454
|
-
return 'published';
|
|
455
|
-
}
|
|
456
|
-
} else {
|
|
457
|
-
return 'draft';
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
/**
|
|
461
|
-
* Gets a promise resolving with a localized asset image field representing a
|
|
462
|
-
* given entities file. The promise may resolve with null.
|
|
463
|
-
*/
|
|
464
|
-
|
|
465
|
-
const getEntryImage = async ({
|
|
466
|
-
entry,
|
|
467
|
-
contentType,
|
|
468
|
-
localeCode
|
|
469
|
-
}, getAsset) => {
|
|
470
|
-
if (!contentType) {
|
|
471
|
-
return null;
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
const assetLink = contentType.fields.find(isAssetField);
|
|
475
|
-
|
|
476
|
-
if (!assetLink) {
|
|
477
|
-
return null;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
const assetId = get(entry.fields, [assetLink.id, localeCode, 'sys', 'id']);
|
|
481
|
-
|
|
482
|
-
if (!assetId) {
|
|
483
|
-
return null;
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
try {
|
|
487
|
-
const asset = await getAsset(assetId);
|
|
488
|
-
const file = get(asset, ['fields', 'file', localeCode]);
|
|
489
|
-
const isImage = Boolean(get(file, ['details', 'image'], false));
|
|
490
|
-
return isImage ? file : null;
|
|
491
|
-
} catch (e) {
|
|
492
|
-
return null;
|
|
493
|
-
}
|
|
494
|
-
};
|
|
495
|
-
|
|
496
|
-
var entityHelpers = {
|
|
497
|
-
__proto__: null,
|
|
498
|
-
getFieldValue: getFieldValue,
|
|
499
|
-
getAssetTitle: getAssetTitle,
|
|
500
|
-
isAssetField: isAssetField,
|
|
501
|
-
isDisplayField: isDisplayField,
|
|
502
|
-
isDescriptionField: isDescriptionField,
|
|
503
|
-
getEntityDescription: getEntityDescription,
|
|
504
|
-
getEntryTitle: getEntryTitle,
|
|
505
|
-
getEntryStatus: getEntryStatus,
|
|
506
|
-
getEntryImage: getEntryImage
|
|
507
|
-
};
|
|
508
|
-
|
|
509
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
510
|
-
function fromFieldValidations(validations = [], fieldType) {
|
|
511
|
-
const sizeValidation = validations.find(v => 'size' in v);
|
|
512
|
-
const size = sizeValidation && sizeValidation.size || {};
|
|
513
|
-
const min = size.min;
|
|
514
|
-
const max = size.max;
|
|
515
|
-
|
|
516
|
-
if (isNumber(min) && isNumber(max)) {
|
|
517
|
-
return {
|
|
518
|
-
type: 'min-max',
|
|
519
|
-
min,
|
|
520
|
-
max
|
|
521
|
-
};
|
|
522
|
-
} else if (isNumber(min)) {
|
|
523
|
-
return {
|
|
524
|
-
type: 'min',
|
|
525
|
-
min
|
|
526
|
-
};
|
|
527
|
-
} else if (isNumber(max)) {
|
|
528
|
-
return {
|
|
529
|
-
type: 'max',
|
|
530
|
-
max
|
|
531
|
-
};
|
|
532
|
-
} else {
|
|
533
|
-
return {
|
|
534
|
-
type: 'max',
|
|
535
|
-
max: fieldType === 'Symbol' ? 256 : 50000
|
|
536
|
-
};
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
function makeChecker(constraint) {
|
|
540
|
-
return function checkConstraint(length) {
|
|
541
|
-
if (constraint.type === 'max') {
|
|
542
|
-
return length <= constraint.max;
|
|
543
|
-
} else if (constraint.type === 'min') {
|
|
544
|
-
return length >= constraint.min;
|
|
545
|
-
} else {
|
|
546
|
-
return length >= constraint.min && length <= constraint.max;
|
|
547
|
-
}
|
|
548
|
-
};
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
var constraints = {
|
|
552
|
-
__proto__: null,
|
|
553
|
-
fromFieldValidations: fromFieldValidations,
|
|
554
|
-
makeChecker: makeChecker
|
|
555
|
-
};
|
|
556
|
-
|
|
557
|
-
/**
|
|
558
|
-
* Checks whether the passed content type matches one of our valid MIME types
|
|
559
|
-
*/
|
|
560
|
-
function isValidImage(file) {
|
|
561
|
-
const validMimeTypes = ['image/avif', 'image/bmp', 'image/x-windows-bmp', 'image/gif', 'image/webp', // This is not a valid MIME type but we supported it in the past.
|
|
562
|
-
'image/jpg', 'image/jpeg', 'image/pjpeg', 'image/x-jps', 'image/png', 'image/svg+xml'];
|
|
563
|
-
return validMimeTypes.includes(file.contentType);
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
/**
|
|
567
|
-
* Transforms a number into a localized string (en-US)
|
|
568
|
-
* toLocaleString(1000); // "1,000"
|
|
569
|
-
* @param {Number} number
|
|
570
|
-
*/
|
|
571
|
-
function toLocaleString(number) {
|
|
572
|
-
return number.toLocaleString('en-US');
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
function formatFloat(value, localize) {
|
|
576
|
-
return localize ? toLocaleString(value) : value.toFixed(2) // remove floating point if not necessary
|
|
577
|
-
.replace(/\.(0)*$|0*$/, '');
|
|
578
|
-
}
|
|
579
|
-
/**
|
|
580
|
-
* Make a storage unit number more readable by making them smaller
|
|
581
|
-
* shortenStorageUnit(1000, 'GB'); // "1 TB"
|
|
582
|
-
* shortenStorageUnit(0.001, 'TB'); // "1 GB"
|
|
583
|
-
* @param value
|
|
584
|
-
* @param uom Unit of measure
|
|
585
|
-
* @returns
|
|
586
|
-
*/
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
function shortenStorageUnit(value, uom) {
|
|
590
|
-
if (value <= 0) {
|
|
591
|
-
return '0 B';
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
const units = ['PB', 'TB', 'GB', 'MB', 'KB', 'B'];
|
|
595
|
-
|
|
596
|
-
const getBigger = unit => units[units.indexOf(unit) - 1];
|
|
597
|
-
|
|
598
|
-
const getSmaller = unit => units[units.indexOf(unit) + 1];
|
|
599
|
-
|
|
600
|
-
const isBiggestUnit = unit => units.indexOf(unit) === 0;
|
|
601
|
-
|
|
602
|
-
const isSmallestUnit = unit => units.indexOf(unit) === units.length - 1;
|
|
603
|
-
|
|
604
|
-
const reduce = (number, unit) => {
|
|
605
|
-
if (number < 0.99 && !isSmallestUnit(unit)) {
|
|
606
|
-
return reduce(number * 1000, getSmaller(unit));
|
|
607
|
-
} else if (number >= 1000 && !isBiggestUnit(unit)) {
|
|
608
|
-
return reduce(number / 1000, getBigger(unit));
|
|
609
|
-
} else {
|
|
610
|
-
return {
|
|
611
|
-
number,
|
|
612
|
-
unit
|
|
613
|
-
};
|
|
614
|
-
}
|
|
615
|
-
};
|
|
616
|
-
|
|
617
|
-
const {
|
|
618
|
-
number,
|
|
619
|
-
unit
|
|
620
|
-
} = reduce(value, uom);
|
|
621
|
-
return `${formatFloat(number, false)} ${unit}`;
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
exports.CharCounter = CharCounter;
|
|
625
|
-
exports.CharValidation = CharValidation;
|
|
626
|
-
exports.ConstraintsUtils = constraints;
|
|
627
|
-
exports.FieldConnector = FieldConnector;
|
|
628
|
-
exports.ModalDialogLauncher = ModalDialogLauncher$1;
|
|
629
|
-
exports.PredefinedValuesError = PredefinedValuesError;
|
|
630
|
-
exports.entityHelpers = entityHelpers;
|
|
631
|
-
exports.isValidImage = isValidImage;
|
|
632
|
-
exports.shortenStorageUnit = shortenStorageUnit;
|
|
633
|
-
exports.toLocaleString = toLocaleString;
|
|
634
|
-
//# sourceMappingURL=field-editor-shared.cjs.development.js.map
|