Skip to content

Commit

Permalink
Refactor available views component
Browse files Browse the repository at this point in the history
Currently, the trace-overview-selection-dialog-component and
the trace-explorer-views-widget have some common code. This
commit refactors the common code by creating the reusable
available-view-component. The prior two components will then
call the later component and thus use the same code.

Signed-off-by: Hoang Thuan Pham <hoang.pham@calian.ca>
  • Loading branch information
hoangphamEclipse authored and MatthewKhouzam committed Aug 5, 2022
1 parent 84a090c commit f936a11
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,10 @@ export class TraceOverviewSelectionDialogComponent extends AbstractDialogCompone
Loading available outputs...
</div>);
}

const key = Number(true);
return (
<div id="trace-overview-selection-dialog-content-container">
<AvailableViewsComponent
availableViewListKey={key}
traceID={this.props.traceID}
onOutputClicked={e => {this.doHandleOutputClicked(e);}}
outputDescriptors={this.state.outputDescriptors}
listRowWidth='95%'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { ListRowProps, AutoSizer, List } from 'react-virtualized';
import React from 'react';
import { OutputDescriptor } from 'tsp-typescript-client/lib/models/output-descriptor';
import { Experiment } from 'tsp-typescript-client/lib/models/experiment';
import { signalManager, Signals } from 'traceviewer-base/lib/signals/signal-manager';

export interface AvailableViewsComponentProps {
availableViewListKey: number,
traceID: string | undefined,
outputDescriptors: OutputDescriptor[],
onContextMenuEvent?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>, output: OutputDescriptor | undefined) => void,
onOutputClicked: (selectedOutput: OutputDescriptor) => void,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
listRowWidth?: string,
listRowPadding?: string
listRowPadding?: string,
highlightAfterSelection?: boolean
}

export interface AvailableViewsComponentState {
Expand All @@ -21,36 +23,43 @@ export class AvailableViewsComponent extends React.Component<AvailableViewsComp
static LINE_HEIGHT = 16;
static ROW_HEIGHT = (2 * AvailableViewsComponent.LINE_HEIGHT) + AvailableViewsComponent.LIST_MARGIN;

private _forceUpdateKey = false;
protected handleOutputClicked = (e: React.MouseEvent<HTMLDivElement>): void => this.doHandleOutputClicked(e);
private _onExperimentSelected = (experiment: Experiment): void => this.doHandleExperimentSelectedSignal(experiment);

constructor(props: AvailableViewsComponentProps){
super(props);
signalManager().on(Signals.EXPERIMENT_SELECTED, this._onExperimentSelected);
this.state = { lastSelectedOutputIndex: -1 };
}

componentWillUnmount(): void {
signalManager().off(Signals.EXPERIMENT_SELECTED, this._onExperimentSelected);
}

render(): React.ReactNode {
this._forceUpdateKey = !this._forceUpdateKey;
const key = Number(this._forceUpdateKey);
let outputsRowCount = 0;
const outputs = this.props.outputDescriptors;
if (outputs) {
outputsRowCount = outputs.length;
}
const totalHeight = this.getTotalHeight();
return (
<div>
<div className='trace-explorer-panel-content disable-select' style={{height: totalHeight}}>
<AutoSizer>
{({ width }) =>
<List
key={this.props.availableViewListKey}
height={totalHeight}
width={width}
rowCount={outputsRowCount}
rowHeight={AvailableViewsComponent.ROW_HEIGHT}
rowRenderer={this.renderRowOutputs}
/>
}
</AutoSizer>
</div>
<div className='trace-explorer-panel-content disable-select' style={{height: totalHeight}}>
<AutoSizer>
{({ width }) =>
<List
key={key}
height={totalHeight}
width={width}
rowCount={outputsRowCount}
rowHeight={AvailableViewsComponent.ROW_HEIGHT}
rowRenderer={this.renderRowOutputs}
/>
}
</AutoSizer>
</div>
);
}
Expand All @@ -68,7 +77,7 @@ export class AvailableViewsComponent extends React.Component<AvailableViewsComp
outputDescription = output.description;
}
let traceContainerClassName = 'outputs-list-container';
if (props.index === this.state.lastSelectedOutputIndex) {
if (this.props.highlightAfterSelection && props.index === this.state.lastSelectedOutputIndex) {
traceContainerClassName = traceContainerClassName + ' theia-mod-selected';
}

Expand Down Expand Up @@ -106,8 +115,15 @@ export class AvailableViewsComponent extends React.Component<AvailableViewsComp
{this.props.onContextMenuEvent(event, output);}
}

