Skip to content

Commit 3f7b8a6

Browse files
authored
Merge pull request #2348 from github/koesie10/non-existing-model-file
Hide link when model file does not exist
2 parents 467c2a5 + 23abc5d commit 3f7b8a6

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)