Skip to content

Commit

Permalink
Add pipeline tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
nathandf committed Aug 28, 2024
1 parent abb8809 commit 35c8967
Show file tree
Hide file tree
Showing 10 changed files with 451 additions and 91 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
pull_request:
branches: [dev, staging, test, release-**]
workflow_dispatch:

jobs:
Client_Side_Unit_Tests:
runs-on: ubuntu-20.04
Expand Down
101 changes: 15 additions & 86 deletions src/app/Workflows/Pipelines/Pipeline/Pipeline.tsx
Original file line number Diff line number Diff line change
@@ -1,80 +1,10 @@
import React, { useState, useCallback } from 'react';
import React from 'react';
import { Workflows } from '@tapis/tapis-typescript';
import { Workflows as Hooks } from '@tapis/tapisui-hooks';
import { SectionMessage, SectionHeader, Icon } from '@tapis/tapisui-common';
import { QueryWrapper } from '@tapis/tapisui-common';
import { Link } from 'react-router-dom';
import { Toolbar } from '../../_components';
import styles from './Pipeline.module.scss';
import { Button, ButtonGroup, Table } from 'reactstrap';
import { useQueryClient } from 'react-query';
import { DagView, Menu } from './_components';
import { useExtension } from 'extensions';
import { Alert } from '@mui/material';
import { ExpandMore } from '@mui/icons-material';

type TaskProps = {
task: Workflows.Task;
groupId: string;
pipelineId: string;
};

const Task: React.FC<TaskProps> = ({ task, groupId, pipelineId }) => {
const { removeAsync, isLoading, isError, error, isSuccess, reset } =
Hooks.Tasks.useDelete();

const queryClient = useQueryClient();
const onSuccess = useCallback(() => {
queryClient.invalidateQueries(Hooks.Tasks.queryKeys.list);
reset();
}, [queryClient, reset]);

return (
<div id={`task-${task.id}`} className={`${styles['container']}`}>
<div className={`${styles['task-header']}`}>
{task.id}
<Button
className={styles['remove-button']}
type="button"
color="danger"
onClick={() => {
removeAsync(
{ groupId, pipelineId, taskId: task.id ?? '' },
{ onSuccess }
);
}}
size="sm"
disabled={isLoading || isSuccess}
>
<QueryWrapper isLoading={isLoading} error={error}>
<Icon name="trash" />
</QueryWrapper>
</Button>
</div>
<div className={`${styles['task-body']}`}>
<p>
<b>type: </b>
{task.type}
</p>
<p>
<b>description: </b>
{task.description || <i>None</i>}
</p>
{isError && error && <Alert severity="error">{error.message}</Alert>}
</div>
{!!task?.depends_on?.length && (
<div>
<div className={`${styles['task-header']}`}>dependencies</div>
<div className={`${styles['task-body']}`}>
{task.depends_on.map((dependency) => {
return <p>{dependency.id}</p>;
})}
</div>
</div>
)}
</div>
);
};
import { DagView } from './_components';
import { EnvTab, ExecutionProfileTab } from './_components/Tabs';