protected doHandleExperimentSelectedSignal(experiment: Experiment | undefined): void {
if ((this.props.traceID !== experiment?.UUID) || this.props.outputDescriptors.length === 0) {
this.setState({ lastSelectedOutputIndex: -1 });
}
}

private doHandleOutputClicked(e: React.MouseEvent<HTMLDivElement>) {
const index = Number(e.currentTarget.getAttribute('data-id'));
this.setState({lastSelectedOutputIndex: index});
const selectedOutput = this.props.outputDescriptors[index];

this.props.onOutputClicked(selectedOutput);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import * as React from 'react';
import { List, ListRowProps, AutoSizer } from 'react-virtualized';
import { OutputAddedSignalPayload } from 'traceviewer-base/lib/signals/output-added-signal-payload';
import { signalManager, Signals } from 'traceviewer-base/lib/signals/signal-manager';
import { OutputDescriptor } from 'tsp-typescript-client/lib/models/output-descriptor';
import { Experiment } from 'tsp-typescript-client/lib/models/experiment';
import { ITspClientProvider } from 'traceviewer-base/lib/tsp-client-provider';
import { ExperimentManager } from 'traceviewer-base/lib/experiment-manager';
import { AvailableViewsComponent } from '../components/utils/available-views-component';

export interface ReactAvailableViewsProps {
id: string,
Expand All @@ -15,16 +15,10 @@ export interface ReactAvailableViewsProps {
}

export interface ReactAvailableViewsState {
availableOutputDescriptors: OutputDescriptor[],
lastSelectedOutputIndex: number;
availableOutputDescriptors: OutputDescriptor[]
}

export class ReactAvailableViewsWidget extends React.Component<ReactAvailableViewsProps, ReactAvailableViewsState> {
static LIST_MARGIN = 2;
static LINE_HEIGHT = 16;
static ROW_HEIGHT = (2 * ReactAvailableViewsWidget.LINE_HEIGHT) + ReactAvailableViewsWidget.LIST_MARGIN;

private _forceUpdateKey = false;
private _selectedExperiment: Experiment | undefined;
private _experimentManager: ExperimentManager;

Expand All @@ -39,7 +33,7 @@ export class ReactAvailableViewsWidget extends React.Component<ReactAvailableVie
});
signalManager().on(Signals.EXPERIMENT_SELECTED, this._onExperimentSelected);
signalManager().on(Signals.EXPERIMENT_CLOSED, this._onExperimentClosed);
this.state = { availableOutputDescriptors: [], lastSelectedOutputIndex: -1 };
this.state = { availableOutputDescriptors: []};
}

componentWillUnmount(): void {
Expand All @@ -48,85 +42,25 @@ export class ReactAvailableViewsWidget extends React.Component<ReactAvailableVie
}

