From 9865da3844674e560e9f87c07ce65ad025afb12f Mon Sep 17 00:00:00 2001 From: Navarone Feekery <13634519+navarone-feekery@users.noreply.github.com> Date: Fri, 27 Dec 2024 12:22:19 +0100 Subject: [PATCH] [Search][a11y] Add validation to extraction rules form (#202980) ## Closes: https://github.com/elastic/kibana/issues/199154 This adds more validations to the Crawler extraction rules form. The original issue of the error being at the top of the page is not easily fixable, as it's a catch-all server error display. Ideally, we shouldn't have server errors occurring at all, so it makes sense to me to just add a front-end validation to the inputs in this field. These validations cover the following previously-missed scenarios: 1. When a user has not added any rules 2. When rule is for a specific URL and the URL pattern field is empty, or doesn't begin with `/` 3. When the value for "Source" is empty (covers both HTML element and URL selectors) 4. When "Content" is "A fixed value" and the value field is empty --- .../extraction_rules/edit_extraction_rule.tsx | 30 ++++++- .../edit_field_rule_flyout.tsx | 79 +++++++++++++------ 2 files changed, 81 insertions(+), 28 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/extraction_rules/edit_extraction_rule.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/extraction_rules/edit_extraction_rule.tsx index fa69e05bd65fd..c32e495f3f889 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/extraction_rules/edit_extraction_rule.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/extraction_rules/edit_extraction_rule.tsx @@ -298,9 +298,34 @@ export const EditExtractionRule: React.FC = ({ ( + rules={{ + validate: (rule) => { + if (!rule?.trim()) { + return i18n.translate( + 'xpack.enterpriseSearch.content.indices.extractionRules.editContentField.fieldInput.requiredError', + { + defaultMessage: 'A value is required.', + } + ); + } + + if (rule[0] !== '/') { + return i18n.translate( + 'xpack.enterpriseSearch.content.indices.extractionRules.editContentField.fieldInput.slashMissingError', + { + defaultMessage: 'Value must begin with a /.', + } + ); + } + + return true; + }, + }} + render={({ field, fieldState: { error, isTouched } }) => ( <> = ({ = ({ data-telemetry-id="entSearchContent-crawler-domainDetail-extractionRules-saveExtractionRule" type="submit" onClick={() => saveRule({ ...getValues() })} - disabled={!formState.isValid} + disabled={!formState.isValid || !rulesFields || rulesFields.length === 0} > {i18n.translate( 'xpack.enterpriseSearch.content.indices.extractionRules.editRule.saveButtonLabel', diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/extraction_rules/edit_field_rule_flyout.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/extraction_rules/edit_field_rule_flyout.tsx index 6dbda38ab1137..b8940cb77468f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/extraction_rules/edit_field_rule_flyout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/extraction_rules/edit_field_rule_flyout.tsx @@ -228,28 +228,39 @@ export const EditFieldRuleFlyout: React.FC = ({ {!!field.value && ( <> - - ( + + !!rule?.trim() || + i18n.translate( + 'xpack.enterpriseSearch.content.indices.extractionRules.editContentField.fieldInput.requiredError', + { + defaultMessage: 'A value is required.', + } + ), + }} + render={({ field: selectorField, fieldState: { error, isTouched } }) => ( + = ({ onChange={selectorField.onChange} value={selectorField.value ?? ''} /> - )} - /> - + + )} + /> {field.value === FieldType.HTML ? ( = ({ ( + rules={{ + validate: (rule) => + !!rule?.trim() || + i18n.translate( + 'xpack.enterpriseSearch.content.indices.extractionRules.editContentField.contentFixedValue.requiredError', + { + defaultMessage: 'A value is required', + } + ), + }} + render={({ + field: valueField, + fieldState: { error: fieldError, isTouched: fieldIsTouched }, + }) => ( = ({