Skip to content

Commit 45e20f4

Browse files
authored
Link from alerts indicator to model alerts view (#3520)
1 parent fcf74b3 commit 45e20f4

File tree

5 files changed

+63
-4
lines changed

5 files changed

+63
-4
lines changed

extensions/ql-vscode/src/common/interface-types.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,10 +752,16 @@ interface StopEvaluationRunMessage {
752752
t: "stopEvaluationRun";
753753
}
754754

755+
interface RevealModelMessage {
756+
t: "revealModel";
757+
modeledMethod: ModeledMethod;
758+
}
759+
755760
export type ToModelAlertsMessage =
756761
| SetModelAlertsViewStateMessage
757762
| SetVariantAnalysisMessage
758-
| SetRepoResultsMessage;
763+
| SetRepoResultsMessage
764+
| RevealModelMessage;
759765

760766
export type FromModelAlertsMessage =
761767
| CommonFromViewMessages

extensions/ql-vscode/src/model-editor/model-alerts/model-alerts-view.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import type {
2020
VariantAnalysisScannedRepositoryResult,
2121
} from "../../variant-analysis/shared/variant-analysis";
2222
import type { AppEvent, AppEventEmitter } from "../../common/events";
23+
import type { ModeledMethod } from "../modeled-method";
2324
import type { MethodSignature } from "../method";
2425

2526
export class ModelAlertsView extends AbstractWebview<
@@ -179,6 +180,14 @@ export class ModelAlertsView extends AbstractWebview<
179180
}
180181
}),
181182
);
183+
184+
this.push(
185+
this.modelingEvents.onRevealInModelAlertsView(async (event) => {
186+
if (event.dbUri === this.dbItem.databaseUri.toString()) {
187+
await this.revealMethod(event.modeledMethod);
188+
}
189+
}),
190+
);
182191
}
183192

184193
private async stopEvaluationRun() {
@@ -195,4 +204,15 @@ export class ModelAlertsView extends AbstractWebview<
195204
method,
196205
);
197206
}
207+
208+
private async revealMethod(method: ModeledMethod): Promise<void> {
209+
const panel = await this.getPanel();
210+
211+
panel?.reveal();
212+
213+
await this.postMessage({
214+
t: "revealModel",
215+
modeledMethod: method,
216+
});
217+
}
198218
}

extensions/ql-vscode/src/view/model-alerts/ModelAlerts.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
filterAndSort,
1818
} from "../../model-editor/shared/model-alerts-filter-sort";
1919
import type { ModelAlertsFilterSortState } from "../../model-editor/shared/model-alerts-filter-sort";
20+
import type { ModeledMethod } from "../../model-editor/modeled-method";
2021

2122
type Props = {
2223
initialViewState?: ModelAlertsViewState;
@@ -62,6 +63,10 @@ export function ModelAlerts({
6263
const [filterSortValue, setFilterSortValue] =
6364
useState<ModelAlertsFilterSortState>(defaultFilterSortState);
6465

66+
const [revealedModel, setRevealedModel] = useState<ModeledMethod | null>(
67+
null,
68+
);
69+
6570
useEffect(() => {
6671
const listener = (evt: MessageEvent) => {
6772
if (evt.origin === window.origin) {
@@ -87,6 +92,10 @@ export function ModelAlerts({
8792
});
8893
break;
8994
}
95+
case "revealModel": {
96+
setRevealedModel(msg.modeledMethod);
97+
break;
98+
}
9099
}
91100
} else {
92101
// sanitize origin
@@ -146,7 +155,11 @@ export function ModelAlerts({
146155
// but we don't have a unique identifier for models. In the future,
147156
// we may need to consider coming up with unique identifiers for models
148157
// and using those as keys.
149-
<ModelAlertsResults key={i} modelAlerts={alerts} />
158+
<ModelAlertsResults
159+
key={i}
160+
modelAlerts={alerts}
161+
revealedModel={revealedModel}
162+
/>
150163
))}
151164
</div>
152165
</div>

extensions/ql-vscode/src/view/model-alerts/ModelAlertsResults.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { styled } from "styled-components";
22
import type { ModelAlerts } from "../../model-editor/model-alerts/model-alerts";
33
import { Codicon } from "../common";
4-
import { useCallback, useState } from "react";
54
import { VSCodeBadge, VSCodeLink } from "@vscode/webview-ui-toolkit/react";
5+
import { useCallback, useEffect, useRef, useState } from "react";
66
import { formatDecimal } from "../../common/number";
77
import AnalysisAlertResult from "../variant-analysis/AnalysisAlertResult";
88
import { MethodName } from "../model-editor/MethodName";
99
import { ModelDetails } from "./ModelDetails";
1010
import { vscode } from "../vscode-api";
11+
import { createModeledMethodKey } from "../../model-editor/modeled-method";
12+
import type { ModeledMethod } from "../../model-editor/modeled-method";
1113

1214
// This will ensure that these icons have a className which we can use in the TitleContainer
1315
const ExpandCollapseCodicon = styled(Codicon)``;
@@ -59,10 +61,12 @@ const Alert = styled.li`
5961

6062
interface Props {
6163
modelAlerts: ModelAlerts;
64+
revealedModel: ModeledMethod | null;
6265
}
6366

6467
export const ModelAlertsResults = ({
6568
modelAlerts,
69+
revealedModel,
6670
}: Props): React.JSX.Element => {
6771
const [isExpanded, setExpanded] = useState(true);
6872
const viewInModelEditor = useCallback(
@@ -73,6 +77,22 @@ export const ModelAlertsResults = ({
7377
}),
7478
[modelAlerts.model],
7579
);
80+
81+
const ref = useRef<HTMLElement>();
82+
83+
useEffect(() => {
84+
if (
85+
revealedModel &&
86+
createModeledMethodKey(modelAlerts.model) ===
87+
createModeledMethodKey(revealedModel)
88+
) {
89+
ref.current?.scrollIntoView({
90+
behavior: "smooth",
91+
block: "center",
92+
});
93+
}
94+
}, [modelAlerts.model, revealedModel]);
95+
7696
return (
7797
<div>
7898
<TitleContainer onClick={() => setExpanded(!isExpanded)}>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export const ModelAlertsIndicator = ({
2424
return null;
2525
}
2626

27-
if (!evaluationRun || !modeledMethod) {
27+
if (!evaluationRun?.variantAnalysis || !modeledMethod) {
2828
return null;
2929
}
3030

0 commit comments

Comments
 (0)