Skip to content

Commit

Permalink
feat(native-filters): add refresh button to default value picker (#14375
Browse files Browse the repository at this point in the history
)

* feat(native-filters): add refresh button to default value picker

* skip flaky test
  • Loading branch information
villebro authored Apr 27, 2021
1 parent d645312 commit 87a895c
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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 {
Expand Down Expand Up @@ -111,8 +116,22 @@ export const FiltersConfigForm: React.FC<FiltersConfigFormProps> = ({
parentFilters,
}) => {
const forceUpdate = useForceUpdate();
const formFilter = (form.getFieldValue('filters') || {})[filterId];
const [datasetDetails, setDatasetDetails] = useState<Record<string, any>>();

// 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
Expand Down Expand Up @@ -158,7 +177,56 @@ export const FiltersConfigForm: React.FC<FiltersConfigFormProps> = ({
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,
Expand Down Expand Up @@ -254,6 +322,7 @@ export const FiltersConfigForm: React.FC<FiltersConfigFormProps> = ({
// We need reset column when dataset changed
if (datasetId && e?.value !== datasetId) {
setNativeFilterFieldValues(form, filterId, {
defaultValue: null,
column: null,
});
}
Expand All @@ -275,7 +344,13 @@ export const FiltersConfigForm: React.FC<FiltersConfigFormProps> = ({
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();
}}
/>
</StyledFormItem>
)}
Expand Down Expand Up @@ -347,27 +422,36 @@ export const FiltersConfigForm: React.FC<FiltersConfigFormProps> = ({
isClearable
/>
</StyledFormItem>
<StyledFormItem
name={['filters', filterId, 'defaultValue']}
initialValue={filterToEdit?.defaultValue}
data-test="default-input"
label={<StyledLabel>{t('Default Value')}</StyledLabel>}
>
{(hasFilledDataset || !hasDataset) && (
<DefaultValue
setDataMask={({ filterState }) => {
setNativeFilterFieldValues(form, filterId, {
defaultValue: filterState?.value,
});
forceUpdate();
}}
filterId={filterId}
hasDataset={hasDataset}
form={form}
formData={newFormData}
/>
)}
</StyledFormItem>
<StyledContainer>
<StyledFormItem className="bottom" label={<StyledLabel />}>
{hasDataset && hasFilledDataset && (
<Button onClick={refreshHandler}>
{isDataDirty ? t('Populate') : t('Refresh')}
</Button>
)}
</StyledFormItem>
<StyledFormItem
name={['filters', filterId, 'defaultValue']}
initialValue={filterToEdit?.defaultValue}
data-test="default-input"
label={<StyledLabel>{t('Default Value')}</StyledLabel>}
>
{!isDataDirty && (hasFilledDataset || !hasDataset) && (
<DefaultValue
setDataMask={({ filterState }) => {
setNativeFilterFieldValues(form, filterId, {
defaultValue: filterState?.value,
});
forceUpdate();
}}
filterId={filterId}
hasDataset={hasDataset}
form={form}
formData={newFormData}
/>
)}
</StyledFormItem>
</StyledContainer>
<StyledCheckboxFormItem
name={['filters', filterId, 'isInstant']}
initialValue={filterToEdit?.isInstant || false}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,102 +18,38 @@
*/
import { useEffect } from 'react';
import { FormInstance } from 'antd/lib/form';
import { getChartDataRequest } from 'src/chart/chartAction';
import { ChartDataResponseResult, t } from '@superset-ui/core';
import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags';
import { waitForAsyncData } from 'src/middleware/asyncEvent';
import { ClientErrorObject } from 'src/utils/getClientErrorObject';
import { NativeFiltersForm } from '../types';
import { setNativeFilterFieldValues, useForceUpdate } from './utils';
import { Filter } from '../../types';
import { getFormData } from '../../utils';

// When some fields in form changed we need re-fetch data for Filter defaultValue
// eslint-disable-next-line import/prefer-default-export
export const useBackendFormUpdate = (
form: FormInstance<NativeFiltersForm>,
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]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 87a895c

Please sign in to comment.