mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
(core) add +
button to the filter bar
Summary: - Adds a + button to the filter. Button triggers a menu that allow to add one of the column that does not already have a filter set. Caveats: - for now menu only allows to choose from visible column. - This diff introduces a slight change of behavior of how filter works: - Filter used to be automatically removed when user set them to all inclusive (ie: by clicking the `All` button). - With this diff, it is no longer the case. - indeed, when filter are added to the filter bar with the `+` btn they are initially in the `all inclusive` state, hence would have been removed with the above mention behaviour. Test Plan: Added new test to nbrowser/FilterBar Reviewers: paulfitz Reviewed By: paulfitz Differential Revision: https://phab.getgrist.com/D2776
This commit is contained in:
parent
8a26550312
commit
5479159960
@ -264,6 +264,7 @@ export function createFilterMenu(openCtl: IOpenController, sectionFilter: Sectio
|
||||
const labelGetter = tableData.getRowPropFunc(field.displayColModel().colId())!;
|
||||
const formatter = field.createVisibleColFormatter();
|
||||
const valueMapFunc = (rowId: number) => formatter.formatAny(labelGetter(rowId));
|
||||
const activeFilterBar = field.viewSection.peek().activeFilterBar;
|
||||
|
||||
const valueCounts: Map<CellValue, {label: string, count: number}> = new Map();
|
||||
// TODO: as of now, this is not working for non text-or-numeric columns, ie: for Date column it is
|
||||
@ -282,7 +283,8 @@ export function createFilterMenu(openCtl: IOpenController, sectionFilter: Sectio
|
||||
onClose: () => openCtl.close(),
|
||||
doSave: (reset: boolean = false) => {
|
||||
const spec = columnFilter.makeFilterJson();
|
||||
field.activeFilter(spec === allInclusive ? '' : spec);
|
||||
// If filter is moot and filter bar is hidden, let's remove the filter.
|
||||
field.activeFilter((spec === allInclusive && !activeFilterBar.peek()) ? '' : spec);
|
||||
if (reset) {
|
||||
sectionFilter.resetTemporaryRows();
|
||||
}
|
||||
|
@ -1,14 +1,17 @@
|
||||
import { allInclusive } from "app/client/models/ColumnFilter";
|
||||
import { ViewFieldRec, ViewSectionRec } from "app/client/models/DocModel";
|
||||
import { attachColumnFilterMenu } from "app/client/ui/ColumnFilterMenu";
|
||||
import { cssButton, cssButtonGroup } from "app/client/ui2018/buttons";
|
||||
import { colors, testId } from "app/client/ui2018/cssVars";
|
||||
import { icon } from "app/client/ui2018/icons";
|
||||
import { menu, menuItemAsync } from "app/client/ui2018/menus";
|
||||
import { dom, IDisposableOwner, IDomArgs, styled } from "grainjs";
|
||||
|
||||
export function filterBar(_owner: IDisposableOwner, viewSection: ViewSectionRec) {
|
||||
return cssFilterBar(
|
||||
testId('filter-bar'),
|
||||
dom.forEach(viewSection.filteredFields, (field) => makeFilterField(viewSection, field)),
|
||||
makePlusButton(viewSection),
|
||||
cssSpacer(),
|
||||
dom.maybe(viewSection.filterSpecChanged, () => [
|
||||
primaryButton(
|
||||
@ -30,18 +33,38 @@ function makeFilterField(viewSection: ViewSectionRec, field: ViewFieldRec) {
|
||||
testId('btn'),
|
||||
cssIcon('FilterSimple'),
|
||||
cssMenuTextLabel(dom.text(field.label)),
|
||||
cssBtn.cls('-disabled', field.activeFilter.isSaved),
|
||||
cssBtn.cls('-saved', field.activeFilter.isSaved),
|
||||
attachColumnFilterMenu(viewSection, field, {placement: 'bottom-start', attach: 'body'}),
|
||||
),
|
||||
deleteButton(
|
||||
testId('delete'),
|
||||
cssIcon('CrossSmall'),
|
||||
cssBtn.cls('-disabled', field.activeFilter.isSaved),
|
||||
cssBtn.cls('-saved', field.activeFilter.isSaved),
|
||||
dom.on('click', () => field.activeFilter('')),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function makePlusButton(viewSectionRec: ViewSectionRec) {
|
||||
return dom.domComputed((use) => {
|
||||
const fields = use(use(viewSectionRec.viewFields).getObservable());
|
||||
const anyFilter = fields.find((f) => use(f.isFiltered));
|
||||
return cssPlusButton(
|
||||
cssBtn.cls('-saved'),
|
||||
cssIcon('Plus'),
|
||||
menu(() => fields.map((f) => (
|
||||
menuItemAsync(
|
||||
() => f.activeFilter(allInclusive),
|
||||
f.label.peek(),
|
||||
dom.cls('disabled', f.isFiltered)
|
||||
)
|
||||
))),
|
||||
anyFilter ? null : cssPlusLabel('Add Filter'),
|
||||
testId('add-filter-btn')
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const cssFilterBar = styled('div', `
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@ -75,13 +98,13 @@ const cssBtn = styled('div', `
|
||||
.${cssFilterBar.className} > & {
|
||||
margin: 0 4px;
|
||||
}
|
||||
&-disabled {
|
||||
&-saved {
|
||||
color: ${colors.light};
|
||||
--icon-color: ${colors.light};
|
||||
background-color: ${colors.slate};
|
||||
border-color: ${colors.slate};
|
||||
}
|
||||
&-disabled:hover {
|
||||
&-saved:hover {
|
||||
background-color: ${colors.darkGrey};
|
||||
border-color: ${colors.darkGrey};
|
||||
}
|
||||
@ -100,3 +123,9 @@ const cssSpacer = styled('div', `
|
||||
width: 8px;
|
||||
flex-shrink: 0;
|
||||
`);
|
||||
const cssPlusButton = styled(primaryButton, `
|
||||
padding: 3px 3px
|
||||
`);
|
||||
const cssPlusLabel = styled('span', `
|
||||
margin: 0 12px 0 4px;
|
||||
`);
|
||||
|
Loading…
Reference in New Issue
Block a user