Table: Add select/unselect all column values to table filter (#79290)

* Add/Remove columns values to the filter using a UX similar to the github inbox

* Align select all checkbox and fix wording

* Update docs/sources/panels-visualizations/visualizations/table/index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

---------

Co-authored-by: Oscar Kilhed <oscar.kilhed@grafana.com>
Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
pull/80026/head
Alvaro Huarte 1 year ago committed by GitHub
parent f0c38611a2
commit 40583aec0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      docs/sources/panels-visualizations/visualizations/table/index.md
  2. 50
      packages/grafana-ui/src/components/Table/FilterList.tsx

@ -191,6 +191,8 @@ To filter column values, click the filter (funnel) icon next to a column title.
Click the check box next to the values that you want to display. Enter text in the search field at the top to show those values in the display so that you can select them rather than scroll to find them.
Click the check box above the **Ok** and **Cancel** buttons to add or remove all displayed values to/from the filter.
### Clear column filters
Columns with filters applied have a blue funnel displayed next to the title.

@ -1,4 +1,4 @@
import { css } from '@emotion/css';
import { css, cx } from '@emotion/css';
import React, { useCallback, useMemo, useState } from 'react';
import { FixedSizeList as List } from 'react-window';
@ -30,6 +30,24 @@ export const FilterList = ({ options, values, caseSensitive, onChange }: Props)
}),
[options, regex]
);
const selectedItems = useMemo(() => items.filter((item) => values.includes(item)), [items, values]);
const selectCheckValue = useMemo(() => items.length === selectedItems.length, [items, selectedItems]);
const selectCheckIndeterminate = useMemo(
() => selectedItems.length > 0 && items.length > selectedItems.length,
[items, selectedItems]
);
const selectCheckLabel = useMemo(
() => (selectedItems.length ? `${selectedItems.length} selected` : `Select all`),
[selectedItems]
);
const selectCheckDescription = useMemo(
() =>
items.length !== selectedItems.length
? 'Add all displayed values to the filter'
: 'Remove all displayed values from the filter',
[items, selectedItems]
);
const styles = useStyles2(getStyles);
const theme = useTheme2();
@ -47,6 +65,16 @@ export const FilterList = ({ options, values, caseSensitive, onChange }: Props)
[onChange, values]
);
const onSelectChanged = useCallback(() => {
if (items.length === selectedItems.length) {
const newValues = values.filter((item) => !items.includes(item));
onChange(newValues);
} else {
const newValues = [...new Set([...values, ...items])];
onChange(newValues);
}
}, [onChange, values, items, selectedItems]);
return (
<VerticalGroup spacing="md">
<FilterInput placeholder="Filter values" onChange={setSearchFilter} value={searchFilter} />
@ -72,6 +100,20 @@ export const FilterList = ({ options, values, caseSensitive, onChange }: Props)
}}
</List>
)}
{items.length && (
<VerticalGroup spacing="xs">
<div className={cx(styles.selectDivider)} />
<div className={cx(styles.filterListRow)}>
<Checkbox
value={selectCheckValue}
indeterminate={selectCheckIndeterminate}
label={selectCheckLabel}
description={selectCheckDescription}
onChange={onSelectChanged}
/>
</div>
</VerticalGroup>
)}
</VerticalGroup>
);
};
@ -92,4 +134,10 @@ const getStyles = (theme: GrafanaTheme2) => ({
backgroundColor: theme.colors.action.hover,
},
}),
selectDivider: css({
label: 'selectDivider',
width: '100%',
borderTop: `1px solid ${theme.colors.border.medium}`,
padding: theme.spacing(0.5, 2),
}),
});

Loading…
Cancel
Save