diff --git a/plugins/scaffolder/src/next/OngoingTask/OngoingTask.tsx b/plugins/scaffolder/src/next/OngoingTask/OngoingTask.tsx index feed582745..68e05f29e2 100644 --- a/plugins/scaffolder/src/next/OngoingTask/OngoingTask.tsx +++ b/plugins/scaffolder/src/next/OngoingTask/OngoingTask.tsx @@ -13,18 +13,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React, { useMemo } from 'react'; +import React, { useEffect, useMemo, useState, useCallback } from 'react'; import { Page, Header, Content } from '@backstage/core-components'; import { useTaskEventStream } from '../../components/hooks/useEventStream'; -import { useParams } from 'react-router-dom'; -import { Box, Paper } from '@material-ui/core'; +import { useNavigate, useParams } from 'react-router-dom'; +import { Box, Button, Paper } from '@material-ui/core'; import { TaskSteps } from './TaskSteps'; import { TaskBorder } from './TaskBorder'; import { TaskLogStream } from './TaskLogStream'; +import { nextSelectedTemplateRouteRef } from '../routes'; +import { useRouteRef } from '@backstage/core-plugin-api'; +import qs from 'qs'; export const OngoingTask = () => { + // todo(blam): check that task Id actually exists, and that it's valid. otherwise redirect to something more useful. const { taskId } = useParams(); - // check that task Id actually exists, and that it's valid. otherwise redirect to something more useful. + const templateRouteRef = useRouteRef(nextSelectedTemplateRouteRef); + const navigate = useNavigate(); const taskStream = useTaskEventStream(taskId!); const steps = useMemo( () => @@ -35,7 +40,15 @@ export const OngoingTask = () => { [taskStream], ); - const activeStep = React.useMemo(() => { + const [logsVisible, setLogsVisible] = useState(false); + + useEffect(() => { + if (taskStream.error) { + setLogsVisible(true); + } + }, [taskStream.error]); + + const activeStep = useMemo(() => { for (let i = steps.length - 1; i >= 0; i--) { if (steps[i].status !== 'open') { return i; @@ -45,6 +58,30 @@ export const OngoingTask = () => { return 0; }, [steps]); + const startOver = useCallback(() => { + const { namespace, name } = + taskStream.task?.spec.templateInfo?.entity?.metadata ?? {}; + + const formData = taskStream.task?.spec.parameters ?? {}; + + if (!namespace || !name) { + return; + } + + navigate({ + pathname: templateRouteRef({ + namespace, + templateName: name, + }), + search: `?${qs.stringify({ formData: JSON.stringify(formData) })}`, + }); + }, [ + navigate, + taskStream.task?.spec.parameters, + taskStream.task?.spec.templateInfo?.entity?.metadata, + templateRouteRef, + ]); + const templateName = taskStream.task?.spec.templateInfo?.entity?.metadata.name; @@ -60,16 +97,49 @@ export const OngoingTask = () => { subtitle={`Task ${taskId}`} /> - - - - - + + + + + + + + + + + + + + + + + + + {logsVisible ? ( + + + + + + - + ) : null} ); diff --git a/plugins/scaffolder/src/next/OngoingTask/TaskLogStream.tsx b/plugins/scaffolder/src/next/OngoingTask/TaskLogStream.tsx index d587f47f17..65c0022e1d 100644 --- a/plugins/scaffolder/src/next/OngoingTask/TaskLogStream.tsx +++ b/plugins/scaffolder/src/next/OngoingTask/TaskLogStream.tsx @@ -20,7 +20,7 @@ import { makeStyles } from '@material-ui/core/styles'; const useStyles = makeStyles({ root: { width: '100%', - height: '200px', + height: '100%', position: 'relative', }, }); @@ -32,10 +32,8 @@ export const TaskLogStream = (opts: { logs: { [k: string]: string[] } }) => { l.join('\n')) .filter(Boolean) - .join('\n')} /> diff --git a/plugins/scaffolder/src/next/OngoingTask/TaskSteps/StepIcon.tsx b/plugins/scaffolder/src/next/OngoingTask/TaskSteps/StepIcon.tsx index 39ef37c771..cecf682596 100644 --- a/plugins/scaffolder/src/next/OngoingTask/TaskSteps/StepIcon.tsx +++ b/plugins/scaffolder/src/next/OngoingTask/TaskSteps/StepIcon.tsx @@ -18,10 +18,10 @@ import React from 'react'; import { BackstageTheme } from '@backstage/theme'; import { CircularProgress, makeStyles, StepIconProps } from '@material-ui/core'; import RemoveCircleOutline from '@material-ui/icons/RemoveCircleOutline'; -import FiberManualRecordIcon from '@material-ui/icons/FiberManualRecord'; +import PanoramaFishEyeIcon from '@material-ui/icons/PanoramaFishEye'; import classNames from 'classnames'; import CheckCircleOutline from '@material-ui/icons/CheckCircleOutline'; -import DeleteOutline from '@material-ui/icons/DeleteOutline'; +import ErrorOutline from '@material-ui/icons/ErrorOutline'; const useStepIconStyles = makeStyles((theme: BackstageTheme) => ({ root: { @@ -48,14 +48,14 @@ export const StepIcon = (props: StepIconProps & { skipped: boolean }) => { } if (error) { - return ; + return ; } if (skipped) { return ; } - return ; + return ; }; return (