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 (