chore: refactor and tidy up the UI slightly
Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
@@ -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}`}
|
||||
/>
|
||||
<Content>
|
||||
<Paper style={{ position: 'relative', overflow: 'hidden' }}>
|
||||
<TaskBorder
|
||||
isComplete={taskStream.completed}
|
||||
isError={Boolean(taskStream.error)}
|
||||
/>
|
||||
<Box padding={2}>
|
||||
<TaskSteps steps={steps} activeStep={activeStep} />
|
||||
<TaskLogStream logs={taskStream.stepLogs} />
|
||||
<Box paddingBottom={2}>
|
||||
<Paper style={{ position: 'relative', overflow: 'hidden' }}>
|
||||
<TaskBorder
|
||||
isComplete={taskStream.completed}
|
||||
isError={Boolean(taskStream.error)}
|
||||
/>
|
||||
<Box padding={2}>
|
||||
<TaskSteps steps={steps} activeStep={activeStep} />
|
||||
</Box>
|
||||
</Paper>
|
||||
</Box>
|
||||
|
||||
<Box paddingBottom={2}>
|
||||
<Paper>
|
||||
<Box
|
||||
padding={2}
|
||||
justifyContent="flex-end"
|
||||
display="flex"
|
||||
gridGap={16}
|
||||
>
|
||||
<Button variant="contained" color="primary" onClick={startOver}>
|
||||
Start over
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => setLogsVisible(!logsVisible)}
|
||||
>
|
||||
{logsVisible ? 'Hide logs' : 'Show logs'}
|
||||
</Button>
|
||||
</Box>
|
||||
</Paper>
|
||||
</Box>
|
||||
|
||||
{logsVisible ? (
|
||||
<Box paddingBottom={2} height="100%">
|
||||
<Paper style={{ height: '100%' }}>
|
||||
<Box padding={2} height="100%">
|
||||
<TaskLogStream logs={taskStream.stepLogs} />
|
||||
</Box>
|
||||
</Paper>
|
||||
</Box>
|
||||
</Paper>
|
||||
) : null}
|
||||
</Content>
|
||||
</Page>
|
||||
);
|
||||
|
||||
@@ -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[] } }) => {
|
||||
<LogViewer
|
||||
tail
|
||||
text={Object.values(opts.logs)
|
||||
|
||||
.map(l => l.join('\n'))
|
||||
.filter(Boolean)
|
||||
|
||||
.join('\n')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -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 <DeleteOutline />;
|
||||
return <ErrorOutline />;
|
||||
}
|
||||
|
||||
if (skipped) {
|
||||
return <RemoveCircleOutline />;
|
||||
}
|
||||
|
||||
return <FiberManualRecordIcon />;
|
||||
return <PanoramaFishEyeIcon />;
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user