From 1f40b68108bcb9b03717bbe9f2bbb6b09a6e80bd Mon Sep 17 00:00:00 2001 From: kolaente Date: Wed, 22 Feb 2023 11:04:31 +0100 Subject: [PATCH] fix(filter): validate title before creating or editing a filter Resolves #3152 --- src/i18n/lang/en.json | 3 ++- src/services/savedFilter.ts | 25 +++++++++++++++++++++++++ src/views/filters/FilterEdit.vue | 18 +++++++++++------- src/views/filters/FilterNew.vue | 12 ++++++++---- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/i18n/lang/en.json b/src/i18n/lang/en.json index 2f5963a4a9..111cb1607e 100644 --- a/src/i18n/lang/en.json +++ b/src/i18n/lang/en.json @@ -405,7 +405,8 @@ "create": { "title": "New Saved Filter", "description": "A saved filter is a virtual list which is computed from a set of filters each time it is accessed. Once created, it will appear in a special namespace.", - "action": "Create new saved filter" + "action": "Create new saved filter", + "titleRequired": "Please provide a title for the filter." }, "delete": { "header": "Delete this saved filter", diff --git a/src/services/savedFilter.ts b/src/services/savedFilter.ts index 6c12f8182c..5bc89f0056 100644 --- a/src/services/savedFilter.ts +++ b/src/services/savedFilter.ts @@ -2,6 +2,7 @@ import {computed, ref, shallowReactive, unref, watch} from 'vue' import {useRouter} from 'vue-router' import {useI18n} from 'vue-i18n' import type {MaybeRef} from '@vueuse/core' +import {useDebounceFn} from '@vueuse/core' import type {IList} from '@/modelTypes/IList' import type {ISavedFilter} from '@/modelTypes/ISavedFilter' @@ -133,14 +134,38 @@ export function useSavedFilter(listId?: MaybeRef) { router.push({name: 'namespaces.index'}) } + const titleValid = ref(true) + const validateTitleField = useDebounceFn(() => { + titleValid.value = filter.value.title !== '' + }, 100) + + async function createFilterWithValidation() { + if (!titleValid.value) { + return + } + return createFilter() + } + + async function saveFilterWithValidation() { + if (!titleValid.value) { + return + } + return saveFilter() + } + return { createFilter, + createFilterWithValidation, saveFilter, + saveFilterWithValidation, deleteFilter, filter, filters, filterService, + + titleValid, + validateTitleField, } } \ No newline at end of file diff --git a/src/views/filters/FilterEdit.vue b/src/views/filters/FilterEdit.vue index 51d9551d2c..1bcd23ecbb 100644 --- a/src/views/filters/FilterEdit.vue +++ b/src/views/filters/FilterEdit.vue @@ -3,25 +3,27 @@ :title="$t('filters.edit.title')" primary-icon="" :primary-label="$t('misc.save')" - @primary="saveFilter" + @primary="saveFilterWithValidation" :tertiary="$t('misc.delete')" @tertiary="$router.push({ name: 'filter.settings.delete', params: { id: listId } })" > -
+
+ @focusout="validateTitleField" + />
+

{{ $t('filters.create.titleRequired') }}

@@ -65,9 +67,11 @@ import type {IList} from '@/modelTypes/IList' const props = defineProps<{ listId: IList['id'] }>() const { - saveFilter, + saveFilterWithValidation, filter, filters, filterService, + titleValid, + validateTitleField, } = useSavedFilter(toRef(props, 'listId')) diff --git a/src/views/filters/FilterNew.vue b/src/views/filters/FilterNew.vue index fe57d5e0d6..4a54af3ce6 100644 --- a/src/views/filters/FilterNew.vue +++ b/src/views/filters/FilterNew.vue @@ -12,15 +12,17 @@
+

{{ $t('filters.create.titleRequired') }}

@@ -51,8 +53,8 @@