Skip to content

Commit c62c054

Browse files
authored
Merge pull request #3001 from github/koesie10/validation-errors-focus
Add higlight on modeled method row when clicking in validation error
2 parents 41aeb47 + faffe45 commit c62c054

File tree

2 files changed

+56
-5
lines changed

2 files changed

+56
-5
lines changed

extensions/ql-vscode/src/stories/model-editor/MethodRow.stories.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as React from "react";
2+
import { useCallback, useEffect, useState } from "react";
23

34
import { Meta, StoryFn } from "@storybook/react";
45

@@ -20,12 +21,33 @@ export default {
2021
} as Meta<typeof MethodRowComponent>;
2122

2223
const Template: StoryFn<typeof MethodRowComponent> = (args) => {
24+
const [modeledMethods, setModeledMethods] = useState<ModeledMethod[]>(
25+
args.modeledMethods,
26+
);
27+
28+
useEffect(() => {
29+
setModeledMethods(args.modeledMethods);
30+
}, [args.modeledMethods]);
31+
32+
const handleChange = useCallback(
33+
(methodSignature: string, modeledMethods: ModeledMethod[]) => {
34+
args.onChange(methodSignature, modeledMethods);
35+
setModeledMethods(modeledMethods);
36+
},
37+
[args],
38+
);
39+
2340
const gridTemplateColumns = args.viewState?.showMultipleModels
2441
? MULTIPLE_MODELS_GRID_TEMPLATE_COLUMNS
2542
: SINGLE_MODEL_GRID_TEMPLATE_COLUMNS;
43+
2644
return (
2745
<DataGrid gridTemplateColumns={gridTemplateColumns}>
28-
<MethodRowComponent {...args} />
46+
<MethodRowComponent
47+
{...args}
48+
modeledMethods={modeledMethods}
49+
onChange={handleChange}
50+
/>
2951
</DataGrid>
3052
);
3153
};

extensions/ql-vscode/src/view/model-editor/MethodRow.tsx

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import {
55
} from "@vscode/webview-ui-toolkit/react";
66
import * as React from "react";
77
import {
8-
Fragment,
98
forwardRef,
109
useCallback,
1110
useEffect,
1211
useMemo,
1312
useRef,
13+
useState,
1414
} from "react";
1515
import { styled } from "styled-components";
1616
import { vscode } from "../vscode-api";
@@ -108,6 +108,32 @@ const ModelableMethodRow = forwardRef<HTMLElement | undefined, MethodRowProps>(
108108
onChange,
109109
} = props;
110110

111+
const [focusedIndex, setFocusedIndex] = useState<number | null>(null);
112+
113+
useEffect(() => {
114+
if (focusedIndex === null) {
115+
return;
116+
}
117+
118+
// If a row is focused, hide it when the user clicks anywhere. In this case, we do need to
119+
// show the user where the method is anymore and they should have seen it.
120+
const listener = () => {
121+
setFocusedIndex(null);
122+
};
123+
124+
// Use a timeout to ensure the click event is not triggered by the click that focused the row.
125+
const timeoutId = setTimeout(
126+
() => window.addEventListener("click", listener),
127+
200,
128+
);
129+
130+
return () => {
131+
clearTimeout(timeoutId);
132+
133+
window.removeEventListener("click", listener);
134+
};
135+
}, [focusedIndex]);
136+
111137
const modeledMethods = useMemo(
112138
() => modeledMethodsToDisplay(modeledMethodsProp, method, viewState),
113139
[modeledMethodsProp, method, viewState],
@@ -212,7 +238,7 @@ const ModelableMethodRow = forwardRef<HTMLElement | undefined, MethodRowProps>(
212238
{!props.modelingInProgress && (
213239
<>
214240
{modeledMethods.map((modeledMethod, index) => (
215-
<Fragment key={index}>
241+
<DataGridRow key={index} focused={focusedIndex === index}>
216242
<DataGridCell>
217243
<ModelTypeDropdown
218244
method={method}
@@ -263,11 +289,14 @@ const ModelableMethodRow = forwardRef<HTMLElement | undefined, MethodRowProps>(
263289
)}
264290
</DataGridCell>
265291
)}
266-
</Fragment>
292+
</DataGridRow>
267293
))}
268294
{validationErrors.map((error, index) => (
269295
<DataGridCell gridColumn="span 5" key={index}>
270-
<ModeledMethodAlert error={error} />
296+
<ModeledMethodAlert
297+
error={error}
298+
setSelectedIndex={setFocusedIndex}
299+
/>
271300
</DataGridCell>
272301
))}
273302
</>

0 commit comments

Comments
 (0)