Commit 88b75065 authored by Lijiao's avatar Lijiao Committed by chicm-ms
Browse files

[Fixed issue#1230] Refactor webui nav (#1319)


* update margin

* modify tablet

* final version
parent 5445bf4b
......@@ -103,7 +103,7 @@ class ExperimentDrawer extends React.Component<ExpDrawerProps, ExpDrawerState> {
height={heights}
>
<div className="card-container log-tab-body" style={{ height: heights }}>
<Tabs type="card">
<Tabs type="card" style={{ height: heights + 19 }}>
<TabPane tab="Experiment Parameters" key="Experiment">
<div className="just-for-log">
<MonacoEditor
......@@ -115,7 +115,7 @@ class ExperimentDrawer extends React.Component<ExpDrawerProps, ExpDrawerState> {
/>
</div>
<Row className="buttons">
<Col span={12}>
<Col span={12} className="download">
<Button
type="primary"
onClick={this.downExperimentParameters}
......
......@@ -145,7 +145,7 @@ class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> {
// className="logDrawer"
>
<div className="card-container log-tab-body" style={{ height: heights }}>
<Tabs type="card" defaultActiveKey={activeTab}>
<Tabs type="card" defaultActiveKey={activeTab} style={{ height: heights + 19 }}>
{/* <Tabs type="card" onTabClick={this.selectwhichLog} defaultActiveKey={activeTab}> */}
{/* <TabPane tab="Dispatcher Log" key="dispatcher"> */}
<TabPane tab={this.dispatcherHTML()} key="dispatcher">
......@@ -153,7 +153,7 @@ class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> {
<MonacoHTML content={dispatcherLogStr} loading={isLoadispatcher} />
</div>
<Row className="buttons">
<Col span={12}>
<Col span={12} className="download">
<Button
type="primary"
onClick={this.downloadDispatcher}
......
......@@ -3,9 +3,12 @@ import { Link } from 'react-router';
import axios from 'axios';
import { MANAGER_IP } from '../static/const';
import MediaQuery from 'react-responsive';
import { Row, Col, Menu, Dropdown, Icon, Select, Button } from 'antd';
import { Row, Col, Menu, Dropdown, Icon, Select, Button, Form } from 'antd';
import { FormComponentProps } from 'antd/lib/form';
import { OVERVIEWTABS, DETAILTABS, NNILOGO } from './stateless-component/NNItabs';
const { SubMenu } = Menu;
const { Option } = Select;
const FormItem = Form.Item;
import LogDrawer from './Modal/LogDrawer';
import ExperimentDrawer from './Modal/ExperimentDrawer';
import '../static/style/slideBar.scss';
......@@ -21,7 +24,7 @@ interface SliderState {
activeKey: string;
}
interface SliderProps {
interface SliderProps extends FormComponentProps {
changeInterval: (value: number) => void;
changeFresh: (value: string) => void;
}
......@@ -122,9 +125,8 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
const { version } = this.state;
const feedBackLink = `https://github.com/Microsoft/nni/issues/new?labels=${version}`;
return (
<Menu onClick={this.handleMenuClick} className="menuModal">
<Menu.Item key="overview"><Link to={'/oview'}>Overview</Link></Menu.Item>
<Menu.Item key="detail"><Link to={'/detail'}>Trials detail</Link></Menu.Item>
<Menu onClick={this.handleMenuClick} className="menu-list" style={{ width: 216 }}>
{/* <Menu onClick={this.handleMenuClick} className="menu-list" style={{width: window.innerWidth}}> */}
<Menu.Item key="feedback">
<a href={feedBackLink} target="_blank">Feedback</a>
</Menu.Item>
......@@ -146,10 +148,46 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
);
}
mobileTabs = () => {
return (
// <Menu className="menuModal" style={{width: 880, position: 'fixed', left: 0, top: 56}}>
<Menu className="menuModal" style={{ padding: '0 10px' }}>
<Menu.Item key="overview"><Link to={'/oview'}>Overview</Link></Menu.Item>
<Menu.Item key="detail"><Link to={'/detail'}>Trials detail</Link></Menu.Item>
</Menu>
);
}
refreshInterval = () => {
const {
form: { getFieldDecorator },
// form: { getFieldDecorator, getFieldValue },
} = this.props;
return (
<Form>
<FormItem style={{ marginBottom: 0 }}>
{getFieldDecorator('interval', {
initialValue: 'Refresh every 10s',
})(
<Select onSelect={this.getInterval}>
<Option value="close">Disable Auto Refresh</Option>
<Option value="10">Refresh every 10s</Option>
<Option value="20">Refresh every 20s</Option>
<Option value="30">Refresh every 30s</Option>
<Option value="60">Refresh every 1min</Option>
</Select>,
)}
</FormItem>
</Form>
);
}
select = () => {
const { isdisabledFresh } = this.state;
return (
<div className="interval">
{this.refreshInterval()}
<Button
className="fresh"
onClick={this.fresh}
......@@ -158,16 +196,6 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
>
<Icon type="sync" /><span>Refresh</span>
</Button>
<Select
onSelect={this.getInterval}
defaultValue="Refresh every 10s"
>
<Option value="close">Disable Auto Refresh</Option>
<Option value="10">Refresh every 10s</Option>
<Option value="20">Refresh every 20s</Option>
<Option value="30">Refresh every 30s</Option>
<Option value="60">Refresh every 1min</Option>
</Select>
</div>
);
}
......@@ -184,59 +212,19 @@ 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();
}
componentWillUnmount() {
this._isMounted = false;
}
render() {
const { version, menuVisible, isvisibleLogDrawer, activeKey, isvisibleExperimentDrawer } = this.state;
desktopHTML = () => {
const { version, menuVisible } = this.state;
const feed = `https://github.com/Microsoft/nni/issues/new?labels=${version}`;
return (
<Row>
<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">
<Col span={8}>
<span className="desktop-logo">{NNILOGO}</span>
<span className="left-right-margin">{OVERVIEWTABS}</span>
<span>{DETAILTABS}</span>
</Col>
<Col span={16} className="desktop-right">
<span>{this.select()}</span>
<span>
<Dropdown
className="dropdown"
overlay={this.menu()}
......@@ -245,9 +233,19 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
trigger={['click']}
>
<a className="ant-dropdown-link" href="#">
Download <Icon type="down" />
<Icon type="download" className="down-icon" />
<span>Download</span>
{
menuVisible
?
<Icon type="up" className="margin-icon"/>
:
<Icon type="down" className="margin-icon"/>
}
</a>
</Dropdown>
</span>
<span className="feedback">
<a href={feed} target="_blank">
<img
src={require('../static/img/icon/issue.png')}
......@@ -255,34 +253,104 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
/>
Feedback
</a>
</span>
<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">
</Row>
);
}
tabeltHTML = () => {
return (
<Row className="nav">
<Col className="tabelt-left" span={14}>
<span>
<Dropdown overlay={this.navigationBar()} trigger={['click']}>
<Icon type="unordered-list" className="more" />
</Dropdown>
</span>
<span className="left-right-margin tabelt-img">{NNILOGO}</span>
<span>{OVERVIEWTABS}</span>
<span className="left-margin">{DETAILTABS}</span>
</Col>
<Col span={14} className="logo">
<Link to={'/oview'}>
<Col className="tabelt-right" span={10}>
{this.select()}
</Col>
</Row>
);
}
mobileHTML = () => {
const { isdisabledFresh } = this.state;
return (
<Row className="nav">
<Col className="left" span={8}>
<span>
<Dropdown className="more-mobile" overlay={this.navigationBar()} trigger={['click']}>
<Icon type="unordered-list" className="more" />
</Dropdown>
</span>
<span>
<Dropdown overlay={this.mobileTabs()} trigger={['click']}>
<a className="ant-dropdown-link" href="#">
<span>NNI <Icon type="down" /></span>
</a>
</Dropdown>
</span>
</Col>
<Col className="center" span={8}>
<img
src={require('../static/img/logo2.png')}
style={{ width: 80 }}
alt="NNI logo"
/>
</Link>
</Col>
</Row>
</MediaQuery>
{/* the class interval have other style ! */}
<Col className="right interval" span={8}>
<Button
className="fresh"
onClick={this.fresh}
type="ghost"
disabled={isdisabledFresh}
>
<Icon type="sync" /><span>Refresh</span>
</Button>
</Col>
<Col span={3}> {this.select()} </Col>
</Row>
);
}
// 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();
}
componentWillUnmount() {
this._isMounted = false;
}
render() {
const mobile = (<MediaQuery maxWidth={884}>{this.mobileHTML()}</MediaQuery>);
const tablet = (<MediaQuery minWidth={885} maxWidth={1241}>{this.tabeltHTML()}</MediaQuery>);
const desktop = (<MediaQuery minWidth={1242}>{this.desktopHTML()}</MediaQuery>);
const { isvisibleLogDrawer, activeKey, isvisibleExperimentDrawer } = this.state;
return (
<div>
{mobile}
{tablet}
{desktop}
{/* the drawer for dispatcher & nnimanager log message */}
<LogDrawer
isVisble={isvisibleLogDrawer}
......@@ -293,9 +361,9 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
isVisble={isvisibleExperimentDrawer}
closeExpDrawer={this.closeExpDrawer}
/>
</Row>
</div>
);
}
}
export default SlideBar;
\ No newline at end of file
export default Form.create<FormComponentProps>()(SlideBar);
\ No newline at end of file
import * as React from 'react';
import {
Row, Col, Popover, Button, message
} from 'antd';
import { Row, Col, Popover, Button, message } from 'antd';
import axios from 'axios';
import { MANAGER_IP, CONTROLTYPE } from '../../static/const';
import { Experiment, TrialNumber } from '../../static/interface';
......
import * as React from 'react';
import { Link } from 'react-router';
const OVERVIEWTABS = (
<Link to={'/oview'} activeClassName="high-light" className="common-tabs">
Overview
</Link>
);
const DETAILTABS = (
<Link to={'/detail'} activeClassName="high-light" className="common-tabs">
Trials detail
</Link>
);
const NNILOGO = (
<Link to={'/oview'}>
<img
src={require('../../static/img/logo2.png')}
alt="NNI logo"
style={{height: 40}}
/>
</Link>
);
export { OVERVIEWTABS, DETAILTABS, NNILOGO };
\ No newline at end of file
......@@ -49,4 +49,3 @@ table {
border-collapse: collapse;
border-spacing: 0;
}
\ No newline at end of file
......@@ -26,7 +26,7 @@
}
.buttons{
margin-top: 15px;
margin-top: 11px;
.close{
text-align: right;
}
......
......@@ -3,54 +3,6 @@ $barHeight: 56px;
$drowBgColor: #f2f2f2;
/* drowdown and select hover bgcolor */
$drowHoverBgColor: #e2e2e2;
.nav{
list-style: none;
width: 95%;
height: $barHeight;
margin: 0 auto;
position: relative;
.tab{
line-height: $barHeight;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
a{
font-size: 18px;
color: #b8c7ce;
text-decoration: none;
}
}
.firstTab{
margin: 0 20px;
}
.logo{
margin-top: 2px;
max-width: 128px;
}
}
.tab a:hover, .tab a.high{
color: white;
border-bottom: 1px solid #fff;
}
.feedback{
position: fixed;
right: 26%;
line-height: $barHeight;
font-size: 16px;
color: #fff;
a{
color: #fff;
text-decoration: none;
margin-left: 10px;
}
img{
width: 20px;
margin-right: 8px;
}
.version{
margin-left: 16px;
}
}
/* refresh button */
.fresh{
......@@ -63,20 +15,25 @@ $drowHoverBgColor: #e2e2e2;
color: #fff;
}
.link li{
float: left;
}
.dropdown{
margin-right: 10px;
/* make dropdown content box position in blue bar bottom */
padding-bottom: 14px;
.down-icon{
font-size: 20px !important;
padding-right: 2px;
}
}
.interval{
position: fixed;
right: 6%;
top: 12px;
display: inline-block;
font-size: 16px;
color: #fff;
.ant-form{
display: inline-block;
}
form .ant-select{
width: 166px;
}
.ant-select-selection{
background-color: transparent;
border: none;
......@@ -87,10 +44,19 @@ $drowHoverBgColor: #e2e2e2;
.ant-select-arrow{
color: #fff;
}
.fresh{
margin-right: 10px;
}
.ant-btn-ghost{
padding: 0 10px;
}
.ant-btn-ghost[disabled]{
background-color: transparent;
background-color: #005b98;
color: #fff;
}
}
/* set select bgcolor */
.ant-select-dropdown-menu{
......@@ -126,26 +92,141 @@ $drowHoverBgColor: #e2e2e2;
}
}
.menu-list{
position: relative;
top: 13px;
}
.ant-dropdown{
.menuModal{
position: relative;
top: 12px;
}
}
.ant-select-selection-selected-value{
font-size: 16px;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.ant-dropdown-menu-submenu-title{
font-size: 16px;
}
.ant-dropdown-menu-item:hover, .ant-dropdown-menu-submenu-title:hover{
background-color: transparent;
}
.nav{
width: 95%;
height: $barHeight;
margin: 0 auto;
line-height: $barHeight;
/* nav style*/
.little{
width: 90%;
.menu{
margin-left: 33px;
.more{
/* mobile start*/
.left{
text-align: left;
/* more menu */
font-size: 18px;
color: #fff;
font-size: 24px;
margin-top: 16px;
a, a:visited{
color: #fff;
text-decoration: none;
}
.more:hover{
.more-mobile{
margin-right: 10%;
font-size: 22px;
position: relative;
top: 1px;
}
.more-mobile:hover{
cursor: pointer;
}
}
.logo{
.center{
text-align: center;
img{
height: 38px;
}
}
.right{
text-align: right;
button{
margin-top: 12px;
}
}
/* mobile end */
/* tabelt mode */
.tabelt-left{
height: $barHeight;
.tabelt-img img{
position: relative;
top: -5px;
}
}
.tabelt-right{
text-align: right;
}
/* desktop mode */
.desktop-logo{
position: relative;
top: -3px;
}
.desktop-right{
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
text-align: right;
line-height: $barHeight;
font-size: 16px;
color: #fff;
a{
color: #fff;
text-decoration: none;
}
img{
width: 20px;
margin-right: 8px;
}
.feedback{
font-size: 16px;
margin: 0 20px;
}
.version{
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 16px;
}
.margin-icon{
margin-left: 8px;
}
}
}
/* public style in nav in threee mode*/
.more{
color: #fff;
font-size: 24px;
}
.more:hover{
cursor: pointer;
}
.menuModal{
width: 198px;
/* overview and detail tabs common style */
a.common-tabs{
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 16px;
color: #b8c7ce;
text-decoration: none;
}
.common-tabs:visited, .high-light:hover{
color: #fff;
text-decoration: none;
}
.common-tabs:hover, .high-light{
color: #fff;
border-bottom: 1px solid #fff;
}
.left-right-margin{
margin-left: 20px;
margin-right: 20px;
}
.left-margin{
margin-left: 20px;
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment