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
cb25d66e
Unverified
Commit
cb25d66e
authored
Jul 18, 2019
by
SparkSnail
Committed by
GitHub
Jul 18, 2019
Browse files
Merge pull request #190 from microsoft/master
merge master
parents
9fb25ccc
7ee86e1d
Changes
26
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
689 additions
and
208 deletions
+689
-208
docs/src/configspace
docs/src/configspace
+0
-1
docs/src/pip-delete-this-directory.txt
docs/src/pip-delete-this-directory.txt
+0
-5
src/sdk/pynni/nni/bohb_advisor/requirements.txt
src/sdk/pynni/nni/bohb_advisor/requirements.txt
+1
-1
src/webui/src/App.css
src/webui/src/App.css
+1
-0
src/webui/src/components/Modal/ExperimentDrawer.tsx
src/webui/src/components/Modal/ExperimentDrawer.tsx
+144
-0
src/webui/src/components/Modal/LogDrawer.tsx
src/webui/src/components/Modal/LogDrawer.tsx
+206
-0
src/webui/src/components/SlideBar.tsx
src/webui/src/components/SlideBar.tsx
+111
-186
src/webui/src/components/overview/Progress.tsx
src/webui/src/components/overview/Progress.tsx
+24
-3
src/webui/src/components/public-child/MonacoEditor.tsx
src/webui/src/components/public-child/MonacoEditor.tsx
+50
-0
src/webui/src/static/const.ts
src/webui/src/static/const.ts
+6
-1
src/webui/src/static/function.ts
src/webui/src/static/function.ts
+23
-1
src/webui/src/static/style/button.scss
src/webui/src/static/style/button.scss
+1
-0
src/webui/src/static/style/compare.scss
src/webui/src/static/style/compare.scss
+2
-2
src/webui/src/static/style/control.scss
src/webui/src/static/style/control.scss
+1
-1
src/webui/src/static/style/logDrawer.scss
src/webui/src/static/style/logDrawer.scss
+112
-0
src/webui/src/static/style/openRow.scss
src/webui/src/static/style/openRow.scss
+1
-1
src/webui/src/static/style/overviewTitle.scss
src/webui/src/static/style/overviewTitle.scss
+2
-2
src/webui/src/static/style/progress.scss
src/webui/src/static/style/progress.scss
+2
-2
src/webui/src/static/style/slideBar.scss
src/webui/src/static/style/slideBar.scss
+1
-1
src/webui/src/static/style/table.scss
src/webui/src/static/style/table.scss
+1
-1
No files found.
configspace
@
f389e1d0
Subproject commit f389e1d0a72564f7f1fd4d86039e5f393a45a058
docs/src/pip-delete-this-directory.txt
deleted
100644 → 0
View file @
9fb25ccc
This file is placed here by pip to indicate the source was put
here by pip.
Once this package is successfully installed this source code will be
deleted (unless you remove this file).
src/sdk/pynni/nni/bohb_advisor/requirements.txt
View file @
cb25d66e
ConfigSpace==0.4.7
statsmodels==0.9.0
\ No newline at end of file
statsmodels==0.10.0
\ No newline at end of file
src/webui/src/App.css
View file @
cb25d66e
.nni
{
font-family
:
'Segoe UI'
,
Tahoma
,
Geneva
,
Verdana
,
sans-serif
;
color
:
#212121
;
font-size
:
14px
;
background
:
#f2f2f2
;
...
...
src/webui/src/components/Modal/ExperimentDrawer.tsx
0 → 100644
View file @
cb25d66e
import
*
as
React
from
'
react
'
;
import
axios
from
'
axios
'
;
import
{
downFile
}
from
'
../../static/function
'
;
import
{
Drawer
,
Tabs
,
Row
,
Col
,
Button
}
from
'
antd
'
;
import
{
MANAGER_IP
,
DRAWEROPTION
}
from
'
../../static/const
'
;
import
MonacoEditor
from
'
react-monaco-editor
'
;
const
{
TabPane
}
=
Tabs
;
import
'
../../static/style/logDrawer.scss
'
;
interface
ExpDrawerProps
{
isVisble
:
boolean
;
closeExpDrawer
:
()
=>
void
;
}
interface
ExpDrawerState
{
experiment
:
string
;
}
class
ExperimentDrawer
extends
React
.
Component
<
ExpDrawerProps
,
ExpDrawerState
>
{
public
_isCompareMount
:
boolean
;
constructor
(
props
:
ExpDrawerProps
)
{
super
(
props
);
this
.
state
=
{
experiment
:
''
};
}
getExperimentContent
=
()
=>
{
axios
.
all
([
axios
.
get
(
`
${
MANAGER_IP
}
/experiment`
),
axios
.
get
(
`
${
MANAGER_IP
}
/trial-jobs`
),
axios
.
get
(
`
${
MANAGER_IP
}
/metric-data`
)
])
.
then
(
axios
.
spread
((
res
,
res1
,
res2
)
=>
{
if
(
res
.
status
===
200
&&
res1
.
status
===
200
&&
res2
.
status
===
200
)
{
if
(
res
.
data
.
params
.
searchSpace
)
{
res
.
data
.
params
.
searchSpace
=
JSON
.
parse
(
res
.
data
.
params
.
searchSpace
);
}
let
trialMessagesArr
=
res1
.
data
;
const
interResultList
=
res2
.
data
;
Object
.
keys
(
trialMessagesArr
).
map
(
item
=>
{
// transform hyperparameters as object to show elegantly
trialMessagesArr
[
item
].
hyperParameters
=
JSON
.
parse
(
trialMessagesArr
[
item
].
hyperParameters
);
const
trialId
=
trialMessagesArr
[
item
].
id
;
// add intermediate result message
trialMessagesArr
[
item
].
intermediate
=
[];
Object
.
keys
(
interResultList
).
map
(
key
=>
{
const
interId
=
interResultList
[
key
].
trialJobId
;
if
(
trialId
===
interId
)
{
trialMessagesArr
[
item
].
intermediate
.
push
(
interResultList
[
key
]);
}
});
});
const
result
=
{
experimentParameters
:
res
.
data
,
trialMessage
:
trialMessagesArr
};
if
(
this
.
_isCompareMount
===
true
)
{
this
.
setState
(()
=>
({
experiment
:
JSON
.
stringify
(
result
,
null
,
4
)
}));
}
}
}));
}
downExperimentParameters
=
()
=>
{
const
{
experiment
}
=
this
.
state
;
downFile
(
experiment
,
'
experiment.json
'
);
}
componentDidMount
()
{
this
.
_isCompareMount
=
true
;
this
.
getExperimentContent
();
}
componentWillReceiveProps
(
nextProps
:
ExpDrawerProps
)
{
const
{
isVisble
}
=
nextProps
;
if
(
isVisble
===
true
)
{
this
.
getExperimentContent
();
}
}
componentWillUnmount
()
{
this
.
_isCompareMount
=
false
;
}
render
()
{
const
{
isVisble
,
closeExpDrawer
}
=
this
.
props
;
const
{
experiment
}
=
this
.
state
;
const
heights
:
number
=
window
.
innerHeight
-
48
;
return
(
<
Row
className
=
"logDrawer"
>
<
Drawer
// title="Log Message"
placement
=
"right"
closable
=
{
false
}
destroyOnClose
=
{
true
}
onClose
=
{
closeExpDrawer
}
visible
=
{
isVisble
}
width
=
"54%"
height
=
{
heights
}
>
<
div
className
=
"card-container log-tab-body"
style
=
{
{
height
:
heights
}
}
>
<
Tabs
type
=
"card"
>
<
TabPane
tab
=
"Experiment Parameters"
key
=
"Experiment"
>
<
div
className
=
"just-for-log"
>
<
MonacoEditor
width
=
"100%"
height
=
{
heights
*
0.9
}
language
=
"json"
value
=
{
experiment
}
options
=
{
DRAWEROPTION
}
/>
</
div
>
<
Row
className
=
"buttons"
>
<
Col
span
=
{
12
}
>
<
Button
type
=
"primary"
onClick
=
{
this
.
downExperimentParameters
}
>
Download
</
Button
>
</
Col
>
<
Col
span
=
{
12
}
className
=
"close"
>
<
Button
type
=
"default"
onClick
=
{
closeExpDrawer
}
>
Close
</
Button
>
</
Col
>
</
Row
>
</
TabPane
>
</
Tabs
>
</
div
>
</
Drawer
>
</
Row
>
);
}
}
export
default
ExperimentDrawer
;
src/webui/src/components/Modal/LogDrawer.tsx
0 → 100644
View file @
cb25d66e
import
*
as
React
from
'
react
'
;
import
axios
from
'
axios
'
;
import
{
Drawer
,
Tabs
,
Row
,
Col
,
Button
,
Icon
}
from
'
antd
'
;
import
{
DOWNLOAD_IP
}
from
'
../../static/const
'
;
import
{
downFile
}
from
'
../../static/function
'
;
const
{
TabPane
}
=
Tabs
;
import
MonacoHTML
from
'
../public-child/MonacoEditor
'
;
import
'
../../static/style/logDrawer.scss
'
;
interface
LogDrawerProps
{
isVisble
:
boolean
;
closeDrawer
:
()
=>
void
;
activeTab
?:
string
;
}
interface
LogDrawerState
{
nniManagerLogStr
:
string
;
dispatcherLogStr
:
string
;
isLoading
:
boolean
;
isLoadispatcher
:
boolean
;
}
class
LogDrawer
extends
React
.
Component
<
LogDrawerProps
,
LogDrawerState
>
{
public
_isLogDrawer
:
boolean
;
constructor
(
props
:
LogDrawerProps
)
{
super
(
props
);
this
.
state
=
{
nniManagerLogStr
:
'
nnimanager
'
,
dispatcherLogStr
:
'
dispatcher
'
,
isLoading
:
false
,
isLoadispatcher
:
false
};
}
getNNImanagerLogmessage
=
()
=>
{
if
(
this
.
_isLogDrawer
===
true
)
{
this
.
setState
({
isLoading
:
true
},
()
=>
{
axios
(
`
${
DOWNLOAD_IP
}
/nnimanager.log`
,
{
method
:
'
GET
'
})
.
then
(
res
=>
{
if
(
res
.
status
===
200
)
{
setTimeout
(()
=>
{
this
.
setNNImanager
(
res
.
data
);
},
300
);
}
});
});
}
}
setDispatcher
=
(
value
:
string
)
=>
{
if
(
this
.
_isLogDrawer
===
true
)
{
this
.
setState
(()
=>
({
isLoadispatcher
:
false
,
dispatcherLogStr
:
value
}));
}
}
setNNImanager
=
(
val
:
string
)
=>
{
if
(
this
.
_isLogDrawer
===
true
)
{
this
.
setState
(()
=>
({
isLoading
:
false
,
nniManagerLogStr
:
val
}));
}
}
getdispatcherLogmessage
=
()
=>
{
if
(
this
.
_isLogDrawer
===
true
)
{
this
.
setState
({
isLoadispatcher
:
true
},
()
=>
{
axios
(
`
${
DOWNLOAD_IP
}
/dispatcher.log`
,
{
method
:
'
GET
'
})
.
then
(
res
=>
{
if
(
res
.
status
===
200
)
{
setTimeout
(()
=>
{
this
.
setDispatcher
(
res
.
data
);
},
300
);
}
});
});
}
}
downloadNNImanager
=
()
=>
{
const
{
nniManagerLogStr
}
=
this
.
state
;
downFile
(
nniManagerLogStr
,
'
nnimanager.log
'
);
}
downloadDispatcher
=
()
=>
{
const
{
dispatcherLogStr
}
=
this
.
state
;
downFile
(
dispatcherLogStr
,
'
dispatcher.log
'
);
}
dispatcherHTML
=
()
=>
{
return
(
<
div
>
<
span
>
Dispatcher Log
</
span
>
<
span
className
=
"refresh"
onClick
=
{
this
.
getdispatcherLogmessage
}
>
<
Icon
type
=
"sync"
/>
</
span
>
</
div
>
);
}
nnimanagerHTML
=
()
=>
{
return
(
<
div
>
<
span
>
NNImanager Log
</
span
>
<
span
className
=
"refresh"
onClick
=
{
this
.
getNNImanagerLogmessage
}
><
Icon
type
=
"sync"
/></
span
>
</
div
>
);
}
componentDidMount
()
{
this
.
_isLogDrawer
=
true
;
this
.
getNNImanagerLogmessage
();
this
.
getdispatcherLogmessage
();
}
componentWillReceiveProps
(
nextProps
:
LogDrawerProps
)
{
const
{
isVisble
,
activeTab
}
=
nextProps
;
if
(
isVisble
===
true
)
{
if
(
activeTab
===
'
nnimanager
'
)
{
this
.
getNNImanagerLogmessage
();
}
if
(
activeTab
===
'
dispatcher
'
)
{
this
.
getdispatcherLogmessage
();
}
}
}
componentWillUnmount
()
{
this
.
_isLogDrawer
=
false
;
}
render
()
{
const
{
isVisble
,
closeDrawer
,
activeTab
}
=
this
.
props
;
const
{
nniManagerLogStr
,
dispatcherLogStr
,
isLoadispatcher
,
isLoading
}
=
this
.
state
;
const
heights
:
number
=
window
.
innerHeight
-
48
;
// padding top and bottom
return
(
<
Row
>
<
Drawer
placement
=
"right"
closable
=
{
false
}
destroyOnClose
=
{
true
}
onClose
=
{
closeDrawer
}
visible
=
{
isVisble
}
width
=
"76%"
height
=
{
heights
}
// className="logDrawer"
>
<
div
className
=
"card-container log-tab-body"
style
=
{
{
height
:
heights
}
}
>
<
Tabs
type
=
"card"
defaultActiveKey
=
{
activeTab
}
>
{
/* <Tabs type="card" onTabClick={this.selectwhichLog} defaultActiveKey={activeTab}> */
}
{
/* <TabPane tab="Dispatcher Log" key="dispatcher"> */
}
<
TabPane
tab
=
{
this
.
dispatcherHTML
()
}
key
=
"dispatcher"
>
<
div
>
<
MonacoHTML
content
=
{
dispatcherLogStr
}
loading
=
{
isLoadispatcher
}
/>
</
div
>
<
Row
className
=
"buttons"
>
<
Col
span
=
{
12
}
>
<
Button
type
=
"primary"
onClick
=
{
this
.
downloadDispatcher
}
>
Download
</
Button
>
</
Col
>
<
Col
span
=
{
12
}
className
=
"close"
>
<
Button
type
=
"default"
onClick
=
{
closeDrawer
}
>
Close
</
Button
>
</
Col
>
</
Row
>
</
TabPane
>
<
TabPane
tab
=
{
this
.
nnimanagerHTML
()
}
key
=
"nnimanager"
>
{
/* <TabPane tab="NNImanager Log" key="nnimanager"> */
}
<
div
>
<
MonacoHTML
content
=
{
nniManagerLogStr
}
loading
=
{
isLoading
}
/>
</
div
>
<
Row
className
=
"buttons"
>
<
Col
span
=
{
12
}
className
=
"download"
>
<
Button
type
=
"primary"
onClick
=
{
this
.
downloadNNImanager
}
>
Download
</
Button
>
</
Col
>
<
Col
span
=
{
12
}
className
=
"close"
>
<
Button
type
=
"default"
onClick
=
{
closeDrawer
}
>
Close
</
Button
>
</
Col
>
</
Row
>
</
TabPane
>
</
Tabs
>
</
div
>
</
Drawer
>
</
Row
>
);
}
}
export
default
LogDrawer
;
src/webui/src/components/SlideBar.tsx
View file @
cb25d66e
...
...
@@ -3,10 +3,11 @@ import { Link } from 'react-router';
import
axios
from
'
axios
'
;
import
{
MANAGER_IP
}
from
'
../static/const
'
;
import
MediaQuery
from
'
react-responsive
'
;
import
{
DOWNLOAD_IP
}
from
'
../static/const
'
;
import
{
Row
,
Col
,
Menu
,
Dropdown
,
Icon
,
Select
,
Button
}
from
'
antd
'
;
const
{
SubMenu
}
=
Menu
;
const
{
Option
}
=
Select
;
import
LogDrawer
from
'
./Modal/LogDrawer
'
;
import
ExperimentDrawer
from
'
./Modal/ExperimentDrawer
'
;
import
'
../static/style/slideBar.scss
'
;
import
'
../static/style/button.scss
'
;
...
...
@@ -15,6 +16,9 @@ interface SliderState {
menuVisible
:
boolean
;
navBarVisible
:
boolean
;
isdisabledFresh
:
boolean
;
isvisibleLogDrawer
:
boolean
;
isvisibleExperimentDrawer
:
boolean
;
activeKey
:
string
;
}
interface
SliderProps
{
...
...
@@ -38,124 +42,13 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
version
:
''
,
menuVisible
:
false
,
navBarVisible
:
false
,
isdisabledFresh
:
false
isdisabledFresh
:
false
,
isvisibleLogDrawer
:
false
,
// download button (nnimanager·dispatcher) click -> drawer
isvisibleExperimentDrawer
:
false
,
activeKey
:
'
dispatcher
'
};
}
downExperimentContent
=
()
=>
{
axios
.
all
([
axios
.
get
(
`
${
MANAGER_IP
}
/experiment`
),
axios
.
get
(
`
${
MANAGER_IP
}
/trial-jobs`
),
axios
.
get
(
`
${
MANAGER_IP
}
/metric-data`
)
])
.
then
(
axios
.
spread
((
res
,
res1
,
res2
)
=>
{
if
(
res
.
status
===
200
&&
res1
.
status
===
200
&&
res2
.
status
===
200
)
{
if
(
res
.
data
.
params
.
searchSpace
)
{
res
.
data
.
params
.
searchSpace
=
JSON
.
parse
(
res
.
data
.
params
.
searchSpace
);
}
const
isEdge
=
navigator
.
userAgent
.
indexOf
(
'
Edge
'
)
!==
-
1
?
true
:
false
;
let
trialMessagesArr
=
res1
.
data
;
const
interResultList
=
res2
.
data
;
Object
.
keys
(
trialMessagesArr
).
map
(
item
=>
{
// transform hyperparameters as object to show elegantly
trialMessagesArr
[
item
].
hyperParameters
=
JSON
.
parse
(
trialMessagesArr
[
item
].
hyperParameters
);
const
trialId
=
trialMessagesArr
[
item
].
id
;
// add intermediate result message
trialMessagesArr
[
item
].
intermediate
=
[];
Object
.
keys
(
interResultList
).
map
(
key
=>
{
const
interId
=
interResultList
[
key
].
trialJobId
;
if
(
trialId
===
interId
)
{
trialMessagesArr
[
item
].
intermediate
.
push
(
interResultList
[
key
]);
}
});
});
const
result
=
{
experimentParameters
:
res
.
data
,
trialMessage
:
trialMessagesArr
};
const
aTag
=
document
.
createElement
(
'
a
'
);
const
file
=
new
Blob
([
JSON
.
stringify
(
result
,
null
,
4
)],
{
type
:
'
application/json
'
});
aTag
.
download
=
'
experiment.json
'
;
aTag
.
href
=
URL
.
createObjectURL
(
file
);
aTag
.
click
();
if
(
!
isEdge
)
{
URL
.
revokeObjectURL
(
aTag
.
href
);
}
if
(
navigator
.
userAgent
.
indexOf
(
'
Firefox
'
)
>
-
1
)
{
const
downTag
=
document
.
createElement
(
'
a
'
);
downTag
.
addEventListener
(
'
click
'
,
function
()
{
downTag
.
download
=
'
experiment.json
'
;
downTag
.
href
=
URL
.
createObjectURL
(
file
);
});
let
eventMouse
=
document
.
createEvent
(
'
MouseEvents
'
);
eventMouse
.
initEvent
(
'
click
'
,
false
,
false
);
downTag
.
dispatchEvent
(
eventMouse
);
}
}
}));
}
downnnimanagerLog
=
()
=>
{
axios
(
`
${
DOWNLOAD_IP
}
/nnimanager.log`
,
{
method
:
'
GET
'
})
.
then
(
res
=>
{
if
(
res
.
status
===
200
)
{
const
nniLogfile
=
res
.
data
;
const
aTag
=
document
.
createElement
(
'
a
'
);
const
isEdge
=
navigator
.
userAgent
.
indexOf
(
'
Edge
'
)
!==
-
1
?
true
:
false
;
const
file
=
new
Blob
([
nniLogfile
],
{
type
:
'
application/json
'
});
aTag
.
download
=
'
nnimanagerLog.log
'
;
aTag
.
href
=
URL
.
createObjectURL
(
file
);
aTag
.
click
();
if
(
!
isEdge
)
{
URL
.
revokeObjectURL
(
aTag
.
href
);
}
if
(
navigator
.
userAgent
.
indexOf
(
'
Firefox
'
)
>
-
1
)
{
const
downTag
=
document
.
createElement
(
'
a
'
);
downTag
.
addEventListener
(
'
click
'
,
function
()
{
downTag
.
download
=
'
nnimanagerLog.log
'
;
downTag
.
href
=
URL
.
createObjectURL
(
file
);
});
let
eventMouse
=
document
.
createEvent
(
'
MouseEvents
'
);
eventMouse
.
initEvent
(
'
click
'
,
false
,
false
);
downTag
.
dispatchEvent
(
eventMouse
);
}
}
});
}
downDispatcherlog
=
()
=>
{
axios
(
`
${
DOWNLOAD_IP
}
/dispatcher.log`
,
{
method
:
'
GET
'
})
.
then
(
res
=>
{
if
(
res
.
status
===
200
)
{
const
dispatchLogfile
=
res
.
data
;
const
aTag
=
document
.
createElement
(
'
a
'
);
const
isEdge
=
navigator
.
userAgent
.
indexOf
(
'
Edge
'
)
!==
-
1
?
true
:
false
;
const
file
=
new
Blob
([
dispatchLogfile
],
{
type
:
'
application/json
'
});
aTag
.
download
=
'
dispatcherLog.log
'
;
aTag
.
href
=
URL
.
createObjectURL
(
file
);
aTag
.
click
();
if
(
!
isEdge
)
{
URL
.
revokeObjectURL
(
aTag
.
href
);
}
if
(
navigator
.
userAgent
.
indexOf
(
'
Firefox
'
)
>
-
1
)
{
const
downTag
=
document
.
createElement
(
'
a
'
);
downTag
.
addEventListener
(
'
click
'
,
function
()
{
downTag
.
download
=
'
dispatcherLog.log
'
;
downTag
.
href
=
URL
.
createObjectURL
(
file
);
});
let
eventMouse
=
document
.
createEvent
(
'
MouseEvents
'
);
eventMouse
.
initEvent
(
'
click
'
,
false
,
false
);
downTag
.
dispatchEvent
(
eventMouse
);
}
}
});
}
getNNIversion
=
()
=>
{
axios
(
`
${
MANAGER_IP
}
/version`
,
{
method
:
'
GET
'
...
...
@@ -170,17 +63,23 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
handleMenuClick
=
(
e
:
EventPer
)
=>
{
if
(
this
.
_isMounted
)
{
this
.
setState
({
menuVisible
:
false
});
}
switch
(
e
.
key
)
{
// download experiment
related content
//
to see &
download experiment
parameters
case
'
1
'
:
this
.
downExperimentContent
();
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
isvisibleExperimentDrawer
:
true
}));
}
break
;
// download nnimanager log
file
//
to see &
download nnimanager log
case
'
2
'
:
this
.
downnnimanagerLog
();
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
activeKey
:
'
nnimanager
'
,
isvisibleLogDrawer
:
true
}));
}
break
;
// download dispatcher log
file
//
to see &
download dispatcher log
case
'
3
'
:
this
.
downDispatcherlog
();
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
isvisibleLogDrawer
:
true
,
activeKey
:
'
dispatcher
'
}));
}
break
;
case
'
close
'
:
case
'
10
'
:
...
...
@@ -285,6 +184,20 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
}
}
// close log drawer (nnimanager.dispatcher)
closeLogDrawer
=
()
=>
{
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
isvisibleLogDrawer
:
false
,
activeKey
:
''
}));
}
}
// close download experiment parameters drawer
closeExpDrawer
=
()
=>
{
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
isvisibleExperimentDrawer
:
false
}));
}
}
componentDidMount
()
{
this
.
_isMounted
=
true
;
this
.
getNNIversion
();
...
...
@@ -295,79 +208,91 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
}
render
()
{
const
{
version
,
menuVisible
}
=
this
.
state
;
const
{
version
,
menuVisible
,
isvisibleLogDrawer
,
activeKey
,
isvisibleExperimentDrawer
}
=
this
.
state
;
const
feed
=
`https://github.com/Microsoft/nni/issues/new?labels=
${
version
}
`
;
return
(
<
Row
>
<
Col
span
=
{
18
}
>
<
MediaQuery
query
=
"(min-width: 1299px)"
>
<
Row
className
=
"nav"
>
<
ul
className
=
"link"
>
<
li
className
=
"logo"
>
<
Row
>
<
Col
span
=
{
18
}
>
<
MediaQuery
query
=
"(min-width: 1299px)"
>
<
Row
className
=
"nav"
>
<
ul
className
=
"link"
>
<
li
className
=
"logo"
>
<
Link
to
=
{
'
/oview
'
}
>
<
img
src
=
{
require
(
'
../static/img/logo2.png
'
)
}
style
=
{
{
width
:
88
}
}
alt
=
"NNI logo"
/>
</
Link
>
</
li
>
<
li
className
=
"tab firstTab"
>
<
Link
to
=
{
'
/oview
'
}
activeClassName
=
"high"
>
Overview
</
Link
>
</
li
>
<
li
className
=
"tab"
>
<
Link
to
=
{
'
/detail
'
}
activeClassName
=
"high"
>
Trials detail
</
Link
>
</
li
>
<
li
className
=
"feedback"
>
<
Dropdown
className
=
"dropdown"
overlay
=
{
this
.
menu
()
}
onVisibleChange
=
{
this
.
handleVisibleChange
}
visible
=
{
menuVisible
}
trigger
=
{
[
'
click
'
]
}
>
<
a
className
=
"ant-dropdown-link"
href
=
"#"
>
Download
<
Icon
type
=
"down"
/>
</
a
>
</
Dropdown
>
<
a
href
=
{
feed
}
target
=
"_blank"
>
<
img
src
=
{
require
(
'
../static/img/icon/issue.png
'
)
}
alt
=
"NNI github issue"
/>
Feedback
</
a
>
<
span
className
=
"version"
>
Version:
{
version
}
</
span
>
</
li
>
</
ul
>
</
Row
>
</
MediaQuery
>
</
Col
>
<
Col
span
=
{
18
}
>
<
MediaQuery
query
=
"(max-width: 1299px)"
>
<
Row
className
=
"little"
>
<
Col
span
=
{
1
}
className
=
"menu"
>
<
Dropdown
overlay
=
{
this
.
navigationBar
()
}
trigger
=
{
[
'
click
'
]
}
>
<
Icon
type
=
"unordered-list"
className
=
"more"
/>
</
Dropdown
>
</
Col
>
<
Col
span
=
{
14
}
className
=
"logo"
>
<
Link
to
=
{
'
/oview
'
}
>
<
img
src
=
{
require
(
'
../static/img/logo2.png
'
)
}
style
=
{
{
width
:
8
8
}
}
style
=
{
{
width
:
8
0
}
}
alt
=
"NNI logo"
/>
</
Link
>
</
li
>
<
li
className
=
"tab firstTab"
>
<
Link
to
=
{
'
/oview
'
}
activeClassName
=
"high"
>
Overview
</
Link
>
</
li
>
<
li
className
=
"tab"
>
<
Link
to
=
{
'
/detail
'
}
activeClassName
=
"high"
>
Trials detail
</
Link
>
</
li
>
<
li
className
=
"feedback"
>
<
Dropdown
className
=
"dropdown"
overlay
=
{
this
.
menu
()
}
onVisibleChange
=
{
this
.
handleVisibleChange
}
visible
=
{
menuVisible
}
trigger
=
{
[
'
click
'
]
}
>
<
a
className
=
"ant-dropdown-link"
href
=
"#"
>
Download
<
Icon
type
=
"down"
/>
</
a
>
</
Dropdown
>
<
a
href
=
{
feed
}
target
=
"_blank"
>
<
img
src
=
{
require
(
'
../static/img/icon/issue.png
'
)
}
alt
=
"NNI github issue"
/>
Feedback
</
a
>
<
span
className
=
"version"
>
Version:
{
version
}
</
span
>
</
li
>
</
ul
>
</
Row
>
</
MediaQuery
>
</
Col
>
<
Col
span
=
{
18
}
>
<
MediaQuery
query
=
"(max-width: 1299px)"
>
<
Row
className
=
"little"
>
<
Col
span
=
{
1
}
className
=
"menu"
>
<
Dropdown
overlay
=
{
this
.
navigationBar
()
}
trigger
=
{
[
'
click
'
]
}
>
<
Icon
type
=
"unordered-list"
className
=
"more"
/>
</
Dropdown
>
</
Col
>
<
Col
span
=
{
14
}
className
=
"logo"
>
<
Link
to
=
{
'
/oview
'
}
>
<
img
src
=
{
require
(
'
../static/img/logo2.png
'
)
}
style
=
{
{
width
:
80
}
}
alt
=
"NNI logo"
/>
</
Link
>
</
Col
>
</
Row
>
</
MediaQuery
>
</
Col
>
<
Col
span
=
{
3
}
>
{
this
.
select
()
}
</
Col
>
</
Col
>
</
Row
>
</
MediaQuery
>
</
Col
>
<
Col
span
=
{
3
}
>
{
this
.
select
()
}
</
Col
>
</
Row
>
{
/* the drawer for dispatcher & nnimanager log message */
}
<
LogDrawer
isVisble
=
{
isvisibleLogDrawer
}
closeDrawer
=
{
this
.
closeLogDrawer
}
activeTab
=
{
activeKey
}
/>
<
ExperimentDrawer
isVisble
=
{
isvisibleExperimentDrawer
}
closeExpDrawer
=
{
this
.
closeExpDrawer
}
/>
</
Row
>
);
}
...
...
src/webui/src/components/overview/Progress.tsx
View file @
cb25d66e
...
...
@@ -7,6 +7,7 @@ import { MANAGER_IP, CONTROLTYPE } from '../../static/const';
import
{
Experiment
,
TrialNumber
}
from
'
../../static/interface
'
;
import
{
convertTime
}
from
'
../../static/function
'
;
import
ProgressBar
from
'
./ProgressItem
'
;
import
LogDrawer
from
'
../Modal/LogDrawer
'
;
import
'
../../static/style/progress.scss
'
;
import
'
../../static/style/probar.scss
'
;
...
...
@@ -24,6 +25,7 @@ interface ProgressState {
isEnable
:
boolean
;
userInputVal
:
string
;
// get user input
cancelSty
:
string
;
isShowLogDrawer
:
boolean
;
}
class
Progressed
extends
React
.
Component
<
ProgressProps
,
ProgressState
>
{
...
...
@@ -36,7 +38,8 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
btnName
:
'
Edit
'
,
isEnable
:
true
,
userInputVal
:
this
.
props
.
trialProfile
.
runConcurren
.
toString
(),
cancelSty
:
'
none
'
cancelSty
:
'
none
'
,
isShowLogDrawer
:
false
};
}
...
...
@@ -139,6 +142,18 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
}
}
isShowDrawer
=
()
=>
{
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
isShowLogDrawer
:
true
}));
}
}
closeDrawer
=
()
=>
{
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
isShowLogDrawer
:
false
}));
}
}
componentWillReceiveProps
()
{
const
{
trialProfile
}
=
this
.
props
;
if
(
this
.
conInput
!==
null
)
{
...
...
@@ -156,7 +171,7 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
render
()
{
const
{
trialProfile
,
trialNumber
,
bestAccuracy
,
status
,
errors
}
=
this
.
props
;
const
{
isEnable
,
btnName
,
cancelSty
}
=
this
.
state
;
const
{
isEnable
,
btnName
,
cancelSty
,
isShowLogDrawer
}
=
this
.
state
;
const
bar2
=
trialNumber
.
totalCurrentTrial
-
trialNumber
.
waitTrial
-
trialNumber
.
unknowTrial
;
const
bar2Percent
=
(
bar2
/
trialProfile
.
MaxTrialNum
)
*
100
;
const
percent
=
(
trialProfile
.
execDuration
/
trialProfile
.
maxDuration
)
*
100
;
...
...
@@ -173,6 +188,7 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
errorContent
=
(
<
div
className
=
"errors"
>
{
errors
}
<
div
><
a
href
=
"#"
onClick
=
{
this
.
isShowDrawer
}
>
Learn about
</
a
></
div
>
</
div
>
);
}
...
...
@@ -282,8 +298,13 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
<
div
>
{
trialNumber
.
failTrial
}
</
div
>
</
Row
>
</
Col
>
</
Row
>
{
/* learn about click -> default active key is dispatcher. */
}
<
LogDrawer
isVisble
=
{
isShowLogDrawer
}
closeDrawer
=
{
this
.
closeDrawer
}
activeTab
=
"dispatcher"
/>
</
Row
>
);
}
...
...
src/webui/src/components/public-child/MonacoEditor.tsx
0 → 100644
View file @
cb25d66e
import
*
as
React
from
'
react
'
;
import
{
Spin
}
from
'
antd
'
;
import
{
DRAWEROPTION
}
from
'
../../static/const
'
;
import
MonacoEditor
from
'
react-monaco-editor
'
;
interface
MonacoEditorProps
{
content
:
string
;
loading
:
boolean
;
}
class
MonacoHTML
extends
React
.
Component
<
MonacoEditorProps
,
{}
>
{
public
_isMonacoMount
:
boolean
;
constructor
(
props
:
MonacoEditorProps
)
{
super
(
props
);
}
componentDidMount
()
{
this
.
_isMonacoMount
=
true
;
}
componentWillUnmount
()
{
this
.
_isMonacoMount
=
false
;
}
render
()
{
const
{
content
,
loading
}
=
this
.
props
;
const
heights
:
number
=
window
.
innerHeight
-
48
;
return
(
<
div
className
=
"just-for-log"
>
<
Spin
// tip="Loading..."
style
=
{
{
width
:
'
100%
'
,
height
:
heights
*
0.9
}
}
spinning
=
{
loading
}
>
<
MonacoEditor
width
=
"100%"
height
=
{
heights
*
0.9
}
language
=
"json"
value
=
{
content
}
options
=
{
DRAWEROPTION
}
/>
</
Spin
>
</
div
>
);
}
}
export
default
MonacoHTML
;
src/webui/src/static/const.ts
View file @
cb25d66e
...
...
@@ -19,6 +19,11 @@ const MONACO = {
readOnly
:
true
,
automaticLayout
:
true
};
const
DRAWEROPTION
=
{
minimap
:
{
enabled
:
false
},
readOnly
:
true
,
automaticLayout
:
true
};
const
COLUMN_INDEX
=
[
{
name
:
'
Trial No.
'
,
...
...
@@ -52,5 +57,5 @@ const COLUMN_INDEX = [
const
COLUMN
=
[
'
Trial No.
'
,
'
ID
'
,
'
Duration
'
,
'
Status
'
,
'
Default
'
,
'
Operation
'
,
'
Intermediate result
'
];
export
{
MANAGER_IP
,
DOWNLOAD_IP
,
trialJobStatus
,
CONTROLTYPE
,
MONACO
,
COLUMN
,
COLUMN_INDEX
CONTROLTYPE
,
MONACO
,
COLUMN
,
COLUMN_INDEX
,
DRAWEROPTION
};
src/webui/src/static/function.ts
View file @
cb25d66e
...
...
@@ -138,7 +138,29 @@ const filterDuration = (item: TableObj) => {
return
item
.
status
!==
'
WAITING
'
;
};
const
downFile
=
(
content
:
string
,
fileName
:
string
)
=>
{
const
aTag
=
document
.
createElement
(
'
a
'
);
const
isEdge
=
navigator
.
userAgent
.
indexOf
(
'
Edge
'
)
!==
-
1
?
true
:
false
;
const
file
=
new
Blob
([
content
],
{
type
:
'
application/json
'
});
aTag
.
download
=
fileName
;
aTag
.
href
=
URL
.
createObjectURL
(
file
);
aTag
.
click
();
if
(
!
isEdge
)
{
URL
.
revokeObjectURL
(
aTag
.
href
);
}
if
(
navigator
.
userAgent
.
indexOf
(
'
Firefox
'
)
>
-
1
)
{
const
downTag
=
document
.
createElement
(
'
a
'
);
downTag
.
addEventListener
(
'
click
'
,
function
()
{
downTag
.
download
=
fileName
;
downTag
.
href
=
URL
.
createObjectURL
(
file
);
});
let
eventMouse
=
document
.
createEvent
(
'
MouseEvents
'
);
eventMouse
.
initEvent
(
'
click
'
,
false
,
false
);
downTag
.
dispatchEvent
(
eventMouse
);
}
};
export
{
convertTime
,
convertDuration
,
getFinalResult
,
getFinal
,
convertTime
,
convertDuration
,
getFinalResult
,
getFinal
,
downFile
,
intermediateGraphOption
,
killJob
,
filterByStatus
,
filterDuration
};
src/webui/src/static/style/button.scss
View file @
cb25d66e
$btnBgcolor
:
#0071bc
;
Button
.tableButton
{
font-family
:
'Segoe UI'
,
Tahoma
,
Geneva
,
Verdana
,
sans-serif
;
background
:
$btnBgcolor
;
border-color
:
$btnBgcolor
;
height
:
26px
;
...
...
src/webui/src/static/style/compare.scss
View file @
cb25d66e
...
...
@@ -12,7 +12,7 @@
.column
{
max-width
:
124px
;
padding-left
:
18px
;
font-weight
:
7
00
;
font-weight
:
6
00
;
}
.value
{
max-width
:
152px
;
...
...
@@ -20,6 +20,6 @@
text-align
:
left
;
}
.idList
{
font-weight
:
7
00
;
font-weight
:
6
00
;
}
}
src/webui/src/static/style/control.scss
View file @
cb25d66e
...
...
@@ -55,7 +55,7 @@ div.addtitle{
font-size
:
20px
;
}
.line
{
font-weight
:
bold
;
font-weight
:
600
;
color
:
rgb
(
60
,
141
,
188
);
padding-right
:
20px
;
}
...
...
src/webui/src/static/style/logDrawer.scss
0 → 100644
View file @
cb25d66e
.card-container
>
.ant-tabs-card
>
.ant-tabs-content
{
margin-top
:
-16px
;
}
.card-container
>
.ant-tabs-card
>
.ant-tabs-content
>
.ant-tabs-tabpane
{
background
:
#fff
;
padding
:
16px
;
}
.card-container
>
.ant-tabs-card
>
.ant-tabs-bar
{
border-color
:
#fff
;
}
.card-container
>
.ant-tabs-card
>
.ant-tabs-bar
.ant-tabs-tab
{
border-color
:
transparent
;
background
:
transparent
;
}
.card-container
>
.ant-tabs-card
>
.ant-tabs-bar
.ant-tabs-tab-active
{
border-color
:
#fff
;
background
:
#fff
;
}
.logContainer
{
height
:
100%
;
}
.buttons
{
margin-top
:
15px
;
.close
{
text-align
:
right
;
}
}
/*
.logDrawer{
width: 100%;
.ant-drawer-body{
box-sizing: border-box;
-webkit-box-sizing: border-box;
}
}
*/
.ant-drawer-body
{
background
:
#333
;
}
.card-container
>
.ant-tabs-card
>
.ant-tabs-bar
{
border
:
none
;
}
.card-container
>
.ant-tabs-card
>
.ant-tabs-content
>
.ant-tabs-tabpane
{
background-color
:
#333
;
}
.close
{
Button
,
Button
:active
,
Button
:hover
{
background-color
:
#212121
;
color
:
#fff
;
border
:
none
;
}
}
.download
{
Button
,
Button
:active
,
Button
:hover
{
background-color
:
#2772be
;
color
:
#fff
;
border
:
none
;
}
}
.log-tab-body
>
.ant-tabs-card
>
.ant-tabs-bar
.ant-tabs-tab-active
{
background-color
:
#1e1e1e
;
color
:
#fff
;
border
:
none
;
}
.log-tab-body
.ant-tabs-nav
.ant-tabs-tab
:hover
,
.log-tab-body
.ant-tabs-nav
.ant-tabs-tab
{
color
:
#fff
;
border
:
none
;
}
.ant-tabs.ant-tabs-card
>
.ant-tabs-bar
.ant-tabs-tab
{
border
:
none
;
}
.log-tab-body
{
.refresh
{
margin-left
:
10px
;
display
:
none
;
}
.ant-tabs-tab-active
{
.refresh
{
transition
:
0
.3s
;
display
:
inline-block
;
}
.refresh
:hover
{
transform
:
scale
(
1
.2
);
}
}
}
.just-for-log
{
.monaco-editor
{
.line-numbers
{
color
:
#fff
;
}
.current-line
~
.line-numbers
{
color
:
#FFFAF0
;
}
}
.view-lines
{
background-color
:
#1e1e1e
;
.mtk1
{
color
:
#fff
;
}
}
.margin-view-overlays
{
background-color
:
#1e1e1e
;
}
}
src/webui/src/static/style/openRow.scss
View file @
cb25d66e
...
...
@@ -22,7 +22,7 @@ $bgColor: #f2f2f2;
}
.ant-tabs-nav
.ant-tabs-tab-active
{
color
:
$color
;
font-weight
:
5
00
;
font-weight
:
6
00
;
background
:
#dedede
;
border-left
:
3px
solid
;
}
...
...
src/webui/src/static/style/overviewTitle.scss
View file @
cb25d66e
...
...
@@ -5,6 +5,7 @@ $titleBgcolor: #b3b3b3;
}
.panelTitle
{
font-family
:
'Segoe UI'
,
Tahoma
,
Geneva
,
Verdana
,
sans-serif
;
width
:
100%
;
height
:
38px
;
background
:
$titleBgcolor
;
...
...
@@ -17,8 +18,7 @@ $titleBgcolor: #b3b3b3;
span
{
font-size
:
18px
;
font-weight
:
bold
;
font-family
:
'Segoe'
;
font-weight
:
600
;
color
:
#333
;
line-height
:
38px
;
margin-left
:
14px
;
...
...
src/webui/src/static/style/progress.scss
View file @
cb25d66e
...
...
@@ -4,7 +4,7 @@
.status
{
color
:
#0573bc
;
font-size
:
20px
;
font-weight
:
bold
;
font-weight
:
600
;
margin-top
:
5px
;
}
...
...
@@ -46,7 +46,7 @@
.basic
{
line-height
:
24px
;
font-family
:
'Segoe
'
;
font-family
:
'Segoe
UI'
,
Tahoma
,
Geneva
,
Verdana
,
sans-serif
;
p
{
font-size
:
14px
;
color
:
#212121
;
...
...
src/webui/src/static/style/slideBar.scss
View file @
cb25d66e
...
...
@@ -10,8 +10,8 @@ $drowHoverBgColor: #e2e2e2;
margin
:
0
auto
;
position
:
relative
;
.tab
{
font-family
:
'Segoe'
;
line-height
:
$barHeight
;
font-family
:
'Segoe UI'
,
Tahoma
,
Geneva
,
Verdana
,
sans-serif
;
a
{
font-size
:
18px
;
color
:
#b8c7ce
;
...
...
src/webui/src/static/style/table.scss
View file @
cb25d66e
...
...
@@ -26,7 +26,7 @@
}
/* add the brother selector to increase the priority */
#succeTable
.commonTableStyle
,
#tableList
.commonTableStyle
{
font-family
:
'Segoe UI'
,
Tahoma
,
Geneva
,
Verdana
,
sans-serif
;
tr
{
text-align
:
center
;
color
:
#212121
;
...
...
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment