зеркало из https://github.com/microsoft/nni.git
Show experiment error message and refactor function component props (#5029)
This commit is contained in:
Родитель
119a2b60a3
Коммит
4ab85d3d47
|
@ -1,12 +1,17 @@
|
|||
import React, { useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import copy from 'copy-to-clipboard';
|
||||
import { IconButton, FontSizes, TooltipHost } from '@fluentui/react';
|
||||
import { TOOLTIP_BACKGROUND_COLOR } from '@static/const';
|
||||
|
||||
interface CopyButtonProps {
|
||||
value: string;
|
||||
hideTooltip?: boolean;
|
||||
}
|
||||
|
||||
const COPIED_TOOLTIP_CLOSE_DELAY = 1000;
|
||||
|
||||
const CopyButton = ({ value, hideTooltip }): any => {
|
||||
const CopyButton = (props: CopyButtonProps): any => {
|
||||
const { value, hideTooltip } = props;
|
||||
const ref = useRef(null);
|
||||
return (
|
||||
<div>
|
||||
|
@ -47,9 +52,4 @@ const CopyButton = ({ value, hideTooltip }): any => {
|
|||
);
|
||||
};
|
||||
|
||||
CopyButton.propTypes = {
|
||||
value: PropTypes.string.isRequired,
|
||||
hideTooltip: PropTypes.bool
|
||||
};
|
||||
|
||||
export default CopyButton;
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { DetailsRow } from '@fluentui/react';
|
||||
import { DetailsRow, IDetailsRowBaseProps } from '@fluentui/react/lib/DetailsList';
|
||||
import OpenRow from './OpenRow';
|
||||
import '@style/table.scss';
|
||||
|
||||
const ExpandableDetails = (props): any => {
|
||||
interface ExpandableDetailsProps {
|
||||
detailsProps: IDetailsRowBaseProps;
|
||||
isExpand: boolean;
|
||||
}
|
||||
|
||||
const ExpandableDetails = (props: ExpandableDetailsProps): any => {
|
||||
const { detailsProps, isExpand } = props;
|
||||
return (
|
||||
<div>
|
||||
|
@ -14,9 +18,4 @@ const ExpandableDetails = (props): any => {
|
|||
);
|
||||
};
|
||||
|
||||
ExpandableDetails.propTypes = {
|
||||
detailsProps: PropTypes.object,
|
||||
isExpand: PropTypes.bool
|
||||
};
|
||||
|
||||
export default ExpandableDetails;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Stack, PrimaryButton, Pivot, PivotItem, DefaultButton } from '@fluentui/react';
|
||||
import * as copy from 'copy-to-clipboard';
|
||||
import JSONTree from 'react-json-tree';
|
||||
|
@ -18,7 +17,11 @@ import '@style/experiment/overview/overview.scss';
|
|||
* Remember to update it if the value is changed or this file is moved.
|
||||
**/
|
||||
|
||||
const OpenRow = (props): any => {
|
||||
interface OpenRowProps {
|
||||
trialId: string;
|
||||
}
|
||||
|
||||
const OpenRow = (props: OpenRowProps): any => {
|
||||
const [typeInfo, setTypeInfo] = useState('');
|
||||
const [info, setInfo] = useState('');
|
||||
const [isHidenInfo, setHideninfo] = useState(true);
|
||||
|
@ -161,8 +164,4 @@ const OpenRow = (props): any => {
|
|||
);
|
||||
};
|
||||
|
||||
OpenRow.propTypes = {
|
||||
trialId: PropTypes.string
|
||||
};
|
||||
|
||||
export default OpenRow;
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import TrialLog from './TrialLog';
|
||||
|
||||
const PaitrialLog = (props): any => {
|
||||
interface PaitrialLogProps {
|
||||
logStr: string;
|
||||
}
|
||||
|
||||
const PaitrialLog = (props: PaitrialLogProps): any => {
|
||||
const { logStr } = props;
|
||||
const isHasNFSLog = logStr.indexOf(',') !== -1 ? true : false;
|
||||
return (
|
||||
|
@ -19,8 +22,4 @@ const PaitrialLog = (props): any => {
|
|||
);
|
||||
};
|
||||
|
||||
PaitrialLog.propTypes = {
|
||||
logStr: PropTypes.string
|
||||
};
|
||||
|
||||
export default PaitrialLog;
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const TrialLog = (props): any => {
|
||||
interface TrialLogProps {
|
||||
logStr: string;
|
||||
logName: string;
|
||||
}
|
||||
|
||||
const TrialLog = (props: TrialLogProps): any => {
|
||||
const { logStr, logName } = props;
|
||||
const isHyperlink = logStr.toLowerCase().startsWith('http');
|
||||
|
||||
|
@ -19,9 +23,4 @@ const TrialLog = (props): any => {
|
|||
);
|
||||
};
|
||||
|
||||
TrialLog.propTypes = {
|
||||
logStr: PropTypes.string,
|
||||
logName: PropTypes.string
|
||||
};
|
||||
|
||||
export default TrialLog;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as React from 'react';
|
||||
import { Stack, PrimaryButton, Toggle, IStackTokens } from '@fluentui/react';
|
||||
import { TooltipForIntermediate, EventMap, allTrialsIntermediateChart } from '@static/interface';
|
||||
import { TooltipForIntermediate, EventMap, AllTrialsIntermediateChart } from '@static/interface';
|
||||
import { reformatRetiariiParameter } from '@static/function';
|
||||
import ReactEcharts from 'echarts-for-react';
|
||||
import 'echarts/lib/component/tooltip';
|
||||
|
@ -11,9 +11,9 @@ const stackTokens: IStackTokens = {
|
|||
};
|
||||
|
||||
interface IntermediateState {
|
||||
detailSource: allTrialsIntermediateChart[];
|
||||
detailSource: AllTrialsIntermediateChart[];
|
||||
interSource: object;
|
||||
filterSource: allTrialsIntermediateChart[];
|
||||
filterSource: AllTrialsIntermediateChart[];
|
||||
eachIntermediateNum: number; // trial's intermediate number count
|
||||
isLoadconfirmBtn: boolean;
|
||||
isFilter?: boolean | undefined;
|
||||
|
@ -23,7 +23,7 @@ interface IntermediateState {
|
|||
}
|
||||
|
||||
interface IntermediateProps {
|
||||
source: allTrialsIntermediateChart[];
|
||||
source: AllTrialsIntermediateChart[];
|
||||
}
|
||||
|
||||
class Intermediate extends React.Component<IntermediateProps, IntermediateState> {
|
||||
|
@ -47,7 +47,7 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
|
|||
};
|
||||
}
|
||||
|
||||
drawIntermediate = (source: allTrialsIntermediateChart[]): void => {
|
||||
drawIntermediate = (source: AllTrialsIntermediateChart[]): void => {
|
||||
if (source.length > 0) {
|
||||
this.setState({
|
||||
length: source.length,
|
||||
|
@ -145,7 +145,7 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
|
|||
|
||||
// confirm btn function [filter data]
|
||||
filterLines = (): void => {
|
||||
const filterSource: allTrialsIntermediateChart[] = [];
|
||||
const filterSource: AllTrialsIntermediateChart[] = [];
|
||||
this.setState({ isLoadconfirmBtn: true }, () => {
|
||||
const { source } = this.props;
|
||||
// get input value
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { PrimaryButton, Dialog, DialogType, DialogFooter } from '@fluentui/react';
|
||||
import { KillJobIsError } from '@static/interface';
|
||||
|
||||
function KillJobDialog(props): any {
|
||||
interface KillJobDialogProps {
|
||||
trialId: string;
|
||||
isError: KillJobIsError;
|
||||
onHideDialog: () => void;
|
||||
}
|
||||
|
||||
function KillJobDialog(props: KillJobDialogProps): any {
|
||||
const { onHideDialog, trialId, isError } = props;
|
||||
|
||||
const dialogContentProps = {
|
||||
|
@ -29,10 +35,4 @@ function KillJobDialog(props): any {
|
|||
);
|
||||
}
|
||||
|
||||
KillJobDialog.propTypes = {
|
||||
trialId: PropTypes.string,
|
||||
isError: PropTypes.object,
|
||||
onHideDialog: PropTypes.func
|
||||
};
|
||||
|
||||
export default KillJobDialog;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import React, { useState, useRef, useContext } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import axios from 'axios';
|
||||
import { Stack, FocusTrapCallout, DefaultButton, FocusZone, PrimaryButton } from '@fluentui/react';
|
||||
import { MANAGER_IP } from '@static/const';
|
||||
|
@ -9,7 +8,11 @@ import { gap10 } from '@components/fluent/ChildrenGap';
|
|||
import { styles } from '@components/experiment/overview/params/basicInfoStyles';
|
||||
import { AppContext } from '@/App';
|
||||
|
||||
function KillJobIndex(props): any {
|
||||
interface KillJobIndexProps {
|
||||
trialId: string;
|
||||
}
|
||||
|
||||
function KillJobIndex(props: KillJobIndexProps): any {
|
||||
const menuButtonElement = useRef(null);
|
||||
const { startTimer, closeTimer, interval, refreshDetailTable } = useContext(AppContext);
|
||||
const { trialId } = props;
|
||||
|
@ -118,9 +121,4 @@ function KillJobIndex(props): any {
|
|||
);
|
||||
}
|
||||
|
||||
KillJobIndex.propTypes = {
|
||||
trialId: PropTypes.string,
|
||||
updatePage: PropTypes.func
|
||||
};
|
||||
|
||||
export default KillJobIndex;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React, { useState, useContext } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Stack, PrimaryButton } from '@fluentui/react';
|
||||
import { gap10 } from '@components/fluent/ChildrenGap';
|
||||
import { AppContext } from '@/App';
|
||||
import { SearchItems } from '@static/interface';
|
||||
import { getSearchInputValueBySearchList } from './searchFunction';
|
||||
|
||||
// This file is for search trial ['Trial id', 'Trial No.']
|
||||
|
@ -14,11 +14,19 @@ import { getSearchInputValueBySearchList } from './searchFunction';
|
|||
// 1 // only filter one trial that trial no is 1
|
||||
// bw // only filter that trial id include `bw`
|
||||
|
||||
function GeneralSearch(props): any {
|
||||
interface GeneralSearchProps {
|
||||
searchName: string;
|
||||
searchFilter: SearchItems[];
|
||||
dismiss: () => void;
|
||||
setSearchInputVal: (a: string) => void;
|
||||
changeSearchFilterList: (a: SearchItems[]) => void;
|
||||
}
|
||||
|
||||
function GeneralSearch(props: GeneralSearchProps): any {
|
||||
const { updateDetailPage } = useContext(AppContext);
|
||||
// searchName val: Trial No. | Trial id
|
||||
const { searchName, searchFilter, dismiss, changeSearchFilterList, setSearchInputVal } = props;
|
||||
const [firstInputVal, setFirstInputVal] = useState(getSearchNameInit());
|
||||
const [firstInputVal, setFirstInputVal] = useState(getSearchNameInit() as string);
|
||||
|
||||
function updateFirstInputVal(ev: React.ChangeEvent<HTMLInputElement>): void {
|
||||
setFirstInputVal(ev.target.value);
|
||||
|
@ -79,12 +87,4 @@ function GeneralSearch(props): any {
|
|||
);
|
||||
}
|
||||
|
||||
GeneralSearch.propTypes = {
|
||||
searchName: PropTypes.string,
|
||||
searchFilter: PropTypes.array,
|
||||
dismiss: PropTypes.func,
|
||||
setSearchInputVal: PropTypes.func,
|
||||
changeSearchFilterList: PropTypes.func
|
||||
};
|
||||
|
||||
export default GeneralSearch;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import React, { useState, useContext } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Stack,
|
||||
DefaultButton,
|
||||
|
@ -18,11 +17,15 @@ import { classNames, isChoiceType } from './searchFunction';
|
|||
import { AppContext } from '@/App';
|
||||
|
||||
// TableList search layout
|
||||
interface SearchProps {
|
||||
searchFilter: SearchItems[];
|
||||
changeSearchFilterList: (a: SearchItems[]) => void;
|
||||
}
|
||||
|
||||
function Search(props): any {
|
||||
function Search(props: SearchProps): any {
|
||||
const { searchFilter, changeSearchFilterList } = props;
|
||||
const { updateDetailPage } = useContext(AppContext);
|
||||
const [searchInputVal, setSearchInputVal] = useState('');
|
||||
const [searchInputVal, setSearchInputVal] = useState('' as string);
|
||||
|
||||
function getSearchMenu(parameterList): IContextualMenuProps {
|
||||
const menu: Array<object> = [];
|
||||
|
@ -96,7 +99,7 @@ function Search(props): any {
|
|||
function renderParametersSearchComponent(item: IContextualMenuItem, dismissMenu: () => void): JSX.Element {
|
||||
return (
|
||||
<SearchParameterConditions
|
||||
parameter={item.text}
|
||||
parameter={item.text ?? ''}
|
||||
searchFilter={searchFilter} // search filter list
|
||||
changeSearchFilterList={changeSearchFilterList}
|
||||
updatePage={updateDetailPage}
|
||||
|
@ -109,7 +112,7 @@ function Search(props): any {
|
|||
function renderDefaultMetricSearchComponent(item: IContextualMenuItem, dismissMenu: () => void): JSX.Element {
|
||||
return (
|
||||
<SearchDefaultMetric
|
||||
parameter={item.text}
|
||||
parameter={item.text ?? ''}
|
||||
searchFilter={searchFilter} // search filter list
|
||||
changeSearchFilterList={changeSearchFilterList}
|
||||
updatePage={updateDetailPage}
|
||||
|
@ -122,7 +125,7 @@ function Search(props): any {
|
|||
function renderIdAndNoComponent(item: IContextualMenuItem, dismissMenu: () => void): JSX.Element {
|
||||
return (
|
||||
<GeneralSearch
|
||||
searchName={item.text}
|
||||
searchName={item.text ?? ''}
|
||||
searchFilter={searchFilter} // search fliter list
|
||||
changeSearchFilterList={changeSearchFilterList}
|
||||
setSearchInputVal={setSearchInputVal}
|
||||
|
@ -136,7 +139,7 @@ function Search(props): any {
|
|||
}
|
||||
|
||||
// update TableList page
|
||||
function changeTableListPage(searchFilterList: Array<SearchItems>): void {
|
||||
function changeTableListPage(searchFilterList: SearchItems[]): void {
|
||||
changeSearchFilterList(searchFilterList);
|
||||
updateDetailPage();
|
||||
}
|
||||
|
@ -310,9 +313,4 @@ function Search(props): any {
|
|||
);
|
||||
}
|
||||
|
||||
Search.propTypes = {
|
||||
searchFilter: PropTypes.array,
|
||||
changeSearchFilterList: PropTypes.func
|
||||
};
|
||||
|
||||
export default Search;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import React, { useState, useContext } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Stack, PrimaryButton, Dropdown, IDropdownOption } from '@fluentui/react';
|
||||
import { EXPERIMENT } from '@static/datamodel';
|
||||
import { getSearchInputValueBySearchList } from './searchFunction';
|
||||
import { gap10 } from '@components/fluent/ChildrenGap';
|
||||
import { AppContext } from '@/App';
|
||||
import { SearchItems } from '@static/interface';
|
||||
|
||||
// This file is for filtering trial default metric column including intermediate results
|
||||
// you could click `filter` button -> `Default metric` use it
|
||||
|
@ -14,13 +14,22 @@ import { AppContext } from '@/App';
|
|||
// Default metric:[0.1,0.2]; // 0.1 < trial metric < 0.2
|
||||
// Default metric:0.1009; // trial metric = 0.1009, because shown metric is dealed with,so it's no use in most time
|
||||
|
||||
function SearchDefaultMetric(props): any {
|
||||
interface SearchDefaultMetricProps {
|
||||
parameter: string;
|
||||
searchFilter: SearchItems[];
|
||||
dismiss: () => void;
|
||||
setSearchInputVal: (a: string) => void;
|
||||
changeSearchFilterList: (a: SearchItems[]) => void;
|
||||
updatePage: () => void;
|
||||
}
|
||||
|
||||
function SearchDefaultMetric(props: SearchDefaultMetricProps): any {
|
||||
const { parameter, searchFilter, dismiss, changeSearchFilterList, setSearchInputVal } = props;
|
||||
const { updateDetailPage } = useContext(AppContext);
|
||||
const operatorList = ['between', '>', '<', '='];
|
||||
|
||||
const initValueList = getInitVal();
|
||||
const [operatorVal, setOperatorVal] = useState(initValueList[0]);
|
||||
const [operatorVal, setOperatorVal] = useState(initValueList[0] as string);
|
||||
const [firstInputVal, setFirstInputVal] = useState(initValueList[1] as string);
|
||||
const [secondInputVal, setSecondInputVal] = useState(initValueList[2] as string);
|
||||
|
||||
|
@ -61,7 +70,7 @@ function SearchDefaultMetric(props): any {
|
|||
if (secondInputVal === '' && operatorVal === 'between') {
|
||||
// if user uses 'between' operator and doesn't write the second input value,
|
||||
// help to set second value as this parameter max value
|
||||
return EXPERIMENT.searchSpace[parameter]._value[1].toString();
|
||||
return String(EXPERIMENT.searchSpace[parameter]._value[1]);
|
||||
}
|
||||
|
||||
return secondInputVal as string;
|
||||
|
@ -141,13 +150,4 @@ function SearchDefaultMetric(props): any {
|
|||
);
|
||||
}
|
||||
|
||||
SearchDefaultMetric.propTypes = {
|
||||
parameter: PropTypes.string,
|
||||
searchFilter: PropTypes.array,
|
||||
dismiss: PropTypes.func,
|
||||
setSearchInputVal: PropTypes.func,
|
||||
changeSearchFilterList: PropTypes.func,
|
||||
updatePage: PropTypes.func
|
||||
};
|
||||
|
||||
export default SearchDefaultMetric;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import React, { useState, useContext } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Stack, PrimaryButton, Dropdown, IDropdownOption } from '@fluentui/react';
|
||||
import { EXPERIMENT } from '@static/datamodel';
|
||||
import { getDropdownOptions, getSearchInputValueBySearchList } from './searchFunction';
|
||||
import { gap10 } from '@components/fluent/ChildrenGap';
|
||||
import { AppContext } from '@/App';
|
||||
import { SearchItems } from '@static/interface';
|
||||
|
||||
/***
|
||||
* This file is for filtering trial parameters and trial status
|
||||
|
@ -30,14 +30,23 @@ import { AppContext } from '@/App';
|
|||
* hidden_size≠1024 // please don't input this format!
|
||||
*/
|
||||
|
||||
function SearchParameterConditions(props): any {
|
||||
interface SearchParameterConditionsProps {
|
||||
parameter: string;
|
||||
searchFilter: SearchItems[];
|
||||
dismiss: () => void;
|
||||
setSearchInputVal: (a: string) => void;
|
||||
changeSearchFilterList: (a: SearchItems[]) => void;
|
||||
updatePage: () => void;
|
||||
}
|
||||
|
||||
function SearchParameterConditions(props: SearchParameterConditionsProps): any {
|
||||
const { parameter, searchFilter, dismiss, changeSearchFilterList, setSearchInputVal } = props;
|
||||
const { updateDetailPage } = useContext(AppContext);
|
||||
const isChoiceTypeSearchFilter = parameter === 'StatusNNI' || EXPERIMENT.searchSpace[parameter]._type === 'choice';
|
||||
const operatorList = isChoiceTypeSearchFilter ? ['=', '≠'] : ['between', '>', '<', '=', '≠'];
|
||||
|
||||
const initValueList = getInitVal();
|
||||
const [operatorVal, setOperatorVal] = useState(initValueList[0]);
|
||||
const [operatorVal, setOperatorVal] = useState(initValueList[0] as string);
|
||||
const [firstInputVal, setFirstInputVal] = useState(initValueList[1] as string);
|
||||
const [secondInputVal, setSecondInputVal] = useState(initValueList[2] as string);
|
||||
// status or choice parameter dropdown selected value list
|
||||
|
@ -209,13 +218,4 @@ function SearchParameterConditions(props): any {
|
|||
);
|
||||
}
|
||||
|
||||
SearchParameterConditions.propTypes = {
|
||||
parameter: PropTypes.string,
|
||||
searchFilter: PropTypes.array,
|
||||
dismiss: PropTypes.func,
|
||||
setSearchInputVal: PropTypes.func,
|
||||
changeSearchFilterList: PropTypes.func,
|
||||
updatePage: PropTypes.func
|
||||
};
|
||||
|
||||
export default SearchParameterConditions;
|
||||
|
|
|
@ -159,7 +159,7 @@ function searchChoiceFilter(arr: TableRecord[], element: SearchItems, field: str
|
|||
}
|
||||
|
||||
// click Apply btn: set searchBox value now
|
||||
function getSearchInputValueBySearchList(searchFilter): string {
|
||||
function getSearchInputValueBySearchList(searchFilter: SearchItems[]): string {
|
||||
let str = ''; // store search input value
|
||||
|
||||
searchFilter.forEach(item => {
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { PrimaryButton, Dialog, DialogType, DialogFooter } from '@fluentui/react';
|
||||
import { KillJobIsError, TensorboardTaskInfo } from '@static/interface';
|
||||
|
||||
function TensorboardDialog(props): any {
|
||||
interface TensorboardDialogProps {
|
||||
isReaptedStartTensorboard: boolean;
|
||||
isShowTensorboardDetail: boolean;
|
||||
onHideDialog: () => void;
|
||||
item: TensorboardTaskInfo;
|
||||
errorMessage: KillJobIsError;
|
||||
}
|
||||
|
||||
function TensorboardDialog(props: TensorboardDialogProps): any {
|
||||
const { isReaptedStartTensorboard, onHideDialog, item, isShowTensorboardDetail, errorMessage } = props;
|
||||
|
||||
const dialogContentProps = {
|
||||
|
@ -19,7 +27,7 @@ function TensorboardDialog(props): any {
|
|||
|
||||
return (
|
||||
<Dialog hidden={false} dialogContentProps={dialogContentProps} modalProps={{ className: 'dialog' }}>
|
||||
{errorMessage.error ? (
|
||||
{errorMessage.isError ? (
|
||||
<div>
|
||||
<span>Error message: {errorMessage.message}</span>
|
||||
</div>
|
||||
|
@ -44,7 +52,7 @@ function TensorboardDialog(props): any {
|
|||
</div>
|
||||
</div>
|
||||
)}
|
||||
{errorMessage.error ? (
|
||||
{errorMessage.isError ? (
|
||||
<DialogFooter>
|
||||
<PrimaryButton onClick={onHideDialog} text='Close' />
|
||||
</DialogFooter>
|
||||
|
@ -60,12 +68,4 @@ function TensorboardDialog(props): any {
|
|||
);
|
||||
}
|
||||
|
||||
TensorboardDialog.propTypes = {
|
||||
isReaptedStartTensorboard: PropTypes.bool,
|
||||
isShowTensorboardDetail: PropTypes.bool,
|
||||
onHideDialog: PropTypes.func,
|
||||
item: PropTypes.object,
|
||||
errorMessage: PropTypes.object
|
||||
};
|
||||
|
||||
export default TensorboardDialog;
|
||||
|
|
|
@ -1,29 +1,33 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import axios from 'axios';
|
||||
import { DefaultButton, IContextualMenuProps } from '@fluentui/react';
|
||||
import { MANAGER_IP } from '@static/const';
|
||||
import { disableTensorboard, getTensorboardMenu } from '@static/function';
|
||||
import { Tensorboard } from '@static/interface';
|
||||
import TensorboardDialog from './TensorboardDialog';
|
||||
import { KillJobIsError, TensorboardTaskInfo } from '@static/interface';
|
||||
|
||||
function TensorboardUI(props): any {
|
||||
interface TensorboardUIProps {
|
||||
selectedRowIds: string[];
|
||||
changeSelectTrialIds: () => void;
|
||||
}
|
||||
|
||||
function TensorboardUI(props: TensorboardUIProps): any {
|
||||
let refreshTensorboard = 0;
|
||||
const { selectedRowIds, changeSelectTrialIds } = props;
|
||||
const [queryTensorboardList, setQueryTensorboardList] = useState([]);
|
||||
const [queryTensorboardList, setQueryTensorboardList] = useState([] as TensorboardTaskInfo[]);
|
||||
const [isReaptedStartTensorboard, setReaptedTensorboard] = useState(false);
|
||||
const [tensorboardPanelVisible, setTensorboardPanelVisible] = useState(false);
|
||||
const [isShowTensorboardDetail, setIsShowTensorboardDetail] = useState(false);
|
||||
const [selectedTensorboard, setSelectedTensorboard] = useState({});
|
||||
const [errorMessage, setErrorMessage] = useState({});
|
||||
const [timerList, setTimerList] = useState([0]);
|
||||
const [selectedTensorboard, setSelectedTensorboard] = useState({} as TensorboardTaskInfo);
|
||||
const [errorMessage, setErrorMessage] = useState({} as KillJobIsError);
|
||||
const [timerList, setTimerList] = useState([0] as number[]);
|
||||
|
||||
function startTrialTensorboard(): void {
|
||||
const { selectedRowIds } = props;
|
||||
if (selectedRowIds.length > 0) {
|
||||
setIsShowTensorboardDetail(false);
|
||||
const result = queryTensorboardList.filter(
|
||||
(item: Tensorboard) => item.trialJobIdList.join(',') === selectedRowIds.join(',')
|
||||
(item: TensorboardTaskInfo) => item.trialJobIdList.join(',') === selectedRowIds.join(',')
|
||||
);
|
||||
if (result.length > 0) {
|
||||
setReaptedTensorboard(true);
|
||||
|
@ -34,17 +38,18 @@ function TensorboardUI(props): any {
|
|||
startTensorboard
|
||||
.then(res => {
|
||||
if (res.status === 200) {
|
||||
console.info(res.data);
|
||||
setSelectedTensorboard(res.data);
|
||||
closeTimer();
|
||||
queryAllTensorboard();
|
||||
setErrorMessage({ error: false, message: '' });
|
||||
setErrorMessage({ isError: false, message: '' });
|
||||
setTensorboardPanelVisible(true);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
if (err.response) {
|
||||
setErrorMessage({
|
||||
error: true,
|
||||
isError: true,
|
||||
message: err.response.data.error || 'Failed to start tensorBoard!'
|
||||
});
|
||||
}
|
||||
|
@ -88,7 +93,7 @@ function TensorboardUI(props): any {
|
|||
});
|
||||
}
|
||||
|
||||
function seeTensorboardWebportal(item: Tensorboard): void {
|
||||
function seeTensorboardWebportal(item: TensorboardTaskInfo): void {
|
||||
setSelectedTensorboard(item);
|
||||
setIsShowTensorboardDetail(true);
|
||||
setTensorboardPanelVisible(true);
|
||||
|
@ -140,9 +145,4 @@ function TensorboardUI(props): any {
|
|||
);
|
||||
}
|
||||
|
||||
TensorboardUI.propTypes = {
|
||||
selectedRowIds: PropTypes.array,
|
||||
changeSelectTrialIds: PropTypes.func
|
||||
};
|
||||
|
||||
export default TensorboardUI;
|
||||
|
|
|
@ -9,6 +9,7 @@ const completed = <Icon iconName='Completed' />;
|
|||
const blocked = <Icon iconName='StatusCircleBlock' />;
|
||||
const copy = <Icon iconName='Copy' />;
|
||||
const tableListIcon = <Icon iconName='BulletedList' />;
|
||||
const Important = <Icon iconName='Important' />;
|
||||
const downLoadIcon = { iconName: 'Download' };
|
||||
const infoIconAbout = { iconName: 'info' };
|
||||
const timeIcon = { iconName: 'ReminderTime' };
|
||||
|
@ -43,5 +44,6 @@ export {
|
|||
Cancel,
|
||||
ReplyAll,
|
||||
RevToggleKey,
|
||||
ChevronRightMed
|
||||
ChevronRightMed,
|
||||
Important
|
||||
};
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
import React, { useState, useCallback } from 'react';
|
||||
import { Stack } from '@fluentui/react/lib/Stack';
|
||||
import { DefaultButton } from '@fluentui/react/lib/Button';
|
||||
import LogPanel from '@components/nav/slideNav/LogPanel';
|
||||
import { Important, Cancel } from '@components/fluent/Icon';
|
||||
import { EXPERIMENT } from '@static/datamodel';
|
||||
import '@style/nav/slideNavBtns.scss';
|
||||
|
||||
export const ErrorMessage: React.FunctionComponent = () => {
|
||||
const [hideDialog, setHideDialog] = useState(EXPERIMENT.status === 'ERROR' ? true : false);
|
||||
const [isShowLogPanel, setShowLogPanel] = useState(false);
|
||||
const closeLogPanel = useCallback(() => setShowLogPanel(false), []);
|
||||
const ShowLogPanel = useCallback(() => setShowLogPanel(true), []);
|
||||
|
||||
return (
|
||||
<>
|
||||
{hideDialog ? (
|
||||
<div className='experiment-error'>
|
||||
<Stack horizontal className='head'>
|
||||
<Stack horizontal>
|
||||
<div className='icon'>{Important}</div>
|
||||
<div className='title'>Error</div>
|
||||
</Stack>
|
||||
<Stack className='close cursor' onClick={() => setHideDialog(false)}>
|
||||
{Cancel}
|
||||
</Stack>
|
||||
</Stack>
|
||||
<div className='message'>{EXPERIMENT.error}</div>
|
||||
<Stack horizontalAlign='end' className='experiment-error-buttons'>
|
||||
<DefaultButton className='detailsBtn' onClick={ShowLogPanel} text='Learn more' />
|
||||
</Stack>
|
||||
{/* learn about click -> default active key is dispatcher. */}
|
||||
{isShowLogPanel ? <LogPanel closePanel={closeLogPanel} activeTab='dispatcher' /> : null}
|
||||
</div>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -17,6 +17,7 @@ import {
|
|||
} from '@components/fluent/Icon';
|
||||
import '@style/nav/nav.scss';
|
||||
import '@style/icon.scss';
|
||||
import { ErrorMessage } from '@components/nav/ErrorMessage';
|
||||
|
||||
interface NavState {
|
||||
version: string;
|
||||
|
@ -165,6 +166,8 @@ class NavCon extends React.Component<NavProps, NavState> {
|
|||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
{/* experiment error model */}
|
||||
<ErrorMessage />
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import axios from 'axios';
|
|||
import { IContextualMenuProps } from '@fluentui/react';
|
||||
import { RETIARIIPARAMETERS } from './const';
|
||||
import { EXPERIMENT } from './datamodel';
|
||||
import { MetricDataRecord, FinalType, Tensorboard } from './interface';
|
||||
import { MetricDataRecord, FinalType, TensorboardTaskInfo } from './interface';
|
||||
|
||||
function getPrefix(): string | undefined {
|
||||
const pathName = window.location.pathname;
|
||||
|
@ -286,7 +286,7 @@ function copyAndSort<T>(items: T[], columnKey: string, isSortedDescending?: bool
|
|||
});
|
||||
}
|
||||
|
||||
function disableTensorboard(selectedRowIds: string[], queryTensorboardList: Tensorboard[]): boolean {
|
||||
function disableTensorboard(selectedRowIds: string[], queryTensorboardList: TensorboardTaskInfo[]): boolean {
|
||||
let flag = true;
|
||||
|
||||
if (selectedRowIds.length !== 0) {
|
||||
|
@ -300,7 +300,11 @@ function disableTensorboard(selectedRowIds: string[], queryTensorboardList: Tens
|
|||
return flag;
|
||||
}
|
||||
|
||||
function getTensorboardMenu(queryTensorboardList: Tensorboard[], stopFunc, seeDetailFunc): IContextualMenuProps {
|
||||
function getTensorboardMenu(
|
||||
queryTensorboardList: TensorboardTaskInfo[],
|
||||
stopFunc,
|
||||
seeDetailFunc
|
||||
): IContextualMenuProps {
|
||||
const result: Array<object> = [];
|
||||
if (queryTensorboardList.length !== 0) {
|
||||
result.push({
|
||||
|
|
|
@ -167,13 +167,20 @@ interface AllExperimentList {
|
|||
prefixUrl: string;
|
||||
}
|
||||
|
||||
interface Tensorboard {
|
||||
interface KillJobIsError {
|
||||
isError: boolean;
|
||||
message: string;
|
||||
}
|
||||
|
||||
type TensorboardTaskStatus = 'RUNNING' | 'DOWNLOADING_DATA' | 'STOPPING' | 'STOPPED' | 'ERROR' | 'FAIL_DOWNLOAD_DATA';
|
||||
|
||||
interface TensorboardTaskInfo {
|
||||
id: string;
|
||||
status: string;
|
||||
status: TensorboardTaskStatus;
|
||||
trialJobIdList: string[];
|
||||
trialLogDirectoryList: string[];
|
||||
pid: number;
|
||||
port: string;
|
||||
pid?: number;
|
||||
port?: string;
|
||||
}
|
||||
|
||||
// for TableList search
|
||||
|
@ -186,7 +193,7 @@ interface SearchItems {
|
|||
isChoice: boolean; // for parameters: type = choice and status also as choice type
|
||||
}
|
||||
|
||||
interface allTrialsIntermediateChart {
|
||||
interface AllTrialsIntermediateChart {
|
||||
name: string;
|
||||
// id: string;
|
||||
sequenceId: number;
|
||||
|
@ -215,7 +222,8 @@ export {
|
|||
MultipleAxes,
|
||||
SortInfo,
|
||||
AllExperimentList,
|
||||
Tensorboard,
|
||||
TensorboardTaskInfo,
|
||||
SearchItems,
|
||||
allTrialsIntermediateChart
|
||||
KillJobIsError,
|
||||
AllTrialsIntermediateChart
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@ import { MetricDataRecord, TableRecord, TrialJobInfo, MultipleAxes } from '../in
|
|||
import { Trial } from './trial';
|
||||
import { SearchSpace, MetricSpace } from './searchspace';
|
||||
import { requestAxios, parseMetrics } from '../function';
|
||||
import { allTrialsIntermediateChart } from '../interface';
|
||||
import { AllTrialsIntermediateChart } from '../interface';
|
||||
|
||||
function groupMetricsByTrial(metrics: MetricDataRecord[]): Map<string, MetricDataRecord[]> {
|
||||
const ret = new Map<string, MetricDataRecord[]>();
|
||||
|
@ -91,8 +91,8 @@ class TrialManager {
|
|||
return this.filter(trial => trial.status !== 'WAITING');
|
||||
}
|
||||
|
||||
public allTrialsIntermediateChart(): allTrialsIntermediateChart[] {
|
||||
const ret: allTrialsIntermediateChart[] = [];
|
||||
public allTrialsIntermediateChart(): AllTrialsIntermediateChart[] {
|
||||
const ret: AllTrialsIntermediateChart[] = [];
|
||||
for (const trial of this.trials.values()) {
|
||||
const mediate: number[] = [];
|
||||
for (const items of trial.intermediates) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
$buttonBorderRadius: 23px;
|
||||
|
||||
$errorseriscolor: #FC615C;
|
||||
.config {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
|
@ -80,3 +80,63 @@ $buttonBorderRadius: 23px;
|
|||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.experiment-error {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
max-width: 455px;
|
||||
min-width: 300px;
|
||||
padding: 28px 32px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0px 4px 16px rgba(78, 97, 123, 0.2);
|
||||
background-color: #fff;
|
||||
|
||||
.head {
|
||||
height: 27px;
|
||||
line-height: 27px;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.title {
|
||||
color: $errorseriscolor;
|
||||
}
|
||||
|
||||
.close {
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
}
|
||||
|
||||
.icon{
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
background-color: $errorseriscolor;
|
||||
border-radius: 50%;
|
||||
margin-right: 15px;
|
||||
|
||||
i{
|
||||
font-size: 21px;
|
||||
color: #fff;
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.message {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
&-buttons {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.detailsBtn {
|
||||
width: 113px;
|
||||
height: 32px;
|
||||
color: #fff;
|
||||
background: $errorseriscolor;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче