Skip to content

Commit d29de8d

Browse files
committed
fix(#98): NO-JIRA: Persist query result
Speed up re-opening of the panel. Fixes #98
1 parent 5bef71e commit d29de8d

6 files changed

Lines changed: 56 additions & 53 deletions

File tree

web/locales/en/plugin__troubleshooting-panel-console-plugin.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
"Create a graph of correlated items from resources in the current view.": "Create a graph of correlated items from resources in the curret view.",
55
"Distance": "Distance",
66
"Find all paths to items of the specified goal class.": "Find all paths to items of the specified goal class.",
7-
"Find all related data that can be reached by following up to N correlation rules. Follows rules from the start to directly related data, then from there to indirectly related data, up to the disance you specify.": "Find all related data that can be reached by following up to N correlation rules. Follows rules from the start to directly related data, then from there to indirectly related data, up to the disance you specify.",
87
"Focus": "Focus",
8+
"Follows correlation rules from the starting point to find related data, then continues the search from that data, up to the number of steps you specify.": "Follows correlation rules from the starting point to find related data, then continues the search from that data, up to the number of steps you specify.",
99
"Goal Class": "Goal Class",
1010
"Korrel8r Error": "Korrel8r Error",
1111
"Logging Plugin Disabled": "Logging Plugin Disabled",
@@ -28,4 +28,4 @@
2828
"Troubleshooting": "Troubleshooting",
2929
"Troubleshooting Panel": "Troubleshooting Panel",
3030
"Unable to find Console Link": "Unable to find Console Link"
31-
}
31+
}

web/src/components/Korrel8rPanel.tsx

Lines changed: 33 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,14 @@ import { AlertDomain } from '../korrel8r/alert';
2626
import { allDomains } from '../korrel8r/all-domains';
2727
import * as api from '../korrel8r/client';
2828
import * as korrel8r from '../korrel8r/types';
29-
import { defaultSearch, Search, SearchType, setPersistedSearch } from '../redux-actions';
29+
import {
30+
defaultSearch,
31+
Result,
32+
Search,
33+
SearchResult,
34+
SearchType,
35+
setPersistedSearch,
36+
} from '../redux-actions';
3037
import { State } from '../redux-reducers';
3138
import * as time from '../time';
3239
import { HelpPopover as FieldLevelHelp } from './HelpPopover';
@@ -36,18 +43,11 @@ import TimeRangeFormGroup from './TimeRangeFormGroup';
3643
import { Korrel8rTopology } from './topology/Korrel8rTopology';
3744
import { LoadingTopology } from './topology/LoadingTopology';
3845

