feat(native-filters): allow cascading from time and numeric filters (#23319)
This commit is contained in:
parent
63513a5873
commit
db95a93f43
|
|
@ -24,7 +24,6 @@ import { useToasts } from 'src/components/MessageToasts/withToasts';
|
|||
import { getClientErrorObject } from 'src/utils/getClientErrorObject';
|
||||
import { cacheWrapper } from 'src/utils/cacheWrapper';
|
||||
import { NativeFiltersForm } from '../types';
|
||||
import { doesColumnMatchFilterType } from './utils';
|
||||
|
||||
interface ColumnSelectProps {
|
||||
allowClear?: boolean;
|
||||
|
|
@ -84,10 +83,7 @@ export function ColumnSelect({
|
|||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
currentColumn &&
|
||||
!doesColumnMatchFilterType(currentFilterType, currentColumn)
|
||||
) {
|
||||
if (currentColumn && !filterValues(currentColumn)) {
|
||||
resetColumnField();
|
||||
}
|
||||
}, [currentColumn, currentFilterType, resetColumnField]);
|
||||
|
|
|
|||
|
|
@ -23,10 +23,15 @@ import { Select } from 'src/components';
|
|||
import { CollapsibleControl } from './CollapsibleControl';
|
||||
|
||||
interface DependencyListProps {
|
||||
availableFilters: { label: string; value: string }[];
|
||||
availableFilters: {
|
||||
label: string;
|
||||
value: string;
|
||||
type: string | undefined;
|
||||
}[];
|
||||
dependencies: string[];
|
||||
onDependenciesChange: (dependencies: string[]) => void;
|
||||
getDependencySuggestion: () => string;
|
||||
children?: JSX.Element;
|
||||
}
|
||||
|
||||
const MainPanel = styled.div`
|
||||
|
|
@ -176,6 +181,7 @@ const DependencyList = ({
|
|||
dependencies = [],
|
||||
onDependenciesChange,
|
||||
getDependencySuggestion,
|
||||
children,
|
||||
}: DependencyListProps) => {
|
||||
const hasAvailableFilters = availableFilters.length > 0;
|
||||
const hasDependencies = dependencies.length > 0;
|
||||
|
|
@ -205,6 +211,7 @@ const DependencyList = ({
|
|||
onDependenciesChange={onDependenciesChange}
|
||||
getDependencySuggestion={getDependencySuggestion}
|
||||
/>
|
||||
{children}
|
||||
</CollapsibleControl>
|
||||
</MainPanel>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -299,7 +299,9 @@ export interface FiltersConfigFormProps {
|
|||
removedFilters: Record<string, FilterRemoval>;
|
||||
restoreFilter: (filterId: string) => void;
|
||||
form: FormInstance<NativeFiltersForm>;
|
||||
getAvailableFilters: (filterId: string) => { label: string; value: string }[];
|
||||
getAvailableFilters: (
|
||||
filterId: string,
|
||||
) => { label: string; value: string; type: string | undefined }[];
|
||||
handleActiveFilterPanelChange: (activeFilterPanel: string | string[]) => void;
|
||||
activeFilterPanelKeys: string | string[];
|
||||
isActive: boolean;
|
||||
|
|
@ -654,6 +656,9 @@ const FiltersConfigForm = (
|
|||
|
||||
const availableFilters = getAvailableFilters(filterId);
|
||||
const hasAvailableFilters = availableFilters.length > 0;
|
||||
const hasTimeDependency = availableFilters
|
||||
.filter(filter => filter.type === 'filter_time')
|
||||
.some(filter => dependencies.includes(filter.value));
|
||||
|
||||
useEffect(() => {
|
||||
if (datasetId) {
|
||||
|
|
@ -736,6 +741,42 @@ const FiltersConfigForm = (
|
|||
return <RemovedFilter onClick={() => restoreFilter(filterId)} />;
|
||||
}
|
||||
|
||||
const timeColumn = (
|
||||
<StyledRowFormItem
|
||||
name={['filters', filterId, 'granularity_sqla']}
|
||||
label={
|
||||
<>
|
||||
<StyledLabel>{t('Time column')}</StyledLabel>
|
||||
<InfoTooltipWithTrigger
|
||||
placement="top"
|
||||
tooltip={
|
||||
hasTimeDependency
|
||||
? t('Time column to apply dependent temporal filter to')
|
||||
: t('Time column to apply time range to')
|
||||
}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
initialValue={filterToEdit?.granularity_sqla}
|
||||
>
|
||||
<ColumnSelect
|
||||
allowClear
|
||||
form={form}
|
||||
formField="granularity_sqla"
|
||||
filterId={filterId}
|
||||
filterValues={(column: Column) => !!column.is_dttm}
|
||||
datasetId={datasetId}
|
||||
onChange={column => {
|
||||
// We need reset default value when when column changed
|
||||
setNativeFilterFieldValues(form, filterId, {
|
||||
granularity_sqla: column,
|
||||
});
|
||||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</StyledRowFormItem>
|
||||
);
|
||||
|
||||
return (
|
||||
<StyledTabs
|
||||
activeKey={activeTabKey}
|
||||
|
|
@ -892,7 +933,9 @@ const FiltersConfigForm = (
|
|||
getDependencySuggestion={() =>
|
||||
getDependencySuggestion(filterId)
|
||||
}
|
||||
/>
|
||||
>
|
||||
{hasTimeDependency ? timeColumn : undefined}
|
||||
</DependencyList>
|
||||
</StyledRowFormItem>
|
||||
)}
|
||||
{hasDataset && hasAdditionalFilters && (
|
||||
|
|
@ -966,39 +1009,9 @@ const FiltersConfigForm = (
|
|||
/>
|
||||
</StyledRowFormItem>
|
||||
)}
|
||||
{hasTimeRange && (
|
||||
<StyledRowFormItem
|
||||
name={['filters', filterId, 'granularity_sqla']}
|
||||
label={
|
||||
<>
|
||||
<StyledLabel>{t('Time column')}</StyledLabel>
|
||||
<InfoTooltipWithTrigger
|
||||
placement="top"
|
||||
tooltip={t(
|
||||
'Optional time column if time range should apply to another column than the default time column',
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
initialValue={filterToEdit?.granularity_sqla}
|
||||
>
|
||||
<ColumnSelect
|
||||
allowClear
|
||||
form={form}
|
||||
formField="granularity_sqla"
|
||||
filterId={filterId}
|
||||
filterValues={(column: Column) => !!column.is_dttm}
|
||||
datasetId={datasetId}
|
||||
onChange={column => {
|
||||
// We need reset default value when when column changed
|
||||
setNativeFilterFieldValues(form, filterId, {
|
||||
granularity_sqla: column,
|
||||
});
|
||||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</StyledRowFormItem>
|
||||
)}
|
||||
{hasTimeRange && !hasTimeDependency
|
||||
? timeColumn
|
||||
: undefined}
|
||||
</CollapsibleControl>
|
||||
</CleanFormItem>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,11 @@ export interface FiltersConfigModalProps {
|
|||
onSave: (filterConfig: FilterConfiguration) => Promise<void>;
|
||||
onCancel: () => void;
|
||||
}
|
||||
export const ALLOW_DEPENDENCIES = ['filter_select'];
|
||||
export const ALLOW_DEPENDENCIES = [
|
||||
'filter_range',
|
||||
'filter_select',
|
||||
'filter_time',
|
||||
];
|
||||
|
||||
const DEFAULT_EMPTY_FILTERS: string[] = [];
|
||||
const DEFAULT_REMOVED_FILTERS: Record<string, FilterRemoval> = {};
|
||||
|
|
@ -287,11 +291,12 @@ function FiltersConfigModal({
|
|||
const getAvailableFilters = useCallback(
|
||||
(filterId: string) =>
|
||||
filterIds
|
||||
.filter(key => key !== filterId)
|
||||
.filter(filterId => canBeUsedAsDependency(filterId))
|
||||
.map(key => ({
|
||||
label: getFilterTitle(key),
|
||||
value: key,
|
||||
.filter(id => id !== filterId)
|
||||
.filter(id => canBeUsedAsDependency(id))
|
||||
.map(id => ({
|
||||
label: getFilterTitle(id),
|
||||
value: id,
|
||||
type: filterConfigMap[id]?.filterType,
|
||||
})),
|
||||
[canBeUsedAsDependency, filterIds, getFilterTitle],
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue