Skip to content

Commit 2303ce6

Browse files
Merge pull request #154 from alanconway/coo-1119-ui
COO-119: fix(COO-1119): Improve text and layout of troubleshooting panel.
2 parents d06a1f0 + 0fb2c82 commit 2303ce6

8 files changed

Lines changed: 187 additions & 121 deletions

File tree

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
{
2+
"<0><0><0>Age</0><1>Return only results more recent than the specified age.</1></0><1><0>Range</0><1>Return only results in the specified time range.</1></1></0>": "<0><0><0>Age</0><1>Return only results more recent than the specified age.</1></0><1><0>Range</0><1>Return only results in the specified time range.</1></1></0>",
3+
"<0><0><0>Distance</0><1>Find all related items up to the specified distance.</1></0><1><0>Goal Class</0><1>Find all paths to items of the specified goal class.</1></1></0>": "<0><0><0>Distance</0><1>Find all related items up to the specified distance.</1></0><1><0>Goal Class</0><1>Find all paths to items of the specified goal class.</1></1></0>",
4+
"<0>Selects the starting point for correlation search. The query is set by the<1>Focus</1> button or you can edit it manually.</0>": "<0>Selects the starting point for correlation search. The query is set by the<1>Focus</1> button or you can edit it manually.</0>",
5+
"Advanced": "Advanced",
6+
"Age": "Age",
27
"Correlation result was empty.": "Correlation result was empty.",
3-
"Duration": "Duration",
8+
"Create a graph of correlated items from resources in the current view.": "Create a graph of correlated items from resources in the current view.",
9+
"Distance": "Distance",
410
"Find related resources.": "Find related resources.",
511
"Focus": "Focus",
6-
"Follow paths to class": "Follow paths to class",
7-
"Follow up to": "Follow up to",
8-
"Generate a correlation graph starting from resources in the current view.": "Generate a correlation graph starting from resources in the current view.",
9-
"Goal": "Goal",
12+
"Goal Class": "Goal Class",
1013
"Korrel8r Error": "Korrel8r Error",
11-
"Last": "Last",
1214
"Logging Plugin Disabled": "Logging Plugin Disabled",
13-
"Neighbourhood": "Neighbourhood",
1415
"Netflow Plugin Disabled": "Netflow Plugin Disabled",
1516
"No Correlated Signals Found": "No Correlated Signals Found",
1617
"Open the Troubleshooting Panel": "Open the Troubleshooting Panel",
1718
"Query": "Query",
18-
"Query to select the starting resources for correlation.": "Query to select the starting resources for correlation.",
1919
"Range": "Range",
20-
"Refresh the graph using the current search settings": "Refresh the graph using the current search settings",
20+
"Refresh the graph using the current settings": "Refresh the graph using the current settings",
2121
"Request Failed": "Request Failed",
22-
"rules": "rules",
2322
"Search Type": "Search Type",
2423
"The current view does not support correlation.": "The current view does not support correlation.",
25-
"Time Range": "Time Range",
24+
"Time": "Time",
25+
"to": "to",
2626
"Troubleshooting": "Troubleshooting",
2727
"Troubleshooting Panel": "Troubleshooting Panel",
2828
"Unable to find Console Link": "Unable to find Console Link"

web/src/components/DateTimePicker.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import {
22
DatePicker,
33
InputGroup,
44
InputGroupItem,
5-
InputGroupText,
65
isValidDate,
76
TimePicker,
87
yyyyMMddFormat,
@@ -14,17 +13,14 @@ import { copyTime, setTime } from '../time';
1413
export const DateTimePicker: React.FC<{
1514
date: Date;
1615
onChange: (date: Date) => void;
17-
label: string;
18-
}> = ({ date, onChange, label }) => {
16+
}> = ({ date, onChange }) => {
1917
if (!isValidDate(date)) date = new Date();
2018
return (
2119
<InputGroup>
22-
<InputGroupText isPlain>{label}</InputGroupText>
2320
<InputGroupItem>
2421
<DatePicker
2522
value={isValidDate(date) ? yyyyMMddFormat(date) : ''}
2623
onChange={(_event, _inputDate, newDate) => onChange(copyTime(newDate, date))}
27-
aria-label={label}
2824
/>
2925
</InputGroupItem>
3026
<InputGroupItem>

web/src/components/HelpPopover.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Button, Icon, Popover } from '@patternfly/react-core';
2+
import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons';
3+
import * as React from 'react';
4+
5+
interface HelpPopoverProps {
6+
header?: string;
7+
children?: React.ReactNode;
8+
}
9+
10+
export const HelpPopover: React.FC<HelpPopoverProps> = ({ header, children }) => {
11+
return (
12+
<Popover headerContent=<>{header}</> bodyContent={children}>
13+
<Button variant="plain" isInline>
14+
<Icon isInline size="sm">
15+
<OutlinedQuestionCircleIcon />
16+
</Icon>
17+
</Button>
18+
</Popover>
19+
);
20+
};

web/src/components/Korrel8rPanel.tsx

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ import {
1515
TextArea,
1616
Tooltip,
1717
} from '@patternfly/react-core';
18-
import { CogIcon, CubesIcon, ExclamationCircleIcon, SyncIcon } from '@patternfly/react-icons';
18+
import { CubesIcon, ExclamationCircleIcon, SyncIcon } from '@patternfly/react-icons';
1919
import * as React from 'react';
20-
import { TFunction, useTranslation } from 'react-i18next';
20+
import { TFunction, Trans, useTranslation } from 'react-i18next';
2121
import { useDispatch, useSelector } from 'react-redux';
2222
import { useLocationQuery } from '../hooks/useLocationQuery';
2323
import { usePluginAvailable } from '../hooks/usePluginAvailable';
@@ -29,6 +29,7 @@ import * as korrel8r from '../korrel8r/types';
2929
import { defaultSearch, Search, SearchType, setPersistedSearch } from '../redux-actions';
3030
import { State } from '../redux-reducers';
3131
import * as time from '../time';
32+
import { HelpPopover as FieldLevelHelp } from './HelpPopover';
3233
import './korrel8rpanel.css';
3334
import { SearchFormGroup } from './SearchFormGroup';
3435
import TimeRangeFormGroup from './TimeRangeFormGroup';
@@ -72,7 +73,7 @@ export default function Korrel8rPanel() {
7273
const [result, setResult] = React.useState<Result | null>(null);
7374
const [showQuery, setShowQuery] = React.useState(false);
7475

75-
const focusTip = t('Create a graph starting from resources in the current view.');
76+
const focusTip = t('Create a graph of correlated items from resources in the current view.');
7677
const cannotFocus = t('The current view does not support correlation.');
7778

7879
React.useEffect(() => {
@@ -127,13 +128,27 @@ export default function Korrel8rPanel() {
127128
newSearch.constraint = new korrel8r.Constraint({ ...newSearch.constraint, start, end });
128129
}
129130
newSearch.depth = depthBounds(newSearch.depth);
130-
newSearch.type = !newSearch.goal ? SearchType.Neighbour : newSearch.type;
131+
newSearch.type = !newSearch.goal ? SearchType.Distance : newSearch.type;
131132
setSearch(newSearch);
132133
setResult(null);
133134
},
134135
[setResult, depthBounds],
135136
);
136137

138+
const queryHelp = (
139+
<>
140+
{t('Query')}
141+
<FieldLevelHelp header={t('Query')}>
142+
<Trans t={t}>
143+
<p>
144+
Selects the starting point for correlation search. The query is set by the
145+
<code>Focus</code> button or you can edit it manually.
146+
</p>
147+
</Trans>
148+
</FieldLevelHelp>
149+
</>
150+
);
151+
137152
return (
138153
<>
139154
<Flex className="tp-plugin__panel-query-container">
@@ -154,24 +169,18 @@ export default function Korrel8rPanel() {
154169
</Tooltip>
155170

156171
<Flex align={{ default: 'alignRight' }}>
157-
<Tooltip content={t('Open graph query settings.')}>
158-
<ExpandableSectionToggle
159-
contentId={queryContentID}
160-
toggleId={queryToggleID}
161-
isExpanded={showQuery}
162-
onToggle={(on: boolean) => {
163-
setShowQuery(on);
164-
}}
165-
>
166-
<CogIcon />
167-
</ExpandableSectionToggle>
168-
</Tooltip>
169-
<Tooltip content={t('Refresh graph from current settings')}>
170-
<Button
171-
isAriaDisabled={!search?.queryStr}
172-
onClick={() => runSearch(search)}
173-
variant="secondary"
174-
>
172+
<ExpandableSectionToggle
173+
contentId={queryContentID}
174+
toggleId={queryToggleID}
175+
isExpanded={showQuery}
176+
onToggle={(on: boolean) => {
177+
setShowQuery(on);
178+
}}
179+
>
180+
{t('Advanced')}
181+
</ExpandableSectionToggle>
182+
<Tooltip content={t('Refresh the graph using the current settings')}>
183+
<Button isAriaDisabled={!search?.queryStr} onClick={() => runSearch(search)}>
175184
<SyncIcon />
176185
</Button>
177186
</Tooltip>
@@ -188,11 +197,11 @@ export default function Korrel8rPanel() {
188197
isIndented
189198
>
190199
<Form>
191-
{/* FIXME Rename */}
192200
<TimeRangeFormGroup
193-
label={t('Time Range')}
201+
label={t('Time')}
194202
period={search.period}
195203
onChange={(period: time.Period): void => setSearch({ ...search, period })}
204+
t={t}
196205
/>
197206
<SearchFormGroup
198207
label={t('Search Type')}
@@ -202,15 +211,19 @@ export default function Korrel8rPanel() {
202211
maxDepth={100}
203212
t={t}
204213
/>
205-
<FormGroup label={t('Query')} className="tp-plugin__panel-query-input">
206-
<Tooltip content={t('Query selecting start resources for correlation.')}>
207-
<TextArea
208-
value={search.queryStr}
209-
onChange={(_event, value) => setSearch({ ...search, queryStr: value })}
210-
placeholder="domain:class:selector"
211-
id={queryInputID}
212-
/>
213-
</Tooltip>
214+
<FormGroup className="tp-plugin__panel-query-input" label={queryHelp}>
215+
<TextArea
216+
value={search.queryStr}
217+
onChange={(_event, value) => setSearch({ ...search, queryStr: value })}
218+
onKeyDown={(event) => {
219+
if (event.key === 'Enter' && !event.shiftKey) {
220+
event.preventDefault();
221+
runSearch(search);
222+
}
223+
}}
224+
placeholder="domain:class:selector (shift-enter for new line)"
225+
id={queryInputID}
226+
/>
214227
</FormGroup>
215228
</Form>
216229
</ExpandableSection>

web/src/components/SearchFormGroup.tsx

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
import {
2-
Flex,
3-
FlexItem,
2+
DescriptionList,
3+
DescriptionListDescription,
4+
DescriptionListGroup,
5+
DescriptionListTerm,
46
FormGroup,
57
InputGroup,
68
InputGroupItem,
7-
InputGroupText,
89
NumberInput,
910
TextInput,
1011
} from '@patternfly/react-core';
1112
import * as React from 'react';
12-
import { TFunction } from 'react-i18next';
13+
import { TFunction, Trans } from 'react-i18next';
1314
import { Search, SearchType } from '../redux-actions';
1415
import { Chooser } from './Chooser';
16+
import { HelpPopover } from './HelpPopover';
1517

1618
export interface SearchFormGroupProps {
1719
search: Search;
@@ -36,14 +38,12 @@ export const SearchFormGroup: React.FC<SearchFormGroupProps> = ({
3638
onChange={(id: string) => onChange({ ...search, type: id as SearchType })}
3739
items={[
3840
{
39-
id: SearchType.Neighbour,
40-
label: t('Neighbourhood'),
41-
tooltip: t('Find neighbours by traversing up to the specified depth.'),
41+
id: SearchType.Distance,
42+
label: t('Distance'),
4243
},
4344
{
4445
id: SearchType.Goal,
45-
label: t('Goal Search'),
46-
tooltip: t('Find all paths to the goal class.'),
46+
label: t('Goal Class'),
4747
},
4848
]}
4949
/>
@@ -53,9 +53,8 @@ export const SearchFormGroup: React.FC<SearchFormGroupProps> = ({
5353
if (n) onChange({ ...search, depth: Math.min(maxDepth, Math.max(minDepth, n)) });
5454
};
5555

56-
const neighbourInput = (
56+
const distanceInput = (
5757
<InputGroup>
58-
<InputGroupText isPlain>{t('Depth')}</InputGroupText>
5958
<InputGroupItem>
6059
<NumberInput
6160
value={search.depth}
@@ -71,27 +70,46 @@ export const SearchFormGroup: React.FC<SearchFormGroupProps> = ({
7170

7271
const goalInput = (
7372
<InputGroup>
74-
<InputGroupText isPlain>{t('Goal class for search:')}</InputGroupText>
7573
<InputGroupItem>
7674
<TextInput
7775
value={search.goal}
78-
placeholder="domain:class"
76+
placeholder="domain:classname"
7977
onChange={(e) => onChange({ ...search, goal: (e.target as HTMLInputElement).value })}
8078
/>
8179
</InputGroupItem>
8280
</InputGroup>
8381
);
8482

83+
const help = (
84+
<HelpPopover header={label}>
85+
<Trans t={t}>
86+
<DescriptionList>
87+
<DescriptionListGroup>
88+
<DescriptionListTerm>Distance</DescriptionListTerm>
89+
<DescriptionListDescription>
90+
Find all related items up to the specified distance.
91+
</DescriptionListDescription>
92+
</DescriptionListGroup>
93+
<DescriptionListGroup>
94+
<DescriptionListTerm>Goal Class</DescriptionListTerm>
95+
<DescriptionListDescription>
96+
Find all paths to items of the specified goal class.
97+
</DescriptionListDescription>
98+
</DescriptionListGroup>
99+
</DescriptionList>
100+
</Trans>
101+
</HelpPopover>
102+
);
103+
85104
return (
86105
<FormGroup
87-
label={
88-
<Flex direction={{ default: 'row' }}>
89-
<FlexItem>{label}</FlexItem>
90-
{chooser}
91-
</Flex>
92-
}
106+
label=<>
107+
{label}
108+
{help}
109+
</>
93110
>
94-
{search.type == SearchType.Neighbour ? neighbourInput : goalInput}
111+
{chooser}
112+
{search.type == SearchType.Distance ? distanceInput : goalInput}
95113
</FormGroup>
96114
);
97115
};

0 commit comments

Comments
 (0)