mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2025-02-09 15:27:11 +00:00
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 <roman@victoriametrics.com> Co-authored-by: hagen1778 <roman@victoriametrics.com>
This commit is contained in:
parent
fa9de9b45c
commit
e35237920a
5 changed files with 140 additions and 53 deletions
|
@ -542,3 +542,14 @@ export const CollapseIcon = () => (
|
||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const SearchIcon = () => (
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { FC, useEffect, useRef, useMemo } from "preact/compat";
|
import React, { FC, useEffect, useRef, useMemo } from "preact/compat";
|
||||||
import Button from "../../Main/Button/Button";
|
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 Popper from "../../Main/Popper/Popper";
|
||||||
import "./style.scss";
|
import "./style.scss";
|
||||||
import Checkbox from "../../Main/Checkbox/Checkbox";
|
import Checkbox from "../../Main/Checkbox/Checkbox";
|
||||||
|
@ -10,6 +10,8 @@ import { arrayEquals } from "../../../utils/array";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import useDeviceDetect from "../../../hooks/useDeviceDetect";
|
import useDeviceDetect from "../../../hooks/useDeviceDetect";
|
||||||
import useBoolean from "../../../hooks/useBoolean";
|
import useBoolean from "../../../hooks/useBoolean";
|
||||||
|
import TextField from "../../Main/TextField/TextField";
|
||||||
|
import { KeyboardEvent, useState } from "react";
|
||||||
|
|
||||||
const title = "Table settings";
|
const title = "Table settings";
|
||||||
|
|
||||||
|
@ -38,6 +40,23 @@ const TableSettings: FC<TableSettingsProps> = ({
|
||||||
setFalse: handleClose,
|
setFalse: handleClose,
|
||||||
} = useBoolean(false);
|
} = 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 disabledButton = useMemo(() => !columns.length, [columns]);
|
||||||
|
|
||||||
const handleChange = (key: string) => {
|
const handleChange = (key: string) => {
|
||||||
|
@ -45,22 +64,35 @@ const TableSettings: FC<TableSettingsProps> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleAllColumns = () => {
|
const toggleAllColumns = () => {
|
||||||
if (defaultColumns.length === columns.length) {
|
if (isAllChecked) {
|
||||||
onChangeColumns([]);
|
onChangeColumns(defaultColumns.filter(col => !filteredColumns.includes(col)));
|
||||||
} else {
|
} else {
|
||||||
onChangeColumns(columns);
|
onChangeColumns(filteredColumns);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleResetColumns = () => {
|
|
||||||
handleClose();
|
|
||||||
onChangeColumns(columns);
|
|
||||||
};
|
|
||||||
|
|
||||||
const createHandlerChange = (key: string) => () => {
|
const createHandlerChange = (key: string) => () => {
|
||||||
handleChange(key);
|
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(() => {
|
useEffect(() => {
|
||||||
if (arrayEquals(columns, defaultColumns)) return;
|
if (arrayEquals(columns, defaultColumns)) return;
|
||||||
onChangeColumns(columns);
|
onChangeColumns(columns);
|
||||||
|
@ -75,7 +107,7 @@ const TableSettings: FC<TableSettingsProps> = ({
|
||||||
startIcon={<SettingsIcon/>}
|
startIcon={<SettingsIcon/>}
|
||||||
onClick={toggleOpenSettings}
|
onClick={toggleOpenSettings}
|
||||||
disabled={disabledButton}
|
disabled={disabledButton}
|
||||||
ariaLabel="table settings"
|
ariaLabel={title}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
@ -100,42 +132,64 @@ const TableSettings: FC<TableSettingsProps> = ({
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="vm-table-settings-popper-list">
|
<div className="vm-table-settings-popper-list">
|
||||||
<div className="vm-table-settings-popper-list-header">
|
<div>
|
||||||
<h3 className="vm-table-settings-popper-list-header__title">Display columns</h3>
|
<div className="vm-table-settings-popper-list-header">
|
||||||
<Tooltip title="Reset to default">
|
<h3 className="vm-table-settings-popper-list-header__title">Display columns</h3>
|
||||||
<Button
|
<Tooltip title="search column">
|
||||||
color="primary"
|
<Button
|
||||||
variant="text"
|
color="primary"
|
||||||
size="small"
|
variant="text"
|
||||||
onClick={handleResetColumns}
|
onClick={toggleShowSearch}
|
||||||
startIcon={<RestartIcon/>}
|
startIcon={<SearchIcon/>}
|
||||||
ariaLabel="reset columns"
|
ariaLabel="reset columns"
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="vm-table-settings-popper-list__item vm-table-settings-popper-list__check_all"
|
|
||||||
>
|
|
||||||
<Checkbox
|
|
||||||
checked={defaultColumns.length === columns.length}
|
|
||||||
onChange={toggleAllColumns}
|
|
||||||
label="Check all"
|
|
||||||
disabled={tableCompact}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{columns.map(col => (
|
|
||||||
<div
|
|
||||||
className="vm-table-settings-popper-list__item"
|
|
||||||
key={col}
|
|
||||||
>
|
|
||||||
<Checkbox
|
|
||||||
checked={defaultColumns.includes(col)}
|
|
||||||
onChange={createHandlerChange(col)}
|
|
||||||
label={col}
|
|
||||||
disabled={tableCompact}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
{showSearch && (
|
||||||
|
<TextField
|
||||||
|
placeholder={"search column"}
|
||||||
|
startIcon={<SearchIcon/>}
|
||||||
|
value={searchColumn}
|
||||||
|
onChange={setSearchColumn}
|
||||||
|
onBlur={handleBlurSearch}
|
||||||
|
onKeyDown={handleKeyDown}
|
||||||
|
type="search"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{!filteredColumns.length && (
|
||||||
|
<p className="vm-table-settings-popper-list__no-found">No columns found</p>
|
||||||
|
)}
|
||||||
|
<div className="vm-table-settings-popper-list-header">
|
||||||
|
{!!filteredColumns.length && (
|
||||||
|
<div className="vm-table-settings-popper-list__item vm-table-settings-popper-list__item_check_all">
|
||||||
|
<Checkbox
|
||||||
|
checked={isAllChecked}
|
||||||
|
onChange={toggleAllColumns}
|
||||||
|
label={isAllChecked ? "Uncheck all" : "Check all"}
|
||||||
|
disabled={tableCompact}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="vm-table-settings-popper-list-columns">
|
||||||
|
{filteredColumns.map((col, i) => (
|
||||||
|
<div
|
||||||
|
className={classNames({
|
||||||
|
"vm-table-settings-popper-list__item": true,
|
||||||
|
"vm-table-settings-popper-list__item_focus": i === indexFocusItem,
|
||||||
|
})}
|
||||||
|
key={col}
|
||||||
|
>
|
||||||
|
<Checkbox
|
||||||
|
checked={defaultColumns.includes(col)}
|
||||||
|
onChange={createHandlerChange(col)}
|
||||||
|
label={col}
|
||||||
|
disabled={tableCompact}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Popper>
|
</Popper>
|
||||||
|
|
|
@ -16,9 +16,8 @@
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
padding: $padding-global;
|
padding: $padding-global;
|
||||||
max-height: 350px;
|
|
||||||
overflow: auto;
|
|
||||||
border-bottom: $border-divider;
|
border-bottom: $border-divider;
|
||||||
|
max-width: 250px;
|
||||||
|
|
||||||
&_first {
|
&_first {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
|
@ -29,6 +28,7 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
grid-template-columns: 1fr auto;
|
grid-template-columns: 1fr auto;
|
||||||
|
gap: $padding-small;
|
||||||
min-height: 25px;
|
min-height: 25px;
|
||||||
|
|
||||||
&__title {
|
&__title {
|
||||||
|
@ -36,12 +36,31 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__item {
|
&-columns {
|
||||||
font-size: $font-size;
|
max-height: 350px;
|
||||||
|
overflow: auto;
|
||||||
}
|
}
|
||||||
&__check_all {
|
|
||||||
padding: 0 0 $padding-global;
|
&__item {
|
||||||
border-bottom: $border-divider;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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): 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): 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): 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: 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).
|
* 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).
|
||||||
|
|
|
@ -32,6 +32,8 @@ The value of `instance` label for those scrape targets will be changed from `<ad
|
||||||
* FEATURE: [vmalert-tool](https://docs.victoriametrics.com/vmalert-tool/): add `-external.label` and `-external.url` command-line flags, in the same way as these flags are supported by vmalert. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6735).
|
* FEATURE: [vmalert-tool](https://docs.victoriametrics.com/vmalert-tool/): add `-external.label` and `-external.url` command-line flags, in the same way as these flags are supported by vmalert. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6735).
|
||||||
* FEATURE: [vmbackup](https://docs.victoriametrics.com/vmbackup/), [vmrestore](https://docs.victoriametrics.com/vmrestore/), [vmbackupmanager](https://docs.victoriametrics.com/vmbackupmanager/): use exponential backoff for retries when uploading or downloading data from S3. This should reduce the number of failed uploads and downloads when S3 is temporarily unavailable. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6732).
|
* FEATURE: [vmbackup](https://docs.victoriametrics.com/vmbackup/), [vmrestore](https://docs.victoriametrics.com/vmrestore/), [vmbackupmanager](https://docs.victoriametrics.com/vmbackupmanager/): use exponential backoff for retries when uploading or downloading data from S3. This should reduce the number of failed uploads and downloads when S3 is temporarily unavailable. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6732).
|
||||||
* FEATURE: [stream aggregation](https://docs.victoriametrics.com/stream-aggregation/): do not allow enabling `-stream.keepInput` and `keep_metric_names` options together in [stream aggregation config](https://docs.victoriametrics.com/stream-aggregation/#stream-aggregation-config), as it may result in time series collision.
|
* FEATURE: [stream aggregation](https://docs.victoriametrics.com/stream-aggregation/): do not allow enabling `-stream.keepInput` and `keep_metric_names` options together in [stream aggregation config](https://docs.victoriametrics.com/stream-aggregation/#stream-aggregation-config), as it may result in time series collision.
|
||||||
|
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add search functionality to the column display settings in the table. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6668).
|
||||||
|
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): 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: [vmagent](https://docs.victoriametrics.com/vmagent): fixes `proxy_url` authorization for scrape targets. Previously proxy authorization configuration was ignored for `https` targets. See [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6771) issue for details.
|
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent): fixes `proxy_url` authorization for scrape targets. Previously proxy authorization configuration was ignored for `https` targets. See [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6771) issue for details.
|
||||||
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent/) fix service discovery of Azure Virtual Machines for response contains `nextLink`. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6784).
|
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent/) fix service discovery of Azure Virtual Machines for response contains `nextLink`. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6784).
|
||||||
|
|
Loading…
Reference in a new issue