pipelines/frontend/src/components/graph/ExecutionNode.tsx

151 lines
5.0 KiB
TypeScript

/*
* Copyright 2021 The Kubeflow Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import CheckCircleIcon from '@material-ui/icons/CheckCircle';
import CloudDownloadIcon from '@material-ui/icons/CloudDownload';
import ErrorIcon from '@material-ui/icons/Error';
import ListAltIcon from '@material-ui/icons/ListAlt';
import PowerSettingsNewIcon from '@material-ui/icons/PowerSettingsNew';
import RefreshIcon from '@material-ui/icons/Refresh';
import RemoveCircleOutlineIcon from '@material-ui/icons/RemoveCircleOutline';
import React, { ReactElement } from 'react';
import { Handle, Position } from 'react-flow-renderer';
import StopCircle from 'src/icons/StopCircle';
import { Execution } from 'src/third_party/mlmd';
import { classes } from 'typestyle';
import { ExecutionFlowElementData } from './Constants';
import MoreHorizIcon from '@material-ui/icons/MoreHoriz';
export interface ExecutionNodeProps {
id: string;
data: ExecutionFlowElementData;
// selected: boolean;
// status: ExecutionNodeStatus;
}
function ExecutionNode({ id, data }: ExecutionNodeProps) {
let icon = getIcon(data.state);
let executionIcon = getExecutionIcon(data.state);
const fullWidth = icon ? 'w-64' : 'w-56';
return (
<>
<div title={data.label} className='container'>
<button
className={classes(
'focus:ring flex items-stretch border-0 transform h-12 hover:scale-105 transition relative overflow:hidden bg-white shadow-lg rounded-lg',
fullWidth,
)}
>
<div className='flex justify-between flex-row relative w-full h-full'>
<div className='w-8 pl-2 h-full flex flex-col justify-center rounded-l-lg'>
{executionIcon}
</div>
<div className='px-3 py-4 w-44 h-full flex justify-center items-center'>
<span className='w-44 text-sm truncate' id={id}>
{data.label}
</span>
</div>
{icon}
</div>
</button>
</div>
<Handle
type='target'
position={Position.Top}
isValidConnection={() => false}
style={{ background: '#000', height: '1px', width: '1px', border: 0 }}
/>
<Handle
type='source'
position={Position.Bottom}
isValidConnection={() => false}
style={{ background: '#000', height: '1px', width: '1px', border: 0 }}
/>
</>
);
}
export default ExecutionNode;
export function getExecutionIcon(state: Execution.State | undefined) {
if (state === undefined) {
return <ListAltIcon className='text-mui-grey-500' />;
}
return <ListAltIcon className='text-mui-blue-600' />;
}
export function getIcon(state: Execution.State | undefined) {
if (state === undefined) {
return null;
}
switch (state) {
case Execution.State.UNKNOWN:
return getStateIconWrapper(
<MoreHorizIcon className='text-mui-grey-600' />,
'bg-mui-grey-200',
);
case Execution.State.NEW:
return getStateIconWrapper(
<PowerSettingsNewIcon className='text-mui-blue-600' />,
'bg-mui-blue-50',
);
case Execution.State.RUNNING:
return getStateIconWrapper(<RefreshIcon className='text-mui-green-600' />, 'bg-mui-green-50');
case Execution.State.CACHED:
return getStateIconWrapper(
<CloudDownloadIcon className='text-mui-green-600' />,
'bg-mui-green-50',
);
case Execution.State.FAILED:
return getStateIconWrapper(<ErrorIcon className='text-mui-red-600' />, 'bg-mui-red-50');
case Execution.State.CANCELED:
return getStateIconWrapper(
<StopCircle colorClass={'text-mui-grey-600'} />,
'bg-mui-grey-200',
);
case Execution.State.COMPLETE:
return getStateIconWrapper(
<CheckCircleIcon className='text-mui-green-600 bla' />,
'bg-mui-green-50',
);
default:
console.error('Unknown exeuction state: ' + state);
return getStateIconWrapper(<RemoveCircleOutlineIcon className='text-white' />, 'bg-black');
}
}
function getStateIconWrapper(element: ReactElement, backgroundClasses: string) {
return (
<div
className={classes(
'px-2 h-full flex flex-col justify-center rounded-r-lg ',
backgroundClasses,
)}
>
{element}
</div>
);
}
// The following code can be used for `canceling state`
// return (
// <div className='px-2 h-full self-stretch flex flex-col justify-center rounded-r-lg bg-mui-lightblue-100'>
// <CircularProgress size={24} />
// {/* <SyncDisabledIcon className=' text-mui-organge-300' /> */}
// </div>
// );