Commit 593a275c authored by Yuge Zhang's avatar Yuge Zhang
Browse files

Merge branch 'master' of https://github.com/microsoft/nni into dev-retiarii

parents b3cdee85 683c458a
import { AllExperimentList, SortInfo } from '../../static/interface';
import { copyAndSort } from '../../static/function';
function compareDate(date1: Date, date2: Date): boolean {
if (date1 !== undefined && date2 !== undefined) {
if (date1.getFullYear() === date2.getFullYear()) {
if (date1.getMonth() === date2.getMonth()) {
if (date1.getDate() === date2.getDate()) {
return true;
}
}
}
}
return false;
}
const filterByStatusOrPlatform = (val: string, type: string, data: AllExperimentList[]): AllExperimentList[] => {
return data.filter(temp => temp[type] === val);
};
function fillOptions(arr: string[]): any {
const list: Array<object> = [];
arr.map(item => {
list.push({ key: item, text: item });
});
return list;
}
function getSortedSource(source: AllExperimentList[], sortInfo: SortInfo): AllExperimentList[] {
const keepSortedSource = copyAndSort(source, sortInfo.field, sortInfo.isDescend);
return keepSortedSource;
}
export { compareDate, filterByStatusOrPlatform, fillOptions, getSortedSource };
const MAXSCREENCOLUMNWIDHT = 180;
const MINSCREENCOLUMNWIDHT = 139;
export { MAXSCREENCOLUMNWIDHT, MINSCREENCOLUMNWIDHT };
...@@ -58,16 +58,16 @@ class Compare extends React.Component<CompareProps, {}> { ...@@ -58,16 +58,16 @@ class Compare extends React.Component<CompareProps, {}> {
super(props); super(props);
} }
private _generateTooltipSummary(row: Item, metricKey: string): string { private _generateTooltipSummary = (row: Item, value: string): string =>
return renderToString( renderToString(
<div className='tooldetailAccuracy'> <div className='tooldetailAccuracy'>
<div>Trial No.: {row.sequenceId}</div>
<div>Trial ID: {row.id}</div> <div>Trial ID: {row.id}</div>
<div>Default metric: {row.metrics.get(metricKey) || 'N/A'}</div> <div>Intermediate metric: {value}</div>
</div> </div>
); );
}
private _intermediates(items: Item[], metricKey: string): React.ReactNode { private _intermediates(items: Item[]): React.ReactNode {
// Precondition: make sure `items` is not empty // Precondition: make sure `items` is not empty
const xAxisMax = Math.max(...items.map(item => item.intermediates.length)); const xAxisMax = Math.max(...items.map(item => item.intermediates.length));
const xAxis = Array(xAxisMax) const xAxis = Array(xAxisMax)
...@@ -84,7 +84,7 @@ class Compare extends React.Component<CompareProps, {}> { ...@@ -84,7 +84,7 @@ class Compare extends React.Component<CompareProps, {}> {
trigger: 'item', trigger: 'item',
enterable: true, enterable: true,
position: (point: number[], data: TooltipForIntermediate): [number, number] => { position: (point: number[], data: TooltipForIntermediate): [number, number] => {
if (data.dataIndex < length / 2) { if (data.dataIndex < xAxisMax / 2) {
return [point[0], 80]; return [point[0], 80];
} else { } else {
return [point[0] - 300, 80]; return [point[0] - 300, 80];
...@@ -92,7 +92,7 @@ class Compare extends React.Component<CompareProps, {}> { ...@@ -92,7 +92,7 @@ class Compare extends React.Component<CompareProps, {}> {
}, },
formatter: (data: TooltipForIntermediate): string => { formatter: (data: TooltipForIntermediate): string => {
const item = items.find(k => k.id === data.seriesName) as Item; const item = items.find(k => k.id === data.seriesName) as Item;
return this._generateTooltipSummary(item, metricKey); return this._generateTooltipSummary(item, data.data);
} }
}, },
grid: { grid: {
...@@ -187,9 +187,13 @@ class Compare extends React.Component<CompareProps, {}> { ...@@ -187,9 +187,13 @@ class Compare extends React.Component<CompareProps, {}> {
{parameterKeys.map(k => {parameterKeys.map(k =>
this._renderRow(`space_${k}`, k, 'value', items, item => item.parameters.get(k)) this._renderRow(`space_${k}`, k, 'value', items, item => item.parameters.get(k))
)} )}
{metricKeys.map(k => {metricKeys !== undefined
this._renderRow(`metrics_${k}`, `Metric: ${k}`, 'value', items, item => item.metrics.get(k)) ? metricKeys.map(k =>
)} this._renderRow(`metrics_${k}`, `Metric: ${k}`, 'value', items, item =>
item.metrics.get(k)
)
)
: null}
</tbody> </tbody>
</table> </table>
); );
...@@ -209,8 +213,6 @@ class Compare extends React.Component<CompareProps, {}> { ...@@ -209,8 +213,6 @@ class Compare extends React.Component<CompareProps, {}> {
metrics: flatten(trial.metrics(TRIALS.inferredMetricSpace())), metrics: flatten(trial.metrics(TRIALS.inferredMetricSpace())),
intermediates: _parseIntermediates(trial) intermediates: _parseIntermediates(trial)
})); }));
const metricKeys = this._overlapKeys(items.map(item => item.metrics));
const defaultMetricKey = !metricKeys || metricKeys.includes('default') ? 'default' : metricKeys[0];
return ( return (
<Modal <Modal
...@@ -232,7 +234,7 @@ class Compare extends React.Component<CompareProps, {}> { ...@@ -232,7 +234,7 @@ class Compare extends React.Component<CompareProps, {}> {
/> />
</div> </div>
<Stack className='compare-modal-intermediate'> <Stack className='compare-modal-intermediate'>
{this._intermediates(items, defaultMetricKey)} {this._intermediates(items)}
<Stack className='compare-yAxis'># Intermediate result</Stack> <Stack className='compare-yAxis'># Intermediate result</Stack>
</Stack> </Stack>
{showDetails && <Stack>{this._columns(items)}</Stack>} {showDetails && <Stack>{this._columns(items)}</Stack>}
......
...@@ -37,9 +37,9 @@ export const Command1 = (): any => { ...@@ -37,9 +37,9 @@ export const Command1 = (): any => {
<div className='basic' style={rightEidtParam}> <div className='basic' style={rightEidtParam}>
<div> <div>
<p className='command'>Training platform</p> <p className='command'>Training platform</p>
<div className='nowrap'>{EXPERIMENT.profile.params.trainingServicePlatform}</div> <div className='ellipsis'>{EXPERIMENT.profile.params.trainingServicePlatform}</div>
<p className='lineMargin'>{title.join('/')}</p> <p className='lineMargin'>{title.join('/')}</p>
<div className='nowrap'>{builtinName.join('/')}</div> <div className='ellipsis'>{builtinName.join('/')}</div>
</div> </div>
</div> </div>
); );
......
...@@ -24,10 +24,10 @@ export const Command2 = (): any => { ...@@ -24,10 +24,10 @@ export const Command2 = (): any => {
return ( return (
<div className='basic' style={leftProgress}> <div className='basic' style={leftProgress}>
<p className='command'>Log directory</p> <p className='command'>Log directory</p>
<div className='nowrap'> <div className='ellipsis'>
<TooltipHost <TooltipHost
content={EXPERIMENT.profile.logDir || 'unknown'} content={EXPERIMENT.profile.logDir || 'unknown'}
className='nowrap' className='ellipsis'
directionalHint={DirectionalHint.bottomCenter} directionalHint={DirectionalHint.bottomCenter}
tooltipProps={{ tooltipProps={{
calloutProps: { calloutProps: {
...@@ -43,10 +43,10 @@ export const Command2 = (): any => { ...@@ -43,10 +43,10 @@ export const Command2 = (): any => {
</TooltipHost> </TooltipHost>
</div> </div>
<p className='lineMargin'>Trial command</p> <p className='lineMargin'>Trial command</p>
<div className='nowrap'> <div className='ellipsis'>
<TooltipHost <TooltipHost
content={trialCommand || 'unknown'} content={trialCommand || 'unknown'}
className='nowrap' className='ellipsis'
directionalHint={DirectionalHint.bottomCenter} directionalHint={DirectionalHint.bottomCenter}
tooltipProps={{ tooltipProps={{
calloutProps: { calloutProps: {
......
...@@ -6,10 +6,10 @@ import { formatTimestamp } from '../../../static/function'; ...@@ -6,10 +6,10 @@ import { formatTimestamp } from '../../../static/function';
import { useId } from '@uifabric/react-hooks'; import { useId } from '@uifabric/react-hooks';
import { BestMetricContext } from '../../Overview'; import { BestMetricContext } from '../../Overview';
import { styles } from './basicInfoStyles'; import { styles } from './basicInfoStyles';
import '../../../static/style/progress/progress.scss'; import '../../../static/style/overview/probar.scss';
import '../../../static/style/progress/probar.scss'; import '../../../static/style/overview/basic.scss';
export const ReBasicInfo = (): any => { export const BasicInfo = (): any => {
const labelId: string = useId('callout-label'); const labelId: string = useId('callout-label');
const descriptionId: string = useId('callout-description'); const descriptionId: string = useId('callout-description');
const ref = React.createRef<HTMLDivElement>(); const ref = React.createRef<HTMLDivElement>();
...@@ -26,9 +26,9 @@ export const ReBasicInfo = (): any => { ...@@ -26,9 +26,9 @@ export const ReBasicInfo = (): any => {
<Stack horizontal horizontalAlign='space-between' className='marginTop'> <Stack horizontal horizontalAlign='space-between' className='marginTop'>
<div className='basic'> <div className='basic'>
<p>Name</p> <p>Name</p>
<div className='nowrap'>{EXPERIMENT.profile.params.experimentName}</div> <div className='ellipsis'>{EXPERIMENT.profile.params.experimentName}</div>
<p className='marginTop'>ID</p> <p className='marginTop'>ID</p>
<div className='nowrap'>{EXPERIMENT.profile.id}</div> <div className='ellipsis'>{EXPERIMENT.profile.id}</div>
</div> </div>
<div className='basic'> <div className='basic'>
<p>Status</p> <p>Status</p>
...@@ -86,9 +86,9 @@ export const ReBasicInfo = (): any => { ...@@ -86,9 +86,9 @@ export const ReBasicInfo = (): any => {
</div> </div>
<div className='basic'> <div className='basic'>
<p>Start time</p> <p>Start time</p>
<div className='nowrap'>{formatTimestamp(EXPERIMENT.profile.startTime)}</div> <div className='ellipsis'>{formatTimestamp(EXPERIMENT.profile.startTime)}</div>
<p className='marginTop'>End time</p> <p className='marginTop'>End time</p>
<div className='nowrap'>{formatTimestamp(EXPERIMENT.profile.endTime)}</div> <div className='ellipsis'>{formatTimestamp(EXPERIMENT.profile.endTime)}</div>
</div> </div>
</Stack> </Stack>
{/* learn about click -> default active key is dispatcher. */} {/* learn about click -> default active key is dispatcher. */}
......
...@@ -106,7 +106,7 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState> ...@@ -106,7 +106,7 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
</React.Fragment> </React.Fragment>
); );
private columns = [ private columns: IColumn[] = [
{ {
key: '_expand', key: '_expand',
name: '', name: '',
......
...@@ -73,18 +73,24 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState> ...@@ -73,18 +73,24 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
data.data[0] < maxSequenceId ? point[0] : point[0] - 300, data.data[0] < maxSequenceId ? point[0] : point[0] - 300,
80 80
], ],
formatter: (data: TooltipForAccuracy): React.ReactNode => formatter: (data: TooltipForAccuracy): React.ReactNode => {
return (
'<div class="tooldetailAccuracy">' + '<div class="tooldetailAccuracy">' +
'<div>Trial No.: ' + '<div>Trial No.: ' +
data.data[0] + data.data[0] +
'</div>' + '</div>' +
'<div>Trial ID: ' +
data.data[2] +
'</div>' +
'<div>Default metric: ' + '<div>Default metric: ' +
data.data[1] + data.data[1] +
'</div>' + '</div>' +
'<div>Parameters: <pre>' + '<div>Parameters: <pre>' +
JSON.stringify(data.data[2], null, 4) + JSON.stringify(data.data[3], null, 4) +
'</pre></div>' + '</pre></div>' +
'</div>' '</div>'
);
}
}, },
dataZoom: [ dataZoom: [
{ {
...@@ -110,7 +116,7 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState> ...@@ -110,7 +116,7 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
} }
generateScatterSeries(trials: Trial[]): any { generateScatterSeries(trials: Trial[]): any {
const data = trials.map(trial => [trial.sequenceId, trial.accuracy, trial.description.parameters]); const data = trials.map(trial => [trial.sequenceId, trial.accuracy, trial.id, trial.description.parameters]);
return { return {
symbolSize: 6, symbolSize: 6,
type: 'scatter', type: 'scatter',
...@@ -120,7 +126,7 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState> ...@@ -120,7 +126,7 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
generateBestCurveSeries(trials: Trial[]): any { generateBestCurveSeries(trials: Trial[]): any {
let best = trials[0]; let best = trials[0];
const data = [[best.sequenceId, best.accuracy, best.description.parameters]]; const data = [[best.sequenceId, best.accuracy, best.id, best.description.parameters]];
for (let i = 1; i < trials.length; i++) { for (let i = 1; i < trials.length; i++) {
const trial = trials[i]; const trial = trials[i];
...@@ -128,10 +134,10 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState> ...@@ -128,10 +134,10 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
const delta = trial.accuracy! - best.accuracy!; const delta = trial.accuracy! - best.accuracy!;
const better = EXPERIMENT.optimizeMode === 'minimize' ? delta < 0 : delta > 0; const better = EXPERIMENT.optimizeMode === 'minimize' ? delta < 0 : delta > 0;
if (better) { if (better) {
data.push([trial.sequenceId, trial.accuracy, trial.description.parameters]); data.push([trial.sequenceId, trial.accuracy, best.id, trial.description.parameters]);
best = trial; best = trial;
} else { } else {
data.push([trial.sequenceId, best.accuracy, trial.description.parameters]); data.push([trial.sequenceId, best.accuracy, best.id, trial.description.parameters]);
} }
} }
......
...@@ -61,6 +61,7 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState> ...@@ -61,6 +61,7 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
const temp = source[item]; const temp = source[item];
trialIntermediate.push({ trialIntermediate.push({
name: temp.id, name: temp.id,
trialNum: temp.sequenceId,
data: temp.description.intermediate, data: temp.description.intermediate,
type: 'line', type: 'line',
hyperPara: temp.description.parameters hyperPara: temp.description.parameters
...@@ -94,13 +95,18 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState> ...@@ -94,13 +95,18 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
}, },
formatter: function(data: TooltipForIntermediate): React.ReactNode { formatter: function(data: TooltipForIntermediate): React.ReactNode {
const trialId = data.seriesName; const trialId = data.seriesName;
let obj = {}; let parameters = {};
let trialNum = 0;
const temp = trialIntermediate.find(key => key.name === trialId); const temp = trialIntermediate.find(key => key.name === trialId);
if (temp !== undefined) { if (temp !== undefined) {
obj = temp.hyperPara; parameters = temp.hyperPara;
trialNum = temp.trialNum;
} }
return ( return (
'<div class="tooldetailAccuracy">' + '<div class="tooldetailAccuracy">' +
'<div>Trial No.: ' +
trialNum +
'</div>' +
'<div>Trial ID: ' + '<div>Trial ID: ' +
trialId + trialId +
'</div>' + '</div>' +
...@@ -109,7 +115,7 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState> ...@@ -109,7 +115,7 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
'</div>' + '</div>' +
'<div>Parameters: ' + '<div>Parameters: ' +
'<pre>' + '<pre>' +
JSON.stringify(obj, null, 4) + JSON.stringify(parameters, null, 4) +
'</pre>' + '</pre>' +
'</div>' + '</div>' +
'</div>' '</div>'
......
...@@ -4,14 +4,13 @@ import App from './App'; ...@@ -4,14 +4,13 @@ import App from './App';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
const Overview = lazy(() => import('./components/Overview')); const Overview = lazy(() => import('./components/Overview'));
const TrialsDetail = lazy(() => import('./components/TrialsDetail')); const TrialsDetail = lazy(() => import('./components/TrialsDetail'));
const Experiment = lazy(() => import('./components/managementExp/ExperimentManager'));
import './index.css'; import './index.css';
import './static/style/loading.scss'; import './static/style/loading.scss';
import * as serviceWorker from './serviceWorker'; import * as serviceWorker from './serviceWorker';
ReactDOM.render( ReactDOM.render(
<Router> <Router>
<App>
<Switch>
<Suspense <Suspense
fallback={ fallback={
<div className='loading'> <div className='loading'>
...@@ -19,12 +18,15 @@ ReactDOM.render( ...@@ -19,12 +18,15 @@ ReactDOM.render(
</div> </div>
} }
> >
<Route path='/experiment' component={Experiment} exact />
<Switch>
<App>
<Route path='/' component={Overview} exact /> <Route path='/' component={Overview} exact />
<Route path='/oview' component={Overview} /> <Route path='/oview' component={Overview} />
<Route path='/detail' component={TrialsDetail} /> <Route path='/detail' component={TrialsDetail} />
</Suspense>
</Switch>
</App> </App>
</Switch>
</Suspense>
</Router>, </Router>,
document.getElementById('root') document.getElementById('root')
......
...@@ -15,6 +15,16 @@ const trialJobStatus = [ ...@@ -15,6 +15,16 @@ const trialJobStatus = [
'SYS_CANCELED', 'SYS_CANCELED',
'EARLY_STOPPED' 'EARLY_STOPPED'
]; ];
const EXPERIMENTSTATUS = [
'INITIALIZED',
'RUNNING',
'ERROR',
'STOPPING',
'STOPPED',
'DONE',
'NO_MORE_TRIAL',
'TUNER_NO_MORE_TRIAL'
];
const CONTROLTYPE = ['MAX_EXEC_DURATION', 'MAX_TRIAL_NUM', 'TRIAL_CONCURRENCY', 'SEARCH_SPACE']; const CONTROLTYPE = ['MAX_EXEC_DURATION', 'MAX_TRIAL_NUM', 'TRIAL_CONCURRENCY', 'SEARCH_SPACE'];
const MONACO = { const MONACO = {
readOnly: true, readOnly: true,
...@@ -64,6 +74,7 @@ export { ...@@ -64,6 +74,7 @@ export {
MANAGER_IP, MANAGER_IP,
DOWNLOAD_IP, DOWNLOAD_IP,
trialJobStatus, trialJobStatus,
EXPERIMENTSTATUS,
COLUMNPro, COLUMNPro,
WEBUIDOC, WEBUIDOC,
CONTROLTYPE, CONTROLTYPE,
......
...@@ -236,6 +236,14 @@ function formatTimestamp(timestamp?: number, placeholder?: string): string { ...@@ -236,6 +236,14 @@ function formatTimestamp(timestamp?: number, placeholder?: string): string {
return timestamp ? new Date(timestamp).toLocaleString('en-US') : placeholder; return timestamp ? new Date(timestamp).toLocaleString('en-US') : placeholder;
} }
function expformatTimestamp(timestamp: number | string): string {
if (typeof timestamp === 'number') {
return new Date(timestamp).toLocaleString('en-US');
} else {
return 'N/A';
}
}
function metricAccuracy(metric: MetricDataRecord): number { function metricAccuracy(metric: MetricDataRecord): number {
const data = parseMetrics(metric.data); const data = parseMetrics(metric.data);
// return typeof data === 'number' ? data : NaN; // return typeof data === 'number' ? data : NaN;
...@@ -262,6 +270,10 @@ function formatComplexTypeValue(value: any): string | number { ...@@ -262,6 +270,10 @@ function formatComplexTypeValue(value: any): string | number {
} }
} }
function isManagerExperimentPage(): boolean {
return location.pathname.indexOf('experiment') === -1 ? false : true;
}
function caclMonacoEditorHeight(height): number { function caclMonacoEditorHeight(height): number {
// [Search space 56px] + [marginBottom 18px] + // [Search space 56px] + [marginBottom 18px] +
// button[height: 32px, marginTop: 45px, marginBottom: 7px] // button[height: 32px, marginTop: 45px, marginBottom: 7px]
...@@ -306,12 +318,14 @@ export { ...@@ -306,12 +318,14 @@ export {
filterDuration, filterDuration,
formatAccuracy, formatAccuracy,
formatTimestamp, formatTimestamp,
expformatTimestamp,
metricAccuracy, metricAccuracy,
parseMetrics, parseMetrics,
isArrayType, isArrayType,
requestAxios, requestAxios,
isNaNorInfinity, isNaNorInfinity,
formatComplexTypeValue, formatComplexTypeValue,
isManagerExperimentPage,
caclMonacoEditorHeight, caclMonacoEditorHeight,
copyAndSort copyAndSort
}; };
...@@ -120,6 +120,7 @@ interface Intermedia { ...@@ -120,6 +120,7 @@ interface Intermedia {
type: string; type: string;
data: Array<number | object>; // intermediate data data: Array<number | object>; // intermediate data
hyperPara: object; // each trial hyperpara value hyperPara: object; // each trial hyperpara value
trialNum: number;
} }
interface MetricDataRecord { interface MetricDataRecord {
...@@ -218,6 +219,19 @@ interface SortInfo { ...@@ -218,6 +219,19 @@ interface SortInfo {
isDescend?: boolean; isDescend?: boolean;
} }
interface AllExperimentList {
id: string;
experimentName: string;
port: number;
status: string;
platform: string;
startTime: number;
endTime: number;
tag: string[];
pid: number;
webuiUrl: string[];
logDir: string[];
}
export { export {
TableObj, TableObj,
TableRecord, TableRecord,
...@@ -240,5 +254,6 @@ export { ...@@ -240,5 +254,6 @@ export {
EventMap, EventMap,
SingleAxis, SingleAxis,
MultipleAxes, MultipleAxes,
SortInfo SortInfo,
AllExperimentList
}; };
import { MANAGER_IP } from '../const';
import { AllExperimentList } from '../interface';
import { requestAxios } from '../function';
class ExperimentsManager {
private experimentList: AllExperimentList[] = [];
private platform: string[] = [];
private errorMessage: string = '';
public getExperimentList(): AllExperimentList[] {
return this.experimentList;
}
public getPlatformList(): string[] {
return this.platform;
}
public getExpErrorMessage(): string {
return this.errorMessage;
}
public async init(): Promise<void> {
await requestAxios(`${MANAGER_IP}/experiments-info`)
.then(data => {
const platforms: Set<string> = new Set();
for (const item of data) {
if (item.port !== undefined) {
if (typeof item.port === 'string') {
item.port = JSON.parse(item.port);
}
}
platforms.add(item.platform);
}
this.experimentList = data;
this.platform = Array.from(platforms);
})
.catch(error => {
this.errorMessage = error.message;
});
}
}
export { ExperimentsManager };
.cursor{ .ellipsis {
&:hover, & i:hover{ overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.link {
outline: none;
color: #333 !important;
text-decoration: none;
&:hover {
color: #0071bc !important;
text-decoration: underline;
}
&:active,
&:visited {
color: #0071bc;
}
}
.cursor {
&:hover,
& i:hover {
cursor: pointer; cursor: pointer;
} }
} }
.expBackground {
background: #f2f2f2;
height: 100%;
.content {
background: #fff;
}
}
.experimentList {
padding: 42px;
.box {
.search {
width: 90%;
&-input {
width: 330px;
}
}
.filter {
width: 10%;
text-align: right;
&-button-open {
background: #f3f2f1;
}
}
}
.filter-condition {
margin-top: 26px;
.reset {
width: 80px;
position: relative;
top: 29px;
}
&-status {
width: 194px;
}
&-platform {
width: 150px;
}
}
.hidden {
display: none;
}
.margin {
margin-left: 10px;
}
.tagContainer {
width: 100%;
.tag {
font-weight: 500;
background: #f2f2f2;
margin: 0 4px;
padding: 0 6px;
}
}
}
...@@ -31,9 +31,17 @@ $barHeight: 56px; ...@@ -31,9 +31,17 @@ $barHeight: 56px;
background-color: transparent; background-color: transparent;
} }
} }
.experiment {
position: relative;
top: 3px;
text-decoration: none;
}
} }
.nav { .nav {
width: 100%;
min-width: 1200px;
height: $barHeight; height: $barHeight;
line-height: $barHeight; line-height: $barHeight;
...@@ -43,6 +51,11 @@ $barHeight: 56px; ...@@ -43,6 +51,11 @@ $barHeight: 56px;
top: 6px; top: 6px;
} }
.logoTitle {
font-size: 18px;
color: #fff;
}
&-refresh { &-refresh {
position: relative; position: relative;
display: flex; display: flex;
...@@ -81,3 +94,19 @@ a.common-tabs { ...@@ -81,3 +94,19 @@ a.common-tabs {
margin-left: 20px; margin-left: 20px;
margin-right: 20px; margin-right: 20px;
} }
.expNavTitle {
span {
color: #fff;
text-decoration: none;
position: relative;
top: -4px;
}
i {
color: #fff;
font-size: 12px;
position: relative;
top: -3px;
padding-left: 4px;
}
}
.status {
color: #0573bc;
font-size: 20px;
font-weight: 600;
.status-text {
display: inline-block;
}
.color {
color: #333;
}
}
.inputBox {
height: 32px;
margin-top: 5px;
}
/* office-fabric-ui progressIndicator */
.ms-ProgressIndicator-itemProgress {
padding: 0;
}
...@@ -58,6 +58,7 @@ $margin: 24px; ...@@ -58,6 +58,7 @@ $margin: 24px;
.concurrency { .concurrency {
.editparam { .editparam {
margin-top: 5px; margin-top: 5px;
position: relative;
} }
} }
.editparam { .editparam {
...@@ -124,5 +125,6 @@ $margin: 24px; ...@@ -124,5 +125,6 @@ $margin: 24px;
.info { .info {
position: absolute; position: absolute;
z-index: 999; z-index: 999;
left: 0; left: -50%;
width: 270%;
} }
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