Skip to content

Commit 991005e

Browse files
committed
COO-1725: fix: Troubleshooting panel cannot focus on node URLs.
- Prefer core resources when matching paths to resources. - Avoid showing an "Empty Query" while a search is in progress. - Enable focus button if result is an error. - Merge all-domains into useDomains - simpler & more readable.
1 parent 983fd65 commit 991005e

6 files changed

Lines changed: 52 additions & 119 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"Advanced search parameters": "Advanced search parameters",
66
"Cancel": "Cancel",
77
"Correlation graph already matches search": "Correlation graph already matches search",
8-
"Correlation graph is already focused on the current view.": "Correlation graph is already focused on the current view.",
8+
"Correlation graph is focused on the current view.": "Correlation graph is focused on the current view.",
99
"Correlation result was empty.": "Correlation result was empty.",
1010
"Current view does not provide a starting point for correlation": "Current view does not provide a starting point for correlation",
1111
"Custom": "Custom",

web/src/__tests__/all-domains.spec.ts

Lines changed: 0 additions & 79 deletions
This file was deleted.

web/src/components/Korrel8rPanel.tsx

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,11 @@ export default function Korrel8rPanel() {
4444
const search: Search = useSelector((state: State) => state.plugins?.tp?.get('search'));
4545
const result: Result | null = useSelector((state: State) => state.plugins?.tp?.get('result'));
4646

47-
// Is the search panel already in focus on the main view?
47+
// Disable focus button if the panel is already focused on the current location,
48+
// or the current result is an error.
4849
const isFocused = React.useMemo(
49-
() => locationQuery?.toString() === search.queryStr,
50-
[locationQuery, search.queryStr],
50+
() => locationQuery?.toString() === search.queryStr && !result?.isError,
51+
[locationQuery, search.queryStr, result?.isError],
5152
);
5253

5354
// Showing advanced query
@@ -71,11 +72,22 @@ export default function Korrel8rPanel() {
7172
[dispatch],
7273
);
7374

74-
// Set up default locationQuery search on mount, when query is blank.
75+
// Create the initial result on startup.
76+
// Use the current location or an explicit "Empty" result.
77+
const initialized = React.useRef(false);
7578
React.useEffect(() => {
76-
if (!search?.queryStr && locationQuery?.toString())
77-
dispatchSearch({ ...defaultSearch, queryStr: locationQuery.toString() });
78-
}, [locationQuery, dispatchSearch, search?.queryStr]);
79+
if (initialized.current) return;
80+
initialized.current = true;
81+
if (!search?.queryStr && !result) {
82+
if (locationQuery?.toString())
83+
dispatchSearch({ ...defaultSearch, queryStr: locationQuery.toString() });
84+
else
85+
dispatchResult({
86+
title: t('Empty Query'),
87+
message: t('No starting point for correlation'),
88+
});
89+
}
90+
}, [locationQuery, dispatchSearch, dispatchResult, search?.queryStr, result, t]);
7991

8092
// Skip the first fetch if we already have a stored result.
8193
const useStoredResult = React.useRef(result != null);
@@ -87,10 +99,8 @@ export default function Korrel8rPanel() {
8799
return;
88100
}
89101
const queryStr = search?.queryStr;
90-
if (!queryStr) {
91-
dispatchResult({ title: t('Empty Query'), message: t('No starting point for correlation') });
92-
return;
93-
}
102+
if (!queryStr) return;
103+
94104
let cancelled = false;
95105
const start: api.Start = {
96106
queries: [queryStr],
@@ -141,7 +151,7 @@ export default function Korrel8rPanel() {
141151
content={
142152
locationQuery
143153
? isFocused
144-
? t('Correlation graph is already focused on the current view.')
154+
? t('Correlation graph is focused on the current view.')
145155
: t('Focus the correlation on the current view.')
146156
: t('Current view does not provide a starting point for correlation')
147157
}

web/src/hooks/useDomains.tsx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import * as React from 'react';
22
import { useSelector } from 'react-redux';
33
import { AlertDomain } from '../korrel8r/alert';
4-
import { allDomains } from '../korrel8r/all-domains';
4+
import { K8sDomain } from '../korrel8r/k8s';
5+
import { LogDomain } from '../korrel8r/log';
6+
import { MetricDomain } from '../korrel8r/metric';
7+
import { NetflowDomain } from '../korrel8r/netflow';
8+
import { TraceDomain } from '../korrel8r/trace';
59
import { Domains } from '../korrel8r/types';
610
import { State } from '../redux-reducers';
711

@@ -16,11 +20,17 @@ export const useDomains = () => {
1620
return new Map<string, string>(alertRules.map(({ id, name }) => [id, name]));
1721
}, [alertRules]);
1822

19-
const domains = React.useMemo(() => {
20-
// Alert domain with IDs loaded from state.
21-
const alert = new AlertDomain(alertIDs);
22-
// Replace the default alert domain.
23-
return new Domains(...allDomains.filter((d) => d.name !== alert.name), alert);
24-
}, [alertIDs]);
23+
const domains = React.useMemo(
24+
() =>
25+
new Domains(
26+
new AlertDomain(alertIDs),
27+
new K8sDomain(),
28+
new LogDomain(),
29+
new MetricDomain(),
30+
new NetflowDomain(),
31+
new TraceDomain(),
32+
),
33+
[alertIDs],
34+
);
2535
return domains;
2636
};

web/src/korrel8r/all-domains.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

web/src/korrel8r/k8s.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,14 +183,22 @@ function findGVK(group: string, version: string, kind: string): Model {
183183
// Return a model for the resource, can be G~V~K or path. Return undefined if not found.
184184
function findResource(resource: string): Model {
185185
if (!resource) return;
186-
// Try as a G~V~K string.
186+
// Try as a G~V~K string
187187
const [g, v, k] = resource.split('~');
188188
if (k) return findGVK(g === 'core' ? '' : g, v, k);
189+
// Try as a bare Kind
190+
const m = findGVK('', 'v1', resource);
191+
if (m) return m;
189192
// Try as a resource path
190193
if (resource === 'projects') resource = 'namespaces'; // Alias
191-
return getCachedResources()?.models?.find(
192-
(m: Model) => m.path === resource && m.verbs.includes('watch'),
193-
);
194+
let found: Model;
195+
for (const m of getCachedResources()?.models || []) {
196+
if (m.path === resource && m.verbs.includes('watch')) {
197+
if (!m.apiGroup) return m; // Prefer core models
198+
found = found || m;
199+
}
200+
}
201+
return found;
194202
}
195203

196204
function parseAPIVersion(apiVersion: string): [group: string, version: string] | undefined {

0 commit comments

Comments
 (0)