From 51bfd1ab803ae16e2961555cf210bb5d95708dc4 Mon Sep 17 00:00:00 2001 From: Yury Molodov Date: Thu, 17 Nov 2022 17:42:33 +0100 Subject: [PATCH] vmui: add ability hide query (#3359) * feat: add ability hide query * fix: change logic hide query * fix: remove console.log --- .../Configurators/QueryEditor/QueryEditor.tsx | 6 ++- .../src/components/Main/Button/Button.tsx | 2 +- .../src/components/Main/Button/style.scss | 17 +++++++ .../vmui/src/components/Main/Icons/index.tsx | 23 +++++++++ .../packages/vmui/src/hooks/useFetchQuery.ts | 7 +-- .../QueryConfigurator/QueryConfigurator.tsx | 38 ++++++++++++-- .../CustomPanel/QueryConfigurator/style.scss | 7 ++- .../vmui/src/pages/CustomPanel/index.tsx | 49 ++++++++++++------- docs/CHANGELOG.md | 1 + 9 files changed, 122 insertions(+), 28 deletions(-) diff --git a/app/vmui/packages/vmui/src/components/Configurators/QueryEditor/QueryEditor.tsx b/app/vmui/packages/vmui/src/components/Configurators/QueryEditor/QueryEditor.tsx index 2fabde6bf..0fb1b13d9 100644 --- a/app/vmui/packages/vmui/src/components/Configurators/QueryEditor/QueryEditor.tsx +++ b/app/vmui/packages/vmui/src/components/Configurators/QueryEditor/QueryEditor.tsx @@ -18,7 +18,7 @@ export interface QueryEditorProps { error?: ErrorTypes | string; options: string[]; label: string; - size?: "small" | "medium" | undefined; + disabled?: boolean } const QueryEditor: FC = ({ @@ -31,6 +31,7 @@ const QueryEditor: FC = ({ error, options, label, + disabled = false }) => { const [focusOption, setFocusOption] = useState(-1); @@ -86,6 +87,7 @@ const QueryEditor: FC = ({ // Enter if (enter && hasAutocomplete && !shiftKey && !ctrlMetaKey) { + if (disabled) return; onChange(foundOptions[focusOption]); setOpenAutocomplete(false); } else if (enter && !shiftKey) { @@ -98,6 +100,7 @@ const QueryEditor: FC = ({ }; const createHandlerOnChangeAutocomplete = (item: string) => () => { + if (disabled) return; onChange(item); handleCloseAutocomplete(); }; @@ -127,6 +130,7 @@ const QueryEditor: FC = ({ error={error} onKeyDown={handleKeyDown} onChange={onChange} + disabled={disabled} /> ( /> ); + +export const VisibilityIcon = () => ( + + + +); + + +export const VisibilityOffIcon = () => ( + + + +); diff --git a/app/vmui/packages/vmui/src/hooks/useFetchQuery.ts b/app/vmui/packages/vmui/src/hooks/useFetchQuery.ts index bcb19472c..bfd7953b2 100644 --- a/app/vmui/packages/vmui/src/hooks/useFetchQuery.ts +++ b/app/vmui/packages/vmui/src/hooks/useFetchQuery.ts @@ -17,9 +17,10 @@ interface FetchQueryParams { visible: boolean display?: DisplayType, customStep: number, + hideQuery?: number[] } -export const useFetchQuery = ({ predefinedQuery, visible, display, customStep }: FetchQueryParams): { +export const useFetchQuery = ({ predefinedQuery, visible, display, customStep, hideQuery = [] }: FetchQueryParams): { fetchUrl?: string[], isLoading: boolean, graphData?: MetricResult[], @@ -111,14 +112,14 @@ export const useFetchQuery = ({ predefinedQuery, visible, display, customStep }: } else if (isValidHttpUrl(serverUrl)) { const updatedPeriod = { ...period }; updatedPeriod.step = customStep; - return expr.filter(q => q.trim()).map(q => displayChart + return expr.filter((q, i) => q.trim() && !hideQuery.includes(i)).map(q => displayChart ? getQueryRangeUrl(serverUrl, q, updatedPeriod, nocache, isTracingEnabled) : getQueryUrl(serverUrl, q, updatedPeriod, isTracingEnabled)); } else { setError(ErrorTypes.validServer); } }, - [serverUrl, period, displayType, customStep]); + [serverUrl, period, displayType, customStep, hideQuery]); useEffect(() => { if (!visible || !fetchUrl?.length) return; diff --git a/app/vmui/packages/vmui/src/pages/CustomPanel/QueryConfigurator/QueryConfigurator.tsx b/app/vmui/packages/vmui/src/pages/CustomPanel/QueryConfigurator/QueryConfigurator.tsx index 4fd10243a..543e91c1b 100644 --- a/app/vmui/packages/vmui/src/pages/CustomPanel/QueryConfigurator/QueryConfigurator.tsx +++ b/app/vmui/packages/vmui/src/pages/CustomPanel/QueryConfigurator/QueryConfigurator.tsx @@ -6,24 +6,28 @@ import usePrevious from "../../../hooks/usePrevious"; import { MAX_QUERY_FIELDS } from "../../../constants/graph"; import { useQueryDispatch, useQueryState } from "../../../state/query/QueryStateContext"; import { useTimeDispatch } from "../../../state/time/TimeStateContext"; -import { DeleteIcon, PlayIcon, PlusIcon } from "../../../components/Main/Icons"; +import { DeleteIcon, PlayIcon, PlusIcon, VisibilityIcon, VisibilityOffIcon } from "../../../components/Main/Icons"; import Button from "../../../components/Main/Button/Button"; import "./style.scss"; import Tooltip from "../../../components/Main/Tooltip/Tooltip"; +import classNames from "classnames"; export interface QueryConfiguratorProps { error?: ErrorTypes | string; queryOptions: string[] + onHideQuery: (queries: number[]) => void } -const QueryConfigurator: FC = ({ error, queryOptions }) => { +const QueryConfigurator: FC = ({ error, queryOptions, onHideQuery }) => { const { query, queryHistory, autocomplete } = useQueryState(); const queryDispatch = useQueryDispatch(); const timeDispatch = useTimeDispatch(); const [stateQuery, setStateQuery] = useState(query || []); + const [hideQuery, setHideQuery] = useState([]); const prevStateQuery = usePrevious(stateQuery) as (undefined | string[]); + const updateHistory = () => { queryDispatch({ type: "SET_QUERY_HISTORY", payload: stateQuery.map((q, i) => { @@ -51,6 +55,10 @@ const QueryConfigurator: FC = ({ error, queryOptions }) setStateQuery(prev => prev.filter((q, i) => i !== index)); }; + const onToggleHideQuery = (index: number) => { + setHideQuery(prev => prev.includes(index) ? prev.filter(n => n !== index) : [...prev, index]); + }; + const handleChangeQuery = (value: string, index: number) => { setStateQuery(prev => prev.map((q, i) => i === index ? value : q)); }; @@ -76,6 +84,11 @@ const QueryConfigurator: FC = ({ error, queryOptions }) const createHandlerRemoveQuery = (i: number) => () => { onRemoveQuery(i); + setHideQuery(prev => prev.map(n => n > i ? n - 1: n)); + }; + + const createHandlerHideQuery = (i: number) => () => { + onToggleHideQuery(i); }; useEffect(() => { @@ -84,11 +97,18 @@ const QueryConfigurator: FC = ({ error, queryOptions }) } }, [stateQuery]); + useEffect(() => { + onHideQuery(hideQuery); + }, [hideQuery]); + return
{stateQuery.map((q, i) => (
= ({ error, queryOptions }) onEnter={onRunQuery} onChange={createHandlerChangeQuery(i)} label={`Query ${i + 1}`} - size={"small"} + disabled={hideQuery.includes(i)} /> + +
+
+
{stateQuery.length > 1 && (
diff --git a/app/vmui/packages/vmui/src/pages/CustomPanel/QueryConfigurator/style.scss b/app/vmui/packages/vmui/src/pages/CustomPanel/QueryConfigurator/style.scss index cfbbf2d90..678988f10 100644 --- a/app/vmui/packages/vmui/src/pages/CustomPanel/QueryConfigurator/style.scss +++ b/app/vmui/packages/vmui/src/pages/CustomPanel/QueryConfigurator/style.scss @@ -9,10 +9,15 @@ &-row { display: grid; - grid-template-columns: 1fr auto; + grid-template-columns: 1fr auto auto; align-items: center; gap: $padding-small; + &_disabled { + filter: grayscale(100%); + opacity: 0.5; + } + &__button { display: grid; width: 36px; diff --git a/app/vmui/packages/vmui/src/pages/CustomPanel/index.tsx b/app/vmui/packages/vmui/src/pages/CustomPanel/index.tsx index c95997886..0f2701b1d 100644 --- a/app/vmui/packages/vmui/src/pages/CustomPanel/index.tsx +++ b/app/vmui/packages/vmui/src/pages/CustomPanel/index.tsx @@ -29,10 +29,18 @@ const CustomPanel: FC = () => { const [displayColumns, setDisplayColumns] = useState(); const [tracesState, setTracesState] = useState([]); + const [hideQuery, setHideQuery] = useState([]); const { customStep, yaxis } = useGraphState(); const graphDispatch = useGraphDispatch(); + const { queryOptions } = useFetchQueryOptions(); + const { isLoading, liveData, graphData, error, warning, traces } = useFetchQuery({ + visible: true, + customStep, + hideQuery + }); + const setYaxisLimits = (limits: AxisRange) => { graphDispatch({ type: "SET_YAXIS_LIMITS", payload: limits }); }; @@ -45,17 +53,15 @@ const CustomPanel: FC = () => { timeDispatch({ type: "SET_PERIOD", payload: { from, to } }); }; - const { queryOptions } = useFetchQueryOptions(); - const { isLoading, liveData, graphData, error, warning, traces } = useFetchQuery({ - visible: true, - customStep - }); - const handleTraceDelete = (trace: Trace) => { const updatedTraces = tracesState.filter((data) => data.idValue !== trace.idValue); setTracesState([...updatedTraces]); }; + const handleHideQuery = (queries: number[]) => { + setHideQuery(queries); + }; + useEffect(() => { if (traces) { setTracesState([...tracesState, ...traces]); @@ -71,6 +77,7 @@ const CustomPanel: FC = () => { {isTracingEnabled && (
@@ -80,22 +87,26 @@ const CustomPanel: FC = () => { />
)} + {isLoading && } {error && {error}} {warning && {warning}}
- {isLoading && }
- {displayType === "chart" && } - {displayType === "table" && } + {displayType === "chart" && ( + + )} + {displayType === "table" && ( + + )}
{graphData && period && (displayType === "chart") && ( { setPeriod={setPeriod} /> )} - {liveData && (displayType === "code") && } + {liveData && (displayType === "code") && ( + + )} {liveData && (displayType === "table") && (