Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,25 @@ import type { App } from "../../common/app";
import { redactableError } from "../../common/errors";
import { extLogger } from "../../common/logging/vscode";
import { showAndLogExceptionWithTelemetry } from "../../common/logging";
import type { ModelingEvents } from "../modeling-events";
import type { ModelingStore } from "../modeling-store";
import type { DatabaseItem } from "../../databases/local-databases";

export class ModelAlertsView extends AbstractWebview<
ToModelAlertsMessage,
FromModelAlertsMessage
> {
public static readonly viewType = "codeQL.modelAlerts";

public constructor(app: App) {
public constructor(
app: App,
private readonly modelingEvents: ModelingEvents,
private readonly modelingStore: ModelingStore,
private readonly dbItem: DatabaseItem,
) {
super(app);

this.registerToModelingEvents();
}

public async showView() {
Expand All @@ -40,7 +50,7 @@ export class ModelAlertsView extends AbstractWebview<
}

protected onPanelDispose(): void {
// Nothing to dispose
this.modelingStore.updateIsModelAlertsViewOpen(this.dbItem, false);
}

protected async onMessage(msg: FromModelAlertsMessage): Promise<void> {
Expand All @@ -64,4 +74,18 @@ export class ModelAlertsView extends AbstractWebview<
assertNever(msg);
}
}

public async focusView(): Promise<void> {
this.panel?.reveal();
}

private registerToModelingEvents() {
this.push(
this.modelingEvents.onFocusModelAlertsView(async (event) => {
if (event.dbUri === this.dbItem.databaseUri.toString()) {
await this.focusView();
}
}),
);
}
}
17 changes: 15 additions & 2 deletions extensions/ql-vscode/src/model-editor/model-evaluator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,21 @@ export class ModelEvaluator extends DisposableObject {
}

public async openModelAlertsView() {
const view = new ModelAlertsView(this.app);
await view.showView();
if (this.modelingStore.isModelAlertsViewOpen(this.dbItem)) {
this.modelingEvents.fireFocusModelAlertsViewEvent(
this.dbItem.databaseUri.toString(),
);
return;
} else {
this.modelingStore.updateIsModelAlertsViewOpen(this.dbItem, true);
const view = new ModelAlertsView(
this.app,
this.modelingEvents,
this.modelingStore,
this.dbItem,
);
await view.showView();
}
}