39-
type Result = {
40-
graph?: korrel8r.Graph;
41-
message?: string;
42-
title?: string;
43-
isError?: boolean;
44-
};
45-
4646
export default function Korrel8rPanel() {
4747
const { t } = useTranslation('plugin__troubleshooting-panel-console-plugin');
48-
const persistedSearch = useSelector((state: State) => {
48+
const searchResult: SearchResult = useSelector((state: State) => {
4949
return state.plugins?.tp?.get('persistedSearch');
50-
}) as Search;
50+
});
5151
const dispatch = useDispatch();
5252

5353
// State
@@ -61,23 +61,19 @@ export default function Korrel8rPanel() {
6161
[alertIDs],
6262
);
6363
const locationQuery = useLocationQuery(domains);
64-
const [search, setSearch] = React.useState<Search>(
65-
persistedSearch?.queryStr
66-
? persistedSearch
67-
: ({
68-
...defaultSearch,
69-
queryStr: locationQuery?.toString(),
70-
constraint: persistedSearch?.constraint,
71-
} as Search),
72-
);
73-
const [result, setResult] = React.useState<Result | null>(null);
64+
const [search, setSearch] = React.useState<Search>({
65+
...defaultSearch, // Default search parameters.
66+
queryStr: locationQuery?.toString(), // Default query string.
67+
...searchResult?.search, // Use persisted search if available.
68+
});
69+
const [result, setResult] = React.useState<Result | null>(searchResult?.result ?? null);
7470
const [showQuery, setShowQuery] = React.useState(false);
7571

7672
const focusTip = t('Create a graph of correlated items from resources in the current view.');
7773
const cannotFocus = t('The current view does not support correlation.');
7874

7975
React.useEffect(() => {
80-
// Set result = null to trigger a reload, don't run the query till then.
76+
// Set result = null to trigger a new client request, don't run the query till then.
8177
if (result !== null) {
8278
return;
8379
}
@@ -86,7 +82,7 @@ export default function Korrel8rPanel() {
8682
return;
8783
}
8884
// eslint-disable-next-line no-console
89-
console.log('korrel8r search', search);
85+
console.debug('korrel8r search', search);
9086
const queryStr = search?.queryStr?.trim();
9187
const start: api.Start = {
9288
queries: queryStr ? [queryStr] : undefined,
@@ -99,17 +95,21 @@ export default function Korrel8rPanel() {
9995

10096
cancellableFetch
10197
.then((response: api.Graph) => {
102-
setResult({ graph: new korrel8r.Graph(response) });
103-
// Only set the persisted search upon a successful query. It would be a
104-
// poor feeling to create a query that fails, and then be forced to rerun it
105-
// when opening the panel later
106-
dispatch(setPersistedSearch(search));
98+
const result: Result = { graph: new korrel8r.Graph(response) };
99+
// eslint-disable-next-line no-console
100+
console.debug('korrel8r result', result);
101+
setResult(result);
102+
dispatch(setPersistedSearch({ search, result }));
107103
})
108104
.catch((e: api.ApiError) => {
109-
setResult({
105+
const result = {
110106
message: e.body?.error || e.message || 'Unknown Error',
111107
title: e?.body?.error ? t('Korrel8r Error') : t('Request Failed'),
112-
});
108+
};
109+
// eslint-disable-next-line no-console
110+
console.debug('korrel8r result', result);
111+
setResult(result);
112+
dispatch(setPersistedSearch({ search, result }));
113113
});
114114
return () => cancellableFetch.cancel();
115115
}, [result, t, dispatch, search, cannotFocus, locationQuery]);
@@ -159,8 +159,8 @@ export default function Korrel8rPanel() {
159159
runSearch({
160160
...defaultSearch,
161161
queryStr: locationQuery?.toString(),
162-
constraint: persistedSearch?.constraint,
163-
period: persistedSearch?.period,
162+
constraint: searchResult?.search?.constraint,
163+
period: searchResult?.search?.period,
164164
})
165165
}
166166
>
@@ -320,16 +320,6 @@ const TopologyInfoState: React.FC<TopologyInfoStateProps> = ({ titleText, text,
320320
);
321321
};
322322

323-
const applyBounds = (minValue: number, maxValue: number) => {
324-
return (val: number) => {
325-
if (!val || val < minValue) {
326-
return minValue;
327-
} else if (val > maxValue) {
328-
return maxValue;
329-
} else {
330-
return val;
331-
}
332-
};
323+
const applyBounds = (min: number, max: number) => {
324+
return (val: number) => Math.max(min, Math.min(val, max));
333325
};
334-
335-
// {/* FIXME Tooltips or popovers uniformly */}

web/src/components/topology/Korrel8rTopology.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ export const Korrel8rTopology: React.FC<{
153153
if (!link) return;
154154
if (!link.startsWith('/')) link = '/' + link;
155155
// eslint-disable-next-line no-console
156-
console.log(
156+
console.debug(
157157
'korrel8r navigate',
158158
'\nquery',
159159
query,

web/src/hooks/useTroubleshootingPanel.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { InfrastructureIcon } from '@patternfly/react-icons';
33
import * as React from 'react';
44
import { useTranslation } from 'react-i18next';
55
import { useDispatch } from 'react-redux';
6-
import { defaultSearch, openTP, setPersistedSearch } from '../redux-actions';
6+
import { openTP } from '../redux-actions';
77
import { useKorrel8r } from './useKorrel8r';
88

99
const useTroubleshootingPanel: ExtensionHook<Array<Action>> = () => {
@@ -12,7 +12,6 @@ const useTroubleshootingPanel: ExtensionHook<Array<Action>> = () => {
1212
const [perspective] = useActivePerspective();
1313
const dispatch = useDispatch();
1414
const open = React.useCallback(() => {
15-
dispatch(setPersistedSearch(defaultSearch));
1615
dispatch(openTP());
1716
}, [dispatch]);
1817

web/src/redux-actions.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { action, ActionType as Action } from 'typesafe-actions';
2-
import { Constraint } from './korrel8r/types';
2+
import { Constraint, Graph } from './korrel8r/types';
33
import { DAY, Duration, Period } from './time';
44

55
export enum ActionType {
@@ -23,7 +23,21 @@ export type Search = {
2323
period?: Period; // Constraint is updated from period on each call.
2424
};
2525

26-
// Default search parameters for new searches.
26+
// Result displayed in troubleshooting panel, graph or error.
27+
export type Result = {
28+
graph?: Graph;
29+
message?: string;
30+
title?: string;
31+
isError?: boolean;
32+
};
33+
34+
// Search parameters and result of the last search.
35+
export type SearchResult = {
36+
search: Search;
37+
result?: Result;
38+
};
39+
40+
// Default search parameters do a neighbourhood search of depth 3.
2741
export const defaultSearch = {
2842
type: SearchType.Distance,
2943
depth: 3,
@@ -32,8 +46,8 @@ export const defaultSearch = {
3246

3347
export const closeTP = () => action(ActionType.CloseTroubleshootingPanel);
3448
export const openTP = () => action(ActionType.OpenTroubleshootingPanel);
35-
export const setPersistedSearch = (query: Search) =>
36-
action(ActionType.SetPersistedSearch, { query });
49+
export const setPersistedSearch = (searchResult: SearchResult) =>
50+
action(ActionType.SetPersistedSearch, searchResult);
3751

3852
export const actions = {
3953
closeTP,

web/src/redux-reducers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const reducer = (state: TPState, action: TPAction): TPState => {
2828
return state.set('isOpen', true);
2929

3030
case ActionType.SetPersistedSearch:
31-
return state.set('persistedSearch', action.payload.query);
31+
return state.set('persistedSearch', action.payload);
3232

3333
default:
3434
break;

0 commit comments

Comments
 (0)