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
257ceacc
Unverified
Commit
257ceacc
authored
Jul 17, 2019
by
Guoxin
Committed by
GitHub
Jul 17, 2019
Browse files
Merge pull request #1294 from lvybriage/error-log
[Fix issue#1173] UX improvement for showing Error log
parents
7c4bc33b
2118e711
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
688 additions
and
201 deletions
+688
-201
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.
src/webui/src/App.css
View file @
257ceacc
.nni
{
.nni
{
font-family
:
'Segoe UI'
,
Tahoma
,
Geneva
,
Verdana
,
sans-serif
;
color
:
#212121
;
color
:
#212121
;
font-size
:
14px
;
font-size
:
14px
;
background
:
#f2f2f2
;
background
:
#f2f2f2
;
...
...
src/webui/src/components/Modal/ExperimentDrawer.tsx
0 → 100644
View file @
257ceacc
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 @
257ceacc
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 @
257ceacc
...
@@ -3,10 +3,11 @@ import { Link } from 'react-router';
...
@@ -3,10 +3,11 @@ import { Link } from 'react-router';
import
axios
from
'
axios
'
;
import
axios
from
'
axios
'
;
import
{
MANAGER_IP
}
from
'
../static/const
'
;
import
{
MANAGER_IP
}
from
'
../static/const
'
;
import
MediaQuery
from
'
react-responsive
'
;
import
MediaQuery
from
'
react-responsive
'
;
import
{
DOWNLOAD_IP
}
from
'
../static/const
'
;
import
{
Row
,
Col
,
Menu
,
Dropdown
,
Icon
,
Select
,
Button
}
from
'
antd
'
;
import
{
Row
,
Col
,
Menu
,
Dropdown
,
Icon
,
Select
,
Button
}
from
'
antd
'
;
const
{
SubMenu
}
=
Menu
;
const
{
SubMenu
}
=
Menu
;
const
{
Option
}
=
Select
;
const
{
Option
}
=
Select
;
import
LogDrawer
from
'
./Modal/LogDrawer
'
;
import
ExperimentDrawer
from
'
./Modal/ExperimentDrawer
'
;
import
'
../static/style/slideBar.scss
'
;
import
'
../static/style/slideBar.scss
'
;
import
'
../static/style/button.scss
'
;
import
'
../static/style/button.scss
'
;
...
@@ -15,6 +16,9 @@ interface SliderState {
...
@@ -15,6 +16,9 @@ interface SliderState {
menuVisible
:
boolean
;
menuVisible
:
boolean
;
navBarVisible
:
boolean
;
navBarVisible
:
boolean
;
isdisabledFresh
:
boolean
;
isdisabledFresh
:
boolean
;
isvisibleLogDrawer
:
boolean
;
isvisibleExperimentDrawer
:
boolean
;
activeKey
:
string
;
}
}
interface
SliderProps
{
interface
SliderProps
{
...
@@ -38,124 +42,13 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
...
@@ -38,124 +42,13 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
version
:
''
,
version
:
''
,
menuVisible
:
false
,
menuVisible
:
false
,
navBarVisible
:
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
=
()
=>
{
getNNIversion
=
()
=>
{
axios
(
`
${
MANAGER_IP
}
/version`
,
{
axios
(
`
${
MANAGER_IP
}
/version`
,
{
method
:
'
GET
'
method
:
'
GET
'
...
@@ -170,17 +63,23 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
...
@@ -170,17 +63,23 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
handleMenuClick
=
(
e
:
EventPer
)
=>
{
handleMenuClick
=
(
e
:
EventPer
)
=>
{
if
(
this
.
_isMounted
)
{
this
.
setState
({
menuVisible
:
false
});
}
if
(
this
.
_isMounted
)
{
this
.
setState
({
menuVisible
:
false
});
}
switch
(
e
.
key
)
{
switch
(
e
.
key
)
{
// download experiment
related content
//
to see &
download experiment
parameters
case
'
1
'
:
case
'
1
'
:
this
.
downExperimentContent
();
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
isvisibleExperimentDrawer
:
true
}));
}
break
;
break
;
// download nnimanager log
file
//
to see &
download nnimanager log
case
'
2
'
:
case
'
2
'
:
this
.
downnnimanagerLog
();
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
activeKey
:
'
nnimanager
'
,
isvisibleLogDrawer
:
true
}));
}
break
;
break
;
// download dispatcher log
file
//
to see &
download dispatcher log
case
'
3
'
:
case
'
3
'
:
this
.
downDispatcherlog
();
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
isvisibleLogDrawer
:
true
,
activeKey
:
'
dispatcher
'
}));
}
break
;
break
;
case
'
close
'
:
case
'
close
'
:
case
'
10
'
:
case
'
10
'
:
...
@@ -285,6 +184,20 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
...
@@ -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
()
{
componentDidMount
()
{
this
.
_isMounted
=
true
;
this
.
_isMounted
=
true
;
this
.
getNNIversion
();
this
.
getNNIversion
();
...
@@ -295,79 +208,91 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
...
@@ -295,79 +208,91 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
}
}
render
()
{
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
}
`
;
const
feed
=
`https://github.com/Microsoft/nni/issues/new?labels=
${
version
}
`
;
return
(
return
(
<
Row
>
<
Row
>
<
Col
span
=
{
18
}
>
<
Row
>
<
MediaQuery
query
=
"(min-width: 1299px)"
>
<
Col
span
=
{
18
}
>
<
Row
className
=
"nav"
>
<
MediaQuery
query
=
"(min-width: 1299px)"
>
<
ul
className
=
"link"
>
<
Row
className
=
"nav"
>
<
li
className
=
"logo"
>
<
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
'
}
>
<
Link
to
=
{
'
/oview
'
}
>
<
img
<
img
src
=
{
require
(
'
../static/img/logo2.png
'
)
}
src
=
{
require
(
'
../static/img/logo2.png
'
)
}
style
=
{
{
width
:
8
8
}
}
style
=
{
{
width
:
8
0
}
}
alt
=
"NNI logo"
alt
=
"NNI logo"
/>
/>
</
Link
>
</
Link
>
</
li
>
</
Col
>
<
li
className
=
"tab firstTab"
>
</
Row
>
<
Link
to
=
{
'
/oview
'
}
activeClassName
=
"high"
>
</
MediaQuery
>
Overview
</
Col
>
</
Link
>
<
Col
span
=
{
3
}
>
{
this
.
select
()
}
</
Col
>
</
li
>
</
Row
>
<
li
className
=
"tab"
>
{
/* the drawer for dispatcher & nnimanager log message */
}
<
Link
to
=
{
'
/detail
'
}
activeClassName
=
"high"
>
<
LogDrawer
Trials detail
isVisble
=
{
isvisibleLogDrawer
}
</
Link
>
closeDrawer
=
{
this
.
closeLogDrawer
}
</
li
>
activeTab
=
{
activeKey
}
<
li
className
=
"feedback"
>
/>
<
Dropdown
<
ExperimentDrawer
className
=
"dropdown"
isVisble
=
{
isvisibleExperimentDrawer
}
overlay
=
{
this
.
menu
()
}
closeExpDrawer
=
{
this
.
closeExpDrawer
}
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
>
</
Row
>
</
Row
>
);
);
}
}
...
...
src/webui/src/components/overview/Progress.tsx
View file @
257ceacc
...
@@ -7,6 +7,7 @@ import { MANAGER_IP, CONTROLTYPE } from '../../static/const';
...
@@ -7,6 +7,7 @@ import { MANAGER_IP, CONTROLTYPE } from '../../static/const';
import
{
Experiment
,
TrialNumber
}
from
'
../../static/interface
'
;
import
{
Experiment
,
TrialNumber
}
from
'
../../static/interface
'
;
import
{
convertTime
}
from
'
../../static/function
'
;
import
{
convertTime
}
from
'
../../static/function
'
;
import
ProgressBar
from
'
./ProgressItem
'
;
import
ProgressBar
from
'
./ProgressItem
'
;
import
LogDrawer
from
'
../Modal/LogDrawer
'
;
import
'
../../static/style/progress.scss
'
;
import
'
../../static/style/progress.scss
'
;
import
'
../../static/style/probar.scss
'
;
import
'
../../static/style/probar.scss
'
;
...
@@ -24,6 +25,7 @@ interface ProgressState {
...
@@ -24,6 +25,7 @@ interface ProgressState {
isEnable
:
boolean
;
isEnable
:
boolean
;
userInputVal
:
string
;
// get user input
userInputVal
:
string
;
// get user input
cancelSty
:
string
;
cancelSty
:
string
;
isShowLogDrawer
:
boolean
;
}
}
class
Progressed
extends
React
.
Component
<
ProgressProps
,
ProgressState
>
{
class
Progressed
extends
React
.
Component
<
ProgressProps
,
ProgressState
>
{
...
@@ -36,7 +38,8 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
...
@@ -36,7 +38,8 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
btnName
:
'
Edit
'
,
btnName
:
'
Edit
'
,
isEnable
:
true
,
isEnable
:
true
,
userInputVal
:
this
.
props
.
trialProfile
.
runConcurren
.
toString
(),
userInputVal
:
this
.
props
.
trialProfile
.
runConcurren
.
toString
(),
cancelSty
:
'
none
'
cancelSty
:
'
none
'
,
isShowLogDrawer
:
false
};
};
}
}
...
@@ -139,6 +142,18 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
...
@@ -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
()
{
componentWillReceiveProps
()
{
const
{
trialProfile
}
=
this
.
props
;
const
{
trialProfile
}
=
this
.
props
;
if
(
this
.
conInput
!==
null
)
{
if
(
this
.
conInput
!==
null
)
{
...
@@ -156,7 +171,7 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
...
@@ -156,7 +171,7 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
render
()
{
render
()
{
const
{
trialProfile
,
trialNumber
,
bestAccuracy
,
status
,
errors
}
=
this
.
props
;
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
bar2
=
trialNumber
.
totalCurrentTrial
-
trialNumber
.
waitTrial
-
trialNumber
.
unknowTrial
;
const
bar2Percent
=
(
bar2
/
trialProfile
.
MaxTrialNum
)
*
100
;
const
bar2Percent
=
(
bar2
/
trialProfile
.
MaxTrialNum
)
*
100
;
const
percent
=
(
trialProfile
.
execDuration
/
trialProfile
.
maxDuration
)
*
100
;
const
percent
=
(
trialProfile
.
execDuration
/
trialProfile
.
maxDuration
)
*
100
;
...
@@ -173,6 +188,7 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
...
@@ -173,6 +188,7 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
errorContent
=
(
errorContent
=
(
<
div
className
=
"errors"
>
<
div
className
=
"errors"
>
{
errors
}
{
errors
}
<
div
><
a
href
=
"#"
onClick
=
{
this
.
isShowDrawer
}
>
Learn about
</
a
></
div
>
</
div
>
</
div
>
);
);
}
}
...
@@ -282,8 +298,13 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
...
@@ -282,8 +298,13 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
<
div
>
{
trialNumber
.
failTrial
}
</
div
>
<
div
>
{
trialNumber
.
failTrial
}
</
div
>
</
Row
>
</
Row
>
</
Col
>
</
Col
>
</
Row
>
</
Row
>
{
/* learn about click -> default active key is dispatcher. */
}
<
LogDrawer
isVisble
=
{
isShowLogDrawer
}
closeDrawer
=
{
this
.
closeDrawer
}
activeTab
=
"dispatcher"
/>
</
Row
>
</
Row
>
);
);
}
}
...
...
src/webui/src/components/public-child/MonacoEditor.tsx
0 → 100644
View file @
257ceacc
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 @
257ceacc
...
@@ -19,6 +19,11 @@ const MONACO = {
...
@@ -19,6 +19,11 @@ const MONACO = {
readOnly
:
true
,
readOnly
:
true
,
automaticLayout
:
true
automaticLayout
:
true
};
};
const
DRAWEROPTION
=
{
minimap
:
{
enabled
:
false
},
readOnly
:
true
,
automaticLayout
:
true
};
const
COLUMN_INDEX
=
[
const
COLUMN_INDEX
=
[
{
{
name
:
'
Trial No.
'
,
name
:
'
Trial No.
'
,
...
@@ -52,5 +57,5 @@ const COLUMN_INDEX = [
...
@@ -52,5 +57,5 @@ const COLUMN_INDEX = [
const
COLUMN
=
[
'
Trial No.
'
,
'
ID
'
,
'
Duration
'
,
'
Status
'
,
'
Default
'
,
'
Operation
'
,
'
Intermediate result
'
];
const
COLUMN
=
[
'
Trial No.
'
,
'
ID
'
,
'
Duration
'
,
'
Status
'
,
'
Default
'
,
'
Operation
'
,
'
Intermediate result
'
];
export
{
export
{
MANAGER_IP
,
DOWNLOAD_IP
,
trialJobStatus
,
MANAGER_IP
,
DOWNLOAD_IP
,
trialJobStatus
,
CONTROLTYPE
,
MONACO
,
COLUMN
,
COLUMN_INDEX
CONTROLTYPE
,
MONACO
,
COLUMN
,
COLUMN_INDEX
,
DRAWEROPTION
};
};
src/webui/src/static/function.ts
View file @
257ceacc
...
@@ -138,7 +138,29 @@ const filterDuration = (item: TableObj) => {
...
@@ -138,7 +138,29 @@ const filterDuration = (item: TableObj) => {
return
item
.
status
!==
'
WAITING
'
;
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
{
export
{
convertTime
,
convertDuration
,
getFinalResult
,
getFinal
,
convertTime
,
convertDuration
,
getFinalResult
,
getFinal
,
downFile
,
intermediateGraphOption
,
killJob
,
filterByStatus
,
filterDuration
intermediateGraphOption
,
killJob
,
filterByStatus
,
filterDuration
};
};
src/webui/src/static/style/button.scss
View file @
257ceacc
$btnBgcolor
:
#0071bc
;
$btnBgcolor
:
#0071bc
;
Button
.tableButton
{
Button
.tableButton
{
font-family
:
'Segoe UI'
,
Tahoma
,
Geneva
,
Verdana
,
sans-serif
;
background
:
$btnBgcolor
;
background
:
$btnBgcolor
;
border-color
:
$btnBgcolor
;
border-color
:
$btnBgcolor
;
height
:
26px
;
height
:
26px
;
...
...
src/webui/src/static/style/compare.scss
View file @
257ceacc
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
.column
{
.column
{
max-width
:
124px
;
max-width
:
124px
;
padding-left
:
18px
;
padding-left
:
18px
;
font-weight
:
7
00
;
font-weight
:
6
00
;
}
}
.value
{
.value
{
max-width
:
152px
;
max-width
:
152px
;
...
@@ -20,6 +20,6 @@
...
@@ -20,6 +20,6 @@
text-align
:
left
;
text-align
:
left
;
}
}
.idList
{
.idList
{
font-weight
:
7
00
;
font-weight
:
6
00
;
}
}
}
}
src/webui/src/static/style/control.scss
View file @
257ceacc
...
@@ -55,7 +55,7 @@ div.addtitle{
...
@@ -55,7 +55,7 @@ div.addtitle{
font-size
:
20px
;
font-size
:
20px
;
}
}
.line
{
.line
{
font-weight
:
bold
;
font-weight
:
600
;
color
:
rgb
(
60
,
141
,
188
);
color
:
rgb
(
60
,
141
,
188
);
padding-right
:
20px
;
padding-right
:
20px
;
}
}
...
...
src/webui/src/static/style/logDrawer.scss
0 → 100644
View file @
257ceacc
.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 @
257ceacc
...
@@ -22,7 +22,7 @@ $bgColor: #f2f2f2;
...
@@ -22,7 +22,7 @@ $bgColor: #f2f2f2;
}
}
.ant-tabs-nav
.ant-tabs-tab-active
{
.ant-tabs-nav
.ant-tabs-tab-active
{
color
:
$color
;
color
:
$color
;
font-weight
:
5
00
;
font-weight
:
6
00
;
background
:
#dedede
;
background
:
#dedede
;
border-left
:
3px
solid
;
border-left
:
3px
solid
;
}
}
...
...
src/webui/src/static/style/overviewTitle.scss
View file @
257ceacc
...
@@ -5,6 +5,7 @@ $titleBgcolor: #b3b3b3;
...
@@ -5,6 +5,7 @@ $titleBgcolor: #b3b3b3;
}
}
.panelTitle
{
.panelTitle
{
font-family
:
'Segoe UI'
,
Tahoma
,
Geneva
,
Verdana
,
sans-serif
;
width
:
100%
;
width
:
100%
;
height
:
38px
;
height
:
38px
;
background
:
$titleBgcolor
;
background
:
$titleBgcolor
;
...
@@ -17,8 +18,7 @@ $titleBgcolor: #b3b3b3;
...
@@ -17,8 +18,7 @@ $titleBgcolor: #b3b3b3;
span
{
span
{
font-size
:
18px
;
font-size
:
18px
;
font-weight
:
bold
;
font-weight
:
600
;
font-family
:
'Segoe'
;
color
:
#333
;
color
:
#333
;
line-height
:
38px
;
line-height
:
38px
;
margin-left
:
14px
;
margin-left
:
14px
;
...
...
src/webui/src/static/style/progress.scss
View file @
257ceacc
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
.status
{
.status
{
color
:
#0573bc
;
color
:
#0573bc
;
font-size
:
20px
;
font-size
:
20px
;
font-weight
:
bold
;
font-weight
:
600
;
margin-top
:
5px
;
margin-top
:
5px
;
}
}
...
@@ -46,7 +46,7 @@
...
@@ -46,7 +46,7 @@
.basic
{
.basic
{
line-height
:
24px
;
line-height
:
24px
;
font-family
:
'Segoe
'
;
font-family
:
'Segoe
UI'
,
Tahoma
,
Geneva
,
Verdana
,
sans-serif
;
p
{
p
{
font-size
:
14px
;
font-size
:
14px
;
color
:
#212121
;
color
:
#212121
;
...
...
src/webui/src/static/style/slideBar.scss
View file @
257ceacc
...
@@ -10,8 +10,8 @@ $drowHoverBgColor: #e2e2e2;
...
@@ -10,8 +10,8 @@ $drowHoverBgColor: #e2e2e2;
margin
:
0
auto
;
margin
:
0
auto
;
position
:
relative
;
position
:
relative
;
.tab
{
.tab
{
font-family
:
'Segoe'
;
line-height
:
$barHeight
;
line-height
:
$barHeight
;
font-family
:
'Segoe UI'
,
Tahoma
,
Geneva
,
Verdana
,
sans-serif
;
a
{
a
{
font-size
:
18px
;
font-size
:
18px
;
color
:
#b8c7ce
;
color
:
#b8c7ce
;
...
...
src/webui/src/static/style/table.scss
View file @
257ceacc
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
}
}
/* add the brother selector to increase the priority */
/* add the brother selector to increase the priority */
#succeTable
.commonTableStyle
,
#tableList
.commonTableStyle
{
#succeTable
.commonTableStyle
,
#tableList
.commonTableStyle
{
font-family
:
'Segoe UI'
,
Tahoma
,
Geneva
,
Verdana
,
sans-serif
;
tr
{
tr
{
text-align
:
center
;
text-align
:
center
;
color
:
#212121
;
color
:
#212121
;
...
...
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