diff --git a/graphql.schema.json b/graphql.schema.json index 4c5da1e..9de9fdf 100644 --- a/graphql.schema.json +++ b/graphql.schema.json @@ -416,196 +416,6 @@ "enumValues": null, "possibleTypes": null }, - { - "kind": "OBJECT", - "name": "LogFields", - "description": null, - "fields": [ - { - "name": "hash", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "date", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "refs", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "body", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "author_name", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "author_email", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "LogList", - "description": null, - "fields": [ - { - "name": "all", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "LogFields", - "ofType": null - } - } - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "total", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Float", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "latest", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "LogFields", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, { "kind": "OBJECT", "name": "PipelineTaskLogs", @@ -897,6 +707,220 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "OBJECT", + "name": "LogFields", + "description": null, + "fields": [ + { + "name": "hash", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "date", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "message", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "refs", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "body", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "author_name", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "author_email", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "tasks", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PipelineTask", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "LogList", + "description": null, + "fields": [ + { + "name": "all", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "LogFields", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "total", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Float", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "latest", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "LogFields", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, { "kind": "OBJECT", "name": "PipelineTaskLogMessage", @@ -945,6 +969,22 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "isError", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -952,6 +992,16 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "SCALAR", + "name": "Boolean", + "description": "The `Boolean` scalar type represents `true` or `false`.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, { "kind": "INPUT_OBJECT", "name": "WorkUnitInput", @@ -2005,6 +2055,39 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "pipelineTaskChanged", + "description": null, + "args": [ + { + "name": "id", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PipelineTask", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -2012,16 +2095,6 @@ "enumValues": null, "possibleTypes": null }, - { - "kind": "SCALAR", - "name": "Boolean", - "description": "The `Boolean` scalar type represents `true` or `false`.", - "fields": null, - "inputFields": null, - "interfaces": null, - "enumValues": null, - "possibleTypes": null - }, { "kind": "OBJECT", "name": "__Schema", diff --git a/src/components/commit-logs/commit-log-list.scss b/src/components/commit-logs/commit-log-list.scss index dd87ffb..350e925 100644 --- a/src/components/commit-logs/commit-log-list.scss +++ b/src/components/commit-logs/commit-log-list.scss @@ -5,16 +5,19 @@ @apply bg-gray-100 overflow-auto max-h-full; } .item { - @apply grid grid-cols-2 grid-rows-2; - @apply bg-white text-gray-700; - @apply py-2 px-4 my-px; - @apply hover:bg-gray-50; + header { + @apply relative; + @apply bg-white text-gray-700; + @apply py-2 px-4 my-px; + @apply hover:bg-gray-50; + } time { @apply col-start-1; @apply text-sm text-gray-400; } :global(.commit-actions) { - @apply col-start-2 row-start-1 row-span-2 justify-self-end self-center; + @apply absolute right-0 top-0 bottom-0; + @apply justify-self-end self-center; } } diff --git a/src/components/commit-logs/commit-log-list.tsx b/src/components/commit-logs/commit-log-list.tsx index bbf74c8..1c0c5d5 100644 --- a/src/components/commit-logs/commit-log-list.tsx +++ b/src/components/commit-logs/commit-log-list.tsx @@ -1,14 +1,11 @@ -import { - LogList, - Project, - ListLogsArgs, - Pipeline -} from '../../generated/graphql'; +import { LogList, Pipeline, LogFields } from '../../generated/graphql'; import { h } from 'preact'; import { gql, useQuery, useSubscription } from '@apollo/client'; import styles from './commit-log-list.scss'; import { CommitActions } from '../commit-actions/commit-actions'; import { FIND_PIPELINE } from '../pipelines/pipeline-list.constants'; +import { route } from 'preact-router'; +import { PipelineTaskStatus } from '../pipeline-tasks/pipeline-task-status'; const LIST_LOGS = gql` subscription listLogsForPipeline($id: String!) { @@ -18,6 +15,13 @@ const LIST_LOGS = gql` author_email message hash + tasks { + id + status + startedAt + endedAt + units + } } total } @@ -41,17 +45,34 @@ export const CommitLogList = ({ pipelineId }: Props) => { variables: { id: pipelineId } }); const pipeline = queryResult.data?.pipeline; - const list = data?.listLogs?.all?.map(log => { - return ( -
  • + const Item = ({ log }: { log: LogFields }) => ( +
  • +

    {log.message}

    {pipeline ? ( ) : null} -
  • - ); - }); + +
      + {log.tasks.map(task => ( +
    1. + route( + `/projects/${pipeline?.projectId}/pipelines/${pipeline?.id}/tasks/${task.id}` + ) + } + > + {task.startedAt} +
    2. + ))} +
    + + ); + const list = data?.listLogs?.all?.map(log => ( + + )); return (
    diff --git a/src/components/pipeline-tasks/pipeline-task-list.tsx b/src/components/pipeline-tasks/pipeline-task-list.tsx index bb726da..5d93d16 100644 --- a/src/components/pipeline-tasks/pipeline-task-list.tsx +++ b/src/components/pipeline-tasks/pipeline-task-list.tsx @@ -1,14 +1,8 @@ import { h } from 'preact'; import styles from './pipeline-tasks.scss'; import { gql, useQuery } from '@apollo/client'; -import { PipelineTask, TaskStatuses } from '../../generated/graphql'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { - faCheckCircle, - faClock, - faExclamationCircle, - faRunning -} from '@fortawesome/free-solid-svg-icons'; +import { PipelineTask } from '../../generated/graphql'; +import { PipelineTaskStatus } from './pipeline-task-status'; const LIST_TASKS = gql` query ListTasks($pipelineId: String!) { @@ -55,7 +49,7 @@ export const PipelineTaskList = ({ pipelineId }: Props) => { const Item = ({ task }: { task: PipelineTask }) => { return (
  • - + {task.id} {task.commit} {task.startedAt} @@ -68,23 +62,3 @@ const Item = ({ task }: { task: PipelineTask }) => {
  • ); }; - -const Status = ({ status }: { status: TaskStatuses }) => { - let icon; - switch (status) { - case TaskStatuses.Failed: - icon = faExclamationCircle; - break; - case TaskStatuses.Success: - icon = faCheckCircle; - break; - case TaskStatuses.Pending: - icon = faClock; - break; - case TaskStatuses.Working: - icon = faRunning; - break; - } - - return ; -}; diff --git a/src/components/pipeline-tasks/pipeline-task-status.tsx b/src/components/pipeline-tasks/pipeline-task-status.tsx new file mode 100644 index 0000000..b7e9292 --- /dev/null +++ b/src/components/pipeline-tasks/pipeline-task-status.tsx @@ -0,0 +1,45 @@ +import { h } from 'preact'; +import { TaskStatuses } from '../../generated/graphql'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { + faCheckCircle, + faExclamationCircle, + faPauseCircle, + faSpinner +} from '@fortawesome/free-solid-svg-icons'; +import classNames from 'classnames'; + +export const PipelineTaskStatus = ({ status }: { status: TaskStatuses }) => { + switch (status) { + case TaskStatuses.Working: + return ( + + ); + case TaskStatuses.Failed: + return ( + + ); + case TaskStatuses.Success: + return ( + + ); + case TaskStatuses.Pending: + return ( + + ); + default: + return null; + } +}; diff --git a/src/generated/graphql.tsx b/src/generated/graphql.tsx index f033041..6162217 100644 --- a/src/generated/graphql.tsx +++ b/src/generated/graphql.tsx @@ -60,24 +60,6 @@ export type Pipeline = { workUnitMetadata: WorkUnitMetadata; }; -export type LogFields = { - __typename?: 'LogFields'; - hash: Scalars['String']; - date: Scalars['String']; - message: Scalars['String']; - refs: Scalars['String']; - body: Scalars['String']; - author_name: Scalars['String']; - author_email: Scalars['String']; -}; - -export type LogList = { - __typename?: 'LogList'; - all: Array; - total: Scalars['Float']; - latest: LogFields; -}; - export type PipelineTaskLogs = { __typename?: 'PipelineTaskLogs'; unit: PipelineUnits; @@ -109,11 +91,31 @@ export type PipelineTask = { endedAt?: Maybe; }; +export type LogFields = { + __typename?: 'LogFields'; + hash: Scalars['String']; + date: Scalars['String']; + message: Scalars['String']; + refs: Scalars['String']; + body: Scalars['String']; + author_name: Scalars['String']; + author_email: Scalars['String']; + tasks: Array; +}; + +export type LogList = { + __typename?: 'LogList'; + all: Array; + total: Scalars['Float']; + latest: LogFields; +}; + export type PipelineTaskLogMessage = { __typename?: 'PipelineTaskLogMessage'; unit?: Maybe; time: Scalars['DateTime']; message: Scalars['String']; + isError: Scalars['Boolean']; }; export type WorkUnitInput = { @@ -250,6 +252,7 @@ export type Subscription = { __typename?: 'Subscription'; listLogsForPipeline: LogList; pipelineTaskLog: PipelineTaskLogMessage; + pipelineTaskChanged: PipelineTask; }; @@ -261,3 +264,8 @@ export type SubscriptionListLogsForPipelineArgs = { export type SubscriptionPipelineTaskLogArgs = { taskId: Scalars['String']; }; + + +export type SubscriptionPipelineTaskChangedArgs = { + id: Scalars['String']; +};