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

Support copy trial id, experiment id in the table (#3378)

parent b1ae52ea
...@@ -12,6 +12,7 @@ import FilterBtns from './FilterBtns'; ...@@ -12,6 +12,7 @@ import FilterBtns from './FilterBtns';
import { TitleContext } from '../overview/TitleContext'; import { TitleContext } from '../overview/TitleContext';
import { Title } from '../overview/Title'; import { Title } from '../overview/Title';
import '../../App.scss'; import '../../App.scss';
import '../../static/style/common.scss';
import '../../static/style/nav/nav.scss'; import '../../static/style/nav/nav.scss';
import '../../static/style/experiment/experiment.scss'; import '../../static/style/experiment/experiment.scss';
import '../../static/style/overview/probar.scss'; import '../../static/style/overview/probar.scss';
...@@ -173,7 +174,7 @@ class Experiment extends React.Component<{}, ExpListState> { ...@@ -173,7 +174,7 @@ class Experiment extends React.Component<{}, ExpListState> {
isResizable: true, isResizable: true,
data: 'number', data: 'number',
onColumnClick: this.onColumnClick, onColumnClick: this.onColumnClick,
onRender: (item: any): React.ReactNode => <div className='succeed-padding'>{item.experimentName}</div> onRender: (item: any): React.ReactNode => <div>{item.experimentName}</div>
}, },
{ {
name: 'ID', name: 'ID',
...@@ -195,9 +196,7 @@ class Experiment extends React.Component<{}, ExpListState> { ...@@ -195,9 +196,7 @@ class Experiment extends React.Component<{}, ExpListState> {
maxWidth: MAXSCREENCOLUMNWIDHT, maxWidth: MAXSCREENCOLUMNWIDHT,
isResizable: true, isResizable: true,
onColumnClick: this.onColumnClick, onColumnClick: this.onColumnClick,
onRender: (item: any): React.ReactNode => ( onRender: (item: any): React.ReactNode => <div className={`${item.status} commonStyle`}>{item.status}</div>
<div className={`${item.status} commonStyle succeed-padding`}>{item.status}</div>
)
}, },
{ {
name: 'Port', name: 'Port',
...@@ -209,10 +208,8 @@ class Experiment extends React.Component<{}, ExpListState> { ...@@ -209,10 +208,8 @@ class Experiment extends React.Component<{}, ExpListState> {
data: 'number', data: 'number',
onColumnClick: this.onColumnClick, onColumnClick: this.onColumnClick,
onRender: (item: any): React.ReactNode => ( onRender: (item: any): React.ReactNode => (
<div className='succeed-padding'> <div className={item.status === 'STOPPED' ? 'gray-port' : ''}>
<div className={item.status === 'STOPPED' ? 'gray-port' : ''}> {item.port !== undefined ? item.port : '--'}
{item.port !== undefined ? item.port : '--'}
</div>
</div> </div>
) )
}, },
...@@ -225,7 +222,7 @@ class Experiment extends React.Component<{}, ExpListState> { ...@@ -225,7 +222,7 @@ class Experiment extends React.Component<{}, ExpListState> {
isResizable: true, isResizable: true,
data: 'string', data: 'string',
onColumnClick: this.onColumnClick, onColumnClick: this.onColumnClick,
onRender: (item: any): React.ReactNode => <div className='commonStyle succeed-padding'>{item.platform}</div> onRender: (item: any): React.ReactNode => <div className='commonStyle'>{item.platform}</div>
}, },
{ {
name: 'Start time', name: 'Start time',
...@@ -236,11 +233,7 @@ class Experiment extends React.Component<{}, ExpListState> { ...@@ -236,11 +233,7 @@ class Experiment extends React.Component<{}, ExpListState> {
isResizable: true, isResizable: true,
data: 'number', data: 'number',
onColumnClick: this.onColumnClick, onColumnClick: this.onColumnClick,
onRender: (item: any): React.ReactNode => ( onRender: (item: any): React.ReactNode => <div>{expformatTimestamp(item.startTime)}</div>
<div className='succeed-padding'>
<div>{expformatTimestamp(item.startTime)}</div>
</div>
)
}, },
{ {
name: 'End time', name: 'End time',
...@@ -251,11 +244,7 @@ class Experiment extends React.Component<{}, ExpListState> { ...@@ -251,11 +244,7 @@ class Experiment extends React.Component<{}, ExpListState> {
isResizable: true, isResizable: true,
data: 'number', data: 'number',
onColumnClick: this.onColumnClick, onColumnClick: this.onColumnClick,
onRender: (item: any): React.ReactNode => ( onRender: (item: any): React.ReactNode => <div>{expformatTimestamp(item.endTime)}</div>
<div className='succeed-padding'>
<div>{expformatTimestamp(item.endTime)}</div>
</div>
)
} }
]; ];
......
import * as React from 'react'; import * as React from 'react';
import { Stack } from '@fluentui/react';
import CopyButton from '../public-child/CopyButton';
interface TrialIdColumnProps { interface TrialIdColumnProps {
port: number; port: number;
...@@ -17,7 +19,7 @@ class TrialIdColumn extends React.Component<TrialIdColumnProps, {}> { ...@@ -17,7 +19,7 @@ class TrialIdColumn extends React.Component<TrialIdColumnProps, {}> {
const protocol = window.location.protocol; const protocol = window.location.protocol;
const webuiPortal = `${protocol}//${hostname}:${port}/oview`; const webuiPortal = `${protocol}//${hostname}:${port}/oview`;
return ( return (
<div className='succeed-padding ellipsis'> <Stack horizontal className='ellipsis idCopy'>
{status === 'STOPPED' ? ( {status === 'STOPPED' ? (
<div className='idColor'>{id}</div> <div className='idColor'>{id}</div>
) : ( ) : (
...@@ -30,7 +32,8 @@ class TrialIdColumn extends React.Component<TrialIdColumnProps, {}> { ...@@ -30,7 +32,8 @@ class TrialIdColumn extends React.Component<TrialIdColumnProps, {}> {
{id} {id}
</a> </a>
)} )}
</div> <CopyButton value={id} />
</Stack>
); );
} }
} }
......
import * as React from 'react'; import * as React from 'react';
import { import {
Stack,
DetailsList, DetailsList,
IDetailsListProps, IDetailsListProps,
IColumn, IColumn,
...@@ -14,6 +15,7 @@ import { ...@@ -14,6 +15,7 @@ import {
} from '@fluentui/react'; } from '@fluentui/react';
import DefaultMetric from '../../public-child/DefaultMetric'; import DefaultMetric from '../../public-child/DefaultMetric';
import OpenRow from '../../public-child/OpenRow'; import OpenRow from '../../public-child/OpenRow';
import CopyButton from '../../public-child/CopyButton';
import { convertDuration, copyAndSort } from '../../../static/function'; import { convertDuration, copyAndSort } from '../../../static/function';
import { TRIALS } from '../../../static/datamodel'; import { TRIALS } from '../../../static/datamodel';
import { SortInfo } from '../../../static/interface'; import { SortInfo } from '../../../static/interface';
...@@ -134,7 +136,7 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState> ...@@ -134,7 +136,7 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
key: 'sequenceId', key: 'sequenceId',
fieldName: 'sequenceId', // required! fieldName: 'sequenceId', // required!
minWidth: 60, minWidth: 60,
maxWidth: 100, maxWidth: 80,
isResizable: true, isResizable: true,
data: 'number', data: 'number',
onColumnClick: this.onColumnClick, onColumnClick: this.onColumnClick,
...@@ -144,18 +146,23 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState> ...@@ -144,18 +146,23 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
name: 'ID', name: 'ID',
key: 'id', key: 'id',
fieldName: 'id', fieldName: 'id',
minWidth: 60, minWidth: 90,
maxWidth: 90, maxWidth: 100,
isResizable: true, isResizable: true,
className: 'tableHead leftTitle', className: 'tableHead leftTitle',
data: 'string', data: 'string',
onColumnClick: this.onColumnClick, onColumnClick: this.onColumnClick,
onRender: (item: any): React.ReactNode => <div className='succeed-padding'>{item.id}</div> onRender: (item: any): React.ReactNode => (
<Stack horizontal className='idCopy'>
<div className='succeed-padding'>{item.id}</div>
<CopyButton value={item.id} />
</Stack>
)
}, },
{ {
name: 'Duration', name: 'Duration',
key: 'duration', key: 'duration',
minWidth: 80, minWidth: 70,
maxWidth: 120, maxWidth: 120,
isResizable: true, isResizable: true,
fieldName: 'duration', fieldName: 'duration',
......
import React, { useRef } from 'react';
import PropTypes from 'prop-types';
import copy from 'copy-to-clipboard';
import { IconButton, FontSizes, TooltipHost } from '@fluentui/react';
import { TOOLTIP_BACKGROUND_COLOR } from '../../static/const';
const COPIED_TOOLTIP_CLOSE_DELAY = 1000;
const CopyButton = ({ value, hideTooltip }): any => {
const ref = useRef(null);
return (
<div>
<IconButton
iconProps={{ iconName: 'Copy' }}
styles={{ icon: [{ fontSize: FontSizes.small }] }}
onClick={(event: React.SyntheticEvent<EventTarget>): void => {
event.stopPropagation();
copy(value);
ref.current && (ref as any).current.show();
setTimeout(() => {
ref.current !== null && (ref as any).current.dismiss();
}, COPIED_TOOLTIP_CLOSE_DELAY);
}}
onMouseDown={(e): void => {
e.stopPropagation();
}}
onMouseUp={(e): void => {
e.stopPropagation();
}}
/>
<TooltipHost
hidden={hideTooltip}
content='Copied'
componentRef={ref}
delay={0}
tooltipProps={{
calloutProps: {
styles: {
beak: { background: TOOLTIP_BACKGROUND_COLOR },
beakCurtain: { background: TOOLTIP_BACKGROUND_COLOR },
calloutMain: { background: TOOLTIP_BACKGROUND_COLOR }
}
}
}}
/>
</div>
);
};
CopyButton.propTypes = {
value: PropTypes.string.isRequired,
hideTooltip: PropTypes.bool
};
export default CopyButton;
...@@ -32,6 +32,7 @@ import Customize from '../modals/CustomizedTrial'; ...@@ -32,6 +32,7 @@ import Customize from '../modals/CustomizedTrial';
import KillJob from '../modals/Killjob'; import KillJob from '../modals/Killjob';
import ExpandableDetails from '../public-child/ExpandableDetails'; import ExpandableDetails from '../public-child/ExpandableDetails';
import PaginationTable from '../public-child/PaginationTable'; import PaginationTable from '../public-child/PaginationTable';
import CopyButton from '../public-child/CopyButton';
import { Trial } from '../../static/model/trial'; import { Trial } from '../../static/model/trial';
require('echarts/lib/chart/line'); require('echarts/lib/chart/line');
...@@ -326,6 +327,14 @@ class TableList extends React.Component<TableListProps, TableListState> { ...@@ -326,6 +327,14 @@ class TableList extends React.Component<TableListProps, TableListState> {
onRender: (record): React.ReactNode => ( onRender: (record): React.ReactNode => (
<span className='durationsty'>{convertDuration(record[k])}</span> <span className='durationsty'>{convertDuration(record[k])}</span>
) )
}),
...(k === 'id' && {
onRender: (record): React.ReactNode => (
<Stack horizontal className='idCopy'>
<div>{record.id}</div>
<CopyButton value={record.id} />
</Stack>
)
}) })
}); });
} }
......
...@@ -25,3 +25,19 @@ ...@@ -25,3 +25,19 @@
cursor: pointer; cursor: pointer;
} }
} }
.idCopy {
.ms-Button--icon {
width: 18px;
height: 18px;
margin-left: 4px;
}
i {
color: #33333C;
}
}
.ms-DetailsRow {
height: 32px;
}
...@@ -30,4 +30,4 @@ $tableHeight: 432px; ...@@ -30,4 +30,4 @@ $tableHeight: 432px;
padding-left: 6px; padding-left: 6px;
box-sizing: border-box; box-sizing: border-box;
} }
} }
\ No newline at end of file
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