From cc704dd53a687271157c9010fc3983a4da0453db Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" <70410625+michael-s-molina@users.noreply.github.com> Date: Fri, 30 Jul 2021 11:59:36 -0300 Subject: [PATCH] fix: Cancel alert is not appearing to all native filters modal fields (#15925) --- .../nativeFilters/NativeFiltersModal_spec.tsx | 14 +----- .../FiltersConfigForm/FiltersConfigForm.tsx | 48 +++++++++++++++---- .../FiltersConfigModal/FiltersConfigModal.tsx | 8 ++-- .../FiltersConfigModal/Footer/Footer.tsx | 27 +---------- .../nativeFilters/FiltersConfigModal/types.ts | 1 + 5 files changed, 48 insertions(+), 50 deletions(-) diff --git a/superset-frontend/spec/javascripts/dashboard/components/nativeFilters/NativeFiltersModal_spec.tsx b/superset-frontend/spec/javascripts/dashboard/components/nativeFilters/NativeFiltersModal_spec.tsx index 5c35510967..7fc0d7e2c7 100644 --- a/superset-frontend/spec/javascripts/dashboard/components/nativeFilters/NativeFiltersModal_spec.tsx +++ b/superset-frontend/spec/javascripts/dashboard/components/nativeFilters/NativeFiltersModal_spec.tsx @@ -119,22 +119,12 @@ describe('FiltersConfigModal', () => { expect(onCancel.mock.calls).toHaveLength(1); }); - it('shows correct alert message for an unsaved filter', async () => { + it('shows correct alert message for unsaved filters', async () => { addFilter(); await clickCancel(); expect(onCancel.mock.calls).toHaveLength(0); expect(wrapper.find(Alert).text()).toContain( - 'Are you sure you want to cancel? "New filter" will not be saved.', - ); - }); - - it('shows correct alert message for 2 unsaved filters', async () => { - addFilter(); - addFilter(); - await clickCancel(); - expect(onCancel.mock.calls).toHaveLength(0); - expect(wrapper.find(Alert).text()).toContain( - 'Are you sure you want to cancel? "New filter" and "New filter" will not be saved.', + 'There are unsaved changes.', ); }); }); diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx index a41cb4670d..c07d8583e4 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx @@ -44,6 +44,7 @@ import React, { useState, } from 'react'; import { useSelector } from 'react-redux'; +import { isEqual } from 'lodash'; import { FormItem } from 'src/components/Form'; import { Input } from 'src/common/components'; import { Select } from 'src/components'; @@ -525,9 +526,21 @@ const FiltersConfigForm = ( showDataset, ]); + const formChanged = useCallback(() => { + form.setFields([ + { + name: 'changed', + value: true, + }, + ]); + }, [form]); + const updateFormValues = useCallback( - (values: any) => setNativeFilterFieldValues(form, filterId, values), - [filterId, form], + (values: any) => { + setNativeFilterFieldValues(form, filterId, values); + formChanged(); + }, + [filterId, form, formChanged], ); const parentFilterOptions = parentFilters.map(filter => ({ @@ -589,6 +602,11 @@ const FiltersConfigForm = ( formFilter?.filterType === 'filter_select' || formFilter?.filterType === 'filter_range'; + const initialDefaultValue = + formFilter.filterType === filterToEdit?.filterType + ? filterToEdit?.defaultDataMask + : null; + const preFilterValidator = () => { if (hasTimeRange || hasAdhoc) { return Promise.resolve(); @@ -784,16 +802,15 @@ const FiltersConfigForm = ( disabled={isRequired || defaultToFirstItem} tooltip={defaultValueTooltip} checked={hasDefaultValue} - onChange={value => setHasDefaultValue(value)} + onChange={value => { + setHasDefaultValue(value); + formChanged(); + }} > {formFilter.filterType && ( {t('Default Value')}} required={hasDefaultValue} @@ -820,6 +837,14 @@ const FiltersConfigForm = ( { + if ( + !isEqual( + initialDefaultValue?.filterState?.value, + dataMask?.filterState?.value, + ) + ) { + formChanged(); + } setNativeFilterFieldValues(form, filterId, { defaultDataMask: dataMask, }); @@ -862,6 +887,7 @@ const FiltersConfigForm = ( title={t('Filter is hierarchical')} initialValue={hasParentFilter} onChange={checked => { + formChanged(); if (checked) { // execute after render setTimeout( @@ -900,6 +926,7 @@ const FiltersConfigForm = ( title={t('Pre-filter available values')} initialValue={hasPreFilter} onChange={checked => { + formChanged(); if (checked) { validatePreFilter(); } @@ -1000,7 +1027,10 @@ const FiltersConfigForm = ( {formFilter?.filterType !== 'filter_range' && ( onSortChanged(checked || undefined)} + onChange={checked => { + onSortChanged(checked || undefined); + formChanged(); + }} initialValue={hasSorting} > @@ -212,6 +212,7 @@ export function FiltersConfigModal({ onSave, values, )(); + resetForm(); } else { configFormRef.current.changeTab('configuration'); } @@ -223,7 +224,8 @@ export function FiltersConfigModal({ }; const handleCancel = () => { - if (unsavedFiltersIds.length > 0) { + const changed = form.getFieldValue('changed'); + if (unsavedFiltersIds.length > 0 || form.isFieldsTouched() || changed) { setSaveAlertVisible(true); } else { handleConfirmCancel(); @@ -245,10 +247,8 @@ export function FiltersConfigModal({