feat: copy pairs on click in legend (#2087)

This commit is contained in:
Yury Molodov 2022-01-21 17:52:05 +03:00 committed by GitHub
parent ede93469ea
commit e46b7d33a7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 5 deletions

View file

@ -1,9 +1,10 @@
import React, {FC, useMemo} from "preact/compat";
import React, {FC, useMemo, useState} from "preact/compat";
import {hexToRGB} from "../../utils/color";
import {useAppState} from "../../state/common/StateContext";
import {LegendItem} from "../../utils/uplot/types";
import "./legend.css";
import {getDashLine} from "../../utils/uplot/helpers";
import Tooltip from "@mui/material/Tooltip";
export interface LegendProps {
labels: LegendItem[];
@ -13,10 +14,18 @@ export interface LegendProps {
const Legend: FC<LegendProps> = ({labels, onChange}) => {
const {query} = useAppState();
const [copiedValue, setCopiedValue] = useState("");
const groups = useMemo(() => {
return Array.from(new Set(labels.map(l => l.group)));
}, [labels]);
const handleClickFreeField = async (val: string, id: string) => {
await navigator.clipboard.writeText(val);
setCopiedValue(id);
setTimeout(() => setCopiedValue(""), 2000);
};
return <>
<div className="legendWrapper">
{groups.map((group) => <div className="legendGroup" key={group}>
@ -39,7 +48,25 @@ const Legend: FC<LegendProps> = ({labels, onChange}) => {
borderColor: legendItem.color,
backgroundColor: `rgba(${hexToRGB(legendItem.color)}, 0.1)`
}}/>
<div className="legendLabel">{legendItem.label}</div>
<div className="legendLabel">
{legendItem.freeFormFields.__name__ || `Query ${legendItem.group} result`}
{!!Object.keys(legendItem.freeFormFields).length && <>
&#160;&#123;
{Object.keys(legendItem.freeFormFields).filter(f => f !== "__name__").map((f) => {
const freeField = `${f}="${legendItem.freeFormFields[f]}"`;
const fieldId = `${legendItem.group}.${legendItem.label}.${freeField}`;
return <Tooltip arrow key={f} open={copiedValue === fieldId} title={"Copied!"}>
<span className="legendFreeFields" onClick={(e) => {
e.stopPropagation();
handleClickFreeField(freeField, fieldId);
}}>
{f}: {legendItem.freeFormFields[f]}
</span>
</Tooltip>;
})}
&#125;
</>}
</div>
</div>
)}
</div>

View file

@ -34,7 +34,7 @@
grid-gap: 6px;
align-items: start;
justify-content: start;
padding: 5px 10px;
padding: 7px 50px 7px 10px;
background-color: #FFF;
cursor: pointer;
transition: 0.2s ease;
@ -56,14 +56,27 @@
border-style: solid;
box-sizing: border-box;
transition: 0.2s ease;
margin: 3px 0;
}
.legendLabel {
font-size: 11px;
line-height: 12px;
font-weight: normal;
}
.legendFreeFields {
padding: 3px;
cursor: pointer;
}
.legendFreeFields:hover {
text-decoration: underline;
}
.legendFreeFields:not(:last-child):after {
content: ",";
}
.legendWrapperHotkey {
display: flex;
align-items: center;

View file

@ -10,6 +10,7 @@ export const getSeriesItem = (d: MetricResult, hideSeries: string[]): Series =>
return {
label,
dash: getDashLine(d.group),
class: JSON.stringify(d.metric),
width: 1.4,
stroke: getColorLine(d.group, label),
show: !includesHideSeries(label, d.group, hideSeries),
@ -25,7 +26,8 @@ export const getLegendItem = (s: Series, group: number): LegendItem => ({
group,
label: s.label || "",
color: s.stroke as string,
checked: s.show || false
checked: s.show || false,
freeFormFields: JSON.parse(s.class || "{}"),
});
export const getHideSeries = ({hideSeries, legend, metaKey, series}: HideSeriesArgs): string[] => {

View file

@ -36,4 +36,5 @@ export interface LegendItem {
label: string;
color: string;
checked: boolean;
freeFormFields: {[key: string]: string};
}