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

Multiple Experiments Management UX (#3127)



* first update

* add click event

* add manager exp nav

* first demo, fix some comments

* use api to dev

* refactor code

* fix lint

* fix test met issue and adjust column width

* add /experiments-info  error status

* no declare platform list, get this from api result filter

* fix compare tooltip issue

* fix tooltip location

* fix some comments

* delete datestring

* fix clickable style and clickable column ID rather than name
Co-authored-by: default avatarLijiao <Lijiaoa@outlook.com>
parent af198888
......@@ -4,27 +4,29 @@ import App from './App';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
const Overview = lazy(() => import('./components/Overview'));
const TrialsDetail = lazy(() => import('./components/TrialsDetail'));
const Experiment = lazy(() => import('./components/managementExp/ExperimentManager'));
import './index.css';
import './static/style/loading.scss';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
<Router>
<App>
<Suspense
fallback={
<div className='loading'>
<img src={require('./static/img/loading.gif')} />
</div>
}
>
<Route path='/experiment' component={Experiment} exact />
<Switch>
<Suspense
fallback={
<div className='loading'>
<img src={require('./static/img/loading.gif')} />
</div>
}
>
<App>
<Route path='/' component={Overview} exact />
<Route path='/oview' component={Overview} />
<Route path='/detail' component={TrialsDetail} />
</Suspense>
</App>
</Switch>
</App>
</Suspense>
</Router>,
document.getElementById('root')
......
......@@ -15,6 +15,16 @@ const trialJobStatus = [
'SYS_CANCELED',
'EARLY_STOPPED'
];
const EXPERIMENTSTATUS = [
'INITIALIZED',
'RUNNING',
'ERROR',
'STOPPING',
'STOPPED',
'DONE',
'NO_MORE_TRIAL',
'TUNER_NO_MORE_TRIAL'
];
const CONTROLTYPE = ['MAX_EXEC_DURATION', 'MAX_TRIAL_NUM', 'TRIAL_CONCURRENCY', 'SEARCH_SPACE'];
const MONACO = {
readOnly: true,
......@@ -64,6 +74,7 @@ export {
MANAGER_IP,
DOWNLOAD_IP,
trialJobStatus,
EXPERIMENTSTATUS,
COLUMNPro,
WEBUIDOC,
CONTROLTYPE,
......
......@@ -236,6 +236,14 @@ function formatTimestamp(timestamp?: number, placeholder?: string): string {
return timestamp ? new Date(timestamp).toLocaleString('en-US') : placeholder;
}
function expformatTimestamp(timestamp: number | string): string {
if (typeof timestamp === 'number') {
return new Date(timestamp).toLocaleString('en-US');
} else {
return 'N/A';
}
}
function metricAccuracy(metric: MetricDataRecord): number {
const data = parseMetrics(metric.data);
// return typeof data === 'number' ? data : NaN;
......@@ -262,6 +270,10 @@ function formatComplexTypeValue(value: any): string | number {
}
}
function isManagerExperimentPage(): boolean {
return location.pathname.indexOf('experiment') === -1 ? false : true;
}
function caclMonacoEditorHeight(height): number {
// [Search space 56px] + [marginBottom 18px] +
// button[height: 32px, marginTop: 45px, marginBottom: 7px]
......@@ -306,12 +318,14 @@ export {
filterDuration,
formatAccuracy,
formatTimestamp,
expformatTimestamp,
metricAccuracy,
parseMetrics,
isArrayType,
requestAxios,
isNaNorInfinity,
formatComplexTypeValue,
isManagerExperimentPage,
caclMonacoEditorHeight,
copyAndSort
};
......@@ -120,6 +120,7 @@ interface Intermedia {
type: string;
data: Array<number | object>; // intermediate data
hyperPara: object; // each trial hyperpara value
trialNum: number;
}
interface MetricDataRecord {
......@@ -218,6 +219,19 @@ interface SortInfo {
isDescend?: boolean;
}
interface AllExperimentList {
id: string;
experimentName: string;
port: number;
status: string;
platform: string;
startTime: number;
endTime: number;
tag: string[];
pid: number;
webuiUrl: string[];
logDir: string[];
}
export {
TableObj,
TableRecord,
......@@ -240,5 +254,6 @@ export {
EventMap,
SingleAxis,
MultipleAxes,
SortInfo
SortInfo,
AllExperimentList
};
import { MANAGER_IP } from '../const';
import { AllExperimentList } from '../interface';
import { requestAxios } from '../function';
class ExperimentsManager {
private experimentList: AllExperimentList[] = [];
private platform: string[] = [];
private errorMessage: string = '';
public getExperimentList(): AllExperimentList[] {
return this.experimentList;
}
public getPlatformList(): string[] {
return this.platform;
}
public getExpErrorMessage(): string {
return this.errorMessage;
}
public async init(): Promise<void> {
await requestAxios(`${MANAGER_IP}/experiments-info`)
.then(data => {
const platforms: Set<string> = new Set();
for (const item of data) {
if (item.port !== undefined) {
if (typeof item.port === 'string') {
item.port = JSON.parse(item.port);
}
}
platforms.add(item.platform);
}
this.experimentList = data;
this.platform = Array.from(platforms);
})
.catch(error => {
this.errorMessage = error.message;
});
}
}
export { ExperimentsManager };
.cursor{
&:hover, & i:hover{
cursor: pointer;
}
}
\ No newline at end of file
.ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.link {
outline: none;
color: #333 !important;
text-decoration: none;
&:hover {
color: #0071bc !important;
text-decoration: underline;
}
&:active,
&:visited {
color: #0071bc;
}
}
.cursor {
&:hover,
& i:hover {
cursor: pointer;
}
}
.expBackground {
background: #f2f2f2;
height: 100%;
.content {
background: #fff;
}
}
.experimentList {
padding: 42px;
.box {
.search {
width: 90%;
&-input {
width: 330px;
}
}
.filter {
width: 10%;
text-align: right;
&-button-open {
background: #f3f2f1;
}
}
}
.filter-condition {
margin-top: 26px;
.reset {
width: 80px;
position: relative;
top: 29px;
}
&-status {
width: 194px;
}
&-platform {
width: 150px;
}
}
.hidden {
display: none;
}
.margin {
margin-left: 10px;
}
.tagContainer {
width: 100%;
.tag {
font-weight: 500;
background: #f2f2f2;
margin: 0 4px;
padding: 0 6px;
}
}
}
$barHeight: 56px;
.navOptions {
.ms-Button-icon {
color: #fff;
&:hover {
color: #fff;
}
}
.ms-Button--commandBar {
background-color: #0071bc;
user-select: none;
&:hover,
&:active {
color: #fff;
.ms-Button-icon {
color: #fff;
}
}
.ms-Button-textContainer {
color: #fff;
}
.ms-Button-menuIcon {
color: #fff;
background-color: transparent;
}
}
.ms-Button-icon {
color: #fff;
&:hover {
color: #fff;
}
}
.ms-Button--commandBar {
background-color: #0071bc;
user-select: none;
&:hover,
&:active {
color: #fff;
.ms-Button-icon {
color: #fff;
}
}
.ms-Button-textContainer {
color: #fff;
}
.ms-Button-menuIcon {
color: #fff;
background-color: transparent;
}
}
.experiment {
position: relative;
top: 3px;
text-decoration: none;
}
}
.nav {
height: $barHeight;
line-height: $barHeight;
/* desktop mode useful */
.desktop-logo {
position: relative;
top: 6px;
}
&-refresh {
position: relative;
display: flex;
}
&-refresh-num {
position: absolute;
top: -13px;
left: 17px;
color: #fff;
font-size: 12px;
}
width: 100%;
min-width: 1200px;
height: $barHeight;
line-height: $barHeight;
/* desktop mode useful */
.desktop-logo {
position: relative;
top: 6px;
}
.logoTitle {
font-size: 18px;
color: #fff;
}
&-refresh {
position: relative;
display: flex;
}
&-refresh-num {
position: absolute;
top: -13px;
left: 17px;
color: #fff;
font-size: 12px;
}
}
/* overview and detail tabs common style */
a.common-tabs {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 16px;
color: #b8c7ce;
text-decoration: none;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 16px;
color: #b8c7ce;
text-decoration: none;
}
.common-tabs:visited,
.selected:hover {
color: #fff;
text-decoration: none;
color: #fff;
text-decoration: none;
}
.common-tabs:hover,
.selected {
color: #fff;
border-bottom: 1px solid #fff;
color: #fff;
border-bottom: 1px solid #fff;
}
.left-right-margin {
margin-left: 20px;
margin-right: 20px;
margin-left: 20px;
margin-right: 20px;
}
.expNavTitle {
span {
color: #fff;
text-decoration: none;
position: relative;
top: -4px;
}
i {
color: #fff;
font-size: 12px;
position: relative;
top: -3px;
padding-left: 4px;
}
}
.status {
color: #0573bc;
font-size: 20px;
font-weight: 600;
.status-text {
display: inline-block;
}
.color {
color: #333;
}
}
.inputBox {
height: 32px;
margin-top: 5px;
}
/* office-fabric-ui progressIndicator */
.ms-ProgressIndicator-itemProgress {
padding: 0;
}
......@@ -58,6 +58,7 @@ $margin: 24px;
.concurrency {
.editparam {
margin-top: 5px;
position: relative;
}
}
.editparam {
......@@ -124,5 +125,6 @@ $margin: 24px;
.info {
position: absolute;
z-index: 999;
left: 0;
left: -50%;
width: 270%;
}
......@@ -61,30 +61,24 @@ $boxGapPadding: 10px;
}
.basic {
line-height: 21px;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
p {
color: #8f8f8f;
font-size: 14px;
font-weight: normal;
span {
color: #484848;
}
}
div {
font-size: 16px;
font-weight: 500;
color: #484848;
}
.nowrap {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
line-height: 21px;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
p {
font-size: 14px;
color: #8f8f8f;
span {
color: #484848;
}
}
div {
font-size: 16px;
font-weight: 500;
color: #484848;
}
}
.overviewBestMetric {
......
.status {
color: #0573bc;
font-size: 20px;
font-weight: 600;
.status-text {
display: inline-block;
}
.color {
color: #333;
}
}
.probar {
width: 100%;
height: 34px;
margin-top: 15px;
.showProgress {
width: 300px;
height: 30px;
}
.name {
width: 178px;
box-sizing: border-box;
line-height: 30px;
text-align: center;
color: #fff;
background-color: #999;
border: 2px solid #e6e6e6;
border-top-left-radius: 12px;
border-bottom-left-radius: 12px;
}
.boundary {
width: 100%;
line-height: 24px;
font-size: 12px;
color: #212121;
.right {
text-align: right;
}
}
.description {
line-height: 34px;
margin-left: 6px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.inputBox {
height: 32px;
margin-top: 5px;
}
/* office-fabric-ui progressIndicator */
.ms-ProgressIndicator-itemProgress {
padding: 0;
}
......@@ -13,12 +13,6 @@
}
}
.ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
#succeTable,
#tableList {
.commonTableStyle .leftTitle div {
......
This diff is collapsed.
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