@@ -24,6 +24,7 @@ import { vscode } from "../vscode-api";
2424import { sendTelemetry } from "../common/telemetry" ;
2525import { ResultTable } from "./ResultTable" ;
2626import { ResultTablesHeader } from "./ResultTablesHeader" ;
27+ import { useEffect } from "react" ;
2728
2829/**
2930 * Properties for the `ResultTables` component.
@@ -43,14 +44,6 @@ interface ResultTablesProps {
4344 queryPath : string ;
4445}
4546
46- /**
47- * State for the `ResultTables` component.
48- */
49- interface ResultTablesState {
50- selectedTable : string ; // name of selected result set
51- problemsViewSelected : boolean ;
52- }
53-
5447const UPDATING_RESULTS_TEXT_CLASS_NAME =
5548 "vscode-codeql__result-tables-updating-text" ;
5649
@@ -122,85 +115,71 @@ function getResultSets(
122115 * Displays multiple `ResultTable` tables, where the table to be displayed is selected by a
123116 * dropdown.
124117 */
125- export class ResultTables extends React . Component <
126- ResultTablesProps ,
127- ResultTablesState
128- > {
129- constructor ( props : ResultTablesProps ) {
130- super ( props ) ;
131- const selectedTable =
132- props . parsedResultSets . selectedTable ||
133- getDefaultResultSet (
134- getResultSets ( props . rawResultSets , props . interpretation ) ,
135- ) ;
136- this . state = {
137- selectedTable,
138- problemsViewSelected : false ,
139- } ;
140- }
118+ export function ResultTables ( props : ResultTablesProps ) {
119+ const {
120+ parsedResultSets,
121+ rawResultSets,
122+ interpretation,
123+ database,
124+ resultsPath,
125+ metadata,
126+ origResultsPaths,
127+ isLoadingNewResults,
128+ sortStates,
129+ } = props ;
141130
142- handleMessage ( msg : IntoResultsViewMsg ) : void {
131+ const [ selectedTable , setSelectedTable ] = React . useState (
132+ parsedResultSets . selectedTable ||
133+ getDefaultResultSet ( getResultSets ( rawResultSets , interpretation ) ) ,
134+ ) ;
135+ const [ problemsViewSelected , setProblemsViewSelected ] = React . useState ( false ) ;
136+
137+ const handleMessage = ( msg : IntoResultsViewMsg ) : void => {
143138 switch ( msg . t ) {
144139 case "untoggleShowProblems" :
145- this . setState ( {
146- problemsViewSelected : false ,
147- } ) ;
140+ setProblemsViewSelected ( false ) ;
148141 break ;
149142
150143 default :
151144 // noop
152145 }
153- }
146+ } ;
154147
155- private vscodeMessageHandler ( evt : MessageEvent ) {
148+ const vscodeMessageHandler = ( evt : MessageEvent ) : void => {
156149 // sanitize origin
157150 const origin = evt . origin . replace ( / \n | \r / g, "" ) ;
158151 evt . origin === window . origin
159- ? this . handleMessage ( evt . data as IntoResultsViewMsg )
152+ ? handleMessage ( evt . data as IntoResultsViewMsg )
160153 : console . error ( `Invalid event origin ${ origin } ` ) ;
161- }
154+ } ;
162155
163156 // TODO: Duplicated from results.tsx consider a way to
164157 // avoid this duplication
165- componentDidMount ( ) : void {
166- this . vscodeMessageHandler = this . vscodeMessageHandler . bind ( this ) ;
167- window . addEventListener ( "message" , this . vscodeMessageHandler ) ;
168- }
158+ useEffect ( ( ) => {
159+ window . addEventListener ( "message" , vscodeMessageHandler ) ;
169160
170- componentWillUnmount ( ) : void {
171- if ( this . vscodeMessageHandler ) {
172- window . removeEventListener ( "message" , this . vscodeMessageHandler ) ;
173- }
174- }
161+ return ( ) => {
162+ window . removeEventListener ( "message" , vscodeMessageHandler ) ;
163+ } ;
164+ } , [ ] ) ;
175165
176- componentDidUpdate (
177- prevProps : Readonly < ResultTablesProps > ,
178- prevState : Readonly < ResultTablesState > ,
179- snapshot ?: any ,
180- ) {
166+ useEffect ( ( ) => {
181167 const resultSetExists =
182- this . props . parsedResultSets . resultSetNames . some (
183- ( v ) => this . state . selectedTable === v ,
184- ) ||
185- getResultSets ( this . props . rawResultSets , this . props . interpretation ) . some (
186- ( v ) => this . state . selectedTable === v . schema . name ,
168+ parsedResultSets . resultSetNames . some ( ( v ) => selectedTable === v ) ||
169+ getResultSets ( rawResultSets , interpretation ) . some (
170+ ( v ) => selectedTable === v . schema . name ,
187171 ) ;
188172
189173 // If the selected result set does not exist, select the default result set.
190174 if ( ! resultSetExists ) {
191- this . setState ( ( state , props ) => {
192- const selectedTable =
193- props . parsedResultSets . selectedTable ||
194- getDefaultResultSet (
195- getResultSets ( props . rawResultSets , props . interpretation ) ,
196- ) ;
197-
198- return { selectedTable } ;
199- } ) ;
175+ setSelectedTable (
176+ parsedResultSets . selectedTable ||
177+ getDefaultResultSet ( getResultSets ( rawResultSets , interpretation ) ) ,
178+ ) ;
200179 }
201- }
180+ } ) ;
202181
203- private onTableSelectionChange = (
182+ const onTableSelectionChange = (
204183 event : React . ChangeEvent < HTMLSelectElement > ,
205184 ) : void => {
206185 const selectedTable = event . target . value ;
@@ -212,16 +191,13 @@ export class ResultTables extends React.Component<
212191 sendTelemetry ( "local-results-table-selection" ) ;
213192 } ;
214193
215- private alertTableExtras ( ) : JSX . Element | undefined {
216- const { database, resultsPath, metadata, origResultsPaths } = this . props ;
194+ const alertTableExtras = ( ) : JSX . Element | undefined => {
217195 const handleCheckboxChanged = ( e : React . ChangeEvent < HTMLInputElement > ) => {
218- if ( e . target . checked === this . state . problemsViewSelected ) {
196+ if ( e . target . checked === problemsViewSelected ) {
219197 // no change
220198 return ;
221199 }
222- this . setState ( {
223- problemsViewSelected : e . target . checked ,
224- } ) ;
200+ setProblemsViewSelected ( e . target . checked ) ;
225201 if ( e . target . checked ) {
226202 sendTelemetry ( "local-results-show-results-in-problems-view" ) ;
227203 }
@@ -244,85 +220,69 @@ export class ResultTables extends React.Component<
244220 id = "toggle-diagnostics"
245221 name = "toggle-diagnostics"
246222 onChange = { handleCheckboxChanged }
247- checked = { this . state . problemsViewSelected }
223+ checked = { problemsViewSelected }
248224 />
249225 < label htmlFor = "toggle-diagnostics" >
250226 Show results in Problems view
251227 </ label >
252228 </ div >
253229 </ div >
254230 ) ;
255- }
231+ } ;
256232
257- getOffset ( ) : number {
258- const { parsedResultSets } = this . props ;
233+ const getOffset = ( ) : number => {
259234 return parsedResultSets . pageNumber * parsedResultSets . pageSize ;
260- }
235+ } ;
261236
262- render ( ) : React . ReactNode {
263- const { selectedTable } = this . state ;
264- const resultSets = getResultSets (
265- this . props . rawResultSets ,
266- this . props . interpretation ,
267- ) ;
268- const resultSetNames = getResultSetNames (
269- this . props . interpretation ,
270- this . props . parsedResultSets ,
271- ) ;
237+ const resultSets = getResultSets ( rawResultSets , interpretation ) ;
238+ const resultSetNames = getResultSetNames ( interpretation , parsedResultSets ) ;
272239
273- const resultSet = resultSets . find (
274- ( resultSet ) => resultSet . schema . name === selectedTable ,
275- ) ;
276- const nonemptyRawResults = resultSets . some (
277- ( resultSet ) =>
278- resultSet . t === "RawResultSet" && resultSet . rows . length > 0 ,
279- ) ;
280- const numberOfResults = resultSet && renderResultCountString ( resultSet ) ;
240+ const resultSet = resultSets . find (
241+ ( resultSet ) => resultSet . schema . name === selectedTable ,
242+ ) ;
243+ const nonemptyRawResults = resultSets . some (
244+ ( resultSet ) => resultSet . t === "RawResultSet" && resultSet . rows . length > 0 ,
245+ ) ;
246+ const numberOfResults = resultSet && renderResultCountString ( resultSet ) ;
281247
282- const resultSetOptions = resultSetNames . map ( ( name ) => (
283- < option key = { name } value = { name } >
284- { name }
285- </ option >
286- ) ) ;
287- return (
288- < div >
289- < ResultTablesHeader
290- { ...this . props }
291- selectedTable = { this . state . selectedTable }
292- />
293- < div className = { tableHeaderClassName } > </ div >
294- < div className = { tableHeaderClassName } >
295- < select value = { selectedTable } onChange = { this . onTableSelectionChange } >
296- { resultSetOptions }
297- </ select >
298- { numberOfResults }
299- { selectedTable === ALERTS_TABLE_NAME
300- ? this . alertTableExtras ( )
301- : undefined }
302- { this . props . isLoadingNewResults ? (
303- < span className = { UPDATING_RESULTS_TEXT_CLASS_NAME } >
304- Updating results…
305- </ span >
306- ) : null }
307- </ div >
308- { resultSet && (
309- < ResultTable
310- key = { resultSet . schema . name }
311- resultSet = { resultSet }
312- databaseUri = { this . props . database . databaseUri }
313- resultsPath = { this . props . resultsPath }
314- sortState = { this . props . sortStates . get ( resultSet . schema . name ) }
315- nonemptyRawResults = { nonemptyRawResults }
316- showRawResults = { ( ) => {
317- this . setState ( { selectedTable : SELECT_TABLE_NAME } ) ;
318- sendTelemetry ( "local-results-show-raw-results" ) ;
319- } }
320- offset = { this . getOffset ( ) }
321- />
322- ) }
248+ const resultSetOptions = resultSetNames . map ( ( name ) => (
249+ < option key = { name } value = { name } >
250+ { name }
251+ </ option >
252+ ) ) ;
253+ return (
254+ < div >
255+ < ResultTablesHeader { ...props } selectedTable = { selectedTable } />
256+ < div className = { tableHeaderClassName } > </ div >
257+ < div className = { tableHeaderClassName } >
258+ < select value = { selectedTable } onChange = { onTableSelectionChange } >
259+ { resultSetOptions }
260+ </ select >
261+ { numberOfResults }
262+ { selectedTable === ALERTS_TABLE_NAME ? alertTableExtras ( ) : undefined }
263+ { isLoadingNewResults ? (
264+ < span className = { UPDATING_RESULTS_TEXT_CLASS_NAME } >
265+ Updating results…
266+ </ span >
267+ ) : null }
323268 </ div >
324- ) ;
325- }
269+ { resultSet && (
270+ < ResultTable
271+ key = { resultSet . schema . name }
272+ resultSet = { resultSet }
273+ databaseUri = { database . databaseUri }
274+ resultsPath = { resultsPath }
275+ sortState = { sortStates . get ( resultSet . schema . name ) }
276+ nonemptyRawResults = { nonemptyRawResults }
277+ showRawResults = { ( ) => {
278+ setSelectedTable ( SELECT_TABLE_NAME ) ;
279+ sendTelemetry ( "local-results-show-raw-results" ) ;
280+ } }
281+ offset = { getOffset ( ) }
282+ />
283+ ) }
284+ </ div >
285+ ) ;
326286}
327287
328288function getDefaultResultSet ( resultSets : readonly ResultSet [ ] ) : string {
0 commit comments