Skip to content

Commit 23abc5d

Browse files
committed
Hide link when model file does not exist
This removes the link to the model file when it does not exist. It will still show the filename of the model file. When clicking on "Apply", it will refresh whether the model file exists after writing the file.
1 parent b9c8983 commit 23abc5d

File tree

8 files changed

+93
-59
lines changed

8 files changed

+93
-59
lines changed

extensions/ql-vscode/src/data-extensions-editor/data-extensions-editor-view.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import { readQueryResults, runQuery } from "./external-api-usage-query";
3535
import { createDataExtensionYaml, loadDataExtensionYaml } from "./yaml";
3636
import { ExternalApiUsage } from "./external-api-usage";
3737
import { ModeledMethod } from "./modeled-method";
38-
import { ExtensionPackModelFile } from "./extension-pack-picker";
38+
import { ExtensionPackModelFile } from "./shared/extension-pack";
3939

4040
function getQlSubmoduleFolder(): WorkspaceFolder | undefined {
4141
const workspaceFolder = workspace.workspaceFolders?.find(
@@ -118,7 +118,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
118118
msg.externalApiUsages,
119119
msg.modeledMethods,
120120
);
121-
await this.loadExternalApiUsages();
121+
await Promise.all([this.setViewState(), this.loadExternalApiUsages()]);
122122

123123
break;
124124
case "generateExternalApi":
@@ -134,16 +134,22 @@ export class DataExtensionsEditorView extends AbstractWebview<
134134
super.onWebViewLoaded();
135135

136136
await Promise.all([
137-
this.postMessage({
138-
t: "setDataExtensionEditorInitialData",
139-
extensionPackName: this.modelFile.extensionPack.name,
140-
modelFilename: this.modelFile.filename,
141-
}),
137+
this.setViewState(),
142138
this.loadExternalApiUsages(),
143139
this.loadExistingModeledMethods(),
144140
]);
145141
}
146142

