Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
nni
Commits
c7187946
Commit
c7187946
authored
Feb 10, 2020
by
Lijiao
Committed by
GitHub
Feb 10, 2020
Browse files
Use office-fabric-ui components (#1964)
parent
fdfff50d
Changes
90
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1226 additions
and
1050 deletions
+1226
-1050
src/webui/src/components/overview/BasicInfo.tsx
src/webui/src/components/overview/BasicInfo.tsx
+23
-11
src/webui/src/components/overview/Details.tsx
src/webui/src/components/overview/Details.tsx
+36
-0
src/webui/src/components/overview/NumInput.tsx
src/webui/src/components/overview/NumInput.tsx
+15
-24
src/webui/src/components/overview/Progress.tsx
src/webui/src/components/overview/Progress.tsx
+188
-87
src/webui/src/components/overview/ProgressItem.tsx
src/webui/src/components/overview/ProgressItem.tsx
+16
-22
src/webui/src/components/overview/SearchSpace.tsx
src/webui/src/components/overview/SearchSpace.tsx
+0
-1
src/webui/src/components/overview/SuccessTable.tsx
src/webui/src/components/overview/SuccessTable.tsx
+110
-61
src/webui/src/components/overview/Title1.tsx
src/webui/src/components/overview/Title1.tsx
+6
-7
src/webui/src/components/overview/TrialProfile.tsx
src/webui/src/components/overview/TrialProfile.tsx
+0
-1
src/webui/src/components/public-child/DefaultMetric.tsx
src/webui/src/components/public-child/DefaultMetric.tsx
+0
-0
src/webui/src/components/public-child/LogPath.tsx
src/webui/src/components/public-child/LogPath.tsx
+0
-48
src/webui/src/components/public-child/MonacoEditor.tsx
src/webui/src/components/public-child/MonacoEditor.tsx
+30
-16
src/webui/src/components/public-child/OpenRow.tsx
src/webui/src/components/public-child/OpenRow.tsx
+96
-111
src/webui/src/components/public-child/PaiTrialChild.tsx
src/webui/src/components/public-child/PaiTrialChild.tsx
+2
-3
src/webui/src/components/public-child/PaiTrialLog.tsx
src/webui/src/components/public-child/PaiTrialLog.tsx
+6
-7
src/webui/src/components/trial-detail/DefaultMetricPoint.tsx
src/webui/src/components/trial-detail/DefaultMetricPoint.tsx
+93
-93
src/webui/src/components/trial-detail/Duration.tsx
src/webui/src/components/trial-detail/Duration.tsx
+86
-17
src/webui/src/components/trial-detail/Intermediate.tsx
src/webui/src/components/trial-detail/Intermediate.tsx
+32
-74
src/webui/src/components/trial-detail/Para.tsx
src/webui/src/components/trial-detail/Para.tsx
+90
-103
src/webui/src/components/trial-detail/TableList.tsx
src/webui/src/components/trial-detail/TableList.tsx
+397
-364
No files found.
src/webui/src/components/overview/BasicInfo.tsx
View file @
c7187946
import
{
Col
,
Row
,
Tooltip
}
from
'
antd
'
;
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
{
Stack
,
TooltipHost
,
getId
}
from
'
office-ui-fabric-react
'
;
import
{
EXPERIMENT
}
from
'
../../static/datamodel
'
;
import
{
EXPERIMENT
}
from
'
../../static/datamodel
'
;
import
{
formatTimestamp
}
from
'
../../static/function
'
;
import
{
formatTimestamp
}
from
'
../../static/function
'
;
...
@@ -8,36 +8,48 @@ interface BasicInfoProps {
...
@@ -8,36 +8,48 @@ interface BasicInfoProps {
}
}
class
BasicInfo
extends
React
.
Component
<
BasicInfoProps
,
{}
>
{
class
BasicInfo
extends
React
.
Component
<
BasicInfoProps
,
{}
>
{
// Use getId() to ensure that the ID is unique on the page.
// (It's also okay to use a plain string without getId() and manually ensure uniqueness.)
// for tooltip user the log directory
private
_hostId
:
string
=
getId
(
'
tooltipHost
'
);
constructor
(
props
:
BasicInfoProps
)
{
constructor
(
props
:
BasicInfoProps
)
{
super
(
props
);
super
(
props
);
}
}
render
():
React
.
ReactNode
{
render
():
React
.
ReactNode
{
return
(
return
(
<
Row
className
=
"main"
>
<
Stack
horizontal
horizontalAlign
=
"space-between"
className
=
"main"
>
<
Col
span
=
{
8
}
className
=
"padItem basic"
>
<
Stack
.
Item
grow
=
{
3
}
className
=
"padItem basic"
>
<
p
>
Name
</
p
>
<
p
>
Name
</
p
>
<
div
>
{
EXPERIMENT
.
profile
.
params
.
experimentName
}
</
div
>
<
div
>
{
EXPERIMENT
.
profile
.
params
.
experimentName
}
</
div
>
<
p
>
ID
</
p
>
<
p
>
ID
</
p
>
<
div
>
{
EXPERIMENT
.
profile
.
id
}
</
div
>
<
div
>
{
EXPERIMENT
.
profile
.
id
}
</
div
>
</
Col
>
</
Stack
.
Item
>
<
Col
span
=
{
8
}
className
=
"padItem basic"
>
<
Stack
.
Item
grow
=
{
3
}
className
=
"padItem basic"
>
<
p
>
Start time
</
p
>
<
p
>
Start time
</
p
>
<
div
className
=
"nowrap"
>
{
formatTimestamp
(
EXPERIMENT
.
profile
.
startTime
)
}
</
div
>
<
div
className
=
"nowrap"
>
{
formatTimestamp
(
EXPERIMENT
.
profile
.
startTime
)
}
</
div
>
<
p
>
End time
</
p
>
<
p
>
End time
</
p
>
<
div
className
=
"nowrap"
>
{
formatTimestamp
(
EXPERIMENT
.
profile
.
endTime
)
}
</
div
>
<
div
className
=
"nowrap"
>
{
formatTimestamp
(
EXPERIMENT
.
profile
.
endTime
)
}
</
div
>
</
Col
>
</
Stack
.
Item
>
<
Col
span
=
{
8
}
className
=
"padItem basic"
>
<
Stack
.
Item
className
=
"padItem basic"
>
<
p
>
Log directory
</
p
>
<
p
>
Log directory
</
p
>
<
div
className
=
"nowrap"
>
<
div
className
=
"nowrap"
>
<
Tooltip
placement
=
"top"
title
=
{
EXPERIMENT
.
profile
.
logDir
||
''
}
>
<
TooltipHost
// Tooltip message content
content
=
{
EXPERIMENT
.
profile
.
logDir
||
'
unknown
'
}
id
=
{
this
.
_hostId
}
calloutProps
=
{
{
gapSpace
:
0
}
}
styles
=
{
{
root
:
{
display
:
'
inline-block
'
}
}
}
>
{
/* show logDir */
}
{
EXPERIMENT
.
profile
.
logDir
||
'
unknown
'
}
{
EXPERIMENT
.
profile
.
logDir
||
'
unknown
'
}
</
Tooltip
>
</
Tooltip
Host
>
</
div
>
</
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
>
</
Col
>
</
Stack
.
Item
>
</
Row
>
</
Stack
>
);
);
}
}
}
}
...
...
src/webui/src/components/overview/Details.tsx
0 → 100644
View file @
c7187946
import
*
as
React
from
'
react
'
;
import
{
DetailsRow
,
IDetailsRowBaseProps
}
from
'
office-ui-fabric-react
'
;
import
OpenRow
from
'
../public-child/OpenRow
'
;
interface
DetailsProps
{
detailsProps
:
IDetailsRowBaseProps
;
}
interface
DetailsState
{
isExpand
:
boolean
;
}
class
Details
extends
React
.
Component
<
DetailsProps
,
DetailsState
>
{
constructor
(
props
:
DetailsProps
)
{
super
(
props
);
this
.
state
=
{
isExpand
:
false
};
}
render
():
React
.
ReactNode
{
const
{
detailsProps
}
=
this
.
props
;
const
{
isExpand
}
=
this
.
state
;
return
(
<
div
>
<
div
onClick
=
{
():
void
=>
{
this
.
setState
(()
=>
({
isExpand
:
!
isExpand
}));
}
}
>
<
DetailsRow
{
...
detailsProps
}
/>
</
div
>
{
isExpand
&&
<
OpenRow
trialId
=
{
detailsProps
.
item
.
id
}
/>
}
</
div
>
);
}
}
export
default
Details
;
\ No newline at end of file
src/webui/src/components/overview/NumInput.tsx
View file @
c7187946
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
{
Button
,
Row
}
from
'
antd
'
;
import
{
Stack
,
Primary
Button
}
from
'
office-ui-fabric-react
'
;
interface
ConcurrencyInputProps
{
interface
ConcurrencyInputProps
{
value
:
number
;
value
:
number
;
...
@@ -36,47 +36,38 @@ class ConcurrencyInput extends React.Component<ConcurrencyInputProps, Concurrenc
...
@@ -36,47 +36,38 @@ class ConcurrencyInput extends React.Component<ConcurrencyInputProps, Concurrenc
render
():
React
.
ReactNode
{
render
():
React
.
ReactNode
{
if
(
this
.
state
.
editting
)
{
if
(
this
.
state
.
editting
)
{
return
(
return
(
<
Row
className
=
"inputBox"
>
<
Stack
horizontal
className
=
"inputBox"
>
<
input
<
input
type
=
"number"
type
=
"number"
className
=
"concurrencyInput"
className
=
"concurrencyInput"
defaultValue
=
{
this
.
props
.
value
.
toString
()
}
defaultValue
=
{
this
.
props
.
value
.
toString
()
}
ref
=
{
this
.
input
}
ref
=
{
this
.
input
}
/>
/>
<
Button
<
PrimaryButton
type
=
"primary"
text
=
"Save"
className
=
"tableButton editStyle"
onClick
=
{
this
.
save
}
onClick
=
{
this
.
save
}
>
/>
Save
<
PrimaryButton
</
Button
>
text
=
"Cancel"
<
Button
type
=
"primary"
onClick
=
{
this
.
cancel
}
style
=
{
{
display
:
'
inline-block
'
,
marginLeft
:
1
}
}
style
=
{
{
display
:
'
inline-block
'
,
marginLeft
:
1
}
}
className
=
"tableButton editStyle"
onClick
=
{
this
.
cancel
}
>
/>
Cancel
</
Stack
>
</
Button
>
</
Row
>
);
);
}
else
{
}
else
{
return
(
return
(
<
Row
className
=
"inputBox"
>
<
Stack
horizontal
className
=
"inputBox"
>
<
input
<
input
type
=
"number"
type
=
"number"
className
=
"concurrencyInput"
className
=
"concurrencyInput"
disabled
=
{
true
}
disabled
=
{
true
}
value
=
{
this
.
props
.
value
}
value
=
{
this
.
props
.
value
}
/>
/>
<
Button
<
PrimaryButton
type
=
"primary"
text
=
"Edit"
className
=
"tableButton editStyle"
onClick
=
{
this
.
edit
}
onClick
=
{
this
.
edit
}
>
/>
Edit
</
Stack
>
</
Button
>
</
Row
>
);
);
}
}
}
}
...
...
src/webui/src/components/overview/Progress.tsx
View file @
c7187946
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
{
Row
,
Col
,
Popover
,
message
}
from
'
antd
'
;
import
{
Stack
,
Callout
,
Link
,
IconButton
,
FontWeights
,
mergeStyleSets
,
getId
,
getTheme
,
StackItem
}
from
'
office-ui-fabric-react
'
;
import
axios
from
'
axios
'
;
import
axios
from
'
axios
'
;
import
{
MANAGER_IP
}
from
'
../../static/const
'
;
import
{
MANAGER_IP
}
from
'
../../static/const
'
;
import
{
EXPERIMENT
,
TRIALS
}
from
'
../../static/datamodel
'
;
import
{
EXPERIMENT
,
TRIALS
}
from
'
../../static/datamodel
'
;
import
{
convertTime
}
from
'
../../static/function
'
;
import
{
convertTime
}
from
'
../../static/function
'
;
import
ConcurrencyInput
from
'
./NumInput
'
;
import
ConcurrencyInput
from
'
./NumInput
'
;
import
ProgressBar
from
'
./ProgressItem
'
;
import
ProgressBar
from
'
./ProgressItem
'
;
import
LogDrawer
from
'
../Modal/LogDrawer
'
;
import
LogDrawer
from
'
../Modals/LogDrawer
'
;
import
MessageInfo
from
'
../Modals/MessageInfo
'
;
import
'
../../static/style/progress.scss
'
;
import
'
../../static/style/progress.scss
'
;
import
'
../../static/style/probar.scss
'
;
import
'
../../static/style/probar.scss
'
;
interface
ProgressProps
{
interface
ProgressProps
{
concurrency
:
number
;
concurrency
:
number
;
bestAccuracy
:
number
;
bestAccuracy
:
number
;
...
@@ -19,24 +19,106 @@ interface ProgressProps {
...
@@ -19,24 +19,106 @@ interface ProgressProps {
interface
ProgressState
{
interface
ProgressState
{
isShowLogDrawer
:
boolean
;
isShowLogDrawer
:
boolean
;
isCalloutVisible
?:
boolean
;
isShowSucceedInfo
:
boolean
;
info
:
string
;
typeInfo
:
string
;
}
}
const
itemStyles
:
React
.
CSSProperties
=
{
height
:
50
,
width
:
100
};
const
theme
=
getTheme
();
const
styles
=
mergeStyleSets
({
buttonArea
:
{
verticalAlign
:
'
top
'
,
display
:
'
inline-block
'
,
textAlign
:
'
center
'
,
// margin: '0 100px',
minWidth
:
30
,
height
:
30
},
callout
:
{
maxWidth
:
300
},
header
:
{
padding
:
'
18px 24px 12px
'
},
title
:
[
theme
.
fonts
.
xLarge
,
{
margin
:
0
,
color
:
theme
.
palette
.
neutralPrimary
,
fontWeight
:
FontWeights
.
semilight
}
],
inner
:
{
height
:
'
100%
'
,
padding
:
'
0 24px 20px
'
},
actions
:
{
position
:
'
relative
'
,
marginTop
:
20
,
width
:
'
100%
'
,
whiteSpace
:
'
nowrap
'
},
subtext
:
[
theme
.
fonts
.
small
,
{
margin
:
0
,
color
:
theme
.
palette
.
neutralPrimary
,
fontWeight
:
FontWeights
.
semilight
}
],
link
:
[
theme
.
fonts
.
medium
,
{
color
:
theme
.
palette
.
neutralPrimary
}
]
});
class
Progressed
extends
React
.
Component
<
ProgressProps
,
ProgressState
>
{
class
Progressed
extends
React
.
Component
<
ProgressProps
,
ProgressState
>
{
private
menuButtonElement
!
:
HTMLDivElement
|
null
;
private
labelId
:
string
=
getId
(
'
callout-label
'
);
private
descriptionId
:
string
=
getId
(
'
callout-description
'
);
constructor
(
props
:
ProgressProps
)
{
constructor
(
props
:
ProgressProps
)
{
super
(
props
);
super
(
props
);
this
.
state
=
{
this
.
state
=
{
isShowLogDrawer
:
false
isShowLogDrawer
:
false
,
isCalloutVisible
:
false
,
isShowSucceedInfo
:
false
,
info
:
''
,
typeInfo
:
'
success
'
};
};
}
}
hideSucceedInfo
=
():
void
=>
{
this
.
setState
(()
=>
({
isShowSucceedInfo
:
false
}));
}
/**
* info: message content
* typeInfo: message type: success | error...
* continuousTime: show time, 2000ms
*/
showMessageInfo
=
(
info
:
string
,
typeInfo
:
string
):
void
=>
{
this
.
setState
(()
=>
({
info
,
typeInfo
,
isShowSucceedInfo
:
true
}));
setTimeout
(
this
.
hideSucceedInfo
,
2000
);
}
editTrialConcurrency
=
async
(
userInput
:
string
):
Promise
<
void
>
=>
{
editTrialConcurrency
=
async
(
userInput
:
string
):
Promise
<
void
>
=>
{
if
(
!
userInput
.
match
(
/^
[
1-9
]\d
*$/
))
{
if
(
!
userInput
.
match
(
/^
[
1-9
]\d
*$/
))
{
message
.
error
(
'
Please enter a positive integer!
'
,
2
);
this
.
showMessageInfo
(
'
Please enter a positive integer!
'
,
'
error
'
);
return
;
return
;
}
}
const
newConcurrency
=
parseInt
(
userInput
,
10
);
const
newConcurrency
=
parseInt
(
userInput
,
10
);
if
(
newConcurrency
===
this
.
props
.
concurrency
)
{
if
(
newConcurrency
===
this
.
props
.
concurrency
)
{
m
essage
.
i
nfo
(
`
Trial concurrency has not changed
`
,
2
);
this
.
showM
essage
I
nfo
(
'
Trial concurrency has not changed
'
,
'
error
'
);
return
;
return
;
}
}
...
@@ -50,19 +132,19 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
...
@@ -50,19 +132,19 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
params
:
{
update_type
:
'
TRIAL_CONCURRENCY
'
}
params
:
{
update_type
:
'
TRIAL_CONCURRENCY
'
}
});
});
if
(
res
.
status
===
200
)
{
if
(
res
.
status
===
200
)
{
message
.
success
(
`
Successfully updated trial concurrency
`
);
this
.
showMessageInfo
(
'
Successfully updated trial concurrency
'
,
'
success
'
);
// NOTE: should we do this earlier in favor of poor networks?
// NOTE: should we do this earlier in favor of poor networks?
this
.
props
.
changeConcurrency
(
newConcurrency
);
this
.
props
.
changeConcurrency
(
newConcurrency
);
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
if
(
error
.
response
&&
error
.
response
.
data
.
error
)
{
if
(
error
.
response
&&
error
.
response
.
data
.
error
)
{
message
.
error
(
`Failed to update trial concurrency\n
${
error
.
response
.
data
.
error
}
`
);
this
.
showMessageInfo
(
`Failed to update trial concurrency\n
${
error
.
response
.
data
.
error
}
`
,
'
error
'
);
}
else
if
(
error
.
response
)
{
}
else
if
(
error
.
response
)
{
message
.
error
(
`Failed to update trial concurrency\nServer responsed
${
error
.
response
.
status
}
`
);
this
.
showMessageInfo
(
`Failed to update trial concurrency\nServer responsed
${
error
.
response
.
status
}
`
,
'
error
'
);
}
else
if
(
error
.
message
)
{
}
else
if
(
error
.
message
)
{
message
.
error
(
`Failed to update trial concurrency\n
${
error
.
message
}
`
);
this
.
showMessageInfo
(
`Failed to update trial concurrency\n
${
error
.
message
}
`
,
'
error
'
);
}
else
{
}
else
{
message
.
error
(
`Failed to update trial concurrency\nUnknown error`
);
this
.
showMessageInfo
(
`Failed to update trial concurrency\nUnknown error`
,
'
error
'
);
}
}
}
}
}
}
...
@@ -75,55 +157,79 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
...
@@ -75,55 +157,79 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
this
.
setState
({
isShowLogDrawer
:
false
});
this
.
setState
({
isShowLogDrawer
:
false
});
}
}
onDismiss
=
():
void
=>
{
this
.
setState
({
isCalloutVisible
:
false
});
}
onShow
=
():
void
=>
{
this
.
setState
({
isCalloutVisible
:
true
});
}
render
():
React
.
ReactNode
{
render
():
React
.
ReactNode
{
const
{
bestAccuracy
}
=
this
.
props
;
const
{
bestAccuracy
}
=
this
.
props
;
const
{
isShowLogDrawer
}
=
this
.
state
;
const
{
isShowLogDrawer
,
isCalloutVisible
,
isShowSucceedInfo
,
info
,
typeInfo
}
=
this
.
state
;
const
count
=
TRIALS
.
countStatus
();
const
count
=
TRIALS
.
countStatus
();
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
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
;
// support type [0, 1], not 98%
const
bar2Percent
=
(
bar2
/
EXPERIMENT
.
profile
.
params
.
maxTrialNum
)
*
100
;
const
bar2Percent
=
bar2
/
EXPERIMENT
.
profile
.
params
.
maxTrialNum
;
const
percent
=
(
EXPERIMENT
.
profile
.
execDuration
/
EXPERIMENT
.
profile
.
params
.
maxExecDuration
)
*
100
;
const
percent
=
EXPERIMENT
.
profile
.
execDuration
/
EXPERIMENT
.
profile
.
params
.
maxExecDuration
;
const
remaining
=
convertTime
(
EXPERIMENT
.
profile
.
params
.
maxExecDuration
-
EXPERIMENT
.
profile
.
execDuration
);
const
remaining
=
convertTime
(
EXPERIMENT
.
profile
.
params
.
maxExecDuration
-
EXPERIMENT
.
profile
.
execDuration
);
const
maxDuration
=
convertTime
(
EXPERIMENT
.
profile
.
params
.
maxExecDuration
);
const
maxDuration
=
convertTime
(
EXPERIMENT
.
profile
.
params
.
maxExecDuration
);
const
maxTrialNum
=
EXPERIMENT
.
profile
.
params
.
maxTrialNum
;
const
maxTrialNum
=
EXPERIMENT
.
profile
.
params
.
maxTrialNum
;
const
execDuration
=
convertTime
(
EXPERIMENT
.
profile
.
execDuration
);
const
execDuration
=
convertTime
(
EXPERIMENT
.
profile
.
execDuration
);
let
errorContent
;
if
(
EXPERIMENT
.
error
)
{
errorContent
=
(
<
div
className
=
"errors"
>
{
EXPERIMENT
.
error
}
<
div
><
a
href
=
"#"
onClick
=
{
this
.
isShowDrawer
}
>
Learn about
</
a
></
div
>
</
div
>
);
}
return
(
return
(
<
Row
className
=
"progress"
id
=
"barBack"
>
<
Stack
className
=
"progress"
id
=
"barBack"
>
<
Row
className
=
"basic lineBasic"
>
<
Stack
className
=
"basic lineBasic"
>
<
p
>
Status
</
p
>
<
p
>
Status
</
p
>
<
div
className
=
"status"
>
<
Stack
horizontal
className
=
"status"
>
<
span
className
=
{
EXPERIMENT
.
status
}
>
{
EXPERIMENT
.
status
}
</
span
>
<
span
className
=
{
`
${
EXPERIMENT
.
status
}
status-text`
}
>
{
EXPERIMENT
.
status
}
</
span
>
{
{
EXPERIMENT
.
status
===
'
ERROR
'
EXPERIMENT
.
status
===
'
ERROR
'
?
?
<
Popover
<
div
>
placement
=
"rightTop"
<
div
className
=
{
styles
.
buttonArea
}
ref
=
{
(
val
):
any
=>
this
.
menuButtonElement
=
val
}
>
content
=
{
errorContent
}
<
IconButton
title
=
"Error"
iconProps
=
{
{
iconName
:
'
info
'
}
}
trigger
=
"hover"
onClick
=
{
isCalloutVisible
?
this
.
onDismiss
:
this
.
onShow
}
>
/>
<
span
className
=
"errorBtn"
>
i
</
span
>
</
div
>
</
Popover
>
{
isCalloutVisible
&&
(
<
Callout
className
=
{
styles
.
callout
}
ariaLabelledBy
=
{
this
.
labelId
}
ariaDescribedBy
=
{
this
.
descriptionId
}
role
=
"alertdialog"
gapSpace
=
{
0
}
target
=
{
this
.
menuButtonElement
}
onDismiss
=
{
this
.
onDismiss
}
setInitialFocus
=
{
true
}
>
<
div
className
=
{
styles
.
header
}
>
<
p
className
=
{
styles
.
title
}
id
=
{
this
.
labelId
}
>
Error
</
p
>
</
div
>
<
div
className
=
{
styles
.
inner
}
>
<
p
className
=
{
styles
.
subtext
}
id
=
{
this
.
descriptionId
}
>
{
EXPERIMENT
.
error
}
</
p
>
<
div
className
=
{
styles
.
actions
}
>
<
Link
className
=
{
styles
.
link
}
onClick
=
{
this
.
isShowDrawer
}
>
Learn about
</
Link
>
</
div
>
</
div
>
</
Callout
>
)
}
</
div
>
:
:
<
span
/>
null
}
}
</
div
>
</
Stack
>
</
Row
>
</
Stack
>
<
ProgressBar
<
ProgressBar
who
=
"Duration"
who
=
"Duration"
percent
=
{
percent
}
percent
=
{
percent
}
...
@@ -138,55 +244,49 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
...
@@ -138,55 +244,49 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
bgclass
=
{
EXPERIMENT
.
status
}
bgclass
=
{
EXPERIMENT
.
status
}
maxString
=
{
`Max trial number:
${
maxTrialNum
}
`
}
maxString
=
{
`Max trial number:
${
maxTrialNum
}
`
}
/>
/>
<
Row
className
=
"basic colorOfbasic mess"
>
<
Stack
className
=
"basic colorOfbasic mess"
horizontal
>
<
p
>
Best metric
</
p
>
<
StackItem
grow
=
{
50
}
>
<
div
>
{
isNaN
(
bestAccuracy
)
?
'
N/A
'
:
bestAccuracy
.
toFixed
(
6
)
}
</
div
>
<
p
>
Best metric
</
p
>
</
Row
>
<
div
>
{
isNaN
(
bestAccuracy
)
?
'
N/A
'
:
bestAccuracy
.
toFixed
(
6
)
}
</
div
>
<
Row
className
=
"mess"
>
</
StackItem
>
<
Col
span
=
{
6
}
>
<
StackItem
>
<
Row
className
=
"basic colorOfbasic"
>
{
isShowSucceedInfo
&&
<
MessageInfo
className
=
"info"
typeInfo
=
{
typeInfo
}
info
=
{
info
}
/>
}
<
p
>
Spent
</
p
>
</
StackItem
>
<
div
>
{
execDuration
}
</
div
>
</
Stack
>
</
Row
>
<
Stack
horizontal
horizontalAlign
=
"space-between"
className
=
"mess"
>
</
Col
>
<
span
style
=
{
itemStyles
}
className
=
"basic colorOfbasic"
>
<
Col
span
=
{
6
}
>
<
p
>
Spent
</
p
>
<
Row
className
=
"basic colorOfbasic"
>
<
div
>
{
execDuration
}
</
div
>
<
p
>
Remaining
</
p
>
</
span
>
<
div
className
=
"time"
>
{
remaining
}
</
div
>
<
span
style
=
{
itemStyles
}
className
=
"basic colorOfbasic"
>
</
Row
>
<
p
>
Remaining
</
p
>
</
Col
>
<
div
className
=
"time"
>
{
remaining
}
</
div
>
<
Col
span
=
{
12
}
>
</
span
>
<
span
style
=
{
itemStyles
}
>
{
/* modify concurrency */
}
{
/* modify concurrency */
}
<
p
>
Concurrency
</
p
>
<
p
>
Concurrency
</
p
>
<
ConcurrencyInput
value
=
{
this
.
props
.
concurrency
}
updateValue
=
{
this
.
editTrialConcurrency
}
/>
<
ConcurrencyInput
value
=
{
this
.
props
.
concurrency
}
updateValue
=
{
this
.
editTrialConcurrency
}
/>
</
Col
>
</
span
>
</
Row
>
<
span
style
=
{
itemStyles
}
className
=
"basic colorOfbasic"
></
span
>
<
Row
className
=
"mess"
>
</
Stack
>
<
Col
span
=
{
6
}
>
<
Stack
horizontal
horizontalAlign
=
"space-between"
className
=
"mess"
>
<
Row
className
=
"basic colorOfbasic"
>
<
div
style
=
{
itemStyles
}
className
=
"basic colorOfbasic"
>
<
p
>
Running
</
p
>
<
p
>
Running
</
p
>
<
div
>
{
count
.
get
(
'
RUNNING
'
)
}
</
div
>
<
div
>
{
count
.
get
(
'
RUNNING
'
)
}
</
div
>
</
Row
>
</
div
>
</
Col
>
<
div
style
=
{
itemStyles
}
className
=
"basic colorOfbasic"
>
<
Col
span
=
{
6
}
>
<
p
>
Succeeded
</
p
>
<
Row
className
=
"basic colorOfbasic"
>
<
div
>
{
count
.
get
(
'
SUCCEEDED
'
)
}
</
div
>
<
p
>
Succeeded
</
p
>
</
div
>
<
div
>
{
count
.
get
(
'
SUCCEEDED
'
)
}
</
div
>
<
div
style
=
{
itemStyles
}
className
=
"basic"
>
</
Row
>
<
p
>
Stopped
</
p
>
</
Col
>
<
div
>
{
stoppedCount
}
</
div
>
<
Col
span
=
{
6
}
>
</
div
>
<
Row
className
=
"basic"
>
<
div
style
=
{
itemStyles
}
className
=
"basic"
>
<
p
>
Stopped
</
p
>
<
p
>
Failed
</
p
>
<
div
>
{
stoppedCount
}
</
div
>
<
div
>
{
count
.
get
(
'
FAILED
'
)
}
</
div
>
</
Row
>
</
div
>
</
Col
>
</
Stack
>
<
Col
span
=
{
6
}
>
<
Row
className
=
"basic"
>
<
p
>
Failed
</
p
>
<
div
>
{
count
.
get
(
'
FAILED
'
)
}
</
div
>
</
Row
>
</
Col
>
</
Row
>
{
/* learn about click -> default active key is dispatcher. */
}
{
/* learn about click -> default active key is dispatcher. */
}
{
isShowLogDrawer
?
(
{
isShowLogDrawer
?
(
<
LogDrawer
<
LogDrawer
...
@@ -194,9 +294,10 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
...
@@ -194,9 +294,10 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
activeTab
=
"dispatcher"
activeTab
=
"dispatcher"
/>
/>
)
:
null
}
)
:
null
}
</
Row
>
</
Stack
>
);
);
}
}
}
}
export
default
Progressed
;
export
default
Progressed
;
src/webui/src/components/overview/ProgressItem.tsx
View file @
c7187946
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
{
Row
,
Col
,
Progress
}
from
'
antd
'
;
import
{
Stack
,
StackItem
,
ProgressIndicator
}
from
'
office-ui-fabric-react
'
;
interface
ProItemProps
{
interface
ProItemProps
{
who
:
string
;
who
:
string
;
...
@@ -18,29 +18,23 @@ class ProgressBar extends React.Component<ProItemProps, {}> {
...
@@ -18,29 +18,23 @@ class ProgressBar extends React.Component<ProItemProps, {}> {
render
():
React
.
ReactNode
{
render
():
React
.
ReactNode
{
const
{
who
,
percent
,
description
,
maxString
,
bgclass
}
=
this
.
props
;
const
{
who
,
percent
,
description
,
maxString
,
bgclass
}
=
this
.
props
;
return
(
return
(
<
div
>
<
div
>
<
Row
className
=
{
`probar
${
bgclass
}
`
}
>
<
Stack
horizontal
className
=
{
`probar
${
bgclass
}
`
}
>
<
Col
span
=
{
8
}
>
<
div
className
=
"name"
>
{
who
}
</
div
>
<
div
className
=
"name"
>
{
who
}
</
div
>
<
div
className
=
"showProgress"
style
=
{
{
width
:
'
80%
'
}
}
>
</
Col
>
<
ProgressIndicator
<
Col
span
=
{
16
}
className
=
"bar"
>
barHeight
=
{
30
}
<
div
className
=
"showProgress"
>
percentComplete
=
{
percent
}
<
Progress
/>
percent
=
{
percent
}
<
Stack
horizontal
className
=
"boundary"
>
strokeWidth
=
{
30
}
<
StackItem
grow
=
{
30
}
>
0
</
StackItem
>
// strokeLinecap={'square'}
<
StackItem
className
=
"right"
grow
=
{
70
}
>
{
maxString
}
</
StackItem
>
format
=
{
():
string
=>
description
}
</
Stack
>
/>
</
div
>
</
div
>
<
div
className
=
"description"
style
=
{
{
width
:
'
20%
'
}
}
>
{
description
}
</
div
>
<
Row
className
=
"description"
>
</
Stack
>
<
Col
span
=
{
9
}
>
0
</
Col
>
<
br
/>
<
Col
className
=
"right"
span
=
{
15
}
>
{
maxString
}
</
Col
>
</
Row
>
</
Col
>
</
Row
>
<
br
/>
</
div
>
</
div
>
);
);
}
}
...
...
src/webui/src/components/overview/SearchSpace.tsx
View file @
c7187946
...
@@ -18,7 +18,6 @@ class SearchSpace extends React.Component<SearchspaceProps, {}> {
...
@@ -18,7 +18,6 @@ class SearchSpace extends React.Component<SearchspaceProps, {}> {
return
(
return
(
<
div
className
=
"searchSpace"
>
<
div
className
=
"searchSpace"
>
<
MonacoEditor
<
MonacoEditor
width
=
"100%"
height
=
"361"
height
=
"361"
language
=
"json"
language
=
"json"
theme
=
"vs-light"
theme
=
"vs-light"
...
...
src/webui/src/components/overview/SuccessTable.tsx
View file @
c7187946
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
{
Table
}
from
'
antd
'
;
import
{
DetailsList
,
IDetailsListProps
,
IColumn
}
from
'
office-ui-fabric-react
'
;
import
OpenRow
from
'
../public-child/OpenRow
'
;
import
DefaultMetric
from
'
../public-child/DefaultMetric
'
;
import
DefaultMetric
from
'
../public-child/DefaultMetrc
'
;
import
Details
from
'
./Details
'
;
import
{
TRIALS
}
from
'
../../static/datamodel
'
;
import
{
TableRecord
}
from
'
../../static/interface
'
;
import
{
convertDuration
}
from
'
../../static/function
'
;
import
{
convertDuration
}
from
'
../../static/function
'
;
import
'
../../static/style/tableStatus.css
'
;
import
{
TRIALS
}
from
'
../../static/datamodel
'
;
import
'
../../static/style/succTable.scss
'
;
import
'
../../static/style/openRow.scss
'
;
import
'
../../static/style/openRow.scss
'
;
interface
SuccessTableProps
{
interface
SuccessTableProps
{
trialIds
:
string
[];
trialIds
:
string
[];
}
}
function
openRow
(
record
:
TableRecord
):
any
{
interface
SuccessTableState
{
return
(
columns
:
IColumn
[];
<
OpenRow
trialId
=
{
record
.
id
}
/>
source
:
Array
<
any
>
;
);
}
}
class
SuccessTable
extends
React
.
Component
<
SuccessTableProps
,
{}
>
{
class
SuccessTable
extends
React
.
Component
<
SuccessTableProps
,
SuccessTableState
>
{
constructor
(
props
:
SuccessTableProps
)
{
constructor
(
props
:
SuccessTableProps
)
{
super
(
props
);
super
(
props
);
this
.
state
=
{
columns
:
this
.
columns
,
source
:
TRIALS
.
table
(
this
.
props
.
trialIds
)
};
}
}
render
():
React
.
ReactNode
{
private
onRenderRow
:
IDetailsListProps
[
'
onRenderRow
'
]
=
props
=>
{
const
columns
=
[
if
(
props
)
{
{
return
<
Details
detailsProps
=
{
props
}
/>;
title
:
'
Trial No.
'
,
}
dataIndex
:
'
sequenceId
'
,
return
null
;
className
:
'
tableHead
'
};
},
{
title
:
'
ID
'
,
onColumnClick
=
(
ev
:
React
.
MouseEvent
<
HTMLElement
>
,
getColumn
:
IColumn
):
void
=>
{
dataIndex
:
'
id
'
,
const
{
columns
,
source
}
=
this
.
state
;
width
:
80
,
const
newColumns
:
IColumn
[]
=
columns
.
slice
();
className
:
'
tableHead leftTitle
'
,
const
currColumn
:
IColumn
=
newColumns
.
filter
(
item
=>
getColumn
.
key
===
item
.
key
)[
0
];
render
:
(
text
:
string
,
record
:
TableRecord
):
React
.
ReactNode
=>
{
newColumns
.
forEach
((
newCol
:
IColumn
)
=>
{
return
(
if
(
newCol
===
currColumn
)
{
<
div
>
{
record
.
id
}
</
div
>
currColumn
.
isSortedDescending
=
!
currColumn
.
isSortedDescending
;
);
currColumn
.
isSorted
=
true
;
},
}
else
{
},
{
newCol
.
isSorted
=
false
;
title
:
'
Duration
'
,
newCol
.
isSortedDescending
=
true
;
dataIndex
:
'
duration
'
,
width
:
140
,
render
:
(
text
:
string
,
record
:
TableRecord
):
React
.
ReactNode
=>
{
return
(
<
div
className
=
"durationsty"
><
div
>
{
convertDuration
(
record
.
duration
)
}
</
div
></
div
>
);
},
},
{
title
:
'
Status
'
,
dataIndex
:
'
status
'
,
width
:
150
,
className
:
'
tableStatus
'
,
render
:
(
text
:
string
,
record
:
TableRecord
):
React
.
ReactNode
=>
{
return
(
<
div
className
=
{
`
${
record
.
status
}
commonStyle`
}
>
{
record
.
status
}
</
div
>
);
}
},
{
title
:
'
Default metric
'
,
dataIndex
:
'
accuracy
'
,
render
:
(
text
:
string
,
record
:
TableRecord
):
React
.
ReactNode
=>
{
return
(
<
DefaultMetric
trialId
=
{
record
.
id
}
/>
);
}
}
}
];
});
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const
newItems
=
this
.
copyAndSort
(
source
,
currColumn
.
fieldName
!
,
currColumn
.
isSortedDescending
);
this
.
setState
({
columns
:
newColumns
,
source
:
newItems
});
};
private
copyAndSort
<
T
>
(
items
:
T
[],
columnKey
:
string
,
isSortedDescending
?:
boolean
):
T
[]
{
const
key
=
columnKey
as
keyof
T
;
return
items
.
slice
(
0
).
sort
((
a
:
T
,
b
:
T
)
=>
((
isSortedDescending
?
a
[
key
]
<
b
[
key
]
:
a
[
key
]
>
b
[
key
])
?
1
:
-
1
));
}
columns
=
[
{
name
:
'
Trial No.
'
,
key
:
'
sequenceId
'
,
fieldName
:
'
sequenceId
'
,
// required!
minWidth
:
60
,
maxWidth
:
80
,
data
:
'
number
'
,
onColumnClick
:
this
.
onColumnClick
},
{
name
:
'
ID
'
,
key
:
'
id
'
,
fieldName
:
'
id
'
,
minWidth
:
80
,
maxWidth
:
150
,
className
:
'
tableHead leftTitle
'
,
data
:
'
string
'
,
onColumnClick
:
this
.
onColumnClick
},
{
name
:
'
Duration
'
,
key
:
'
duration
'
,
minWidth
:
100
,
maxWidth
:
150
,
fieldName
:
'
duration
'
,
data
:
'
number
'
,
onColumnClick
:
this
.
onColumnClick
,
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
{
return
(
<
div
className
=
"durationsty"
><
div
>
{
convertDuration
(
item
.
duration
)
}
</
div
></
div
>
);
},
},
{
name
:
'
Status
'
,
key
:
'
status
'
,
minWidth
:
100
,
maxWidth
:
150
,
fieldName
:
'
status
'
,
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
{
return
(
<
div
className
=
{
`
${
item
.
status
}
commonStyle`
}
>
{
item
.
status
}
</
div
>
);
}
},
{
name
:
'
Default metric
'
,
key
:
'
accuracy
'
,
fieldName
:
'
accuracy
'
,
minWidth
:
100
,
maxWidth
:
150
,
data
:
'
number
'
,
onColumnClick
:
this
.
onColumnClick
,
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
{
return
(
<
DefaultMetric
trialId
=
{
item
.
id
}
/>
);
}
}
];
render
():
React
.
ReactNode
{
const
{
columns
,
source
}
=
this
.
state
;
return
(
return
(
<
div
className
=
"tabScroll"
>
<
div
id
=
"succTable"
>
<
Table
{
/* TODO: [style] lineHeight question */
}
<
DetailsList
columns
=
{
columns
}
columns
=
{
columns
}
expandedRowRender
=
{
openRow
}
items
=
{
source
}
dataSource
=
{
TRIALS
.
table
(
this
.
props
.
trialIds
)
}
setKey
=
"set"
className
=
"commonTableStyle"
compact
=
{
true
}
pagination
=
{
false
}
onRenderRow
=
{
this
.
onRenderRow
}
selectionMode
=
{
0
}
// close selector function
/>
/>
</
div
>
</
div
>
);
);
...
...
src/webui/src/components/overview/Title1.tsx
View file @
c7187946
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
{
Stack
}
from
'
office-ui-fabric-react
'
;
import
'
../../static/style/overviewTitle.scss
'
;
interface
Title1Props
{
interface
Title1Props
{
text
:
string
;
text
:
string
;
icon
?:
string
;
icon
?:
string
;
...
@@ -15,12 +16,10 @@ class Title1 extends React.Component<Title1Props, {}> {
...
@@ -15,12 +16,10 @@ class Title1 extends React.Component<Title1Props, {}> {
render
():
React
.
ReactNode
{
render
():
React
.
ReactNode
{
const
{
text
,
icon
,
bgcolor
}
=
this
.
props
;
const
{
text
,
icon
,
bgcolor
}
=
this
.
props
;
return
(
return
(
<
div
>
<
Stack
horizontal
className
=
"panelTitle"
style
=
{
{
backgroundColor
:
bgcolor
}
}
>
<
div
className
=
"panelTitle"
style
=
{
{
backgroundColor
:
bgcolor
}
}
>
<
img
src
=
{
require
(
`../../static/img/icon/
${
icon
}
`
)
}
alt
=
"icon"
/>
<
img
src
=
{
require
(
`../../static/img/icon/
${
icon
}
`
)
}
alt
=
"icon"
/>
<
span
>
{
text
}
</
span
>
<
span
>
{
text
}
</
span
>
</
Stack
>
</
div
>
</
div
>
);
);
}
}
}
}
...
...
src/webui/src/components/overview/TrialProfile.tsx
View file @
c7187946
...
@@ -27,7 +27,6 @@ class TrialInfo extends React.Component<TrialInfoProps, {}> {
...
@@ -27,7 +27,6 @@ class TrialInfo extends React.Component<TrialInfoProps, {}> {
};
};
const
profile
=
JSON
.
stringify
(
EXPERIMENT
.
profile
,
filter
,
2
);
const
profile
=
JSON
.
stringify
(
EXPERIMENT
.
profile
,
filter
,
2
);
// FIXME: highlight not working?
return
(
return
(
<
div
className
=
"profile"
>
<
div
className
=
"profile"
>
<
MonacoEditor
<
MonacoEditor
...
...
src/webui/src/components/public-child/DefaultMetrc.tsx
→
src/webui/src/components/public-child/DefaultMetr
i
c.tsx
View file @
c7187946
File moved
src/webui/src/components/public-child/LogPath.tsx
deleted
100644 → 0
View file @
fdfff50d
import
*
as
React
from
'
react
'
;
import
LogPathChild
from
'
./LogPathChild
'
;
interface
LogpathProps
{
logStr
:
string
;
}
class
LogPath
extends
React
.
Component
<
LogpathProps
,
{}
>
{
constructor
(
props
:
LogpathProps
)
{
super
(
props
);
}
render
():
React
.
ReactNode
{
const
{
logStr
}
=
this
.
props
;
const
isTwopath
=
logStr
.
indexOf
(
'
,
'
)
!==
-
1
?
true
:
false
;
return
(
<
div
>
{
isTwopath
?
<
div
>
<
LogPathChild
eachLogpath
=
{
logStr
.
split
(
'
,
'
)[
0
]
}
logName
=
"LogPath:"
/>
<
LogPathChild
eachLogpath
=
{
logStr
.
split
(
'
,
'
)[
1
]
}
logName
=
"Log on HDFS:"
/>
</
div
>
:
<
LogPathChild
eachLogpath
=
{
logStr
}
logName
=
"Log path:"
/>
}
</
div
>
);
}
}
export
default
LogPath
;
\ No newline at end of file
src/webui/src/components/public-child/MonacoEditor.tsx
View file @
c7187946
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
{
Spin
}
from
'
antd
'
;
import
{
Spin
ner
}
from
'
office-ui-fabric-react
'
;
import
{
DRAWEROPTION
}
from
'
../../static/const
'
;
import
{
DRAWEROPTION
}
from
'
../../static/const
'
;
import
MonacoEditor
from
'
react-monaco-editor
'
;
import
MonacoEditor
from
'
react-monaco-editor
'
;
...
@@ -11,7 +11,7 @@ interface MonacoEditorProps {
...
@@ -11,7 +11,7 @@ interface MonacoEditorProps {
class
MonacoHTML
extends
React
.
Component
<
MonacoEditorProps
,
{}
>
{
class
MonacoHTML
extends
React
.
Component
<
MonacoEditorProps
,
{}
>
{
public
_isMonacoMount
:
boolean
;
public
_isMonacoMount
!
:
boolean
;
constructor
(
props
:
MonacoEditorProps
)
{
constructor
(
props
:
MonacoEditorProps
)
{
super
(
props
);
super
(
props
);
...
@@ -25,23 +25,37 @@ class MonacoHTML extends React.Component<MonacoEditorProps, {}> {
...
@@ -25,23 +25,37 @@ class MonacoHTML extends React.Component<MonacoEditorProps, {}> {
this
.
_isMonacoMount
=
false
;
this
.
_isMonacoMount
=
false
;
}
}
render
():
React
.
ReactNode
{
render
():
React
.
ReactNode
{
const
{
content
,
loading
,
height
}
=
this
.
props
;
const
{
content
,
loading
,
height
}
=
this
.
props
;
return
(
return
(
<
div
className
=
"just-for-log"
>
<
div
className
=
"just-for-log"
>
<
Spin
{
// tip="Loading..."
loading
style
=
{
{
width
:
'
100%
'
,
height
:
height
}
}
?
spinning
=
{
loading
}
<
Spinner
>
label
=
"Wait, wait..."
<
MonacoEditor
ariaLive
=
"assertive"
width
=
"100%"
labelPosition
=
"right"
height
=
{
height
}
styles
=
{
{
root
:
{
width
:
'
100%
'
,
height
:
height
}
}
}
language
=
"json"
>
value
=
{
content
}
<
MonacoEditor
options
=
{
DRAWEROPTION
}
width
=
"100%"
/>
height
=
{
height
}
</
Spin
>
language
=
"json"
value
=
{
content
}
options
=
{
DRAWEROPTION
}
/>
</
Spinner
>
:
<
MonacoEditor
width
=
"100%"
height
=
{
height
}
language
=
"json"
value
=
{
content
}
options
=
{
DRAWEROPTION
}
/>
}
</
div
>
</
div
>
);
);
}
}
...
...
src/webui/src/components/public-child/OpenRow.tsx
View file @
c7187946
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
*
as
copy
from
'
copy-to-clipboard
'
;
import
*
as
copy
from
'
copy-to-clipboard
'
;
import
PaiTrialLog
from
'
../public-child/PaiTrialLog
'
;
import
{
Stack
,
PrimaryButton
,
Pivot
,
PivotItem
}
from
'
office-ui-fabric-react
'
;
import
TrialLog
from
'
../public-child/TrialLog
'
;
import
{
EXPERIMENT
,
TRIALS
}
from
'
../../static/datamodel
'
;
import
{
Trial
}
from
'
../../static/model/trial
'
;
import
{
Trial
}
from
'
../../static/model/trial
'
;
import
{
Row
,
Tabs
,
Button
,
message
,
Modal
}
from
'
antd
'
;
import
{
EXPERIMENT
,
TRIALS
}
from
'
../../static/datamodel
'
;
import
{
MANAGER_IP
}
from
'
../../static/const
'
;
import
{
MANAGER_IP
}
from
'
../../static/const
'
;
import
JSONTree
from
'
react-json-tree
'
;
import
PaiTrialLog
from
'
../public-child/PaiTrialLog
'
;
import
TrialLog
from
'
../public-child/TrialLog
'
;
import
MessageInfo
from
'
../Modals/MessageInfo
'
;
import
'
../../static/style/overview.scss
'
;
import
'
../../static/style/overview.scss
'
;
import
'
../../static/style/copyParameter.scss
'
;
import
'
../../static/style/copyParameter.scss
'
;
import
JSONTree
from
'
react-json-tree
'
;
const
TabPane
=
Tabs
.
TabPane
;
interface
OpenRowProps
{
interface
OpenRowProps
{
trialId
:
string
;
trialId
:
string
;
}
}
interface
OpenRowState
{
interface
OpenRowState
{
isShowFormatModal
:
boolean
;
typeInfo
:
string
;
formatStr
:
string
;
info
:
string
;
isHidenInfo
:
boolean
;
}
}
class
OpenRow
extends
React
.
Component
<
OpenRowProps
,
OpenRowState
>
{
class
OpenRow
extends
React
.
Component
<
OpenRowProps
,
OpenRowState
>
{
...
@@ -25,127 +26,111 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
...
@@ -25,127 +26,111 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
constructor
(
props
:
OpenRowProps
)
{
constructor
(
props
:
OpenRowProps
)
{
super
(
props
);
super
(
props
);
this
.
state
=
{
this
.
state
=
{
isShowFormatModal
:
false
,
typeInfo
:
''
,
formatStr
:
''
info
:
''
,
isHidenInfo
:
true
};
};
}
}
showFormatModal
=
(
trial
:
Trial
):
void
=>
{
hideMessageInfo
=
():
void
=>
{
// get copy parameters
this
.
setState
(()
=>
({
isHidenInfo
:
true
}));
const
params
=
JSON
.
stringify
(
trial
.
info
.
hyperParameters
,
null
,
4
);
// open modal with format string
this
.
setState
({
isShowFormatModal
:
true
,
formatStr
:
params
});
}
}
hideFormatModal
=
():
void
=>
{
/**
// close modal, destroy state format string data
* info: message content
this
.
setState
({
isShowFormatModal
:
false
,
formatStr
:
''
});
* typeInfo: message type: success | error...
* continuousTime: show time, 2000ms
*/
getCopyStatus
=
(
info
:
string
,
typeInfo
:
string
):
void
=>
{
this
.
setState
(()
=>
({
info
,
typeInfo
,
isHidenInfo
:
false
}));
setTimeout
(
this
.
hideMessageInfo
,
2000
);
}
}
copyParams
=
():
void
=>
{
copyParams
=
(
trial
:
Trial
):
void
=>
{
// json format
// get copy parameters
const
{
formatStr
}
=
this
.
state
;
const
params
=
JSON
.
stringify
(
trial
.
description
.
parameters
,
null
,
4
);
if
(
copy
(
formatStr
))
{
if
(
copy
.
default
(
params
))
{
message
.
destroy
();
this
.
getCopyStatus
(
'
Success copy parameters to clipboard in form of python dict !
'
,
'
success
'
);
message
.
success
(
'
Success copy parameters to clipboard in form of python dict !
'
,
3
);
}
else
{
}
else
{
message
.
destroy
();
this
.
getCopyStatus
(
'
Failed !
'
,
'
error
'
);
message
.
error
(
'
Failed !
'
,
2
);
}
}
this
.
hideFormatModal
();
}
}
render
():
React
.
ReactNode
{
render
():
React
.
ReactNode
{
const
{
is
ShowFormatModal
,
formatStr
}
=
this
.
state
;
const
{
is
HidenInfo
,
typeInfo
,
info
}
=
this
.
state
;
const
trialId
=
this
.
props
.
trialId
;
const
trialId
=
this
.
props
.
trialId
;
const
trial
=
TRIALS
.
getTrial
(
trialId
);
const
trial
=
TRIALS
.
getTrial
(
trialId
);
const
trialLink
:
string
=
`
${
MANAGER_IP
}
/trial-jobs/
${
trialId
}
`
;
const
trialLink
:
string
=
`
${
MANAGER_IP
}
/trial-jobs/
${
trialId
}
`
;
const
logPathRow
=
trial
.
info
.
logPath
||
'
This trial
\'
s log path is not available.
'
;
const
logPathRow
=
trial
.
info
.
logPath
||
'
This trial
\'
s log path is not available.
'
;
const
multiProgress
=
trial
.
info
.
hyperParameters
===
undefined
?
0
:
trial
.
info
.
hyperParameters
.
length
;
const
multiProgress
=
trial
.
info
.
hyperParameters
===
undefined
?
0
:
trial
.
info
.
hyperParameters
.
length
;
return
(
return
(
<
Row
className
=
"openRowContent hyperpar"
>
<
Stack
className
=
"openRow"
>
<
Tabs
tabPosition
=
"left"
className
=
"card"
>
<
Stack
className
=
"openRowContent"
>
<
TabPane
tab
=
"Parameters"
key
=
"1"
>
<
Pivot
>
{
<
PivotItem
headerText
=
"Parameters"
key
=
"1"
itemIcon
=
"TestParameter"
>
EXPERIMENT
.
multiPhase
{
?
EXPERIMENT
.
multiPhase
<
Row
className
=
"link"
>
?
Trails for multiphase experiment will return a set of parameters,
<
Stack
className
=
"link"
>
we are listing the latest parameter in webportal.
{
<
br
/>
`
For the entire parameter set, please refer to the following
"
Trails for multiphase experiment will return a set of parameters,
<
a
we are listing the latest parameter in webportal.
href
=
{
trialLink
}
For the entire parameter set, please refer to the following "
rel
=
"noopener noreferrer"
`
target
=
"_blank"
}
style
=
{
{
marginLeft
:
2
}
}
<
a
href
=
{
trialLink
}
rel
=
"noopener noreferrer"
target
=
"_blank"
>
{
trialLink
}
</
a
>
{
`".`
}
>
<
div
>
Current Phase:
{
multiProgress
}
.
</
div
>
{
trialLink
}
</
Stack
>
</
a
>
"
:
<
br
/>
null
Current Phase:
{
multiProgress
}
.
}
</
Row
>
{
:
trial
.
info
.
hyperParameters
!==
undefined
<
div
/>
?
}
<
Stack
id
=
"description"
>
{
<
Stack
className
=
"bgHyper"
>
trial
.
info
.
hyperParameters
!==
undefined
<
JSONTree
?
hideRoot
=
{
true
}
<
Row
id
=
"description"
>
shouldExpandNode
=
{
():
boolean
=>
true
}
// default expandNode
<
Row
className
=
"bgHyper"
>
getItemString
=
{
():
null
=>
null
}
// remove the {} items
<
JSONTree
data
=
{
trial
.
description
.
parameters
}
hideRoot
=
{
true
}
/>
shouldExpandNode
=
{
():
boolean
=>
true
}
// default expandNode
</
Stack
>
getItemString
=
{
():
any
=>
(<
span
/>)
}
// remove the {} items
<
Stack
horizontal
className
=
"copy"
>
data
=
{
trial
.
description
.
parameters
}
<
PrimaryButton
/>
onClick
=
{
this
.
copyParams
.
bind
(
this
,
trial
)
}
</
Row
>
text
=
"Copy as json"
<
Row
className
=
"copy"
>
styles
=
{
{
root
:
{
width
:
128
,
marginRight
:
10
}
}
}
<
Button
/>
onClick
=
{
this
.
showFormatModal
.
bind
(
this
,
trial
)
}
{
/* copy success | failed message info */
}
>
{
!
isHidenInfo
&&
<
MessageInfo
typeInfo
=
{
typeInfo
}
info
=
{
info
}
/>
}
Copy as json
</
Stack
>
</
Button
>
</
Stack
>
</
Row
>
:
</
Row
>
<
Stack
className
=
"logpath"
>
:
<
span
className
=
"logName"
>
Error:
</
span
>
<
Row
className
=
"logpath"
>
<
span
className
=
"error"
>
{
`This trial's parameters are not available.'`
}
</
span
>
<
span
className
=
"logName"
style
=
{
{
marginRight
:
2
}
}
>
Error:
</
span
>
</
Stack
>
<
span
className
=
"error"
>
'
This trial
'
s parameters are not available.
'
</
span
>
}
</
Row
>
</
PivotItem
>
}
<
PivotItem
headerText
=
"Log"
key
=
"2"
itemIcon
=
"M365InvoicingLogo"
>
</
TabPane
>
{
<
TabPane
tab
=
"Log"
key
=
"2"
>
// FIXME: this should not be handled in web UI side
{
EXPERIMENT
.
trainingServicePlatform
!==
'
local
'
// FIXME: this should not be handled in web UI side
?
EXPERIMENT
.
trainingServicePlatform
!==
'
local
'
<
PaiTrialLog
?
logStr
=
{
logPathRow
}
<
PaiTrialLog
id
=
{
trialId
}
logStr
=
{
logPathRow
}
logCollection
=
{
EXPERIMENT
.
logCollectionEnabled
}
id
=
{
trialId
}
/>
logCollection
=
{
EXPERIMENT
.
logCollectionEnabled
}
:
/>
<
TrialLog
logStr
=
{
logPathRow
}
id
=
{
trialId
}
/>
:
}
<
TrialLog
logStr
=
{
logPathRow
}
id
=
{
trialId
}
/>
</
PivotItem
>
}
</
Pivot
>
</
TabPane
>
</
Stack
>
</
Tabs
>
</
Stack
>
<
Modal
title
=
"Format"
okText
=
"Copy"
centered
=
{
true
}
visible
=
{
isShowFormatModal
}
onCancel
=
{
this
.
hideFormatModal
}
maskClosable
=
{
false
}
// click mongolian layer don't close modal
onOk
=
{
this
.
copyParams
}
destroyOnClose
=
{
true
}
width
=
"60%"
className
=
"format"
>
{
/* write string in pre to show format string */
}
<
pre
className
=
"formatStr"
>
{
formatStr
}
</
pre
>
</
Modal
>
</
Row
>
);
);
}
}
}
}
...
...
src/webui/src/components/public-child/PaiTrialChild.tsx
View file @
c7187946
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
{
Row
}
from
'
antd
'
;
import
{
DOWNLOAD_IP
}
from
'
../../static/const
'
;
import
{
DOWNLOAD_IP
}
from
'
../../static/const
'
;
interface
PaiTrialChildProps
{
interface
PaiTrialChildProps
{
...
@@ -24,7 +23,7 @@ class PaiTrialChild extends React.Component<PaiTrialChildProps, {}> {
...
@@ -24,7 +23,7 @@ class PaiTrialChild extends React.Component<PaiTrialChildProps, {}> {
?
?
<
div
/>
<
div
/>
:
:
<
Row
>
<
div
>
{
{
logCollect
logCollect
?
?
...
@@ -39,7 +38,7 @@ class PaiTrialChild extends React.Component<PaiTrialChildProps, {}> {
...
@@ -39,7 +38,7 @@ class PaiTrialChild extends React.Component<PaiTrialChildProps, {}> {
:
:
<
span
>
trial stdout:
{
logString
}
</
span
>
<
span
>
trial stdout:
{
logString
}
</
span
>
}
}
</
Row
>
</
div
>
}
}
</
div
>
</
div
>
);
);
...
...
src/webui/src/components/public-child/PaiTrialLog.tsx
View file @
c7187946
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
{
Row
}
from
'
antd
'
;
import
{
DOWNLOAD_IP
}
from
'
../../static/const
'
;
import
{
DOWNLOAD_IP
}
from
'
../../static/const
'
;
import
PaiTrialChild
from
'
./PaiTrialChild
'
;
import
PaiTrialChild
from
'
./PaiTrialChild
'
;
import
LogPathChild
from
'
./LogPathChild
'
;
import
LogPathChild
from
'
./LogPathChild
'
;
...
@@ -30,11 +29,11 @@ class PaitrialLog extends React.Component<PaitrialLogProps, {}> {
...
@@ -30,11 +29,11 @@ class PaitrialLog extends React.Component<PaitrialLogProps, {}> {
{
{
isTwopath
isTwopath
?
?
<
Row
>
<
div
>
{
{
logCollection
logCollection
?
?
<
Row
>
<
div
>
<
a
<
a
target
=
"_blank"
target
=
"_blank"
rel
=
"noopener noreferrer"
rel
=
"noopener noreferrer"
...
@@ -44,9 +43,9 @@ class PaitrialLog extends React.Component<PaitrialLogProps, {}> {
...
@@ -44,9 +43,9 @@ class PaitrialLog extends React.Component<PaitrialLogProps, {}> {
Trial stdout
Trial stdout
</
a
>
</
a
>
<
a
target
=
"_blank"
rel
=
"noopener noreferrer"
href
=
{
logStr
.
split
(
'
,
'
)[
1
]
}
>
hdfsLog
</
a
>
<
a
target
=
"_blank"
rel
=
"noopener noreferrer"
href
=
{
logStr
.
split
(
'
,
'
)[
1
]
}
>
hdfsLog
</
a
>
</
Row
>
</
div
>
:
:
<
Row
>
<
div
>
<
LogPathChild
<
LogPathChild
eachLogpath
=
{
logStr
.
split
(
'
,
'
)[
0
]
}
eachLogpath
=
{
logStr
.
split
(
'
,
'
)[
0
]
}
logName
=
"Trial stdout:"
logName
=
"Trial stdout:"
...
@@ -55,9 +54,9 @@ class PaitrialLog extends React.Component<PaitrialLogProps, {}> {
...
@@ -55,9 +54,9 @@ class PaitrialLog extends React.Component<PaitrialLogProps, {}> {
eachLogpath
=
{
logStr
.
split
(
'
,
'
)[
1
]
}
eachLogpath
=
{
logStr
.
split
(
'
,
'
)[
1
]
}
logName
=
"Log on HDFS:"
logName
=
"Log on HDFS:"
/>
/>
</
Row
>
</
div
>
}
}
</
Row
>
</
div
>
:
:
<
PaiTrialChild
<
PaiTrialChild
logString
=
{
logStr
}
logString
=
{
logStr
}
...
...
src/webui/src/components/trial-detail/DefaultMetricPoint.tsx
View file @
c7187946
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
{
Switch
}
from
'
antd
'
;
import
{
Toggle
,
Stack
}
from
'
office-ui-fabric-react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
{
EXPERIMENT
,
TRIALS
}
from
'
../../static/datamodel
'
;
import
{
EXPERIMENT
,
TRIALS
}
from
'
../../static/datamodel
'
;
import
{
Trial
}
from
'
../../static/model/trial
'
;
import
{
Trial
}
from
'
../../static/model/trial
'
;
import
{
TooltipForAccuracy
,
EventMap
}
from
'
../../static/interface
'
;
import
{
TooltipForAccuracy
,
EventMap
}
from
'
../../static/interface
'
;
require
(
'
echarts/lib/chart/scatter
'
);
import
'
echarts/lib/chart/scatter
'
;
require
(
'
echarts/lib/component/tooltip
'
);
import
'
echarts/lib/component/tooltip
'
;
require
(
'
echarts/lib/component/title
'
);
import
'
echarts/lib/component/title
'
;
const
EmptyGraph
=
{
const
EmptyGraph
=
{
grid
:
{
grid
:
{
left
:
'
8%
'
left
:
'
8%
'
...
@@ -18,9 +19,9 @@ const EmptyGraph = {
...
@@ -18,9 +19,9 @@ const EmptyGraph = {
yAxis
:
{
yAxis
:
{
name
:
'
Default metric
'
,
name
:
'
Default metric
'
,
type
:
'
value
'
,
type
:
'
value
'
,
scale
:
true
,
}
}
};
};
interface
DefaultPointProps
{
interface
DefaultPointProps
{
trialIds
:
string
[];
trialIds
:
string
[];
visible
:
boolean
;
visible
:
boolean
;
...
@@ -28,7 +29,7 @@ interface DefaultPointProps {
...
@@ -28,7 +29,7 @@ interface DefaultPointProps {
}
}
interface
DefaultPointState
{
interface
DefaultPointState
{
bestCurveEnabled
:
boolean
;
bestCurveEnabled
?
:
boolean
|
undefined
;
startY
:
number
;
// dataZoomY
startY
:
number
;
// dataZoomY
endY
:
number
;
endY
:
number
;
}
}
...
@@ -39,11 +40,11 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
...
@@ -39,11 +40,11 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
this
.
state
=
{
this
.
state
=
{
bestCurveEnabled
:
false
,
bestCurveEnabled
:
false
,
startY
:
0
,
// dataZoomY
startY
:
0
,
// dataZoomY
endY
:
100
,
endY
:
100
};
};
}
}
loadDefault
=
(
checked
:
boolean
):
void
=>
{
loadDefault
=
(
ev
:
React
.
MouseEvent
<
HTMLElement
>
,
checked
?
:
boolean
):
void
=>
{
this
.
setState
({
bestCurveEnabled
:
checked
});
this
.
setState
({
bestCurveEnabled
:
checked
});
}
}
...
@@ -51,7 +52,59 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
...
@@ -51,7 +52,59 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
return
nextProps
.
visible
;
return
nextProps
.
visible
;
}
}
generateScatterSeries
=
(
trials
:
Trial
[]):
any
=>
{
metricDataZoom
=
(
e
:
EventMap
):
void
=>
{
if
(
e
.
batch
!==
undefined
)
{
this
.
setState
(()
=>
({
startY
:
(
e
.
batch
[
0
].
start
!==
null
?
e
.
batch
[
0
].
start
:
0
),
endY
:
(
e
.
batch
[
0
].
end
!==
null
?
e
.
batch
[
0
].
end
:
100
)
}));
}
}
generateGraphConfig
(
maxSequenceId
:
number
):
any
{
const
{
startY
,
endY
}
=
this
.
state
;
return
{
grid
:
{
left
:
'
8%
'
,
},
tooltip
:
{
trigger
:
'
item
'
,
enterable
:
true
,
position
:
(
point
:
number
[],
data
:
TooltipForAccuracy
):
number
[]
=>
(
[(
data
.
data
[
0
]
<
maxSequenceId
?
point
[
0
]
:
(
point
[
0
]
-
300
)),
80
]
),
formatter
:
(
data
:
TooltipForAccuracy
):
React
.
ReactNode
=>
(
'
<div class="tooldetailAccuracy">
'
+
'
<div>Trial No.:
'
+
data
.
data
[
0
]
+
'
</div>
'
+
'
<div>Default metric:
'
+
data
.
data
[
1
]
+
'
</div>
'
+
'
<div>Parameters: <pre>
'
+
JSON
.
stringify
(
data
.
data
[
2
],
null
,
4
)
+
'
</pre></div>
'
+
'
</div>
'
),
},
dataZoom
:
[
{
id
:
'
dataZoomY
'
,
type
:
'
inside
'
,
yAxisIndex
:
[
0
],
filterMode
:
'
empty
'
,
start
:
startY
,
end
:
endY
}
],
xAxis
:
{
name
:
'
Trial
'
,
type
:
'
category
'
,
},
yAxis
:
{
name
:
'
Default metric
'
,
type
:
'
value
'
,
scale
:
true
,
},
series
:
undefined
,
};
}
generateScatterSeries
(
trials
:
Trial
[]):
any
{
const
data
=
trials
.
map
(
trial
=>
[
const
data
=
trials
.
map
(
trial
=>
[
trial
.
sequenceId
,
trial
.
sequenceId
,
trial
.
accuracy
,
trial
.
accuracy
,
...
@@ -63,27 +116,24 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
...
@@ -63,27 +116,24 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
data
,
data
,
};
};
}
}
generateBestCurveSeries
=
(
trials
:
Trial
[]):
any
=>
{
generateBestCurveSeries
(
trials
:
Trial
[]):
any
{
let
best
=
trials
[
0
];
let
best
=
trials
[
0
];
const
data
=
[[
best
.
sequenceId
,
best
.
accuracy
,
best
.
description
.
parameters
]];
const
data
=
[[
best
.
sequenceId
,
best
.
accuracy
,
best
.
description
.
parameters
]];
for
(
let
i
=
1
;
i
<
trials
.
length
;
i
++
)
{
for
(
let
i
=
1
;
i
<
trials
.
length
;
i
++
)
{
const
trial
=
trials
[
i
];
const
trial
=
trials
[
i
];
if
(
trial
.
accuracy
!==
undefined
)
{
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if
(
best
.
accuracy
!==
undefined
)
{
const
delta
=
trial
.
accuracy
!
-
best
.
accuracy
!
;
const
delta
=
trial
.
accuracy
-
best
.
accuracy
;
const
better
=
(
EXPERIMENT
.
optimizeMode
===
'
minimize
'
)
?
(
delta
<
0
)
:
(
delta
>
0
);
const
better
=
(
EXPERIMENT
.
optimizeMode
===
'
minimize
'
)
?
(
delta
<
0
)
:
(
delta
>
0
);
if
(
better
)
{
if
(
better
)
{
data
.
push
([
trial
.
sequenceId
,
trial
.
accuracy
,
trial
.
description
.
parameters
]);
data
.
push
([
trial
.
sequenceId
,
trial
.
accuracy
,
trial
.
description
.
parameters
]);
best
=
trial
;
best
=
trial
;
}
else
{
}
else
{
data
.
push
([
trial
.
sequenceId
,
best
.
accuracy
,
trial
.
description
.
parameters
]);
data
.
push
([
trial
.
sequenceId
,
best
.
accuracy
,
trial
.
description
.
parameters
]);
}
}
}
}
}
}
return
{
return
{
type
:
'
line
'
,
type
:
'
line
'
,
lineStyle
:
{
color
:
'
#FF6600
'
},
lineStyle
:
{
color
:
'
#FF6600
'
},
...
@@ -98,24 +148,26 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
...
@@ -98,24 +148,26 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
return
(
return
(
<
div
>
<
div
>
<
div
className
=
"default-metric"
>
<
Stack
horizontalAlign
=
"end"
className
=
"default-metric"
>
<
div
className
=
"position"
>
<
Toggle
label
=
"Optimization curve"
<
span
className
=
"bold"
>
Optimization curve
</
span
>
inlineLabel
<
Switch
defaultChecked
=
{
false
}
onChange
=
{
this
.
loadDefault
}
/>
onChange
=
{
this
.
loadDefault
}
</
div
>
/>
</
Stack
>
<
div
className
=
"default-metric-graph"
>
<
ReactEcharts
option
=
{
graph
}
style
=
{
{
width
:
'
100%
'
,
height
:
402
,
margin
:
'
0 auto
'
,
}
}
theme
=
"my_theme"
notMerge
=
{
true
}
// update now
onEvents
=
{
onEvents
}
/>
<
div
className
=
"default-metric-noData"
>
{
accNodata
}
</
div
>
</
div
>
</
div
>
<
ReactEcharts
option
=
{
graph
}
style
=
{
{
width
:
'
100%
'
,
height
:
402
,
margin
:
'
0 auto
'
,
}
}
theme
=
"my_theme"
notMerge
=
{
true
}
// update now
onEvents
=
{
onEvents
}
/>
<
div
className
=
"showMess"
>
{
accNodata
}
</
div
>
</
div
>
</
div
>
);
);
}
}
...
@@ -133,58 +185,6 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
...
@@ -133,58 +185,6 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
}
}
return
graph
;
return
graph
;
}
}
private
generateGraphConfig
(
maxSequenceId
:
number
):
any
{
const
{
startY
,
endY
}
=
this
.
state
;
return
{
grid
:
{
left
:
'
8%
'
,
},
tooltip
:
{
trigger
:
'
item
'
,
enterable
:
true
,
position
:
(
point
:
number
[],
data
:
TooltipForAccuracy
):
number
[]
=>
(
[(
data
.
data
[
0
]
<
maxSequenceId
?
point
[
0
]
:
(
point
[
0
]
-
300
)),
80
]
),
formatter
:
(
data
:
TooltipForAccuracy
):
any
=>
(
'
<div class="tooldetailAccuracy">
'
+
'
<div>Trial No.:
'
+
data
.
data
[
0
]
+
'
</div>
'
+
'
<div>Default metric:
'
+
data
.
data
[
1
]
+
'
</div>
'
+
'
<div>Parameters: <pre>
'
+
JSON
.
stringify
(
data
.
data
[
2
],
null
,
4
)
+
'
</pre></div>
'
+
'
</div>
'
),
},
dataZoom
:
[
{
id
:
'
dataZoomY
'
,
type
:
'
inside
'
,
yAxisIndex
:
[
0
],
filterMode
:
'
empty
'
,
start
:
startY
,
end
:
endY
}
],
xAxis
:
{
name
:
'
Trial
'
,
type
:
'
category
'
,
},
yAxis
:
{
name
:
'
Default metric
'
,
type
:
'
value
'
,
scale
:
true
,
},
series
:
undefined
,
};
}
private
metricDataZoom
=
(
e
:
EventMap
):
void
=>
{
if
(
e
.
batch
!==
undefined
)
{
this
.
setState
(()
=>
({
startY
:
(
e
.
batch
[
0
].
start
!==
null
?
e
.
batch
[
0
].
start
:
0
),
endY
:
(
e
.
batch
[
0
].
end
!==
null
?
e
.
batch
[
0
].
end
:
100
)
}));
}
}
}
}
export
default
DefaultPoint
;
export
default
DefaultPoint
;
src/webui/src/components/trial-detail/Duration.tsx
View file @
c7187946
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
{
TableObj
,
EventMap
}
from
'
src
/static/interface
'
;
import
{
TableObj
,
EventMap
}
from
'
../..
/static/interface
'
;
// eslint-disable-line no-unused-vars
import
{
filterDuration
}
from
'
src
/static/function
'
;
import
{
filterDuration
}
from
'
../..
/static/function
'
;
require
(
'
echarts/lib/chart/bar
'
)
;
import
'
echarts/lib/chart/bar
'
;
require
(
'
echarts/lib/component/tooltip
'
)
;
import
'
echarts/lib/component/tooltip
'
;
require
(
'
echarts/lib/component/title
'
)
;
import
'
echarts/lib/component/title
'
;
interface
Runtrial
{
interface
Runtrial
{
trialId
:
Array
<
string
>
;
trialId
:
string
[]
;
trialTime
:
number
[];
trialTime
:
number
[];
}
}
...
@@ -19,6 +19,7 @@ interface DurationProps {
...
@@ -19,6 +19,7 @@ interface DurationProps {
interface
DurationState
{
interface
DurationState
{
startDuration
:
number
;
// for record data zoom
startDuration
:
number
;
// for record data zoom
endDuration
:
number
;
endDuration
:
number
;
durationSource
:
{};
}
}
class
Duration
extends
React
.
Component
<
DurationProps
,
DurationState
>
{
class
Duration
extends
React
.
Component
<
DurationProps
,
DurationState
>
{
...
@@ -29,6 +30,59 @@ class Duration extends React.Component<DurationProps, DurationState> {
...
@@ -29,6 +30,59 @@ class Duration extends React.Component<DurationProps, DurationState> {
this
.
state
=
{
this
.
state
=
{
startDuration
:
0
,
// for record data zoom
startDuration
:
0
,
// for record data zoom
endDuration
:
100
,
endDuration
:
100
,
durationSource
:
this
.
initDuration
(
this
.
props
.
source
),
};
}
initDuration
=
(
source
:
Array
<
TableObj
>
):
any
=>
{
const
trialId
:
number
[]
=
[];
const
trialTime
:
number
[]
=
[];
const
trialJobs
=
source
.
filter
(
filterDuration
);
trialJobs
.
forEach
(
item
=>
{
trialId
.
push
(
item
.
sequenceId
);
trialTime
.
push
(
item
.
duration
);
});
return
{
tooltip
:
{
trigger
:
'
axis
'
,
axisPointer
:
{
type
:
'
shadow
'
}
},
grid
:
{
bottom
:
'
3%
'
,
containLabel
:
true
,
left
:
'
1%
'
,
right
:
'
5%
'
},
dataZoom
:
[
{
id
:
'
dataZoomY
'
,
type
:
'
inside
'
,
yAxisIndex
:
[
0
],
filterMode
:
'
empty
'
,
start
:
0
,
end
:
100
},
],
xAxis
:
{
name
:
'
Time/s
'
,
type
:
'
value
'
,
},
yAxis
:
{
name
:
'
Trial No.
'
,
type
:
'
category
'
,
data
:
trialId
,
nameTextStyle
:
{
padding
:
[
0
,
0
,
0
,
30
]
}
},
series
:
[{
type
:
'
bar
'
,
data
:
trialTime
}]
};
};
}
}
...
@@ -45,7 +99,7 @@ class Duration extends React.Component<DurationProps, DurationState> {
...
@@ -45,7 +99,7 @@ class Duration extends React.Component<DurationProps, DurationState> {
bottom
:
'
3%
'
,
bottom
:
'
3%
'
,
containLabel
:
true
,
containLabel
:
true
,
left
:
'
1%
'
,
left
:
'
1%
'
,
right
:
'
4
%
'
right
:
'
5
%
'
},
},
dataZoom
:
[
dataZoom
:
[
{
{
...
@@ -64,7 +118,10 @@ class Duration extends React.Component<DurationProps, DurationState> {
...
@@ -64,7 +118,10 @@ class Duration extends React.Component<DurationProps, DurationState> {
yAxis
:
{
yAxis
:
{
name
:
'
Trial
'
,
name
:
'
Trial
'
,
type
:
'
category
'
,
type
:
'
category
'
,
data
:
dataObj
.
trialId
data
:
dataObj
.
trialId
,
nameTextStyle
:
{
padding
:
[
0
,
0
,
0
,
30
]
}
},
},
series
:
[{
series
:
[{
type
:
'
bar
'
,
type
:
'
bar
'
,
...
@@ -73,11 +130,11 @@ class Duration extends React.Component<DurationProps, DurationState> {
...
@@ -73,11 +130,11 @@ class Duration extends React.Component<DurationProps, DurationState> {
};
};
}
}
drawDurationGraph
=
(
source
:
Array
<
TableObj
>
):
any
=>
{
drawDurationGraph
=
(
source
:
Array
<
TableObj
>
):
void
=>
{
// why this function run two times when props changed?
// why this function run two times when props changed?
const
trialId
:
Array
<
string
>
=
[];
const
trialId
:
string
[]
=
[];
const
trialTime
:
number
[]
=
[];
const
trialTime
:
number
[]
=
[];
const
trialRun
:
Array
<
Runtrial
>
=
[];
const
trialRun
:
Runtrial
[]
=
[];
const
trialJobs
=
source
.
filter
(
filterDuration
);
const
trialJobs
=
source
.
filter
(
filterDuration
);
Object
.
keys
(
trialJobs
).
map
(
item
=>
{
Object
.
keys
(
trialJobs
).
map
(
item
=>
{
const
temp
=
trialJobs
[
item
];
const
temp
=
trialJobs
[
item
];
...
@@ -88,7 +145,21 @@ class Duration extends React.Component<DurationProps, DurationState> {
...
@@ -88,7 +145,21 @@ class Duration extends React.Component<DurationProps, DurationState> {
trialId
:
trialId
,
trialId
:
trialId
,
trialTime
:
trialTime
trialTime
:
trialTime
});
});
return
this
.
getOption
(
trialRun
[
0
]);
this
.
setState
({
durationSource
:
this
.
getOption
(
trialRun
[
0
])
});
}
componentDidMount
():
void
{
const
{
source
}
=
this
.
props
;
this
.
drawDurationGraph
(
source
);
}
componentWillReceiveProps
(
nextProps
:
DurationProps
):
void
{
const
{
whichGraph
,
source
}
=
nextProps
;
if
(
whichGraph
===
'
3
'
)
{
this
.
drawDurationGraph
(
source
);
}
}
}
shouldComponentUpdate
(
nextProps
:
DurationProps
):
boolean
{
shouldComponentUpdate
(
nextProps
:
DurationProps
):
boolean
{
...
@@ -117,15 +188,13 @@ class Duration extends React.Component<DurationProps, DurationState> {
...
@@ -117,15 +188,13 @@ class Duration extends React.Component<DurationProps, DurationState> {
}
}
render
():
React
.
ReactNode
{
render
():
React
.
ReactNode
{
const
{
durationSource
}
=
this
.
state
;
const
{
source
}
=
this
.
props
;
const
graph
=
this
.
drawDurationGraph
(
source
);
const
onEvents
=
{
'
dataZoom
'
:
this
.
durationDataZoom
};
const
onEvents
=
{
'
dataZoom
'
:
this
.
durationDataZoom
};
return
(
return
(
<
div
>
<
div
>
<
ReactEcharts
<
ReactEcharts
option
=
{
graph
}
option
=
{
durationSource
}
style
=
{
{
width
:
'
9
5
%
'
,
height
:
412
,
margin
:
'
0 auto
'
}
}
style
=
{
{
width
:
'
9
4
%
'
,
height
:
412
,
margin
:
'
0 auto
'
,
marginTop
:
15
}
}
theme
=
"my_theme"
theme
=
"my_theme"
notMerge
=
{
true
}
// update now
notMerge
=
{
true
}
// update now
onEvents
=
{
onEvents
}
onEvents
=
{
onEvents
}
...
...
src/webui/src/components/trial-detail/Intermediate.tsx
View file @
c7187946
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
{
Row
,
Button
,
Switch
}
from
'
antd
'
;
import
{
Stack
,
PrimaryButton
,
Toggle
,
IStackTokens
}
from
'
office-ui-fabric-react
'
;
import
{
TooltipForIntermediate
,
TableObj
,
Intermedia
,
EventMap
}
from
'
../../static/interface
'
;
import
{
TooltipForIntermediate
,
TableObj
,
Intermedia
,
EventMap
}
from
'
../../static/interface
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
require
(
'
echarts/lib/component/tooltip
'
);
import
'
echarts/lib/component/tooltip
'
;
require
(
'
echarts/lib/component/title
'
);
import
'
echarts/lib/component/title
'
;
const
stackTokens
:
IStackTokens
=
{
childrenGap
:
20
};
interface
IntermediateState
{
interface
IntermediateState
{
detailSource
:
Array
<
TableObj
>
;
detailSource
:
Array
<
TableObj
>
;
...
@@ -11,7 +15,7 @@ interface IntermediateState {
...
@@ -11,7 +15,7 @@ interface IntermediateState {
filterSource
:
Array
<
TableObj
>
;
filterSource
:
Array
<
TableObj
>
;
eachIntermediateNum
:
number
;
// trial's intermediate number count
eachIntermediateNum
:
number
;
// trial's intermediate number count
isLoadconfirmBtn
:
boolean
;
isLoadconfirmBtn
:
boolean
;
isFilter
:
boolean
;
isFilter
?
:
boolean
|
undefined
;
length
:
number
;
length
:
number
;
clickCounts
:
number
;
// user filter intermediate click confirm btn's counts
clickCounts
:
number
;
// user filter intermediate click confirm btn's counts
startMediaY
:
number
;
startMediaY
:
number
;
...
@@ -26,9 +30,9 @@ interface IntermediateProps {
...
@@ -26,9 +30,9 @@ interface IntermediateProps {
class
Intermediate
extends
React
.
Component
<
IntermediateProps
,
IntermediateState
>
{
class
Intermediate
extends
React
.
Component
<
IntermediateProps
,
IntermediateState
>
{
static
intervalMediate
=
1
;
static
intervalMediate
=
1
;
public
pointInput
:
HTMLInputElement
|
null
;
public
pointInput
!
:
HTMLInputElement
|
null
;
public
minValInput
:
HTMLInputElement
|
null
;
public
minValInput
!
:
HTMLInputElement
|
null
;
public
maxValInput
:
HTMLInputElement
|
null
;
public
maxValInput
!
:
HTMLInputElement
|
null
;
constructor
(
props
:
IntermediateProps
)
{
constructor
(
props
:
IntermediateProps
)
{
super
(
props
);
super
(
props
);
...
@@ -65,7 +69,7 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
...
@@ -65,7 +69,7 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
});
});
// find max intermediate number
// find max intermediate number
trialIntermediate
.
sort
((
a
,
b
)
=>
{
return
(
b
.
data
.
length
-
a
.
data
.
length
);
});
trialIntermediate
.
sort
((
a
,
b
)
=>
{
return
(
b
.
data
.
length
-
a
.
data
.
length
);
});
const
legend
:
Array
<
string
>
=
[];
const
legend
:
string
[]
=
[];
// max length
// max length
const
length
=
trialIntermediate
[
0
].
data
.
length
;
const
length
=
trialIntermediate
[
0
].
data
.
length
;
const
xAxis
:
number
[]
=
[];
const
xAxis
:
number
[]
=
[];
...
@@ -87,7 +91,7 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
...
@@ -87,7 +91,7 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
return
[
point
[
0
]
-
300
,
80
];
return
[
point
[
0
]
-
300
,
80
];
}
}
},
},
formatter
:
function
(
data
:
TooltipForIntermediate
):
any
{
formatter
:
function
(
data
:
TooltipForIntermediate
):
React
.
ReactNode
{
const
trialId
=
data
.
seriesName
;
const
trialId
=
data
.
seriesName
;
let
obj
=
{};
let
obj
=
{};
const
temp
=
trialIntermediate
.
find
(
key
=>
key
.
name
===
trialId
);
const
temp
=
trialIntermediate
.
find
(
key
=>
key
.
name
===
trialId
);
...
@@ -116,7 +120,8 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
...
@@ -116,7 +120,8 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
},
},
yAxis
:
{
yAxis
:
{
type
:
'
value
'
,
type
:
'
value
'
,
name
:
'
Metric
'
name
:
'
Metric
'
,
scale
:
true
,
},
},
dataZoom
:
[
dataZoom
:
[
{
{
...
@@ -195,7 +200,7 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
...
@@ -195,7 +200,7 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
});
});
}
}
switchTurn
=
(
checked
:
boolean
):
void
=>
{
switchTurn
=
(
ev
:
React
.
MouseEvent
<
HTMLElement
>
,
checked
?
:
boolean
):
void
=>
{
this
.
setState
({
isFilter
:
checked
});
this
.
setState
({
isFilter
:
checked
});
if
(
checked
===
false
)
{
if
(
checked
===
false
)
{
this
.
drawIntermediate
(
this
.
props
.
source
);
this
.
drawIntermediate
(
this
.
props
.
source
);
...
@@ -226,62 +231,18 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
...
@@ -226,62 +231,18 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
}
}
}
}
shouldComponentUpdate
(
nextProps
:
IntermediateProps
,
nextState
:
IntermediateState
):
boolean
{
const
{
whichGraph
,
source
}
=
nextProps
;
const
beforeGraph
=
this
.
props
.
whichGraph
;
if
(
whichGraph
===
'
4
'
)
{
const
{
isFilter
,
length
,
clickCounts
}
=
nextState
;
const
beforeLength
=
this
.
state
.
length
;
const
beforeSource
=
this
.
props
.
source
;
const
beforeClickCounts
=
this
.
state
.
clickCounts
;
if
(
isFilter
!==
this
.
state
.
isFilter
)
{
return
true
;
}
if
(
clickCounts
!==
beforeClickCounts
)
{
return
true
;
}
if
(
isFilter
===
false
)
{
if
(
whichGraph
!==
beforeGraph
)
{
return
true
;
}
if
(
length
!==
beforeLength
)
{
return
true
;
}
if
(
beforeSource
.
length
!==
source
.
length
)
{
return
true
;
}
if
(
beforeSource
[
beforeSource
.
length
-
1
]
!==
undefined
)
{
if
(
source
[
source
.
length
-
1
].
description
.
intermediate
.
length
!==
beforeSource
[
beforeSource
.
length
-
1
].
description
.
intermediate
.
length
)
{
return
true
;
}
if
(
source
[
source
.
length
-
1
].
duration
!==
beforeSource
[
beforeSource
.
length
-
1
].
duration
)
{
return
true
;
}
if
(
source
[
source
.
length
-
1
].
status
!==
beforeSource
[
beforeSource
.
length
-
1
].
status
)
{
return
true
;
}
}
}
}
return
false
;
}
render
():
React
.
ReactNode
{
render
():
React
.
ReactNode
{
const
{
interSource
,
isLoadconfirmBtn
,
isFilter
}
=
this
.
state
;
const
{
interSource
,
isLoadconfirmBtn
,
isFilter
}
=
this
.
state
;
const
IntermediateEvents
=
{
'
dataZoom
'
:
this
.
intermediateDataZoom
};
const
IntermediateEvents
=
{
'
dataZoom
'
:
this
.
intermediateDataZoom
};
return
(
return
(
<
div
>
<
div
>
{
/* style in para.scss */
}
{
/* style in para.scss */
}
<
Row
className
=
"meline intermediate"
>
<
Stack
horizontal
horizontalAlign
=
"end"
tokens
=
{
stackTokens
}
className
=
"meline intermediate"
>
{
{
isFilter
isFilter
?
?
<
span
style
=
{
{
marginRight
:
15
}
}
>
<
div
>
<
span
className
=
"filter-x"
>
# Intermediate result
</
span
>
<
span
className
=
"filter-x"
>
# Intermediate result
</
span
>
<
input
<
input
// placeholder="point"
// placeholder="point"
...
@@ -298,34 +259,31 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
...
@@ -298,34 +259,31 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
// placeholder="range"
// placeholder="range"
ref
=
{
(
input
):
any
=>
this
.
maxValInput
=
input
}
ref
=
{
(
input
):
any
=>
this
.
maxValInput
=
input
}
/>
/>
<
Button
<
PrimaryButton
type
=
"primary"
text
=
"Confirm"
className
=
"changeBtu tableButton"
onClick
=
{
this
.
filterLines
}
onClick
=
{
this
.
filterLines
}
disabled
=
{
isLoadconfirmBtn
}
disabled
=
{
isLoadconfirmBtn
}
>
/>
Confirm
</
div
>
</
Button
>
</
span
>
:
:
null
null
}
}
{
/* filter message */
}
{
/* filter message */
}
<
span
>
Filter
</
span
>
<
Stack
horizontal
className
=
"filter-toggle"
>
<
Switch
<
span
>
Filter
</
span
>
defaultChecked
=
{
false
}
<
Toggle
onChange
=
{
this
.
switchTurn
}
/>
onChange
=
{
this
.
switchTurn
}
</
Stack
>
/>
</
Row
>
</
Stack
>
<
Row
className
=
"intermediate-graph"
>
<
div
className
=
"intermediate-graph"
>
<
ReactEcharts
<
ReactEcharts
option
=
{
interSource
}
option
=
{
interSource
}
style
=
{
{
width
:
'
100%
'
,
height
:
4
18
,
margin
:
'
0 auto
'
}
}
style
=
{
{
width
:
'
100%
'
,
height
:
4
00
,
margin
:
'
0 auto
'
}
}
notMerge
=
{
true
}
// update now
notMerge
=
{
true
}
// update now
onEvents
=
{
IntermediateEvents
}
onEvents
=
{
IntermediateEvents
}
/>
/>
<
div
className
=
"yAxis"
>
# Intermediate result
</
div
>
<
div
className
=
"yAxis"
>
# Intermediate result
</
div
>
</
Row
>
</
div
>
</
div
>
</
div
>
);
);
}
}
...
...
src/webui/src/components/trial-detail/Para.tsx
View file @
c7187946
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
{
filterByStatus
}
from
'
../../static/function
'
;
import
{
filterByStatus
}
from
'
../../static/function
'
;
import
{
Row
,
Col
,
Select
,
Button
,
message
}
from
'
antd
'
;
import
{
Stack
,
PrimaryButton
,
Dropdown
,
IDropdownOption
,
}
from
'
office-ui-fabric-react
'
;
// eslint-disable-line no-unused-vars
import
{
ParaObj
,
Dimobj
,
TableObj
}
from
'
../../static/interface
'
;
import
{
ParaObj
,
Dimobj
,
TableObj
}
from
'
../../static/interface
'
;
// eslint-disable-line no-unused-vars
const
Option
=
Select
.
Option
;
import
'
echarts/lib/chart/parallel
'
;
require
(
'
echarts/lib/chart/parallel
'
);
import
'
echarts/lib/component/tooltip
'
;
require
(
'
echarts/lib/component/tooltip
'
);
import
'
echarts/lib/component/title
'
;
require
(
'
echarts/lib/component/title
'
);
import
'
echarts/lib/component/visualMap
'
;
require
(
'
echarts/lib/component/visualMap
'
);
import
'
../../static/style/para.scss
'
;
require
(
'
../../static/style/para.scss
'
);
import
'
../../static/style/button.scss
'
;
require
(
'
../../static/style/button.scss
'
);
interface
ParaState
{
interface
ParaState
{
// paraSource: Array<TableObj>;
// paraSource: Array<TableObj>;
option
:
object
;
option
:
object
;
paraBack
:
ParaObj
;
paraBack
:
ParaObj
;
dimName
:
Array
<
string
>
;
dimName
:
string
[]
;
swapAxisArr
:
Array
<
string
>
;
swapAxisArr
:
string
[]
;
percent
:
number
;
percent
:
number
;
paraNodata
:
string
;
paraNodata
:
string
;
max
:
number
;
// graph color bar limit
max
:
number
;
// graph color bar limit
...
@@ -25,6 +24,9 @@ interface ParaState {
...
@@ -25,6 +24,9 @@ interface ParaState {
succeedRenderCount
:
number
;
// all succeed trials number
succeedRenderCount
:
number
;
// all succeed trials number
clickCounts
:
number
;
clickCounts
:
number
;
isLoadConfirm
:
boolean
;
isLoadConfirm
:
boolean
;
// office-fabric-ui
selectedItem
?:
{
key
:
string
|
number
|
undefined
};
// percent Selector
swapyAxis
?:
string
[];
// yAxis Selector
}
}
interface
ParaProps
{
interface
ParaProps
{
...
@@ -33,11 +35,6 @@ interface ParaProps {
...
@@ -33,11 +35,6 @@ interface ParaProps {
whichGraph
:
string
;
whichGraph
:
string
;
}
}
message
.
config
({
top
:
250
,
duration
:
2
,
});
class
Para
extends
React
.
Component
<
ParaProps
,
ParaState
>
{
class
Para
extends
React
.
Component
<
ParaProps
,
ParaState
>
{
private
chartMulineStyle
=
{
private
chartMulineStyle
=
{
...
@@ -69,14 +66,15 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -69,14 +66,15 @@ class Para extends React.Component<ParaProps, ParaState> {
sutrialCount
:
10000000
,
sutrialCount
:
10000000
,
succeedRenderCount
:
10000000
,
succeedRenderCount
:
10000000
,
clickCounts
:
1
,
clickCounts
:
1
,
isLoadConfirm
:
false
isLoadConfirm
:
false
,
swapyAxis
:
[]
};
};
}
}
getParallelAxis
=
getParallelAxis
=
(
(
dimName
:
Array
<
string
>
,
parallelAxis
:
Array
<
Dimobj
>
,
dimName
:
string
[]
,
parallelAxis
:
Array
<
Dimobj
>
,
accPara
:
number
[],
eachTrialParams
:
Array
<
string
>
,
accPara
:
number
[],
eachTrialParams
:
string
[]
,
lengthofTrials
:
number
lengthofTrials
:
number
):
void
=>
{
):
void
=>
{
// get data for every lines. if dim is choice type, number -> toString()
// get data for every lines. if dim is choice type, number -> toString()
...
@@ -128,7 +126,7 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -128,7 +126,7 @@ class Para extends React.Component<ParaProps, ParaState> {
const
lenOfDataSource
:
number
=
dataSource
.
length
;
const
lenOfDataSource
:
number
=
dataSource
.
length
;
const
accPara
:
number
[]
=
[];
const
accPara
:
number
[]
=
[];
// specific value array
// specific value array
const
eachTrialParams
:
Array
<
string
>
=
[];
const
eachTrialParams
:
string
[]
=
[];
// experiment interface search space obj
// experiment interface search space obj
const
searchRange
=
searchSpace
!==
undefined
?
JSON
.
parse
(
searchSpace
)
:
''
;
const
searchRange
=
searchSpace
!==
undefined
?
JSON
.
parse
(
searchSpace
)
:
''
;
// nest search space
// nest search space
...
@@ -147,8 +145,8 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -147,8 +145,8 @@ class Para extends React.Component<ParaProps, ParaState> {
let
i
=
0
;
let
i
=
0
;
if
(
isNested
===
false
)
{
if
(
isNested
===
false
)
{
for
(
i
;
i
<
dimName
.
length
;
i
++
)
{
for
(
i
;
i
<
dimName
.
length
;
i
++
)
{
const
data
:
string
[]
=
[];
const
searchKey
=
searchRange
[
dimName
[
i
]];
const
searchKey
=
searchRange
[
dimName
[
i
]];
const
data
:
Array
<
string
>
=
[];
switch
(
searchKey
.
_type
)
{
switch
(
searchKey
.
_type
)
{
case
'
uniform
'
:
case
'
uniform
'
:
case
'
quniform
'
:
case
'
quniform
'
:
...
@@ -220,10 +218,11 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -220,10 +218,11 @@ class Para extends React.Component<ParaProps, ParaState> {
}
else
{
}
else
{
for
(
i
;
i
<
dimName
.
length
;
i
++
)
{
for
(
i
;
i
<
dimName
.
length
;
i
++
)
{
const
searchKey
=
searchRange
[
dimName
[
i
]];
const
searchKey
=
searchRange
[
dimName
[
i
]];
const
data
:
Array
<
string
>
=
[];
const
data
:
string
[]
=
[];
let
j
=
0
;
switch
(
searchKey
.
_type
)
{
switch
(
searchKey
.
_type
)
{
case
'
choice
'
:
case
'
choice
'
:
for
(
let
j
=
0
;
j
<
searchKey
.
_value
.
length
;
j
++
)
{
for
(
j
;
j
<
searchKey
.
_value
.
length
;
j
++
)
{
const
item
=
searchKey
.
_value
[
j
];
const
item
=
searchKey
.
_value
[
j
];
Object
.
keys
(
item
).
map
(
key
=>
{
Object
.
keys
(
item
).
map
(
key
=>
{
if
(
key
!==
'
_name
'
&&
key
!==
'
_type
'
)
{
if
(
key
!==
'
_name
'
&&
key
!==
'
_type
'
)
{
...
@@ -362,10 +361,15 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -362,10 +361,15 @@ class Para extends React.Component<ParaProps, ParaState> {
}
}
// get percent value number
// get percent value number
percentNum
=
(
value
:
string
):
void
=>
{
// percentNum = (value: string) => {
percentNum
=
(
event
:
React
.
FormEvent
<
HTMLDivElement
>
,
item
?:
IDropdownOption
):
void
=>
{
const
vals
=
parseFloat
(
value
);
// percentNum = (event: React.FormEvent<HTMLDivElement>, item?: ISelectableOption) => {
this
.
setState
({
percent
:
vals
},
()
=>
{
this
.
reInit
();
});
if
(
item
!==
undefined
)
{
const
vals
=
parseFloat
(
item
!==
undefined
?
item
.
text
:
''
);
this
.
setState
({
percent
:
vals
/
100
,
selectedItem
:
item
},
()
=>
{
this
.
reInit
();
});
}
}
}
// deal with response data into pic data
// deal with response data into pic data
...
@@ -439,8 +443,24 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -439,8 +443,24 @@ class Para extends React.Component<ParaProps, ParaState> {
}
}
// get swap parallel axis
// get swap parallel axis
getSwapArr
=
(
value
:
Array
<
string
>
):
void
=>
{
getSwapArr
=
(
event
:
React
.
FormEvent
<
HTMLDivElement
>
,
item
?:
IDropdownOption
):
void
=>
{
this
.
setState
({
swapAxisArr
:
value
});
const
newSelectedItems
=
[...
this
.
state
.
swapyAxis
];
if
(
item
!==
undefined
)
{
if
(
item
.
selected
)
{
// add the option if it's checked
newSelectedItems
.
push
(
item
.
key
as
string
);
}
else
{
// remove the option if it's unchecked
const
currIndex
=
newSelectedItems
.
indexOf
(
item
.
key
as
string
);
if
(
currIndex
>
-
1
)
{
newSelectedItems
.
splice
(
currIndex
,
1
);
}
}
this
.
setState
({
swapAxisArr
:
newSelectedItems
,
swapyAxis
:
newSelectedItems
});
}
}
}
reInit
=
():
void
=>
{
reInit
=
():
void
=>
{
...
@@ -571,80 +591,47 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -571,80 +591,47 @@ class Para extends React.Component<ParaProps, ParaState> {
}
}
}
}
shouldComponentUpdate
(
nextProps
:
ParaProps
,
nextState
:
ParaState
):
boolean
{
const
{
whichGraph
}
=
nextProps
;
const
beforeGraph
=
this
.
props
.
whichGraph
;
if
(
whichGraph
===
'
2
'
)
{
if
(
whichGraph
!==
beforeGraph
)
{
return
true
;
}
const
{
sutrialCount
,
clickCounts
,
succeedRenderCount
}
=
nextState
;
const
beforeCount
=
this
.
state
.
sutrialCount
;
const
beforeClickCount
=
this
.
state
.
clickCounts
;
const
beforeRealRenderCount
=
this
.
state
.
succeedRenderCount
;
if
(
sutrialCount
!==
beforeCount
)
{
return
true
;
}
if
(
succeedRenderCount
!==
beforeRealRenderCount
)
{
return
true
;
}
if
(
clickCounts
!==
beforeClickCount
)
{
return
true
;
}
}
return
false
;
}
render
():
React
.
ReactNode
{
render
():
React
.
ReactNode
{
const
{
option
,
paraNodata
,
dimName
,
isLoadConfirm
}
=
this
.
state
;
const
{
option
,
paraNodata
,
dimName
,
isLoadConfirm
,
selectedItem
,
swapyAxis
}
=
this
.
state
;
return
(
return
(
<
Row
className
=
"parameter"
>
<
div
className
=
"parameter"
>
<
Row
>
<
Stack
horizontal
className
=
"para-filter"
horizontalAlign
=
"end"
>
<
Col
span
=
{
6
}
/>
<
span
className
=
"para-filter-text"
>
Top
</
span
>
<
Col
span
=
{
18
}
>
<
Dropdown
<
Row
className
=
"meline"
>
selectedKey
=
{
selectedItem
?
selectedItem
.
key
:
undefined
}
<
span
>
Top
</
span
>
onChange
=
{
this
.
percentNum
}
<
Select
placeholder
=
"100%"
style
=
{
{
width
:
'
20%
'
,
marginRight
:
10
}
}
defaultSelectedKeys
=
{
[
0.2
]
}
placeholder
=
"100%"
options
=
{
[
optionFilterProp
=
"children"
{
key
:
'
0.2
'
,
text
:
'
20%
'
},
onSelect
=
{
this
.
percentNum
}
{
key
:
'
0.5
'
,
text
:
'
50%
'
},
>
{
key
:
'
0.8
'
,
text
:
'
80%
'
},
<
Option
value
=
"0.2"
>
20%
</
Option
>
{
key
:
'
1
'
,
text
:
'
100%
'
},
<
Option
value
=
"0.5"
>
50%
</
Option
>
]
}
<
Option
value
=
"0.8"
>
80%
</
Option
>
styles
=
{
{
dropdown
:
{
width
:
300
}
}
}
<
Option
value
=
"1"
>
100%
</
Option
>
className
=
"para-filter-percent"
</
Select
>
/>
<
Select
<
Dropdown
style
=
{
{
width
:
'
60%
'
}
}
placeholder
=
"Select options"
mode
=
"multiple"
selectedKeys
=
{
swapyAxis
}
placeholder
=
"Please select two items to swap"
onChange
=
{
this
.
getSwapArr
}
onChange
=
{
this
.
getSwapArr
}
multiSelect
maxTagCount
=
{
2
}
options
=
{
>
dimName
.
map
((
key
,
item
)
=>
{
{
return
{
dimName
.
map
((
key
,
item
)
=>
{
key
:
key
,
text
:
dimName
[
item
]
return
(
};
<
Option
key
=
{
key
}
value
=
{
dimName
[
item
]
}
>
{
dimName
[
item
]
}
</
Option
>
})
);
}
})
styles
=
{
{
dropdown
:
{
width
:
300
}
}
}
}
/>
</
Select
>
<
PrimaryButton
<
Button
text
=
"Confirm"
type
=
"primary"
onClick
=
{
this
.
swapReInit
}
className
=
"changeBtu tableButton"
disabled
=
{
isLoadConfirm
}
onClick
=
{
this
.
swapReInit
}
/>
disabled
=
{
isLoadConfirm
}
</
Stack
>
>
<
div
className
=
"searcHyper"
>
Confirm
</
Button
>
</
Row
>
</
Col
>
</
Row
>
<
Row
className
=
"searcHyper"
>
<
ReactEcharts
<
ReactEcharts
option
=
{
option
}
option
=
{
option
}
style
=
{
this
.
chartMulineStyle
}
style
=
{
this
.
chartMulineStyle
}
...
@@ -652,8 +639,8 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -652,8 +639,8 @@ class Para extends React.Component<ParaProps, ParaState> {
notMerge
=
{
true
}
// update now
notMerge
=
{
true
}
// update now
/>
/>
<
div
className
=
"noneData"
>
{
paraNodata
}
</
div
>
<
div
className
=
"noneData"
>
{
paraNodata
}
</
div
>
</
Row
>
</
div
>
</
Row
>
</
div
>
);
);
}
}
}
}
...
...
src/webui/src/components/trial-detail/TableList.tsx
View file @
c7187946
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
axios
from
'
axios
'
;
import
axios
from
'
axios
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
{
Row
,
Table
,
Button
,
Popconfirm
,
Modal
,
Checkbox
,
Select
,
Icon
}
from
'
antd
'
;
import
{
import
{
ColumnProps
}
from
'
antd/lib/table
'
;
Stack
,
Dropdown
,
DetailsList
,
IDetailsListProps
,
DetailsListLayoutMode
,
const
Option
=
Select
.
Option
;
PrimaryButton
,
Modal
,
IDropdownOption
,
IColumn
,
Selection
,
SelectionMode
,
IconButton
const
CheckboxGroup
=
Checkbox
.
Group
;
}
from
'
office-ui-fabric-react
'
;
import
{
MANAGER_IP
,
trialJobStatus
,
COLUMN_INDEX
,
COLUMNPro
}
from
'
../../static/const
'
;
import
{
LineChart
,
blocked
,
copy
}
from
'
../Buttons/Icon
'
;
import
{
convertDuration
,
formatTimestamp
,
intermediateGraphOption
,
killJob
,
parseMetrics
}
from
'
../../static/function
'
;
import
{
MANAGER_IP
,
COLUMNPro
}
from
'
../../static/const
'
;
import
{
convertDuration
,
formatTimestamp
,
intermediateGraphOption
,
parseMetrics
}
from
'
../../static/function
'
;
import
{
EXPERIMENT
,
TRIALS
}
from
'
../../static/datamodel
'
;
import
{
EXPERIMENT
,
TRIALS
}
from
'
../../static/datamodel
'
;
import
{
TableRecord
}
from
'
../../static/interface
'
;
import
{
TableRecord
}
from
'
../../static/interface
'
;
import
OpenRow
from
'
../public-child/OpenRow
'
;
import
Details
from
'
../overview/Details
'
;
import
Compare
from
'
../Modal/Compare
'
;
import
ChangeColumnComponent
from
'
../Modals/ChangeColumnComponent
'
;
import
Customize
from
'
../Modal/CustomizedTrial
'
;
import
Compare
from
'
../Modals/Compare
'
;
import
KillJob
from
'
../Modals/Killjob
'
;
import
Customize
from
'
../Modals/CustomizedTrial
'
;
import
{
contentStyles
,
iconButtonStyles
}
from
'
../Buttons/ModalTheme
'
;
import
'
../../static/style/search.scss
'
;
import
'
../../static/style/search.scss
'
;
require
(
'
../../static/style/tableStatus.css
'
)
;
import
'
../../static/style/tableStatus.css
'
;
require
(
'
../../static/style/logPath.scss
'
)
;
import
'
../../static/style/logPath.scss
'
;
require
(
'
../../static/style/search.scss
'
)
;
import
'
../../static/style/search.scss
'
;
require
(
'
../../static/style/table.scss
'
)
;
import
'
../../static/style/table.scss
'
;
require
(
'
../../static/style/button.scss
'
)
;
import
'
../../static/style/button.scss
'
;
require
(
'
../../static/style/openRow.scss
'
)
;
import
'
../../static/style/openRow.scss
'
;
const
echarts
=
require
(
'
echarts/lib/echarts
'
);
const
echarts
=
require
(
'
echarts/lib/echarts
'
);
require
(
'
echarts/lib/chart/line
'
);
require
(
'
echarts/lib/chart/line
'
);
require
(
'
echarts/lib/component/tooltip
'
);
require
(
'
echarts/lib/component/tooltip
'
);
...
@@ -27,11 +31,12 @@ echarts.registerTheme('my_theme', {
...
@@ -27,11 +31,12 @@ echarts.registerTheme('my_theme', {
color
:
'
#3c8dbc
'
color
:
'
#3c8dbc
'
});
});
interface
TableListProps
{
interface
TableListProps
{
pageSize
:
number
;
pageSize
:
number
;
tableSource
:
Array
<
TableRecord
>
;
tableSource
:
Array
<
TableRecord
>
;
columnList
:
Array
<
string
>
;
// user select columnKeys
columnList
:
string
[]
;
// user select columnKeys
changeColumn
:
(
val
:
Array
<
string
>
)
=>
void
;
changeColumn
:
(
val
:
string
[]
)
=>
void
;
trialsUpdateBroadcast
:
number
;
trialsUpdateBroadcast
:
number
;
}
}
...
@@ -40,115 +45,29 @@ interface TableListState {
...
@@ -40,115 +45,29 @@ interface TableListState {
modalVisible
:
boolean
;
modalVisible
:
boolean
;
isObjFinal
:
boolean
;
isObjFinal
:
boolean
;
isShowColumn
:
boolean
;
isShowColumn
:
boolean
;
selectRows
:
Array
<
TableRecord
>
;
selectRows
:
Array
<
any
>
;
isShowCompareModal
:
boolean
;
isShowCompareModal
:
boolean
;
selectedRowKeys
:
string
[]
|
number
[];
selectedRowKeys
:
string
[]
|
number
[];
intermediateData
:
Array
<
object
>
;
// a trial's intermediate results (include dict)
intermediateData
:
Array
<
object
>
;
// a trial's intermediate results (include dict)
intermediateId
:
string
;
intermediateId
:
string
;
intermediateOtherKeys
:
Array
<
string
>
;
intermediateOtherKeys
:
string
[]
;
isShowCustomizedModal
:
boolean
;
isShowCustomizedModal
:
boolean
;
copyTrialId
:
string
;
// user copy trial to submit a new customized trial
copyTrialId
:
string
;
// user copy trial to submit a new customized trial
isCalloutVisible
:
boolean
;
// kill job button callout [kill or not kill job window]
intermediateKeys
:
string
[];
// intermeidate modal: which key is choosed.
isExpand
:
boolean
;
modalIntermediateWidth
:
number
;
modalIntermediateHeight
:
number
;
tableColumns
:
IColumn
[];
allColumnList
:
string
[];
tableSourceForSort
:
Array
<
TableRecord
>
;
}
}
interface
ColumnIndex
{
name
:
string
;
index
:
number
;
}
const
AccuracyColumnConfig
:
ColumnProps
<
TableRecord
>
=
{
title
:
'
Default metric
'
,
className
:
'
leftTitle
'
,
dataIndex
:
'
accuracy
'
,
sorter
:
(
a
,
b
,
sortOrder
)
=>
{
if
(
a
.
latestAccuracy
===
undefined
)
{
return
sortOrder
===
'
ascend
'
?
1
:
-
1
;
}
else
if
(
b
.
latestAccuracy
===
undefined
)
{
return
sortOrder
===
'
ascend
'
?
-
1
:
1
;
}
else
{
return
a
.
latestAccuracy
-
b
.
latestAccuracy
;
}
},
render
:
(
text
,
record
):
React
.
ReactNode
=>
<
div
>
{
record
.
formattedLatestAccuracy
}
</
div
>
};
const
SequenceIdColumnConfig
:
ColumnProps
<
TableRecord
>
=
{
title
:
'
Trial No.
'
,
dataIndex
:
'
sequenceId
'
,
className
:
'
tableHead
'
,
sorter
:
(
a
,
b
)
=>
a
.
sequenceId
-
b
.
sequenceId
};
const
IdColumnConfig
:
ColumnProps
<
TableRecord
>
=
{
title
:
'
ID
'
,
dataIndex
:
'
id
'
,
className
:
'
tableHead leftTitle
'
,
sorter
:
(
a
,
b
)
=>
a
.
id
.
localeCompare
(
b
.
id
),
render
:
(
text
,
record
):
React
.
ReactNode
=>
(
<
div
>
{
record
.
id
}
</
div
>
)
};
const
StartTimeColumnConfig
:
ColumnProps
<
TableRecord
>
=
{
title
:
'
Start Time
'
,
dataIndex
:
'
startTime
'
,
sorter
:
(
a
,
b
)
=>
a
.
startTime
-
b
.
startTime
,
render
:
(
text
,
record
):
React
.
ReactNode
=>
(
<
span
>
{
formatTimestamp
(
record
.
startTime
)
}
</
span
>
)
};
const
EndTimeColumnConfig
:
ColumnProps
<
TableRecord
>
=
{
title
:
'
End Time
'
,
dataIndex
:
'
endTime
'
,
sorter
:
(
a
,
b
,
sortOrder
)
=>
{
if
(
a
.
endTime
===
undefined
)
{
return
sortOrder
===
'
ascend
'
?
1
:
-
1
;
}
else
if
(
b
.
endTime
===
undefined
)
{
return
sortOrder
===
'
ascend
'
?
-
1
:
1
;
}
else
{
return
a
.
endTime
-
b
.
endTime
;
}
},
render
:
(
text
,
record
):
React
.
ReactNode
=>
(
<
span
>
{
formatTimestamp
(
record
.
endTime
,
'
--
'
)
}
</
span
>
)
};
const
DurationColumnConfig
:
ColumnProps
<
TableRecord
>
=
{
title
:
'
Duration
'
,
dataIndex
:
'
duration
'
,
sorter
:
(
a
,
b
)
=>
a
.
duration
-
b
.
duration
,
render
:
(
text
,
record
):
React
.
ReactNode
=>
(
<
span
className
=
"durationsty"
>
{
convertDuration
(
record
.
duration
)
}
</
span
>
)
};
const
StatusColumnConfig
:
ColumnProps
<
TableRecord
>
=
{
title
:
'
Status
'
,
dataIndex
:
'
status
'
,
className
:
'
tableStatus
'
,
render
:
(
text
,
record
):
React
.
ReactNode
=>
(
<
span
className
=
{
`
${
record
.
status
}
commonStyle`
}
>
{
record
.
status
}
</
span
>
),
sorter
:
(
a
,
b
)
=>
a
.
status
.
localeCompare
(
b
.
status
),
filters
:
trialJobStatus
.
map
(
status
=>
({
text
:
status
,
value
:
status
})),
onFilter
:
(
value
,
record
)
=>
(
record
.
status
===
value
)
};
const
IntermediateCountColumnConfig
:
ColumnProps
<
TableRecord
>
=
{
title
:
'
Intermediate result
'
,
dataIndex
:
'
intermediateCount
'
,
sorter
:
(
a
,
b
)
=>
a
.
intermediateCount
-
b
.
intermediateCount
,
render
:
(
text
,
record
):
React
.
ReactNode
=>
(
<
span
>
{
`#
${
record
.
intermediateCount
}
`
}
</
span
>
)
};
class
TableList
extends
React
.
Component
<
TableListProps
,
TableListState
>
{
class
TableList
extends
React
.
Component
<
TableListProps
,
TableListState
>
{
public
intervalTrialLog
=
10
;
public
intervalTrialLog
=
10
;
public
_trialId
:
string
;
public
trialId
!
:
string
;
public
tables
:
Table
<
TableRecord
>
|
null
;
constructor
(
props
:
TableListProps
)
{
constructor
(
props
:
TableListProps
)
{
super
(
props
);
super
(
props
);
...
@@ -165,18 +84,164 @@ class TableList extends React.Component<TableListProps, TableListState> {
...
@@ -165,18 +84,164 @@ class TableList extends React.Component<TableListProps, TableListState> {
intermediateId
:
''
,
intermediateId
:
''
,
intermediateOtherKeys
:
[],
intermediateOtherKeys
:
[],
isShowCustomizedModal
:
false
,
isShowCustomizedModal
:
false
,
copyTrialId
:
''
isCalloutVisible
:
false
,
copyTrialId
:
''
,
intermediateKeys
:
[
'
default
'
],
isExpand
:
false
,
modalIntermediateWidth
:
window
.
innerWidth
,
modalIntermediateHeight
:
window
.
innerHeight
,
tableColumns
:
this
.
initTableColumnList
(
this
.
props
.
columnList
),
allColumnList
:
this
.
getAllColumnKeys
(),
tableSourceForSort
:
this
.
props
.
tableSource
};
};
}
}
showIntermediateModal
=
async
(
id
:
string
):
Promise
<
void
>
=>
{
// sort for table column
onColumnClick
=
(
ev
:
React
.
MouseEvent
<
HTMLElement
>
,
getColumn
:
IColumn
):
void
=>
{
const
{
tableColumns
}
=
this
.
state
;
const
{
tableSource
}
=
this
.
props
;
const
newColumns
:
IColumn
[]
=
tableColumns
.
slice
();
const
currColumn
:
IColumn
=
newColumns
.
filter
(
item
=>
getColumn
.
key
===
item
.
key
)[
0
];
newColumns
.
forEach
((
newCol
:
IColumn
)
=>
{
if
(
newCol
===
currColumn
)
{
currColumn
.
isSortedDescending
=
!
currColumn
.
isSortedDescending
;
currColumn
.
isSorted
=
true
;
}
else
{
newCol
.
isSorted
=
false
;
newCol
.
isSortedDescending
=
true
;
}
});
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const
newItems
=
this
.
copyAndSort
(
tableSource
,
currColumn
.
fieldName
!
,
currColumn
.
isSortedDescending
);
this
.
setState
({
tableColumns
:
newColumns
,
tableSourceForSort
:
newItems
});
};
private
copyAndSort
<
T
>
(
items
:
T
[],
columnKey
:
string
,
isSortedDescending
?:
boolean
):
T
[]
{
const
key
=
columnKey
as
keyof
T
;
return
items
.
slice
(
0
).
sort
((
a
:
T
,
b
:
T
)
=>
((
isSortedDescending
?
a
[
key
]
<
b
[
key
]
:
a
[
key
]
>
b
[
key
])
?
1
:
-
1
));
}
AccuracyColumnConfig
:
any
=
{
name
:
'
Default metric
'
,
className
:
'
leftTitle
'
,
key
:
'
accuracy
'
,
fieldName
:
'
accuracy
'
,
minWidth
:
200
,
maxWidth
:
300
,
isResizable
:
true
,
data
:
'
number
'
,
onColumnClick
:
this
.
onColumnClick
,
onRender
:
(
item
):
React
.
ReactNode
=>
<
div
>
{
item
.
formattedLatestAccuracy
}
</
div
>
};
SequenceIdColumnConfig
:
any
=
{
name
:
'
Trial No.
'
,
key
:
'
sequenceId
'
,
fieldName
:
'
sequenceId
'
,
minWidth
:
80
,
maxWidth
:
120
,
className
:
'
tableHead
'
,
data
:
'
string
'
,
onColumnClick
:
this
.
onColumnClick
,
};
IdColumnConfig
:
any
=
{
name
:
'
ID
'
,
key
:
'
id
'
,
fieldName
:
'
id
'
,
minWidth
:
150
,
maxWidth
:
200
,
isResizable
:
true
,
data
:
'
string
'
,
onColumnClick
:
this
.
onColumnClick
,
className
:
'
tableHead leftTitle
'
};
StartTimeColumnConfig
:
any
=
{
name
:
'
Start Time
'
,
key
:
'
startTime
'
,
fieldName
:
'
startTime
'
,
minWidth
:
150
,
maxWidth
:
200
,
isResizable
:
true
,
data
:
'
number
'
,
onColumnClick
:
this
.
onColumnClick
,
onRender
:
(
record
):
React
.
ReactNode
=>
(
<
span
>
{
formatTimestamp
(
record
.
startTime
)
}
</
span
>
)
};
EndTimeColumnConfig
:
any
=
{
name
:
'
End Time
'
,
key
:
'
endTime
'
,
fieldName
:
'
endTime
'
,
minWidth
:
150
,
maxWidth
:
200
,
isResizable
:
true
,
data
:
'
number
'
,
onColumnClick
:
this
.
onColumnClick
,
onRender
:
(
record
):
React
.
ReactNode
=>
(
<
span
>
{
formatTimestamp
(
record
.
endTime
,
'
--
'
)
}
</
span
>
)
};
DurationColumnConfig
:
any
=
{
name
:
'
Duration
'
,
key
:
'
duration
'
,
fieldName
:
'
duration
'
,
minWidth
:
150
,
maxWidth
:
200
,
isResizable
:
true
,
data
:
'
number
'
,
onColumnClick
:
this
.
onColumnClick
,
onRender
:
(
record
):
React
.
ReactNode
=>
(
<
span
className
=
"durationsty"
>
{
convertDuration
(
record
.
duration
)
}
</
span
>
)
};
StatusColumnConfig
:
any
=
{
name
:
'
Status
'
,
key
:
'
status
'
,
fieldName
:
'
status
'
,
className
:
'
tableStatus
'
,
minWidth
:
150
,
maxWidth
:
200
,
isResizable
:
true
,
data
:
'
string
'
,
onColumnClick
:
this
.
onColumnClick
,
onRender
:
(
record
):
React
.
ReactNode
=>
(
<
span
className
=
{
`
${
record
.
status
}
commonStyle`
}
>
{
record
.
status
}
</
span
>
),
};
IntermediateCountColumnConfig
:
any
=
{
name
:
'
Intermediate result
'
,
dataIndex
:
'
intermediateCount
'
,
fieldName
:
'
intermediateCount
'
,
minWidth
:
150
,
maxWidth
:
200
,
isResizable
:
true
,
data
:
'
number
'
,
onColumnClick
:
this
.
onColumnClick
,
onRender
:
(
record
):
React
.
ReactNode
=>
(
<
span
>
{
`#
${
record
.
intermediateCount
}
`
}
</
span
>
)
};
showIntermediateModal
=
async
(
id
:
string
,
event
:
React
.
SyntheticEvent
<
EventTarget
>
):
Promise
<
void
>
=>
{
event
.
preventDefault
();
event
.
stopPropagation
();
const
res
=
await
axios
.
get
(
`
${
MANAGER_IP
}
/metric-data/
${
id
}
`
);
const
res
=
await
axios
.
get
(
`
${
MANAGER_IP
}
/metric-data/
${
id
}
`
);
if
(
res
.
status
===
200
)
{
if
(
res
.
status
===
200
)
{
const
intermediateArr
:
number
[]
=
[];
const
intermediateArr
:
number
[]
=
[];
// support intermediate result is dict because the last intermediate result is
// support intermediate result is dict because the last intermediate result is
// final result in a succeed trial, it may be a dict.
// final result in a succeed trial, it may be a dict.
// get intermediate result dict keys array
// get intermediate result dict keys array
let
otherkeys
:
Array
<
string
>
=
[
'
default
'
];
let
otherkeys
:
string
[]
=
[
'
default
'
];
if
(
res
.
data
.
length
!==
0
)
{
if
(
res
.
data
.
length
!==
0
)
{
otherkeys
=
Object
.
keys
(
parseMetrics
(
res
.
data
[
0
].
data
));
otherkeys
=
Object
.
keys
(
parseMetrics
(
res
.
data
[
0
].
data
));
}
}
...
@@ -202,34 +267,37 @@ class TableList extends React.Component<TableListProps, TableListState> {
...
@@ -202,34 +267,37 @@ class TableList extends React.Component<TableListProps, TableListState> {
// intermediate button click -> intermediate graph for each trial
// intermediate button click -> intermediate graph for each trial
// support intermediate is dict
// support intermediate is dict
selectOtherKeys
=
(
value
:
string
):
void
=>
{
selectOtherKeys
=
(
event
:
React
.
FormEvent
<
HTMLDivElement
>
,
item
?:
IDropdownOption
):
void
=>
{
if
(
item
!==
undefined
)
{
const
isShowDefault
:
boolean
=
value
===
'
default
'
?
true
:
false
;
const
value
=
item
.
text
;
const
{
intermediateData
,
intermediateId
}
=
this
.
state
;
const
isShowDefault
:
boolean
=
value
===
'
default
'
?
true
:
false
;
const
intermediateArr
:
number
[]
=
[];
const
{
intermediateData
,
intermediateId
}
=
this
.
state
;
// just watch default key-val
const
intermediateArr
:
number
[]
=
[];
if
(
isShowDefault
===
true
)
{
// just watch default key-val
Object
.
keys
(
intermediateData
).
map
(
item
=>
{
if
(
isShowDefault
===
true
)
{
const
temp
=
parseMetrics
(
intermediateData
[
item
].
data
);
Object
.
keys
(
intermediateData
).
map
(
item
=>
{
if
(
typeof
temp
===
'
object
'
)
{
const
temp
=
parseMetrics
(
intermediateData
[
item
].
data
);
intermediateArr
.
push
(
temp
[
value
]);
if
(
typeof
temp
===
'
object
'
)
{
}
else
{
intermediateArr
.
push
(
temp
[
value
]);
intermediateArr
.
push
(
temp
);
}
else
{
}
intermediateArr
.
push
(
temp
);
});
}
}
else
{
});
Object
.
keys
(
intermediateData
).
map
(
item
=>
{
}
else
{
const
temp
=
parseMetrics
(
intermediateData
[
item
].
data
);
Object
.
keys
(
intermediateData
).
map
(
item
=>
{
if
(
typeof
temp
===
'
object
'
)
{
const
temp
=
parseMetrics
(
intermediateData
[
item
].
data
);
intermediateArr
.
push
(
temp
[
value
]);
if
(
typeof
temp
===
'
object
'
)
{
}
intermediateArr
.
push
(
temp
[
value
]);
}
});
}
const
intermediate
=
intermediateGraphOption
(
intermediateArr
,
intermediateId
);
// re-render
this
.
setState
({
intermediateKeys
:
[
value
],
intermediateOption
:
intermediate
});
});
}
}
const
intermediate
=
intermediateGraphOption
(
intermediateArr
,
intermediateId
);
// re-render
this
.
setState
({
intermediateOption
:
intermediate
});
}
}
hideIntermediateModal
=
():
void
=>
{
hideIntermediateModal
=
():
void
=>
{
...
@@ -239,81 +307,20 @@ class TableList extends React.Component<TableListProps, TableListState> {
...
@@ -239,81 +307,20 @@ class TableList extends React.Component<TableListProps, TableListState> {
}
}
hideShowColumnModal
=
():
void
=>
{
hideShowColumnModal
=
():
void
=>
{
this
.
setState
({
isShowColumn
:
false
this
.
setState
(()
=>
({
isShowColumn
:
false
}));
});
}
}
// click add column btn, just show the modal of addcolumn
// click add column btn, just show the modal of addcolumn
addColumn
=
():
void
=>
{
addColumn
=
():
void
=>
{
// show user select check button
// show user select check button
this
.
setState
({
this
.
setState
(()
=>
({
isShowColumn
:
true
}));
isShowColumn
:
true
});
}
// checkbox for coloumn
selectedColumn
=
(
checkedValues
:
Array
<
string
>
):
void
=>
{
// 9: because have nine common column,
// [Intermediate count, Start Time, End Time] is hidden by default
let
count
=
9
;
const
want
:
Array
<
object
>
=
[];
const
finalKeys
:
Array
<
string
>
=
[];
const
wantResult
:
Array
<
string
>
=
[];
Object
.
keys
(
checkedValues
).
map
(
m
=>
{
switch
(
checkedValues
[
m
])
{
case
'
Trial No.
'
:
case
'
ID
'
:
case
'
Start Time
'
:
case
'
End Time
'
:
case
'
Duration
'
:
case
'
Status
'
:
case
'
Operation
'
:
case
'
Default
'
:
case
'
Intermediate result
'
:
break
;
default
:
finalKeys
.
push
(
checkedValues
[
m
]);
}
});
Object
.
keys
(
finalKeys
).
map
(
n
=>
{
want
.
push
({
name
:
finalKeys
[
n
],
index
:
count
++
});
});
Object
.
keys
(
checkedValues
).
map
(
item
=>
{
const
temp
=
checkedValues
[
item
];
Object
.
keys
(
COLUMN_INDEX
).
map
(
key
=>
{
const
index
=
COLUMN_INDEX
[
key
];
if
(
index
.
name
===
temp
)
{
want
.
push
(
index
);
}
});
});
want
.
sort
((
a
:
ColumnIndex
,
b
:
ColumnIndex
)
=>
{
return
a
.
index
-
b
.
index
;
});
Object
.
keys
(
want
).
map
(
i
=>
{
wantResult
.
push
(
want
[
i
].
name
);
});
this
.
props
.
changeColumn
(
wantResult
);
}
openRow
=
(
record
:
TableRecord
):
any
=>
{
return
(
<
OpenRow
trialId
=
{
record
.
id
}
/>
);
}
}
fillSelectedRowsTostate
=
(
selected
:
number
[]
|
string
[],
selectedRows
:
Array
<
TableRecord
>
):
void
=>
{
fillSelectedRowsTostate
=
(
selected
:
number
[]
|
string
[],
selectedRows
:
Array
<
TableRecord
>
):
void
=>
{
this
.
setState
({
selectRows
:
selectedRows
,
selectedRowKeys
:
selected
});
this
.
setState
({
selectRows
:
selectedRows
,
selectedRowKeys
:
selected
});
}
}
// open Compare-modal
// open Compare-modal
compareBtn
=
():
void
=>
{
compareBtn
=
():
void
=>
{
...
@@ -324,6 +331,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
...
@@ -324,6 +331,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
this
.
setState
({
isShowCompareModal
:
true
});
this
.
setState
({
isShowCompareModal
:
true
});
}
}
}
}
// close Compare-modal
// close Compare-modal
hideCompareModal
=
():
void
=>
{
hideCompareModal
=
():
void
=>
{
// close modal. clear select rows data, clear selected track
// close modal. clear select rows data, clear selected track
...
@@ -331,178 +339,181 @@ class TableList extends React.Component<TableListProps, TableListState> {
...
@@ -331,178 +339,181 @@ class TableList extends React.Component<TableListProps, TableListState> {
}
}
// open customized trial modal
// open customized trial modal
setCustomizedTrial
=
(
trialId
:
string
):
void
=>
{
private
setCustomizedTrial
=
(
trialId
:
string
,
event
:
React
.
SyntheticEvent
<
EventTarget
>
):
void
=>
{
event
.
preventDefault
();
event
.
stopPropagation
();
this
.
setState
({
this
.
setState
({
isShowCustomizedModal
:
true
,
isShowCustomizedModal
:
true
,
copyTrialId
:
trialId
copyTrialId
:
trialId
});
});
}
}
closeCustomizedTrial
=
():
void
=>
{
private
closeCustomizedTrial
=
():
void
=>
{
this
.
setState
({
this
.
setState
({
isShowCustomizedModal
:
false
,
isShowCustomizedModal
:
false
,
copyTrialId
:
''
copyTrialId
:
''
});
});
}
}
render
():
React
.
ReactNode
{
const
{
pageSize
,
columnList
}
=
this
.
props
;
const
tableSource
:
Array
<
TableRecord
>
=
JSON
.
parse
(
JSON
.
stringify
(
this
.
props
.
tableSource
));
const
{
intermediateOption
,
modalVisible
,
isShowColumn
,
selectRows
,
isShowCompareModal
,
selectedRowKeys
,
intermediateOtherKeys
,
isShowCustomizedModal
,
copyTrialId
}
=
this
.
state
;
const
rowSelection
=
{
selectedRowKeys
:
selectedRowKeys
,
onChange
:
(
selected
:
string
[]
|
number
[],
selectedRows
:
Array
<
TableRecord
>
):
void
=>
{
this
.
fillSelectedRowsTostate
(
selected
,
selectedRows
);
}
};
// [supportCustomizedTrial: true]
const
supportCustomizedTrial
=
(
EXPERIMENT
.
multiPhase
===
true
)
?
false
:
true
;
const
disabledAddCustomizedTrial
=
[
'
DONE
'
,
'
ERROR
'
,
'
STOPPED
'
].
includes
(
EXPERIMENT
.
status
);
let
showTitle
=
COLUMNPro
;
const
showColumn
:
Array
<
object
>
=
[];
private
onWindowResize
=
():
void
=>
{
this
.
setState
(()
=>
({
modalIntermediateHeight
:
window
.
innerHeight
,
modalIntermediateWidth
:
window
.
innerWidth
}));
}
private
onRenderRow
:
IDetailsListProps
[
'
onRenderRow
'
]
=
props
=>
{
if
(
props
)
{
return
<
Details
detailsProps
=
{
props
}
/>;
}
return
null
;
};
private
getSelectedRows
=
new
Selection
({
onSelectionChanged
:
():
void
=>
{
this
.
setState
(()
=>
({
selectRows
:
this
.
getSelectedRows
.
getSelection
()
}));
}
});
// trial parameters & dict final keys & Trial No. Id ...
private
getAllColumnKeys
=
():
string
[]
=>
{
const
tableSource
:
Array
<
TableRecord
>
=
JSON
.
parse
(
JSON
.
stringify
(
this
.
props
.
tableSource
));
// parameter as table column
// parameter as table column
const
parameterStr
:
Array
<
string
>
=
[];
const
parameterStr
:
string
[]
=
[];
if
(
tableSource
.
length
>
0
)
{
if
(
tableSource
.
length
>
0
)
{
const
trialMess
=
TRIALS
.
getTrial
(
tableSource
[
0
].
id
);
const
trialMess
=
TRIALS
.
getTrial
(
tableSource
[
0
].
id
);
const
trial
=
trialMess
.
description
.
parameters
;
const
trial
=
trialMess
.
description
.
parameters
;
const
parameterColumn
:
Array
<
string
>
=
Object
.
keys
(
trial
);
const
parameterColumn
:
string
[]
=
Object
.
keys
(
trial
);
parameterColumn
.
forEach
(
value
=>
{
parameterColumn
.
forEach
(
value
=>
{
parameterStr
.
push
(
`
${
value
}
(search space)`
);
parameterStr
.
push
(
`
${
value
}
(search space)`
);
});
});
}
}
showTitle
=
COLUMNPro
.
concat
(
parameterStr
);
let
allColumnList
=
COLUMNPro
;
// eslint-disable-line @typescript-eslint/no-unused-vars
allColumnList
=
COLUMNPro
.
concat
(
parameterStr
);
// only succeed trials have final keys
// only succeed trials have final keys
if
(
tableSource
.
filter
(
record
=>
record
.
status
===
'
SUCCEEDED
'
).
length
>=
1
)
{
if
(
tableSource
.
filter
(
record
=>
record
.
status
===
'
SUCCEEDED
'
).
length
>=
1
)
{
const
temp
=
tableSource
.
filter
(
record
=>
record
.
status
===
'
SUCCEEDED
'
)[
0
].
accuracy
;
const
temp
=
tableSource
.
filter
(
record
=>
record
.
status
===
'
SUCCEEDED
'
)[
0
].
accuracy
;
if
(
temp
!==
undefined
&&
typeof
temp
===
'
object
'
)
{
if
(
temp
!==
undefined
&&
typeof
temp
===
'
object
'
)
{
// concat default column and finalkeys
if
(
!
isNaN
(
temp
))
{
const
item
=
Object
.
keys
(
temp
);
// concat default column and finalkeys
// item: ['default', 'other-keys', 'maybe loss']
const
item
=
Object
.
keys
(
temp
);
if
(
item
.
length
>
1
)
{
// item: ['default', 'other-keys', 'maybe loss']
const
want
:
Array
<
string
>
=
[];
if
(
item
.
length
>
1
)
{
item
.
forEach
(
value
=>
{
const
want
:
string
[]
=
[];
if
(
value
!==
'
default
'
)
{
item
.
forEach
(
value
=>
{
want
.
push
(
value
);
if
(
value
!==
'
default
'
)
{
}
want
.
push
(
value
);
});
}
showTitle
=
COLUMNPro
.
concat
(
want
);
});
allColumnList
=
COLUMNPro
.
concat
(
want
);
}
}
}
}
}
}
}
return
allColumnList
;
}
// get IColumn[]
// when user click [Add Column] need to use the function
private
initTableColumnList
=
(
columnList
:
string
[]):
IColumn
[]
=>
{
// const { columnList } = this.props;
// [supportCustomizedTrial: true]
const
supportCustomizedTrial
=
(
EXPERIMENT
.
multiPhase
===
true
)
?
false
:
true
;
const
disabledAddCustomizedTrial
=
[
'
DONE
'
,
'
ERROR
'
,
'
STOPPED
'
].
includes
(
EXPERIMENT
.
status
);
const
showColumn
:
IColumn
[]
=
[];
for
(
const
item
of
columnList
)
{
for
(
const
item
of
columnList
)
{
const
paraColumn
=
item
.
match
(
/
\(
search space
\)
$/
);
const
paraColumn
=
item
.
match
(
/
\(
search space
\)
$/
);
let
cc
;
let
result
;
if
(
paraColumn
!==
null
)
{
if
(
paraColumn
!==
null
)
{
cc
=
paraColumn
.
input
;
result
=
paraColumn
.
input
;
}
}
switch
(
item
)
{
switch
(
item
)
{
case
'
Trial No.
'
:
case
'
Trial No.
'
:
showColumn
.
push
(
SequenceIdColumnConfig
);
showColumn
.
push
(
this
.
SequenceIdColumnConfig
);
break
;
break
;
case
'
ID
'
:
case
'
ID
'
:
showColumn
.
push
(
IdColumnConfig
);
showColumn
.
push
(
this
.
IdColumnConfig
);
break
;
break
;
case
'
Start Time
'
:
case
'
Start Time
'
:
showColumn
.
push
(
StartTimeColumnConfig
);
showColumn
.
push
(
this
.
StartTimeColumnConfig
);
break
;
break
;
case
'
End Time
'
:
case
'
End Time
'
:
showColumn
.
push
(
EndTimeColumnConfig
);
showColumn
.
push
(
this
.
EndTimeColumnConfig
);
break
;
break
;
case
'
Duration
'
:
case
'
Duration
'
:
showColumn
.
push
(
DurationColumnConfig
);
showColumn
.
push
(
this
.
DurationColumnConfig
);
break
;
break
;
case
'
Status
'
:
case
'
Status
'
:
showColumn
.
push
(
StatusColumnConfig
);
showColumn
.
push
(
this
.
StatusColumnConfig
);
break
;
break
;
case
'
Intermediate result
'
:
case
'
Intermediate result
'
:
showColumn
.
push
(
IntermediateCountColumnConfig
);
showColumn
.
push
(
this
.
IntermediateCountColumnConfig
);
break
;
break
;
case
'
Default
'
:
case
'
Default
'
:
showColumn
.
push
(
AccuracyColumnConfig
);
showColumn
.
push
(
this
.
AccuracyColumnConfig
);
break
;
break
;
case
'
Operation
'
:
case
'
Operation
'
:
showColumn
.
push
({
showColumn
.
push
({
title
:
'
Operation
'
,
name
:
'
Operation
'
,
dataIndex
:
'
operation
'
,
key
:
'
operation
'
,
key
:
'
operation
'
,
render
:
(
text
:
string
,
record
:
TableRecord
)
=>
{
fieldName
:
'
operation
'
,
minWidth
:
160
,
maxWidth
:
200
,
isResizable
:
true
,
className
:
'
detail-table
'
,
onRender
:
(
record
:
any
)
=>
{
const
trialStatus
=
record
.
status
;
const
trialStatus
=
record
.
status
;
// could kill a job when its status is RUNNING or UNKNOWN
const
flag
:
boolean
=
(
trialStatus
===
'
RUNNING
'
||
trialStatus
===
'
UNKNOWN
'
)
?
false
:
true
;
const
flag
:
boolean
=
(
trialStatus
===
'
RUNNING
'
||
trialStatus
===
'
UNKNOWN
'
)
?
false
:
true
;
return
(
return
(
<
Row
id
=
"detail-button"
>
<
Stack
className
=
"detail-button"
horizontal
>
{
/* see intermediate result graph */
}
{
/* see intermediate result graph */
}
<
Button
<
PrimaryButton
type
=
"primary"
className
=
"detail-button-operation"
className
=
"common-style"
onClick
=
{
this
.
showIntermediateModal
.
bind
(
this
,
record
.
id
)
}
title
=
"Intermediate"
title
=
"Intermediate"
onClick
=
{
this
.
showIntermediateModal
.
bind
(
this
,
record
.
id
)
}
>
>
<
Icon
type
=
"l
ine
-c
hart
"
/>
{
L
ine
C
hart
}
</
Button
>
</
Primary
Button
>
{
/* kill job */
}
{
/* kill job */
}
{
{
flag
flag
?
?
<
Button
<
PrimaryButton
className
=
"detail-button-operation"
disabled
=
{
true
}
title
=
"kill"
>
type
=
"default"
{
blocked
}
disabled
=
{
true
}
</
PrimaryButton
>
className
=
"margin-mediate special"
title
=
"kill"
>
<
Icon
type
=
"stop"
/>
</
Button
>
:
:
<
Popconfirm
<
KillJob
trial
=
{
record
}
/>
title
=
"Are you sure to cancel this trial?"
okText
=
"Yes"
cancelText
=
"No"
onConfirm
=
{
killJob
.
bind
(
this
,
record
.
key
,
record
.
id
,
record
.
status
)
}
>
<
Button
type
=
"default"
disabled
=
{
false
}
className
=
"margin-mediate special"
title
=
"kill"
>
<
Icon
type
=
"stop"
/>
</
Button
>
</
Popconfirm
>
}
}
{
/* Add a new trial-customized trial */
}
{
/* Add a new trial-customized trial */
}
{
{
supportCustomizedTrial
supportCustomizedTrial
?
?
<
Button
<
PrimaryButton
type
=
"primary"
className
=
"detail-button-operation"
className
=
"common-style"
disabled
=
{
disabledAddCustomizedTrial
}
onClick
=
{
this
.
setCustomizedTrial
.
bind
(
this
,
record
.
id
)
}
title
=
"Customized trial"
title
=
"Customized trial"
onClick
=
{
this
.
setCustomizedTrial
.
bind
(
this
,
record
.
id
)
}
disabled
=
{
disabledAddCustomizedTrial
}
>
>
<
Icon
type
=
"copy"
/>
{
copy
}
</
Button
>
</
Primary
Button
>
:
:
null
null
}
}
</
Row
>
</
Stack
>
);
);
},
},
});
});
break
;
break
;
case
(
cc
):
case
(
result
):
// remove SEARCH_SPACE title
// remove SEARCH_SPACE title
// const realItem = item.replace(' (search space)', '');
// const realItem = item.replace(' (search space)', '');
showColumn
.
push
({
showColumn
.
push
({
title
:
item
.
replace
(
'
(search space)
'
,
''
),
name
:
item
.
replace
(
'
(search space)
'
,
''
),
dataIndex
:
item
,
key
:
item
,
key
:
item
,
render
:
(
text
:
string
,
record
:
TableRecord
)
=>
{
fieldName
:
item
,
minWidth
:
150
,
onRender
:
(
record
:
TableRecord
)
=>
{
const
eachTrial
=
TRIALS
.
getTrial
(
record
.
id
);
const
eachTrial
=
TRIALS
.
getTrial
(
record
.
id
);
return
(
return
(
<
span
>
{
eachTrial
.
description
.
parameters
[
item
.
replace
(
'
(search space)
'
,
''
)]
}
</
span
>
<
span
>
{
eachTrial
.
description
.
parameters
[
item
.
replace
(
'
(search space)
'
,
''
)]
}
</
span
>
...
@@ -515,88 +526,110 @@ class TableList extends React.Component<TableListProps, TableListState> {
...
@@ -515,88 +526,110 @@ class TableList extends React.Component<TableListProps, TableListState> {
alert
(
'
Unexpected column type
'
);
alert
(
'
Unexpected column type
'
);
}
}
}
}
return
showColumn
;
}
componentDidMount
():
void
{
window
.
addEventListener
(
'
resize
'
,
this
.
onWindowResize
);
}
UNSAFE_componentWillReceiveProps
(
nextProps
:
TableListProps
):
void
{
const
{
columnList
}
=
nextProps
;
this
.
setState
({
tableColumns
:
this
.
initTableColumnList
(
columnList
)
});
}
render
():
React
.
ReactNode
{
const
{
intermediateKeys
,
modalIntermediateWidth
,
modalIntermediateHeight
,
tableColumns
,
allColumnList
,
isShowColumn
,
modalVisible
,
selectRows
,
isShowCompareModal
,
intermediateOtherKeys
,
isShowCustomizedModal
,
copyTrialId
,
intermediateOption
}
=
this
.
state
;
const
{
columnList
}
=
this
.
props
;
const
tableSource
:
Array
<
TableRecord
>
=
JSON
.
parse
(
JSON
.
stringify
(
this
.
state
.
tableSourceForSort
));
return
(
return
(
<
Row
className
=
"tableList"
>
<
Stack
>
<
div
id
=
"tableList"
>
<
div
id
=
"tableList"
>
<
Table
<
DetailsList
ref
=
{
(
table
:
Table
<
TableRecord
>
|
null
):
any
=>
this
.
tables
=
table
}
columns
=
{
tableColumns
}
columns
=
{
showColumn
}
items
=
{
tableSource
}
rowSelection
=
{
rowSelection
}
setKey
=
"set"
expandedRowRender
=
{
this
.
openRow
}
compact
=
{
true
}
dataSource
=
{
tableSource
}
onRenderRow
=
{
this
.
onRenderRow
}
c
la
ssName
=
"commonTableStyle"
la
youtMode
=
{
DetailsListLayoutMode
.
justified
}
s
croll
=
{
{
x
:
'
max-content
'
}
}
s
electionMode
=
{
SelectionMode
.
multiple
}
pagination
=
{
pageSize
>
0
?
{
pageSize
}
:
false
}
selection
=
{
this
.
getSelectedRows
}
/>
/>
{
/* Intermediate Result Modal */
}
<
Modal
title
=
"Intermediate result"
visible
=
{
modalVisible
}
onCancel
=
{
this
.
hideIntermediateModal
}
footer
=
{
null
}
destroyOnClose
=
{
true
}
width
=
"80%"
>
{
intermediateOtherKeys
.
length
>
1
?
<
Row
className
=
"selectKeys"
>
<
Select
className
=
"select"
defaultValue
=
"default"
onSelect
=
{
this
.
selectOtherKeys
}
>
{
Object
.
keys
(
intermediateOtherKeys
).
map
(
item
=>
{
const
keys
=
intermediateOtherKeys
[
item
];
return
<
Option
value
=
{
keys
}
key
=
{
item
}
>
{
keys
}
</
Option
>;
})
}
</
Select
>
</
Row
>
:
<
div
/>
}
<
ReactEcharts
option
=
{
intermediateOption
}
style
=
{
{
width
:
'
100%
'
,
height
:
0.7
*
window
.
innerHeight
}
}
theme
=
"my_theme"
/>
</
Modal
>
</
div
>
</
div
>
{
/*
Add Column
Modal */
}
{
/*
Intermediate Result
Modal */
}
<
Modal
<
Modal
title
=
"Table Title"
isOpen
=
{
modalVisible
}
visible
=
{
isShowColumn
}
onDismiss
=
{
this
.
hideIntermediateModal
}
onCancel
=
{
this
.
hideShowColumnModal
}
containerClassName
=
{
contentStyles
.
container
}
footer
=
{
null
}
destroyOnClose
=
{
true
}
width
=
"40%"
>
>
<
CheckboxGroup
<
div
className
=
{
contentStyles
.
header
}
>
options
=
{
showTitle
}
<
span
>
Intermediate result
</
span
>
defaultValue
=
{
columnList
}
<
IconButton
// defaultValue={columnSelected}
styles
=
{
iconButtonStyles
}
onChange
=
{
this
.
selectedColumn
}
iconProps
=
{
{
iconName
:
'
Cancel
'
}
}
className
=
"titleColumn"
ariaLabel
=
"Close popup modal"
onClick
=
{
this
.
hideIntermediateModal
as
any
}
/>
</
div
>
{
intermediateOtherKeys
.
length
>
1
?
<
Stack
className
=
"selectKeys"
styles
=
{
{
root
:
{
width
:
800
}
}
}
>
<
Dropdown
className
=
"select"
selectedKeys
=
{
intermediateKeys
}
onChange
=
{
this
.
selectOtherKeys
}
options
=
{
intermediateOtherKeys
.
map
((
key
,
item
)
=>
{
return
{
key
:
key
,
text
:
intermediateOtherKeys
[
item
]
};
})
}
styles
=
{
{
dropdown
:
{
width
:
300
}
}
}
/>
</
Stack
>
:
null
}
<
ReactEcharts
option
=
{
intermediateOption
}
style
=
{
{
width
:
0.5
*
modalIntermediateWidth
,
height
:
0.7
*
modalIntermediateHeight
,
padding
:
20
}
}
theme
=
"my_theme"
/>
/>
</
Modal
>
</
Modal
>
{
/* Add Column Modal */
}
{
isShowColumn
&&
<
ChangeColumnComponent
hideShowColumnDialog
=
{
this
.
hideShowColumnModal
}
isHideDialog
=
{
!
isShowColumn
}
showColumn
=
{
allColumnList
}
selectedColumn
=
{
columnList
}
changeColumn
=
{
this
.
props
.
changeColumn
}
/>
}
{
/* compare trials based message */
}
{
/* compare trials based message */
}
<
Compare
compare
Row
s
=
{
selectRows
}
visible
=
{
isShowCompareModal
}
cancelFunc
=
{
this
.
hideCompareModal
}
/>
{
isShowCompareModal
&&
<
Compare
compare
Stack
s
=
{
selectRows
}
cancelFunc
=
{
this
.
hideCompareModal
}
/>
}
{
/* clone trial parameters and could submit a customized trial */
}
{
/* clone trial parameters and could submit a customized trial */
}
<
Customize
<
Customize
visible
=
{
isShowCustomizedModal
}
visible
=
{
isShowCustomizedModal
}
copyTrialId
=
{
copyTrialId
}
copyTrialId
=
{
copyTrialId
}
closeCustomizeModal
=
{
this
.
closeCustomizedTrial
}
closeCustomizeModal
=
{
this
.
closeCustomizedTrial
}
/>
/>
</
Row
>
</
Stack
>
);
);
}
}
}
}
export
default
TableList
;
export
default
TableList
;
\ No newline at end of file
Prev
1
2
3
4
5
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