Unverified Commit 4ab85d3d authored by Lijiaoa's avatar Lijiaoa Committed by GitHub
Browse files

Show experiment error message and refactor function component props (#5029)

parent 119a2b60
import React, { useRef } from 'react'; import React, { useRef } from 'react';
import PropTypes from 'prop-types';
import copy from 'copy-to-clipboard'; import copy from 'copy-to-clipboard';
import { IconButton, FontSizes, TooltipHost } from '@fluentui/react'; import { IconButton, FontSizes, TooltipHost } from '@fluentui/react';
import { TOOLTIP_BACKGROUND_COLOR } from '@static/const'; import { TOOLTIP_BACKGROUND_COLOR } from '@static/const';
interface CopyButtonProps {
value: string;
hideTooltip?: boolean;
}
const COPIED_TOOLTIP_CLOSE_DELAY = 1000; const COPIED_TOOLTIP_CLOSE_DELAY = 1000;
const CopyButton = ({ value, hideTooltip }): any => { const CopyButton = (props: CopyButtonProps): any => {
const { value, hideTooltip } = props;
const ref = useRef(null); const ref = useRef(null);
return ( return (
<div> <div>
...@@ -47,9 +52,4 @@ const CopyButton = ({ value, hideTooltip }): any => { ...@@ -47,9 +52,4 @@ const CopyButton = ({ value, hideTooltip }): any => {
); );
}; };
CopyButton.propTypes = {
value: PropTypes.string.isRequired,
hideTooltip: PropTypes.bool
};
export default CopyButton; export default CopyButton;
import * as React from 'react'; import * as React from 'react';
import PropTypes from 'prop-types'; import { DetailsRow, IDetailsRowBaseProps } from '@fluentui/react/lib/DetailsList';
import { DetailsRow } from '@fluentui/react';
import OpenRow from './OpenRow'; import OpenRow from './OpenRow';
import '@style/table.scss'; import '@style/table.scss';
const ExpandableDetails = (props): any => { interface ExpandableDetailsProps {
detailsProps: IDetailsRowBaseProps;
isExpand: boolean;
}
const ExpandableDetails = (props: ExpandableDetailsProps): any => {
const { detailsProps, isExpand } = props; const { detailsProps, isExpand } = props;
return ( return (
<div> <div>
...@@ -14,9 +18,4 @@ const ExpandableDetails = (props): any => { ...@@ -14,9 +18,4 @@ const ExpandableDetails = (props): any => {
); );
}; };
ExpandableDetails.propTypes = {
detailsProps: PropTypes.object,
isExpand: PropTypes.bool
};
export default ExpandableDetails; export default ExpandableDetails;
import React, { useState } from 'react'; import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { Stack, PrimaryButton, Pivot, PivotItem, DefaultButton } from '@fluentui/react'; import { Stack, PrimaryButton, Pivot, PivotItem, DefaultButton } from '@fluentui/react';
import * as copy from 'copy-to-clipboard'; import * as copy from 'copy-to-clipboard';
import JSONTree from 'react-json-tree'; import JSONTree from 'react-json-tree';
...@@ -18,7 +17,11 @@ import '@style/experiment/overview/overview.scss'; ...@@ -18,7 +17,11 @@ import '@style/experiment/overview/overview.scss';
* Remember to update it if the value is changed or this file is moved. * 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 [typeInfo, setTypeInfo] = useState('');
const [info, setInfo] = useState(''); const [info, setInfo] = useState('');
const [isHidenInfo, setHideninfo] = useState(true); const [isHidenInfo, setHideninfo] = useState(true);
...@@ -161,8 +164,4 @@ const OpenRow = (props): any => { ...@@ -161,8 +164,4 @@ const OpenRow = (props): any => {
); );
}; };
OpenRow.propTypes = {
trialId: PropTypes.string
};
export default OpenRow; export default OpenRow;
import * as React from 'react'; import * as React from 'react';
import PropTypes from 'prop-types';
import TrialLog from './TrialLog'; import TrialLog from './TrialLog';
const PaitrialLog = (props): any => { interface PaitrialLogProps {
logStr: string;
}
const PaitrialLog = (props: PaitrialLogProps): any => {
const { logStr } = props; const { logStr } = props;
const isHasNFSLog = logStr.indexOf(',') !== -1 ? true : false; const isHasNFSLog = logStr.indexOf(',') !== -1 ? true : false;
return ( return (
...@@ -19,8 +22,4 @@ const PaitrialLog = (props): any => { ...@@ -19,8 +22,4 @@ const PaitrialLog = (props): any => {
); );
}; };
PaitrialLog.propTypes = {
logStr: PropTypes.string
};
export default PaitrialLog; export default PaitrialLog;
import * as React from 'react'; 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 { logStr, logName } = props;
const isHyperlink = logStr.toLowerCase().startsWith('http'); const isHyperlink = logStr.toLowerCase().startsWith('http');
...@@ -19,9 +23,4 @@ const TrialLog = (props): any => { ...@@ -19,9 +23,4 @@ const TrialLog = (props): any => {
); );
}; };
TrialLog.propTypes = {
logStr: PropTypes.string,
logName: PropTypes.string
};
export default TrialLog; export default TrialLog;
import * as React from 'react'; import * as React from 'react';
import { Stack, PrimaryButton, Toggle, IStackTokens } from '@fluentui/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 { reformatRetiariiParameter } from '@static/function';
import ReactEcharts from 'echarts-for-react'; import ReactEcharts from 'echarts-for-react';
import 'echarts/lib/component/tooltip'; import 'echarts/lib/component/tooltip';
...@@ -11,9 +11,9 @@ const stackTokens: IStackTokens = { ...@@ -11,9 +11,9 @@ const stackTokens: IStackTokens = {
}; };
interface IntermediateState { interface IntermediateState {
detailSource: allTrialsIntermediateChart[]; detailSource: AllTrialsIntermediateChart[];
interSource: object; interSource: object;
filterSource: allTrialsIntermediateChart[]; filterSource: AllTrialsIntermediateChart[];
eachIntermediateNum: number; // trial's intermediate number count eachIntermediateNum: number; // trial's intermediate number count
isLoadconfirmBtn: boolean; isLoadconfirmBtn: boolean;
isFilter?: boolean | undefined; isFilter?: boolean | undefined;
...@@ -23,7 +23,7 @@ interface IntermediateState { ...@@ -23,7 +23,7 @@ interface IntermediateState {
} }
interface IntermediateProps { interface IntermediateProps {
source: allTrialsIntermediateChart[]; source: AllTrialsIntermediateChart[];
} }
class Intermediate extends React.Component<IntermediateProps, IntermediateState> { class Intermediate extends React.Component<IntermediateProps, IntermediateState> {
...@@ -47,7 +47,7 @@ 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) { if (source.length > 0) {
this.setState({ this.setState({
length: source.length, length: source.length,
...@@ -145,7 +145,7 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState> ...@@ -145,7 +145,7 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
// confirm btn function [filter data] // confirm btn function [filter data]
filterLines = (): void => { filterLines = (): void => {
const filterSource: allTrialsIntermediateChart[] = []; const filterSource: AllTrialsIntermediateChart[] = [];
this.setState({ isLoadconfirmBtn: true }, () => { this.setState({ isLoadconfirmBtn: true }, () => {
const { source } = this.props; const { source } = this.props;
// get input value // get input value
......
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import { PrimaryButton, Dialog, DialogType, DialogFooter } from '@fluentui/react'; 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 { onHideDialog, trialId, isError } = props;
const dialogContentProps = { const dialogContentProps = {
...@@ -29,10 +35,4 @@ function KillJobDialog(props): any { ...@@ -29,10 +35,4 @@ function KillJobDialog(props): any {
); );
} }
KillJobDialog.propTypes = {
trialId: PropTypes.string,
isError: PropTypes.object,
onHideDialog: PropTypes.func
};
export default KillJobDialog; export default KillJobDialog;
import React, { useState, useRef, useContext } from 'react'; import React, { useState, useRef, useContext } from 'react';
import PropTypes from 'prop-types';
import axios from 'axios'; import axios from 'axios';
import { Stack, FocusTrapCallout, DefaultButton, FocusZone, PrimaryButton } from '@fluentui/react'; import { Stack, FocusTrapCallout, DefaultButton, FocusZone, PrimaryButton } from '@fluentui/react';
import { MANAGER_IP } from '@static/const'; import { MANAGER_IP } from '@static/const';
...@@ -9,7 +8,11 @@ import { gap10 } from '@components/fluent/ChildrenGap'; ...@@ -9,7 +8,11 @@ import { gap10 } from '@components/fluent/ChildrenGap';
import { styles } from '@components/experiment/overview/params/basicInfoStyles'; import { styles } from '@components/experiment/overview/params/basicInfoStyles';
import { AppContext } from '@/App'; import { AppContext } from '@/App';
function KillJobIndex(props): any { interface KillJobIndexProps {
trialId: string;
}
function KillJobIndex(props: KillJobIndexProps): any {
const menuButtonElement = useRef(null); const menuButtonElement = useRef(null);
const { startTimer, closeTimer, interval, refreshDetailTable } = useContext(AppContext); const { startTimer, closeTimer, interval, refreshDetailTable } = useContext(AppContext);
const { trialId } = props; const { trialId } = props;
...@@ -118,9 +121,4 @@ function KillJobIndex(props): any { ...@@ -118,9 +121,4 @@ function KillJobIndex(props): any {
); );
} }
KillJobIndex.propTypes = {
trialId: PropTypes.string,
updatePage: PropTypes.func
};
export default KillJobIndex; export default KillJobIndex;
import React, { useState, useContext } from 'react'; import React, { useState, useContext } from 'react';
import PropTypes from 'prop-types';
import { Stack, PrimaryButton } from '@fluentui/react'; import { Stack, PrimaryButton } from '@fluentui/react';
import { gap10 } from '@components/fluent/ChildrenGap'; import { gap10 } from '@components/fluent/ChildrenGap';
import { AppContext } from '@/App'; import { AppContext } from '@/App';
import { SearchItems } from '@static/interface';
import { getSearchInputValueBySearchList } from './searchFunction'; import { getSearchInputValueBySearchList } from './searchFunction';
// This file is for search trial ['Trial id', 'Trial No.'] // This file is for search trial ['Trial id', 'Trial No.']
...@@ -14,11 +14,19 @@ import { getSearchInputValueBySearchList } from './searchFunction'; ...@@ -14,11 +14,19 @@ import { getSearchInputValueBySearchList } from './searchFunction';
// 1 // only filter one trial that trial no is 1 // 1 // only filter one trial that trial no is 1
// bw // only filter that trial id include `bw` // 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); const { updateDetailPage } = useContext(AppContext);
// searchName val: Trial No. | Trial id // searchName val: Trial No. | Trial id
const { searchName, searchFilter, dismiss, changeSearchFilterList, setSearchInputVal } = props; 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 { function updateFirstInputVal(ev: React.ChangeEvent<HTMLInputElement>): void {
setFirstInputVal(ev.target.value); setFirstInputVal(ev.target.value);
...@@ -79,12 +87,4 @@ function GeneralSearch(props): any { ...@@ -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; export default GeneralSearch;
import React, { useState, useContext } from 'react'; import React, { useState, useContext } from 'react';
import PropTypes from 'prop-types';
import { import {
Stack, Stack,
DefaultButton, DefaultButton,
...@@ -18,11 +17,15 @@ import { classNames, isChoiceType } from './searchFunction'; ...@@ -18,11 +17,15 @@ import { classNames, isChoiceType } from './searchFunction';
import { AppContext } from '@/App'; import { AppContext } from '@/App';
// TableList search layout // 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 { searchFilter, changeSearchFilterList } = props;
const { updateDetailPage } = useContext(AppContext); const { updateDetailPage } = useContext(AppContext);
const [searchInputVal, setSearchInputVal] = useState(''); const [searchInputVal, setSearchInputVal] = useState('' as string);
function getSearchMenu(parameterList): IContextualMenuProps { function getSearchMenu(parameterList): IContextualMenuProps {
const menu: Array<object> = []; const menu: Array<object> = [];
...@@ -96,7 +99,7 @@ function Search(props): any { ...@@ -96,7 +99,7 @@ function Search(props): any {
function renderParametersSearchComponent(item: IContextualMenuItem, dismissMenu: () => void): JSX.Element { function renderParametersSearchComponent(item: IContextualMenuItem, dismissMenu: () => void): JSX.Element {
return ( return (
<SearchParameterConditions <SearchParameterConditions
parameter={item.text} parameter={item.text ?? ''}
searchFilter={searchFilter} // search filter list searchFilter={searchFilter} // search filter list
changeSearchFilterList={changeSearchFilterList} changeSearchFilterList={changeSearchFilterList}
updatePage={updateDetailPage} updatePage={updateDetailPage}
...@@ -109,7 +112,7 @@ function Search(props): any { ...@@ -109,7 +112,7 @@ function Search(props): any {
function renderDefaultMetricSearchComponent(item: IContextualMenuItem, dismissMenu: () => void): JSX.Element { function renderDefaultMetricSearchComponent(item: IContextualMenuItem, dismissMenu: () => void): JSX.Element {
return ( return (
<SearchDefaultMetric <SearchDefaultMetric
parameter={item.text} parameter={item.text ?? ''}
searchFilter={searchFilter} // search filter list searchFilter={searchFilter} // search filter list
changeSearchFilterList={changeSearchFilterList} changeSearchFilterList={changeSearchFilterList}
updatePage={updateDetailPage} updatePage={updateDetailPage}
...@@ -122,7 +125,7 @@ function Search(props): any { ...@@ -122,7 +125,7 @@ function Search(props): any {
function renderIdAndNoComponent(item: IContextualMenuItem, dismissMenu: () => void): JSX.Element { function renderIdAndNoComponent(item: IContextualMenuItem, dismissMenu: () => void): JSX.Element {
return ( return (
<GeneralSearch <GeneralSearch
searchName={item.text} searchName={item.text ?? ''}
searchFilter={searchFilter} // search fliter list searchFilter={searchFilter} // search fliter list
changeSearchFilterList={changeSearchFilterList} changeSearchFilterList={changeSearchFilterList}
setSearchInputVal={setSearchInputVal} setSearchInputVal={setSearchInputVal}
...@@ -136,7 +139,7 @@ function Search(props): any { ...@@ -136,7 +139,7 @@ function Search(props): any {
} }
// update TableList page // update TableList page
function changeTableListPage(searchFilterList: Array<SearchItems>): void { function changeTableListPage(searchFilterList: SearchItems[]): void {
changeSearchFilterList(searchFilterList); changeSearchFilterList(searchFilterList);
updateDetailPage(); updateDetailPage();
} }
...@@ -310,9 +313,4 @@ function Search(props): any { ...@@ -310,9 +313,4 @@ function Search(props): any {
); );
} }
Search.propTypes = {
searchFilter: PropTypes.array,
changeSearchFilterList: PropTypes.func
};
export default Search; export default Search;
import React, { useState, useContext } from 'react'; import React, { useState, useContext } from 'react';
import PropTypes from 'prop-types';
import { Stack, PrimaryButton, Dropdown, IDropdownOption } from '@fluentui/react'; import { Stack, PrimaryButton, Dropdown, IDropdownOption } from '@fluentui/react';
import { EXPERIMENT } from '@static/datamodel'; import { EXPERIMENT } from '@static/datamodel';
import { getSearchInputValueBySearchList } from './searchFunction'; import { getSearchInputValueBySearchList } from './searchFunction';
import { gap10 } from '@components/fluent/ChildrenGap'; import { gap10 } from '@components/fluent/ChildrenGap';
import { AppContext } from '@/App'; import { AppContext } from '@/App';
import { SearchItems } from '@static/interface';
// This file is for filtering trial default metric column including intermediate results // This file is for filtering trial default metric column including intermediate results
// you could click `filter` button -> `Default metric` use it // you could click `filter` button -> `Default metric` use it
...@@ -14,13 +14,22 @@ import { AppContext } from '@/App'; ...@@ -14,13 +14,22 @@ import { AppContext } from '@/App';
// Default metric:[0.1,0.2]; // 0.1 < trial metric < 0.2 // 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 // 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 { parameter, searchFilter, dismiss, changeSearchFilterList, setSearchInputVal } = props;
const { updateDetailPage } = useContext(AppContext); const { updateDetailPage } = useContext(AppContext);
const operatorList = ['between', '>', '<', '=']; const operatorList = ['between', '>', '<', '='];
const initValueList = getInitVal(); 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 [firstInputVal, setFirstInputVal] = useState(initValueList[1] as string);
const [secondInputVal, setSecondInputVal] = useState(initValueList[2] as string); const [secondInputVal, setSecondInputVal] = useState(initValueList[2] as string);
...@@ -61,7 +70,7 @@ function SearchDefaultMetric(props): any { ...@@ -61,7 +70,7 @@ function SearchDefaultMetric(props): any {
if (secondInputVal === '' && operatorVal === 'between') { if (secondInputVal === '' && operatorVal === 'between') {
// if user uses 'between' operator and doesn't write the second input value, // if user uses 'between' operator and doesn't write the second input value,
// help to set second value as this parameter max 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; return secondInputVal as string;
...@@ -141,13 +150,4 @@ function SearchDefaultMetric(props): any { ...@@ -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; export default SearchDefaultMetric;
import React, { useState, useContext } from 'react'; import React, { useState, useContext } from 'react';
import PropTypes from 'prop-types';
import { Stack, PrimaryButton, Dropdown, IDropdownOption } from '@fluentui/react'; import { Stack, PrimaryButton, Dropdown, IDropdownOption } from '@fluentui/react';
import { EXPERIMENT } from '@static/datamodel'; import { EXPERIMENT } from '@static/datamodel';
import { getDropdownOptions, getSearchInputValueBySearchList } from './searchFunction'; import { getDropdownOptions, getSearchInputValueBySearchList } from './searchFunction';
import { gap10 } from '@components/fluent/ChildrenGap'; import { gap10 } from '@components/fluent/ChildrenGap';
import { AppContext } from '@/App'; import { AppContext } from '@/App';
import { SearchItems } from '@static/interface';
/*** /***
* This file is for filtering trial parameters and trial status * This file is for filtering trial parameters and trial status
...@@ -30,14 +30,23 @@ import { AppContext } from '@/App'; ...@@ -30,14 +30,23 @@ import { AppContext } from '@/App';
* hidden_size≠1024 // please don't input this format! * 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 { parameter, searchFilter, dismiss, changeSearchFilterList, setSearchInputVal } = props;
const { updateDetailPage } = useContext(AppContext); const { updateDetailPage } = useContext(AppContext);
const isChoiceTypeSearchFilter = parameter === 'StatusNNI' || EXPERIMENT.searchSpace[parameter]._type === 'choice'; const isChoiceTypeSearchFilter = parameter === 'StatusNNI' || EXPERIMENT.searchSpace[parameter]._type === 'choice';
const operatorList = isChoiceTypeSearchFilter ? ['=', ''] : ['between', '>', '<', '=', '']; const operatorList = isChoiceTypeSearchFilter ? ['=', ''] : ['between', '>', '<', '=', ''];
const initValueList = getInitVal(); 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 [firstInputVal, setFirstInputVal] = useState(initValueList[1] as string);
const [secondInputVal, setSecondInputVal] = useState(initValueList[2] as string); const [secondInputVal, setSecondInputVal] = useState(initValueList[2] as string);
// status or choice parameter dropdown selected value list // status or choice parameter dropdown selected value list
...@@ -209,13 +218,4 @@ function SearchParameterConditions(props): any { ...@@ -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; export default SearchParameterConditions;
...@@ -159,7 +159,7 @@ function searchChoiceFilter(arr: TableRecord[], element: SearchItems, field: str ...@@ -159,7 +159,7 @@ function searchChoiceFilter(arr: TableRecord[], element: SearchItems, field: str
} }
// click Apply btn: set searchBox value now // click Apply btn: set searchBox value now
function getSearchInputValueBySearchList(searchFilter): string { function getSearchInputValueBySearchList(searchFilter: SearchItems[]): string {
let str = ''; // store search input value let str = ''; // store search input value
searchFilter.forEach(item => { searchFilter.forEach(item => {
......
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import { PrimaryButton, Dialog, DialogType, DialogFooter } from '@fluentui/react'; 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 { isReaptedStartTensorboard, onHideDialog, item, isShowTensorboardDetail, errorMessage } = props;
const dialogContentProps = { const dialogContentProps = {
...@@ -19,7 +27,7 @@ function TensorboardDialog(props): any { ...@@ -19,7 +27,7 @@ function TensorboardDialog(props): any {
return ( return (
<Dialog hidden={false} dialogContentProps={dialogContentProps} modalProps={{ className: 'dialog' }}> <Dialog hidden={false} dialogContentProps={dialogContentProps} modalProps={{ className: 'dialog' }}>
{errorMessage.error ? ( {errorMessage.isError ? (
<div> <div>
<span>Error message: {errorMessage.message}</span> <span>Error message: {errorMessage.message}</span>
</div> </div>
...@@ -44,7 +52,7 @@ function TensorboardDialog(props): any { ...@@ -44,7 +52,7 @@ function TensorboardDialog(props): any {
</div> </div>
</div> </div>
)} )}
{errorMessage.error ? ( {errorMessage.isError ? (
<DialogFooter> <DialogFooter>
<PrimaryButton onClick={onHideDialog} text='Close' /> <PrimaryButton onClick={onHideDialog} text='Close' />
</DialogFooter> </DialogFooter>
...@@ -60,12 +68,4 @@ function TensorboardDialog(props): any { ...@@ -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; export default TensorboardDialog;
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import axios from 'axios'; import axios from 'axios';
import { DefaultButton, IContextualMenuProps } from '@fluentui/react'; import { DefaultButton, IContextualMenuProps } from '@fluentui/react';
import { MANAGER_IP } from '@static/const'; import { MANAGER_IP } from '@static/const';
import { disableTensorboard, getTensorboardMenu } from '@static/function'; import { disableTensorboard, getTensorboardMenu } from '@static/function';
import { Tensorboard } from '@static/interface';
import TensorboardDialog from './TensorboardDialog'; 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; let refreshTensorboard = 0;
const { selectedRowIds, changeSelectTrialIds } = props; const { selectedRowIds, changeSelectTrialIds } = props;
const [queryTensorboardList, setQueryTensorboardList] = useState([]); const [queryTensorboardList, setQueryTensorboardList] = useState([] as TensorboardTaskInfo[]);
const [isReaptedStartTensorboard, setReaptedTensorboard] = useState(false); const [isReaptedStartTensorboard, setReaptedTensorboard] = useState(false);
const [tensorboardPanelVisible, setTensorboardPanelVisible] = useState(false); const [tensorboardPanelVisible, setTensorboardPanelVisible] = useState(false);
const [isShowTensorboardDetail, setIsShowTensorboardDetail] = useState(false); const [isShowTensorboardDetail, setIsShowTensorboardDetail] = useState(false);
const [selectedTensorboard, setSelectedTensorboard] = useState({}); const [selectedTensorboard, setSelectedTensorboard] = useState({} as TensorboardTaskInfo);
const [errorMessage, setErrorMessage] = useState({}); const [errorMessage, setErrorMessage] = useState({} as KillJobIsError);
const [timerList, setTimerList] = useState([0]); const [timerList, setTimerList] = useState([0] as number[]);
function startTrialTensorboard(): void { function startTrialTensorboard(): void {
const { selectedRowIds } = props; const { selectedRowIds } = props;
if (selectedRowIds.length > 0) { if (selectedRowIds.length > 0) {
setIsShowTensorboardDetail(false); setIsShowTensorboardDetail(false);
const result = queryTensorboardList.filter( const result = queryTensorboardList.filter(
(item: Tensorboard) => item.trialJobIdList.join(',') === selectedRowIds.join(',') (item: TensorboardTaskInfo) => item.trialJobIdList.join(',') === selectedRowIds.join(',')
); );
if (result.length > 0) { if (result.length > 0) {
setReaptedTensorboard(true); setReaptedTensorboard(true);
...@@ -34,17 +38,18 @@ function TensorboardUI(props): any { ...@@ -34,17 +38,18 @@ function TensorboardUI(props): any {
startTensorboard startTensorboard
.then(res => { .then(res => {
if (res.status === 200) { if (res.status === 200) {
console.info(res.data);
setSelectedTensorboard(res.data); setSelectedTensorboard(res.data);
closeTimer(); closeTimer();
queryAllTensorboard(); queryAllTensorboard();
setErrorMessage({ error: false, message: '' }); setErrorMessage({ isError: false, message: '' });
setTensorboardPanelVisible(true); setTensorboardPanelVisible(true);
} }
}) })
.catch(err => { .catch(err => {
if (err.response) { if (err.response) {
setErrorMessage({ setErrorMessage({
error: true, isError: true,
message: err.response.data.error || 'Failed to start tensorBoard!' message: err.response.data.error || 'Failed to start tensorBoard!'
}); });
} }
...@@ -88,7 +93,7 @@ function TensorboardUI(props): any { ...@@ -88,7 +93,7 @@ function TensorboardUI(props): any {
}); });
} }
function seeTensorboardWebportal(item: Tensorboard): void { function seeTensorboardWebportal(item: TensorboardTaskInfo): void {
setSelectedTensorboard(item); setSelectedTensorboard(item);
setIsShowTensorboardDetail(true); setIsShowTensorboardDetail(true);
setTensorboardPanelVisible(true); setTensorboardPanelVisible(true);
...@@ -140,9 +145,4 @@ function TensorboardUI(props): any { ...@@ -140,9 +145,4 @@ function TensorboardUI(props): any {
); );
} }
TensorboardUI.propTypes = {
selectedRowIds: PropTypes.array,
changeSelectTrialIds: PropTypes.func
};
export default TensorboardUI; export default TensorboardUI;
...@@ -9,6 +9,7 @@ const completed = <Icon iconName='Completed' />; ...@@ -9,6 +9,7 @@ const completed = <Icon iconName='Completed' />;
const blocked = <Icon iconName='StatusCircleBlock' />; const blocked = <Icon iconName='StatusCircleBlock' />;
const copy = <Icon iconName='Copy' />; const copy = <Icon iconName='Copy' />;
const tableListIcon = <Icon iconName='BulletedList' />; const tableListIcon = <Icon iconName='BulletedList' />;
const Important = <Icon iconName='Important' />;
const downLoadIcon = { iconName: 'Download' }; const downLoadIcon = { iconName: 'Download' };
const infoIconAbout = { iconName: 'info' }; const infoIconAbout = { iconName: 'info' };
const timeIcon = { iconName: 'ReminderTime' }; const timeIcon = { iconName: 'ReminderTime' };
...@@ -43,5 +44,6 @@ export { ...@@ -43,5 +44,6 @@ export {
Cancel, Cancel,
ReplyAll, ReplyAll,
RevToggleKey, RevToggleKey,
ChevronRightMed ChevronRightMed,
Important
}; };
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 { ...@@ -17,6 +17,7 @@ import {
} from '@components/fluent/Icon'; } from '@components/fluent/Icon';
import '@style/nav/nav.scss'; import '@style/nav/nav.scss';
import '@style/icon.scss'; import '@style/icon.scss';
import { ErrorMessage } from '@components/nav/ErrorMessage';
interface NavState { interface NavState {
version: string; version: string;
...@@ -165,6 +166,8 @@ class NavCon extends React.Component<NavProps, NavState> { ...@@ -165,6 +166,8 @@ class NavCon extends React.Component<NavProps, NavState> {
/> />
)} )}
</React.Fragment> </React.Fragment>
{/* experiment error model */}
<ErrorMessage />
</Stack> </Stack>
); );
} }
......
...@@ -3,7 +3,7 @@ import axios from 'axios'; ...@@ -3,7 +3,7 @@ import axios from 'axios';
import { IContextualMenuProps } from '@fluentui/react'; import { IContextualMenuProps } from '@fluentui/react';
import { RETIARIIPARAMETERS } from './const'; import { RETIARIIPARAMETERS } from './const';
import { EXPERIMENT } from './datamodel'; import { EXPERIMENT } from './datamodel';
import { MetricDataRecord, FinalType, Tensorboard } from './interface'; import { MetricDataRecord, FinalType, TensorboardTaskInfo } from './interface';
function getPrefix(): string | undefined { function getPrefix(): string | undefined {
const pathName = window.location.pathname; const pathName = window.location.pathname;
...@@ -286,7 +286,7 @@ function copyAndSort<T>(items: T[], columnKey: string, isSortedDescending?: bool ...@@ -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; let flag = true;
if (selectedRowIds.length !== 0) { if (selectedRowIds.length !== 0) {
...@@ -300,7 +300,11 @@ function disableTensorboard(selectedRowIds: string[], queryTensorboardList: Tens ...@@ -300,7 +300,11 @@ function disableTensorboard(selectedRowIds: string[], queryTensorboardList: Tens
return flag; return flag;
} }
function getTensorboardMenu(queryTensorboardList: Tensorboard[], stopFunc, seeDetailFunc): IContextualMenuProps { function getTensorboardMenu(
queryTensorboardList: TensorboardTaskInfo[],
stopFunc,
seeDetailFunc
): IContextualMenuProps {
const result: Array<object> = []; const result: Array<object> = [];
if (queryTensorboardList.length !== 0) { if (queryTensorboardList.length !== 0) {
result.push({ result.push({
......
...@@ -167,13 +167,20 @@ interface AllExperimentList { ...@@ -167,13 +167,20 @@ interface AllExperimentList {
prefixUrl: string; 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; id: string;
status: string; status: TensorboardTaskStatus;
trialJobIdList: string[]; trialJobIdList: string[];
trialLogDirectoryList: string[]; trialLogDirectoryList: string[];
pid: number; pid?: number;
port: string; port?: string;
} }
// for TableList search // for TableList search
...@@ -186,7 +193,7 @@ interface SearchItems { ...@@ -186,7 +193,7 @@ interface SearchItems {
isChoice: boolean; // for parameters: type = choice and status also as choice type isChoice: boolean; // for parameters: type = choice and status also as choice type
} }
interface allTrialsIntermediateChart { interface AllTrialsIntermediateChart {
name: string; name: string;
// id: string; // id: string;
sequenceId: number; sequenceId: number;
...@@ -215,7 +222,8 @@ export { ...@@ -215,7 +222,8 @@ export {
MultipleAxes, MultipleAxes,
SortInfo, SortInfo,
AllExperimentList, AllExperimentList,
Tensorboard, TensorboardTaskInfo,
SearchItems, SearchItems,
allTrialsIntermediateChart KillJobIsError,
AllTrialsIntermediateChart
}; };
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