Unverified Commit e5fb9c51 authored by Lijiaoa's avatar Lijiaoa Committed by GitHub
Browse files

Make selected trials consistent across auto-refresh in detail table (#3597)


Co-authored-by: default avatarLijiao <Lijiaoa@outlook.com>
parent 7add1c69
...@@ -51,6 +51,7 @@ interface CompareProps { ...@@ -51,6 +51,7 @@ interface CompareProps {
title: string; title: string;
showDetails: boolean; showDetails: boolean;
onHideDialog: () => void; onHideDialog: () => void;
changeSelectTrialIds?: () => void;
} }
class Compare extends React.Component<CompareProps, {}> { class Compare extends React.Component<CompareProps, {}> {
...@@ -196,8 +197,17 @@ class Compare extends React.Component<CompareProps, {}> { ...@@ -196,8 +197,17 @@ class Compare extends React.Component<CompareProps, {}> {
); );
} }
private closeCompareModal = (): void => {
const { showDetails, changeSelectTrialIds, onHideDialog } = this.props;
if (showDetails === true) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
changeSelectTrialIds!();
}
onHideDialog();
};
render(): React.ReactNode { render(): React.ReactNode {
const { onHideDialog, trials, title, showDetails } = this.props; const { trials, title, showDetails } = this.props;
const flatten = (m: Map<SingleAxis, any>): Map<string, any> => { const flatten = (m: Map<SingleAxis, any>): Map<string, any> => {
return new Map(Array.from(m).map(([key, value]) => [key.baseName, value])); return new Map(Array.from(m).map(([key, value]) => [key.baseName, value]));
}; };
...@@ -218,7 +228,7 @@ class Compare extends React.Component<CompareProps, {}> { ...@@ -218,7 +228,7 @@ class Compare extends React.Component<CompareProps, {}> {
className='compare-modal' className='compare-modal'
allowTouchBodyScroll={true} allowTouchBodyScroll={true}
dragOptions={dragOptions} dragOptions={dragOptions}
onDismiss={onHideDialog} onDismiss={this.closeCompareModal}
> >
<div> <div>
<div className={contentStyles.header}> <div className={contentStyles.header}>
...@@ -227,7 +237,7 @@ class Compare extends React.Component<CompareProps, {}> { ...@@ -227,7 +237,7 @@ class Compare extends React.Component<CompareProps, {}> {
styles={iconButtonStyles} styles={iconButtonStyles}
iconProps={{ iconName: 'Cancel' }} iconProps={{ iconName: 'Cancel' }}
ariaLabel='Close popup modal' ariaLabel='Close popup modal'
onClick={onHideDialog} onClick={this.closeCompareModal}
/> />
</div> </div>
<Stack className='compare-modal-intermediate'> <Stack className='compare-modal-intermediate'>
......
...@@ -9,7 +9,7 @@ import TensorboardDialog from './TensorboardDialog'; ...@@ -9,7 +9,7 @@ import TensorboardDialog from './TensorboardDialog';
function TensorboardUI(props): any { function TensorboardUI(props): any {
let refreshTensorboard = 0; let refreshTensorboard = 0;
const { selectedRowIds } = props; const { selectedRowIds, changeSelectTrialIds } = props;
const [queryTensorboardList, setQueryTensorboardList] = useState([]); const [queryTensorboardList, setQueryTensorboardList] = useState([]);
const [isReaptedStartTensorboard, setReaptedTensorboard] = useState(false); const [isReaptedStartTensorboard, setReaptedTensorboard] = useState(false);
const [tensorboardPanelVisible, setTensorboardPanelVisible] = useState(false); const [tensorboardPanelVisible, setTensorboardPanelVisible] = useState(false);
...@@ -130,6 +130,7 @@ function TensorboardUI(props): any { ...@@ -130,6 +130,7 @@ function TensorboardUI(props): any {
item={selectedTensorboard} item={selectedTensorboard}
onHideDialog={(): void => { onHideDialog={(): void => {
setTensorboardPanelVisible(false); setTensorboardPanelVisible(false);
changeSelectTrialIds();
}} }}
/> />
)} )}
...@@ -138,7 +139,8 @@ function TensorboardUI(props): any { ...@@ -138,7 +139,8 @@ function TensorboardUI(props): any {
} }
TensorboardUI.propTypes = { TensorboardUI.propTypes = {
selectedRowIds: PropTypes.array selectedRowIds: PropTypes.array,
changeSelectTrialIds: PropTypes.func
}; };
export default TensorboardUI; export default TensorboardUI;
...@@ -6,12 +6,11 @@ import { ...@@ -6,12 +6,11 @@ import {
Icon, Icon,
IDropdownOption, IDropdownOption,
PrimaryButton, PrimaryButton,
Selection,
SelectionMode,
Stack, Stack,
StackItem, StackItem,
TooltipHost, TooltipHost,
DirectionalHint DirectionalHint,
Checkbox
} from '@fluentui/react'; } from '@fluentui/react';
import { EXPERIMENT, TRIALS } from '../../static/datamodel'; import { EXPERIMENT, TRIALS } from '../../static/datamodel';
import { TOOLTIP_BACKGROUND_COLOR } from '../../static/const'; import { TOOLTIP_BACKGROUND_COLOR } from '../../static/const';
...@@ -95,7 +94,6 @@ interface TableListState { ...@@ -95,7 +94,6 @@ interface TableListState {
} }
class TableList extends React.Component<TableListProps, TableListState> { class TableList extends React.Component<TableListProps, TableListState> {
private _selection: Selection;
private _expandedTrialIds: Set<string>; private _expandedTrialIds: Set<string>;
constructor(props: TableListProps) { constructor(props: TableListProps) {
...@@ -119,14 +117,6 @@ class TableList extends React.Component<TableListProps, TableListState> { ...@@ -119,14 +117,6 @@ class TableList extends React.Component<TableListProps, TableListState> {
sortInfo: { field: '', isDescend: true } sortInfo: { field: '', isDescend: true }
}; };
this._selection = new Selection({
onSelectionChanged: (): void => {
this.setState({
selectedRowIds: this._selection.getSelection().map(s => (s as any).id)
});
}
});
this._expandedTrialIds = new Set<string>(); this._expandedTrialIds = new Set<string>();
} }
...@@ -185,10 +175,12 @@ class TableList extends React.Component<TableListProps, TableListState> { ...@@ -185,10 +175,12 @@ class TableList extends React.Component<TableListProps, TableListState> {
// TODO: use search space and metrics space from TRIALS will cause update issues. // TODO: use search space and metrics space from TRIALS will cause update issues.
const searchSpace = TRIALS.inferredSearchSpace(EXPERIMENT.searchSpaceNew); const searchSpace = TRIALS.inferredSearchSpace(EXPERIMENT.searchSpaceNew);
const metricSpace = TRIALS.inferredMetricSpace(); const metricSpace = TRIALS.inferredMetricSpace();
const { selectedRowIds } = this.state;
const items = trials.map(trial => { const items = trials.map(trial => {
const ret = { const ret = {
sequenceId: trial.sequenceId, sequenceId: trial.sequenceId,
id: trial.id, id: trial.id,
checked: selectedRowIds.includes(trial.id) ? true : false,
startTime: (trial as Trial).info.startTime, // FIXME: why do we need info here? startTime: (trial as Trial).info.startTime, // FIXME: why do we need info here?
endTime: (trial as Trial).info.endTime, endTime: (trial as Trial).info.endTime,
duration: trial.duration, duration: trial.duration,
...@@ -216,9 +208,58 @@ class TableList extends React.Component<TableListProps, TableListState> { ...@@ -216,9 +208,58 @@ class TableList extends React.Component<TableListProps, TableListState> {
} }
} }
private selectedTrialOnChangeEvent = (
id: string,
_ev?: React.FormEvent<HTMLElement | HTMLInputElement>,
checked?: boolean
): void => {
const { displayedItems, selectedRowIds } = this.state;
const items = JSON.parse(JSON.stringify(displayedItems));
const temp = selectedRowIds;
if (checked === true) {
temp.push(id);
}
items.forEach(item => {
if (item.id === id) {
item.checked = !!checked;
}
});
this.setState(() => ({ displayedItems: items, selectedRowIds: temp }));
};
private changeSelectTrialIds = (): void => {
const { displayedItems } = this.state;
const newDisplayedItems = displayedItems;
newDisplayedItems.forEach(item => {
item.checked = false;
});
this.setState(() => ({
selectedRowIds: [],
displayedItems: newDisplayedItems
}));
};
private _buildColumnsFromTableItems(tableItems: any[]): IColumn[] { private _buildColumnsFromTableItems(tableItems: any[]): IColumn[] {
// extra column, for a icon to expand the trial details panel
const columns: IColumn[] = [ const columns: IColumn[] = [
// select trial function
{
name: '',
key: '_selected',
fieldName: 'selected',
minWidth: 20,
maxWidth: 20,
isResizable: true,
className: 'detail-table',
onRender: (record): React.ReactNode => (
<Checkbox
label={undefined}
checked={record.checked}
className='detail-check'
onChange={this.selectedTrialOnChangeEvent.bind(this, record.id)}
/>
)
},
// extra column, for a icon to expand the trial details panel
{ {
key: '_expand', key: '_expand',
name: '', name: '',
...@@ -265,6 +306,7 @@ class TableList extends React.Component<TableListProps, TableListState> { ...@@ -265,6 +306,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
maxWidth: 20 maxWidth: 20
} }
]; ];
// looking at the first row only for now // looking at the first row only for now
for (const k of Object.keys(tableItems[0])) { for (const k of Object.keys(tableItems[0])) {
if (k === 'metric/default') { if (k === 'metric/default') {
...@@ -493,7 +535,10 @@ class TableList extends React.Component<TableListProps, TableListState> { ...@@ -493,7 +535,10 @@ class TableList extends React.Component<TableListProps, TableListState> {
}} }}
disabled={selectedRowIds.length === 0} disabled={selectedRowIds.length === 0}
/> />
<TensorboardUI selectedRowIds={selectedRowIds} /> <TensorboardUI
selectedRowIds={selectedRowIds}
changeSelectTrialIds={this.changeSelectTrialIds}
/>
</StackItem> </StackItem>
<StackItem grow={50}> <StackItem grow={50}>
<Stack horizontal horizontalAlign='end' className='allList'> <Stack horizontal horizontalAlign='end' className='allList'>
...@@ -531,12 +576,12 @@ class TableList extends React.Component<TableListProps, TableListState> { ...@@ -531,12 +576,12 @@ class TableList extends React.Component<TableListProps, TableListState> {
<PaginationTable <PaginationTable
columns={columns.filter( columns={columns.filter(
column => column =>
displayedColumns.includes(column.key) || ['_expand', '_operation'].includes(column.key) displayedColumns.includes(column.key) ||
['_expand', '_operation', '_selected'].includes(column.key)
)} )}
items={displayedItems} items={displayedItems}
compact={true} compact={true}
selection={this._selection} selectionMode={0}
selectionMode={SelectionMode.multiple}
selectionPreservedOnEmptyClick={true} selectionPreservedOnEmptyClick={true}
onRenderRow={(props): any => { onRenderRow={(props): any => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
...@@ -552,6 +597,7 @@ class TableList extends React.Component<TableListProps, TableListState> { ...@@ -552,6 +597,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
onHideDialog={(): void => { onHideDialog={(): void => {
this.setState({ compareDialogVisible: false }); this.setState({ compareDialogVisible: false });
}} }}
changeSelectTrialIds={this.changeSelectTrialIds}
/> />
)} )}
{intermediateDialogTrial !== undefined && ( {intermediateDialogTrial !== undefined && (
......
...@@ -59,3 +59,22 @@ ...@@ -59,3 +59,22 @@
max-height: 335px; max-height: 335px;
overflow-y: auto; overflow-y: auto;
} }
$checkboxwidth: 17px;
.detail-check {
.ms-Checkbox-checkbox {
width: $checkboxwidth;
height: $checkboxwidth;
border-radius: 50%;
border: none;
&:hover {
border: 1px solid grey;
}
i {
width: 12px;
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment