Skip to content

Commit c457d5c

Browse files
committed
Show informative message if filter matched nothing
1 parent 9e6aa15 commit c457d5c

File tree

4 files changed

+103
-2
lines changed

4 files changed

+103
-2
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,15 @@ interface UntoggleShowProblemsMsg {
220220
t: "untoggleShowProblems";
221221
}
222222

223+
export const enum SourceArchiveRelationship {
224+
/** The file is in the source archive of the database the query was run on. */
225+
CorrectArchive = "correct-archive",
226+
/** The file is in a source archive, but for a different database. */
227+
WrongArchive = "wrong-archive",
228+
/** The file is not in any source archive. */
229+
NotInArchive = "not-in-archive",
230+
}
231+
223232
/**
224233
* Information about the current editor selection, sent to the results view
225234
* so it can filter results to only those overlapping the selection.
@@ -233,6 +242,8 @@ export interface EditorSelection {
233242
endColumn: number;
234243
/** True if the selection is empty (just a cursor), in which case we match the whole file. */
235244
isEmpty: boolean;
245+
/** Describes the relationship between the current file and the query's database source archive. */
246+
sourceArchiveRelationship: SourceArchiveRelationship;
236247
}
237248

238249
interface SetEditorSelectionMsg {

extensions/ql-vscode/src/local-queries/results-view.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import {
5252
NavigationDirection,
5353
getDefaultResultSetName,
5454
RAW_RESULTS_LIMIT,
55+
SourceArchiveRelationship,
5556
} from "../common/interface-types";
5657
import { extLogger } from "../common/logging/vscode";
5758
import type { Logger } from "../common/logging";
@@ -1103,6 +1104,7 @@ export class ResultsView extends AbstractWebview<
11031104
startColumn: range.start.character + 1,
11041105
endColumn: range.end.character + 1,
11051106
isEmpty: range.isEmpty,
1107+
sourceArchiveRelationship: this.getSourceArchiveRelationship(uri),
11061108
};
11071109
}
11081110

@@ -1129,6 +1131,29 @@ export class ResultsView extends AbstractWebview<
11291131
return undefined;
11301132
}
11311133

1134+
/**
1135+
* Determines the relationship between the editor file and the query's database source archive.
1136+
*/
1137+
private getSourceArchiveRelationship(
1138+
editorUri: Uri,
1139+
): SourceArchiveRelationship {
1140+
if (editorUri.scheme !== zipArchiveScheme) {
1141+
return SourceArchiveRelationship.NotInArchive;
1142+
}
1143+
const dbItem = this._displayedQuery
1144+
? this.databaseManager.findDatabaseItem(
1145+
Uri.parse(this._displayedQuery.initialInfo.databaseInfo.databaseUri),
1146+
)
1147+
: undefined;
1148+
if (
1149+
dbItem?.sourceArchive &&
1150+
dbItem.belongsToSourceArchiveExplorerUri(editorUri)
1151+
) {
1152+
return SourceArchiveRelationship.CorrectArchive;
1153+
}
1154+
return SourceArchiveRelationship.WrongArchive;
1155+
}
1156+
11321157
/**
11331158
* Loads all results from the given table that reference the given file URI,
11341159
* and sends them to the webview. Called on demand when the webview requests

extensions/ql-vscode/src/view/results/ResultTable.tsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,29 @@ import { RawTable } from "./RawTable";
44
import type { ResultTableProps } from "./result-table-utils";
55
import { AlertTableNoResults } from "./AlertTableNoResults";
66
import { AlertTableHeader } from "./AlertTableHeader";
7+
import { SelectionFilterNoResults } from "./SelectionFilterNoResults";
78

89
export function ResultTable(props: ResultTableProps) {
9-
const { resultSet, userSettings, filteredRawRows, filteredSarifResults } =
10-
props;
10+
const {
11+
resultSet,
12+
userSettings,
13+
selectionFilter,
14+
filteredRawRows,
15+
filteredSarifResults,
16+
} = props;
17+
18+
const filteredCount = filteredRawRows?.length ?? filteredSarifResults?.length;
19+
// When filtering is active and the filtered results are empty, show a
20+
// message instead of forwarding to child tables (which would misleadingly
21+
// say the query returned no results).
22+
if (selectionFilter && filteredCount === 0) {
23+
return (
24+
<SelectionFilterNoResults
25+
sourceArchiveRelationship={selectionFilter.sourceArchiveRelationship}
26+
/>
27+
);
28+
}
29+
1130
switch (resultSet.t) {
1231
case "RawResultSet": {
1332
const filteredResultSet = {
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { styled } from "styled-components";
2+
import { SourceArchiveRelationship } from "../../common/interface-types";
3+
4+
interface Props {
5+
sourceArchiveRelationship: SourceArchiveRelationship;
6+
}
7+
8+
const Root = styled.div`
9+
height: 300px;
10+
display: flex;
11+
align-items: center;
12+
justify-content: center;
13+
`;
14+
15+
const Container = styled.span`
16+
max-width: 80%;
17+
font-size: 14px;
18+
text-align: center;
19+
`;
20+
21+
export function SelectionFilterNoResults({
22+
sourceArchiveRelationship,
23+
}: Props): React.JSX.Element {
24+
return (
25+
<Root>
26+
<Container>
27+
No results match the current selection filter.
28+
{sourceArchiveRelationship ===
29+
SourceArchiveRelationship.NotInArchive && (
30+
<>
31+
<br />
32+
This file is not part of a source archive for a database.
33+
</>
34+
)}
35+
{sourceArchiveRelationship ===
36+
SourceArchiveRelationship.WrongArchive && (
37+
<>
38+
<br />
39+
This file is part of the source archive for a different database
40+
than the one this query was run on.
41+
</>
42+
)}
43+
</Container>
44+
</Root>
45+
);
46+
}

0 commit comments

Comments
 (0)