Add 'stop evaluation' action to Model Alerts view (#3487)

This commit is contained in:
Charis Kyriakou 2024-03-18 15:41:33 +00:00 коммит произвёл GitHub
Родитель 46efb7c971
Коммит 2d1c2349f8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
10 изменённых файлов: 165 добавлений и 9 удалений

Просмотреть файл

@ -737,6 +737,10 @@ interface OpenModelPackMessage {
path: string;
}
interface StopEvaluationRunMessage {
t: "stopEvaluationRun";
}
export type ToModelAlertsMessage =
| SetModelAlertsViewStateMessage
| SetVariantAnalysisMessage
@ -745,4 +749,5 @@ export type ToModelAlertsMessage =
export type FromModelAlertsMessage =
| CommonFromViewMessages
| OpenModelPackMessage;
| OpenModelPackMessage
| StopEvaluationRunMessage;

Просмотреть файл

@ -20,6 +20,7 @@ import type {
VariantAnalysisScannedRepositoryResult,
VariantAnalysisScannedRepositoryState,
} from "../../variant-analysis/shared/variant-analysis";
import type { AppEvent, AppEventEmitter } from "../../common/events";
export class ModelAlertsView extends AbstractWebview<
ToModelAlertsMessage,
@ -27,6 +28,9 @@ export class ModelAlertsView extends AbstractWebview<
> {
public static readonly viewType = "codeQL.modelAlerts";
public readonly onEvaluationRunStopClicked: AppEvent<void>;
private readonly onEvaluationRunStopClickedEventEmitter: AppEventEmitter<void>;
public constructor(
app: App,
private readonly modelingEvents: ModelingEvents,
@ -37,6 +41,12 @@ export class ModelAlertsView extends AbstractWebview<
super(app);
this.registerToModelingEvents();
this.onEvaluationRunStopClickedEventEmitter = this.push(
app.createEventEmitter<void>(),
);
this.onEvaluationRunStopClicked =
this.onEvaluationRunStopClickedEventEmitter.event;
}
public async showView() {
@ -81,6 +91,9 @@ export class ModelAlertsView extends AbstractWebview<
case "openModelPack":
await this.app.commands.execute("revealInExplorer", Uri.file(msg.path));
break;
case "stopEvaluationRun":
await this.stopEvaluationRun();
break;
default:
assertNever(msg);
}
@ -155,4 +168,8 @@ export class ModelAlertsView extends AbstractWebview<
}),
);
}
private async stopEvaluationRun() {
this.onEvaluationRunStopClickedEventEmitter.fire();
}
}

Просмотреть файл

