From e82de8fcc041c28bbd0a7367bf1d4c2230cb0f19 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Tue, 7 Apr 2020 15:02:16 +0300 Subject: [PATCH 1/3] use validation by clicking on save, added autotrim --- .../ui/saved_query_form/save_query_form.tsx | 58 +++++++++---------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/src/plugins/data/public/ui/saved_query_form/save_query_form.tsx b/src/plugins/data/public/ui/saved_query_form/save_query_form.tsx index 36dcd4a00c05e..17e30b4ec8efd 100644 --- a/src/plugins/data/public/ui/saved_query_form/save_query_form.tsx +++ b/src/plugins/data/public/ui/saved_query_form/save_query_form.tsx @@ -63,6 +63,7 @@ export function SaveQueryForm({ showTimeFilterOption = true, }: Props) { const [title, setTitle] = useState(savedQuery ? savedQuery.title : ''); + const [enabledSaveButton, setEnabledSaveButton] = useState(!!savedQuery); const [description, setDescription] = useState(savedQuery ? savedQuery.description : ''); const [savedQueries, setSavedQueries] = useState([]); const [shouldIncludeFilters, setShouldIncludeFilters] = useState( @@ -98,27 +99,16 @@ export function SaveQueryForm({ defaultMessage: 'Name conflicts with an existing saved query', } ); - const titleMissingErrorText = i18n.translate( - 'data.search.searchBar.savedQueryForm.titleMissingText', - { - defaultMessage: 'Name is required', - } - ); - const whitespaceErrorText = i18n.translate( - 'data.search.searchBar.savedQueryForm.whitespaceErrorText', - { - defaultMessage: 'Name cannot contain leading or trailing whitespace', + + const autoTrim = () => { + const trimmedTitle = title.trim(); + if (title.length > trimmedTitle.length) { + setTitle(trimmedTitle); } - ); + }; const validate = () => { const errors = []; - if (!title.length) { - errors.push(titleMissingErrorText); - } - if (title.length > title.trim().length) { - errors.push(whitespaceErrorText); - } if ( !!savedQueries.find( existingSavedQuery => !savedQuery && existingSavedQuery.attributes.title === title @@ -129,15 +119,14 @@ export function SaveQueryForm({ if (!isEqual(errors, formErrors)) { setFormErrors(errors); + return false; } + + return !formErrors.length; }; const hasErrors = formErrors.length > 0; - if (hasErrors) { - validate(); - } - const saveQueryForm = ( @@ -158,11 +147,16 @@ export function SaveQueryForm({ value={title} name="title" onChange={event => { + if (!event.target.value) { + setEnabledSaveButton(false); + } else { + setEnabledSaveButton(true); + } setTitle(event.target.value); }} data-test-subj="saveQueryFormTitle" isInvalid={hasErrors} - onBlur={validate} + onBlur={autoTrim} /> @@ -235,17 +229,19 @@ export function SaveQueryForm({ - onSave({ - title, - description, - shouldIncludeFilters, - shouldIncludeTimefilter, - }) - } + onClick={() => { + if (validate()) { + onSave({ + title, + description, + shouldIncludeFilters, + shouldIncludeTimefilter, + }); + } + }} fill data-test-subj="savedQueryFormSaveButton" - disabled={hasErrors} + disabled={hasErrors || !enabledSaveButton} > {i18n.translate('data.search.searchBar.savedQueryFormSaveButtonText', { defaultMessage: 'Save', From d53c994c76c397afd1c6b88dd71fb049df33837e Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Tue, 7 Apr 2020 15:23:40 +0300 Subject: [PATCH 2/3] Fixes form errors. --- src/plugins/data/public/ui/saved_query_form/save_query_form.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/data/public/ui/saved_query_form/save_query_form.tsx b/src/plugins/data/public/ui/saved_query_form/save_query_form.tsx index 17e30b4ec8efd..db687dc5cce90 100644 --- a/src/plugins/data/public/ui/saved_query_form/save_query_form.tsx +++ b/src/plugins/data/public/ui/saved_query_form/save_query_form.tsx @@ -152,6 +152,7 @@ export function SaveQueryForm({ } else { setEnabledSaveButton(true); } + setFormErrors([]); setTitle(event.target.value); }} data-test-subj="saveQueryFormTitle" From dc23f177d9493d0f3b745a02d12e85b5fc301052 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Tue, 7 Apr 2020 18:11:55 +0300 Subject: [PATCH 3/3] Fixed comments --- .../ui/saved_query_form/save_query_form.tsx | 88 +++++++++---------- .../translations/translations/ja-JP.json | 2 - .../translations/translations/zh-CN.json | 2 - 3 files changed, 44 insertions(+), 48 deletions(-) diff --git a/src/plugins/data/public/ui/saved_query_form/save_query_form.tsx b/src/plugins/data/public/ui/saved_query_form/save_query_form.tsx index db687dc5cce90..5550ea16c22df 100644 --- a/src/plugins/data/public/ui/saved_query_form/save_query_form.tsx +++ b/src/plugins/data/public/ui/saved_query_form/save_query_form.tsx @@ -17,7 +17,7 @@ * under the License. */ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useCallback } from 'react'; import { EuiButtonEmpty, EuiOverlayMask, @@ -63,7 +63,7 @@ export function SaveQueryForm({ showTimeFilterOption = true, }: Props) { const [title, setTitle] = useState(savedQuery ? savedQuery.title : ''); - const [enabledSaveButton, setEnabledSaveButton] = useState(!!savedQuery); + const [enabledSaveButton, setEnabledSaveButton] = useState(Boolean(savedQuery)); const [description, setDescription] = useState(savedQuery ? savedQuery.description : ''); const [savedQueries, setSavedQueries] = useState([]); const [shouldIncludeFilters, setShouldIncludeFilters] = useState( @@ -77,22 +77,6 @@ export function SaveQueryForm({ ); const [formErrors, setFormErrors] = useState([]); - useEffect(() => { - const fetchQueries = async () => { - const allSavedQueries = await savedQueryService.getAllSavedQueries(); - const sortedAllSavedQueries = sortBy(allSavedQueries, 'attributes.title') as SavedQuery[]; - setSavedQueries(sortedAllSavedQueries); - }; - fetchQueries(); - }, [savedQueryService]); - - const savedQueryDescriptionText = i18n.translate( - 'data.search.searchBar.savedQueryDescriptionText', - { - defaultMessage: 'Save query text and filters that you want to use again.', - } - ); - const titleConflictErrorText = i18n.translate( 'data.search.searchBar.savedQueryForm.titleConflictText', { @@ -100,14 +84,23 @@ export function SaveQueryForm({ } ); - const autoTrim = () => { - const trimmedTitle = title.trim(); - if (title.length > trimmedTitle.length) { - setTitle(trimmedTitle); + const savedQueryDescriptionText = i18n.translate( + 'data.search.searchBar.savedQueryDescriptionText', + { + defaultMessage: 'Save query text and filters that you want to use again.', } - }; + ); + + useEffect(() => { + const fetchQueries = async () => { + const allSavedQueries = await savedQueryService.getAllSavedQueries(); + const sortedAllSavedQueries = sortBy(allSavedQueries, 'attributes.title') as SavedQuery[]; + setSavedQueries(sortedAllSavedQueries); + }; + fetchQueries(); + }, [savedQueryService]); - const validate = () => { + const validate = useCallback(() => { const errors = []; if ( !!savedQueries.find( @@ -123,7 +116,31 @@ export function SaveQueryForm({ } return !formErrors.length; - }; + }, [savedQueries, savedQuery, title, titleConflictErrorText, formErrors]); + + const onClickSave = useCallback(() => { + if (validate()) { + onSave({ + title, + description, + shouldIncludeFilters, + shouldIncludeTimefilter, + }); + } + }, [validate, onSave, title, description, shouldIncludeFilters, shouldIncludeTimefilter]); + + const onInputChange = useCallback(event => { + setEnabledSaveButton(Boolean(event.target.value)); + setFormErrors([]); + setTitle(event.target.value); + }, []); + + const autoTrim = useCallback(() => { + const trimmedTitle = title.trim(); + if (title.length > trimmedTitle.length) { + setTitle(trimmedTitle); + } + }, [title]); const hasErrors = formErrors.length > 0; @@ -146,15 +163,7 @@ export function SaveQueryForm({ disabled={!!savedQuery} value={title} name="title" - onChange={event => { - if (!event.target.value) { - setEnabledSaveButton(false); - } else { - setEnabledSaveButton(true); - } - setFormErrors([]); - setTitle(event.target.value); - }} + onChange={onInputChange} data-test-subj="saveQueryFormTitle" isInvalid={hasErrors} onBlur={autoTrim} @@ -230,16 +239,7 @@ export function SaveQueryForm({ { - if (validate()) { - onSave({ - title, - description, - shouldIncludeFilters, - shouldIncludeTimefilter, - }); - } - }} + onClick={onClickSave} fill data-test-subj="savedQueryFormSaveButton" disabled={hasErrors || !enabledSaveButton} diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 79c1bbc49810b..cb8d226dad752 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -793,8 +793,6 @@ "data.search.searchBar.savedQueryDescriptionLabelText": "説明", "data.search.searchBar.savedQueryDescriptionText": "再度使用するクエリテキストとフィルターを保存します。", "data.search.searchBar.savedQueryForm.titleConflictText": "タイトルが既に保存されているクエリに使用されています", - "data.search.searchBar.savedQueryForm.titleMissingText": "名前が必要です", - "data.search.searchBar.savedQueryForm.whitespaceErrorText": "タイトルの始めと終わりにはスペースを使用できません", "data.search.searchBar.savedQueryFormCancelButtonText": "キャンセル", "data.search.searchBar.savedQueryFormSaveButtonText": "保存", "data.search.searchBar.savedQueryFormTitle": "クエリを保存", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 77bf8f1467783..74dca098b02d6 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -794,8 +794,6 @@ "data.search.searchBar.savedQueryDescriptionLabelText": "描述", "data.search.searchBar.savedQueryDescriptionText": "保存想要再次使用的查询文本和筛选。", "data.search.searchBar.savedQueryForm.titleConflictText": "标题与现有已保存查询有冲突", - "data.search.searchBar.savedQueryForm.titleMissingText": "“名称”必填", - "data.search.searchBar.savedQueryForm.whitespaceErrorText": "标题不能包含前导或尾随空格", "data.search.searchBar.savedQueryFormCancelButtonText": "取消", "data.search.searchBar.savedQueryFormSaveButtonText": "保存", "data.search.searchBar.savedQueryFormTitle": "保存查询",