Wire up modeling panel empty states (#2915)

This commit is contained in:
Charis Kyriakou
2023-10-06 11:27:16 +01:00
committed by GitHub
parent b1df4a4f0a
commit 20c63921f7
6 changed files with 65 additions and 38 deletions

View File

@@ -1996,7 +1996,7 @@
"id": "codeQLMethodModeling",
"type": "webview",
"name": "CodeQL Method Modeling",
"when": "config.codeQL.canary && config.codeQL.model.methodModelingView && codeql.modelEditorOpen && !codeql.modelEditorActive"
"when": "config.codeQL.canary && config.codeQL.model.methodModelingView"
}
],
"codeql-methods-usage": [

View File

@@ -577,6 +577,11 @@ interface SetModeledMethodMessage {
method: ModeledMethod;
}
interface SetInModelingModeMessage {
t: "setInModelingMode";
inModelingMode: boolean;
}
interface RevealMethodMessage {
t: "revealMethod";
method: Method;
@@ -641,4 +646,5 @@ export type ToMethodModelingMessage =
| SetMethodMessage
| SetModeledMethodMessage
| SetMethodModifiedMessage
| SetSelectedMethodMessage;
| SetSelectedMethodMessage
| SetInModelingModeMessage;

View File

@@ -46,14 +46,16 @@ export class MethodModelingViewProvider extends AbstractWebviewViewProvider<
}
private setInitialState(): void {
const selectedMethod = this.modelingStore.getSelectedMethodDetails();
if (selectedMethod) {
void this.postMessage({
t: "setSelectedMethod",
method: selectedMethod.method,
modeledMethod: selectedMethod.modeledMethod,
isModified: selectedMethod.isModified,
});
if (this.modelingStore.hasStateForActiveDb()) {
const selectedMethod = this.modelingStore.getSelectedMethodDetails();
if (selectedMethod) {
void this.postMessage({
t: "setSelectedMethod",
method: selectedMethod.method,
modeledMethod: selectedMethod.modeledMethod,
isModified: selectedMethod.isModified,
});
}
}
}
@@ -165,5 +167,25 @@ export class MethodModelingViewProvider extends AbstractWebviewViewProvider<
}
}),
);
this.push(
this.modelingStore.onDbOpened(async () => {
await this.postMessage({
t: "setInModelingMode",
inModelingMode: true,
});
}),
);
this.push(
this.modelingStore.onDbClosed(async () => {
if (!this.modelingStore.anyDbsBeingModeled()) {
await this.postMessage({
t: "setInModelingMode",
inModelingMode: false,
});
}
}),
);
}
}

View File

@@ -100,9 +100,6 @@ export class ModelEditorView extends AbstractWebview<
panel.onDidChangeViewState(async () => {
if (panel.active) {
this.modelingStore.setActiveDb(this.databaseItem);
await this.markModelEditorAsActive();
} else {
await this.updateModelEditorActiveContext();
}
});
@@ -126,36 +123,12 @@ export class ModelEditorView extends AbstractWebview<
);
}
private async markModelEditorAsActive(): Promise<void> {
void this.app.commands.execute(
"setContext",
"codeql.modelEditorActive",
true,
);
}
private async updateModelEditorActiveContext(): Promise<void> {
await this.app.commands.execute(
"setContext",
"codeql.modelEditorActive",
this.isAModelEditorActive(),
);
}
private isAModelEditorOpen(): boolean {
return window.tabGroups.all.some((tabGroup) =>
tabGroup.tabs.some((tab) => this.isTabModelEditorView(tab)),
);
}
private isAModelEditorActive(): boolean {
return window.tabGroups.all.some((tabGroup) =>
tabGroup.tabs.some(
(tab) => this.isTabModelEditorView(tab) && tab.isActive,
),
);
}
private isTabModelEditorView(tab: Tab): boolean {
if (!(tab.input instanceof TabInputWebview)) {
return false;

View File

@@ -49,6 +49,7 @@ interface SelectedMethodChangedEvent {
export class ModelingStore extends DisposableObject {
public readonly onActiveDbChanged: AppEvent<void>;
public readonly onDbOpened: AppEvent<string>;
public readonly onDbClosed: AppEvent<string>;
public readonly onMethodsChanged: AppEvent<MethodsChangedEvent>;
public readonly onHideModeledMethodsChanged: AppEvent<HideModeledMethodsChangedEvent>;
@@ -60,6 +61,7 @@ export class ModelingStore extends DisposableObject {
private activeDb: string | undefined;
private readonly onActiveDbChangedEventEmitter: AppEventEmitter<void>;
private readonly onDbOpenedEventEmitter: AppEventEmitter<string>;
private readonly onDbClosedEventEmitter: AppEventEmitter<string>;
private readonly onMethodsChangedEventEmitter: AppEventEmitter<MethodsChangedEvent>;
private readonly onHideModeledMethodsChangedEventEmitter: AppEventEmitter<HideModeledMethodsChangedEvent>;
@@ -79,6 +81,9 @@ export class ModelingStore extends DisposableObject {
);
this.onActiveDbChanged = this.onActiveDbChangedEventEmitter.event;
this.onDbOpenedEventEmitter = this.push(app.createEventEmitter<string>());
this.onDbOpened = this.onDbOpenedEventEmitter.event;
this.onDbClosedEventEmitter = this.push(app.createEventEmitter<string>());
this.onDbClosed = this.onDbClosedEventEmitter.event;
@@ -123,6 +128,8 @@ export class ModelingStore extends DisposableObject {
selectedMethod: undefined,
selectedUsage: undefined,
});
this.onDbOpenedEventEmitter.fire(dbUri);
}
public setActiveDb(databaseItem: DatabaseItem) {
@@ -154,6 +161,14 @@ export class ModelingStore extends DisposableObject {
return this.state.get(this.activeDb);
}
public hasStateForActiveDb(): boolean {
return !!this.getStateForActiveDb();
}
public anyDbsBeingModeled(): boolean {
return this.state.size > 0;
}
public setMethods(dbItem: DatabaseItem, methods: Method[]) {
const dbState = this.getState(dbItem);
const dbUri = dbItem.databaseUri.toString();

View File

@@ -7,8 +7,12 @@ import { ToMethodModelingMessage } from "../../common/interface-types";
import { assertNever } from "../../common/helpers-pure";
import { ModeledMethod } from "../../model-editor/modeled-method";
import { vscode } from "../vscode-api";
import { NotInModelingMode } from "./NotInModelingMode";
import { NoMethodSelected } from "./NoMethodSelected";
export function MethodModelingView(): JSX.Element {
const [inModelingMode, setInModelingMode] = useState<boolean>(false);
const [method, setMethod] = useState<Method | undefined>(undefined);
const [modeledMethod, setModeledMethod] = React.useState<
@@ -27,6 +31,9 @@ export function MethodModelingView(): JSX.Element {
if (evt.origin === window.origin) {
const msg: ToMethodModelingMessage = evt.data;
switch (msg.t) {
case "setInModelingMode":
setInModelingMode(msg.inModelingMode);
break;
case "setMethod":
setMethod(msg.method);
break;
@@ -57,8 +64,12 @@ export function MethodModelingView(): JSX.Element {
};
}, []);
if (!inModelingMode) {
return <NotInModelingMode />;
}
if (!method) {
return <>Select method to model</>;
return <NoMethodSelected />;
}
const onChange = (modeledMethod: ModeledMethod) => {