Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
OpenDAS
nni
Commits
3b90b9d9
Commit
3b90b9d9
authored
Oct 26, 2020
by
liuzhe
Browse files
Merge branch 'master' into v2.0-merge
parents
e21a6984
77dac12b
Changes
143
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
456 additions
and
287 deletions
+456
-287
ts/webui/src/components/overview/count/ExpDurationContext.tsx
...ebui/src/components/overview/count/ExpDurationContext.tsx
+4
-1
ts/webui/src/components/overview/count/TrialCount.tsx
ts/webui/src/components/overview/count/TrialCount.tsx
+56
-52
ts/webui/src/components/overview/count/commonStyle.ts
ts/webui/src/components/overview/count/commonStyle.ts
+16
-0
ts/webui/src/components/overview/experiment/BasicInfo.tsx
ts/webui/src/components/overview/experiment/BasicInfo.tsx
+47
-45
ts/webui/src/components/overview/overviewConst.ts
ts/webui/src/components/overview/overviewConst.ts
+7
-1
ts/webui/src/components/overview/table/SuccessTable.tsx
ts/webui/src/components/overview/table/SuccessTable.tsx
+24
-25
ts/webui/src/components/public-child/DefaultMetric.tsx
ts/webui/src/components/public-child/DefaultMetric.tsx
+1
-1
ts/webui/src/components/public-child/config/TrialConfigButton.tsx
.../src/components/public-child/config/TrialConfigButton.tsx
+1
-1
ts/webui/src/components/public-child/config/TrialConfigPanel.tsx
...i/src/components/public-child/config/TrialConfigPanel.tsx
+63
-43
ts/webui/src/components/trial-detail/TableList.tsx
ts/webui/src/components/trial-detail/TableList.tsx
+40
-13
ts/webui/src/index.tsx
ts/webui/src/index.tsx
+2
-2
ts/webui/src/static/const.ts
ts/webui/src/static/const.ts
+6
-1
ts/webui/src/static/function.ts
ts/webui/src/static/function.ts
+13
-22
ts/webui/src/static/interface.ts
ts/webui/src/static/interface.ts
+5
-1
ts/webui/src/static/style/overview/command.scss
ts/webui/src/static/style/overview/command.scss
+10
-26
ts/webui/src/static/style/overview/config.scss
ts/webui/src/static/style/overview/config.scss
+11
-5
ts/webui/src/static/style/overview/count.scss
ts/webui/src/static/style/overview/count.scss
+71
-11
ts/webui/src/static/style/overview/overview.scss
ts/webui/src/static/style/overview/overview.scss
+51
-21
ts/webui/src/static/style/overview/overviewTitle.scss
ts/webui/src/static/style/overview/overviewTitle.scss
+0
-10
ts/webui/src/static/style/progress/probar.scss
ts/webui/src/static/style/progress/probar.scss
+28
-6
No files found.
ts/webui/src/components/overview/count/ExpDurationContext.tsx
View file @
3b90b9d9
...
...
@@ -3,5 +3,8 @@ export const ExpDurationContext = React.createContext({
maxExecDuration
:
0
,
execDuration
:
0
,
// eslint-disable-next-line @typescript-eslint/no-empty-function
updateOverviewPage
:
():
void
=>
{}
updateOverviewPage
:
():
void
=>
{},
maxDurationUnit
:
'
m
'
,
// eslint-disable-next-line @typescript-eslint/no-empty-function
changeMaxDurationUnit
:
(
_val
:
'
d
'
|
'
h
'
|
'
m
'
):
void
=>
{}
});
ts/webui/src/components/overview/count/TrialCount.tsx
View file @
3b90b9d9
import
*
as
React
from
'
react
'
;
import
{
Stack
,
TooltipHost
,
ProgressIndicator
}
from
'
@fluentui/react
'
;
import
{
Stack
,
TooltipHost
,
ProgressIndicator
,
DirectionalHint
}
from
'
@fluentui/react
'
;
import
{
EXPERIMENT
,
TRIALS
}
from
'
../../../static/datamodel
'
;
import
{
CONTROLTYPE
}
from
'
../../../static/const
'
;
import
{
CONTROLTYPE
,
TOOLTIP_BACKGROUND_COLOR
,
MAX_TRIAL_NUMBERS
}
from
'
../../../static/const
'
;
import
{
EditExperimentParam
}
from
'
./EditExperimentParam
'
;
import
{
EditExpeParamContext
}
from
'
./context
'
;
import
{
ExpDurationContext
}
from
'
./ExpDurationContext
'
;
const
itemStyles
:
React
.
CSSProperties
=
{
width
:
'
62%
'
};
const
itemStyle2
:
React
.
CSSProperties
=
{
width
:
'
63%
'
,
textAlign
:
'
right
'
};
const
itemStyle1
:
React
.
CSSProperties
=
{
width
:
'
30%
'
,
height
:
50
};
const
itemRunning
:
React
.
CSSProperties
=
{
width
:
'
42%
'
,
height
:
56
};
import
{
trialCountItem1
,
trialCountItem2
}
from
'
./commonStyle
'
;
export
const
TrialCount
=
():
any
=>
{
const
count
=
TRIALS
.
countStatus
();
...
...
@@ -30,8 +13,9 @@ export const TrialCount = (): any => {
const
stoppedCount
=
count
.
get
(
'
USER_CANCELED
'
)
!
+
count
.
get
(
'
SYS_CANCELED
'
)
!
+
count
.
get
(
'
EARLY_STOPPED
'
)
!
;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const
bar2
=
count
.
get
(
'
RUNNING
'
)
!
+
count
.
get
(
'
SUCCEEDED
'
)
!
+
count
.
get
(
'
FAILED
'
)
!
+
stoppedCount
;
const
maxTrialNum
=
EXPERIMENT
.
profile
.
params
.
maxTrialNum
;
// support type [0, 1], not 98%
const
bar2Percent
=
bar2
/
EXPERIMENT
.
profile
.
params
.
maxTrialNum
;
const
bar2Percent
=
bar2
/
maxTrialNum
;
return
(
<
ExpDurationContext
.
Consumer
>
{
(
value
):
React
.
ReactNode
=>
{
...
...
@@ -39,40 +23,36 @@ export const TrialCount = (): any => {
return
(
<
React
.
Fragment
>
<
Stack
horizontal
horizontalAlign
=
'space-between'
className
=
'ExpDuration'
>
<
div
style
=
{
itemStyles
}
>
<
TooltipHost
content
=
{
bar2
.
toString
()
}
>
<
ProgressIndicator
percentComplete
=
{
bar2Percent
}
barHeight
=
{
15
}
/>
<
div
style
=
{
trialCountItem1
}
>
<
TooltipHost
content
=
{
bar2
.
toString
()
}
directionalHint
=
{
DirectionalHint
.
bottomCenter
}
tooltipProps
=
{
{
calloutProps
:
{
styles
:
{
beak
:
{
background
:
TOOLTIP_BACKGROUND_COLOR
},
beakCurtain
:
{
background
:
TOOLTIP_BACKGROUND_COLOR
},
calloutMain
:
{
background
:
TOOLTIP_BACKGROUND_COLOR
}
}
}
}
}
>
<
ProgressIndicator
className
=
{
EXPERIMENT
.
status
}
percentComplete
=
{
bar2Percent
}
barHeight
=
{
15
}
/>
</
TooltipHost
>
<
Stack
horizontal
className
=
'mess'
>
<
div
style
=
{
itemRunning
}
className
=
'basic'
>
<
p
>
Running
</
p
>
<
div
>
{
count
.
get
(
'
RUNNING
'
)
}
</
div
>
</
div
>
<
div
style
=
{
itemStyle1
}
className
=
'basic'
>
<
p
>
Failed
</
p
>
<
div
>
{
count
.
get
(
'
FAILED
'
)
}
</
div
>
</
div
>
<
div
style
=
{
itemStyle1
}
className
=
'basic'
>
<
p
>
Stopped
</
p
>
<
div
>
{
stoppedCount
}
</
div
>
</
div
>
</
Stack
>
<
Stack
horizontal
horizontalAlign
=
'space-between'
className
=
'mess'
>
<
div
style
=
{
itemStyle1
}
className
=
'basic'
>
<
p
>
Succeeded
</
p
>
<
div
>
{
count
.
get
(
'
SUCCEEDED
'
)
}
</
div
>
</
div
>
<
div
style
=
{
itemStyle1
}
className
=
'basic'
>
<
p
>
Waiting
</
p
>
<
div
>
{
count
.
get
(
'
WAITING
'
)
}
</
div
>
</
div
>
</
Stack
>
<
div
className
=
'exp-progress'
>
<
span
className
=
{
`
${
EXPERIMENT
.
status
}
bold`
}
>
{
bar2
}
</
span
>
<
span
className
=
'joiner'
>
/
</
span
>
<
span
>
{
maxTrialNum
}
</
span
>
</
div
>
</
div
>
<
div
style
=
{
itemStyle
2
}
>
<
div
style
=
{
trialCountItem
2
}
>
<
EditExpeParamContext
.
Provider
value
=
{
{
title
:
'
Max trial numbers
'
,
title
:
MAX_TRIAL_NUMBERS
,
field
:
'
maxTrialNum
'
,
editType
:
CONTROLTYPE
[
1
],
maxExecDuration
:
''
,
...
...
@@ -81,7 +61,9 @@ export const TrialCount = (): any => {
updateOverviewPage
}
}
>
<
EditExperimentParam
/>
<
div
className
=
'maxTrialNum'
>
<
EditExperimentParam
/>
</
div
>
</
EditExpeParamContext
.
Provider
>
<
EditExpeParamContext
.
Provider
value
=
{
{
...
...
@@ -99,6 +81,28 @@ export const TrialCount = (): any => {
</
EditExpeParamContext
.
Provider
>
</
div
>
</
Stack
>
<
Stack
horizontal
horizontalAlign
=
'space-between'
className
=
'mess'
>
<
div
className
=
'basic'
>
<
p
>
Running
</
p
>
<
div
>
{
count
.
get
(
'
RUNNING
'
)
}
</
div
>
</
div
>
<
div
className
=
'basic'
>
<
p
>
Succeeded
</
p
>
<
div
>
{
count
.
get
(
'
SUCCEEDED
'
)
}
</
div
>
</
div
>
<
div
className
=
'basic'
>
<
p
>
Stopped
</
p
>
<
div
>
{
stoppedCount
}
</
div
>
</
div
>
<
div
className
=
'basic'
>
<
p
>
Failed
</
p
>
<
div
>
{
count
.
get
(
'
FAILED
'
)
}
</
div
>
</
div
>
<
div
className
=
'basic'
>
<
p
>
Waiting
</
p
>
<
div
>
{
count
.
get
(
'
WAITING
'
)
}
</
div
>
</
div
>
</
Stack
>
</
React
.
Fragment
>
);
}
}
...
...
ts/webui/src/components/overview/count/commonStyle.ts
0 → 100644
View file @
3b90b9d9
const
durationItem1
:
React
.
CSSProperties
=
{
width
:
'
33%
'
};
const
durationItem2
:
React
.
CSSProperties
=
{
width
:
'
52%
'
,
paddingLeft
:
'
15%
'
};
const
trialCountItem1
:
React
.
CSSProperties
=
{
width
:
'
33%
'
};
const
trialCountItem2
:
React
.
CSSProperties
=
{
width
:
'
52%
'
};
export
{
durationItem1
,
durationItem2
,
trialCountItem1
,
trialCountItem2
};
ts/webui/src/components/overview/experiment/BasicInfo.tsx
View file @
3b90b9d9
...
...
@@ -24,61 +24,63 @@ export const ReBasicInfo = (): any => {
return
(
<
div
>
<
div
className
=
'basic'
>
<
p
>
ID:
{
EXPERIMENT
.
profile
.
id
}
</
p
>
<
p
>
ID:
<
span
>
{
EXPERIMENT
.
profile
.
id
}
</
span
>
</
p
>
<
div
>
{
EXPERIMENT
.
profile
.
params
.
experimentName
}
</
div
>
</
div
>
<
div
className
=
'basic'
>
<
Stack
className
=
'basic'
>
<
p
>
Status
</
p
>
<
Stack
horizontal
className
=
'status'
>
<
span
className
=
{
`
${
EXPERIMENT
.
status
}
status-text`
}
>
{
EXPERIMENT
.
status
}
</
span
>
{
EXPERIMENT
.
status
===
'
ERROR
'
?
(
<
div
>
<
div
className
=
{
styles
.
buttonArea
}
ref
=
{
ref
}
>
<
IconButton
iconProps
=
{
{
iconName
:
'
info
'
}
}
onClick
=
{
isCalloutVisible
?
onDismiss
:
showCallout
}
/>
</
div
>
{
isCalloutVisible
&&
(
<
Callout
className
=
{
styles
.
callout
}
ariaLabelledBy
=
{
labelId
}
ariaDescribedBy
=
{
descriptionId
}
role
=
'alertdialog'
gapSpace
=
{
0
}
target
=
{
ref
}
onDismiss
=
{
onDismiss
}
setInitialFocus
=
{
true
}
>
<
div
className
=
{
styles
.
header
}
>
<
p
className
=
{
styles
.
title
}
id
=
{
labelId
}
>
Error
</
p
>
</
div
>
<
div
className
=
{
styles
.
inner
}
>
<
p
className
=
{
styles
.
subtext
}
id
=
{
descriptionId
}
>
{
EXPERIMENT
.
error
}
</
p
>
<
div
className
=
{
styles
.
actions
}
>
<
Link
className
=
{
styles
.
link
}
onClick
=
{
ShowLogDrawer
}
>
Learn about
</
Link
>
</
div
>
</
div
>
</
Callout
>
)
}
<
p
>
Status
</
p
>
<
Stack
horizontal
className
=
'status'
>
<
span
className
=
{
`
${
EXPERIMENT
.
status
}
status-text`
}
>
{
EXPERIMENT
.
status
}
</
span
>
{
EXPERIMENT
.
status
===
'
ERROR
'
?
(
<
div
>
<
div
className
=
{
styles
.
buttonArea
}
ref
=
{
ref
}
>
<
IconButton
iconProps
=
{
{
iconName
:
'
info
'
}
}
onClick
=
{
isCalloutVisible
?
onDismiss
:
showCallout
}
/>
</
div
>
)
:
null
}
</
Stack
>
{
isCalloutVisible
&&
(
<
Callout
className
=
{
styles
.
callout
}
ariaLabelledBy
=
{
labelId
}
ariaDescribedBy
=
{
descriptionId
}
role
=
'alertdialog'
gapSpace
=
{
0
}
target
=
{
ref
}
onDismiss
=
{
onDismiss
}
setInitialFocus
=
{
true
}
>
<
div
className
=
{
styles
.
header
}
>
<
p
className
=
{
styles
.
title
}
id
=
{
labelId
}
style
=
{
{
color
:
'
#333
'
}
}
>
Error
</
p
>
</
div
>
<
div
className
=
{
styles
.
inner
}
>
<
p
className
=
{
styles
.
subtext
}
id
=
{
descriptionId
}
style
=
{
{
color
:
'
#333
'
}
}
>
{
EXPERIMENT
.
error
}
</
p
>
<
div
className
=
{
styles
.
actions
}
>
<
Link
className
=
{
styles
.
link
}
onClick
=
{
ShowLogDrawer
}
>
Learn about
</
Link
>
</
div
>
</
div
>
</
Callout
>
)
}
</
div
>
)
:
null
}
</
Stack
>
</
div
>
<
div
className
=
'basic'
>
<
BestMetricContext
.
Consumer
>
{
(
value
):
React
.
ReactNode
=>
(
<
Stack
>
<
Stack
className
=
'bestMetric'
>
<
p
>
Best metric
</
p
>
<
div
>
{
isNaN
(
value
.
bestAccuracy
)
?
'
N/A
'
:
value
.
bestAccuracy
.
toFixed
(
6
)
}
</
div
>
<
div
className
=
{
EXPERIMENT
.
status
}
>
{
isNaN
(
value
.
bestAccuracy
)
?
'
N/A
'
:
value
.
bestAccuracy
.
toFixed
(
6
)
}
</
div
>
</
Stack
>
)
}
</
BestMetricContext
.
Consumer
>
...
...
ts/webui/src/components/overview/overviewConst.ts
View file @
3b90b9d9
...
...
@@ -18,4 +18,10 @@ const entriesOption = [
{
key
:
'
100
'
,
text
:
'
100
'
}
];
export
{
itemStyle1
,
itemStyleSucceed
,
itemStyle2
,
entriesOption
};
const
durationUnit
=
[
{
key
:
'
m
'
,
text
:
'
min
'
},
{
key
:
'
h
'
,
text
:
'
hour
'
},
{
key
:
'
d
'
,
text
:
'
day
'
}
];
export
{
itemStyle1
,
itemStyleSucceed
,
itemStyle2
,
entriesOption
,
durationUnit
};
ts/webui/src/components/overview/table/SuccessTable.tsx
View file @
3b90b9d9
...
...
@@ -63,12 +63,10 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
}
tooltipStr
=
(
<
div
>
<
p
>
The experiment is running, please wait for the final metric patiently.
</
p
>
<
div
className
=
'link'
>
You could also find status of trial job with
<
span
>
{
DETAILTABS
}
</
span
>
button.
</
div
>
</
div
>
<
React
.
Fragment
>
The experiment is running, please wait for the final metric patiently. You could also find status of trial
job with
<
span
>
{
DETAILTABS
}
</
span
>
button.
</
React
.
Fragment
>
);
columns
=
[
...
...
@@ -76,34 +74,36 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
name
:
'
Trial No.
'
,
key
:
'
sequenceId
'
,
fieldName
:
'
sequenceId
'
,
// required!
minWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
maxWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
minWidth
:
5
0
,
maxWidth
:
87
,
isResizable
:
true
,
data
:
'
number
'
,
onColumnClick
:
this
.
onColumnClick
onColumnClick
:
this
.
onColumnClick
,
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
<
div
className
=
'succeed-padding'
>
{
item
.
sequenceId
}
</
div
>
},
{
name
:
'
ID
'
,
key
:
'
id
'
,
fieldName
:
'
id
'
,
minWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
maxWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
minWidth
:
5
0
,
maxWidth
:
87
,
isResizable
:
true
,
className
:
'
tableHead leftTitle
'
,
data
:
'
string
'
,
onColumnClick
:
this
.
onColumnClick
onColumnClick
:
this
.
onColumnClick
,
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
<
div
className
=
'succeed-padding'
>
{
item
.
id
}
</
div
>
},
{
name
:
'
Duration
'
,
key
:
'
duration
'
,
minWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
maxWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
minWidth
:
6
5
,
maxWidth
:
150
,
isResizable
:
true
,
fieldName
:
'
duration
'
,
data
:
'
number
'
,
onColumnClick
:
this
.
onColumnClick
,
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
(
<
div
className
=
'durationsty'
>
<
div
className
=
'durationsty
succeed-padding
'
>
<
div
>
{
convertDuration
(
item
.
duration
)
}
</
div
>
</
div
>
)
...
...
@@ -111,26 +111,24 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
{
name
:
'
Status
'
,
key
:
'
status
'
,
minWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
maxWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
minWidth
:
80
,
maxWidth
:
150
,
isResizable
:
true
,
fieldName
:
'
status
'
,
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
{
return
<
div
className
=
{
`
${
item
.
status
}
commonStyle`
}
>
{
item
.
status
}
</
div
>
;
}
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
(
<
div
className
=
{
`
${
item
.
status
}
commonStyle
succeed-padding
`
}
>
{
item
.
status
}
</
div
>
)
},
{
name
:
'
Default metric
'
,
key
:
'
accuracy
'
,
fieldName
:
'
accuracy
'
,
minWidth
:
(
window
.
innerWidth
*
0.333
-
200
)
/
5
,
//
maxWidth:
(window.innerWidth * 0.333 - 150) / 5
,
minWidth
:
100
,
maxWidth
:
160
,
isResizable
:
true
,
data
:
'
number
'
,
onColumnClick
:
this
.
onColumnClick
,
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
{
return
<
DefaultMetric
trialId
=
{
item
.
id
}
/>;
}
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
<
DefaultMetric
trialId
=
{
item
.
id
}
/>
}
];
...
...
@@ -155,6 +153,7 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
render
():
React
.
ReactNode
{
const
{
columns
,
source
}
=
this
.
state
;
const
isNoneData
=
source
.
length
===
0
?
true
:
false
;
return
(
<
div
id
=
'succTable'
>
<
DetailsList
...
...
ts/webui/src/components/public-child/DefaultMetric.tsx
View file @
3b90b9d9
...
...
@@ -13,7 +13,7 @@ class DefaultMetric extends React.Component<DefaultMetricProps, {}> {
render
():
React
.
ReactNode
{
const
accuracy
=
TRIALS
.
getTrial
(
this
.
props
.
trialId
).
accuracy
;
return
<
div
>
{
accuracy
!==
undefined
?
formatAccuracy
(
accuracy
)
:
'
--
'
}
</
div
>;
return
<
div
className
=
'succeed-padding'
>
{
accuracy
!==
undefined
?
formatAccuracy
(
accuracy
)
:
'
--
'
}
</
div
>;
}
}
...
...
ts/webui/src/components/public-child/config/TrialConfigButton.tsx
View file @
3b90b9d9
...
...
@@ -18,8 +18,8 @@ export const TrialConfigButton = (): any => {
return
(
<
React
.
Fragment
>
<
Stack
className
=
'config'
>
<
DefaultButton
text
=
'Config'
onClick
=
{
showTrialConfigpPanel
}
/>
<
DefaultButton
text
=
'Search space'
onClick
=
{
showSearchSpacePanel
}
/>
<
DefaultButton
text
=
'Config'
onClick
=
{
showTrialConfigpPanel
}
/>
</
Stack
>
{
isShowConfigPanel
&&
<
TrialConfigPanel
hideConfigPanel
=
{
hideConfigPanel
}
activeTab
=
{
activeTab
}
/>
}
</
React
.
Fragment
>
...
...
ts/webui/src/components/public-child/config/TrialConfigPanel.tsx
View file @
3b90b9d9
...
...
@@ -3,7 +3,8 @@ import { Stack, Panel, Pivot, PivotItem, PrimaryButton } from '@fluentui/react';
import
{
EXPERIMENT
}
from
'
../../../static/datamodel
'
;
import
MonacoEditor
from
'
react-monaco-editor
'
;
import
{
MONACO
}
from
'
../../../static/const
'
;
import
{
convertDuration
}
from
'
../../../static/function
'
;
import
{
AppContext
}
from
'
../../../App
'
;
import
{
convertDuration
,
convertTimeAsUnit
}
from
'
../../../static/function
'
;
import
{
prettyStringify
}
from
'
../../../static/json_util
'
;
import
lodash
from
'
lodash
'
;
import
'
../../../static/style/logDrawer.scss
'
;
...
...
@@ -15,6 +16,7 @@ interface LogDrawerProps {
interface
LogDrawerState
{
panelInnerHeight
:
number
;
innerWidth
:
number
;
}
class
TrialConfigPanel
extends
React
.
Component
<
LogDrawerProps
,
LogDrawerState
>
{
...
...
@@ -22,13 +24,15 @@ class TrialConfigPanel extends React.Component<LogDrawerProps, LogDrawerState> {
super
(
props
);
this
.
state
=
{
panelInnerHeight
:
window
.
innerHeight
panelInnerHeight
:
window
.
innerHeight
,
innerWidth
:
window
.
innerWidth
};
}
setLogDrawerHeight
():
void
{
this
.
setState
(()
=>
({
panelInnerHeight
:
window
.
innerHeight
}));
}
// use arrow function for change window size met error: this.setState is not a function
setLogDrawerHeight
=
():
void
=>
{
this
.
setState
(()
=>
({
panelInnerHeight
:
window
.
innerHeight
,
innerWidth
:
window
.
innerWidth
}));
};
async
componentDidMount
():
Promise
<
void
>
{
window
.
addEventListener
(
'
resize
'
,
this
.
setLogDrawerHeight
);
...
...
@@ -40,7 +44,7 @@ class TrialConfigPanel extends React.Component<LogDrawerProps, LogDrawerState> {
render
():
React
.
ReactNode
{
const
{
hideConfigPanel
,
activeTab
}
=
this
.
props
;
const
{
panelInnerHeight
}
=
this
.
state
;
const
{
panelInnerHeight
,
innerWidth
}
=
this
.
state
;
// [marginTop 16px] + [Search space 46px] +
// button[height: 32px, marginTop: 45px, marginBottom: 25px] + [padding-bottom: 20px]
const
monacoEditorHeight
=
panelInnerHeight
-
184
;
...
...
@@ -58,45 +62,61 @@ class TrialConfigPanel extends React.Component<LogDrawerProps, LogDrawerState> {
};
const
profile
=
lodash
.
cloneDeep
(
EXPERIMENT
.
profile
);
profile
.
execDuration
=
convertDuration
(
profile
.
execDuration
);
profile
.
params
.
maxExecDuration
=
convertDuration
(
profile
.
params
.
maxExecDuration
);
const
showProfile
=
JSON
.
stringify
(
profile
,
filter
,
2
);
const
prettyWidth
=
innerWidth
>
1400
?
100
:
60
;
return
(
<
Stack
>
<
Panel
isOpen
=
{
true
}
hasCloseButton
=
{
false
}
isFooterAtBottom
=
{
true
}
isLightDismiss
=
{
true
}
onLightDismissClick
=
{
hideConfigPanel
}
>
<
div
className
=
'log-tab-body'
>
<
Pivot
initialSelectedKey
=
{
activeTab
}
style
=
{
{
minHeight
:
190
,
paddingTop
:
'
16px
'
}
}
>
<
PivotItem
headerText
=
'Search space'
itemKey
=
'search space'
>
<
MonacoEditor
height
=
{
monacoEditorHeight
}
language
=
'json'
theme
=
'vs-light'
value
=
{
prettyStringify
(
EXPERIMENT
.
searchSpace
,
300
,
2
)
}
options
=
{
MONACO
}
/>
</
PivotItem
>
<
PivotItem
headerText
=
'Config'
itemKey
=
'config'
>
<
div
className
=
'profile'
>
<
MonacoEditor
width
=
'100%'
height
=
{
monacoEditorHeight
}
language
=
'json'
theme
=
'vs-light'
value
=
{
showProfile
}
options
=
{
MONACO
}
/>
<
AppContext
.
Consumer
>
{
(
value
):
React
.
ReactNode
=>
{
const
unit
=
value
.
maxDurationUnit
;
profile
.
params
.
maxExecDuration
=
`
${
convertTimeAsUnit
(
unit
,
profile
.
params
.
maxExecDuration
)}${
unit
}
`
;
const
showProfile
=
JSON
.
stringify
(
profile
,
filter
,
2
);
return
(
<
Stack
>
<
Panel
isOpen
=
{
true
}
hasCloseButton
=
{
false
}
isFooterAtBottom
=
{
true
}
isLightDismiss
=
{
true
}
onLightDismissClick
=
{
hideConfigPanel
}
>
<
div
className
=
'log-tab-body'
>
<
Pivot
initialSelectedKey
=
{
activeTab
}
style
=
{
{
minHeight
:
190
,
paddingTop
:
'
16px
'
}
}
>
<
PivotItem
headerText
=
'Search space'
itemKey
=
'search space'
>
<
MonacoEditor
height
=
{
monacoEditorHeight
}
language
=
'json'
theme
=
'vs-light'
value
=
{
prettyStringify
(
EXPERIMENT
.
searchSpace
,
prettyWidth
,
2
)
}
options
=
{
MONACO
}
/>
</
PivotItem
>
<
PivotItem
headerText
=
'Config'
itemKey
=
'config'
>
<
div
className
=
'profile'
>
<
MonacoEditor
width
=
'100%'
height
=
{
monacoEditorHeight
}
language
=
'json'
theme
=
'vs-light'
value
=
{
showProfile
}
options
=
{
MONACO
}
/>
</
div
>
</
PivotItem
>
</
Pivot
>
</
div
>
</
PivotItem
>
</
Pivot
>
</
div
>
<
PrimaryButton
text
=
'Close'
className
=
'configClose'
onClick
=
{
hideConfigPanel
}
/>
</
Panel
>
</
Stack
>
<
PrimaryButton
text
=
'Close'
className
=
'configClose'
onClick
=
{
hideConfigPanel
}
/
>
</
Panel
>
</
Stack
>
);
}
}
</
AppContext
.
Consumer
>
);
}
}
...
...
ts/webui/src/components/trial-detail/TableList.tsx
View file @
3b90b9d9
...
...
@@ -9,10 +9,12 @@ import {
SelectionMode
,
Stack
,
StackItem
,
TooltipHost
TooltipHost
,
DirectionalHint
}
from
'
@fluentui/react
'
;
import
React
from
'
react
'
;
import
{
EXPERIMENT
,
TRIALS
}
from
'
../../static/datamodel
'
;
import
{
TOOLTIP_BACKGROUND_COLOR
}
from
'
../../static/const
'
;
import
{
convertDuration
,
formatTimestamp
}
from
'
../../static/function
'
;
import
{
TableObj
}
from
'
../../static/interface
'
;
import
'
../../static/style/search.scss
'
;
...
...
@@ -26,6 +28,7 @@ import '../../static/style/pagination.scss';
import
'
../../static/style/search.scss
'
;
import
'
../../static/style/table.scss
'
;
import
'
../../static/style/tableStatus.css
'
;
import
'
../../static/style/overview/overviewTitle.scss
'
;
import
{
blocked
,
copy
,
LineChart
,
tableListIcon
}
from
'
../buttons/Icon
'
;
import
ChangeColumnComponent
from
'
../modals/ChangeColumnComponent
'
;
import
Compare
from
'
../modals/Compare
'
;
...
...
@@ -247,7 +250,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
{
key
:
'
_expand
'
,
name
:
''
,
onRender
:
(
item
,
index
):
any
=>
{
onRender
:
(
item
):
any
=>
{
return
(
<
Icon
aria
-
hidden
=
{
true
}
...
...
@@ -267,8 +270,9 @@ class TableList extends React.Component<TableListProps, TableListState> {
}
else
{
this
.
_expandedTrialIds
.
delete
(
newItem
.
id
);
}
const
newItems
=
[...
this
.
state
.
displayedItems
];
newItems
[
index
as
number
]
=
newItem
;
const
newItems
=
this
.
state
.
displayedItems
.
map
(
item
=>
item
.
id
===
newItem
.
id
?
newItem
:
item
);
this
.
setState
({
displayedItems
:
newItems
});
...
...
@@ -294,17 +298,16 @@ class TableList extends React.Component<TableListProps, TableListState> {
// FIXME: default metric is hacked as latestAccuracy currently
continue
;
}
const
lengths
=
tableItems
.
map
(
item
=>
`
${
item
[
k
]}
`
.
length
);
const
avgLengths
=
lengths
.
reduce
((
a
,
b
)
=>
a
+
b
)
/
lengths
.
length
;
const
columnTitle
=
_inferColumnTitle
(
k
);
const
columnWidth
=
Math
.
max
(
columnTitle
.
length
,
avgLengths
);
// TODO: add blacklist
// 0.85: tableWidth / screen
const
widths
=
window
.
innerWidth
*
0.85
;
columns
.
push
({
name
:
columnTitle
,
key
:
k
,
fieldName
:
k
,
minWidth
:
columnW
idth
*
13
,
maxWidth
:
columnW
idth
*
18
,
minWidth
:
w
idth
s
*
0.12
,
maxWidth
:
w
idth
s
*
0.19
,
isResizable
:
true
,
onColumnClick
:
this
.
_onColumnClick
.
bind
(
this
),
...(
k
===
'
status
'
&&
{
...
...
@@ -316,7 +319,19 @@ class TableList extends React.Component<TableListProps, TableListState> {
...((
k
.
startsWith
(
'
metric/
'
)
||
k
.
startsWith
(
'
space/
'
))
&&
{
// show tooltip
onRender
:
(
record
):
React
.
ReactNode
=>
(
<
TooltipHost
content
=
{
record
[
k
]
}
>
<
TooltipHost
content
=
{
record
[
k
]
}
directionalHint
=
{
DirectionalHint
.
bottomCenter
}
tooltipProps
=
{
{
calloutProps
:
{
styles
:
{
beak
:
{
background
:
TOOLTIP_BACKGROUND_COLOR
},
beakCurtain
:
{
background
:
TOOLTIP_BACKGROUND_COLOR
},
calloutMain
:
{
background
:
TOOLTIP_BACKGROUND_COLOR
}
}
}
}
}
>
<
div
className
=
'ellipsis'
>
{
record
[
k
]
}
</
div
>
</
TooltipHost
>
)
...
...
@@ -324,7 +339,19 @@ class TableList extends React.Component<TableListProps, TableListState> {
...(
k
===
'
latestAccuracy
'
&&
{
// FIXME: this is ad-hoc
onRender
:
(
record
):
React
.
ReactNode
=>
(
<
TooltipHost
content
=
{
record
.
_formattedLatestAccuracy
}
>
<
TooltipHost
content
=
{
record
.
_formattedLatestAccuracy
}
directionalHint
=
{
DirectionalHint
.
bottomCenter
}
tooltipProps
=
{
{
calloutProps
:
{
styles
:
{
beak
:
{
background
:
TOOLTIP_BACKGROUND_COLOR
},
beakCurtain
:
{
background
:
TOOLTIP_BACKGROUND_COLOR
},
calloutMain
:
{
background
:
TOOLTIP_BACKGROUND_COLOR
}
}
}
}
}
>
<
div
className
=
'ellipsis'
>
{
record
.
_formattedLatestAccuracy
}
</
div
>
</
TooltipHost
>
)
...
...
@@ -344,8 +371,8 @@ class TableList extends React.Component<TableListProps, TableListState> {
name
:
'
Operation
'
,
key
:
'
_operation
'
,
fieldName
:
'
operation
'
,
minWidth
:
1
6
0
,
maxWidth
:
20
0
,
minWidth
:
1
5
0
,
maxWidth
:
16
0
,
isResizable
:
true
,
className
:
'
detail-table
'
,
onRender
:
this
.
_renderOperationColumn
.
bind
(
this
)
...
...
ts/webui/src/index.tsx
View file @
3b90b9d9
import
React
,
{
lazy
,
Suspense
}
from
'
react
'
;
import
ReactDOM
from
'
react-dom
'
;
import
App
from
'
./App
'
;
import
{
BrowserRouter
as
Router
,
Route
,
Switch
,
Redirect
}
from
'
react-router-dom
'
;
import
{
BrowserRouter
as
Router
,
Route
,
Switch
}
from
'
react-router-dom
'
;
const
Overview
=
lazy
(()
=>
import
(
'
./components/Overview
'
));
const
TrialsDetail
=
lazy
(()
=>
import
(
'
./components/TrialsDetail
'
));
import
'
./index.css
'
;
...
...
@@ -19,9 +19,9 @@ ReactDOM.render(
</
div
>
}
>
<
Route
path
=
'/'
component
=
{
Overview
}
exact
/>
<
Route
path
=
'/oview'
component
=
{
Overview
}
/>
<
Route
path
=
'/detail'
component
=
{
TrialsDetail
}
/>
<
Route
path
=
'/'
render
=
{
():
React
.
ReactNode
=>
<
Redirect
to
=
{
{
pathname
:
'
/oview
'
}
}
/>
}
/>
</
Suspense
>
</
Switch
>
</
App
>
...
...
ts/webui/src/static/const.ts
View file @
3b90b9d9
...
...
@@ -57,6 +57,9 @@ const SUPPORTED_SEARCH_SPACE_TYPE = [
'
qlognormal
'
];
const
TOOLTIP_BACKGROUND_COLOR
=
'
#484848
'
;
const
MAX_TRIAL_NUMBERS
=
'
Max trial No.
'
;
export
{
MANAGER_IP
,
DOWNLOAD_IP
,
...
...
@@ -71,5 +74,7 @@ export {
METRIC_GROUP_UPDATE_THRESHOLD
,
METRIC_GROUP_UPDATE_SIZE
,
CONCURRENCYTOOLTIP
,
SUPPORTED_SEARCH_SPACE_TYPE
SUPPORTED_SEARCH_SPACE_TYPE
,
TOOLTIP_BACKGROUND_COLOR
,
MAX_TRIAL_NUMBERS
};
ts/webui/src/static/function.ts
View file @
3b90b9d9
...
...
@@ -29,27 +29,6 @@ const convertTime = (num: number): string => {
}
};
const
convertTimeToSecond
=
(
str
:
string
):
number
=>
{
let
seconds
=
0
;
let
d
,
h
,
m
;
if
(
str
.
includes
(
'
d
'
))
{
[
d
,
str
]
=
str
.
split
(
'
d
'
);
seconds
+=
parseInt
(
d
)
*
24
*
3600
;
}
if
(
str
.
includes
(
'
h
'
))
{
[
h
,
str
]
=
str
.
split
(
'
h
'
);
seconds
+=
parseInt
(
h
)
*
3600
;
}
if
(
str
.
includes
(
'
m
'
))
{
[
m
,
str
]
=
str
.
split
(
'
m
'
);
seconds
+=
parseInt
(
m
)
*
60
;
}
if
(
str
)
{
seconds
+=
parseInt
(
str
.
split
(
'
s
'
)[
0
]);
}
return
seconds
;
};
// trial's duration, accurate to seconds for example 10min 30s
const
convertDuration
=
(
seconds
:
number
):
string
=>
{
let
str
=
''
;
...
...
@@ -78,6 +57,18 @@ const convertDuration = (seconds: number): string => {
return
str
?
str
:
'
0s
'
;
};
// according the unit(d,h,m) to convert duration
function
convertTimeAsUnit
(
unit
:
string
,
value
:
number
):
number
{
let
divisor
=
1
;
if
(
unit
===
'
h
'
)
{
divisor
=
3600
;
}
else
if
(
unit
===
'
m
'
)
{
divisor
=
60
;
}
else
{
divisor
=
24
*
3600
;
}
return
value
/
divisor
;
}
function
parseMetrics
(
metricData
:
string
):
any
{
if
(
metricData
.
includes
(
'
NaN
'
)
||
metricData
.
includes
(
'
Infinity
'
))
{
return
JSON5
.
parse
(
JSON5
.
parse
(
metricData
));
...
...
@@ -274,7 +265,7 @@ function formatComplexTypeValue(value: any): string | number {
export
{
convertTime
,
convertDuration
,
convertTime
ToSecond
,
convertTime
AsUnit
,
getFinalResult
,
getFinal
,
downFile
,
...
...
ts/webui/src/static/interface.ts
View file @
3b90b9d9
...
...
@@ -184,10 +184,14 @@ interface ExperimentParams {
};
clusterMetaData
?:
{
key
:
string
;
value
:
string
;
value
:
string
|
ClusterItem
;
}[];
}
interface
ClusterItem
{
command
?:
string
;
}
interface
ExperimentProfile
{
params
:
ExperimentParams
;
id
:
string
;
...
...
ts/webui/src/static/style/overview/command.scss
View file @
3b90b9d9
.command
{
width
:
100%
;
>
div
{
display
:
inline-block
;
}
.command1
{
width
:
46%
;
p
{
margin-top
:
0
;
}
}
.command2
{
width
:
54%
;
p
{
margin-top
:
0
;
}
.overviewCommand1
,
.overviewCommand2
{
.command
{
margin-top
:
0
;
font-weight
:
normal
;
}
}
.command1
,
.command2
{
.lineMargin
{
margin-top
:
20px
;
}
.basic
{
.lineMargin
{
margin-top
:
20px
;
font-weight
:
normal
;
}
}
ts/webui/src/static/style/overview/config.scss
View file @
3b90b9d9
...
...
@@ -4,15 +4,21 @@
z-index
:
1000
;
.ms-Button--default
{
padding
:
0
;
margin
:
0
0
15px
0
;
padding
:
0
8px
;
margin
:
0
0
12px
0
;
border
:
none
;
box-shadow
:
0
3px
3px
rgba
(
0
,
0
,
0
,
0
.08
);
border-radius
:
18px
0
0
18px
;
border
:
1px
solid
#ccc
;
color
:
#0573bc
;
font-size
:
12px
;
text-align
:
left
;
.ms-Button-label
{
font-weight
:
normal
;
}
}
.ms-Button--default
:hover
{
background-color
:
orangered
;
background-color
:
#0071bc
;
color
:
#fff
;
}
}
...
...
ts/webui/src/static/style/overview/count.scss
View file @
3b90b9d9
$seriesIconMargin
:
13
px
;
$seriesIconMargin
:
8
px
;
.ExpDuration
{
margin-top
:
28px
;
...
...
@@ -6,23 +6,74 @@ $seriesIconMargin: 13px;
span
:hover
{
cursor
:
pointer
;
}
.maxTrialNum
{
margin-bottom
:
10px
;
}
}
.durationInput
{
width
:
42px
;
height
:
32px
;
padding-right
:
5px
;
text-align
:
right
;
outline
:
none
;
border
:
none
;
border-bottom
:
1px
solid
#ccc
;
.exp-progress
{
margin-top
:
10px
;
.bold
{
font-weight
:
500
;
}
.joiner
{
padding
:
0
3px
;
}
}
.maxTrialNum
{
.editparam
{
position
:
relative
;
top
:
-7px
;
}
}
.noEditDuration
{
position
:
relative
;
top
:
-7px
;
}
.editDuration
{
position
:
relative
;
top
:
-17px
;
}
.maxExecDuration
{
width
:
74px
;
.editparam
{
&
-Input
{
width
:
42px
;
height
:
32px
;
padding-right
:
5px
;
text-align
:
right
;
outline
:
none
;
border
:
none
;
border-bottom
:
1px
solid
#ccc
;
}
.maxExecDuration
{
width
:
36px
;
}
&
-dropdown
{
width
:
48px
;
display
:
inline-block
;
position
:
relative
;
top
:
13px
;
left
:
4px
;
margin-right
:
3px
;
}
}
.ExpDuration
.series
.confirm
{
margin
:
0
6px
;
}
.series
{
position
:
relative
;
top
:
5px
;
i
{
font-size
:
20px
;
font-weight
:
700
;
...
...
@@ -39,6 +90,7 @@ $seriesIconMargin: 13px;
.cancel
i
{
color
:
red
;
font-size
:
16px
;
}
.edit
i
{
...
...
@@ -55,3 +107,11 @@ $seriesIconMargin: 13px;
z-index
:
999
;
left
:
0
;
}
.mess
{
margin-top
:
20px
;
.basic
p
{
margin-top
:
0
;
}
}
ts/webui/src/static/style/overview/overview.scss
View file @
3b90b9d9
$boxPadding
:
20px
42px
;
$boxPadding
:
20px
;
$boxBorderRadius
:
5px
;
$boxGapPadding
:
10px
;
.wrapper
{
display
:
grid
;
grid-template-columns
:
repeat
(
8
,
1fr
);
grid-auto-rows
:
82px
;
grid-gap
:
18px
;
grid-template-columns
:
repeat
(
9
,
1fr
);
grid-auto-rows
:
97px
;
>
div
{
>
div
{
background
:
#fff
;
padding
:
$boxPadding
;
border-radius
:
20px
;
border-radius
:
$boxBorderRadius
;
box-sizing
:
border-box
;
}
.overviewProgress
{
grid-column
:
2
/
5
;
grid-column
:
2
/
6
;
grid-row
:
1
/
5
;
display
:
grid
;
grid-auto-rows
:
70px
;
margin
:
0
$boxGapPadding
;
padding
:
0
;
background
:
transparent
;
...
...
@@ -25,7 +27,7 @@ $boxPadding: 20px 42px;
.trialCount
{
background
:
#fff
;
padding
:
$boxPadding
;
border-radius
:
20px
;
border-radius
:
$boxBorderRadius
;
box-sizing
:
border-box
;
/* for alert message tooltip position */
...
...
@@ -34,14 +36,31 @@ $boxPadding: 20px 42px;
.duration
{
// grid-row: 1 / 3;
height
:
13
6
px
;
height
:
13
9
px
;
}
.trialCount
{
margin-top
:
14
px
;
height
:
2
28
px
;
margin-top
:
79
px
;
height
:
2
39
px
;
}
}
.overviewCommand1
,
.overviewCommand2
{
border-radius
:
0
;
}
.overviewCommand1
{
grid-column-start
:
1
;
border-radius
:
$boxBorderRadius
0
0
$boxBorderRadius
;
}
.overviewCommand2
{
grid-column
:
2
/
6
;
margin-right
:
10px
;
padding-left
:
30px
;
border-radius
:
0
$boxBorderRadius
$boxBorderRadius
0
;
}
}
.overviewBasicInfo
{
...
...
@@ -58,10 +77,15 @@ $boxPadding: 20px 42px;
font-size
:
14px
;
color
:
#8f8f8f
;
margin-top
:
20px
;
span
{
color
:
#484848
;
}
}
div
{
font-size
:
16px
;
font-weight
:
500
;
color
:
#484848
;
}
...
...
@@ -73,8 +97,8 @@ $boxPadding: 20px 42px;
}
.overviewTable
{
grid-column
:
5
/
9
;
grid-row
:
1
/
1
0
;
grid-column
:
6
/
10
;
grid-row
:
1
/
1
1
;
overflow
:
hidden
;
.topTrialTitle
{
...
...
@@ -82,7 +106,7 @@ $boxPadding: 20px 42px;
}
.active
{
background
:
#
f3f2f1
;
background
:
#
d2d0ce
;
}
.max
{
...
...
@@ -99,21 +123,21 @@ $boxPadding: 20px 42px;
}
}
.overviewCommand
,
.overviewChart
{
grid-column
:
1
/
5
;
}
.overviewCommand
{
.overviewCommand1
,
.overviewCommand2
{
height
:
144px
;
overflow
:
hidden
;
margin-top
:
10px
;
}
$circle
:
10px
;
$bgblue
:
#0071bc
;
.overviewChart
{
grid-column
:
1
/
6
;
grid-row
:
7
/
11
;
margin-top
:
-38px
;
margin-right
:
$boxGapPadding
;
margin-top
:
-29px
;
.circle
{
width
:
$circle
;
...
...
@@ -124,3 +148,9 @@ $bgblue: #0071bc;
margin-right
:
18px
;
}
}
.showMess
{
position
:
absolute
;
top
:
42%
;
left
:
48%
;
}
ts/webui/src/static/style/overview/overviewTitle.scss
View file @
3b90b9d9
$iconPaddingVal
:
20px
;
.panelTitle
{
img
{
height
:
23px
;
/* (38 - 22 ) / 2 */
margin-top
:
8px
;
/* icon right */
padding
:
0
$iconPaddingVal
0
0
;
}
span
{
font-size
:
18px
;
font-weight
:
600
;
...
...
ts/webui/src/static/style/progress/probar.scss
View file @
3b90b9d9
/* status: 'INITIALIZED' | 'RUNNING' | 'ERROR' | 'STOPPING' | 'STOPPED' | 'DONE' */
$running
:
#0071bc
;
$done
:
#00ad56
;
$error
:
#a4262c
;
/* status: 'TUNER_NO_MORE_TRIAL' | 'NO_MORE_TRIAL' */
.RUNNING
,
...
...
@@ -7,27 +10,46 @@
.NO_MORE_TRIAL
,
.TUNER_NO_MORE_TRIAL
{
/* specific status color */
color
:
#0071bc
;
color
:
$running
;
/* progress- duration & trial numbers span */
.ms-ProgressIndicator-progressBar
{
background-color
:
#0071bc
;
background-color
:
$running
;
}
}
.DONE
,
.STOPPED
{
color
:
#009245
;
color
:
$done
;
.ms-ProgressIndicator-progressBar
{
background-color
:
#009245
;
background-color
:
$done
;
}
}
.ERROR
{
color
:
#eb0716
;
color
:
$error
;
.ms-ProgressIndicator-progressBar
{
background-color
:
#eb0716
;
background-color
:
$error
;
}
}
.bestMetric
{
.DONE
,
.STOPPED
{
color
:
$done
;
}
.ERROR
{
color
:
$error
;
}
.RUNNING
,
.STOPPING
,
.INITIALIZED
,
.NO_MORE_TRIAL
,
.TUNER_NO_MORE_TRIAL
{
color
:
$running
;
}
}
Prev
1
…
3
4
5
6
7
8
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment