From 4da3f9f16eb52d8b42c6450bbd6849accc88b352 Mon Sep 17 00:00:00 2001 From: Sakari Laine Date: Thu, 18 Apr 2024 16:00:50 +0300 Subject: [PATCH] Add config horizontal to switch for horizontal layout of jobs --- README.md | 1 + public/client.less | 29 +++++++++++++++++++++++++++++ src/app.js | 1 + src/client/gitlab-types.ts | 1 + src/client/groupedProjects.tsx | 10 +++++----- src/client/index.tsx | 4 +++- src/client/jobs.tsx | 6 ++++-- src/client/projects.tsx | 8 ++++---- src/client/stages.tsx | 16 ++++++++++------ src/config.js | 1 + 10 files changed, 59 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index fa5e902..446847b 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ Optional configuration properties: - `gitlabs / caFile` - CA file location to be passed to the request library when accessing the gitlab instance. - `gitlabs / ignoreArchived` - Ignore archived projects. Default value is `true` - `groupSuccessfulProjects` - If set to `true` projects with successful pipeline status are grouped by namespace. Projects with other pipeline statuses are still rendered seperately. Default value is `false`. +- `horizontal` - If set to `true` jobs are ordered horizontally to stages. Default value is `false`. - `auth / username` - Enables HTTP basic authentication with the defined username and password. - `auth / password` - Enables HTTP basic authentication with the defined username and password. - `projectsOrder` - Array of project attributes to use for sorting projects. Default value is `['name']` (available attributes are `status, name, id, nameWithoutNamespace, group`). diff --git a/public/client.less b/public/client.less index f865f93..dd40bf7 100644 --- a/public/client.less +++ b/public/client.less @@ -161,6 +161,22 @@ ol.stages { white-space: nowrap; } } + + .stage.horizontal { + flex-wrap: nowrap; + align-items: flex-start; + flex-direction: row; + + .name { + min-width: 170px; + } + } +} + +ol.stages.horizontal { + flex-direction: column; + flex-wrap: nowrap; + flex-grow: 1; } ol.jobs { @@ -228,6 +244,19 @@ ol.jobs { } } +ol.jobs.horizontal { + flex-direction: row; + flex-wrap: wrap; + + li { + margin-right: 5px; + } + + :last-child { + margin-bottom: 5px; + } +} + ol.groups { list-style: none; width: 100vmax; diff --git a/src/app.js b/src/app.js index ce4df87..3a10ff1 100644 --- a/src/app.js +++ b/src/app.js @@ -36,6 +36,7 @@ const globalState = { zoom: config.zoom, projectsOrder: config.projectsOrder, columns: config.columns, + horizontal: config.horizontal, groupSuccessfulProjects: config.groupSuccessfulProjects } diff --git a/src/client/gitlab-types.ts b/src/client/gitlab-types.ts index 16ae1cf..21d2fb1 100644 --- a/src/client/gitlab-types.ts +++ b/src/client/gitlab-types.ts @@ -3,6 +3,7 @@ export interface GlobalState { columns: number error: string | null groupSuccessfulProjects: boolean + horizontal: boolean projects: Project[] | null projectsOrder: string[] zoom: number diff --git a/src/client/groupedProjects.tsx b/src/client/groupedProjects.tsx index 8470575..2e3cba3 100644 --- a/src/client/groupedProjects.tsx +++ b/src/client/groupedProjects.tsx @@ -4,20 +4,20 @@ import {Projects} from './projects' import React from 'react' import type {Project} from './gitlab-types' -export function GroupedProjects({projects, projectsOrder, groupSuccessfulProjects, zoom, columns, now, screen}: {projects: Project[], projectsOrder: string[], groupSuccessfulProjects: boolean, zoom: number, columns: number, now: number, screen: {id: number, total: number}}): JSX.Element { +export function GroupedProjects({projects, projectsOrder, groupSuccessfulProjects, zoom, columns, now, horizontal, screen}: {projects: Project[], projectsOrder: string[], groupSuccessfulProjects: boolean, zoom: number, columns: number, now: number, horizontal: boolean, screen: {id: number, total: number}}): JSX.Element { if (groupSuccessfulProjects) { - return renderProjectsGrouped(projects, projectsOrder, zoom, columns, now, screen) + return renderProjectsGrouped(projects, projectsOrder, zoom, columns, now, horizontal, screen) } - return + return } -function renderProjectsGrouped(projects: Project[], projectsOrder: string[], zoom: number, columns: number, now: number, screen: {id: number, total: number}) { +function renderProjectsGrouped(projects: Project[], projectsOrder: string[], zoom: number, columns: number, now: number, horizontal: boolean, screen: {id: number, total: number}) { const successfullProjects = projects.filter(({status}) => status === 'success') const otherProjects= projects.filter(({status}) => status !== 'success') const groupedProjects = groupBy(successfullProjects, 'group') return - + } diff --git a/src/client/index.tsx b/src/client/index.tsx index e43250e..c31781b 100644 --- a/src/client/index.tsx +++ b/src/client/index.tsx @@ -16,6 +16,7 @@ class RadiatorApp extends React.Component { columns: 1, error: null, groupSuccessfulProjects: false, + horizontal: false, projects: null, projectsOrder: [], now: 0, @@ -34,7 +35,7 @@ class RadiatorApp extends React.Component { render = () => { const {screen} = this.args - const {now, zoom, columns, projects, projectsOrder, groupSuccessfulProjects} = this.state + const {now, zoom, columns, projects, projectsOrder, groupSuccessfulProjects, horizontal} = this.state return
{this.renderErrorMessage()} {this.renderProgressMessage()} @@ -43,6 +44,7 @@ class RadiatorApp extends React.Component { }
diff --git a/src/client/jobs.tsx b/src/client/jobs.tsx index 51b33d8..8e45bfe 100644 --- a/src/client/jobs.tsx +++ b/src/client/jobs.tsx @@ -17,7 +17,7 @@ const JOB_STATES_IN_INTEREST_ORDER: JobStatus[] = [ 'skipped' ] -export function Jobs({jobs, maxNonFailedJobsVisible}: {jobs: Job[], maxNonFailedJobsVisible: number}): JSX.Element { +export function Jobs({jobs, maxNonFailedJobsVisible, horizontal}: {jobs: Job[], maxNonFailedJobsVisible: number, horizontal: boolean}): JSX.Element { const [failedJobs, nonFailedJobs] = partition(jobs, {status: 'failed'}) const filteredJobs = sortByOriginalOrder( failedJobs.concat( @@ -37,7 +37,9 @@ export function Jobs({jobs, maxNonFailedJobsVisible}: {jobs: Job[], maxNonFailed .map(([status, count]) => `${count}${NON_BREAKING_SPACE}${status}`) .join(', ') - return
    + const horizontalClass = horizontal ? ' horizontal' : '' + + return
      {filteredJobs.map(job => )} { hiddenJobs.length > 0 ?
    1. + {hiddenJobsText}
    2. : null diff --git a/src/client/projects.tsx b/src/client/projects.tsx index 3b8d646..33edaaa 100644 --- a/src/client/projects.tsx +++ b/src/client/projects.tsx @@ -4,16 +4,16 @@ import sortBy from 'lodash/sortBy' import {Stages} from './stages' import type {Project} from './gitlab-types' -export function Projects({columns, now, projects, projectsOrder, screen, zoom}: {columns: number, now: number, projects: Project[], projectsOrder: string[], screen: {id: number, total: number}, zoom: number}): JSX.Element { +export function Projects({columns, now, horizontal, projects, projectsOrder, screen, zoom}: {columns: number, now: number, horizontal: boolean, projects: Project[], projectsOrder: string[], screen: {id: number, total: number}, zoom: number}): JSX.Element { return
        {sortBy(projects, projectsOrder) .filter(forScreen(screen, projects.length)) - .map(project => ) + .map(project => ) }
      } -function ProjectElement({columns, now, project}: {columns: number, now: number, project: Project}) { +function ProjectElement({columns, now, horizontal, project}: {columns: number, now: number, horizontal: boolean, project: Project}) { const [pipeline] = project.pipelines return
    3. @@ -21,7 +21,7 @@ function ProjectElement({columns, now, project}: {columns: number, now: number, {project.url && {project.name}} {!project.url && project.name} - +
    4. } diff --git a/src/client/stages.tsx b/src/client/stages.tsx index d81fb8c..6360bef 100644 --- a/src/client/stages.tsx +++ b/src/client/stages.tsx @@ -2,17 +2,21 @@ import {Jobs} from './jobs' import React from 'react' import type {Stage} from './gitlab-types' -export function Stages({stages, maxNonFailedJobsVisible}: {stages: Stage[], maxNonFailedJobsVisible: number}): JSX.Element { - return
        +export function Stages({stages, maxNonFailedJobsVisible, horizontal}: {stages: Stage[], maxNonFailedJobsVisible: number, horizontal: boolean}): JSX.Element { + const horizontalClass = horizontal ? ' horizontal' : '' + + return
          {stages.map(stage => - + )}
        } -function StageElement({stage, maxNonFailedJobsVisible}: {stage: Stage, maxNonFailedJobsVisible: number}) { - return
      1. +function StageElement({stage, maxNonFailedJobsVisible, horizontal}: {stage: Stage, maxNonFailedJobsVisible: number, horizontal: boolean}) { + const horizontalClass = horizontal ? ' horizontal' : '' + + return
      2. {stage.name}
        - +
      3. } diff --git a/src/config.js b/src/config.js index b32fb18..50684d5 100644 --- a/src/config.js +++ b/src/config.js @@ -11,6 +11,7 @@ config.interval = Number(config.interval || 10) * 1000 config.port = Number(config.port || 3000) config.zoom = Number(config.zoom || 1.0) config.columns = Number(config.columns || 1) +config.horizontal = config.horizontal || false config.groupSuccessfulProjects = config.groupSuccessfulProjects || false config.projectsOrder = config.projectsOrder || ['name'] config.gitlabs = config.gitlabs.map((gitlab) => {