Implement query history

Signed-off-by: Julius Volz <julius.volz@gmail.com>
pull/14872/head
Julius Volz 2024-09-04 17:25:34 +02:00
parent f3f324be89
commit a99c01b53f
4 changed files with 56 additions and 10 deletions

View File

@ -68,6 +68,7 @@ import { notifications } from "@mantine/notifications";
import { useSettings } from "../../state/settingsSlice";
import MetricsExplorer from "./MetricsExplorer/MetricsExplorer";
import ErrorBoundary from "../../components/ErrorBoundary";
import { useAppSelector } from "../../state/hooks";
const promqlExtension = new PromQLExtension();
@ -127,11 +128,13 @@ const ExpressionInput: FC<ExpressionInputProps> = ({
removePanel,
}) => {
const theme = useComputedColorScheme();
const { queryHistory } = useAppSelector((state) => state.queryPage);
const {
pathPrefix,
enableAutocomplete,
enableSyntaxHighlighting,
enableLinter,
enableQueryHistory,
} = useSettings();
const [expr, setExpr] = useState(initialExpr);
useEffect(() => {
@ -175,10 +178,6 @@ const ExpressionInput: FC<ExpressionInputProps> = ({
const [showMetricsExplorer, setShowMetricsExplorer] = useState(false);
// TODO: Implement query history.
// This is just a placeholder until query history is implemented, so disable the linter warning.
const queryHistory = useMemo<string[]>(() => [], []);
// (Re)initialize editor based on settings / setting changes.
useEffect(() => {
// Build the dynamic part of the config.
@ -193,10 +192,17 @@ const ExpressionInput: FC<ExpressionInputProps> = ({
cache: { initialMetricList: metricNames },
},
}),
queryHistory
enableQueryHistory ? queryHistory : []
),
});
}, [pathPrefix, metricNames, enableAutocomplete, enableLinter, queryHistory]); // TODO: Make this depend on external settings changes, maybe use dynamic config compartment again.
}, [
pathPrefix,
metricNames,
enableAutocomplete,
enableLinter,
enableQueryHistory,
queryHistory,
]); // TODO: Make this depend on external settings changes, maybe use dynamic config compartment again.
return (
<Group align="flex-start" wrap="nowrap" gap="xs">

View File

@ -17,6 +17,7 @@ import {
import { FC, useCallback, useState } from "react";
import { useAppDispatch, useAppSelector } from "../../state/hooks";
import {
addQueryToHistory,
GraphDisplayMode,
GraphResolution,
removePanel,
@ -73,6 +74,10 @@ const QueryPanel: FC<PanelProps> = ({ idx, metricNames }) => {
executeQuery={(expr: string) => {
setRetriggerIdx((idx) => idx + 1);
dispatch(setExpr({ idx, expr }));
if (!metricNames.includes(expr) && expr.trim() !== "") {
dispatch(addQueryToHistory(expr));
}
}}
removePanel={() => {
dispatch(removePanel(idx));

View File

@ -6,9 +6,13 @@ import {
} from "./targetsPageSlice";
import {
localStorageKeyCollapsedPools as localStorageKeyServiceDiscoveryPageCollapsedPools,
setCollapsedPools as ServiceDiscoveryPageSetCollapsedPools,
setCollapsedPools as serviceDiscoveryPageSetCollapsedPools,
} from "./serviceDiscoveryPageSlice";
import { updateSettings } from "./settingsSlice";
import {
addQueryToHistory,
localStorageKeyQueryHistory,
} from "./queryPageSlice";
const persistToLocalStorage = <T>(key: string, value: T) => {
localStorage.setItem(key, JSON.stringify(value));
@ -29,7 +33,7 @@ startAppListening({
});
startAppListening({
actionCreator: ServiceDiscoveryPageSetCollapsedPools,
actionCreator: serviceDiscoveryPageSetCollapsedPools,
effect: ({ payload }) => {
persistToLocalStorage(
localStorageKeyServiceDiscoveryPageCollapsedPools,
@ -38,6 +42,16 @@ startAppListening({
},
});
startAppListening({
actionCreator: addQueryToHistory,
effect: (_, { getState }) => {
persistToLocalStorage(
localStorageKeyQueryHistory,
getState().queryPage.queryHistory
);
},
});
startAppListening({
actionCreator: updateSettings,
effect: ({ payload }) => {

View File

@ -1,6 +1,9 @@
import { randomId } from "@mantine/hooks";
import { PayloadAction, createSlice } from "@reduxjs/toolkit";
import { encodePanelOptionsToURLParams } from "../pages/query/urlStateEncoding";
import { initializeFromLocalStorage } from "./initializeFromLocalStorage";
export const localStorageKeyQueryHistory = "queryPage.queryHistory";
export enum GraphDisplayMode {
Lines = "lines",
@ -68,6 +71,7 @@ export type Panel = {
interface QueryPageState {
panels: Panel[];
queryHistory: string[];
}
export const newDefaultPanel = (): Panel => ({
@ -87,6 +91,10 @@ export const newDefaultPanel = (): Panel => ({
const initialState: QueryPageState = {
panels: [newDefaultPanel()],
queryHistory: initializeFromLocalStorage<string[]>(
localStorageKeyQueryHistory,
[]
),
};
const updateURL = (panels: Panel[]) => {
@ -116,6 +124,12 @@ export const queryPageSlice = createSlice({
state.panels[payload.idx].expr = payload.expr;
updateURL(state.panels);
},
addQueryToHistory: (state, { payload: query }: PayloadAction<string>) => {
state.queryHistory = [
query,
...state.queryHistory.filter((q) => q !== query),
].slice(0, 50);
},
setVisualizer: (
state,
{ payload }: PayloadAction<{ idx: number; visualizer: Visualizer }>
@ -126,7 +140,14 @@ export const queryPageSlice = createSlice({
},
});
export const { setPanels, addPanel, removePanel, setExpr, setVisualizer } =
queryPageSlice.actions;
export const {
setPanels,
addPanel,
removePanel,
setExpr,
addQueryToHistory,
setShowTree,
setVisualizer,
} = queryPageSlice.actions;
export default queryPageSlice.reducer;