mirror of
https://github.com/apache/superset.git
synced 2026-05-07 08:54:23 +00:00
fix(dashboard): Fill form with the latest values when undo in native filters (#16851)
* Set undoFormValues * Reorganize * Revert check * Fix and clean up * Fix pre-filter and sort values
This commit is contained in:
@@ -315,12 +315,15 @@ const FiltersConfigForm = (
|
|||||||
const [activeFilterPanelKey, setActiveFilterPanelKey] = useState<
|
const [activeFilterPanelKey, setActiveFilterPanelKey] = useState<
|
||||||
string | string[]
|
string | string[]
|
||||||
>(FilterPanels.basic.key);
|
>(FilterPanels.basic.key);
|
||||||
|
const [undoFormValues, setUndoFormValues] = useState<Record<
|
||||||
|
string,
|
||||||
|
any
|
||||||
|
> | null>(null);
|
||||||
const forceUpdate = useForceUpdate();
|
const forceUpdate = useForceUpdate();
|
||||||
const [datasetDetails, setDatasetDetails] = useState<Record<string, any>>();
|
const [datasetDetails, setDatasetDetails] = useState<Record<string, any>>();
|
||||||
const defaultFormFilter = useMemo(() => ({}), []);
|
const defaultFormFilter = useMemo(() => ({}), []);
|
||||||
const formFilter =
|
const formValues = form.getFieldValue('filters')?.[filterId];
|
||||||
form.getFieldValue('filters')?.[filterId] || defaultFormFilter;
|
const formFilter = formValues || undoFormValues || defaultFormFilter;
|
||||||
|
|
||||||
const nativeFilterItems = getChartMetadataRegistry().items;
|
const nativeFilterItems = getChartMetadataRegistry().items;
|
||||||
const nativeFilterVizTypes = Object.entries(nativeFilterItems)
|
const nativeFilterVizTypes = Object.entries(nativeFilterItems)
|
||||||
@@ -346,11 +349,11 @@ const FiltersConfigForm = (
|
|||||||
|
|
||||||
const showTimeRangePicker = useMemo(() => {
|
const showTimeRangePicker = useMemo(() => {
|
||||||
const currentDataset = Object.values(loadedDatasets).find(
|
const currentDataset = Object.values(loadedDatasets).find(
|
||||||
dataset => dataset.id === formFilter.dataset?.value,
|
dataset => dataset.id === formFilter?.dataset?.value,
|
||||||
);
|
);
|
||||||
|
|
||||||
return currentDataset ? hasTemporalColumns(currentDataset) : true;
|
return currentDataset ? hasTemporalColumns(currentDataset) : true;
|
||||||
}, [formFilter.dataset?.value, loadedDatasets]);
|
}, [formFilter?.dataset?.value, loadedDatasets]);
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const hasDataset = !!nativeFilterItems[formFilter?.filterType]?.value
|
const hasDataset = !!nativeFilterItems[formFilter?.filterType]?.value
|
||||||
@@ -368,7 +371,7 @@ const FiltersConfigForm = (
|
|||||||
forceUpdate,
|
forceUpdate,
|
||||||
form,
|
form,
|
||||||
filterId,
|
filterId,
|
||||||
filterType: formFilter.filterType,
|
filterType: formFilter?.filterType,
|
||||||
filterToEdit,
|
filterToEdit,
|
||||||
formFilter,
|
formFilter,
|
||||||
removed,
|
removed,
|
||||||
@@ -380,31 +383,6 @@ const FiltersConfigForm = (
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const enableNoResults = !!nativeFilterItem.value?.enableNoResults;
|
const enableNoResults = !!nativeFilterItem.value?.enableNoResults;
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (datasetId) {
|
|
||||||
cachedSupersetGet({
|
|
||||||
endpoint: `/api/v1/dataset/${datasetId}`,
|
|
||||||
})
|
|
||||||
.then((response: JsonResponse) => {
|
|
||||||
setMetrics(response.json?.result?.metrics);
|
|
||||||
const dataset = response.json?.result;
|
|
||||||
// modify the response to fit structure expected by AdhocFilterControl
|
|
||||||
dataset.type = dataset.datasource_type;
|
|
||||||
dataset.filter_select = true;
|
|
||||||
setDatasetDetails(dataset);
|
|
||||||
})
|
|
||||||
.catch((response: SupersetApiError) => {
|
|
||||||
addDangerToast(response.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [datasetId]);
|
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
|
||||||
changeTab(tab: 'configuration' | 'scoping') {
|
|
||||||
setActiveTabKey(tab);
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
const hasMetrics = hasColumn && !!metrics.length;
|
const hasMetrics = hasColumn && !!metrics.length;
|
||||||
|
|
||||||
const hasFilledDataset =
|
const hasFilledDataset =
|
||||||
@@ -418,8 +396,6 @@ const FiltersConfigForm = (
|
|||||||
|
|
||||||
const isDataDirty = formFilter?.isDataDirty ?? true;
|
const isDataDirty = formFilter?.isDataDirty ?? true;
|
||||||
|
|
||||||
useBackendFormUpdate(form, filterId);
|
|
||||||
|
|
||||||
const setNativeFilterFieldValuesWrapper = (values: object) => {
|
const setNativeFilterFieldValuesWrapper = (values: object) => {
|
||||||
setNativeFilterFieldValues(form, filterId, values);
|
setNativeFilterFieldValues(form, filterId, values);
|
||||||
setError('');
|
setError('');
|
||||||
@@ -513,20 +489,6 @@ const FiltersConfigForm = (
|
|||||||
const showDataset =
|
const showDataset =
|
||||||
!datasetId || datasetDetails || formFilter?.dataset?.label;
|
!datasetId || datasetDetails || formFilter?.dataset?.label;
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (hasDataset && hasFilledDataset && hasDefaultValue && isDataDirty) {
|
|
||||||
refreshHandler();
|
|
||||||
}
|
|
||||||
}, [
|
|
||||||
hasDataset,
|
|
||||||
hasFilledDataset,
|
|
||||||
hasDefaultValue,
|
|
||||||
formFilter,
|
|
||||||
isDataDirty,
|
|
||||||
refreshHandler,
|
|
||||||
showDataset,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const formChanged = useCallback(() => {
|
const formChanged = useCallback(() => {
|
||||||
form.setFields([
|
form.setFields([
|
||||||
{
|
{
|
||||||
@@ -550,15 +512,21 @@ const FiltersConfigForm = (
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
const parentFilter = parentFilterOptions.find(
|
const parentFilter = parentFilterOptions.find(
|
||||||
({ value }) => value === filterToEdit?.cascadeParentIds[0],
|
({ value }) =>
|
||||||
|
value === formFilter?.parentFilter?.value ||
|
||||||
|
value === filterToEdit?.cascadeParentIds?.[0],
|
||||||
);
|
);
|
||||||
|
|
||||||
const hasParentFilter = !!parentFilter;
|
const hasParentFilter = !!parentFilter;
|
||||||
|
|
||||||
const hasPreFilter =
|
const hasPreFilter =
|
||||||
!!filterToEdit?.adhoc_filters || !!filterToEdit?.time_range;
|
!!formFilter?.adhoc_filters ||
|
||||||
|
!!formFilter?.time_range ||
|
||||||
|
!!filterToEdit?.adhoc_filters?.length ||
|
||||||
|
!!filterToEdit?.time_range;
|
||||||
|
|
||||||
const hasSorting =
|
const hasSorting =
|
||||||
|
typeof formFilter?.controlValues?.sortAscending === 'boolean' ||
|
||||||
typeof filterToEdit?.controlValues?.sortAscending === 'boolean';
|
typeof filterToEdit?.controlValues?.sortAscending === 'boolean';
|
||||||
|
|
||||||
let sort = filterToEdit?.controlValues?.sortAscending;
|
let sort = filterToEdit?.controlValues?.sortAscending;
|
||||||
@@ -604,7 +572,7 @@ const FiltersConfigForm = (
|
|||||||
formFilter?.filterType === 'filter_range';
|
formFilter?.filterType === 'filter_range';
|
||||||
|
|
||||||
const initialDefaultValue =
|
const initialDefaultValue =
|
||||||
formFilter.filterType === filterToEdit?.filterType
|
formFilter?.filterType === filterToEdit?.filterType
|
||||||
? filterToEdit?.defaultDataMask
|
? filterToEdit?.defaultDataMask
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
@@ -622,6 +590,62 @@ const FiltersConfigForm = (
|
|||||||
.some(key => controlItems[key].checked);
|
.some(key => controlItems[key].checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ParentSelect = ({
|
||||||
|
value,
|
||||||
|
...rest
|
||||||
|
}: {
|
||||||
|
value?: { value: string | number };
|
||||||
|
}) => (
|
||||||
|
<Select
|
||||||
|
ariaLabel={t('Parent filter')}
|
||||||
|
placeholder={t('None')}
|
||||||
|
options={parentFilterOptions}
|
||||||
|
allowClear
|
||||||
|
value={value?.value}
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (datasetId) {
|
||||||
|
cachedSupersetGet({
|
||||||
|
endpoint: `/api/v1/dataset/${datasetId}`,
|
||||||
|
})
|
||||||
|
.then((response: JsonResponse) => {
|
||||||
|
setMetrics(response.json?.result?.metrics);
|
||||||
|
const dataset = response.json?.result;
|
||||||
|
// modify the response to fit structure expected by AdhocFilterControl
|
||||||
|
dataset.type = dataset.datasource_type;
|
||||||
|
dataset.filter_select = true;
|
||||||
|
setDatasetDetails(dataset);
|
||||||
|
})
|
||||||
|
.catch((response: SupersetApiError) => {
|
||||||
|
addDangerToast(response.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [datasetId]);
|
||||||
|
|
||||||
|
useImperativeHandle(ref, () => ({
|
||||||
|
changeTab(tab: 'configuration' | 'scoping') {
|
||||||
|
setActiveTabKey(tab);
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
useBackendFormUpdate(form, filterId);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (hasDataset && hasFilledDataset && hasDefaultValue && isDataDirty) {
|
||||||
|
refreshHandler();
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
hasDataset,
|
||||||
|
hasFilledDataset,
|
||||||
|
hasDefaultValue,
|
||||||
|
isDataDirty,
|
||||||
|
refreshHandler,
|
||||||
|
showDataset,
|
||||||
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const activeFilterPanelKey = [FilterPanels.basic.key];
|
const activeFilterPanelKey = [FilterPanels.basic.key];
|
||||||
if (hasCheckedAdvancedControl) {
|
if (hasCheckedAdvancedControl) {
|
||||||
@@ -652,21 +676,20 @@ const FiltersConfigForm = (
|
|||||||
JSON.stringify(loadedDatasets),
|
JSON.stringify(loadedDatasets),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const ParentSelect = ({
|
useEffect(() => {
|
||||||
value,
|
// just removed, saving current form items for eventual undo
|
||||||
...rest
|
if (removed) {
|
||||||
}: {
|
setUndoFormValues(formValues);
|
||||||
value?: { value: string | number };
|
}
|
||||||
}) => (
|
}, [removed]);
|
||||||
<Select
|
|
||||||
ariaLabel={t('Parent filter')}
|
useEffect(() => {
|
||||||
placeholder={t('None')}
|
// the filter was just restored after undo
|
||||||
options={parentFilterOptions}
|
if (undoFormValues && !removed) {
|
||||||
allowClear
|
setNativeFilterFieldValues(form, filterId, undoFormValues);
|
||||||
value={value?.value}
|
setUndoFormValues(null);
|
||||||
{...rest}
|
}
|
||||||
/>
|
}, [formValues, filterId, form, removed, undoFormValues]);
|
||||||
);
|
|
||||||
|
|
||||||
if (removed) {
|
if (removed) {
|
||||||
return <RemovedFilter onClick={() => restoreFilter(filterId)} />;
|
return <RemovedFilter onClick={() => restoreFilter(filterId)} />;
|
||||||
@@ -814,7 +837,7 @@ const FiltersConfigForm = (
|
|||||||
formChanged();
|
formChanged();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{formFilter.filterType && (
|
{!removed && (
|
||||||
<StyledRowSubFormItem
|
<StyledRowSubFormItem
|
||||||
name={['filters', filterId, 'defaultDataMask']}
|
name={['filters', filterId, 'defaultDataMask']}
|
||||||
initialValue={initialDefaultValue}
|
initialValue={initialDefaultValue}
|
||||||
|
|||||||
Reference in New Issue
Block a user