Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(filter-set): adding new filters #13515

Merged
merged 42 commits into from
Mar 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
2731518
refactor(native-filters): move data mask to root reducer
simcha90 Mar 3, 2021
de6a332
Merge branch 'master' of github.com:apache/superset into filtersState…
simcha90 Mar 3, 2021
6652d19
refactor: update rest stuff for dataMask
simcha90 Mar 3, 2021
266a0a3
refactor: add ownCrrentState to explore
simcha90 Mar 3, 2021
5344dd4
fix: fix immer reducer
simcha90 Mar 4, 2021
2b4bd8f
Merge branch 'master' of github.com:apache/superset into filtersState…
simcha90 Mar 4, 2021
dabfd24
fix: merge with master
simcha90 Mar 4, 2021
802823c
refactor: support explore dataMask
simcha90 Mar 4, 2021
8aed240
refactor: support explore dataMask
simcha90 Mar 4, 2021
a0fa114
docs: add comment
simcha90 Mar 4, 2021
eaec7ef
refactor: remove json stringify
simcha90 Mar 4, 2021
cba3467
fix: fix failed cases
simcha90 Mar 4, 2021
04d6398
feat: filter bat buttons start
simcha90 Mar 4, 2021
af9e35a
fix: fix CR notes
simcha90 Mar 4, 2021
64fb87d
fix: fix cascade filters
simcha90 Mar 4, 2021
57c954f
fix: fix CR notes
simcha90 Mar 4, 2021
bd9b767
Merge branch 'filtersState_to_data_mask' of github.com:simchaNielsen/…
simcha90 Mar 4, 2021
bff44d1
refactor: add clear all
simcha90 Mar 7, 2021
09b594a
fix: fix CR notes
simcha90 Mar 7, 2021
c522391
Merge branch 'master' of github.com:apache/superset into filtersState…
simcha90 Mar 7, 2021
1bf1552
Merge branch 'filtersState_to_data_mask' of github.com:simchaNielsen/…
simcha90 Mar 7, 2021
0527067
fix: fix CR notes
simcha90 Mar 7, 2021
9abe26e
Merge branch 'filtersState_to_data_mask' of github.com:simchaNielsen/…
simcha90 Mar 7, 2021
2d12c37
fix: fix CR notes
simcha90 Mar 7, 2021
84d8cbd
Merge branch 'filtersState_to_data_mask' of github.com:simchaNielsen/…
simcha90 Mar 7, 2021
a9202b1
feat: buttons in filter bar
simcha90 Mar 7, 2021
9ae46b9
Merge branch 'master' of github.com:apache/superset into filter_bar_a…
simcha90 Mar 7, 2021
cdcae95
lint: update imports
simcha90 Mar 7, 2021
6c91054
feat: add tabs for filter sets
simcha90 Mar 7, 2021
844adaa
Merge branch 'master' of github.com:apache/superset into filter-set_tabs
simcha90 Mar 7, 2021
93e5d97
Merge branch 'master' of github.com:apache/superset into filter-set_tabs
simcha90 Mar 7, 2021
04259c2
feat: add buttons to filter set
simcha90 Mar 7, 2021
c053836
Merge branch 'master' of github.com:apache/superset into filter_set_d…
simcha90 Mar 7, 2021
26a0f28
feat: first phase add filter sets
simcha90 Mar 8, 2021
60b1374
fix: undo FF
simcha90 Mar 8, 2021
6671c1d
Merge branch 'master' of github.com:apache/superset into filter_set_d…
simcha90 Mar 8, 2021
3af62be
fix: fix CR notes
simcha90 Mar 8, 2021
d47a1ea
fix: fix CR notes
simcha90 Mar 8, 2021
68e32d8
lint: fix lint
simcha90 Mar 8, 2021
bdbd0f9
fix: fix filter bar opening
simcha90 Mar 9, 2021
cc82b6a
Merge branch 'master' of github.com:apache/superset into filter_set_d…
simcha90 Mar 9, 2021
760e375
refactor: continue filter sets
simcha90 Mar 9, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion superset-frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions superset-frontend/src/common/components/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export { FormInstance } from 'antd/lib/form';
export { RadioChangeEvent } from 'antd/lib/radio';

export { default as Badge } from './Badge';
export { default as Collapse } from './Collapse';
export { default as Progress } from './ProgressBar';

