import { gql, useQuery, useSubscription } from "@apollo/client"; import { LinearProgress, makeStyles, Typography } from "@material-ui/core"; import { format } from "date-fns"; import React, { FC, useState } from "react"; import { ErrorPage } from "../commons/fallbacks/error-page"; import { PipelineTask, PipelineTaskEvent, PipelineTaskLogs, TaskStatuses, } from "../generated/graphql"; import { PIPELINE_TASK_EVENT } from "./subscriptions"; import { clone, find, propEq } from "ramda"; import { PipelineUnits } from '../generated/graphql'; interface Props { taskId: string; } const PIPELINE_TASK = gql` query FindPipelineTask($taskId: String!) { pipelineTask(id: $taskId) { id units commit status startedAt endedAt logs { unit logs status startedAt endedAt } } } `; const useStyles = makeStyles((theme) => ({ root: {}, groupTitle: { backgroundColor: "white", fontWeight: 500, borderTop: "1px solid #eee", fontSize: "16px", padding: "12px", marginLeft: "1px", }, logText: { fontFamily: 'Menlo, Monaco, "Courier New", monospace', whiteSpace: "pre-wrap", border: "none", margin: "6px 12px", display: "block", }, })); export const PipelineTaskDetail: FC = ({ taskId }) => { const [taskEvents, setTaskEvents] = useState( () => new Array() ); const { data, loading, error, client } = useQuery<{ pipelineTask: PipelineTask; }>(PIPELINE_TASK, { variables: { taskId }, }); const task = data?.pipelineTask; useSubscription<{ pipelineTaskEvent: PipelineTaskEvent }>( PIPELINE_TASK_EVENT, { variables: { taskId }, onSubscriptionData({ subscriptionData: { data } }) { const event = data?.pipelineTaskEvent; console.log(event); if (event && task) { setTaskEvents((prev) => [...prev, event]); if (event.unit) { // event of running scripts client.cache.modify({ id: client.cache.identify(task!), fields: { logs(before: PipelineTaskLogs[]) { before = clone(before); let l = find(propEq("unit", event.unit), before); if (l) { l.logs += event.message; } else { l = { unit: event.unit!, logs: event.message, status: event.status, startedAt: event.emittedAt, endedAt: null, __typename: "PipelineTaskLogs", }; before.push(l); } if (event.status === TaskStatuses.Working) { l.startedAt || (l.startedAt = event.emittedAt); } if ( [TaskStatuses.Failed, TaskStatuses.Success].includes( event.status ) ) { l.startedAt && (l.startedAt = event.emittedAt); l.endedAt = event.emittedAt; } l.status = event.status; return before; }, }, }); } else { // event of task status change client.cache.modify({ id: client.cache.identify(task!), fields: { status() { return event.status; }, startedAt(before) { if (event.status === TaskStatuses.Working) { return event.emittedAt; } else { return before; } }, endedAt(before) { if ( [TaskStatuses.Success, TaskStatuses.Failed].includes( event.status ) ) { return event.emittedAt; } else { return before; } }, }, }); } } }, } ); const classes = useStyles(); if (error) { return {error.message}; } if (loading) { return ; } return (
{taskId} detail {task?.status} {task?.startedAt && format(task?.startedAt, "yyyy-MM-dd HH:mm:ss.SSS")}- {task?.endedAt && format(task?.endedAt, "yyyy-MM-dd HH:mm:ss.SSS")} {task?.logs.map((logs) => ( ))}
); }; const LogGroup: FC<{ logs: PipelineTaskLogs }> = ({ logs }) => { const classes = useStyles(); return (
{logs.unit}{" "} {logs.startedAt && format(logs.startedAt, "yyyy-MM-dd HH:mm:ss")}{" "} {logs.endedAt && format(logs.endedAt, "yyyy-MM-dd HH:mm:ss")} {logs.status}
{logs.logs}
); };