@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.
@@ -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 || status === 'duplicate',
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
- })), status === 'duplicate' && /*#__PURE__*/ _react.createElement(_f36components.ValidationMessage, {
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) {
@@ -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 || status === 'duplicate',
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
- })), status === 'duplicate' && /*#__PURE__*/ React.createElement(ValidationMessage, {
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) {
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  interface SlugEditorFieldProps {
3
3
  hasError: boolean;
4
+ isUniqueValidationEnabled: boolean;
4
5
  isOptionalLocaleWithFallback: boolean;
5
6
  isDisabled: boolean;
6
7
  value: string | null | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/field-editor-slug",
3
- "version": "2.1.4",
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": "51e565419e82705b2e2db20e136f50c497f1e8e0"
61
+ "gitHead": "5ade548d2b5bb4c897943a157e570fbe6dffeadb"
62
62
  }