Hook method modeling view to modeling store (#2870)
This commit is contained in:
@@ -599,11 +599,28 @@ export type FromModelEditorMessage =
|
||||
|
||||
export type FromMethodModelingMessage =
|
||||
| TelemetryMessage
|
||||
| UnhandledErrorMessage;
|
||||
| UnhandledErrorMessage
|
||||
| SetModeledMethodMessage;
|
||||
|
||||
interface SetMethodMessage {
|
||||
t: "setMethod";
|
||||
method: Method;
|
||||
}
|
||||
|
||||
export type ToMethodModelingMessage = SetMethodMessage;
|
||||
interface SetMethodModifiedMessage {
|
||||
t: "setMethodModified";
|
||||
isModified: boolean;
|
||||
}
|
||||
|
||||
interface SetSelectedMethodMessage {
|
||||
t: "setSelectedMethod";
|
||||
method: Method;
|
||||
modeledMethod: ModeledMethod;
|
||||
isModified: boolean;
|
||||
}
|
||||
|
||||
export type ToMethodModelingMessage =
|
||||
| SetMethodMessage
|
||||
| SetModeledMethodMessage
|
||||
| SetMethodModifiedMessage
|
||||
| SetSelectedMethodMessage;
|
||||
|
||||
@@ -3,14 +3,15 @@ import { App } from "../../common/app";
|
||||
import { DisposableObject } from "../../common/disposable-object";
|
||||
import { MethodModelingViewProvider } from "./method-modeling-view-provider";
|
||||
import { Method } from "../method";
|
||||
import { ModelingStore } from "../modeling-store";
|
||||
|
||||
export class MethodModelingPanel extends DisposableObject {
|
||||
private readonly provider: MethodModelingViewProvider;
|
||||
|
||||
constructor(app: App) {
|
||||
constructor(app: App, modelingStore: ModelingStore) {
|
||||
super();
|
||||
|
||||
this.provider = new MethodModelingViewProvider(app);
|
||||
this.provider = new MethodModelingViewProvider(app, modelingStore);
|
||||
this.push(this.provider);
|
||||
this.push(
|
||||
window.registerWebviewViewProvider(
|
||||
|
||||
@@ -9,6 +9,7 @@ import { App } from "../../common/app";
|
||||
import { redactableError } from "../../common/errors";
|
||||
import { Method } from "../method";
|
||||
import { DisposableObject } from "../../common/disposable-object";
|
||||
import { ModelingStore } from "../modeling-store";
|
||||
|
||||
export class MethodModelingViewProvider
|
||||
extends DisposableObject
|
||||
@@ -18,7 +19,12 @@ export class MethodModelingViewProvider
|
||||
|
||||
private webviewView: vscode.WebviewView | undefined = undefined;
|
||||
|
||||
constructor(private readonly app: App) {
|
||||
private method: Method | undefined = undefined;
|
||||
|
||||
constructor(
|
||||
private readonly app: App,
|
||||
private readonly modelingStore: ModelingStore,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -51,9 +57,13 @@ export class MethodModelingViewProvider
|
||||
webviewView.webview.onDidReceiveMessage(async (msg) => this.onMessage(msg));
|
||||
|
||||
this.webviewView = webviewView;
|
||||
|
||||
this.registerToModelingStoreEvents();
|
||||
}
|
||||
|
||||
public async setMethod(method: Method): Promise<void> {
|
||||
this.method = method;
|
||||
|
||||
if (this.webviewView) {
|
||||
await this.webviewView.webview.postMessage({
|
||||
t: "setMethod",
|
||||
@@ -64,6 +74,18 @@ export class MethodModelingViewProvider
|
||||
|
||||
private async onMessage(msg: FromMethodModelingMessage): Promise<void> {
|
||||
switch (msg.t) {
|
||||
case "setModeledMethod": {
|
||||
const activeState = this.modelingStore.getStateForActiveDb();
|
||||
if (!activeState) {
|
||||
throw new Error("No active state found in modeling store");
|
||||
}
|
||||
this.modelingStore.updateModeledMethod(
|
||||
activeState.databaseItem,
|
||||
msg.method,
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case "telemetry": {
|
||||
telemetryListener?.sendUIInteraction(msg.action);
|
||||
break;
|
||||
@@ -79,4 +101,40 @@ export class MethodModelingViewProvider
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private registerToModelingStoreEvents(): void {
|
||||
this.modelingStore.onModeledMethodsChanged(async (e) => {
|
||||
if (this.webviewView && e.isActiveDb) {
|
||||
const modeledMethod = e.modeledMethods[this.method?.signature ?? ""];
|
||||
if (modeledMethod) {
|
||||
await this.webviewView.webview.postMessage({
|
||||
t: "setModeledMethod",
|
||||
method: modeledMethod,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.modelingStore.onModifiedMethodsChanged(async (e) => {
|
||||
if (this.webviewView && e.isActiveDb && this.method) {
|
||||
const isModified = e.modifiedMethods.has(this.method.signature);
|
||||
await this.webviewView.webview.postMessage({
|
||||
t: "setMethodModified",
|
||||
isModified,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.modelingStore.onSelectedMethodChanged(async (e) => {
|
||||
if (this.webviewView) {
|
||||
this.method = e.method;
|
||||
await this.webviewView.webview.postMessage({
|
||||
t: "setSelectedMethod",
|
||||
method: e.method,
|
||||
modeledMethod: e.modeledMethod,
|
||||
isModified: e.isModified,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,9 @@ export class ModelEditorModule extends DisposableObject {
|
||||
this.methodsUsagePanel = this.push(
|
||||
new MethodsUsagePanel(this.modelingStore, cliServer),
|
||||
);
|
||||
this.methodModelingPanel = this.push(new MethodModelingPanel(app));
|
||||
this.methodModelingPanel = this.push(
|
||||
new MethodModelingPanel(app, this.modelingStore),
|
||||
);
|
||||
|
||||
this.registerToModelingStoreEvents();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import * as React from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { MethodModeling } from "./MethodModeling";
|
||||
import { ModelingStatus } from "../../model-editor/shared/modeling-status";
|
||||
import { getModelingStatus } from "../../model-editor/shared/modeling-status";
|
||||
import { Method } from "../../model-editor/method";
|
||||
import { ToMethodModelingMessage } from "../../common/interface-types";
|
||||
import { assertNever } from "../../common/helpers-pure";
|
||||
import { ModeledMethod } from "../../model-editor/modeled-method";
|
||||
import { vscode } from "../vscode-api";
|
||||
|
||||
export function MethodModelingView(): JSX.Element {
|
||||
const [method, setMethod] = useState<Method | undefined>(undefined);
|
||||
@@ -14,14 +15,34 @@ export function MethodModelingView(): JSX.Element {
|
||||
ModeledMethod | undefined
|
||||
>(undefined);
|
||||
|
||||
const [isMethodModified, setIsMethodModified] = useState<boolean>(false);
|
||||
|
||||
const modelingStatus = useMemo(
|
||||
() => getModelingStatus(modeledMethod, isMethodModified),
|
||||
[modeledMethod, isMethodModified],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const listener = (evt: MessageEvent) => {
|
||||
if (evt.origin === window.origin) {
|
||||
const msg: ToMethodModelingMessage = evt.data;
|
||||
if (msg.t === "setMethod") {
|
||||
setMethod(msg.method);
|
||||
} else {
|
||||
assertNever(msg.t);
|
||||
switch (msg.t) {
|
||||
case "setMethod":
|
||||
setMethod(msg.method);
|
||||
break;
|
||||
case "setModeledMethod":
|
||||
setModeledMethod(msg.method);
|
||||
break;
|
||||
case "setMethodModified":
|
||||
setIsMethodModified(msg.isModified);
|
||||
break;
|
||||
case "setSelectedMethod":
|
||||
setMethod(msg.method);
|
||||
setModeledMethod(msg.modeledMethod);
|
||||
setIsMethodModified(msg.isModified);
|
||||
break;
|
||||
default:
|
||||
assertNever(msg);
|
||||
}
|
||||
} else {
|
||||
// sanitize origin
|
||||
@@ -40,12 +61,11 @@ export function MethodModelingView(): JSX.Element {
|
||||
return <>Select method to model</>;
|
||||
}
|
||||
|
||||
const modelingStatus: ModelingStatus = "saved";
|
||||
|
||||
// For now we just store the updated method in the state but soon
|
||||
// we'll need to send it back to the other views.
|
||||
const onChange = (modeledMethod: ModeledMethod) => {
|
||||
setModeledMethod(modeledMethod);
|
||||
vscode.postMessage({
|
||||
t: "setModeledMethod",
|
||||
method: modeledMethod,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user