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
92738382
Unverified
Commit
92738382
authored
Oct 21, 2020
by
Lijiaoa
Committed by
GitHub
Oct 21, 2020
Browse files
[webui v1.9 bug bash] fix bugs in v1.9 (#2989)
parent
30d29116
Changes
31
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
526 additions
and
279 deletions
+526
-279
src/webui/src/App.scss
src/webui/src/App.scss
+1
-1
src/webui/src/App.tsx
src/webui/src/App.tsx
+32
-2
src/webui/src/components/Overview.tsx
src/webui/src/components/Overview.tsx
+28
-8
src/webui/src/components/TrialsDetail.tsx
src/webui/src/components/TrialsDetail.tsx
+1
-1
src/webui/src/components/modals/Killjob.tsx
src/webui/src/components/modals/Killjob.tsx
+6
-2
src/webui/src/components/overview/command/Command1.tsx
src/webui/src/components/overview/command/Command1.tsx
+3
-26
src/webui/src/components/overview/command/Command2.tsx
src/webui/src/components/overview/command/Command2.tsx
+60
-0
src/webui/src/components/overview/count/EditExperimentParam.tsx
...bui/src/components/overview/count/EditExperimentParam.tsx
+121
-51
src/webui/src/components/overview/count/ExpDuration.tsx
src/webui/src/components/overview/count/ExpDuration.tsx
+29
-19
src/webui/src/components/overview/count/ExpDurationContext.tsx
...ebui/src/components/overview/count/ExpDurationContext.tsx
+4
-1
src/webui/src/components/overview/count/TrialCount.tsx
src/webui/src/components/overview/count/TrialCount.tsx
+56
-52
src/webui/src/components/overview/count/commonStyle.ts
src/webui/src/components/overview/count/commonStyle.ts
+16
-0
src/webui/src/components/overview/experiment/BasicInfo.tsx
src/webui/src/components/overview/experiment/BasicInfo.tsx
+47
-45
src/webui/src/components/overview/overviewConst.ts
src/webui/src/components/overview/overviewConst.ts
+7
-1
src/webui/src/components/overview/table/SuccessTable.tsx
src/webui/src/components/overview/table/SuccessTable.tsx
+19
-20
src/webui/src/components/public-child/DefaultMetric.tsx
src/webui/src/components/public-child/DefaultMetric.tsx
+1
-1
src/webui/src/components/public-child/config/TrialConfigButton.tsx
.../src/components/public-child/config/TrialConfigButton.tsx
+1
-1
src/webui/src/components/public-child/config/TrialConfigPanel.tsx
...i/src/components/public-child/config/TrialConfigPanel.tsx
+63
-43
src/webui/src/components/trial-detail/TableList.tsx
src/webui/src/components/trial-detail/TableList.tsx
+29
-3
src/webui/src/index.tsx
src/webui/src/index.tsx
+2
-2
No files found.
src/webui/src/App.scss
View file @
92738382
...
@@ -53,7 +53,7 @@
...
@@ -53,7 +53,7 @@
.ms-Callout-main
{
.ms-Callout-main
{
p
{
p
{
font-weight
:
500
;
font-weight
:
500
;
color
:
#
333
;
color
:
#
fff
;
}
}
}
}
...
...
src/webui/src/App.tsx
View file @
92738382
...
@@ -12,6 +12,7 @@ interface AppState {
...
@@ -12,6 +12,7 @@ interface AppState {
columnList
:
string
[];
columnList
:
string
[];
experimentUpdateBroadcast
:
number
;
experimentUpdateBroadcast
:
number
;
trialsUpdateBroadcast
:
number
;
trialsUpdateBroadcast
:
number
;
maxDurationUnit
:
string
;
metricGraphMode
:
'
max
'
|
'
min
'
;
// tuner's optimize_mode filed
metricGraphMode
:
'
max
'
|
'
min
'
;
// tuner's optimize_mode filed
isillegalFinal
:
boolean
;
isillegalFinal
:
boolean
;
expWarningMessage
:
string
;
expWarningMessage
:
string
;
...
@@ -26,11 +27,14 @@ export const AppContext = React.createContext({
...
@@ -26,11 +27,14 @@ export const AppContext = React.createContext({
trialsUpdateBroadcast
:
0
,
trialsUpdateBroadcast
:
0
,
metricGraphMode
:
'
max
'
,
metricGraphMode
:
'
max
'
,
bestTrialEntries
:
'
10
'
,
bestTrialEntries
:
'
10
'
,
maxDurationUnit
:
'
m
'
,
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
changeColumn
:
(
val
:
string
[])
=>
{},
changeColumn
:
(
val
:
string
[])
=>
{},
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
changeMetricGraphMode
:
(
val
:
'
max
'
|
'
min
'
)
=>
{},
changeMetricGraphMode
:
(
val
:
'
max
'
|
'
min
'
)
=>
{},
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
changeMaxDurationUnit
:
(
val
:
string
)
=>
{},
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
changeEntries
:
(
val
:
string
)
=>
{},
changeEntries
:
(
val
:
string
)
=>
{},
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
updateOverviewPage
:
()
=>
{}
updateOverviewPage
:
()
=>
{}
...
@@ -47,6 +51,7 @@ class App extends React.Component<{}, AppState> {
...
@@ -47,6 +51,7 @@ class App extends React.Component<{}, AppState> {
experimentUpdateBroadcast
:
0
,
experimentUpdateBroadcast
:
0
,
trialsUpdateBroadcast
:
0
,
trialsUpdateBroadcast
:
0
,
metricGraphMode
:
'
max
'
,
metricGraphMode
:
'
max
'
,
maxDurationUnit
:
'
m
'
,
isillegalFinal
:
false
,
isillegalFinal
:
false
,
expWarningMessage
:
''
,
expWarningMessage
:
''
,
bestTrialEntries
:
'
10
'
,
bestTrialEntries
:
'
10
'
,
...
@@ -91,6 +96,11 @@ class App extends React.Component<{}, AppState> {
...
@@ -91,6 +96,11 @@ class App extends React.Component<{}, AppState> {
this
.
setState
({
bestTrialEntries
:
entries
});
this
.
setState
({
bestTrialEntries
:
entries
});
};
};
// overview max duration unit
changeMaxDurationUnit
=
(
unit
:
string
):
void
=>
{
this
.
setState
({
maxDurationUnit
:
unit
});
};
updateOverviewPage
=
():
void
=>
{
updateOverviewPage
=
():
void
=>
{
this
.
setState
(
state
=>
({
this
.
setState
(
state
=>
({
experimentUpdateBroadcast
:
state
.
experimentUpdateBroadcast
+
1
experimentUpdateBroadcast
:
state
.
experimentUpdateBroadcast
+
1
...
@@ -114,7 +124,8 @@ class App extends React.Component<{}, AppState> {
...
@@ -114,7 +124,8 @@ class App extends React.Component<{}, AppState> {
metricGraphMode
,
metricGraphMode
,
isillegalFinal
,
isillegalFinal
,
expWarningMessage
,
expWarningMessage
,
bestTrialEntries
bestTrialEntries
,
maxDurationUnit
}
=
this
.
state
;
}
=
this
.
state
;
if
(
experimentUpdateBroadcast
===
0
||
trialsUpdateBroadcast
===
0
)
{
if
(
experimentUpdateBroadcast
===
0
||
trialsUpdateBroadcast
===
0
)
{
return
null
;
// TODO: render a loading page
return
null
;
// TODO: render a loading page
...
@@ -137,7 +148,24 @@ class App extends React.Component<{}, AppState> {
...
@@ -137,7 +148,24 @@ class App extends React.Component<{}, AppState> {
<
Stack
className
=
'contentBox'
>
<
Stack
className
=
'contentBox'
>
<
Stack
className
=
'content'
>
<
Stack
className
=
'content'
>
{
/* search space & config */
}
{
/* search space & config */
}
<
AppContext
.
Provider
value
=
{
{
interval
,
columnList
,
changeColumn
:
this
.
changeColumn
,
experimentUpdateBroadcast
,
trialsUpdateBroadcast
,
metricGraphMode
,
maxDurationUnit
,
changeMaxDurationUnit
:
this
.
changeMaxDurationUnit
,
changeMetricGraphMode
:
this
.
changeMetricGraphMode
,
bestTrialEntries
,
changeEntries
:
this
.
changeEntries
,
updateOverviewPage
:
this
.
updateOverviewPage
}
}
>
<
TrialConfigButton
/>
<
TrialConfigButton
/>
</
AppContext
.
Provider
>
{
/* if api has error field, show error message */
}
{
/* if api has error field, show error message */
}
{
errorList
.
map
(
{
errorList
.
map
(
(
item
,
key
)
=>
(
item
,
key
)
=>
...
@@ -160,6 +188,8 @@ class App extends React.Component<{}, AppState> {
...
@@ -160,6 +188,8 @@ class App extends React.Component<{}, AppState> {
experimentUpdateBroadcast
,
experimentUpdateBroadcast
,
trialsUpdateBroadcast
,
trialsUpdateBroadcast
,
metricGraphMode
,
metricGraphMode
,
maxDurationUnit
,
changeMaxDurationUnit
:
this
.
changeMaxDurationUnit
,
changeMetricGraphMode
:
this
.
changeMetricGraphMode
,
changeMetricGraphMode
:
this
.
changeMetricGraphMode
,
bestTrialEntries
,
bestTrialEntries
,
changeEntries
:
this
.
changeEntries
,
changeEntries
:
this
.
changeEntries
,
...
...
src/webui/src/components/Overview.tsx
View file @
92738382
...
@@ -10,7 +10,8 @@ import { ReBasicInfo } from './overview/experiment/BasicInfo';
...
@@ -10,7 +10,8 @@ import { ReBasicInfo } from './overview/experiment/BasicInfo';
import
{
ExpDuration
}
from
'
./overview/count/ExpDuration
'
;
import
{
ExpDuration
}
from
'
./overview/count/ExpDuration
'
;
import
{
ExpDurationContext
}
from
'
./overview/count/ExpDurationContext
'
;
import
{
ExpDurationContext
}
from
'
./overview/count/ExpDurationContext
'
;
import
{
TrialCount
}
from
'
./overview/count/TrialCount
'
;
import
{
TrialCount
}
from
'
./overview/count/TrialCount
'
;
import
{
Command
}
from
'
./overview/experiment/Command
'
;
import
{
Command1
}
from
'
./overview/command/Command1
'
;
import
{
Command2
}
from
'
./overview/command/Command2
'
;
import
{
TitleContext
}
from
'
./overview/TitleContext
'
;
import
{
TitleContext
}
from
'
./overview/TitleContext
'
;
import
{
itemStyle1
,
itemStyleSucceed
,
itemStyle2
,
entriesOption
}
from
'
./overview/overviewConst
'
;
import
{
itemStyle1
,
itemStyleSucceed
,
itemStyle2
,
entriesOption
}
from
'
./overview/overviewConst
'
;
import
'
../static/style/overview/overview.scss
'
;
import
'
../static/style/overview/overview.scss
'
;
...
@@ -66,7 +67,13 @@ class Overview extends React.Component<{}, OverviewState> {
...
@@ -66,7 +67,13 @@ class Overview extends React.Component<{}, OverviewState> {
return
(
return
(
<
AppContext
.
Consumer
>
<
AppContext
.
Consumer
>
{
(
value
):
React
.
ReactNode
=>
{
{
(
value
):
React
.
ReactNode
=>
{
const
{
metricGraphMode
,
bestTrialEntries
,
updateOverviewPage
}
=
value
;
const
{
metricGraphMode
,
bestTrialEntries
,
maxDurationUnit
,
updateOverviewPage
,
changeMaxDurationUnit
}
=
value
;
const
maxActive
=
metricGraphMode
===
'
max
'
?
'
active
'
:
''
;
const
maxActive
=
metricGraphMode
===
'
max
'
?
'
active
'
:
''
;
const
minActive
=
metricGraphMode
===
'
min
'
?
'
active
'
:
''
;
const
minActive
=
metricGraphMode
===
'
min
'
?
'
active
'
:
''
;
return
(
return
(
...
@@ -88,18 +95,29 @@ class Overview extends React.Component<{}, OverviewState> {
...
@@ -88,18 +95,29 @@ class Overview extends React.Component<{}, OverviewState> {
<
Title
/>
<
Title
/>
</
TitleContext
.
Provider
>
</
TitleContext
.
Provider
>
<
ExpDurationContext
.
Provider
<
ExpDurationContext
.
Provider
value
=
{
{
maxExecDuration
,
execDuration
,
updateOverviewPage
}
}
value
=
{
{
maxExecDuration
,
execDuration
,
updateOverviewPage
,
maxDurationUnit
,
changeMaxDurationUnit
}
}
>
>
<
ExpDuration
/>
<
ExpDuration
/>
</
ExpDurationContext
.
Provider
>
</
ExpDurationContext
.
Provider
>
</
div
>
</
div
>
<
div
className
=
'empty'
/>
<
div
className
=
'trialCount'
>
<
div
className
=
'trialCount'
>
<
TitleContext
.
Provider
value
=
{
{
text
:
'
Trial numbers
'
,
icon
:
'
NumberSymbol
'
}
}
>
<
TitleContext
.
Provider
value
=
{
{
text
:
'
Trial numbers
'
,
icon
:
'
NumberSymbol
'
}
}
>
<
Title
/>
<
Title
/>
</
TitleContext
.
Provider
>
</
TitleContext
.
Provider
>
<
ExpDurationContext
.
Provider
<
ExpDurationContext
.
Provider
value
=
{
{
maxExecDuration
,
execDuration
,
updateOverviewPage
}
}
value
=
{
{
maxExecDuration
,
execDuration
,
updateOverviewPage
,
maxDurationUnit
,
changeMaxDurationUnit
}
}
>
>
<
TrialCount
/>
<
TrialCount
/>
</
ExpDurationContext
.
Provider
>
</
ExpDurationContext
.
Provider
>
...
@@ -114,7 +132,6 @@ class Overview extends React.Component<{}, OverviewState> {
...
@@ -114,7 +132,6 @@ class Overview extends React.Component<{}, OverviewState> {
</
TitleContext
.
Provider
>
</
TitleContext
.
Provider
>
</
div
>
</
div
>
<
div
className
=
'topTrialTitle'
>
<
div
className
=
'topTrialTitle'
>
{
/* <Stack horizontal horizontalAlign='space-between'> */
}
<
Stack
horizontal
horizontalAlign
=
'end'
>
<
Stack
horizontal
horizontalAlign
=
'end'
>
<
DefaultButton
<
DefaultButton
onClick
=
{
this
.
clickMaxTop
}
onClick
=
{
this
.
clickMaxTop
}
...
@@ -152,8 +169,11 @@ class Overview extends React.Component<{}, OverviewState> {
...
@@ -152,8 +169,11 @@ class Overview extends React.Component<{}, OverviewState> {
</
Stack
>
</
Stack
>
<
SuccessTable
trialIds
=
{
bestTrials
.
map
(
trial
=>
trial
.
info
.
id
)
}
/>
<
SuccessTable
trialIds
=
{
bestTrials
.
map
(
trial
=>
trial
.
info
.
id
)
}
/>
</
div
>
</
div
>
<
div
className
=
'overviewCommand'
>
<
div
className
=
'overviewCommand1'
>
<
Command
/>
<
Command1
/>
</
div
>
<
div
className
=
'overviewCommand2'
>
<
Command2
/>
</
div
>
</
div
>
<
div
className
=
'overviewChart'
>
<
div
className
=
'overviewChart'
>
<
Stack
horizontal
>
<
Stack
horizontal
>
...
...
src/webui/src/components/TrialsDetail.tsx
View file @
92738382
...
@@ -82,7 +82,7 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
...
@@ -82,7 +82,7 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
</
Pivot
>
</
Pivot
>
</
div
>
</
div
>
{
/* trial table list */
}
{
/* trial table list */
}
<
div
style
=
{
{
backgroundColor
:
'
#fff
'
}
}
>
<
div
style
=
{
{
backgroundColor
:
'
#fff
'
,
marginTop
:
10
}
}
>
<
TableList
<
TableList
tableSource
=
{
source
}
tableSource
=
{
source
}
trialsUpdateBroadcast
=
{
this
.
context
.
trialsUpdateBroadcast
}
trialsUpdateBroadcast
=
{
this
.
context
.
trialsUpdateBroadcast
}
...
...
src/webui/src/components/modals/Killjob.tsx
View file @
92738382
...
@@ -112,11 +112,15 @@ class KillJob extends React.Component<KillJobProps, KillJobState> {
...
@@ -112,11 +112,15 @@ class KillJob extends React.Component<KillJobProps, KillJobState> {
setInitialFocus
=
{
true
}
setInitialFocus
=
{
true
}
>
>
<
div
className
=
{
styles
.
header
}
>
<
div
className
=
{
styles
.
header
}
>
<
p
className
=
{
styles
.
title
}
>
Kill trial
</
p
>
<
p
className
=
{
styles
.
title
}
style
=
{
{
color
:
'
#333
'
}
}
>
Kill trial
</
p
>
</
div
>
</
div
>
<
div
className
=
{
styles
.
inner
}
>
<
div
className
=
{
styles
.
inner
}
>
<
div
>
<
div
>
<
p
className
=
{
styles
.
subtext
}
>
{
prompString
}
</
p
>
<
p
className
=
{
styles
.
subtext
}
style
=
{
{
color
:
'
#333
'
}
}
>
{
prompString
}
</
p
>
</
div
>
</
div
>
</
div
>
</
div
>
<
FocusZone
>
<
FocusZone
>
...
...
src/webui/src/components/overview/
experiment
/Command.tsx
→
src/webui/src/components/overview/
command
/Command
1
.tsx
View file @
92738382
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
TooltipHost
,
Stack
}
from
'
@fluentui/react
'
;
import
{
EXPERIMENT
}
from
'
../../../static/datamodel
'
;
import
{
EXPERIMENT
}
from
'
../../../static/datamodel
'
;
import
'
../../../static/style/overview/command.scss
'
;
import
'
../../../static/style/overview/command.scss
'
;
export
const
Command
=
():
any
=>
{
export
const
Command1
=
():
any
=>
{
const
clusterMetaData
=
EXPERIMENT
.
profile
.
params
.
clusterMetaData
;
const
tuner
=
EXPERIMENT
.
profile
.
params
.
tuner
;
const
tuner
=
EXPERIMENT
.
profile
.
params
.
tuner
;
const
advisor
=
EXPERIMENT
.
profile
.
params
.
advisor
;
const
advisor
=
EXPERIMENT
.
profile
.
params
.
advisor
;
const
assessor
=
EXPERIMENT
.
profile
.
params
.
assessor
;
const
assessor
=
EXPERIMENT
.
profile
.
params
.
assessor
;
let
title
=
''
;
let
title
=
''
;
let
builtinName
=
''
;
let
builtinName
=
''
;
let
trialCommand
=
'
unknown
'
;
if
(
tuner
!==
undefined
)
{
if
(
tuner
!==
undefined
)
{
title
=
title
.
concat
(
'
Tuner
'
);
title
=
title
.
concat
(
'
Tuner
'
);
if
(
tuner
.
builtinTunerName
!==
undefined
)
{
if
(
tuner
.
builtinTunerName
!==
undefined
)
{
...
@@ -29,35 +26,15 @@ export const Command = (): any => {
...
@@ -29,35 +26,15 @@ export const Command = (): any => {
builtinName
=
builtinName
.
concat
(
assessor
.
builtinAssessorName
);
builtinName
=
builtinName
.
concat
(
assessor
.
builtinAssessorName
);
}
}
}
}
if
(
clusterMetaData
!==
undefined
)
{
for
(
const
item
of
clusterMetaData
)
{
if
(
item
.
key
===
'
command
'
)
{
trialCommand
=
item
.
value
;
}
}
}
return
(
return
(
<
div
className
=
'command basic'
>
<
div
className
=
'command basic'
>
<
div
className
=
'command1'
>
<
div
>
<
p
>
Training platform
</
p
>
<
p
>
Training platform
</
p
>
<
div
className
=
'nowrap'
>
{
EXPERIMENT
.
profile
.
params
.
trainingServicePlatform
}
</
div
>
<
div
className
=
'nowrap'
>
{
EXPERIMENT
.
profile
.
params
.
trainingServicePlatform
}
</
div
>
<
p
className
=
'lineMargin'
>
{
title
}
</
p
>
<
p
className
=
'lineMargin'
>
{
title
}
</
p
>
<
div
className
=
'nowrap'
>
{
builtinName
}
</
div
>
<
div
className
=
'nowrap'
>
{
builtinName
}
</
div
>
</
div
>
</
div
>
<
Stack
className
=
'command2'
>
<
p
>
Log directory
</
p
>
<
div
className
=
'nowrap'
>
<
TooltipHost
content
=
{
EXPERIMENT
.
profile
.
logDir
||
'
unknown
'
}
className
=
'nowrap'
>
{
EXPERIMENT
.
profile
.
logDir
||
'
unknown
'
}
</
TooltipHost
>
</
div
>
<
p
className
=
'lineMargin'
>
Trial command
</
p
>
<
div
className
=
'nowrap'
>
<
TooltipHost
content
=
{
trialCommand
||
'
unknown
'
}
className
=
'nowrap'
>
{
trialCommand
||
'
unknown
'
}
</
TooltipHost
>
</
div
>
</
Stack
>
</
div
>
</
div
>
);
);
};
};
src/webui/src/components/overview/command/Command2.tsx
0 → 100644
View file @
92738382
import
React
from
'
react
'
;
import
{
TooltipHost
,
DirectionalHint
}
from
'
@fluentui/react
'
;
import
{
EXPERIMENT
}
from
'
../../../static/datamodel
'
;
import
{
TOOLTIP_BACKGROUND_COLOR
}
from
'
../../../static/const
'
;
import
'
../../../static/style/overview/command.scss
'
;
export
const
Command2
=
():
any
=>
{
const
clusterMetaData
=
EXPERIMENT
.
profile
.
params
.
clusterMetaData
;
let
trialCommand
=
'
unknown
'
;
if
(
clusterMetaData
!==
undefined
)
{
for
(
const
item
of
clusterMetaData
)
{
if
(
item
.
key
===
'
command
'
)
{
trialCommand
=
item
.
value
;
}
}
}
return
(
<
div
className
=
'command basic'
>
<
p
>
Log directory
</
p
>
<
div
className
=
'nowrap'
>
<
TooltipHost
content
=
{
EXPERIMENT
.
profile
.
logDir
||
'
unknown
'
}
className
=
'nowrap'
directionalHint
=
{
DirectionalHint
.
bottomCenter
}
tooltipProps
=
{
{
calloutProps
:
{
styles
:
{
beak
:
{
background
:
TOOLTIP_BACKGROUND_COLOR
},
beakCurtain
:
{
background
:
TOOLTIP_BACKGROUND_COLOR
},
calloutMain
:
{
background
:
TOOLTIP_BACKGROUND_COLOR
}
}
}
}
}
>
{
EXPERIMENT
.
profile
.
logDir
||
'
unknown
'
}
</
TooltipHost
>
</
div
>
<
p
className
=
'lineMargin'
>
Trial command
</
p
>
<
div
className
=
'nowrap'
>
<
TooltipHost
content
=
{
trialCommand
||
'
unknown
'
}
className
=
'nowrap'
directionalHint
=
{
DirectionalHint
.
bottomCenter
}
tooltipProps
=
{
{
calloutProps
:
{
styles
:
{
beak
:
{
background
:
TOOLTIP_BACKGROUND_COLOR
},
beakCurtain
:
{
background
:
TOOLTIP_BACKGROUND_COLOR
},
calloutMain
:
{
background
:
TOOLTIP_BACKGROUND_COLOR
}
}
}
}
}
>
{
trialCommand
||
'
unknown
'
}
</
TooltipHost
>
</
div
>
</
div
>
);
};
src/webui/src/components/overview/count/EditExperimentParam.tsx
View file @
92738382
import
React
,
{
useState
,
useCallback
,
useContext
}
from
'
react
'
;
import
React
,
{
useState
,
useCallback
,
useContext
}
from
'
react
'
;
import
axios
from
'
axios
'
;
import
axios
from
'
axios
'
;
import
{
Dropdown
}
from
'
@fluentui/react
'
;
import
{
EXPERIMENT
}
from
'
../../../static/datamodel
'
;
import
{
EXPERIMENT
}
from
'
../../../static/datamodel
'
;
import
{
AppContext
}
from
'
../../../App
'
;
import
{
EditExpeParamContext
}
from
'
./context
'
;
import
{
EditExpeParamContext
}
from
'
./context
'
;
import
{
MANAGER_IP
}
from
'
../../../static/c
onst
'
;
import
{
durationUnit
}
from
'
../overviewC
onst
'
;
import
{
convertTimeToSecond
}
from
'
../../../static/
function
'
;
import
{
MANAGER_IP
,
MAX_TRIAL_NUMBERS
}
from
'
../../../static/
const
'
;
import
{
Edit
,
CheckMark
,
Cancel
}
from
'
../../buttons/Icon
'
;
import
{
Edit
,
CheckMark
,
Cancel
}
from
'
../../buttons/Icon
'
;
import
MessageInfo
from
'
../../modals/MessageInfo
'
;
import
MessageInfo
from
'
../../modals/MessageInfo
'
;
import
'
../../../static/style/overview/count.scss
'
;
import
'
../../../static/style/overview/count.scss
'
;
...
@@ -28,12 +30,14 @@ export const EditExperimentParam = (): any => {
...
@@ -28,12 +30,14 @@ export const EditExperimentParam = (): any => {
const
{
title
,
field
,
editType
,
maxExecDuration
,
maxTrialNum
,
trialConcurrency
,
updateOverviewPage
}
=
useContext
(
const
{
title
,
field
,
editType
,
maxExecDuration
,
maxTrialNum
,
trialConcurrency
,
updateOverviewPage
}
=
useContext
(
EditExpeParamContext
EditExpeParamContext
);
);
const
{
maxDurationUnit
,
changeMaxDurationUnit
}
=
useContext
(
AppContext
);
const
[
unit
,
setUnit
]
=
useState
(
maxDurationUnit
);
let
defaultVal
=
''
;
let
defaultVal
=
''
;
let
editVal
=
''
;
let
editVal
=
''
;
if
(
title
===
'
Max duration
'
)
{
if
(
title
===
'
Max duration
'
)
{
defaultVal
=
maxExecDuration
;
defaultVal
=
maxExecDuration
;
editVal
=
maxExecDuration
;
editVal
=
maxExecDuration
;
}
else
if
(
title
===
'
Max trial numbers
'
)
{
}
else
if
(
title
===
MAX_TRIAL_NUMBERS
)
{
defaultVal
=
maxTrialNum
.
toString
();
defaultVal
=
maxTrialNum
.
toString
();
editVal
=
maxTrialNum
.
toString
();
editVal
=
maxTrialNum
.
toString
();
}
else
{
}
else
{
...
@@ -46,32 +50,64 @@ export const EditExperimentParam = (): any => {
...
@@ -46,32 +50,64 @@ export const EditExperimentParam = (): any => {
setEditValInput
(
event
.
target
.
value
);
setEditValInput
(
event
.
target
.
value
);
}
}
function
cancelEdit
():
void
{
function
showMessageInfo
(
info
:
string
,
typeInfo
:
string
):
any
{
setEditValInput
(
defaultVal
);
setInfo
(
info
);
showPencil
();
setTypeInfo
(
typeInfo
);
showSucceedInfo
();
setTimeout
(
hideSucceedInfo
,
2000
);
}
function
updateUnit
(
event
:
React
.
FormEvent
<
HTMLDivElement
>
,
item
:
any
):
void
{
if
(
item
!==
undefined
)
{
setUnit
(
item
.
key
);
}
}
}
async
function
confirmEdit
():
Promise
<
void
>
{
async
function
confirmEdit
():
Promise
<
void
>
{
const
isMaxDuration
=
title
===
'
Max duration
'
;
const
isMaxDuration
=
title
===
'
Max duration
'
;
const
newProfile
=
Object
.
assign
({},
EXPERIMENT
.
profile
);
const
newProfile
=
Object
.
assign
({},
EXPERIMENT
.
profile
);
let
beforeParam
=
''
;
let
beforeParam
=
''
;
if
(
!
isMaxDuration
&&
!
editInputVal
.
match
(
/^
[
1-9
]\d
*$/
))
{
if
(
isMaxDuration
)
{
if
(
!
editInputVal
.
match
(
/^
\d
+
(?=\.{0,1}\d
+$|$
)
/
))
{
showMessageInfo
(
'
Please enter a number!
'
,
'
error
'
);
setEditValInput
(
defaultVal
);
return
;
}
}
else
{
if
(
!
editInputVal
.
match
(
/^
[
1-9
]\d
*$/
))
{
showMessageInfo
(
'
Please enter a positive integer!
'
,
'
error
'
);
showMessageInfo
(
'
Please enter a positive integer!
'
,
'
error
'
);
setEditValInput
(
defaultVal
);
return
;
return
;
}
}
}
if
(
isMaxDuration
)
{
if
(
isMaxDuration
)
{
beforeParam
=
maxExecDuration
;
beforeParam
=
maxExecDuration
;
}
else
if
(
title
===
'
Max trial numbers
'
)
{
}
else
if
(
title
===
MAX_TRIAL_NUMBERS
)
{
beforeParam
=
maxTrialNum
.
toString
();
beforeParam
=
maxTrialNum
.
toString
();
}
else
{
}
else
{
beforeParam
=
trialConcurrency
.
toString
();
beforeParam
=
trialConcurrency
.
toString
();
}
}
if
(
editInputVal
===
beforeParam
)
{
if
(
editInputVal
===
beforeParam
)
{
if
(
isMaxDuration
)
{
if
(
maxDurationUnit
===
unit
)
{
showMessageInfo
(
`Trial
${
field
}
has not changed`
,
'
error
'
);
return
;
}
}
else
{
showMessageInfo
(
`Trial
${
field
}
has not changed`
,
'
error
'
);
showMessageInfo
(
`Trial
${
field
}
has not changed`
,
'
error
'
);
return
;
return
;
}
}
}
if
(
isMaxDuration
)
{
if
(
isMaxDuration
)
{
newProfile
.
params
[
field
]
=
convertTimeToSecond
(
editInputVal
);
const
maxDura
=
JSON
.
parse
(
editInputVal
);
if
(
unit
===
'
m
'
)
{
newProfile
.
params
[
field
]
=
maxDura
*
60
;
}
else
if
(
unit
===
'
h
'
)
{
newProfile
.
params
[
field
]
=
maxDura
*
3600
;
}
else
{
newProfile
.
params
[
field
]
=
maxDura
*
24
*
60
*
60
;
}
}
else
{
}
else
{
newProfile
.
params
[
field
]
=
parseInt
(
editInputVal
,
10
);
newProfile
.
params
[
field
]
=
parseInt
(
editInputVal
,
10
);
}
}
...
@@ -82,7 +118,8 @@ export const EditExperimentParam = (): any => {
...
@@ -82,7 +118,8 @@ export const EditExperimentParam = (): any => {
params
:
{
update_type
:
editType
}
params
:
{
update_type
:
editType
}
});
});
if
(
res
.
status
===
200
)
{
if
(
res
.
status
===
200
)
{
showMessageInfo
(
`Successfully updated
${
field
}
`
,
'
success
'
);
showMessageInfo
(
`Successfully updated experiment's
${
field
}
`
,
'
success
'
);
changeMaxDurationUnit
(
unit
);
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
if
(
error
.
response
&&
error
.
response
.
data
.
error
)
{
if
(
error
.
response
&&
error
.
response
.
data
.
error
)
{
...
@@ -94,38 +131,66 @@ export const EditExperimentParam = (): any => {
...
@@ -94,38 +131,66 @@ export const EditExperimentParam = (): any => {
}
else
{
}
else
{
showMessageInfo
(
`Failed to update trial
${
field
}
\nUnknown error`
,
'
error
'
);
showMessageInfo
(
`Failed to update trial
${
field
}
\nUnknown error`
,
'
error
'
);
}
}
setEditValInput
(
defaultVal
);
}
}
showPencil
();
showPencil
();
updateOverviewPage
();
updateOverviewPage
();
}
}
function
showMessageInfo
(
info
:
string
,
typeInfo
:
string
):
any
{
function
cancelEdit
():
void
{
setInfo
(
info
);
setEditValInput
(
defaultVal
);
setTypeInfo
(
typeInfo
);
showPencil
();
showSucceedInfo
();
setUnit
(
maxDurationUnit
);
setTimeout
(
hideSucceedInfo
,
2000
);
}
}
function
convertUnit
(
val
:
string
):
string
{
if
(
val
===
'
d
'
)
{
return
'
day
'
;
}
else
if
(
val
===
'
h
'
)
{
return
'
hour
'
;
}
else
if
(
val
===
'
m
'
)
{
return
'
min
'
;
}
else
{
return
val
;
}
}
return
(
<
AppContext
.
Consumer
>
{
(
values
):
React
.
ReactNode
=>
{
return
(
return
(
<
EditExpeParamContext
.
Consumer
>
<
EditExpeParamContext
.
Consumer
>
{
(
value
):
React
.
ReactNode
=>
{
{
(
value
):
React
.
ReactNode
=>
{
let
editClassName
=
''
;
if
(
value
.
field
===
'
maxExecDuration
'
)
{
editClassName
=
isShowPencil
?
'
noEditDuration
'
:
'
editDuration
'
;
}
return
(
return
(
<
React
.
Fragment
>
<
React
.
Fragment
>
<
p
>
{
value
.
title
}
</
p
>
<
div
className
=
{
`
${
editClassName
}
editparam`
}
>
<
div
>
<
span
>
{
value
.
title
}
</
span
>
<
input
<
input
className
=
{
`
${
value
.
field
}
duration
Input`
}
className
=
{
`
${
value
.
field
}
editparam-
Input`
}
ref
=
{
DurationInputRef
}
ref
=
{
DurationInputRef
}
disabled
=
{
isShowPencil
?
true
:
false
}
disabled
=
{
isShowPencil
?
true
:
false
}
value
=
{
editInputVal
}
value
=
{
editInputVal
}
onChange
=
{
setInputVal
}
onChange
=
{
setInputVal
}
/>
/>
{
isShowPencil
&&
title
===
'
Max duration
'
&&
(
<
span
>
{
convertUnit
(
values
.
maxDurationUnit
)
}
</
span
>
)
}
{
!
isShowPencil
&&
title
===
'
Max duration
'
&&
(
<
Dropdown
selectedKey
=
{
unit
}
options
=
{
durationUnit
}
className
=
'editparam-dropdown'
onChange
=
{
updateUnit
}
/>
)
}
{
isShowPencil
&&
(
{
isShowPencil
&&
(
<
span
className
=
'edit'
onClick
=
{
hidePencil
}
>
<
span
className
=
'edit'
onClick
=
{
hidePencil
}
>
{
Edit
}
{
Edit
}
</
span
>
</
span
>
)
}
)
}
{
!
isShowPencil
&&
(
{
!
isShowPencil
&&
(
<
span
className
=
'series'
>
<
span
className
=
'series'
>
<
span
className
=
'confirm'
onClick
=
{
confirmEdit
}
>
<
span
className
=
'confirm'
onClick
=
{
confirmEdit
}
>
...
@@ -137,11 +202,16 @@ export const EditExperimentParam = (): any => {
...
@@ -137,11 +202,16 @@ export const EditExperimentParam = (): any => {
</
span
>
</
span
>
)
}
)
}
{
isShowSucceedInfo
&&
<
MessageInfo
className
=
'info'
typeInfo
=
{
typeInfo
}
info
=
{
info
}
/>
}
{
isShowSucceedInfo
&&
(
<
MessageInfo
className
=
'info'
typeInfo
=
{
typeInfo
}
info
=
{
info
}
/>
)
}
</
div
>
</
div
>
</
React
.
Fragment
>
</
React
.
Fragment
>
);
);
}
}
}
}
</
EditExpeParamContext
.
Consumer
>
</
EditExpeParamContext
.
Consumer
>
);
);
}
}
</
AppContext
.
Consumer
>
);
};
};
src/webui/src/components/overview/count/ExpDuration.tsx
View file @
92738382
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
Stack
,
TooltipHost
,
ProgressIndicator
}
from
'
@fluentui/react
'
;
import
{
Stack
,
ProgressIndicator
,
TooltipHost
,
DirectionalHint
}
from
'
@fluentui/react
'
;
import
{
EXPERIMENT
}
from
'
../../../static/datamodel
'
;
import
{
EXPERIMENT
}
from
'
../../../static/datamodel
'
;
import
{
CONTROLTYPE
}
from
'
../../../static/const
'
;
import
{
CONTROLTYPE
,
TOOLTIP_BACKGROUND_COLOR
}
from
'
../../../static/const
'
;
import
{
convertDuration
}
from
'
../../../static/function
'
;
import
{
convertDuration
,
convertTimeAsUnit
}
from
'
../../../static/function
'
;
import
{
EditExperimentParam
}
from
'
./EditExperimentParam
'
;
import
{
EditExperimentParam
}
from
'
./EditExperimentParam
'
;
import
{
ExpDurationContext
}
from
'
./ExpDurationContext
'
;
import
{
ExpDurationContext
}
from
'
./ExpDurationContext
'
;
import
{
EditExpeParamContext
}
from
'
./context
'
;
import
{
EditExpeParamContext
}
from
'
./context
'
;
import
{
durationItem1
,
durationItem2
}
from
'
./commonStyle
'
;
import
'
../../../static/style/overview/count.scss
'
;
import
'
../../../static/style/overview/count.scss
'
;
const
itemStyle1
:
React
.
CSSProperties
=
{
width
:
'
62%
'
,
height
:
80
};
const
itemStyle2
:
React
.
CSSProperties
=
{
width
:
'
63%
'
,
height
:
80
,
textAlign
:
'
right
'
};
export
const
ExpDuration
=
():
any
=>
(
export
const
ExpDuration
=
():
any
=>
(
<
ExpDurationContext
.
Consumer
>
<
ExpDurationContext
.
Consumer
>
{
(
value
):
React
.
ReactNode
=>
{
{
(
value
):
React
.
ReactNode
=>
{
const
{
maxExecDuration
,
execDuration
,
updateOverviewPage
}
=
value
;
const
{
maxExecDuration
,
execDuration
,
maxDurationUnit
,
updateOverviewPage
}
=
value
;
const
tooltip
=
maxExecDuration
-
execDuration
;
const
tooltip
=
maxExecDuration
-
execDuration
;
const
maxExecDurationStr
=
convertDuration
(
maxExecDuration
);
const
percent
=
execDuration
/
maxExecDuration
;
const
percent
=
execDuration
/
maxExecDuration
;
const
execDurationStr
=
convertDuration
(
execDuration
);
const
maxExecDurationStr
=
convertTimeAsUnit
(
maxDurationUnit
,
maxExecDuration
).
toString
();
return
(
return
(
<
Stack
horizontal
className
=
'ExpDuration'
>
<
Stack
horizontal
className
=
'ExpDuration'
>
<
div
style
=
{
itemStyle1
}
>
<
div
style
=
{
durationItem1
}
>
<
TooltipHost
content
=
{
`
${
convertDuration
(
tooltip
)}
remaining`
}
>
<
TooltipHost
<
ProgressIndicator
percentComplete
=
{
percent
}
barHeight
=
{
15
}
/>
content
=
{
`
${
convertDuration
(
tooltip
)}
remaining`
}
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
=
{
percent
}
barHeight
=
{
15
}
/>
</
TooltipHost
>
</
TooltipHost
>
{
/* execDuration / maxDuration: 20min / 1h */
}
<
div
className
=
'exp-progress'
>
<
span
className
=
{
`
${
EXPERIMENT
.
status
}
bold`
}
>
{
execDurationStr
}
</
span
>
<
span
className
=
'joiner'
>
/
</
span
>
<
span
>
{
`
${
maxExecDurationStr
}
${
maxDurationUnit
}
`
}
</
span
>
</
div
>
</
div
>
</
div
>
<
div
style
=
{
itemStyle2
}
>
<
div
style
=
{
durationItem2
}
>
<
Stack
horizontal
></
Stack
>
<
EditExpeParamContext
.
Provider
<
EditExpeParamContext
.
Provider
value
=
{
{
value
=
{
{
editType
:
CONTROLTYPE
[
0
],
editType
:
CONTROLTYPE
[
0
],
...
...
src/webui/src/components/overview/count/ExpDurationContext.tsx
View file @
92738382
...
@@ -3,5 +3,8 @@ export const ExpDurationContext = React.createContext({
...
@@ -3,5 +3,8 @@ export const ExpDurationContext = React.createContext({
maxExecDuration
:
0
,
maxExecDuration
:
0
,
execDuration
:
0
,
execDuration
:
0
,
// eslint-disable-next-line @typescript-eslint/no-empty-function
// 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
=>
{}
});
});
src/webui/src/components/overview/count/TrialCount.tsx
View file @
92738382
import
*
as
React
from
'
react
'
;
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
{
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
{
EditExperimentParam
}
from
'
./EditExperimentParam
'
;
import
{
EditExpeParamContext
}
from
'
./context
'
;
import
{
EditExpeParamContext
}
from
'
./context
'
;
import
{
ExpDurationContext
}
from
'
./ExpDurationContext
'
;
import
{
ExpDurationContext
}
from
'
./ExpDurationContext
'
;
import
{
trialCountItem1
,
trialCountItem2
}
from
'
./commonStyle
'
;
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
};
export
const
TrialCount
=
():
any
=>
{
export
const
TrialCount
=
():
any
=>
{
const
count
=
TRIALS
.
countStatus
();
const
count
=
TRIALS
.
countStatus
();
...
@@ -30,8 +13,9 @@ export const TrialCount = (): any => {
...
@@ -30,8 +13,9 @@ export const TrialCount = (): any => {
const
stoppedCount
=
count
.
get
(
'
USER_CANCELED
'
)
!
+
count
.
get
(
'
SYS_CANCELED
'
)
!
+
count
.
get
(
'
EARLY_STOPPED
'
)
!
;
const
stoppedCount
=
count
.
get
(
'
USER_CANCELED
'
)
!
+
count
.
get
(
'
SYS_CANCELED
'
)
!
+
count
.
get
(
'
EARLY_STOPPED
'
)
!
;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const
bar2
=
count
.
get
(
'
RUNNING
'
)
!
+
count
.
get
(
'
SUCCEEDED
'
)
!
+
count
.
get
(
'
FAILED
'
)
!
+
stoppedCount
;
const
bar2
=
count
.
get
(
'
RUNNING
'
)
!
+
count
.
get
(
'
SUCCEEDED
'
)
!
+
count
.
get
(
'
FAILED
'
)
!
+
stoppedCount
;
const
maxTrialNum
=
EXPERIMENT
.
profile
.
params
.
maxTrialNum
;
// support type [0, 1], not 98%
// support type [0, 1], not 98%
const
bar2Percent
=
bar2
/
EXPERIMENT
.
profile
.
params
.
maxTrialNum
;
const
bar2Percent
=
bar2
/
maxTrialNum
;
return
(
return
(
<
ExpDurationContext
.
Consumer
>
<
ExpDurationContext
.
Consumer
>
{
(
value
):
React
.
ReactNode
=>
{
{
(
value
):
React
.
ReactNode
=>
{
...
@@ -39,40 +23,36 @@ export const TrialCount = (): any => {
...
@@ -39,40 +23,36 @@ export const TrialCount = (): any => {
return
(
return
(
<
React
.
Fragment
>
<
React
.
Fragment
>
<
Stack
horizontal
horizontalAlign
=
'space-between'
className
=
'ExpDuration'
>
<
Stack
horizontal
horizontalAlign
=
'space-between'
className
=
'ExpDuration'
>
<
div
style
=
{
itemStyles
}
>
<
div
style
=
{
trialCountItem1
}
>
<
TooltipHost
content
=
{
bar2
.
toString
()
}
>
<
TooltipHost
<
ProgressIndicator
percentComplete
=
{
bar2Percent
}
barHeight
=
{
15
}
/>
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
>
</
TooltipHost
>
<
Stack
horizontal
className
=
'
m
ess'
>
<
div
className
=
'
exp-progr
ess'
>
<
div
style
=
{
itemRunning
}
className
=
'basic'
>
<
span
className
=
{
`
${
EXPERIMENT
.
status
}
bold`
}
>
{
bar2
}
</
span
>
<
p
>
Running
</
p
>
<
span
className
=
'joiner'
>
/
</
span
>
<
div
>
{
count
.
get
(
'
RUNNING
'
)
}
</
div
>
<
span
>
{
maxTrialNum
}
</
span
>
</
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
>
</
div
>
</
Stack
>
<
div
style
=
{
trialCountItem2
}
>
<
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
>
<
div
style
=
{
itemStyle2
}
>
<
EditExpeParamContext
.
Provider
<
EditExpeParamContext
.
Provider
value
=
{
{
value
=
{
{
title
:
'
Max trial numbers
'
,
title
:
MAX_TRIAL_NUMBERS
,
field
:
'
maxTrialNum
'
,
field
:
'
maxTrialNum
'
,
editType
:
CONTROLTYPE
[
1
],
editType
:
CONTROLTYPE
[
1
],
maxExecDuration
:
''
,
maxExecDuration
:
''
,
...
@@ -81,7 +61,9 @@ export const TrialCount = (): any => {
...
@@ -81,7 +61,9 @@ export const TrialCount = (): any => {
updateOverviewPage
updateOverviewPage
}
}
}
}
>
>
<
div
className
=
'maxTrialNum'
>
<
EditExperimentParam
/>
<
EditExperimentParam
/>
</
div
>
</
EditExpeParamContext
.
Provider
>
</
EditExpeParamContext
.
Provider
>
<
EditExpeParamContext
.
Provider
<
EditExpeParamContext
.
Provider
value
=
{
{
value
=
{
{
...
@@ -99,6 +81,28 @@ export const TrialCount = (): any => {
...
@@ -99,6 +81,28 @@ export const TrialCount = (): any => {
</
EditExpeParamContext
.
Provider
>
</
EditExpeParamContext
.
Provider
>
</
div
>
</
div
>
</
Stack
>
</
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
>
</
React
.
Fragment
>
);
);
}
}
}
}
...
...
src/webui/src/components/overview/count/commonStyle.ts
0 → 100644
View file @
92738382
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
};
src/webui/src/components/overview/experiment/BasicInfo.tsx
View file @
92738382
...
@@ -24,11 +24,12 @@ export const ReBasicInfo = (): any => {
...
@@ -24,11 +24,12 @@ export const ReBasicInfo = (): any => {
return
(
return
(
<
div
>
<
div
>
<
div
className
=
'basic'
>
<
div
className
=
'basic'
>
<
p
>
ID:
{
EXPERIMENT
.
profile
.
id
}
</
p
>
<
p
>
ID:
<
span
>
{
EXPERIMENT
.
profile
.
id
}
</
span
>
</
p
>
<
div
>
{
EXPERIMENT
.
profile
.
params
.
experimentName
}
</
div
>
<
div
>
{
EXPERIMENT
.
profile
.
params
.
experimentName
}
</
div
>
</
div
>
</
div
>
<
div
className
=
'basic'
>
<
div
className
=
'basic'
>
<
Stack
className
=
'basic'
>
<
p
>
Status
</
p
>
<
p
>
Status
</
p
>
<
Stack
horizontal
className
=
'status'
>
<
Stack
horizontal
className
=
'status'
>
<
span
className
=
{
`
${
EXPERIMENT
.
status
}
status-text`
}
>
{
EXPERIMENT
.
status
}
</
span
>
<
span
className
=
{
`
${
EXPERIMENT
.
status
}
status-text`
}
>
{
EXPERIMENT
.
status
}
</
span
>
...
@@ -52,12 +53,12 @@ export const ReBasicInfo = (): any => {
...
@@ -52,12 +53,12 @@ export const ReBasicInfo = (): any => {
setInitialFocus
=
{
true
}
setInitialFocus
=
{
true
}
>
>
<
div
className
=
{
styles
.
header
}
>
<
div
className
=
{
styles
.
header
}
>
<
p
className
=
{
styles
.
title
}
id
=
{
labelId
}
>
<
p
className
=
{
styles
.
title
}
id
=
{
labelId
}
style
=
{
{
color
:
'
#333
'
}
}
>
Error
Error
</
p
>
</
p
>
</
div
>
</
div
>
<
div
className
=
{
styles
.
inner
}
>
<
div
className
=
{
styles
.
inner
}
>
<
p
className
=
{
styles
.
subtext
}
id
=
{
descriptionId
}
>
<
p
className
=
{
styles
.
subtext
}
id
=
{
descriptionId
}
style
=
{
{
color
:
'
#333
'
}
}
>
{
EXPERIMENT
.
error
}
{
EXPERIMENT
.
error
}
</
p
>
</
p
>
<
div
className
=
{
styles
.
actions
}
>
<
div
className
=
{
styles
.
actions
}
>
...
@@ -71,14 +72,15 @@ export const ReBasicInfo = (): any => {
...
@@ -71,14 +72,15 @@ export const ReBasicInfo = (): any => {
</
div
>
</
div
>
)
:
null
}
)
:
null
}
</
Stack
>
</
Stack
>
</
Stack
>
</
div
>
</
div
>
<
div
className
=
'basic'
>
<
div
className
=
'basic'
>
<
BestMetricContext
.
Consumer
>
<
BestMetricContext
.
Consumer
>
{
(
value
):
React
.
ReactNode
=>
(
{
(
value
):
React
.
ReactNode
=>
(
<
Stack
>
<
Stack
className
=
'bestMetric'
>
<
p
>
Best metric
</
p
>
<
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
>
</
Stack
>
)
}
)
}
</
BestMetricContext
.
Consumer
>
</
BestMetricContext
.
Consumer
>
...
...
src/webui/src/components/overview/overviewConst.ts
View file @
92738382
...
@@ -18,4 +18,10 @@ const entriesOption = [
...
@@ -18,4 +18,10 @@ const entriesOption = [
{
key
:
'
100
'
,
text
:
'
100
'
}
{
key
:
'
100
'
,
text
:
'
100
'
}
];
];
export
{
itemStyle1
,
itemStyleSucceed
,
itemStyle2
,
entriesOption
};
const
durationUnit
=
[
{
key
:
'
m
'
,
text
:
'
m
'
},
{
key
:
'
h
'
,
text
:
'
h
'
},
{
key
:
'
d
'
,
text
:
'
d
'
}
];
export
{
itemStyle1
,
itemStyleSucceed
,
itemStyle2
,
entriesOption
,
durationUnit
};
src/webui/src/components/overview/table/SuccessTable.tsx
View file @
92738382
...
@@ -70,40 +70,41 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
...
@@ -70,40 +70,41 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
</
div
>
</
div
>
</
div
>
</
div
>
);
);
columns
=
[
columns
=
[
{
{
name
:
'
Trial No.
'
,
name
:
'
Trial No.
'
,
key
:
'
sequenceId
'
,
key
:
'
sequenceId
'
,
fieldName
:
'
sequenceId
'
,
// required!
fieldName
:
'
sequenceId
'
,
// required!
minWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
minWidth
:
5
0
,
maxWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
maxWidth
:
87
,
isResizable
:
true
,
isResizable
:
true
,
data
:
'
number
'
,
data
:
'
number
'
,
onColumnClick
:
this
.
onColumnClick
onColumnClick
:
this
.
onColumnClick
,
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
<
div
className
=
'succeed-padding'
>
{
item
.
sequenceId
}
</
div
>
},
},
{
{
name
:
'
ID
'
,
name
:
'
ID
'
,
key
:
'
id
'
,
key
:
'
id
'
,
fieldName
:
'
id
'
,
fieldName
:
'
id
'
,
minWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
minWidth
:
5
0
,
maxWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
maxWidth
:
87
,
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
>
},
},
{
{
name
:
'
Duration
'
,
name
:
'
Duration
'
,
key
:
'
duration
'
,
key
:
'
duration
'
,
minWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
minWidth
:
6
5
,
maxWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
maxWidth
:
150
,
isResizable
:
true
,
isResizable
:
true
,
fieldName
:
'
duration
'
,
fieldName
:
'
duration
'
,
data
:
'
number
'
,
data
:
'
number
'
,
onColumnClick
:
this
.
onColumnClick
,
onColumnClick
:
this
.
onColumnClick
,
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
(
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
(
<
div
className
=
'durationsty'
>
<
div
className
=
'durationsty
succeed-padding
'
>
<
div
>
{
convertDuration
(
item
.
duration
)
}
</
div
>
<
div
>
{
convertDuration
(
item
.
duration
)
}
</
div
>
</
div
>
</
div
>
)
)
...
@@ -111,26 +112,24 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
...
@@ -111,26 +112,24 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
{
{
name
:
'
Status
'
,
name
:
'
Status
'
,
key
:
'
status
'
,
key
:
'
status
'
,
minWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
minWidth
:
80
,
maxWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
maxWidth
:
150
,
isResizable
:
true
,
isResizable
:
true
,
fieldName
:
'
status
'
,
fieldName
:
'
status
'
,
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
{
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
(
return
<
div
className
=
{
`
${
item
.
status
}
commonStyle`
}
>
{
item
.
status
}
</
div
>
;
<
div
className
=
{
`
${
item
.
status
}
commonStyle
succeed-padding
`
}
>
{
item
.
status
}
</
div
>
}
)
},
},
{
{
name
:
'
Default metric
'
,
name
:
'
Default metric
'
,
key
:
'
accuracy
'
,
key
:
'
accuracy
'
,
fieldName
:
'
accuracy
'
,
fieldName
:
'
accuracy
'
,
minWidth
:
(
window
.
innerWidth
*
0.333
-
200
)
/
5
,
minWidth
:
100
,
//
maxWidth:
(window.innerWidth * 0.333 - 150) / 5
,
maxWidth
:
160
,
isResizable
:
true
,
isResizable
:
true
,
data
:
'
number
'
,
data
:
'
number
'
,
onColumnClick
:
this
.
onColumnClick
,
onColumnClick
:
this
.
onColumnClick
,
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
{
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
<
DefaultMetric
trialId
=
{
item
.
id
}
/>
return
<
DefaultMetric
trialId
=
{
item
.
id
}
/>;
}
}
}
];
];
...
...
src/webui/src/components/public-child/DefaultMetric.tsx
View file @
92738382
...
@@ -13,7 +13,7 @@ class DefaultMetric extends React.Component<DefaultMetricProps, {}> {
...
@@ -13,7 +13,7 @@ class DefaultMetric extends React.Component<DefaultMetricProps, {}> {
render
():
React
.
ReactNode
{
render
():
React
.
ReactNode
{
const
accuracy
=
TRIALS
.
getTrial
(
this
.
props
.
trialId
).
accuracy
;
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
>;
}
}
}
}
...
...
src/webui/src/components/public-child/config/TrialConfigButton.tsx
View file @
92738382
...
@@ -18,8 +18,8 @@ export const TrialConfigButton = (): any => {
...
@@ -18,8 +18,8 @@ export const TrialConfigButton = (): any => {
return
(
return
(
<
React
.
Fragment
>
<
React
.
Fragment
>
<
Stack
className
=
'config'
>
<
Stack
className
=
'config'
>
<
DefaultButton
text
=
'Config'
onClick
=
{
showTrialConfigpPanel
}
/>
<
DefaultButton
text
=
'Search space'
onClick
=
{
showSearchSpacePanel
}
/>
<
DefaultButton
text
=
'Search space'
onClick
=
{
showSearchSpacePanel
}
/>
<
DefaultButton
text
=
'Config'
onClick
=
{
showTrialConfigpPanel
}
/>
</
Stack
>
</
Stack
>
{
isShowConfigPanel
&&
<
TrialConfigPanel
hideConfigPanel
=
{
hideConfigPanel
}
activeTab
=
{
activeTab
}
/>
}
{
isShowConfigPanel
&&
<
TrialConfigPanel
hideConfigPanel
=
{
hideConfigPanel
}
activeTab
=
{
activeTab
}
/>
}
</
React
.
Fragment
>
</
React
.
Fragment
>
...
...
src/webui/src/components/public-child/config/TrialConfigPanel.tsx
View file @
92738382
...
@@ -3,7 +3,8 @@ import { Stack, Panel, Pivot, PivotItem, PrimaryButton } from '@fluentui/react';
...
@@ -3,7 +3,8 @@ import { Stack, Panel, Pivot, PivotItem, PrimaryButton } from '@fluentui/react';
import
{
EXPERIMENT
}
from
'
../../../static/datamodel
'
;
import
{
EXPERIMENT
}
from
'
../../../static/datamodel
'
;
import
MonacoEditor
from
'
react-monaco-editor
'
;
import
MonacoEditor
from
'
react-monaco-editor
'
;
import
{
MONACO
}
from
'
../../../static/const
'
;
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
{
prettyStringify
}
from
'
../../../static/json_util
'
;
import
lodash
from
'
lodash
'
;
import
lodash
from
'
lodash
'
;
import
'
../../../static/style/logDrawer.scss
'
;
import
'
../../../static/style/logDrawer.scss
'
;
...
@@ -15,6 +16,7 @@ interface LogDrawerProps {
...
@@ -15,6 +16,7 @@ interface LogDrawerProps {
interface
LogDrawerState
{
interface
LogDrawerState
{
panelInnerHeight
:
number
;
panelInnerHeight
:
number
;
innerWidth
:
number
;
}
}
class
TrialConfigPanel
extends
React
.
Component
<
LogDrawerProps
,
LogDrawerState
>
{
class
TrialConfigPanel
extends
React
.
Component
<
LogDrawerProps
,
LogDrawerState
>
{
...
@@ -22,13 +24,15 @@ class TrialConfigPanel extends React.Component<LogDrawerProps, LogDrawerState> {
...
@@ -22,13 +24,15 @@ class TrialConfigPanel extends React.Component<LogDrawerProps, LogDrawerState> {
super
(
props
);
super
(
props
);
this
.
state
=
{
this
.
state
=
{
panelInnerHeight
:
window
.
innerHeight
panelInnerHeight
:
window
.
innerHeight
,
innerWidth
:
window
.
innerWidth
};
};
}
}
setLogDrawerHeight
():
void
{
// use arrow function for change window size met error: this.setState is not a function
this
.
setState
(()
=>
({
panelInnerHeight
:
window
.
innerHeight
}));
setLogDrawerHeight
=
():
void
=>
{
}
this
.
setState
(()
=>
({
panelInnerHeight
:
window
.
innerHeight
,
innerWidth
:
window
.
innerWidth
}));
};
async
componentDidMount
():
Promise
<
void
>
{
async
componentDidMount
():
Promise
<
void
>
{
window
.
addEventListener
(
'
resize
'
,
this
.
setLogDrawerHeight
);
window
.
addEventListener
(
'
resize
'
,
this
.
setLogDrawerHeight
);
...
@@ -40,7 +44,7 @@ class TrialConfigPanel extends React.Component<LogDrawerProps, LogDrawerState> {
...
@@ -40,7 +44,7 @@ class TrialConfigPanel extends React.Component<LogDrawerProps, LogDrawerState> {
render
():
React
.
ReactNode
{
render
():
React
.
ReactNode
{
const
{
hideConfigPanel
,
activeTab
}
=
this
.
props
;
const
{
hideConfigPanel
,
activeTab
}
=
this
.
props
;
const
{
panelInnerHeight
}
=
this
.
state
;
const
{
panelInnerHeight
,
innerWidth
}
=
this
.
state
;
// [marginTop 16px] + [Search space 46px] +
// [marginTop 16px] + [Search space 46px] +
// button[height: 32px, marginTop: 45px, marginBottom: 25px] + [padding-bottom: 20px]
// button[height: 32px, marginTop: 45px, marginBottom: 25px] + [padding-bottom: 20px]
const
monacoEditorHeight
=
panelInnerHeight
-
184
;
const
monacoEditorHeight
=
panelInnerHeight
-
184
;
...
@@ -58,7 +62,17 @@ class TrialConfigPanel extends React.Component<LogDrawerProps, LogDrawerState> {
...
@@ -58,7 +62,17 @@ class TrialConfigPanel extends React.Component<LogDrawerProps, LogDrawerState> {
};
};
const
profile
=
lodash
.
cloneDeep
(
EXPERIMENT
.
profile
);
const
profile
=
lodash
.
cloneDeep
(
EXPERIMENT
.
profile
);
profile
.
execDuration
=
convertDuration
(
profile
.
execDuration
);
profile
.
execDuration
=
convertDuration
(
profile
.
execDuration
);
profile
.
params
.
maxExecDuration
=
convertDuration
(
profile
.
params
.
maxExecDuration
);
const
prettyWidth
=
innerWidth
>
1400
?
100
:
60
;
return
(
<
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
);
const
showProfile
=
JSON
.
stringify
(
profile
,
filter
,
2
);
return
(
return
(
<
Stack
>
<
Stack
>
...
@@ -70,13 +84,16 @@ class TrialConfigPanel extends React.Component<LogDrawerProps, LogDrawerState> {
...
@@ -70,13 +84,16 @@ class TrialConfigPanel extends React.Component<LogDrawerProps, LogDrawerState> {
onLightDismissClick
=
{
hideConfigPanel
}
onLightDismissClick
=
{
hideConfigPanel
}
>
>
<
div
className
=
'log-tab-body'
>
<
div
className
=
'log-tab-body'
>
<
Pivot
initialSelectedKey
=
{
activeTab
}
style
=
{
{
minHeight
:
190
,
paddingTop
:
'
16px
'
}
}
>
<
Pivot
initialSelectedKey
=
{
activeTab
}
style
=
{
{
minHeight
:
190
,
paddingTop
:
'
16px
'
}
}
>
<
PivotItem
headerText
=
'Search space'
itemKey
=
'search space'
>
<
PivotItem
headerText
=
'Search space'
itemKey
=
'search space'
>
<
MonacoEditor
<
MonacoEditor
height
=
{
monacoEditorHeight
}
height
=
{
monacoEditorHeight
}
language
=
'json'
language
=
'json'
theme
=
'vs-light'
theme
=
'vs-light'
value
=
{
prettyStringify
(
EXPERIMENT
.
searchSpace
,
300
,
2
)
}
value
=
{
prettyStringify
(
EXPERIMENT
.
searchSpace
,
prettyWidth
,
2
)
}
options
=
{
MONACO
}
options
=
{
MONACO
}
/>
/>
</
PivotItem
>
</
PivotItem
>
...
@@ -98,6 +115,9 @@ class TrialConfigPanel extends React.Component<LogDrawerProps, LogDrawerState> {
...
@@ -98,6 +115,9 @@ class TrialConfigPanel extends React.Component<LogDrawerProps, LogDrawerState> {
</
Panel
>
</
Panel
>
</
Stack
>
</
Stack
>
);
);
}
}
</
AppContext
.
Consumer
>
);
}
}
}
}
...
...
src/webui/src/components/trial-detail/TableList.tsx
View file @
92738382
...
@@ -9,10 +9,12 @@ import {
...
@@ -9,10 +9,12 @@ import {
SelectionMode
,
SelectionMode
,
Stack
,
Stack
,
StackItem
,
StackItem
,
TooltipHost
TooltipHost
,
DirectionalHint
}
from
'
@fluentui/react
'
;
}
from
'
@fluentui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
EXPERIMENT
,
TRIALS
}
from
'
../../static/datamodel
'
;
import
{
EXPERIMENT
,
TRIALS
}
from
'
../../static/datamodel
'
;
import
{
TOOLTIP_BACKGROUND_COLOR
}
from
'
../../static/const
'
;
import
{
convertDuration
,
formatTimestamp
}
from
'
../../static/function
'
;
import
{
convertDuration
,
formatTimestamp
}
from
'
../../static/function
'
;
import
{
TableObj
}
from
'
../../static/interface
'
;
import
{
TableObj
}
from
'
../../static/interface
'
;
import
'
../../static/style/search.scss
'
;
import
'
../../static/style/search.scss
'
;
...
@@ -316,7 +318,19 @@ class TableList extends React.Component<TableListProps, TableListState> {
...
@@ -316,7 +318,19 @@ class TableList extends React.Component<TableListProps, TableListState> {
...((
k
.
startsWith
(
'
metric/
'
)
||
k
.
startsWith
(
'
space/
'
))
&&
{
...((
k
.
startsWith
(
'
metric/
'
)
||
k
.
startsWith
(
'
space/
'
))
&&
{
// show tooltip
// show tooltip
onRender
:
(
record
):
React
.
ReactNode
=>
(
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
>
<
div
className
=
'ellipsis'
>
{
record
[
k
]
}
</
div
>
</
TooltipHost
>
</
TooltipHost
>
)
)
...
@@ -324,7 +338,19 @@ class TableList extends React.Component<TableListProps, TableListState> {
...
@@ -324,7 +338,19 @@ class TableList extends React.Component<TableListProps, TableListState> {
...(
k
===
'
latestAccuracy
'
&&
{
...(
k
===
'
latestAccuracy
'
&&
{
// FIXME: this is ad-hoc
// FIXME: this is ad-hoc
onRender
:
(
record
):
React
.
ReactNode
=>
(
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
>
<
div
className
=
'ellipsis'
>
{
record
.
_formattedLatestAccuracy
}
</
div
>
</
TooltipHost
>
</
TooltipHost
>
)
)
...
...
src/webui/src/index.tsx
View file @
92738382
import
React
,
{
lazy
,
Suspense
}
from
'
react
'
;
import
React
,
{
lazy
,
Suspense
}
from
'
react
'
;
import
ReactDOM
from
'
react-dom
'
;
import
ReactDOM
from
'
react-dom
'
;
import
App
from
'
./App
'
;
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
Overview
=
lazy
(()
=>
import
(
'
./components/Overview
'
));
const
TrialsDetail
=
lazy
(()
=>
import
(
'
./components/TrialsDetail
'
));
const
TrialsDetail
=
lazy
(()
=>
import
(
'
./components/TrialsDetail
'
));
import
'
./index.css
'
;
import
'
./index.css
'
;
...
@@ -19,9 +19,9 @@ ReactDOM.render(
...
@@ -19,9 +19,9 @@ ReactDOM.render(
</
div
>
</
div
>
}
}
>
>
<
Route
path
=
'/'
component
=
{
Overview
}
exact
/>
<
Route
path
=
'/oview'
component
=
{
Overview
}
/>
<
Route
path
=
'/oview'
component
=
{
Overview
}
/>
<
Route
path
=
'/detail'
component
=
{
TrialsDetail
}
/>
<
Route
path
=
'/detail'
component
=
{
TrialsDetail
}
/>
<
Route
path
=
'/'
render
=
{
():
React
.
ReactNode
=>
<
Redirect
to
=
{
{
pathname
:
'
/oview
'
}
}
/>
}
/>
</
Suspense
>
</
Suspense
>
</
Switch
>
</
Switch
>
</
App
>
</
App
>
...
...
Prev
1
2
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