Teach webview to do pagination in interpreted results

This commit is contained in:
Jason Reed
2020-06-30 09:39:04 -04:00
parent 0e3b7a8eb5
commit 11c538a99d
4 changed files with 32 additions and 17 deletions

View File

@@ -1,5 +1,6 @@
import { DecodedBqrsChunk, ResultSetSchema, ColumnKind, Column, ColumnValue } from './bqrs-cli-types';
import { LocationValue, ResultSetSchema as AdaptedSchema, ColumnSchema, ColumnType, LocationStyle } from 'semmle-bqrs';
import { ResultSet } from './interface-types';
// FIXME: This is a temporary bit of impedance matching to convert
// from the types provided by ./bqrs-cli-types, to the types used by
@@ -130,5 +131,5 @@ export interface ExtensionParsedResultSets {
numPages: number;
selectedTable?: string; // when undefined, means 'show default table'
resultSetNames: string[];
resultSet: RawResultSet;
resultSet: ResultSet;
}

View File

@@ -362,7 +362,7 @@ export class InterfaceManager extends DisposableObject {
t: 'ExtensionParsed',
pageNumber: 0,
numPages: numPagesOfResultSet(resultSet),
resultSet,
resultSet: { t: 'RawResultSet', ...resultSet },
selectedTable: undefined,
resultSetNames,
};
@@ -456,7 +456,7 @@ export class InterfaceManager extends DisposableObject {
const parsedResultSets: ParsedResultSets = {
t: 'ExtensionParsed',
pageNumber,
resultSet,
resultSet: { t: 'RawResultSet', ...resultSet },
numPages: numPagesOfResultSet(resultSet),
selectedTable: selectedTable,
resultSetNames,

View File

@@ -70,13 +70,13 @@ function renderResultCountString(resultSet: ResultSet): JSX.Element {
export class ResultTables
extends React.Component<ResultTablesProps, ResultTablesState> {
private getResultSets(): ResultSet[] {
private static _getResultSetsOfProps(props: ResultTablesProps): ResultSet[] {
const resultSets: ResultSet[] =
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore 2783
this.props.rawResultSets.map((rs) => ({ t: 'RawResultSet', ...rs }));
props.rawResultSets.map((rs) => ({ t: 'RawResultSet', ...rs }));
if (this.props.interpretation != undefined) {
if (props.interpretation != undefined) {
resultSets.push({
t: 'SarifResultSet',
// FIXME: The values of version, columns, tupleCount are
@@ -85,12 +85,16 @@ export class ResultTables
// out.
schema: { name: ALERTS_TABLE_NAME, version: 0, columns: [], tupleCount: 1 },
name: ALERTS_TABLE_NAME,
...this.props.interpretation,
...props.interpretation,
});
}
return resultSets;
}
private getResultSets(): ResultSet[] {
return ResultTables._getResultSetsOfProps(this.props);
}
private getResultSetNames(resultSets: ResultSet[]): string[] {
if (this.props.parsedResultSets.t === 'ExtensionParsed') {
return this.props.parsedResultSets.resultSetNames.concat([ALERTS_TABLE_NAME]);
@@ -120,10 +124,14 @@ export class ResultTables
constructor(props: ResultTablesProps) {
super(props);
this.state = ResultTables.getDerivedStateFromProps(props);
}
const selectedTable = props.parsedResultSets.selectedTable || getDefaultResultSet(this.getResultSets());
// Static lifecycle method which is called by react when props change.
static getDerivedStateFromProps(props: Readonly<ResultTablesProps>, _prevState?: ResultTablesState): ResultTablesState {
const selectedTable = props.parsedResultSets.selectedTable || getDefaultResultSet(ResultTables._getResultSetsOfProps(props));
let selectedPage: string;
switch (props.parsedResultSets.t) {
case 'ExtensionParsed':
selectedPage = (props.parsedResultSets.pageNumber + 1) + '';
@@ -132,8 +140,7 @@ export class ResultTables
selectedPage = '';
break;
}
this.state = { selectedTable, selectedPage };
return { selectedTable, selectedPage };
}
private onTableSelectionChange = (event: React.ChangeEvent<HTMLSelectElement>): void => {
@@ -218,7 +225,7 @@ export class ResultTables
};
return <span>
<button onClick={prevPage} >&lt;</button>
<input value={this.state.selectedPage} onChange={onChange}
<input size={3} value={this.state.selectedPage} onChange={onChange}
onBlur={e => choosePage(e.target.value)}
onKeyDown={e => { if (e.keyCode === 13) choosePage((e.target as HTMLInputElement).value); }}
/>

View File

@@ -197,23 +197,30 @@ class App extends React.Component<{}, ResultsViewState> {
this.loadResults();
break;
case 'showInterpretedPage':
this.updateStateWithNewResultsInfo({
const resultsInfo: ResultsInfo = {
resultsPath: '...', // XXX
parsedResultSets: {
t: 'ExtensionParsed',
numPages: msg.numPages,
resultSetNames: ['alerts'], // XXX get the other result set names from the extension
pageNumber: msg.pageNumber,
resultSet: undefined as any, // XXX this is awkward
resultSet: {
t: 'SarifResultSet',
name: ALERTS_TABLE_NAME,
schema: { name: ALERTS_TABLE_NAME, version: 0, columns: [], tupleCount: 1 },
...msg.interpretation,
},
selectedTable: ALERTS_TABLE_NAME,
},
origResultsPaths: undefined as any,
sortedResultsMap: undefined as any,
sortedResultsMap: new Map(), // XXX ?
database: msg.database,
interpretation: msg.interpretation,
shouldKeepOldResultsWhileRendering: false,
shouldKeepOldResultsWhileRendering: true,
metadata: msg.metadata,
});
};
this.updateStateWithNewResultsInfo(resultsInfo);
this.loadResults();
break;
case 'resultsUpdating':
this.setState({