143+
private async setViewState(): Promise<void> {
144+
await this.postMessage({
145+
t: "setDataExtensionEditorViewState",
146+
viewState: {
147+
extensionPackModelFile: this.modelFile,
148+
modelFileExists: await pathExists(this.modelFile.filename),
149+
},
150+
});
151+
}
152+
147153
protected async jumpToUsage(
148154
location: ResolvableLocationValue,
149155
): Promise<void> {

extensions/ql-vscode/src/data-extensions-editor/extension-pack-picker.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { ProgressCallback } from "../progress";
1313
import { DatabaseItem } from "../local-databases";
1414
import { getQlPackPath, QLPACK_FILENAMES } from "../pure/ql";
1515
import { getErrorMessage } from "../pure/helpers-pure";
16+
import { ExtensionPack, ExtensionPackModelFile } from "./shared/extension-pack";
1617

1718
const maxStep = 3;
1819

@@ -22,22 +23,6 @@ const packNameRegex = new RegExp(
2223
);
2324
const packNameLength = 128;
2425

25-
export interface ExtensionPack {
26-
path: string;
27-
yamlPath: string;
28-
29-
name: string;
30-
version: string;
31-
32-
extensionTargets: Record<string, string>;
33-
dataExtensions: string[];
34-
}
35-
36-
export interface ExtensionPackModelFile {
37-
filename: string;
38-
extensionPack: ExtensionPack;
39-
}
40-
4126
export async function pickExtensionPackModelFile(
4227
cliServer: Pick<CodeQLCliServer, "resolveQlpacks" | "resolveExtensions">,
4328
databaseItem: Pick<DatabaseItem, "name" | "language">,
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export interface ExtensionPack {
2+
path: string;
3+
yamlPath: string;
4+
5+
name: string;
6+
version: string;
7+
8+
extensionTargets: Record<string, string>;
9+
dataExtensions: string[];
10+
}
11+
12+
export interface ExtensionPackModelFile {
13+
filename: string;
14+
extensionPack: ExtensionPack;
15+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { ExtensionPackModelFile } from "./extension-pack";
2+
3+
export interface DataExtensionEditorViewState {
4+
extensionPackModelFile: ExtensionPackModelFile;
5+
modelFileExists: boolean;
6+
}

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { ErrorLike } from "./errors";
1616
import { DataFlowPaths } from "../variant-analysis/shared/data-flow-paths";
1717
import { ExternalApiUsage } from "../data-extensions-editor/external-api-usage";
1818
import { ModeledMethod } from "../data-extensions-editor/modeled-method";
19+
import { DataExtensionEditorViewState } from "../data-extensions-editor/shared/view-state";
1920

2021
/**
2122
* This module contains types and code that are shared between
@@ -481,10 +482,9 @@ export type ToDataFlowPathsMessage = SetDataFlowPathsMessage;
481482

482483
export type FromDataFlowPathsMessage = CommonFromViewMessages;
483484

484-
export interface SetDataExtensionEditorInitialDataMessage {
485-
t: "setDataExtensionEditorInitialData";
486-
extensionPackName: string;
487-
modelFilename: string;
485+
export interface SetExtensionPackStateMessage {
486+
t: "setDataExtensionEditorViewState";
487+
viewState: DataExtensionEditorViewState;
488488
}
489489

490490
export interface SetExternalApiUsagesMessage {
@@ -536,7 +536,7 @@ export interface GenerateExternalApiMessage {
536536
}
537537

538538
export type ToDataExtensionsEditorMessage =
539-
| SetDataExtensionEditorInitialDataMessage
539+
| SetExtensionPackStateMessage
540540
| SetExternalApiUsagesMessage
541541
| ShowProgressMessage
542542
| AddModeledMethodsMessage;

extensions/ql-vscode/src/stories/data-extensions-editor/DataExtensionsEditor.stories.tsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,22 @@ const Template: ComponentStory<typeof DataExtensionsEditorComponent> = (
1515

1616
export const DataExtensionsEditor = Template.bind({});
1717
DataExtensionsEditor.args = {
18-
initialExtensionPackName: "codeql/sql2o-models",
19-
initialModelFilename:
20-
"/home/user/vscode-codeql-starter/codeql-custom-queries-java/sql2o/models/sql2o.yml",
18+
initialViewState: {
19+
extensionPackModelFile: {
20+
extensionPack: {
21+
path: "/home/user/vscode-codeql-starter/codeql-custom-queries-java/sql2o",
22+
yamlPath:
23+
"/home/user/vscode-codeql-starter/codeql-custom-queries-java/sql2o/codeql-pack.yml",
24+
name: "codeql/sql2o-models",
25+
version: "0.0.0",
26+
extensionTargets: {},
27+
dataExtensions: [],
28+
},
29+
filename:
30+
"/home/user/vscode-codeql-starter/codeql-custom-queries-java/sql2o/models/sql2o.yml",
31+
},
32+
modelFileExists: true,
33+
},
2134
initialExternalApiUsages: [
2235
{
2336
signature: "org.sql2o.Connection#createQuery(String)",

extensions/ql-vscode/src/view/data-extensions-editor/DataExtensionsEditor.tsx

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { calculateModeledPercentage } from "./modeled";
2020
import { LinkIconButton } from "../variant-analysis/LinkIconButton";
2121
import { basename } from "../common/path";
2222
import { ViewTitle } from "../common";
23+
import { DataExtensionEditorViewState } from "../../data-extensions-editor/shared/view-state";
2324

2425
const DataExtensionsEditorContainer = styled.div`
2526
margin-top: 1rem;
@@ -31,6 +32,12 @@ const DetailsContainer = styled.div`
3132
align-items: center;
3233
`;
3334

35+
const NonExistingModelFileContainer = styled.div`
36+
display: flex;
37+
gap: 0.2em;
38+
align-items: center;
39+
`;
40+
3441
const EditorContainer = styled.div`
3542
margin-top: 1rem;
3643
`;
@@ -47,24 +54,19 @@ const ProgressBar = styled.div<ProgressBarProps>`
4754
`;
4855

4956
type Props = {
50-
initialExtensionPackName?: string;
51-
initialModelFilename?: string;
57+
initialViewState?: DataExtensionEditorViewState;
5258
initialExternalApiUsages?: ExternalApiUsage[];
5359
initialModeledMethods?: Record<string, ModeledMethod>;
5460
};
5561

5662
export function DataExtensionsEditor({
57-
initialExtensionPackName,
58-
initialModelFilename,
63+
initialViewState,
5964
initialExternalApiUsages = [],
6065
initialModeledMethods = {},
6166
}: Props): JSX.Element {
62-
const [extensionPackName, setExtensionPackName] = useState<
63-
string | undefined
64-
>(initialExtensionPackName);
65-
const [modelFilename, setModelFilename] = useState<string | undefined>(
66-
initialModelFilename,
67-
);
67+
const [viewState, setViewState] = useState<
68+
DataExtensionEditorViewState | undefined
69+
>(initialViewState);
6870

6971
const [externalApiUsages, setExternalApiUsages] = useState<
7072
ExternalApiUsage[]
@@ -83,9 +85,8 @@ export function DataExtensionsEditor({
8385
if (evt.origin === window.origin) {
8486
const msg: ToDataExtensionsEditorMessage = evt.data;
8587
switch (msg.t) {
86-
case "setDataExtensionEditorInitialData":
87-
setExtensionPackName(msg.extensionPackName);
88-
setModelFilename(msg.modelFilename);
88+
case "setDataExtensionEditorViewState":
89+
setViewState(msg.viewState);
8990
break;
9091
case "setExternalApiUsages":
9192
setExternalApiUsages(msg.externalApiUsages);
@@ -181,17 +182,27 @@ export function DataExtensionsEditor({
181182
<>
182183
<ViewTitle>Data extensions editor</ViewTitle>
183184
<DetailsContainer>
184-
{extensionPackName && (
185-
<LinkIconButton onClick={onOpenExtensionPackClick}>
186-
<span slot="start" className="codicon codicon-package"></span>
187-
{extensionPackName}
188-
</LinkIconButton>
189-
)}
190-
{modelFilename && (
191-
<LinkIconButton onClick={onOpenModelFileClick}>
192-
<span slot="start" className="codicon codicon-file-code"></span>
193-
{basename(modelFilename)}
194-
</LinkIconButton>
185+
{viewState?.extensionPackModelFile && (
186+
<>
187+
<LinkIconButton onClick={onOpenExtensionPackClick}>
188+
<span slot="start" className="codicon codicon-package"></span>
189+
{viewState.extensionPackModelFile.extensionPack.name}
190+
</LinkIconButton>
191+
{viewState.modelFileExists ? (
192+
<LinkIconButton onClick={onOpenModelFileClick}>
193+
<span
194+
slot="start"
195+
className="codicon codicon-file-code"
196+
></span>
197+
{basename(viewState.extensionPackModelFile.filename)}
198+
</LinkIconButton>
199+
) : (
200+
<NonExistingModelFileContainer>
201+
<span className="codicon codicon-file-code"></span>
202+
{basename(viewState.extensionPackModelFile.filename)}
203+
</NonExistingModelFileContainer>
204+
)}
205+
</>
195206
)}
196207
<div>{modeledPercentage.toFixed(2)}% modeled</div>
197208
<div>{unModeledPercentage.toFixed(2)}% unmodeled</div>

extensions/ql-vscode/test/vscode-tests/no-workspace/data-extensions-editor/extension-pack-picker.test.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@ import { dir } from "tmp-promise";
66
import { QlpacksInfo, ResolveExtensionsResult } from "../../../../src/cli";
77
import * as helpers from "../../../../src/helpers";
88

9-
import {
10-
ExtensionPack,
11-
pickExtensionPackModelFile,
12-
} from "../../../../src/data-extensions-editor/extension-pack-picker";
9+
import { pickExtensionPackModelFile } from "../../../../src/data-extensions-editor/extension-pack-picker";
10+
import { ExtensionPack } from "../../../../src/data-extensions-editor/shared/extension-pack";
1311

1412
describe("pickExtensionPackModelFile", () => {
1513
let tmpDir: string;

0 commit comments

Comments
 (0)