From 84c397b6ae2d2589415be01cf364b9371b70b781 Mon Sep 17 00:00:00 2001 From: Dfdez Date: Fri, 11 Apr 2025 19:21:10 +0200 Subject: [PATCH] feat: add negative pattern feature --- .../Editor/EditorControlPane/Widget.js | 28 +++++++++++++++++-- .../src/constants/configSchema.js | 5 ++++ packages/decap-cms-locales/src/en/index.js | 3 +- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/packages/decap-cms-core/src/components/Editor/EditorControlPane/Widget.js b/packages/decap-cms-core/src/components/Editor/EditorControlPane/Widget.js index 6d0bcac29050..2c6cc3249b22 100644 --- a/packages/decap-cms-core/src/components/Editor/EditorControlPane/Widget.js +++ b/packages/decap-cms-core/src/components/Editor/EditorControlPane/Widget.js @@ -127,7 +127,7 @@ export default class Widget extends Component { const value = this.getValidateValue(); const field = this.props.field; const errors = []; - const validations = [this.validatePresence, this.validatePattern]; + const validations = [this.validatePresence, this.validatePattern, this.validateNegativePattern]; if (field.get('meta')) { validations.push(this.props.validateMetaField); } @@ -186,6 +186,30 @@ export default class Widget extends Component { return { error: false }; }; + validateNegativePattern = (field, value) => { + const { t, parentIds } = this.props; + const negativePattern = field.get('negative_pattern', false); + + if (isEmpty(value)) { + return { error: false }; + } + + if (negativePattern && RegExp(negativePattern.first()).test(value)) { + const error = { + type: ValidationErrorTypes.PATTERN, + parentIds, + message: t('editor.editorControlPane.widget.regexNegativePattern', { + fieldLabel: field.get('label', field.get('name')), + pattern: negativePattern.last(), + }), + }; + + return { error }; + } + + return { error: false }; + }; + validateWrappedControl = field => { const { t, parentIds } = this.props; if (typeof this.wrappedControlValid !== 'function') { @@ -255,7 +279,7 @@ export default class Widget extends Component { setInactiveStyle = () => { this.props.setInactiveStyle(); - if (this.props.field.has('pattern') && !isEmpty(this.getValidateValue())) { + if ((this.props.field.has('pattern') || this.props.field.has('negative_pattern')) && !isEmpty(this.getValidateValue())) { this.validate(); } }; diff --git a/packages/decap-cms-core/src/constants/configSchema.js b/packages/decap-cms-core/src/constants/configSchema.js index 5efd2cd4c172..3d0cc81cfda6 100644 --- a/packages/decap-cms-core/src/constants/configSchema.js +++ b/packages/decap-cms-core/src/constants/configSchema.js @@ -66,6 +66,11 @@ function fieldsConfig() { minItems: 2, items: [{ oneOf: [{ type: 'string' }, { instanceof: 'RegExp' }] }, { type: 'string' }], }, + negative_pattern: { + type: 'array', + minItems: 2, + items: [{ oneOf: [{ type: 'string' }, { instanceof: 'RegExp' }] }, { type: 'string' }], + }, field: { $ref: `field_${id}` }, fields: { $ref: `fields_${id}` }, types: { $ref: `fields_${id}` }, diff --git a/packages/decap-cms-locales/src/en/index.js b/packages/decap-cms-locales/src/en/index.js index ede9afcb9294..c75762c44b55 100644 --- a/packages/decap-cms-locales/src/en/index.js +++ b/packages/decap-cms-locales/src/en/index.js @@ -80,6 +80,7 @@ const en = { widget: { required: '%{fieldLabel} is required.', regexPattern: "%{fieldLabel} didn't match the pattern: %{pattern}.", + regexNegativePattern: "%{fieldLabel} should not contain pattern: %{pattern}.", processing: '%{fieldLabel} is processing.', range: '%{fieldLabel} must be between %{minValue} and %{maxValue}.', min: '%{fieldLabel} must be at least %{minValue}.', @@ -139,7 +140,7 @@ const en = { saving: 'Saving...', save: 'Save', statusInfoTooltipDraft: - 'Entry status is set to draft. To finalize and submit it for review, set the status to ‘In review’', + 'Entry status is set to draft. To finalize and submit it for review, set the status to "In review"', statusInfoTooltipInReview: 'Entry is being reviewed, no further actions are required. However, you can still make additional changes while it is being reviewed.', discarding: 'Discarding...',