Skip to content

Commit 0a75a0e

Browse files
Merge pull request #2983 from github/robertbrignull/remove_selected_model
Handle when the number of modeled methods decreases
2 parents c62c054 + 07a4ffb commit 0a75a0e

File tree

2 files changed

+141
-2
lines changed

2 files changed

+141
-2
lines changed

extensions/ql-vscode/src/view/method-modeling/MultipleModeledMethodsPanel.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from "react";
2-
import { useCallback, useMemo, useState } from "react";
2+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
33
import { Method } from "../../model-editor/method";
44
import { ModeledMethod } from "../../model-editor/modeled-method";
55
import {
@@ -60,6 +60,22 @@ export const MultipleModeledMethodsPanel = ({
6060
}: MultipleModeledMethodsPanelProps) => {
6161
const [selectedIndex, setSelectedIndex] = useState<number>(0);
6262

63+
const selectNewMethod = useRef<number | null>(null);
64+
65+
useEffect(() => {
66+
if (selectNewMethod.current === modeledMethods.length - 1) {
67+
setSelectedIndex(selectNewMethod.current);
68+
selectNewMethod.current = null;
69+
return;
70+
}
71+
72+
if (selectedIndex >= modeledMethods.length) {
73+
setSelectedIndex(
74+
modeledMethods.length > 0 ? modeledMethods.length - 1 : 0,
75+
);
76+
}
77+
}, [modeledMethods.length, selectedIndex]);
78+
6379
const handlePreviousClick = useCallback(() => {
6480
setSelectedIndex((previousIndex) => previousIndex - 1);
6581
}, []);
@@ -89,7 +105,7 @@ export const MultipleModeledMethodsPanel = ({
89105
const newModeledMethods = [...modeledMethods, newModeledMethod];
90106

91107
onChange(method.signature, newModeledMethods);
92-
setSelectedIndex(newModeledMethods.length - 1);
108+
selectNewMethod.current = newModeledMethods.length - 1;
93109
}, [onChange, modeledMethods, method]);
94110

95111
const handleRemoveClick = useCallback(() => {

extensions/ql-vscode/src/view/method-modeling/__tests__/MultipleModeledMethodsPanel.spec.tsx

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,30 @@ describe(MultipleModeledMethodsPanel.name, () => {
162162
},
163163
]);
164164
});
165+
166+
it("changes selection to the newly added modeling", async () => {
167+
const { rerender } = render({
168+
method,
169+
modeledMethods,
170+
isModelingInProgress,
171+
onChange,
172+
});
173+
174+
await userEvent.click(screen.getByLabelText("Add modeling"));
175+
176+
rerender(
177+
<MultipleModeledMethodsPanel
178+
method={method}
179+
modeledMethods={
180+
onChange.mock.calls[onChange.mock.calls.length - 1][1]
181+
}
182+
isModelingInProgress={isModelingInProgress}
183+
onChange={onChange}
184+
/>,
185+
);
186+
187+
expect(screen.getByText("2/2")).toBeInTheDocument();
188+
});
165189
});
166190

167191
describe("with two modeled methods", () => {
@@ -264,6 +288,33 @@ describe(MultipleModeledMethodsPanel.name, () => {
264288
).toHaveValue("source");
265289
});
266290

291+
it("correctly updates selected pagination index when the number of models decreases", async () => {
292+
const { rerender } = render({
293+
method,
294+
modeledMethods,
295+
isModelingInProgress,
296+
onChange,
297+
});
298+
299+
await userEvent.click(screen.getByLabelText("Next modeling"));
300+
301+
rerender(
302+
<MultipleModeledMethodsPanel
303+
method={method}
304+
modeledMethods={[modeledMethods[1]]}
305+
isModelingInProgress={isModelingInProgress}
306+
onChange={onChange}
307+
/>,
308+
);
309+
310+
expect(screen.getAllByRole("combobox")).toHaveLength(4);
311+
expect(
312+
screen.getByRole("combobox", {
313+
name: "Model type",
314+
}),
315+
).toHaveValue("source");
316+
});
317+
267318
it("does not show errors", () => {
268319
render({
269320
method,
@@ -444,6 +495,32 @@ describe(MultipleModeledMethodsPanel.name, () => {
444495
screen.getByText("Error: Conflicting classification"),
445496
).toBeInTheDocument();
446497
});
498+
499+
it("changes selection to the newly added modeling", async () => {
500+
const { rerender } = render({
501+
method,
502+
modeledMethods,
503+
isModelingInProgress,
504+
onChange,
505+
});
506+
507+
expect(screen.getByText("1/2")).toBeInTheDocument();
508+
509+
await userEvent.click(screen.getByLabelText("Add modeling"));
510+
511+
rerender(
512+
<MultipleModeledMethodsPanel
513+
method={method}
514+
modeledMethods={
515+
onChange.mock.calls[onChange.mock.calls.length - 1][1]
516+
}
517+
isModelingInProgress={isModelingInProgress}
518+
onChange={onChange}
519+
/>,
520+
);
521+
522+
expect(screen.getByText("3/3")).toBeInTheDocument();
523+
});
447524
});
448525

449526
describe("with three modeled methods", () => {
@@ -559,6 +636,52 @@ describe(MultipleModeledMethodsPanel.name, () => {
559636
}),
560637
).toHaveValue("remote");
561638
});
639+
640+
it("preserves selection when a modeling other than the selected modeling is removed", async () => {
641+
const { rerender } = render({
642+
method,
643+
modeledMethods,
644+
isModelingInProgress,
645+
onChange,
646+
});
647+
648+
expect(screen.getByText("1/3")).toBeInTheDocument();
649+
650+
rerender(
651+
<MultipleModeledMethodsPanel
652+
method={method}
653+
modeledMethods={modeledMethods.slice(0, 2)}
654+
isModelingInProgress={isModelingInProgress}
655+
onChange={onChange}
656+
/>,
657+
);
658+
659+
expect(screen.getByText("1/2")).toBeInTheDocument();
660+
});
661+
662+
it("reduces selection when the selected modeling is removed", async () => {
663+
const { rerender } = render({
664+
method,
665+
modeledMethods,
666+
isModelingInProgress,
667+
onChange,
668+
});
669+
670+
await userEvent.click(screen.getByLabelText("Next modeling"));
671+
await userEvent.click(screen.getByLabelText("Next modeling"));
672+
expect(screen.getByText("3/3")).toBeInTheDocument();
673+
674+
rerender(
675+
<MultipleModeledMethodsPanel
676+
method={method}
677+
modeledMethods={modeledMethods.slice(0, 2)}
678+
isModelingInProgress={isModelingInProgress}
679+
onChange={onChange}
680+
/>,
681+
);
682+
683+
expect(screen.getByText("2/2")).toBeInTheDocument();
684+
});
562685
});
563686

564687
describe("with 1 modeled and 1 unmodeled method", () => {

0 commit comments

Comments
 (0)