export const MenuItem = styled(AntdMenu.Item)`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
FilterValue,
} from './Styles';
import { Indicator } from './selectors';
import { getFilterValueForDisplay } from '../nativeFilters/FilterBar/FilterSets/utils';

export interface IndicatorProps {
indicator: Indicator;
Expand All @@ -46,18 +47,21 @@ export interface IndicatorProps {
const Indicator = ({
indicator: { column, name, value = [], path },
onClick,
}: IndicatorProps) => (
<Item onClick={() => onClick([...path, `LABEL-${column}`])}>
<Title bold>
<ItemIcon>
<SearchOutlined />
</ItemIcon>
{name}
{value.length ? ': ' : ''}
</Title>
<FilterValue>{value.length ? value.join(', ') : ''}</FilterValue>
</Item>
);
}: IndicatorProps) => {
const resultValue = getFilterValueForDisplay(value);
return (
<Item onClick={() => onClick([...path, `LABEL-${column}`])}>
<Title bold>
<ItemIcon>
<SearchOutlined />
</ItemIcon>
{name}
{resultValue ? ': ' : ''}
</Title>
<FilterValue>{resultValue}</FilterValue>
</Item>
);
};

export interface DetailsPanelProps {
appliedIndicators: Indicator[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ import { useImmer } from 'use-immer';
import { getInitialMask } from 'src/dataMask/reducer';
import { areObjectsEqual } from 'src/reduxUtils';
import FilterConfigurationLink from './FilterConfigurationLink';
import { useFilterConfiguration } from '../state';
import { Filter } from '../types';
import { buildCascadeFiltersTree, mapParentFiltersToChildren } from './utils';
import CascadePopover from './CascadePopover';
import FilterSets from './FilterSets';
import FilterSets from './FilterSets/FilterSets';
import { useFilters, useFilterSets } from './state';

const barWidth = `250px`;

Expand Down Expand Up @@ -128,14 +128,6 @@ const TitleArea = styled.h4`
& > span {
flex-grow: 1;
}

