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 776e1e97e649e..d1cabf9b6c246 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx @@ -17,13 +17,14 @@ * under the License. */ import { - styled, - t, - getChartMetadataRegistry, - Behavior, AdhocFilter, + Behavior, + ChartDataResponseResult, + getChartMetadataRegistry, JsonResponse, + styled, SupersetApiError, + t, } from '@superset-ui/core'; import { ColumnMeta, DatasourceMeta } from '@superset-ui/chart-controls'; import { FormInstance } from 'antd/lib/form'; @@ -38,6 +39,10 @@ import AdhocFilterControl from 'src/explore/components/controls/FilterControl/Ad import DateFilterControl from 'src/explore/components/controls/DateFilterControl'; import { addDangerToast } from 'src/messageToasts/actions'; import { ClientErrorObject } from 'src/utils/getClientErrorObject'; +import Button from 'src/components/Button'; +import { getChartDataRequest } from 'src/chart/chartAction'; +import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags'; +import { waitForAsyncData } from 'src/middleware/asyncEvent'; import { ColumnSelect } from './ColumnSelect'; import { NativeFiltersForm } from '../types'; import { @@ -111,8 +116,22 @@ export const FiltersConfigForm: React.FC = ({ parentFilters, }) => { const forceUpdate = useForceUpdate(); - const formFilter = (form.getFieldValue('filters') || {})[filterId]; const [datasetDetails, setDatasetDetails] = useState>(); + + // make sure the formFilter is populated + if (!form.getFieldValue('filters')) { + setNativeFilterFieldValues(form, filterId, filterToEdit || {}); + forceUpdate(); + } + const formFilter = form.getFieldValue('filters')[filterId]; + + useEffect(() => { + setNativeFilterFieldValues(form, filterId, { + defaultValue: filterToEdit?.defaultValue, + }); + forceUpdate(); + }, [form, forceUpdate, filterId, filterToEdit?.defaultValue]); + const nativeFilterItems = getChartMetadataRegistry().items; const nativeFilterVizTypes = Object.entries(nativeFilterItems) // @ts-ignore @@ -158,7 +177,56 @@ export const FiltersConfigForm: React.FC = ({ formFilter?.filterType, ); - useBackendFormUpdate(form, filterId, filterToEdit, hasDataset, hasColumn); + const isDataDirty = formFilter?.isDataDirty ?? true; + + useBackendFormUpdate(form, filterId); + + const refreshHandler = () => { + if (!hasDataset || !formFilter?.dataset?.value) { + forceUpdate(); + return; + } + const formData = getFormData({ + datasetId: formFilter?.dataset?.value, + groupby: formFilter?.column, + defaultValue: formFilter?.defaultValue, + ...formFilter, + }); + setNativeFilterFieldValues(form, filterId, { + defaultValueQueriesData: null, + isDataDirty: false, + }); + forceUpdate(); + getChartDataRequest({ + formData, + force: false, + requestParams: { dashboardId: 0 }, + }).then(response => { + if (isFeatureEnabled(FeatureFlag.GLOBAL_ASYNC_QUERIES)) { + // deal with getChartDataRequest transforming the response data + const result = 'result' in response ? response.result[0] : response; + waitForAsyncData(result) + .then((asyncResult: ChartDataResponseResult[]) => { + setNativeFilterFieldValues(form, filterId, { + defaultValueQueriesData: asyncResult, + }); + forceUpdate(); + }) + .catch((error: ClientErrorObject) => { + // TODO: show error once this logic is moved into new NativeFilter + // component + console.error( + error.message || error.error || t('Check configuration'), + ); + }); + } else { + setNativeFilterFieldValues(form, filterId, { + defaultValueQueriesData: response.result, + }); + forceUpdate(); + } + }); + }; const defaultDatasetSelectOptions = Object.values(loadedDatasets).map( datasetToSelectOption, @@ -254,6 +322,7 @@ export const FiltersConfigForm: React.FC = ({ // We need reset column when dataset changed if (datasetId && e?.value !== datasetId) { setNativeFilterFieldValues(form, filterId, { + defaultValue: null, column: null, }); } @@ -275,7 +344,13 @@ export const FiltersConfigForm: React.FC = ({ form={form} filterId={filterId} datasetId={datasetId} - onChange={forceUpdate} + onChange={e => { + // We need reset default value when when column changed + setNativeFilterFieldValues(form, filterId, { + defaultValue: null, + }); + forceUpdate(); + }} /> )} @@ -347,27 +422,36 @@ export const FiltersConfigForm: React.FC = ({ isClearable /> - {t('Default Value')}} - > - {(hasFilledDataset || !hasDataset) && ( - { - setNativeFilterFieldValues(form, filterId, { - defaultValue: filterState?.value, - }); - forceUpdate(); - }} - filterId={filterId} - hasDataset={hasDataset} - form={form} - formData={newFormData} - /> - )} - + + }> + {hasDataset && hasFilledDataset && ( + + )} + + {t('Default Value')}} + > + {!isDataDirty && (hasFilledDataset || !hasDataset) && ( + { + setNativeFilterFieldValues(form, filterId, { + defaultValue: filterState?.value, + }); + forceUpdate(); + }} + filterId={filterId} + hasDataset={hasDataset} + form={form} + formData={newFormData} + /> + )} + + , filterId: string, - filterToEdit?: Filter, - hasDatasource?: boolean, - hasColumn?: boolean, ) => { const forceUpdate = useForceUpdate(); const formFilter = (form.getFieldValue('filters') || {})[filterId]; useEffect(() => { - let resolvedDefaultValue: any = null; - if (!hasDatasource) { - forceUpdate(); - return; - } - // No need to check data set change because it cascading update column - // So check that column exists is enough - if (hasColumn && !formFilter?.column) { - setNativeFilterFieldValues(form, filterId, { - defaultValueQueriesData: [], - defaultValue: resolvedDefaultValue, - }); - return; - } - if (!formFilter?.dataset?.value) { - // no need to make chart data request if no dataset is defined - return; - } - const formData = getFormData({ - datasetId: formFilter?.dataset?.value, - groupby: formFilter?.column, - defaultValue: formFilter?.defaultValue, - ...formFilter, - }); setNativeFilterFieldValues(form, filterId, { + isDataDirty: true, defaultValueQueriesData: null, - defaultValue: resolvedDefaultValue, }); forceUpdate(); - getChartDataRequest({ - formData, - force: false, - requestParams: { dashboardId: 0 }, - }).then(response => { - if ( - filterToEdit?.filterType === formFilter?.filterType && - filterToEdit?.targets[0].datasetId === formFilter?.dataset?.value && - (!hasColumn || - formFilter?.column === filterToEdit?.targets[0].column?.name) - ) { - resolvedDefaultValue = filterToEdit?.defaultValue; - } - if (isFeatureEnabled(FeatureFlag.GLOBAL_ASYNC_QUERIES)) { - // deal with getChartDataRequest transforming the response data - const result = 'result' in response ? response.result[0] : response; - waitForAsyncData(result) - .then((asyncResult: ChartDataResponseResult[]) => { - setNativeFilterFieldValues(form, filterId, { - defaultValueQueriesData: asyncResult, - defaultValue: resolvedDefaultValue, - }); - forceUpdate(); - }) - .catch((error: ClientErrorObject) => { - // TODO: show error once this logic is moved into new NativeFilter - // component - console.error( - error.message || error.error || t('Check configuration'), - ); - }); - } else { - setNativeFilterFieldValues(form, filterId, { - defaultValueQueriesData: response.result, - defaultValue: resolvedDefaultValue, - }); - forceUpdate(); - } - }); }, [ + form, formFilter?.filterType, formFilter?.column, formFilter?.dataset?.value, JSON.stringify(formFilter?.adhoc_filters), formFilter?.time_range, + forceUpdate, filterId, ]); + + useEffect(() => { + setNativeFilterFieldValues(form, filterId, { + defaultValue: formFilter?.defaultValue, + }); + forceUpdate(); + }, [form, formFilter?.defaultValue, forceUpdate, filterId]); }; diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/utils.ts b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/utils.ts index 015a2f1a18f65..61ef409c34c97 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/utils.ts +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/utils.ts @@ -31,7 +31,7 @@ export const setNativeFilterFieldValues = ( filterId: string, values: object, ) => { - const formFilters = form.getFieldValue('filters'); + const formFilters = form.getFieldValue('filters') || {}; form.setFieldsValue({ filters: { ...formFilters,