Unverified Commit cb25d66e authored by SparkSnail's avatar SparkSnail Committed by GitHub
Browse files

Merge pull request #190 from microsoft/master

merge master
parents 9fb25ccc 7ee86e1d
configspace @ f389e1d0
Subproject commit f389e1d0a72564f7f1fd4d86039e5f393a45a058
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).
ConfigSpace==0.4.7
statsmodels==0.9.0
\ No newline at end of file
statsmodels==0.10.0
\ No newline at end of file
.nni{
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
color: #212121;
font-size: 14px;
background: #f2f2f2;
......
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;
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;
......@@ -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,9 +208,10 @@ 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>
<Row>
<Col span={18}>
<MediaQuery query="(min-width: 1299px)">
......@@ -369,6 +283,17 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
</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>
);
}
}
......
......@@ -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>
);
}
......
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;
......@@ -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
};
......@@ -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
};
$btnBgcolor: #0071bc;
Button.tableButton{
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: $btnBgcolor;
border-color: $btnBgcolor;
height: 26px;
......
......@@ -12,7 +12,7 @@
.column{
max-width: 124px;
padding-left: 18px;
font-weight: 700;
font-weight: 600;
}
.value{
max-width: 152px;
......@@ -20,6 +20,6 @@
text-align: left;
}
.idList{
font-weight: 700;
font-weight: 600;
}
}
......@@ -55,7 +55,7 @@ div.addtitle{
font-size: 20px;
}
.line{
font-weight: bold;
font-weight: 600;
color: rgb(60,141,188);
padding-right: 20px;
}
......
.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;
}
}
......@@ -22,7 +22,7 @@ $bgColor: #f2f2f2;
}
.ant-tabs-nav .ant-tabs-tab-active{
color: $color;
font-weight: 500;
font-weight: 600;
background: #dedede;
border-left: 3px solid ;
}
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
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