@ -128,6 +128,10 @@ export class ModelEvaluator extends DisposableObject {
);
await this.modelAlertsView.showView();
this.modelAlertsView.onEvaluationRunStopClicked(async () => {
await this.stopEvaluation();
});
// There should be a variant analysis available at this point, as the
// view can only opened when the variant analysis is submitted.
const evaluationRun = this.modelingStore.getModelEvaluationRun(

Просмотреть файл

@ -3,7 +3,7 @@ import type { Meta, StoryFn } from "@storybook/react";
import { ModelAlerts as ModelAlertsComponent } from "../../view/model-alerts/ModelAlerts";
export default {
title: "CodeQL Model Alerts/CodeQL Model Alerts",
title: "Model Alerts/Model Alerts",
component: ModelAlertsComponent,
} as Meta<typeof ModelAlertsComponent>;

Просмотреть файл

@ -0,0 +1,52 @@
import type { Meta, StoryFn } from "@storybook/react";
import { ModelAlertsHeader as ModelAlertsHeaderComponent } from "../../view/model-alerts/ModelAlertsHeader";
import { createMockVariantAnalysis } from "../../../test/factories/variant-analysis/shared/variant-analysis";
export default {
title: "Model Alerts/Model Alerts Header",
component: ModelAlertsHeaderComponent,
argTypes: {
openModelPackClick: {
action: "open-model-pack-clicked",
table: {
disable: true,
},
},
stopRunClick: {
action: "stop-run-clicked",
table: {
disable: true,
},
},
},
} as Meta<typeof ModelAlertsHeaderComponent>;
const Template: StoryFn<typeof ModelAlertsHeaderComponent> = (args) => (
<ModelAlertsHeaderComponent {...args} />
);
export const ModelAlertsHeader = Template.bind({});
ModelAlertsHeader.args = {
viewState: { title: "codeql/sql2o-models" },
variantAnalysis: createMockVariantAnalysis({
modelPacks: [
{
name: "Model pack 1",
path: "/path/to/model-pack-1",
},
{
name: "Model pack 2",
path: "/path/to/model-pack-2",
},
{
name: "Model pack 3",
path: "/path/to/model-pack-3",
},
{
name: "Model pack 4",
path: "/path/to/model-pack-4",
},
],
}),
};

Просмотреть файл

@ -21,6 +21,12 @@ export function ModelAlerts({ initialViewState }: Props): React.JSX.Element {
});
}, []);
const onStopRunClick = useCallback(() => {
vscode.postMessage({
t: "stopEvaluationRun",
});
}, []);
const [viewState, setViewState] = useState<ModelAlertsViewState | undefined>(
initialViewState,
);
@ -96,6 +102,7 @@ export function ModelAlerts({ initialViewState }: Props): React.JSX.Element {
viewState={viewState}
variantAnalysis={variantAnalysis}
openModelPackClick={onOpenModelPackClick}
stopRunClick={onStopRunClick}
></ModelAlertsHeader>
<div>
<h3>Repo states</h3>

Просмотреть файл

@ -0,0 +1,39 @@
import { styled } from "styled-components";
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react";
import { VariantAnalysisStatus } from "../../variant-analysis/shared/variant-analysis";
type ModelAlertsActionsProps = {
variantAnalysisStatus: VariantAnalysisStatus;
onStopRunClick: () => void;
};
const Container = styled.div`
margin-left: auto;
display: flex;
gap: 1em;
`;
const Button = styled(VSCodeButton)`
white-space: nowrap;
`;
export const ModelAlertsActions = ({
variantAnalysisStatus,
onStopRunClick,
}: ModelAlertsActionsProps) => {
return (
<Container>
{variantAnalysisStatus === VariantAnalysisStatus.InProgress && (
<Button appearance="secondary" onClick={onStopRunClick}>
Stop evaluation
</Button>
)}
{variantAnalysisStatus === VariantAnalysisStatus.Canceling && (
<Button appearance="secondary" disabled={true}>
Stopping evaluation
</Button>
)}
</Container>
);
};

Просмотреть файл

@ -1,26 +1,50 @@
import { styled } from "styled-components";
import type { ModelAlertsViewState } from "../../model-editor/shared/view-state";
import type { VariantAnalysis } from "../../variant-analysis/shared/variant-analysis";
import { ViewTitle } from "../common";
import { ModelAlertsActions } from "./ModelAlertsActions";
import { ModelPacks } from "./ModelPacks";
type Props = {
viewState: ModelAlertsViewState;
variantAnalysis: VariantAnalysis;
openModelPackClick: (path: string) => void;
stopRunClick: () => void;
};
const Container = styled.div`
display: flex;
flex-direction: column;
`;
const Row = styled.div`
display: flex;
align-items: flex-start;
`;
export const ModelAlertsHeader = ({
viewState,
variantAnalysis,
openModelPackClick,
stopRunClick,
}: Props) => {
return (
<>
<ViewTitle>Model evaluation results for {viewState.title}</ViewTitle>
<ModelPacks
modelPacks={variantAnalysis.modelPacks || []}
openModelPackClick={openModelPackClick}
></ModelPacks>
<Container>
<Row>
<ViewTitle>Model evaluation results for {viewState.title}</ViewTitle>
</Row>
<Row>
<ModelPacks
modelPacks={variantAnalysis.modelPacks || []}
openModelPackClick={openModelPackClick}
></ModelPacks>
<ModelAlertsActions
variantAnalysisStatus={variantAnalysis.status}
onStopRunClick={stopRunClick}
/>
</Row>
</Container>
</>
);
};

Просмотреть файл

@ -2,6 +2,10 @@ import { styled } from "styled-components";
import { LinkIconButton } from "../common/LinkIconButton";
import type { ModelPackDetails } from "../../common/model-pack-details";
const Container = styled.div`
display: block;
`;
const Title = styled.h3`
font-size: medium;
font-weight: 500;
@ -26,7 +30,7 @@ export const ModelPacks = ({
}
return (
<>
<Container>
<Title>Model packs</Title>
<List>
{modelPacks.map((modelPack) => (
@ -38,6 +42,6 @@ export const ModelPacks = ({
</li>
))}
</List>
</>
</Container>
);
};

Просмотреть файл

@ -9,6 +9,7 @@ import { createMockScannedRepos } from "./scanned-repositories";
import { createMockSkippedRepos } from "./skipped-repositories";
import { createMockRepository } from "./repository";
import { QueryLanguage } from "../../../../src/common/query-language";
import type { ModelPackDetails } from "../../../../src/common/model-pack-details";
export function createMockVariantAnalysis({
status = VariantAnalysisStatus.InProgress,
@ -16,12 +17,14 @@ export function createMockVariantAnalysis({
skippedRepos = createMockSkippedRepos(),
executionStartTime = faker.number.int(),
language = QueryLanguage.Javascript,
modelPacks = undefined,
}: {
status?: VariantAnalysisStatus;
scannedRepos?: VariantAnalysisScannedRepository[];
skippedRepos?: VariantAnalysisSkippedRepositories;
executionStartTime?: number | undefined;
language?: QueryLanguage;
modelPacks?: ModelPackDetails[] | undefined;
}): VariantAnalysis {
return {
id: faker.number.int(),
@ -37,6 +40,7 @@ export function createMockVariantAnalysis({
filePath: "a-query-file-path",
text: "a-query-text",
},
modelPacks,
databases: {
repositories: ["1", "2", "3"],
},