Prometheus: Metrics explorer remove select dropdown behavior (#70722)

* remove hover style from results

* remove metric select keyboard interactions and highlighting for table results

* update naming for metrics explorer

* fix bug for match highlighting persisting when empty query
This commit is contained in:
Brendan O'Handley 2023-06-29 08:57:47 -04:00 committed by GitHub
parent cc794b884e
commit bb7a3be86e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 12 additions and 70 deletions

View File

@ -226,7 +226,7 @@ export function MetricSelect({
// add the modal butoon option to the options
metrics: [...metricsModalOption, ...metrics],
isLoading: undefined,
// pass the initial metrics into the Metrics Modal
// pass the initial metrics into the metrics explorer
initialMetrics: initialMetrics,
});
} else {

View File

@ -17,7 +17,7 @@ export function FeedbackLink({ feedbackUrl }: Props) {
<a
href={feedbackUrl}
className={styles.link}
title="The Metrics Modal is new, please let us know how we can improve it"
title="The metrics explorer is new, please let us know how we can improve it"
target="_blank"
rel="noreferrer noopener"
>

View File

@ -66,7 +66,6 @@ const {
setIncludeNullMetadata,
setSelectedTypes,
setUseBackend,
setSelectedIdx,
setDisableTextWrap,
showAdditionalSettings,
} = stateSlice.actions;
@ -158,22 +157,6 @@ export const MetricsModal = (props: MetricsModalProps) => {
}
}
function keyFunction(e: React.KeyboardEvent<HTMLElement>) {
if (e.code === 'ArrowDown' && state.selectedIdx < state.resultsPerPage - 1) {
dispatch(setSelectedIdx(state.selectedIdx + 1));
} else if (e.code === 'ArrowUp' && state.selectedIdx > 0) {
dispatch(setSelectedIdx(state.selectedIdx - 1));
} else if (e.code === 'Enter') {
const metric = displayedMetrics(state, dispatch)[state.selectedIdx];
onChange({ ...query, metric: metric.value });
tracking('grafana_prom_metric_encycopedia_tracking', state, metric.value);
onClose();
}
}
/* Settings switches */
const additionalSettings = (
<AdditionalSettings
@ -182,7 +165,6 @@ export const MetricsModal = (props: MetricsModalProps) => {
const newVal = !state.fullMetaSearch;
dispatch(setFullMetaSearch(newVal));
onChange({ ...query, fullMetaSearch: newVal });
searchCallback(state.fuzzySearchQuery, newVal);
}}
onChangeIncludeNullMetadata={() => {
@ -234,9 +216,6 @@ export const MetricsModal = (props: MetricsModalProps) => {
dispatch(setFuzzySearchQuery(value));
searchCallback(value, state.fullMetaSearch);
}}
onKeyDown={(e) => {
keyFunction(e);
}}
/>
</div>
{state.hasMetadata && (
@ -299,9 +278,7 @@ export const MetricsModal = (props: MetricsModalProps) => {
onClose={onClose}
query={query}
state={state}
selectedIdx={state.selectedIdx}
disableTextWrap={state.disableTextWrap}
onFocusRow={(idx: number) => dispatch(setSelectedIdx(idx))}
/>
)}
</div>

View File

@ -1,5 +1,5 @@
import { css } from '@emotion/css';
import React, { ReactElement, useEffect, useRef } from 'react';
import React, { ReactElement } from 'react';
import Highlighter from 'react-highlight-words';
import { GrafanaTheme2 } from '@grafana/data';
@ -18,23 +18,15 @@ type ResultsTableProps = {
onClose: () => void;
query: PromVisualQuery;
state: MetricsModalState;
selectedIdx: number;
disableTextWrap: boolean;
onFocusRow: (idx: number) => void;
};
export function ResultsTable(props: ResultsTableProps) {
const { metrics, onChange, onClose, query, state, selectedIdx, disableTextWrap, onFocusRow } = props;
const { metrics, onChange, onClose, query, state, disableTextWrap } = props;
const theme = useTheme2();
const styles = getStyles(theme, disableTextWrap);
const tableRef = useRef<HTMLTableElement | null>(null);
function isSelectedRow(idx: number): boolean {
return idx === selectedIdx;
}
function selectMetric(metric: MetricData) {
if (metric.value) {
onChange({ ...query, metric: metric.value });
@ -43,11 +35,6 @@ export function ResultsTable(props: ResultsTableProps) {
}
}
useEffect(() => {
const tr = tableRef.current?.getElementsByClassName('selected-row')[0];
tr?.scrollIntoView({ block: 'nearest', inline: 'nearest' });
}, [selectedIdx]);
function metaRows(metric: MetricData) {
if (state.fullMetaSearch && metric) {
return (
@ -149,7 +136,7 @@ export function ResultsTable(props: ResultsTableProps) {
}
return (
<table className={styles.table} ref={tableRef}>
<table className={styles.table}>
<thead className={styles.stickyHeader}>
<tr>
<th className={`${styles.nameWidth} ${styles.tableHeaderPadding}`}>Name</th>
@ -167,16 +154,7 @@ export function ResultsTable(props: ResultsTableProps) {
{metrics.length > 0 &&
metrics.map((metric: MetricData, idx: number) => {
return (
<tr
key={metric?.value ?? idx}
className={`${styles.row} ${isSelectedRow(idx) ? `${styles.selectedRow} selected-row` : ''}`}
onFocus={() => onFocusRow(idx)}
onKeyDown={(e) => {
if (e.code === 'Enter' && e.currentTarget.classList.contains('selected-row')) {
selectMetric(metric);
}
}}
>
<tr key={metric?.value ?? idx} className={styles.row}>
<td className={styles.nameOverflow}>
<Highlighter
textToHighlight={metric?.value ?? ''}
@ -207,8 +185,6 @@ export function ResultsTable(props: ResultsTableProps) {
}
const getStyles = (theme: GrafanaTheme2, disableTextWrap: boolean) => {
const rowHoverBg = theme.colors.emphasize(theme.colors.background.primary, 0.03);
return {
table: css`
${disableTextWrap ? '' : 'table-layout: fixed;'}
@ -231,16 +207,10 @@ const getStyles = (theme: GrafanaTheme2, disableTextWrap: boolean) => {
&:last-child {
border-bottom: 0;
}
:hover {
background-color: ${rowHoverBg};
}
`,
tableHeaderPadding: css`
padding: 8px;
`,
selectedRow: css`
background-color: ${rowHoverBg};
`,
matchHighLight: css`
background: inherit;
color: ${theme.components.textHighlight.text};

View File

@ -48,7 +48,6 @@ export const stateSlice = createSlice({
setFuzzySearchQuery: (state, action: PayloadAction<string>) => {
state.fuzzySearchQuery = action.payload;
state.pageNum = 1;
state.selectedIdx = 0;
},
setNameHaystack: (state, action: PayloadAction<string[][]>) => {
state.nameHaystackOrder = action.payload[0];
@ -75,9 +74,6 @@ export const stateSlice = createSlice({
state.fullMetaSearch = false;
state.pageNum = 1;
},
setSelectedIdx: (state, action: PayloadAction<number>) => {
state.selectedIdx = action.payload;
},
setDisableTextWrap: (state) => {
state.disableTextWrap = !state.disableTextWrap;
},
@ -88,7 +84,7 @@ export const stateSlice = createSlice({
});
/**
* Initial state for the Metrics Modal
* Initial state for the metrics explorer
* @returns
*/
export function initialState(query?: PromVisualQuery): MetricsModalState {
@ -112,13 +108,12 @@ export function initialState(query?: PromVisualQuery): MetricsModalState {
selectedTypes: [],
useBackend: query?.useBackend ?? false,
disableTextWrap: query?.disableTextWrap ?? false,
selectedIdx: 0,
showAdditionalSettings: false,
};
}
/**
* The Metrics Modal state object
* The metrics explorer state object
*/
export interface MetricsModalState {
/** Used for the loading spinner */
@ -163,8 +158,6 @@ export interface MetricsModalState {
useBackend: boolean;
/** Disable text wrap for descriptions in the results table */
disableTextWrap: boolean;
/** The selected metric in the table represented by hover style highlighting */
selectedIdx: number;
/** Display toggle switches for settings */
showAdditionalSettings: boolean;
}

View File

@ -37,6 +37,8 @@ export function fuzzySearch(haystack: string[], query: string, dispatcher: (data
}
dispatcher([haystackOrder, [...matchesSet]]);
} else if (!query) {
dispatcher([[], []]);
}
}

View File

@ -9,7 +9,7 @@ export interface PromVisualQuery {
labels: QueryBuilderLabelFilter[];
operations: QueryBuilderOperation[];
binaryQueries?: PromVisualQueryBinary[];
// metrics modal additional settings
// metrics explorer additional settings
useBackend?: boolean;
disableTextWrap?: boolean;
includeNullMetadata?: boolean;

View File

@ -16,7 +16,7 @@ export interface PromQuery extends GenPromQuery, DataQuery {
showingTable?: boolean;
hinting?: boolean;
interval?: string;
// store the metrics modal additional settings
// store the metrics explorer additional settings
useBackend?: boolean;
disableTextWrap?: boolean;
fullMetaSearch?: boolean;