@contentful/field-editor-slug 2.1.4 → 2.1.5-canary.5
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/SlugEditor.js +4 -1
- package/dist/cjs/SlugEditor.test.js +35 -0
- package/dist/cjs/SlugEditorField.js +11 -3
- package/dist/esm/SlugEditor.js +4 -1
- package/dist/esm/SlugEditor.test.js +35 -0
- package/dist/esm/SlugEditorField.js +11 -3
- package/dist/types/SlugEditorField.d.ts +1 -0
- package/package.json +2 -2
package/dist/cjs/SlugEditor.js
CHANGED
|
@@ -56,7 +56,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
56
56
|
function isSupportedFieldTypes(val) {
|
|
57
57
|
return val === 'Symbol';
|
|
58
58
|
}
|
|
59
|
-
function FieldConnectorCallback({ Component, value, disabled, setValue, errors, titleValue, isOptionalLocaleWithFallback, locale, createdAt, performUniqueCheck, id }) {
|
|
59
|
+
function FieldConnectorCallback({ Component, value, disabled, setValue, errors, titleValue, isOptionalLocaleWithFallback, locale, createdAt, performUniqueCheck, isUniqueValidationEnabled, id }) {
|
|
60
60
|
const safeSetValue = _react.useCallback(async (...args)=>{
|
|
61
61
|
try {
|
|
62
62
|
await setValue(...args);
|
|
@@ -70,6 +70,7 @@ function FieldConnectorCallback({ Component, value, disabled, setValue, errors,
|
|
|
70
70
|
locale: locale,
|
|
71
71
|
createdAt: createdAt,
|
|
72
72
|
performUniqueCheck: performUniqueCheck,
|
|
73
|
+
isUniqueValidationEnabled: isUniqueValidationEnabled,
|
|
73
74
|
hasError: errors.length > 0,
|
|
74
75
|
value: value,
|
|
75
76
|
isOptionalLocaleWithFallback: isOptionalLocaleWithFallback,
|
|
@@ -87,6 +88,7 @@ function SlugEditor(props) {
|
|
|
87
88
|
}
|
|
88
89
|
const trackingFieldId = parameters?.instance?.trackingFieldId ?? undefined;
|
|
89
90
|
const entrySys = entry.getSys();
|
|
91
|
+
const isUniqueValidationEnabled = (field.validations || []).some((validation)=>'unique' in validation && validation.unique === true);
|
|
90
92
|
const isLocaleOptional = locales.optional[field.locale];
|
|
91
93
|
const localeFallbackCode = locales.fallbacks[field.locale];
|
|
92
94
|
const isOptionalFieldLocale = Boolean(!field.required || isLocaleOptional);
|
|
@@ -135,6 +137,7 @@ function SlugEditor(props) {
|
|
|
135
137
|
createdAt: entrySys.createdAt,
|
|
136
138
|
locale: field.locale,
|
|
137
139
|
performUniqueCheck: performUniqueCheck,
|
|
140
|
+
isUniqueValidationEnabled: isUniqueValidationEnabled,
|
|
138
141
|
key: `slug-editor-${externalReset}`,
|
|
139
142
|
id: id
|
|
140
143
|
});
|
|
@@ -60,6 +60,11 @@ function createMocks(initialValues = {}) {
|
|
|
60
60
|
const [field] = (0, _fieldeditortestutils.createFakeFieldAPI)((field)=>({
|
|
61
61
|
...field,
|
|
62
62
|
id: 'slug-id',
|
|
63
|
+
validations: [
|
|
64
|
+
{
|
|
65
|
+
unique: true
|
|
66
|
+
}
|
|
67
|
+
],
|
|
63
68
|
onValueChanged: jest.fn().mockImplementation(field.onValueChanged),
|
|
64
69
|
setValue: jest.fn().mockImplementation(field.setValue)
|
|
65
70
|
}), initialValues.field || '');
|
|
@@ -269,6 +274,36 @@ describe('SlugEditor', ()=>{
|
|
|
269
274
|
expect(queryByText('This slug has already been published in another entry')).not.toBeInTheDocument();
|
|
270
275
|
});
|
|
271
276
|
});
|
|
277
|
+
it('shows warning instead of error when unique validation is disabled on content model', async ()=>{
|
|
278
|
+
const { field, sdk } = createMocks({
|
|
279
|
+
titleField: 'Slug value',
|
|
280
|
+
field: 'slug-value'
|
|
281
|
+
});
|
|
282
|
+
field.validations = [];
|
|
283
|
+
sdk.entry.getSys.mockReturnValue({
|
|
284
|
+
id: 'entry-id',
|
|
285
|
+
publishedVersion: undefined,
|
|
286
|
+
contentType: {
|
|
287
|
+
sys: {
|
|
288
|
+
id: 'content-type-id'
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
sdk.cma.entry.getMany.mockResolvedValue({
|
|
293
|
+
total: 2
|
|
294
|
+
});
|
|
295
|
+
const { queryByText, getByTestId } = (0, _react1.render)(/*#__PURE__*/ _react.createElement(_SlugEditor.SlugEditor, {
|
|
296
|
+
field: field,
|
|
297
|
+
baseSdk: sdk,
|
|
298
|
+
isInitiallyDisabled: false
|
|
299
|
+
}));
|
|
300
|
+
await (0, _react1.waitFor)(()=>{
|
|
301
|
+
expect(sdk.cma.entry.getMany).toHaveBeenCalledTimes(1);
|
|
302
|
+
expect(queryByText('Warning: This slug has already been published in another entry. Enable "Unique" validation in the content model to enforce this as an error.')).toBeInTheDocument();
|
|
303
|
+
expect(queryByText('This slug has already been published in another entry')).not.toBeInTheDocument();
|
|
304
|
+
expect(getByTestId('cf-ui-text-input')).not.toHaveAttribute('aria-invalid');
|
|
305
|
+
});
|
|
306
|
+
});
|
|
272
307
|
});
|
|
273
308
|
describe('should react to title changes', ()=>{
|
|
274
309
|
it('when field is disabled', async ()=>{
|
|
@@ -110,15 +110,17 @@ function useUniqueChecker(props) {
|
|
|
110
110
|
return status;
|
|
111
111
|
}
|
|
112
112
|
function SlugEditorFieldStatic(props) {
|
|
113
|
-
const { hasError, isDisabled, value, setValue, onChange, onBlur, id } = props;
|
|
113
|
+
const { hasError, isDisabled, value, setValue, onChange, onBlur, isUniqueValidationEnabled, id } = props;
|
|
114
114
|
const status = useUniqueChecker(props);
|
|
115
|
+
const hasDuplicate = status === 'duplicate';
|
|
116
|
+
const shouldShowDuplicateAsError = hasDuplicate && isUniqueValidationEnabled;
|
|
115
117
|
return /*#__PURE__*/ _react.createElement("div", {
|
|
116
118
|
className: _styles.inputContainer
|
|
117
119
|
}, /*#__PURE__*/ _react.createElement(_f36icons.LinkSimpleIcon, {
|
|
118
120
|
className: _styles.icon
|
|
119
121
|
}), /*#__PURE__*/ _react.createElement(_f36components.TextInput, {
|
|
120
122
|
className: _styles.input,
|
|
121
|
-
isInvalid: hasError ||
|
|
123
|
+
isInvalid: hasError || shouldShowDuplicateAsError,
|
|
122
124
|
isDisabled: isDisabled,
|
|
123
125
|
value: value || '',
|
|
124
126
|
id: id,
|
|
@@ -137,12 +139,18 @@ function SlugEditorFieldStatic(props) {
|
|
|
137
139
|
className: _styles.spinnerContainer
|
|
138
140
|
}, /*#__PURE__*/ _react.createElement(_f36components.Spinner, {
|
|
139
141
|
testId: "slug-editor-spinner"
|
|
140
|
-
})),
|
|
142
|
+
})), hasDuplicate && isUniqueValidationEnabled && /*#__PURE__*/ _react.createElement(_f36components.ValidationMessage, {
|
|
141
143
|
testId: "slug-editor-duplicate-error",
|
|
142
144
|
className: _styles.uniqueValidationError
|
|
143
145
|
}, _core.i18n._({
|
|
144
146
|
id: "FieldEditors.Slug.SlugEditorField.DuplicateSlugError",
|
|
145
147
|
message: "This slug has already been published in another entry"
|
|
148
|
+
})), hasDuplicate && !isUniqueValidationEnabled && /*#__PURE__*/ _react.createElement(_f36components.ValidationMessage, {
|
|
149
|
+
testId: "slug-editor-duplicate-warning",
|
|
150
|
+
className: _styles.uniqueValidationError
|
|
151
|
+
}, _core.i18n._({
|
|
152
|
+
id: "FieldEditors.Slug.SlugEditorField.DuplicateSlugWarning",
|
|
153
|
+
message: 'Warning: This slug has already been published in another entry. Enable "Unique" validation in the content model to enforce this as an error.'
|
|
146
154
|
})));
|
|
147
155
|
}
|
|
148
156
|
function SlugEditorField(props) {
|
package/dist/esm/SlugEditor.js
CHANGED
|
@@ -5,7 +5,7 @@ import { TrackingFieldConnector } from './TrackingFieldConnector';
|
|
|
5
5
|
function isSupportedFieldTypes(val) {
|
|
6
6
|
return val === 'Symbol';
|
|
7
7
|
}
|
|
8
|
-
function FieldConnectorCallback({ Component, value, disabled, setValue, errors, titleValue, isOptionalLocaleWithFallback, locale, createdAt, performUniqueCheck, id }) {
|
|
8
|
+
function FieldConnectorCallback({ Component, value, disabled, setValue, errors, titleValue, isOptionalLocaleWithFallback, locale, createdAt, performUniqueCheck, isUniqueValidationEnabled, id }) {
|
|
9
9
|
const safeSetValue = React.useCallback(async (...args)=>{
|
|
10
10
|
try {
|
|
11
11
|
await setValue(...args);
|
|
@@ -19,6 +19,7 @@ function FieldConnectorCallback({ Component, value, disabled, setValue, errors,
|
|
|
19
19
|
locale: locale,
|
|
20
20
|
createdAt: createdAt,
|
|
21
21
|
performUniqueCheck: performUniqueCheck,
|
|
22
|
+
isUniqueValidationEnabled: isUniqueValidationEnabled,
|
|
22
23
|
hasError: errors.length > 0,
|
|
23
24
|
value: value,
|
|
24
25
|
isOptionalLocaleWithFallback: isOptionalLocaleWithFallback,
|
|
@@ -36,6 +37,7 @@ export function SlugEditor(props) {
|
|
|
36
37
|
}
|
|
37
38
|
const trackingFieldId = parameters?.instance?.trackingFieldId ?? undefined;
|
|
38
39
|
const entrySys = entry.getSys();
|
|
40
|
+
const isUniqueValidationEnabled = (field.validations || []).some((validation)=>'unique' in validation && validation.unique === true);
|
|
39
41
|
const isLocaleOptional = locales.optional[field.locale];
|
|
40
42
|
const localeFallbackCode = locales.fallbacks[field.locale];
|
|
41
43
|
const isOptionalFieldLocale = Boolean(!field.required || isLocaleOptional);
|
|
@@ -84,6 +86,7 @@ export function SlugEditor(props) {
|
|
|
84
86
|
createdAt: entrySys.createdAt,
|
|
85
87
|
locale: field.locale,
|
|
86
88
|
performUniqueCheck: performUniqueCheck,
|
|
89
|
+
isUniqueValidationEnabled: isUniqueValidationEnabled,
|
|
87
90
|
key: `slug-editor-${externalReset}`,
|
|
88
91
|
id: id
|
|
89
92
|
});
|
|
@@ -15,6 +15,11 @@ function createMocks(initialValues = {}) {
|
|
|
15
15
|
const [field] = createFakeFieldAPI((field)=>({
|
|
16
16
|
...field,
|
|
17
17
|
id: 'slug-id',
|
|
18
|
+
validations: [
|
|
19
|
+
{
|
|
20
|
+
unique: true
|
|
21
|
+
}
|
|
22
|
+
],
|
|
18
23
|
onValueChanged: jest.fn().mockImplementation(field.onValueChanged),
|
|
19
24
|
setValue: jest.fn().mockImplementation(field.setValue)
|
|
20
25
|
}), initialValues.field || '');
|
|
@@ -224,6 +229,36 @@ describe('SlugEditor', ()=>{
|
|
|
224
229
|
expect(queryByText('This slug has already been published in another entry')).not.toBeInTheDocument();
|
|
225
230
|
});
|
|
226
231
|
});
|
|
232
|
+
it('shows warning instead of error when unique validation is disabled on content model', async ()=>{
|
|
233
|
+
const { field, sdk } = createMocks({
|
|
234
|
+
titleField: 'Slug value',
|
|
235
|
+
field: 'slug-value'
|
|
236
|
+
});
|
|
237
|
+
field.validations = [];
|
|
238
|
+
sdk.entry.getSys.mockReturnValue({
|
|
239
|
+
id: 'entry-id',
|
|
240
|
+
publishedVersion: undefined,
|
|
241
|
+
contentType: {
|
|
242
|
+
sys: {
|
|
243
|
+
id: 'content-type-id'
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
sdk.cma.entry.getMany.mockResolvedValue({
|
|
248
|
+
total: 2
|
|
249
|
+
});
|
|
250
|
+
const { queryByText, getByTestId } = render(/*#__PURE__*/ React.createElement(SlugEditor, {
|
|
251
|
+
field: field,
|
|
252
|
+
baseSdk: sdk,
|
|
253
|
+
isInitiallyDisabled: false
|
|
254
|
+
}));
|
|
255
|
+
await waitFor(()=>{
|
|
256
|
+
expect(sdk.cma.entry.getMany).toHaveBeenCalledTimes(1);
|
|
257
|
+
expect(queryByText('Warning: This slug has already been published in another entry. Enable "Unique" validation in the content model to enforce this as an error.')).toBeInTheDocument();
|
|
258
|
+
expect(queryByText('This slug has already been published in another entry')).not.toBeInTheDocument();
|
|
259
|
+
expect(getByTestId('cf-ui-text-input')).not.toHaveAttribute('aria-invalid');
|
|
260
|
+
});
|
|
261
|
+
});
|
|
227
262
|
});
|
|
228
263
|
describe('should react to title changes', ()=>{
|
|
229
264
|
it('when field is disabled', async ()=>{
|
|
@@ -51,15 +51,17 @@ function useUniqueChecker(props) {
|
|
|
51
51
|
return status;
|
|
52
52
|
}
|
|
53
53
|
export function SlugEditorFieldStatic(props) {
|
|
54
|
-
const { hasError, isDisabled, value, setValue, onChange, onBlur, id } = props;
|
|
54
|
+
const { hasError, isDisabled, value, setValue, onChange, onBlur, isUniqueValidationEnabled, id } = props;
|
|
55
55
|
const status = useUniqueChecker(props);
|
|
56
|
+
const hasDuplicate = status === 'duplicate';
|
|
57
|
+
const shouldShowDuplicateAsError = hasDuplicate && isUniqueValidationEnabled;
|
|
56
58
|
return /*#__PURE__*/ React.createElement("div", {
|
|
57
59
|
className: styles.inputContainer
|
|
58
60
|
}, /*#__PURE__*/ React.createElement(LinkSimpleIcon, {
|
|
59
61
|
className: styles.icon
|
|
60
62
|
}), /*#__PURE__*/ React.createElement(TextInput, {
|
|
61
63
|
className: styles.input,
|
|
62
|
-
isInvalid: hasError ||
|
|
64
|
+
isInvalid: hasError || shouldShowDuplicateAsError,
|
|
63
65
|
isDisabled: isDisabled,
|
|
64
66
|
value: value || '',
|
|
65
67
|
id: id,
|
|
@@ -78,12 +80,18 @@ export function SlugEditorFieldStatic(props) {
|
|
|
78
80
|
className: styles.spinnerContainer
|
|
79
81
|
}, /*#__PURE__*/ React.createElement(Spinner, {
|
|
80
82
|
testId: "slug-editor-spinner"
|
|
81
|
-
})),
|
|
83
|
+
})), hasDuplicate && isUniqueValidationEnabled && /*#__PURE__*/ React.createElement(ValidationMessage, {
|
|
82
84
|
testId: "slug-editor-duplicate-error",
|
|
83
85
|
className: styles.uniqueValidationError
|
|
84
86
|
}, $_i18n._({
|
|
85
87
|
id: "FieldEditors.Slug.SlugEditorField.DuplicateSlugError",
|
|
86
88
|
message: "This slug has already been published in another entry"
|
|
89
|
+
})), hasDuplicate && !isUniqueValidationEnabled && /*#__PURE__*/ React.createElement(ValidationMessage, {
|
|
90
|
+
testId: "slug-editor-duplicate-warning",
|
|
91
|
+
className: styles.uniqueValidationError
|
|
92
|
+
}, $_i18n._({
|
|
93
|
+
id: "FieldEditors.Slug.SlugEditorField.DuplicateSlugWarning",
|
|
94
|
+
message: 'Warning: This slug has already been published in another entry. Enable "Unique" validation in the content model to enforce this as an error.'
|
|
87
95
|
})));
|
|
88
96
|
}
|
|
89
97
|
export function SlugEditorField(props) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/field-editor-slug",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.5-canary.5+5ade548d",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
5
|
"module": "dist/esm/index.js",
|
|
6
6
|
"types": "dist/types/index.d.ts",
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
"publishConfig": {
|
|
59
59
|
"registry": "https://npm.pkg.github.com/"
|
|
60
60
|
},
|
|
61
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "5ade548d2b5bb4c897943a157e570fbe6dffeadb"
|
|
62
62
|
}
|