From a3509add4d7a8fb76ceb23798c72a9d95fd965ae Mon Sep 17 00:00:00 2001 From: Yury Molodov Date: Thu, 22 Aug 2024 16:57:26 +0200 Subject: [PATCH] vmui: add column search in table settings (#6804) ### Describe Your Changes Add search functionality to the column display settings in the table #6668 ![image](https://github.com/user-attachments/assets/e9bd52c3-6428-4d4f-8b7f-d83dd80b6912) ### Checklist The following checks are **mandatory**: - [ ] My change adheres [VictoriaMetrics contributing guidelines](https://docs.victoriametrics.com/contributing/). --------- Signed-off-by: hagen1778 Co-authored-by: hagen1778 (cherry picked from commit e35237920aebe0f70fe6eddf4379e19ce6d70d19) --- .../vmui/src/components/Main/Icons/index.tsx | 11 ++ .../Table/TableSettings/TableSettings.tsx | 144 ++++++++++++------ .../components/Table/TableSettings/style.scss | 33 +++- docs/VictoriaLogs/CHANGELOG.md | 3 +- docs/changelog/CHANGELOG.md | 2 + 5 files changed, 140 insertions(+), 53 deletions(-) diff --git a/app/vmui/packages/vmui/src/components/Main/Icons/index.tsx b/app/vmui/packages/vmui/src/components/Main/Icons/index.tsx index bef8f8c638..0340a4ffd5 100644 --- a/app/vmui/packages/vmui/src/components/Main/Icons/index.tsx +++ b/app/vmui/packages/vmui/src/components/Main/Icons/index.tsx @@ -542,3 +542,14 @@ export const CollapseIcon = () => ( > ); + +export const SearchIcon = () => ( + + + +); diff --git a/app/vmui/packages/vmui/src/components/Table/TableSettings/TableSettings.tsx b/app/vmui/packages/vmui/src/components/Table/TableSettings/TableSettings.tsx index c5a4e4ffe4..a5eb0219fc 100644 --- a/app/vmui/packages/vmui/src/components/Table/TableSettings/TableSettings.tsx +++ b/app/vmui/packages/vmui/src/components/Table/TableSettings/TableSettings.tsx @@ -1,6 +1,6 @@ import React, { FC, useEffect, useRef, useMemo } from "preact/compat"; import Button from "../../Main/Button/Button"; -import { RestartIcon, SettingsIcon } from "../../Main/Icons"; +import { SearchIcon, SettingsIcon } from "../../Main/Icons"; import Popper from "../../Main/Popper/Popper"; import "./style.scss"; import Checkbox from "../../Main/Checkbox/Checkbox"; @@ -10,6 +10,8 @@ import { arrayEquals } from "../../../utils/array"; import classNames from "classnames"; import useDeviceDetect from "../../../hooks/useDeviceDetect"; import useBoolean from "../../../hooks/useBoolean"; +import TextField from "../../Main/TextField/TextField"; +import { KeyboardEvent, useState } from "react"; const title = "Table settings"; @@ -38,6 +40,23 @@ const TableSettings: FC = ({ setFalse: handleClose, } = useBoolean(false); + const { + value: showSearch, + toggle: toggleShowSearch, + } = useBoolean(false); + + const [searchColumn, setSearchColumn] = useState(""); + const [indexFocusItem, setIndexFocusItem] = useState(-1); + + const filteredColumns = useMemo(() => { + if (!searchColumn) return columns; + return columns.filter(col => col.includes(searchColumn)); + }, [columns, searchColumn]); + + const isAllChecked = useMemo(() => { + return filteredColumns.every(col => defaultColumns.includes(col)); + }, [defaultColumns, filteredColumns]); + const disabledButton = useMemo(() => !columns.length, [columns]); const handleChange = (key: string) => { @@ -45,22 +64,35 @@ const TableSettings: FC = ({ }; const toggleAllColumns = () => { - if (defaultColumns.length === columns.length) { - onChangeColumns([]); + if (isAllChecked) { + onChangeColumns(defaultColumns.filter(col => !filteredColumns.includes(col))); } else { - onChangeColumns(columns); + onChangeColumns(filteredColumns); } }; - const handleResetColumns = () => { - handleClose(); - onChangeColumns(columns); - }; - const createHandlerChange = (key: string) => () => { handleChange(key); }; + const handleBlurSearch = () => { + setIndexFocusItem(-1); + }; + + const handleKeyDown = (e: KeyboardEvent) => { + const arrowUp = e.key === "ArrowUp"; + const arrowDown = e.key === "ArrowDown"; + const enter = e.key === "Enter"; + if (arrowDown || arrowUp || enter) e.preventDefault(); + if (arrowDown) { + setIndexFocusItem(prev => prev + 1 > filteredColumns.length - 1 ? prev : prev + 1); + } else if (arrowUp) { + setIndexFocusItem(prev => prev - 1 < 0 ? prev : prev - 1); + } else if (enter) { + handleChange(filteredColumns[indexFocusItem]); + } + }; + useEffect(() => { if (arrayEquals(columns, defaultColumns)) return; onChangeColumns(columns); @@ -75,7 +107,7 @@ const TableSettings: FC = ({ startIcon={} onClick={toggleOpenSettings} disabled={disabledButton} - ariaLabel="table settings" + ariaLabel={title} /> @@ -100,42 +132,64 @@ const TableSettings: FC = ({ />
-
-

Display columns

- -
-
- -
- {columns.map(col => ( -
- +
+
+

Display columns

+ +
- ))} + {showSearch && ( + } + value={searchColumn} + onChange={setSearchColumn} + onBlur={handleBlurSearch} + onKeyDown={handleKeyDown} + type="search" + /> + )} + {!filteredColumns.length && ( +

No columns found

+ )} +
+ {!!filteredColumns.length && ( +
+ +
+ )} +
+
+ {filteredColumns.map((col, i) => ( +
+ +
+ ))} +
+
diff --git a/app/vmui/packages/vmui/src/components/Table/TableSettings/style.scss b/app/vmui/packages/vmui/src/components/Table/TableSettings/style.scss index 9c77a56cad..2c0049cdac 100644 --- a/app/vmui/packages/vmui/src/components/Table/TableSettings/style.scss +++ b/app/vmui/packages/vmui/src/components/Table/TableSettings/style.scss @@ -16,9 +16,8 @@ display: grid; gap: 12px; padding: $padding-global; - max-height: 350px; - overflow: auto; border-bottom: $border-divider; + max-width: 250px; &_first { padding-top: 0; @@ -29,6 +28,7 @@ align-items: center; justify-content: space-between; grid-template-columns: 1fr auto; + gap: $padding-small; min-height: 25px; &__title { @@ -36,12 +36,31 @@ } } - &__item { - font-size: $font-size; + &-columns { + max-height: 350px; + overflow: auto; } - &__check_all { - padding: 0 0 $padding-global; - border-bottom: $border-divider; + + &__item { + padding: calc($padding-global/2) $padding-global; + font-size: $font-size; + + &:hover, + &_focus { + background-color: $color-hover-black; + } + + &_check_all { + padding: calc($padding-global/2) $padding-global; + margin: 0 (-$padding-global); + } + } + + &__no-found { + text-align: center; + font-style: italic; + color: $color-text-secondary; + margin-bottom: $padding-small; } } } diff --git a/docs/VictoriaLogs/CHANGELOG.md b/docs/VictoriaLogs/CHANGELOG.md index c3d97cb79e..cd0a422bc6 100644 --- a/docs/VictoriaLogs/CHANGELOG.md +++ b/docs/VictoriaLogs/CHANGELOG.md @@ -22,7 +22,8 @@ according to [these docs](https://docs.victoriametrics.com/victorialogs/quicksta * FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): introduce the ability to select a key for grouping logs within the "Group" tab. * FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): display the number of entries within each log group. * FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): move the Markdown toggle to the general settings panel in the upper left corner. -* FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): add "select/deselect all" button to table settings for managing displayed columns. Thanks to @yincongcyincong for the [pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/6680). +* FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): add search functionality to the column display settings in the table. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6668). +* FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): add the ability to select all columns in the column display settings of the table. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6668). Thanks to @yincongcyincong for the [pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/6680). * BUGFIX: properly handle Logstash requests for Elasticsearch configuration when using `outputs.elasticsearch` in Logstash pipelines. Previously, the requests could be rejected with `400 Bad Request` response. * BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix `not found index.js` error when loading vmui in VictoriaLogs. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6764). Thanks to @yincongcyincong for the [pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/6770). diff --git a/docs/changelog/CHANGELOG.md b/docs/changelog/CHANGELOG.md index f55c905dc5..0757a7f796 100644 --- a/docs/changelog/CHANGELOG.md +++ b/docs/changelog/CHANGELOG.md @@ -32,6 +32,8 @@ The value of `instance` label for those scrape targets will be changed from `