render(): React.ReactNode {
this._forceUpdateKey = !this._forceUpdateKey;
const key = Number(this._forceUpdateKey);
let outputsRowCount = 0;
const outputs = this.state.availableOutputDescriptors;
if (outputs) {
outputsRowCount = outputs.length;
}
const totalHeight = this.getTotalHeight();
return (
<div className='trace-explorer-views'>
<div className='trace-explorer-panel-content disable-select'>
<AutoSizer>
{({ width }) =>
<List
key={key}
height={totalHeight}
width={width}
rowCount={outputsRowCount}
rowHeight={ReactAvailableViewsWidget.ROW_HEIGHT}
rowRenderer={this.renderRowOutputs}
/>
}
</AutoSizer>
</div>
<AvailableViewsComponent
traceID={this._selectedExperiment?.UUID}
outputDescriptors={this.state.availableOutputDescriptors}
onContextMenuEvent={this.handleContextMenuEvent}
onOutputClicked={this.handleOutputClicked}
highlightAfterSelection={true}
></AvailableViewsComponent>
</div>
);
}

protected renderRowOutputs = (props: ListRowProps): React.ReactNode => this.doRenderRowOutputs(props);

private doRenderRowOutputs(props: ListRowProps): React.ReactNode {
let outputName = '';
let outputDescription = '';
let output: OutputDescriptor | undefined;
const outputDescriptors = this.state.availableOutputDescriptors;
if (outputDescriptors && outputDescriptors.length && props.index < outputDescriptors.length) {
output = outputDescriptors[props.index];
outputName = output.name;
outputDescription = output.description;
}
let traceContainerClassName = 'outputs-list-container';
if (props.index === this.state.lastSelectedOutputIndex) {
traceContainerClassName = traceContainerClassName + ' theia-mod-selected';
}
return <div className={traceContainerClassName}
title={outputName + ':\n' + outputDescription}
id={`${traceContainerClassName}-${props.index}`}
key={props.key}
style={props.style}
onClick={this.handleOutputClicked}
onContextMenu={event => { this.handleContextMenuEvent(event, output); }}
data-id={`${props.index}`}
>
<h4 className='outputs-element-name'>
{outputName}
</h4>
<div className='outputs-element-description child-element'>
{outputDescription}
</div>
</div>;
}

protected getTotalHeight(): number {
let totalHeight = 0;
const outputDescriptors = this.state.availableOutputDescriptors;
outputDescriptors?.forEach(() => totalHeight += ReactAvailableViewsWidget.ROW_HEIGHT);
return totalHeight;
}

protected handleOutputClicked = (e: React.MouseEvent<HTMLDivElement>): void => this.doHandleOutputClicked(e);
protected handleOutputClicked = (outputDescriptor: OutputDescriptor): void => this.doHandleOutputClicked(outputDescriptor);
protected handleContextMenuEvent = (e: React.MouseEvent<HTMLDivElement>, output: OutputDescriptor | undefined): void => this.doHandleContextMenuEvent(e, output);

private doHandleOutputClicked(e: React.MouseEvent<HTMLDivElement>) {
const index = Number(e.currentTarget.getAttribute('data-id'));
this.setState({ lastSelectedOutputIndex: index });
const outputs = this.state.availableOutputDescriptors;

if (outputs && this._selectedExperiment) {
signalManager().fireOutputAddedSignal(new OutputAddedSignalPayload(outputs[index], this._selectedExperiment));
private doHandleOutputClicked(selectedOutput: OutputDescriptor) {
if (selectedOutput && this._selectedExperiment) {
signalManager().fireOutputAddedSignal(new OutputAddedSignalPayload(selectedOutput, this._selectedExperiment));
}
}

Expand All @@ -141,7 +75,7 @@ export class ReactAvailableViewsWidget extends React.Component<ReactAvailableVie
protected doHandleExperimentSelectedSignal(experiment: Experiment | undefined): void {
if ((this._selectedExperiment?.UUID !== experiment?.UUID) || this.state.availableOutputDescriptors.length === 0) {
this._selectedExperiment = experiment;
this.setState({ availableOutputDescriptors: [], lastSelectedOutputIndex: -1 });
this.setState({ availableOutputDescriptors: []});
this.updateAvailableViews();
}
}
Expand Down

0 comments on commit f936a11

Please sign in to comment.