-
Notifications
You must be signed in to change notification settings - Fork 226
Add commands for navigation of alerts #1568
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 14 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
ab933fc
Add 'show next/previous alert' commands
asgerf 2949fc3
Replace 'expanded' with a Set<number>
asgerf bb61b5e
Replace the expansion index with the result key
asgerf 3c4682e
Ensure nodes are expanded
asgerf 20dea5e
Also show selection in raw result view
asgerf 125f638
Make raw result view respond to navigation events
asgerf 88bfd19
Switch commands to up/down/left/right semantics
asgerf 0f6100c
Bugfix in getPathNode
asgerf 5a69465
Rename command IDs.
asgerf f759eed
Remove unsed parts of result-keys.ts
asgerf 4871728
Added change note
asgerf d08e005
When stepping up or down, collapse the previous node
asgerf 45b6288
Reveal panel on navigate, to prevent webview destruction
asgerf 0e3679d
Scroll selected item into view
asgerf ecc07a5
Update extensions/ql-vscode/CHANGELOG.md
asgerf cbf15e6
Update extensions/ql-vscode/src/view/results/alert-table.tsx
asgerf 53bb9d7
Title-case command names, like other commands
asgerf 65777b5
Use null-aware accessors in getResult
asgerf d4a58a6
Consistently check for undefined rather than nullish
asgerf e1a56dd
Update a new more nullish checks
asgerf bdf7208
Mention keyboard navigation in README
asgerf 9cb4b9d
Update extensions/ql-vscode/package.json
asgerf 0acf9f7
Fix bad suggestion merge in package.json
asgerf ead1fb4
Merge branch 'main' into asgerf/navigate-alerts
asgerf b480f8f
Fix incorrect merge resolution in changelog
asgerf File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,33 +1,45 @@ | ||
| import * as sarif from 'sarif'; | ||
|
|
||
| /** | ||
| * Identifies a result, a path, or one of the nodes on a path. | ||
| */ | ||
| interface ResultKeyBase { | ||
| resultIndex: number; | ||
| pathIndex?: number; | ||
| pathNodeIndex?: number; | ||
| } | ||
|
|
||
| /** | ||
| * Identifies one of the results in a result set by its index in the result list. | ||
| */ | ||
| export interface Result { | ||
| export interface Result extends ResultKeyBase { | ||
| resultIndex: number; | ||
| pathIndex?: undefined; | ||
| pathNodeIndex?: undefined; | ||
| } | ||
|
|
||
| /** | ||
| * Identifies one of the paths associated with a result. | ||
| */ | ||
| export interface Path extends Result { | ||
| export interface Path extends ResultKeyBase { | ||
| pathIndex: number; | ||
| pathNodeIndex?: undefined; | ||
| } | ||
|
|
||
| /** | ||
| * Identifies one of the nodes in a path. | ||
| */ | ||
| export interface PathNode extends Path { | ||
| export interface PathNode extends ResultKeyBase { | ||
| pathIndex: number; | ||
| pathNodeIndex: number; | ||
| } | ||
|
|
||
| /** Alias for `undefined` but more readable in some cases */ | ||
| export const none: PathNode | undefined = undefined; | ||
| export type ResultKey = Result | Path | PathNode; | ||
|
|
||
| /** | ||
| * Looks up a specific result in a result set. | ||
| */ | ||
| export function getResult(sarif: sarif.Log, key: Result): sarif.Result | undefined { | ||
| export function getResult(sarif: sarif.Log, key: Result | Path | PathNode): sarif.Result | undefined { | ||
|
aeisenberg marked this conversation as resolved.
|
||
| if (sarif.runs.length === 0) return undefined; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor: The body of this function can be replaced with this: It's really outside the scope of this PR, but it's a minor readability improvement if you want to add it. |
||
| if (sarif.runs[0].results === undefined) return undefined; | ||
| const results = sarif.runs[0].results; | ||
|
|
@@ -37,7 +49,7 @@ export function getResult(sarif: sarif.Log, key: Result): sarif.Result | undefin | |
| /** | ||
| * Looks up a specific path in a result set. | ||
| */ | ||
| export function getPath(sarif: sarif.Log, key: Path): sarif.ThreadFlow | undefined { | ||
| export function getPath(sarif: sarif.Log, key: Path | PathNode): sarif.ThreadFlow | undefined { | ||
|
aeisenberg marked this conversation as resolved.
|
||
| const result = getResult(sarif, key); | ||
| if (result === undefined) return undefined; | ||
| let index = -1; | ||
|
|
@@ -58,22 +70,13 @@ export function getPath(sarif: sarif.Log, key: Path): sarif.ThreadFlow | undefin | |
| export function getPathNode(sarif: sarif.Log, key: PathNode): sarif.Location | undefined { | ||
| const path = getPath(sarif, key); | ||
| if (path === undefined) return undefined; | ||
| return path.locations[key.pathNodeIndex]; | ||
| } | ||
|
|
||
| /** | ||
| * Returns true if the two keys are both `undefined` or contain the same set of indices. | ||
| */ | ||
| export function equals(key1: PathNode | undefined, key2: PathNode | undefined): boolean { | ||
| if (key1 === key2) return true; | ||
| if (key1 === undefined || key2 === undefined) return false; | ||
| return key1.resultIndex === key2.resultIndex && key1.pathIndex === key2.pathIndex && key1.pathNodeIndex === key2.pathNodeIndex; | ||
| return path.locations[key.pathNodeIndex]?.location; | ||
| } | ||
|
|
||
| /** | ||
| * Returns true if the two keys contain the same set of indices and neither are `undefined`. | ||
| */ | ||
| export function equalsNotUndefined(key1: PathNode | undefined, key2: PathNode | undefined): boolean { | ||
| export function equalsNotUndefined(key1: Partial<PathNode> | undefined, key2: Partial<PathNode> | undefined): boolean { | ||
| if (key1 === undefined || key2 === undefined) return false; | ||
| return key1.resultIndex === key2.resultIndex && key1.pathIndex === key2.pathIndex && key1.pathNodeIndex === key2.pathNodeIndex; | ||
| } | ||
|
|
@@ -93,3 +96,11 @@ export function getAllPaths(result: sarif.Result): sarif.ThreadFlow[] { | |
| } | ||
| return paths; | ||
| } | ||
|
|
||
| /** | ||
| * Creates a unique string representation of the given key, suitable for use | ||
| * as the key in a map or set. | ||
| */ | ||
| export function keyToString(key: ResultKey) { | ||
| return key.resultIndex + '-' + (key.pathIndex ?? '') + '-' + (key.pathNodeIndex ?? ''); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,28 +1,36 @@ | ||
| import * as React from 'react'; | ||
| import { ResultRow } from '../../pure/bqrs-cli-types'; | ||
| import { zebraStripe } from './result-table-utils'; | ||
| import { selectedRowClassName, zebraStripe } from './result-table-utils'; | ||
| import RawTableValue from './RawTableValue'; | ||
| import { ScrollIntoViewHelper } from './scroll-into-view-helper'; | ||
|
|
||
| interface Props { | ||
| rowIndex: number; | ||
| row: ResultRow; | ||
| databaseUri: string; | ||
| className?: string; | ||
| selectedColumn?: number; | ||
| onSelected?: (row: number, column: number) => void; | ||
| scroller?: ScrollIntoViewHelper; | ||
| } | ||
|
|
||
| export default function RawTableRow(props: Props) { | ||
| return ( | ||
| <tr key={props.rowIndex} {...zebraStripe(props.rowIndex, props.className || '')}> | ||
| <td key={-1}>{props.rowIndex + 1}</td> | ||
|
|
||
| {props.row.map((value, columnIndex) => ( | ||
| <td key={columnIndex}> | ||
| <RawTableValue | ||
| value={value} | ||
| databaseUri={props.databaseUri} | ||
| /> | ||
| </td> | ||
| ))} | ||
| {props.row.map((value, columnIndex) => { | ||
| const isSelected = props.selectedColumn === columnIndex; | ||
| return ( | ||
| <td ref={props.scroller?.ref(isSelected)} key={columnIndex} {...isSelected ? { className: selectedRowClassName } : {}}> | ||
| <RawTableValue | ||
| value={value} | ||
| databaseUri={props.databaseUri} | ||
| onSelected={() => props.onSelected?.(props.rowIndex, columnIndex)} | ||
| /> | ||
| </td> | ||
| ); | ||
| })} | ||
| </tr> | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.