& :not(:first-child) {
margin-left: ${({ theme }) => theme.gridUnit}px;

&:hover {
cursor: pointer;
}
}
`;

const StyledTabs = styled(Tabs)`
Expand All @@ -153,6 +145,9 @@ const StyledTabs = styled(Tabs)`
const ActionButtons = styled.div`
display: grid;
flex-direction: row;
justify-content: center;
align-items: center;
grid-gap: 10px;
grid-template-columns: 1fr 1fr;
${({ theme }) =>
`padding: 0 ${theme.gridUnit * 2}px ${theme.gridUnit * 2}px`};
Expand All @@ -164,6 +159,9 @@ const ActionButtons = styled.div`

const FilterControls = styled.div`
padding: 0 ${({ theme }) => theme.gridUnit * 4}px;
&:hover {
cursor: pointer;
}
`;

interface FiltersBarProps {
Expand All @@ -183,48 +181,67 @@ const FilterBar: React.FC<FiltersBarProps> = ({
setLastAppliedFilterData,
] = useImmer<DataMaskUnit>({});
const dispatch = useDispatch();
const filterSets = useFilterSets();
const filterSetsArray = Object.values(filterSets);
const filters = useFilters();
const filtersArray = Object.values(filters);
const dataMaskState = useSelector<any, DataMaskUnitWithId>(
state => state.dataMask.nativeFilters ?? {},
);
const filterConfigs = useFilterConfiguration();
const canEdit = useSelector<any, boolean>(
({ dashboardInfo }) => dashboardInfo.dash_edit_perm,
);
const [visiblePopoverId, setVisiblePopoverId] = useState<string | null>(null);
const [isInitialized, setIsInitialized] = useState<boolean>(false);

const handleApply = () => {
const filterIds = Object.keys(filterData);
filterIds.forEach(filterId => {
if (filterData[filterId]) {
dispatch(
updateDataMask(filterId, {
nativeFilters: filterData[filterId],
}),
);
}
});
setLastAppliedFilterData(() => filterData);
};

useEffect(() => {
if (isInitialized) {
return;
}
const areFiltersInitialized = filterConfigs.every(
filterConfig =>
filterConfig.defaultValue ===
const areFiltersInitialized = filtersArray.every(filterConfig =>
areObjectsEqual(
filterConfig.defaultValue,
filterData[filterConfig.id]?.currentState?.value,
),
);
if (areFiltersInitialized) {
handleApply();
setIsInitialized(true);
}
}, [filterConfigs, filterData, isInitialized]);
}, [filtersArray, filterData, isInitialized]);

useEffect(() => {
if (filterConfigs.length === 0 && filtersOpen) {
if (filtersArray.length === 0 && filtersOpen) {
toggleFiltersBar(false);
}
}, [filterConfigs]);
}, [filtersArray.length]);

const cascadeChildren = useMemo(
() => mapParentFiltersToChildren(filterConfigs),
[filterConfigs],
() => mapParentFiltersToChildren(filtersArray),
[filtersArray],
);

const cascadeFilters = useMemo(() => {
const filtersWithValue = filterConfigs.map(filter => ({
const filtersWithValue = filtersArray.map(filter => ({
...filter,
currentValue: filterData[filter.id]?.currentState?.value,
}));
return buildCascadeFiltersTree(filtersWithValue);
}, [filterConfigs, filterData]);
}, [filtersArray, filterData]);

const handleFilterSelectionChange = (
filter: Pick<Filter, 'id'> & Partial<Filter>,
Expand All @@ -243,35 +260,15 @@ const FilterBar: React.FC<FiltersBarProps> = ({
});
};

const handleApply = () => {
const filterIds = Object.keys(filterData);
filterIds.forEach(filterId => {
if (filterData[filterId]) {
dispatch(
updateDataMask(filterId, {
nativeFilters: filterData[filterId],
}),
);
}
});
setLastAppliedFilterData(() => filterData);
};

useEffect(() => {
if (isInitialized) {
handleApply();
}
}, [isInitialized]);

const handleClearAll = () => {
filterConfigs.forEach(filter => {
filtersArray.forEach(filter => {
setFilterData(draft => {
draft[filter.id] = getInitialMask(filter.id);
});
});
};

const isClearAllDisabled = !Object.values(dataMaskState).every(
const isClearAllDisabled = Object.values(dataMaskState).every(
filter =>
filterData[filter.id]?.currentState?.value === null ||
(!filterData[filter.id] && filter.currentState?.value === null),
Expand All @@ -295,6 +292,9 @@ const FilterBar: React.FC<FiltersBarProps> = ({
</FilterControls>
);

const isApplyDisabled =
!isInitialized || areObjectsEqual(filterData, lastAppliedFilterData);

return (
<BarWrapper data-test="filter-bar" className={cx({ open: filtersOpen })}>
<CollapsedBar
Expand All @@ -309,7 +309,7 @@ const FilterBar: React.FC<FiltersBarProps> = ({
<span>{t('Filters')}</span>
{canEdit && (
<FilterConfigurationLink
createNewOnOpen={filterConfigs.length === 0}
createNewOnOpen={filtersArray.length === 0}
>
<Icon name="edit" data-test="create-filter" />
</FilterConfigurationLink>
Expand All @@ -318,7 +318,7 @@ const FilterBar: React.FC<FiltersBarProps> = ({
</TitleArea>
<ActionButtons>
<Button
disabled={!isClearAllDisabled}
disabled={isClearAllDisabled}
buttonStyle="tertiary"
buttonSize="small"
onClick={handleClearAll}
Expand All @@ -327,10 +327,7 @@ const FilterBar: React.FC<FiltersBarProps> = ({
{t('Clear all')}
</Button>
<Button
disabled={
!isInitialized ||
areObjectsEqual(filterData, lastAppliedFilterData)
}
disabled={isApplyDisabled}
buttonStyle="primary"
htmlType="submit"
buttonSize="small"
Expand All @@ -347,13 +344,17 @@ const FilterBar: React.FC<FiltersBarProps> = ({
onChange={() => {}}
>
<Tabs.TabPane
tab={t(`All Filters (${filterConfigs.length})`)}
tab={t(`All Filters (${filtersArray.length})`)}
key="allFilters"
>
{getFilterControls()}
</Tabs.TabPane>
<Tabs.TabPane tab={t('Filter Sets')} key="filterSets">
<Tabs.TabPane
tab={t(`Filter Sets (${filterSetsArray.length})`)}
key="filterSets"
>
<FilterSets
disabled={!isApplyDisabled}
dataMaskState={dataMaskState}
onFilterSelectionChange={handleFilterSelectionChange}
/>
Expand Down
Loading