type PipelineProps = {
groupId: string;
Expand All @@ -93,25 +23,24 @@ const Pipeline: React.FC<PipelineProps> = ({
error: pipelineError,
} = Hooks.Pipelines.useDetails({ groupId, pipelineId });

const {
data: tasksData,
isLoading: isLoadingTasks,
error: listTasksError,
} = Hooks.Tasks.useList({ groupId, pipelineId });
// const {
// data: tasksData,
// isLoading: isLoadingTasks,
// error: listTasksError,
// } = Hooks.Tasks.useList({ groupId, pipelineId });

const pipeline: Workflows.Pipeline = pipelineData?.result!;
const tasks: Array<Workflows.Task> = tasksData?.result! || [];
// const tasks: Array<Workflows.Task> = tasksData?.result! || [];

return (
<QueryWrapper
isLoading={isLoadingPipeline || isLoadingTasks}
error={pipelineError || listTasksError}
>
{pipeline && tasks && (
<QueryWrapper isLoading={isLoadingPipeline} error={pipelineError}>
{pipeline && (
<div id={`pipeline`} className={styles['grid']}>
{tab === 'tasks' && <DagView pipeline={pipeline} groupId={groupId} />}
{tab === 'execprofile' && <>Exec Profile</>}
{tab === 'env' && <>Env</>}
{tab === 'execprofile' && (
<ExecutionProfileTab pipeline={pipeline} groupId={groupId} />
)}
{tab === 'env' && <EnvTab pipeline={pipeline} groupId={groupId} />}
{tab === 'params' && <>Parameters</>}
{tab === 'uses' && <>Inheritance</>}
</div>
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
import React from 'react';
import { Workflows } from '@tapis/tapis-typescript';
import styles from './EnvTab.module.scss';
import {
FormControl,
InputLabel,
Select,
MenuItem,
TextField,
FormHelperText,
} from '@mui/material';
import { usePatchTask } from 'app/Workflows/_hooks';

type TabProps = {
groupId: string;
pipeline: Workflows.Pipeline;
};

const EnvTab: React.FC<TabProps> = ({ groupId, pipeline }) => {
return (
<div className={styles['form']}>
{JSON.stringify(pipeline.env)}
{/* <FormControl fullWidth margin="dense" style={{ marginBottom: '-16px' }}>
<InputLabel size="small" id="mode">
Task invocation mode
</InputLabel>
<Select
label="Task invocation mode"
labelId="mode"
size="small"
defaultValue={(taskPatch as any).execution_profile.invocation_mode}
onChange={(e) => {
setTaskPatch(
task,
{
execution_profile: {
...taskPatch.execution_profile,
invocation_mode: (e.target.value as Workflows.EnumInvocationMode)
}
}
)
}}
>
{Object.values(Workflows.EnumInvocationMode).map((mode) => {
return (
<MenuItem
selected={mode === (taskPatch as any).execution_profile.invocation_mode}
value={mode}
disabled={mode === Workflows.EnumInvocationMode.Sync}
>
{mode}{mode === Workflows.EnumInvocationMode.Sync ? " - unavailable" : ""}
</MenuItem>
);
})}
</Select>
</FormControl>
<FormHelperText>Excute tasks asynchronously or serially</FormHelperText>
<FormControl
fullWidth
margin="normal"
style={{ marginBottom: '-16px' }}
>
<InputLabel size="small" id="retrypolicy">
Retry policy
</InputLabel>
<Select
label="Retry Policy"
onChange={(e) => {
setTaskPatch(
task,
{
execution_profile: {
...taskPatch.execution_profile,
retry_policy: (e.target.value as Workflows.EnumRetryPolicy)
}
}
)
}}
labelId="retrypolicy"
size="small"
defaultValue={taskPatch.execution_profile?.retry_policy}
>
{Object.values(Workflows.EnumRetryPolicy).map((policy) => {
return (
<MenuItem
selected={policy === task.execution_profile?.retry_policy}
value={policy}
>
{policy}
</MenuItem>
);
})}
</Select>
</FormControl>
<FormHelperText>
Controls how soon to retry a task once it enters a failed state
</FormHelperText>
<FormControl
fullWidth
margin="normal"
style={{ marginBottom: '-16px' }}
>
<InputLabel size="small" id="flavor">
Flavor
</InputLabel>
<Select
label="Flavor"
labelId="flavor"
size="small"
defaultValue={taskPatch.execution_profile?.flavor}
onChange={(e) => {
setTaskPatch(
task,
{
execution_profile: {
...taskPatch.execution_profile,
flavor: (e.target.value as Workflows.EnumTaskFlavor)
}
}
)
}}
>
{Object.values(Workflows.EnumTaskFlavor).map((flavor) => {
return (
<MenuItem
selected={flavor === task.execution_profile?.flavor}
value={flavor}
>
{flavor}
</MenuItem>
);
})}
</Select>
</FormControl>
<FormHelperText>
How many cpus/gpus, and how much memory and disk available to this
task
</FormHelperText>
<TextField
defaultValue={taskPatch.execution_profile?.max_retries || 0}
size="small"
margin="normal"
style={{ marginBottom: '-16px' }}
label="Max retries"
variant="outlined"
type="number"
onChange={(e) => {
setTaskPatch(
task,
{
execution_profile: {
...taskPatch.execution_profile,
max_retries: parseInt(e.target.value)
}
}
)
}}
/>
<FormHelperText>
Maximum number of times this task will execute after failing once
</FormHelperText>
<TextField
defaultValue={taskPatch.execution_profile?.max_exec_time || 86400}
size="small"
margin="normal"
style={{ marginBottom: '-16px' }}
label="Max exec time (sec)"
variant="outlined"
type="number"
onChange={(e) => {
setTaskPatch(
task,
{
execution_profile: {
...taskPatch.execution_profile,
max_exec_time: parseInt(e.target.value)
}
}
)
}}
/>
<FormHelperText>
Max time in seconds this task is permitted to run
</FormHelperText> */}
</div>
);
};

export default EnvTab;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as EnvTab } from './EnvTab';
Loading

0 comments on commit 35c8967

Please sign in to comment.