Skip to content

Commit 3b00d74

Browse files
authored
Hook method modeling view to modeling store (#2870)
1 parent 4efd3f8 commit 3b00d74

File tree

5 files changed

+115
-17
lines changed

5 files changed

+115
-17
lines changed

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

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,11 +599,28 @@ export type FromModelEditorMessage =
599599

600600
export type FromMethodModelingMessage =
601601
| TelemetryMessage
602-
| UnhandledErrorMessage;
602+
| UnhandledErrorMessage
603+
| SetModeledMethodMessage;
603604

604605
interface SetMethodMessage {
605606
t: "setMethod";
606607
method: Method;
607608
}
608609

609-
export type ToMethodModelingMessage = SetMethodMessage;
610+
interface SetMethodModifiedMessage {
611+
t: "setMethodModified";
612+
isModified: boolean;
613+
}
614+
615+
interface SetSelectedMethodMessage {
616+
t: "setSelectedMethod";
617+
method: Method;
618+
modeledMethod: ModeledMethod;
619+
isModified: boolean;
620+
}
621+
622+
export type ToMethodModelingMessage =
623+
| SetMethodMessage
624+
| SetModeledMethodMessage
625+
| SetMethodModifiedMessage
626+
| SetSelectedMethodMessage;

extensions/ql-vscode/src/model-editor/method-modeling/method-modeling-panel.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ import { App } from "../../common/app";
33
import { DisposableObject } from "../../common/disposable-object";
44
import { MethodModelingViewProvider } from "./method-modeling-view-provider";
55
import { Method } from "../method";
6+
import { ModelingStore } from "../modeling-store";
67

78
export class MethodModelingPanel extends DisposableObject {
89
private readonly provider: MethodModelingViewProvider;
910

10-
constructor(app: App) {
11+
constructor(app: App, modelingStore: ModelingStore) {
1112
super();
1213

13-
this.provider = new MethodModelingViewProvider(app);
14+
this.provider = new MethodModelingViewProvider(app, modelingStore);
1415
this.push(this.provider);
1516
this.push(
1617
window.registerWebviewViewProvider(

extensions/ql-vscode/src/model-editor/method-modeling/method-modeling-view-provider.ts

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { App } from "../../common/app";
99
import { redactableError } from "../../common/errors";
1010
import { Method } from "../method";
1111
import { DisposableObject } from "../../common/disposable-object";
12+
import { ModelingStore } from "../modeling-store";
1213

1314
export class MethodModelingViewProvider
1415
extends DisposableObject
@@ -18,7 +19,12 @@ export class MethodModelingViewProvider
1819

1920
private webviewView: vscode.WebviewView | undefined = undefined;
2021

21-
constructor(private readonly app: App) {
22+
private method: Method | undefined = undefined;
23+
24+
constructor(
25+
private readonly app: App,
26+
private readonly modelingStore: ModelingStore,
27+
) {
2228
super();
2329
}
2430

@@ -51,9 +57,13 @@ export class MethodModelingViewProvider
5157
webviewView.webview.onDidReceiveMessage(async (msg) => this.onMessage(msg));
5258

5359
this.webviewView = webviewView;
60+
61+
this.registerToModelingStoreEvents();
5462
}
5563

5664
public async setMethod(method: Method): Promise<void> {
65+
this.method = method;
66+
5767
if (this.webviewView) {
5868
await this.webviewView.webview.postMessage({
5969
t: "setMethod",
@@ -64,6 +74,18 @@ export class MethodModelingViewProvider
6474

6575
private async onMessage(msg: FromMethodModelingMessage): Promise<void> {
6676
switch (msg.t) {
77+
case "setModeledMethod": {
78+
const activeState = this.modelingStore.getStateForActiveDb();
79+
if (!activeState) {
80+
throw new Error("No active state found in modeling store");
81+
}
82+
this.modelingStore.updateModeledMethod(
83+
activeState.databaseItem,
84+
msg.method,
85+
);
86+
break;
87+
}
88+
6789
case "telemetry": {
6890
telemetryListener?.sendUIInteraction(msg.action);
6991
break;
@@ -79,4 +101,40 @@ export class MethodModelingViewProvider
79101
break;
80102
}
81103
}
104+
105+
private registerToModelingStoreEvents(): void {
106+
this.modelingStore.onModeledMethodsChanged(async (e) => {
107+
if (this.webviewView && e.isActiveDb) {
108+
const modeledMethod = e.modeledMethods[this.method?.signature ?? ""];
109+
if (modeledMethod) {
110+
await this.webviewView.webview.postMessage({
111+
t: "setModeledMethod",
112+
method: modeledMethod,
113+
});
114+
}
115+
}
116+
});
117+
118+
this.modelingStore.onModifiedMethodsChanged(async (e) => {
119+
if (this.webviewView && e.isActiveDb && this.method) {
120+
const isModified = e.modifiedMethods.has(this.method.signature);
121+
await this.webviewView.webview.postMessage({
122+
t: "setMethodModified",
123+
isModified,
124+
});
125+
}
126+
});
127+
128+
this.modelingStore.onSelectedMethodChanged(async (e) => {
129+
if (this.webviewView) {
130+
this.method = e.method;
131+
await this.webviewView.webview.postMessage({
132+
t: "setSelectedMethod",
133+
method: e.method,
134+
modeledMethod: e.modeledMethod,
135+
isModified: e.isModified,
136+
});
137+
}
138+
});
139+
}
82140
}

extensions/ql-vscode/src/model-editor/model-editor-module.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ export class ModelEditorModule extends DisposableObject {
4242
this.methodsUsagePanel = this.push(
4343
new MethodsUsagePanel(this.modelingStore, cliServer),
4444
);
45-
this.methodModelingPanel = this.push(new MethodModelingPanel(app));
45+
this.methodModelingPanel = this.push(
46+
new MethodModelingPanel(app, this.modelingStore),
47+
);
4648

4749
this.registerToModelingStoreEvents();
4850
}

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

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import * as React from "react";
2-
import { useEffect, useState } from "react";
2+
import { useEffect, useMemo, useState } from "react";
33
import { MethodModeling } from "./MethodModeling";
4-
import { ModelingStatus } from "../../model-editor/shared/modeling-status";
4+
import { getModelingStatus } from "../../model-editor/shared/modeling-status";
55
import { Method } from "../../model-editor/method";
66
import { ToMethodModelingMessage } from "../../common/interface-types";
77
import { assertNever } from "../../common/helpers-pure";
88
import { ModeledMethod } from "../../model-editor/modeled-method";
9+
import { vscode } from "../vscode-api";
910

1011
export function MethodModelingView(): JSX.Element {
1112
const [method, setMethod] = useState<Method | undefined>(undefined);
@@ -14,14 +15,34 @@ export function MethodModelingView(): JSX.Element {
1415
ModeledMethod | undefined
1516
>(undefined);
1617

18+
const [isMethodModified, setIsMethodModified] = useState<boolean>(false);
19+
20+
const modelingStatus = useMemo(
21+
() => getModelingStatus(modeledMethod, isMethodModified),
22+
[modeledMethod, isMethodModified],
23+
);
24+
1725
useEffect(() => {
1826
const listener = (evt: MessageEvent) => {
1927
if (evt.origin === window.origin) {
2028
const msg: ToMethodModelingMessage = evt.data;
21-
if (msg.t === "setMethod") {
22-
setMethod(msg.method);
23-
} else {
24-
assertNever(msg.t);
29+
switch (msg.t) {
30+
case "setMethod":
31+
setMethod(msg.method);
32+
break;
33+
case "setModeledMethod":
34+
setModeledMethod(msg.method);
35+
break;
36+
case "setMethodModified":
37+
setIsMethodModified(msg.isModified);
38+
break;
39+
case "setSelectedMethod":
40+
setMethod(msg.method);
41+
setModeledMethod(msg.modeledMethod);
42+
setIsMethodModified(msg.isModified);
43+
break;
44+
default:
45+
assertNever(msg);
2546
}
2647
} else {
2748
// sanitize origin
@@ -40,12 +61,11 @@ export function MethodModelingView(): JSX.Element {
4061
return <>Select method to model</>;
4162
}
4263

43-
const modelingStatus: ModelingStatus = "saved";
44-
45-
// For now we just store the updated method in the state but soon
46-
// we'll need to send it back to the other views.
4764
const onChange = (modeledMethod: ModeledMethod) => {
48-
setModeledMethod(modeledMethod);
65+
vscode.postMessage({
66+
t: "setModeledMethod",
67+
method: modeledMethod,
68+
});
4969
};
5070

5171
return (

0 commit comments

Comments
 (0)