private registerToModelingEvents() {
Expand Down
15 changes: 15 additions & 0 deletions extensions/ql-vscode/src/model-editor/modeling-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ interface FocusModelEditorEvent {
dbUri: string;
}

interface FocusModelAlertsViewEvent {
dbUri: string;
}

export class ModelingEvents extends DisposableObject {
public readonly onActiveDbChanged: AppEvent<void>;
public readonly onDbOpened: AppEvent<DatabaseItem>;
Expand All @@ -79,6 +83,7 @@ export class ModelingEvents extends DisposableObject {
public readonly onModelEvaluationRunChanged: AppEvent<ModelEvaluationRunChangedEvent>;
public readonly onRevealInModelEditor: AppEvent<RevealInModelEditorEvent>;
public readonly onFocusModelEditor: AppEvent<FocusModelEditorEvent>;
public readonly onFocusModelAlertsView: AppEvent<FocusModelAlertsViewEvent>;

private readonly onActiveDbChangedEventEmitter: AppEventEmitter<void>;
private readonly onDbOpenedEventEmitter: AppEventEmitter<DatabaseItem>;
Expand All @@ -93,6 +98,7 @@ export class ModelingEvents extends DisposableObject {
private readonly onModelEvaluationRunChangedEventEmitter: AppEventEmitter<ModelEvaluationRunChangedEvent>;
private readonly onRevealInModelEditorEventEmitter: AppEventEmitter<RevealInModelEditorEvent>;
private readonly onFocusModelEditorEventEmitter: AppEventEmitter<FocusModelEditorEvent>;
private readonly onFocusModelAlertsViewEventEmitter: AppEventEmitter<FocusModelAlertsViewEvent>;

constructor(app: App) {
super();
Expand Down Expand Up @@ -165,6 +171,11 @@ export class ModelingEvents extends DisposableObject {
app.createEventEmitter<FocusModelEditorEvent>(),
);
this.onFocusModelEditor = this.onFocusModelEditorEventEmitter.event;

this.onFocusModelAlertsViewEventEmitter = this.push(
app.createEventEmitter<FocusModelAlertsViewEvent>(),
);
this.onFocusModelAlertsView = this.onFocusModelAlertsViewEventEmitter.event;
}

public fireActiveDbChangedEvent() {
Expand Down Expand Up @@ -286,4 +297,8 @@ export class ModelingEvents extends DisposableObject {
dbUri,
});
}

public fireFocusModelAlertsViewEvent(dbUri: string) {
this.onFocusModelAlertsViewEventEmitter.fire({ dbUri });
}
}
22 changes: 22 additions & 0 deletions extensions/ql-vscode/src/model-editor/modeling-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ interface InternalDbModelingState {
selectedMethod: Method | undefined;
selectedUsage: Usage | undefined;
modelEvaluationRun: ModelEvaluationRun | undefined;
isModelAlertsViewOpen: boolean;
}

export interface DbModelingState {
Expand All @@ -34,6 +35,7 @@ export interface DbModelingState {
readonly selectedMethod: Method | undefined;
readonly selectedUsage: Usage | undefined;
readonly modelEvaluationRun: ModelEvaluationRun | undefined;
readonly isModelAlertsViewOpen: boolean;
}

export interface SelectedMethodDetails {
Expand Down Expand Up @@ -71,6 +73,7 @@ export class ModelingStore extends DisposableObject {
selectedUsage: undefined,
inProgressMethods: new Set(),
modelEvaluationRun: undefined,
isModelAlertsViewOpen: false,
});

this.modelingEvents.fireDbOpenedEvent(databaseItem);
Expand Down Expand Up @@ -498,4 +501,23 @@ export class ModelingStore extends DisposableObject {
state.modelEvaluationRun,
);
}

public isModelAlertsViewOpen(dbItem: DatabaseItem): boolean {
return this.getState(dbItem).isModelAlertsViewOpen ?? false;
}

private changeIsModelAlertsViewOpen(
dbItem: DatabaseItem,
updateState: (state: InternalDbModelingState) => void,
) {
const state = this.getState(dbItem);

updateState(state);
}

public updateIsModelAlertsViewOpen(dbItem: DatabaseItem, isOpen: boolean) {
this.changeIsModelAlertsViewOpen(dbItem, (state) => {
state.isModelAlertsViewOpen = isOpen;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export const ModelEvaluation = ({

const shouldShowStopButton = !shouldShowEvaluateButton;

const shouldShowEvaluationRunLink = !!evaluationRun;
const shouldShowEvaluationRunLink =
!!evaluationRun && evaluationRun.variantAnalysis;

const customModelsExist = Object.values(modeledMethods).some(
(methods) => methods.filter((m) => m.type !== "none").length > 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ describe(ModelEvaluation.name, () => {
expect(screen.queryByText("Stop evaluation")).not.toBeInTheDocument();
});

it("renders 'Stop evaluation' button and 'Evaluation run' link when there is an in progress evaluation", () => {
it("renders 'Stop evaluation' button when there is an in progress evaluation, but no variant analysis yet", () => {
render({
evaluationRun: {
isPreparing: true,
Expand All @@ -112,6 +112,27 @@ describe(ModelEvaluation.name, () => {
stopEvaluationButton?.getElementsByTagName("input")[0],
).toBeEnabled();

expect(screen.queryByText("Evaluation run")).not.toBeInTheDocument();

expect(screen.queryByText("Evaluate")).not.toBeInTheDocument();
});

it("renders 'Stop evaluation' button and 'Evaluation run' link when there is an in progress evaluation with variant analysis", () => {
render({
evaluationRun: {
isPreparing: false,
variantAnalysis: createMockVariantAnalysis({
status: VariantAnalysisStatus.InProgress,
}),
},
});

const stopEvaluationButton = screen.queryByText("Stop evaluation");
expect(stopEvaluationButton).toBeInTheDocument();
expect(
stopEvaluationButton?.getElementsByTagName("input")[0],
).toBeEnabled();

expect(screen.queryByText("Evaluation run")).toBeInTheDocument();

expect(screen.queryByText("Evaluate")).not.toBeInTheDocument();
Expand Down