From c48dab83ea3c63738422b17d2fec2868be72e0a4 Mon Sep 17 00:00:00 2001 From: Dan Wilson Date: Fri, 1 Sep 2023 16:34:21 +0100 Subject: [PATCH 1/4] update pipeline list to match designs --- web/src/App.tsx | 2 +- web/src/framework/strings/stringTypes.ts | 2 + web/src/i18n/strings.en.yaml | 2 + .../ExecutionList/ExecutionList.module.scss | 4 +- web/src/pages/ExecutionList/ExecutionList.tsx | 38 +++---- .../PipelineList/PipelineList.module.scss | 104 +++++++++--------- .../PipelineList.module.scss.d.ts | 9 +- web/src/pages/PipelineList/PipelineList.tsx | 96 ++++++++++++---- web/src/services/code/index.tsx | 6 +- web/src/services/code/swagger.yaml | 12 +- 10 files changed, 172 insertions(+), 103 deletions(-) diff --git a/web/src/App.tsx b/web/src/App.tsx index 4aae0d320..fd4c98585 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -75,7 +75,7 @@ const App: React.FC = React.memo(function App({ }}> diff --git a/web/src/framework/strings/stringTypes.ts b/web/src/framework/strings/stringTypes.ts index b8dd3c197..92cc58077 100644 --- a/web/src/framework/strings/stringTypes.ts +++ b/web/src/framework/strings/stringTypes.ts @@ -314,9 +314,11 @@ export interface StringsMap { payloadUrl: string payloadUrlLabel: string pending: string + 'pipelines.lastExecution': string 'pipelines.name': string 'pipelines.newPipelineButton': string 'pipelines.noData': string + 'pipelines.time': string 'pr.ableToMerge': string 'pr.addDescription': string 'pr.authorCommentedPR': string diff --git a/web/src/i18n/strings.en.yaml b/web/src/i18n/strings.en.yaml index 54a4e7191..9114b1208 100644 --- a/web/src/i18n/strings.en.yaml +++ b/web/src/i18n/strings.en.yaml @@ -624,6 +624,8 @@ pipelines: noData: There are no pipelines :( newPipelineButton: New Pipeline name: Pipeline Name + time: Time + lastExecution: Last Execution executions: noData: There are no executions :( newExecutionButton: Run Pipeline diff --git a/web/src/pages/ExecutionList/ExecutionList.module.scss b/web/src/pages/ExecutionList/ExecutionList.module.scss index 678e0a41b..9fed84abe 100644 --- a/web/src/pages/ExecutionList/ExecutionList.module.scss +++ b/web/src/pages/ExecutionList/ExecutionList.module.scss @@ -80,8 +80,8 @@ .hash { color: var(--primary-7) !important; font-family: Roboto Mono !important; - font-size: 0.75rem; - font-weight: 500; + font-size: 0.75rem !important; + font-weight: 500 !important; } .triggerLayout { diff --git a/web/src/pages/ExecutionList/ExecutionList.tsx b/web/src/pages/ExecutionList/ExecutionList.tsx index 04c9033e7..3d1160ca0 100644 --- a/web/src/pages/ExecutionList/ExecutionList.tsx +++ b/web/src/pages/ExecutionList/ExecutionList.tsx @@ -71,26 +71,24 @@ const ExecutionList = () => { Cell: ({ row }: CellProps) => { const record = row.original return ( - - - - {/* TODO this icon need to depend on the status */} - - {`#${record.number}.`} - {record.title} - - - - {/* TODO need logic here for different trigger types */} - {`${record.author_name} triggered manually`} - {`|`} - {/* TODO Will need to replace this with commit action - wont match Yifan designs */} - - {record.after} - - - - + + + {/* TODO this icon need to depend on the status */} + + {`#${record.number}.`} + {record.title} + + + + {/* TODO need logic here for different trigger types */} + {`${record.author_name} triggered manually`} + {`|`} + {/* TODO Will need to replace this with commit component - wont match Yifan designs */} + + {record.after} + + + ) } }, diff --git a/web/src/pages/PipelineList/PipelineList.module.scss b/web/src/pages/PipelineList/PipelineList.module.scss index dfdc0aec4..7ba58fc8a 100644 --- a/web/src/pages/PipelineList/PipelineList.module.scss +++ b/web/src/pages/PipelineList/PipelineList.module.scss @@ -31,56 +31,56 @@ } .nameContainer { - position: relative; - - .name { - flex-grow: 1; - align-items: baseline !important; - width: calc(100% - 100px) !important; - - > span { - width: 100%; - > span { - width: 100%; - } - } - - & + span:last-of-type { - align-self: center; - } - } - - .pinned { - transform: rotate(-90deg); - position: absolute; - top: 7px; - left: -43px; - font-size: var(--font-size-xsmall) !important; - padding: 6px 14px; - } - - .repoName { - font-weight: 600 !important; - font-size: 16px !important; - line-height: 24px !important; - color: var(--grey-800); - - .repoScope { - color: var(--grey-400); - padding: 2px 6px; - font-size: var(--font-size-xsmall) !important; - border-radius: 4px; - border: 1px solid var(--grey-200); - display: inline-block; - margin-left: var(--spacing-medium); - text-transform: uppercase; - line-height: 16px; - } - } - - .desc { - color: var(--grey-500); - font-size: var(--font-size-small); - padding-top: var(--spacing-xsmall) !important; - } + display: flex; + align-items: center; + height: 3rem !important; +} + +.repoName { + font-weight: 600 !important; + font-size: 0.875rem !important; + color: var(--grey-700) !important; +} + +.nameContainer { + // display: flex; + // align-items: center; + // height: 3rem !important; +} + +.desc { + color: var(--grey-700) !important; + font-size: 0.75rem !important; + font-style: normal !important; + font-weight: 600 !important; +} + +.avatar { + margin: 0 0 0 -3px !important; +} + +.author { + color: var(--grey500) !important; + font-size: 0.75rem !important; + font-weight: 500 !important; +} + +.hash { + color: var(--primary-7) !important; + font-family: Roboto Mono !important; + font-size: 0.75rem !important; + font-weight: 500 !important; +} + +.triggerLayout { + align-items: center !important; +} + +.spacer { + width: 180px; +} + +.divider { + color: var(--grey-300) !important; + font-size: 0.5rem !important; } diff --git a/web/src/pages/PipelineList/PipelineList.module.scss.d.ts b/web/src/pages/PipelineList/PipelineList.module.scss.d.ts index c83440288..ee305031a 100644 --- a/web/src/pages/PipelineList/PipelineList.module.scss.d.ts +++ b/web/src/pages/PipelineList/PipelineList.module.scss.d.ts @@ -8,10 +8,13 @@ declare const styles: { readonly row: string readonly noDesc: string readonly nameContainer: string - readonly name: string - readonly pinned: string readonly repoName: string - readonly repoScope: string readonly desc: string + readonly avatar: string + readonly author: string + readonly hash: string + readonly triggerLayout: string + readonly spacer: string + readonly divider: string } export default styles diff --git a/web/src/pages/PipelineList/PipelineList.tsx b/web/src/pages/PipelineList/PipelineList.tsx index 4fb8383d1..b5866bc1f 100644 --- a/web/src/pages/PipelineList/PipelineList.tsx +++ b/web/src/pages/PipelineList/PipelineList.tsx @@ -1,5 +1,6 @@ import React, { useMemo, useState } from 'react' import { + Avatar, Button, ButtonVariation, Container, @@ -7,7 +8,8 @@ import { Layout, PageBody, TableV2 as Table, - Text + Text, + Utils } from '@harnessio/uicore' import { Color } from '@harnessio/design-system' import cx from 'classnames' @@ -15,11 +17,13 @@ import type { CellProps, Column } from 'react-table' import Keywords from 'react-keywords' import { useHistory } from 'react-router-dom' import { useGet } from 'restful-react' +import { Icon } from '@harnessio/icons' +import { Calendar, Timer, GitFork } from 'iconoir-react' import { useStrings } from 'framework/strings' import { LoadingSpinner } from 'components/LoadingSpinner/LoadingSpinner' import { SearchInputWithSpinner } from 'components/SearchInputWithSpinner/SearchInputWithSpinner' import { NoResultCard } from 'components/NoResultCard/NoResultCard' -import { LIST_FETCHING_LIMIT, PageBrowserProps, formatDate, getErrorMessage, voidFn } from 'utils/Utils' +import { LIST_FETCHING_LIMIT, PageBrowserProps, getErrorMessage, timeDistance, voidFn } from 'utils/Utils' import type { TypesPipeline } from 'services/code' import { useQueryParams } from 'hooks/useQueryParams' import { usePageIndex } from 'hooks/usePageIndex' @@ -48,7 +52,7 @@ const PipelineList = () => { response } = useGet({ path: `/api/v1/repos/${repoMetadata?.path}/+/pipelines`, - queryParams: { page, limit: LIST_FETCHING_LIMIT, query: searchTerm }, + queryParams: { page, limit: LIST_FETCHING_LIMIT, query: searchTerm, latest: true }, lazy: !repoMetadata }) @@ -66,33 +70,83 @@ const PipelineList = () => { () => [ { Header: getString('pipelines.name'), - width: 'calc(100% - 180px)', + width: 'calc(50% - 90px)', Cell: ({ row }: CellProps) => { const record = row.original return ( - - - - - {record.uid} - - {record.description && {record.description}} - - - + + {/* TODO this icon need to depend on the status */} + + + {record.uid} + + ) } }, { - Header: getString('repos.updated'), + Header: getString('pipelines.lastExecution'), + width: 'calc(50% - 90px)', + Cell: ({ row }: CellProps) => { + const record = row.original.execution + + return record ? ( + + + {/* TODO this icon need to depend on the status */} + {`#${record.number}`} + {`|`} + {record.title} + + + + {/* TODO need logic here for different trigger types */} + {record.author_name} + {`|`} + + {record.source} + {`|`} + {/* TODO Will need to replace this with commit component - wont match Yifan designs */} + + {/* {record.after} */} + hardcoded + + + + ) : ( +
+ ) + } + }, + { + Header: getString('pipelines.time'), width: '180px', Cell: ({ row }: CellProps) => { - return ( - - - {formatDate(row.original.updated as number)} - - + const record = row.original.execution + + return record ? ( + + + + + {timeDistance(record.started, record.finished)} + + + + + + {timeDistance(record.finished, Date.now())} ago + + + + ) : ( +
) }, disableSortBy: true diff --git a/web/src/services/code/index.tsx b/web/src/services/code/index.tsx index 95a3c0ebf..103744780 100644 --- a/web/src/services/code/index.tsx +++ b/web/src/services/code/index.tsx @@ -634,12 +634,12 @@ export interface TypesPipeline { created?: number default_branch?: string description?: string + execution?: TypesExecution id?: number repo_id?: number seq?: number uid?: string updated?: number - version?: number } export interface TypesPlugin { @@ -2239,6 +2239,10 @@ export interface ListPipelinesQueryParams { * The maximum number of results to return. */ limit?: number + /** + * Whether to fetch latest build information for each pipeline. + */ + latest?: boolean } export interface ListPipelinesPathParams { diff --git a/web/src/services/code/swagger.yaml b/web/src/services/code/swagger.yaml index f4d555cb1..a60374f0c 100644 --- a/web/src/services/code/swagger.yaml +++ b/web/src/services/code/swagger.yaml @@ -1971,6 +1971,12 @@ paths: maximum: 100 minimum: 1 type: integer + - description: Whether to fetch latest build information for each pipeline. + in: query + name: latest + required: false + schema: + type: boolean - in: path name: repo_ref required: true @@ -2010,7 +2016,7 @@ paths: $ref: '#/components/schemas/UsererrorError' description: Internal Server Error tags: - - repos + - pipeline post: operationId: createPipeline parameters: @@ -7231,6 +7237,8 @@ components: type: string description: type: string + execution: + $ref: '#/components/schemas/TypesExecution' id: type: integer repo_id: @@ -7241,8 +7249,6 @@ components: type: string updated: type: integer - version: - type: integer type: object TypesPlugin: properties: From 627a3ae55d2e51ce4f174ec40677e2930fe2e13f Mon Sep 17 00:00:00 2001 From: Dan Wilson Date: Fri, 1 Sep 2023 17:55:26 +0100 Subject: [PATCH 2/4] update pipeline list to match designs --- web/src/App.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/App.tsx b/web/src/App.tsx index fd4c98585..4aae0d320 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -75,7 +75,7 @@ const App: React.FC = React.memo(function App({ }}> From f7969d3bf5fac3f809dd19f057c3ca7f789ee480 Mon Sep 17 00:00:00 2001 From: Dan Wilson Date: Mon, 4 Sep 2023 13:48:43 +0100 Subject: [PATCH 3/4] use shared status icon component and remove rem usage --- .../components/Console/Console.module.scss | 1 - .../ConsoleLogs/ConsoleLogs.module.scss | 8 ++-- .../ConsoleStep/ConsoleStep.module.scss | 3 +- .../ExecutionStageList.module.scss | 8 +++- .../ExecutionStageList.module.scss.d.ts | 1 + .../ExecutionStageList/ExecutionStageList.tsx | 11 ++++- .../ExecutionStatus.module.scss} | 0 .../ExecutionStatus.module.scss.d.ts} | 0 .../ExecutionStatus.tsx} | 20 ++++----- web/src/hooks/usePRChecksDecision.tsx | 24 +++++----- .../ExecutionList/ExecutionList.module.scss | 29 +++--------- .../ExecutionList.module.scss.d.ts | 3 -- web/src/pages/ExecutionList/ExecutionList.tsx | 13 +++--- .../PipelineList/PipelineList.module.scss | 44 +++++-------------- .../PipelineList.module.scss.d.ts | 4 +- web/src/pages/PipelineList/PipelineList.tsx | 19 +++++--- web/src/pages/PullRequest/Checks/Checks.tsx | 22 +++++----- .../PullRequest/Checks/ChecksOverview.tsx | 6 +-- web/src/pages/PullRequest/PullRequest.tsx | 4 +- web/src/utils/PipelineUtils.ts | 16 +++++++ 20 files changed, 112 insertions(+), 124 deletions(-) rename web/src/components/{PRCheckExecutionStatus/PRCheckExecutionStatus.module.scss => ExecutionStatus/ExecutionStatus.module.scss} (100%) rename web/src/components/{PRCheckExecutionStatus/PRCheckExecutionStatus.module.scss.d.ts => ExecutionStatus/ExecutionStatus.module.scss.d.ts} (100%) rename web/src/components/{PRCheckExecutionStatus/PRCheckExecutionStatus.tsx => ExecutionStatus/ExecutionStatus.tsx} (77%) create mode 100644 web/src/utils/PipelineUtils.ts diff --git a/web/src/components/Console/Console.module.scss b/web/src/components/Console/Console.module.scss index b7df1b8b6..6b2f0e1cd 100644 --- a/web/src/components/Console/Console.module.scss +++ b/web/src/components/Console/Console.module.scss @@ -9,7 +9,6 @@ .log { color: white; font-family: Inconsolata, monospace; - font-size: 2rem; } .header { diff --git a/web/src/components/ConsoleLogs/ConsoleLogs.module.scss b/web/src/components/ConsoleLogs/ConsoleLogs.module.scss index f5aa335fa..2c19a31c4 100644 --- a/web/src/components/ConsoleLogs/ConsoleLogs.module.scss +++ b/web/src/components/ConsoleLogs/ConsoleLogs.module.scss @@ -1,16 +1,16 @@ .logLayout { - margin-left: 2.3rem !important; + margin-left: var(--spacing-xxxlarge) !important; } .lineNumber { - width: 1.5rem; + width: var(--spacing-xlarge); color: #999; - margin-right: 1rem; + margin-right: 16px; font-family: 'Roboto Mono' !important; } .log { color: white !important; - margin-bottom: 1rem; + margin-bottom: var(--spacing-medium); font-family: 'Roboto Mono' !important; } diff --git a/web/src/components/ConsoleStep/ConsoleStep.module.scss b/web/src/components/ConsoleStep/ConsoleStep.module.scss index 966563a30..56f5deaae 100644 --- a/web/src/components/ConsoleStep/ConsoleStep.module.scss +++ b/web/src/components/ConsoleStep/ConsoleStep.module.scss @@ -5,6 +5,5 @@ } .loading { - margin-left: 2.3rem !important; - margin-top: 1.5rem !important; + margin-left: var(--spacing-xxxlarge) !important; } diff --git a/web/src/components/ExecutionStageList/ExecutionStageList.module.scss b/web/src/components/ExecutionStageList/ExecutionStageList.module.scss index 097a1d1cc..3afdb541a 100644 --- a/web/src/components/ExecutionStageList/ExecutionStageList.module.scss +++ b/web/src/components/ExecutionStageList/ExecutionStageList.module.scss @@ -11,7 +11,7 @@ height: 100%; .menuItem { - margin: 0.5rem 0 0.5rem 1rem !important; + margin: var(--spacing-small) 0 var(--spacing-small) var(--spacing-medium) !important; cursor: pointer; &:not(:last-child) { @@ -35,8 +35,12 @@ .uid { color: var(--grey-700) !important; font-weight: 600 !important; - font-size: 1rem !important; + font-size: var(--font-size-normal) !important; } } } } + +.statusIcon { + align-self: center !important; +} diff --git a/web/src/components/ExecutionStageList/ExecutionStageList.module.scss.d.ts b/web/src/components/ExecutionStageList/ExecutionStageList.module.scss.d.ts index 0980665f8..4e9a9861f 100644 --- a/web/src/components/ExecutionStageList/ExecutionStageList.module.scss.d.ts +++ b/web/src/components/ExecutionStageList/ExecutionStageList.module.scss.d.ts @@ -7,5 +7,6 @@ declare const styles: { readonly layout: string readonly selected: string readonly uid: string + readonly statusIcon: string } export default styles diff --git a/web/src/components/ExecutionStageList/ExecutionStageList.tsx b/web/src/components/ExecutionStageList/ExecutionStageList.tsx index e2c44a2c8..399be3cf6 100644 --- a/web/src/components/ExecutionStageList/ExecutionStageList.tsx +++ b/web/src/components/ExecutionStageList/ExecutionStageList.tsx @@ -1,8 +1,9 @@ import React, { FC } from 'react' import { Container, Layout, Text } from '@harnessio/uicore' -import { Icon } from '@harnessio/icons' import cx from 'classnames' import type { TypesStage } from 'services/code' +import { ExecutionState, ExecutionStatus } from 'components/ExecutionStatus/ExecutionStatus' +import { getStatus } from 'utils/PipelineUtils' import css from './ExecutionStageList.module.scss' interface ExecutionStageListProps { @@ -26,7 +27,13 @@ const ExecutionStage: FC = ({ stage, isSelected = false, se setSelectedStage(stage.number || null) }}> - + {stage.name} diff --git a/web/src/components/PRCheckExecutionStatus/PRCheckExecutionStatus.module.scss b/web/src/components/ExecutionStatus/ExecutionStatus.module.scss similarity index 100% rename from web/src/components/PRCheckExecutionStatus/PRCheckExecutionStatus.module.scss rename to web/src/components/ExecutionStatus/ExecutionStatus.module.scss diff --git a/web/src/components/PRCheckExecutionStatus/PRCheckExecutionStatus.module.scss.d.ts b/web/src/components/ExecutionStatus/ExecutionStatus.module.scss.d.ts similarity index 100% rename from web/src/components/PRCheckExecutionStatus/PRCheckExecutionStatus.module.scss.d.ts rename to web/src/components/ExecutionStatus/ExecutionStatus.module.scss.d.ts diff --git a/web/src/components/PRCheckExecutionStatus/PRCheckExecutionStatus.tsx b/web/src/components/ExecutionStatus/ExecutionStatus.tsx similarity index 77% rename from web/src/components/PRCheckExecutionStatus/PRCheckExecutionStatus.tsx rename to web/src/components/ExecutionStatus/ExecutionStatus.tsx index 2fd183463..40f1c3128 100644 --- a/web/src/components/PRCheckExecutionStatus/PRCheckExecutionStatus.tsx +++ b/web/src/components/ExecutionStatus/ExecutionStatus.tsx @@ -3,9 +3,9 @@ import { Text } from '@harnessio/uicore' import type { IconName } from '@harnessio/icons' import cx from 'classnames' import { useStrings } from 'framework/strings' -import css from './PRCheckExecutionStatus.module.scss' +import css from './ExecutionStatus.module.scss' -export enum PRCheckExecutionState { +export enum ExecutionState { PENDING = 'pending', RUNNING = 'running', SUCCESS = 'success', @@ -13,15 +13,15 @@ export enum PRCheckExecutionState { ERROR = 'error' } -interface PRCheckExecutionStatusProps { - status: PRCheckExecutionState +interface ExecutionStatusProps { + status: ExecutionState iconOnly?: boolean noBackground?: boolean iconSize?: number className?: string } -export const PRCheckExecutionStatus: React.FC = ({ +export const ExecutionStatus: React.FC = ({ status, iconSize = 20, iconOnly = false, @@ -31,27 +31,27 @@ export const PRCheckExecutionStatus: React.FC = ({ const { getString } = useStrings() const maps = useMemo( () => ({ - [PRCheckExecutionState.PENDING]: { + [ExecutionState.PENDING]: { icon: 'ci-pending-build', css: css.pending, title: getString('pending').toLocaleUpperCase() }, - [PRCheckExecutionState.RUNNING]: { + [ExecutionState.RUNNING]: { icon: 'running-filled', css: css.running, title: getString('running').toLocaleUpperCase() }, - [PRCheckExecutionState.SUCCESS]: { + [ExecutionState.SUCCESS]: { icon: 'execution-success', css: css.success, title: getString('success').toLocaleUpperCase() }, - [PRCheckExecutionState.FAILURE]: { + [ExecutionState.FAILURE]: { icon: 'error-transparent-no-outline', css: css.failure, title: getString('failed').toLocaleUpperCase() }, - [PRCheckExecutionState.ERROR]: { + [ExecutionState.ERROR]: { icon: 'solid-error', css: css.error, title: getString('error').toLocaleUpperCase() diff --git a/web/src/hooks/usePRChecksDecision.tsx b/web/src/hooks/usePRChecksDecision.tsx index ae8b80b64..740bd161c 100644 --- a/web/src/hooks/usePRChecksDecision.tsx +++ b/web/src/hooks/usePRChecksDecision.tsx @@ -4,7 +4,7 @@ import { Color } from '@harnessio/design-system' import type { GitInfoProps } from 'utils/GitUtils' import { useStrings } from 'framework/strings' import { useListStatusCheckResults } from 'services/code' -import { PRCheckExecutionState } from 'components/PRCheckExecutionStatus/PRCheckExecutionStatus' +import { ExecutionState } from 'components/ExecutionStatus/ExecutionStatus' export function usePRChecksDecision({ repoMetadata, @@ -22,18 +22,18 @@ export function usePRChecksDecision({ const [message, setMessage] = useState('') const [complete, setComplete] = useState(true) const status = useMemo(() => { - let _status: PRCheckExecutionState | undefined + let _status: ExecutionState | undefined const _count = { ...DEFAULT_COUNTS } const total = data?.length if (total) { for (const check of data) { switch (check.status) { - case PRCheckExecutionState.ERROR: - case PRCheckExecutionState.FAILURE: - case PRCheckExecutionState.RUNNING: - case PRCheckExecutionState.PENDING: - case PRCheckExecutionState.SUCCESS: + case ExecutionState.ERROR: + case ExecutionState.FAILURE: + case ExecutionState.RUNNING: + case ExecutionState.PENDING: + case ExecutionState.SUCCESS: _count[check.status]++ setCount({ ..._count }) break @@ -44,27 +44,27 @@ export function usePRChecksDecision({ } if (_count.error) { - _status = PRCheckExecutionState.ERROR + _status = ExecutionState.ERROR setColor(Color.RED_900) setBackground(Color.RED_50) setMessage(stringSubstitute(getString('prChecks.error'), { count: _count.error, total }) as string) } else if (_count.failure) { - _status = PRCheckExecutionState.FAILURE + _status = ExecutionState.FAILURE setColor(Color.RED_900) setBackground(Color.RED_50) setMessage(stringSubstitute(getString('prChecks.failure'), { count: _count.failure, total }) as string) } else if (_count.running) { - _status = PRCheckExecutionState.RUNNING + _status = ExecutionState.RUNNING setColor(Color.ORANGE_900) setBackground(Color.ORANGE_100) setMessage(stringSubstitute(getString('prChecks.running'), { count: _count.running, total }) as string) } else if (_count.pending) { - _status = PRCheckExecutionState.PENDING + _status = ExecutionState.PENDING setColor(Color.GREY_600) setBackground(Color.GREY_100) setMessage(stringSubstitute(getString('prChecks.pending'), { count: _count.pending, total }) as string) } else if (_count.success) { - _status = PRCheckExecutionState.SUCCESS + _status = ExecutionState.SUCCESS setColor(Color.GREEN_800) setBackground(Color.GREEN_50) setMessage(stringSubstitute(getString('prChecks.success'), { count: _count.success, total }) as string) diff --git a/web/src/pages/ExecutionList/ExecutionList.module.scss b/web/src/pages/ExecutionList/ExecutionList.module.scss index 9fed84abe..0125cfe4e 100644 --- a/web/src/pages/ExecutionList/ExecutionList.module.scss +++ b/web/src/pages/ExecutionList/ExecutionList.module.scss @@ -7,25 +7,6 @@ } } -.table { - [class*='TableV2--header'] [class*='variation-table-headers'] { - text-transform: none; - color: var(--grey-400); - font-weight: 500; - font-size: 13px; - } - - .row { - height: 80px; - box-shadow: 0px 0px 1px rgba(40, 41, 61, 0.08), 0px 0.5px 2px rgba(96, 97, 112, 0.16); - overflow: hidden; - - &.noDesc > div { - height: 44px; - } - } -} - .withError { display: grid; } @@ -61,26 +42,26 @@ .number { color: var(--grey-400) !important; - font-size: 0.875rem !important; + font-size: var(--font-size-normal) !important; font-weight: 500 !important; } .desc { color: var(--grey-800) !important; - font-size: 0.875rem !important; + font-size: var(--font-size-normal) !important; font-weight: 600 !important; } .author { color: var(--grey500) !important; - font-size: 0.6875rem !important; + font-size: var(--font-size-small) !important; font-weight: 600 !important; } .hash { color: var(--primary-7) !important; font-family: Roboto Mono !important; - font-size: 0.75rem !important; + font-size: var(--font-size-small) !important; font-weight: 500 !important; } @@ -90,6 +71,6 @@ .divider { color: var(--grey-300) !important; - font-size: 0.25rem !important; + font-size: 4px !important; } } diff --git a/web/src/pages/ExecutionList/ExecutionList.module.scss.d.ts b/web/src/pages/ExecutionList/ExecutionList.module.scss.d.ts index 2f7763f6a..6f124d0b5 100644 --- a/web/src/pages/ExecutionList/ExecutionList.module.scss.d.ts +++ b/web/src/pages/ExecutionList/ExecutionList.module.scss.d.ts @@ -3,9 +3,6 @@ declare const styles: { readonly main: string readonly layout: string - readonly table: string - readonly row: string - readonly noDesc: string readonly withError: string readonly nameContainer: string readonly name: string diff --git a/web/src/pages/ExecutionList/ExecutionList.tsx b/web/src/pages/ExecutionList/ExecutionList.tsx index 3d1160ca0..925f0ba80 100644 --- a/web/src/pages/ExecutionList/ExecutionList.tsx +++ b/web/src/pages/ExecutionList/ExecutionList.tsx @@ -16,7 +16,6 @@ import cx from 'classnames' import type { CellProps, Column } from 'react-table' import { useHistory, useParams } from 'react-router-dom' import { useGet } from 'restful-react' -import { Icon } from '@harnessio/icons' import { Timer, Calendar } from 'iconoir-react' import { useStrings } from 'framework/strings' import { LoadingSpinner } from 'components/LoadingSpinner/LoadingSpinner' @@ -30,6 +29,8 @@ import { usePageIndex } from 'hooks/usePageIndex' import { ResourceListingPagination } from 'components/ResourceListingPagination/ResourceListingPagination' import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata' import { RepositoryPageHeader } from 'components/RepositoryPageHeader/RepositoryPageHeader' +import { ExecutionState, ExecutionStatus } from 'components/ExecutionStatus/ExecutionStatus' +import { getStatus } from 'utils/PipelineUtils' import noExecutionImage from '../RepositoriesListing/no-repo.svg' import css from './ExecutionList.module.scss' @@ -73,8 +74,12 @@ const ExecutionList = () => { return ( - {/* TODO this icon need to depend on the status */} - + {`#${record.number}.`} {record.title} @@ -156,7 +161,6 @@ const ExecutionList = () => { {!!executions?.length && ( - className={css.table} columns={columns} data={executions || []} onRowClick={executionInfo => @@ -168,7 +172,6 @@ const ExecutionList = () => { }) ) } - getRowClassName={row => cx(css.row, !row.original.number && css.noDesc)} /> )} diff --git a/web/src/pages/PipelineList/PipelineList.module.scss b/web/src/pages/PipelineList/PipelineList.module.scss index 7ba58fc8a..cc215737f 100644 --- a/web/src/pages/PipelineList/PipelineList.module.scss +++ b/web/src/pages/PipelineList/PipelineList.module.scss @@ -11,46 +11,20 @@ display: grid; } -.table { - [class*='TableV2--header'] [class*='variation-table-headers'] { - text-transform: none; - color: var(--grey-400); - font-weight: 500; - font-size: 13px; - } - - .row { - height: 80px; - box-shadow: 0px 0px 1px rgba(40, 41, 61, 0.08), 0px 0.5px 2px rgba(96, 97, 112, 0.16); - overflow: hidden; - - &.noDesc > div { - height: 44px; - } - } -} - .nameContainer { - display: flex; - align-items: center; - height: 3rem !important; + display: flex !important; + align-items: center !important; } .repoName { font-weight: 600 !important; - font-size: 0.875rem !important; + font-size: var(--font-size-normal) !important; color: var(--grey-700) !important; } -.nameContainer { - // display: flex; - // align-items: center; - // height: 3rem !important; -} - .desc { color: var(--grey-700) !important; - font-size: 0.75rem !important; + font-size: var(--font-size-small) !important; font-style: normal !important; font-weight: 600 !important; } @@ -61,14 +35,14 @@ .author { color: var(--grey500) !important; - font-size: 0.75rem !important; + font-size: var(--font-size-small) !important; font-weight: 500 !important; } .hash { color: var(--primary-7) !important; font-family: Roboto Mono !important; - font-size: 0.75rem !important; + font-size: var(--font-size-small) !important; font-weight: 500 !important; } @@ -82,5 +56,9 @@ .divider { color: var(--grey-300) !important; - font-size: 0.5rem !important; + font-size: 8px !important; +} + +.statusIcon { + align-self: center !important; } diff --git a/web/src/pages/PipelineList/PipelineList.module.scss.d.ts b/web/src/pages/PipelineList/PipelineList.module.scss.d.ts index ee305031a..e108e3e1d 100644 --- a/web/src/pages/PipelineList/PipelineList.module.scss.d.ts +++ b/web/src/pages/PipelineList/PipelineList.module.scss.d.ts @@ -4,9 +4,6 @@ declare const styles: { readonly main: string readonly layout: string readonly withError: string - readonly table: string - readonly row: string - readonly noDesc: string readonly nameContainer: string readonly repoName: string readonly desc: string @@ -16,5 +13,6 @@ declare const styles: { readonly triggerLayout: string readonly spacer: string readonly divider: string + readonly statusIcon: string } export default styles diff --git a/web/src/pages/PipelineList/PipelineList.tsx b/web/src/pages/PipelineList/PipelineList.tsx index b5866bc1f..40fe4476b 100644 --- a/web/src/pages/PipelineList/PipelineList.tsx +++ b/web/src/pages/PipelineList/PipelineList.tsx @@ -17,7 +17,6 @@ import type { CellProps, Column } from 'react-table' import Keywords from 'react-keywords' import { useHistory } from 'react-router-dom' import { useGet } from 'restful-react' -import { Icon } from '@harnessio/icons' import { Calendar, Timer, GitFork } from 'iconoir-react' import { useStrings } from 'framework/strings' import { LoadingSpinner } from 'components/LoadingSpinner/LoadingSpinner' @@ -31,6 +30,8 @@ import { ResourceListingPagination } from 'components/ResourceListingPagination/ import { useAppContext } from 'AppContext' import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata' import { RepositoryPageHeader } from 'components/RepositoryPageHeader/RepositoryPageHeader' +import { ExecutionStatus, ExecutionState } from 'components/ExecutionStatus/ExecutionStatus' +import { getStatus } from 'utils/PipelineUtils' import noPipelineImage from '../RepositoriesListing/no-repo.svg' import css from './PipelineList.module.scss' @@ -53,7 +54,8 @@ const PipelineList = () => { } = useGet({ path: `/api/v1/repos/${repoMetadata?.path}/+/pipelines`, queryParams: { page, limit: LIST_FETCHING_LIMIT, query: searchTerm, latest: true }, - lazy: !repoMetadata + lazy: !repoMetadata, + debounce: 500 }) const NewPipelineButton = ( @@ -75,8 +77,13 @@ const PipelineList = () => { const record = row.original return ( - {/* TODO this icon need to depend on the status */} - + {record.uid} @@ -91,7 +98,7 @@ const PipelineList = () => { const record = row.original.execution return record ? ( - + {/* TODO this icon need to depend on the status */} {`#${record.number}`} @@ -187,7 +194,6 @@ const PipelineList = () => { {!!pipelines?.length && ( - className={css.table} columns={columns} data={pipelines || []} onRowClick={pipelineInfo => @@ -198,7 +204,6 @@ const PipelineList = () => { }) ) } - getRowClassName={row => cx(css.row, !row.original.description && css.noDesc)} /> )} diff --git a/web/src/pages/PullRequest/Checks/Checks.tsx b/web/src/pages/PullRequest/Checks/Checks.tsx index d41a131ca..ae74a03a5 100644 --- a/web/src/pages/PullRequest/Checks/Checks.tsx +++ b/web/src/pages/PullRequest/Checks/Checks.tsx @@ -27,7 +27,7 @@ import { useStrings } from 'framework/strings' import { MarkdownViewer } from 'components/MarkdownViewer/MarkdownViewer' import type { PRChecksDecisionResult } from 'hooks/usePRChecksDecision' import type { TypesCheck } from 'services/code' -import { PRCheckExecutionState, PRCheckExecutionStatus } from 'components/PRCheckExecutionStatus/PRCheckExecutionStatus' +import { ExecutionState, ExecutionStatus } from 'components/ExecutionStatus/ExecutionStatus' import css from './Checks.module.scss' interface ChecksProps extends Pick { @@ -77,11 +77,11 @@ export const Checks: React.FC = props => { - = ({ } else { // Find and set a default selected item. Order: Error, Failure, Running, Success, Pending const defaultSelectedItem = - prChecksDecisionResult?.data?.find(({ status }) => status === PRCheckExecutionState.ERROR) || - prChecksDecisionResult?.data?.find(({ status }) => status === PRCheckExecutionState.FAILURE) || - prChecksDecisionResult?.data?.find(({ status }) => status === PRCheckExecutionState.RUNNING) || - prChecksDecisionResult?.data?.find(({ status }) => status === PRCheckExecutionState.SUCCESS) || - prChecksDecisionResult?.data?.find(({ status }) => status === PRCheckExecutionState.PENDING) || + prChecksDecisionResult?.data?.find(({ status }) => status === ExecutionState.ERROR) || + prChecksDecisionResult?.data?.find(({ status }) => status === ExecutionState.FAILURE) || + prChecksDecisionResult?.data?.find(({ status }) => status === ExecutionState.RUNNING) || + prChecksDecisionResult?.data?.find(({ status }) => status === ExecutionState.SUCCESS) || + prChecksDecisionResult?.data?.find(({ status }) => status === ExecutionState.PENDING) || prChecksDecisionResult?.data?.[0] if (defaultSelectedItem) { @@ -266,9 +266,9 @@ const CheckMenuItem: React.FC = ({ expandable, isSelected = {timeDistance(itemData.updated, itemData.created)} - - + {getString('pr.checks')} {message} @@ -94,7 +94,7 @@ const CheckSection: React.FC = ({ repoMetadata, pullRequestMe - + - { + switch (status) { + case 'success': + return ExecutionState.SUCCESS + case 'failed': + return ExecutionState.FAILURE + case 'running': + return ExecutionState.RUNNING + case 'pending': + return ExecutionState.PENDING + default: + return ExecutionState.PENDING + } +} From 7cde39a7b4ca29fed019d0606e9bf48848985f0e Mon Sep 17 00:00:00 2001 From: Dan Wilson Date: Mon, 4 Sep 2023 15:51:29 +0100 Subject: [PATCH 4/4] use shared pipe component --- web/src/pages/ExecutionList/ExecutionList.module.scss | 5 ----- .../pages/ExecutionList/ExecutionList.module.scss.d.ts | 1 - web/src/pages/ExecutionList/ExecutionList.tsx | 3 ++- web/src/pages/PipelineList/PipelineList.module.scss | 5 ----- web/src/pages/PipelineList/PipelineList.module.scss.d.ts | 1 - web/src/pages/PipelineList/PipelineList.tsx | 8 ++++---- 6 files changed, 6 insertions(+), 17 deletions(-) diff --git a/web/src/pages/ExecutionList/ExecutionList.module.scss b/web/src/pages/ExecutionList/ExecutionList.module.scss index 0125cfe4e..069671835 100644 --- a/web/src/pages/ExecutionList/ExecutionList.module.scss +++ b/web/src/pages/ExecutionList/ExecutionList.module.scss @@ -68,9 +68,4 @@ .triggerLayout { align-items: center !important; } - - .divider { - color: var(--grey-300) !important; - font-size: 4px !important; - } } diff --git a/web/src/pages/ExecutionList/ExecutionList.module.scss.d.ts b/web/src/pages/ExecutionList/ExecutionList.module.scss.d.ts index 6f124d0b5..0fd6a5b97 100644 --- a/web/src/pages/ExecutionList/ExecutionList.module.scss.d.ts +++ b/web/src/pages/ExecutionList/ExecutionList.module.scss.d.ts @@ -12,6 +12,5 @@ declare const styles: { readonly author: string readonly hash: string readonly triggerLayout: string - readonly divider: string } export default styles diff --git a/web/src/pages/ExecutionList/ExecutionList.tsx b/web/src/pages/ExecutionList/ExecutionList.tsx index 925f0ba80..31ad3f3b6 100644 --- a/web/src/pages/ExecutionList/ExecutionList.tsx +++ b/web/src/pages/ExecutionList/ExecutionList.tsx @@ -31,6 +31,7 @@ import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata' import { RepositoryPageHeader } from 'components/RepositoryPageHeader/RepositoryPageHeader' import { ExecutionState, ExecutionStatus } from 'components/ExecutionStatus/ExecutionStatus' import { getStatus } from 'utils/PipelineUtils' +import { PipeSeparator } from 'components/PipeSeparator/PipeSeparator' import noExecutionImage from '../RepositoriesListing/no-repo.svg' import css from './ExecutionList.module.scss' @@ -87,7 +88,7 @@ const ExecutionList = () => { {/* TODO need logic here for different trigger types */} {`${record.author_name} triggered manually`} - {`|`} + {/* TODO Will need to replace this with commit component - wont match Yifan designs */} {record.after} diff --git a/web/src/pages/PipelineList/PipelineList.module.scss b/web/src/pages/PipelineList/PipelineList.module.scss index cc215737f..9369446d0 100644 --- a/web/src/pages/PipelineList/PipelineList.module.scss +++ b/web/src/pages/PipelineList/PipelineList.module.scss @@ -54,11 +54,6 @@ width: 180px; } -.divider { - color: var(--grey-300) !important; - font-size: 8px !important; -} - .statusIcon { align-self: center !important; } diff --git a/web/src/pages/PipelineList/PipelineList.module.scss.d.ts b/web/src/pages/PipelineList/PipelineList.module.scss.d.ts index e108e3e1d..287329376 100644 --- a/web/src/pages/PipelineList/PipelineList.module.scss.d.ts +++ b/web/src/pages/PipelineList/PipelineList.module.scss.d.ts @@ -12,7 +12,6 @@ declare const styles: { readonly hash: string readonly triggerLayout: string readonly spacer: string - readonly divider: string readonly statusIcon: string } export default styles diff --git a/web/src/pages/PipelineList/PipelineList.tsx b/web/src/pages/PipelineList/PipelineList.tsx index 40fe4476b..d64f4ebe1 100644 --- a/web/src/pages/PipelineList/PipelineList.tsx +++ b/web/src/pages/PipelineList/PipelineList.tsx @@ -32,6 +32,7 @@ import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata' import { RepositoryPageHeader } from 'components/RepositoryPageHeader/RepositoryPageHeader' import { ExecutionStatus, ExecutionState } from 'components/ExecutionStatus/ExecutionStatus' import { getStatus } from 'utils/PipelineUtils' +import { PipeSeparator } from 'components/PipeSeparator/PipeSeparator' import noPipelineImage from '../RepositoriesListing/no-repo.svg' import css from './PipelineList.module.scss' @@ -100,9 +101,8 @@ const PipelineList = () => { return record ? ( - {/* TODO this icon need to depend on the status */} {`#${record.number}`} - {`|`} + {record.title} @@ -115,10 +115,10 @@ const PipelineList = () => { /> {/* TODO need logic here for different trigger types */} {record.author_name} - {`|`} + {record.source} - {`|`} + {/* TODO Will need to replace this with commit component - wont match Yifan designs */} {/* {record.after} */}