From 40583aec0fd88631184f0127a992b3af57899a3a Mon Sep 17 00:00:00 2001 From: Alvaro Huarte Date: Thu, 4 Jan 2024 16:09:16 +0100 Subject: [PATCH] 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 Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com> --- .../visualizations/table/index.md | 2 + .../src/components/Table/FilterList.tsx | 50 ++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/docs/sources/panels-visualizations/visualizations/table/index.md b/docs/sources/panels-visualizations/visualizations/table/index.md index d78221b79d0..91862f56b01 100644 --- a/docs/sources/panels-visualizations/visualizations/table/index.md +++ b/docs/sources/panels-visualizations/visualizations/table/index.md @@ -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. diff --git a/packages/grafana-ui/src/components/Table/FilterList.tsx b/packages/grafana-ui/src/components/Table/FilterList.tsx index 2ff6d26bb41..1c56ff7f631 100644 --- a/packages/grafana-ui/src/components/Table/FilterList.tsx +++ b/packages/grafana-ui/src/components/Table/FilterList.tsx @@ -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 ( @@ -72,6 +100,20 @@ export const FilterList = ({ options, values, caseSensitive, onChange }: Props) }} )} + {items.length && ( + +
+
+ +
+ + )} ); }; @@ -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), + }), });