diff --git a/plugins/scaffolder/src/components/TaskPage/TaskPage.tsx b/plugins/scaffolder/src/components/TaskPage/TaskPage.tsx
index 2f22cb9849..820e65d126 100644
--- a/plugins/scaffolder/src/components/TaskPage/TaskPage.tsx
+++ b/plugins/scaffolder/src/components/TaskPage/TaskPage.tsx
@@ -15,7 +15,7 @@
*/
import { Page, Header, Lifecycle, Content } from '@backstage/core';
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect, memo } from 'react';
import {
makeStyles,
Theme,
@@ -34,7 +34,11 @@ import Check from '@material-ui/icons/Check';
import Cancel from '@material-ui/icons/Cancel';
import Typography from '@material-ui/core/Typography';
import { useParams } from 'react-router';
-import { useTaskEventStream, TaskStream } from '../hooks/useEventStream';
+import {
+ useTaskEventStream,
+ TaskStream,
+ Status,
+} from '../hooks/useEventStream';
import LazyLog from 'react-lazylog/build/LazyLog';
import { StepButton, StepIconProps } from '@material-ui/core';
@@ -130,36 +134,29 @@ const useStyles = makeStyles((theme: Theme) =>
}),
);
-export const TaskStepper = ({ taskStream }: { taskStream: TaskStream }) => {
+type Steps = {
+ log: string[];
+ id: string;
+ name: string;
+ status: Status;
+};
+
+export const TaskStepper = ({ steps }: { steps: Steps[] }) => {
const classes = useStyles();
const [activeStep, setActiveStep] = useState(0);
const [expandAll, setExpandAll] = useState(false);
- const steps = taskStream?.task?.spec.steps ?? [];
-
- const handleNext = () => {
- setActiveStep(prevActiveStep => prevActiveStep + 1);
- };
-
- const handleBack = () => {
- setActiveStep(prevActiveStep => prevActiveStep - 1);
- };
-
const handleStep = (step: number) => {
setExpandAll(false);
setActiveStep(step);
};
- const handleReset = () => {
- setActiveStep(0);
- };
-
useEffect(() => {
- const activeIndex = Object.values(taskStream?.steps ?? {}).findIndex(step =>
+ const activeIndex = steps.findIndex(step =>
['failed', 'processing'].includes(step.status),
);
- setActiveStep(activeIndex);
- }, [taskStream]);
+ setActiveStep(2);
+ }, [steps]);
return (
@@ -170,12 +167,24 @@ export const TaskStepper = ({ taskStream }: { taskStream: TaskStream }) => {
{steps.map((step, index) => {
- const isCompleted =
- taskStream.steps?.[step.id].status === 'completed';
- const isFailed = taskStream.steps?.[step.id].status === 'failed';
+ const isCompleted = step.status === 'completed';
+ const isFailed = step.status === 'failed';
+ // return (
+ //
+ // );
+
return (
-
- handleStep(index)}>
+
+ {}}>
{
@@ -200,21 +205,62 @@ export const TaskStepper = ({ taskStream }: { taskStream: TaskStream }) => {
);
})}
- {activeStep === steps.length && (
-
- All steps completed - you're finished
-
-
- )}
);
};
+type TaskStepOptions = {
+ name: string;
+ isCompleted: boolean;
+ isFailed: boolean;
+ expanded: boolean;
+ handleStep: () => void;
+ index: number;
+ log: string;
+};
+
+export const TaskStep = memo(
+ ({
+ log,
+ name,
+ isCompleted,
+ isFailed,
+ handleStep,
+ index,
+ expanded,
+ }: TaskStepOptions) => {
+ const onClick = React.useCallback(() => handleStep(index), [
+ handleStep,
+ index,
+ ]);
+ return (
+
+
+
+ {name}
+
+
+
+
+
+
+
+
+
+ );
+ },
+);
export const TaskPage = () => {
const { taskId } = useParams();
const taskStream = useTaskEventStream(taskId);
+ const steps =
+ taskStream.task?.spec.steps.map(step => ({
+ ...step,
+ ...taskStream?.steps?.[step.id],
+ })) ?? [];
return (
@@ -228,7 +274,7 @@ export const TaskPage = () => {
subtitle={`Activity for task: ${taskId}`}
/>
-
+
);
diff --git a/plugins/scaffolder/src/components/hooks/useEventStream.ts b/plugins/scaffolder/src/components/hooks/useEventStream.ts
index 2cbf8b4f83..20338463c3 100644
--- a/plugins/scaffolder/src/components/hooks/useEventStream.ts
+++ b/plugins/scaffolder/src/components/hooks/useEventStream.ts
@@ -14,16 +14,16 @@
* limitations under the License.
*/
import { useImmerReducer } from 'use-immer';
-import { useEffect } from 'react';
+import { useEffect, useState } from 'react';
import { scaffolderApiRef } from '../../api';
import { ScaffolderTask } from '../../types';
+import { useDebounce } from 'react-use';
import { Subscription, useApi } from '@backstage/core';
-type Status = 'open' | 'processing' | 'failed' | 'completed';
+export type Status = 'open' | 'processing' | 'failed' | 'completed';
type Step = {
id: string;
status: Status;
- log: string[];
endedAt?: string;
startedAt?: string;
};
@@ -34,7 +34,7 @@ export type TaskStream = {
log: string[];
completed: boolean;
task?: ScaffolderTask;
- steps?: { [stepId in string]: Step };
+ steps: { [stepId in string]: Step };
};
type ReducerAction =
@@ -56,7 +56,7 @@ function reducer(draft: TaskStream, action: ReducerAction) {
switch (action.type) {
case 'INIT': {
draft.steps = action.data.spec.steps.reduce((current, next) => {
- current[next.id] = { log: [], status: 'open', id: next.id };
+ current[next.id] = { status: 'open', id: next.id };
return current;
}, {} as { [stepId in string]: Step });
draft.loading = false;
@@ -72,12 +72,7 @@ function reducer(draft: TaskStream, action: ReducerAction) {
const currentStep = draft.steps?.[stepId];
const logLine = `${action.data.createdAt} ${action.data.body.message}`;
- if (!currentStep) {
- draft.log.push(logLine);
- return;
- }
-
- currentStep.log.push(logLine);
+ draft.log.push(logLine);
if (
action.data.body.status &&
@@ -89,9 +84,7 @@ function reducer(draft: TaskStream, action: ReducerAction) {
currentStep.startedAt = action.data.createdAt;
}
- if (
- ['zcancelled', 'failed', 'completed'].includes(currentStep.status)
- ) {
+ if (['cancelled', 'failed', 'completed'].includes(currentStep.status)) {
currentStep.endedAt = action.data.createdAt;
}
}
@@ -124,7 +117,14 @@ export const useTaskEventStream = (taskId: string): TaskStream => {
log: [],
steps: {} as { [stepId in string]: Step },
});
-
+ // const [debouncedState, setDebouncedState] = useState(state);
+ // useDebounce(
+ // () => {
+ // setDebouncedState(state);
+ // },
+ // 1000,
+ // [state],
+ // );
useEffect(() => {
let didCancel = false;
let subscription: Subscription | undefined;
@@ -167,4 +167,5 @@ export const useTaskEventStream = (taskId: string): TaskStream => {
}, [scaffolderApi, dispatch, taskId]);
return state;
+ // return debouncedState;
};