mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-26 20:01:02 +00:00
Harmonize pipeline status information and add a review link to the approval (#2345)
Ref: https://github.com/woodpecker-ci/woodpecker/discussions/2162#discussioncomment-6666864 Adds a `PipelineInfo` view to harmonize pipeline status information and add a review link to the approval view. ![image](https://github.com/woodpecker-ci/woodpecker/assets/3391958/41062b5f-0f15-4c3c-b72c-e22092804072) ![image](https://github.com/woodpecker-ci/woodpecker/assets/3391958/4cfb1bc8-8bfd-4217-bce3-c9a1378f58ee) ![image](https://github.com/woodpecker-ci/woodpecker/assets/3391958/f3b22a07-464e-4d29-85f0-de122bce1bbe) --------- Co-authored-by: Lauris BH <lauris@nix.lv> Co-authored-by: qwerty287 <80460567+qwerty287@users.noreply.github.com>
This commit is contained in:
parent
41f6ecfa1b
commit
5c2f02c4a1
5 changed files with 44 additions and 18 deletions
1
web/components.d.ts
vendored
1
web/components.d.ts
vendored
|
@ -83,6 +83,7 @@ declare module '@vue/runtime-core' {
|
||||||
Panel: typeof import('./src/components/layout/Panel.vue')['default']
|
Panel: typeof import('./src/components/layout/Panel.vue')['default']
|
||||||
PipelineFeedItem: typeof import('./src/components/pipeline-feed/PipelineFeedItem.vue')['default']
|
PipelineFeedItem: typeof import('./src/components/pipeline-feed/PipelineFeedItem.vue')['default']
|
||||||
PipelineFeedSidebar: typeof import('./src/components/pipeline-feed/PipelineFeedSidebar.vue')['default']
|
PipelineFeedSidebar: typeof import('./src/components/pipeline-feed/PipelineFeedSidebar.vue')['default']
|
||||||
|
PipelineInfo: typeof import('./src/components/repo/pipeline/PipelineInfo.vue')['default']
|
||||||
PipelineItem: typeof import('./src/components/repo/pipeline/PipelineItem.vue')['default']
|
PipelineItem: typeof import('./src/components/repo/pipeline/PipelineItem.vue')['default']
|
||||||
PipelineList: typeof import('./src/components/repo/pipeline/PipelineList.vue')['default']
|
PipelineList: typeof import('./src/components/repo/pipeline/PipelineList.vue')['default']
|
||||||
PipelineLog: typeof import('./src/components/repo/pipeline/PipelineLog.vue')['default']
|
PipelineLog: typeof import('./src/components/repo/pipeline/PipelineLog.vue')['default']
|
||||||
|
|
|
@ -255,7 +255,8 @@
|
||||||
"log_auto_scroll_off": "Turn off automatic scrolling"
|
"log_auto_scroll_off": "Turn off automatic scrolling"
|
||||||
},
|
},
|
||||||
"protected": {
|
"protected": {
|
||||||
"awaits": "This pipeline is awaiting approval by some maintainer!",
|
"review": "Review changes",
|
||||||
|
"awaits": "This pipeline is awaiting approval by a maintainer!",
|
||||||
"approve": "Approve",
|
"approve": "Approve",
|
||||||
"decline": "Decline",
|
"decline": "Decline",
|
||||||
"declined": "This pipeline has been declined!",
|
"declined": "This pipeline has been declined!",
|
||||||
|
|
9
web/src/components/repo/pipeline/PipelineInfo.vue
Normal file
9
web/src/components/repo/pipeline/PipelineInfo.vue
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<template>
|
||||||
|
<div class="w-full md:px-4 text-wp-text-100">
|
||||||
|
<div
|
||||||
|
class="flex flex-col px-4 py-8 gap-4 justify-center items-center text-center flex-shrink-0 rounded-md border bg-wp-background-100 border-wp-background-400 dark:bg-wp-background-200"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -9,15 +9,26 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="flex flex-grow relative">
|
<div class="flex flex-grow relative">
|
||||||
<div v-if="error" class="flex flex-col p-4">
|
<PipelineInfo v-if="error">
|
||||||
<span class="text-wp-state-error-100 font-bold text-xl mb-2">{{ $t('repo.pipeline.execution_error') }}</span>
|
<Icon name="status-error" class="w-16 h-16 text-wp-state-error-100" />
|
||||||
<span class="text-wp-state-error-100">{{ error }}</span>
|
<div class="flex flex-wrap items-center justify-center gap-2 text-xl">
|
||||||
</div>
|
<span class="capitalize">{{ $t('repo.pipeline.execution_error') }}:</span>
|
||||||
|
<span>{{ error }}</span>
|
||||||
|
</div>
|
||||||
|
</PipelineInfo>
|
||||||
|
|
||||||
<div v-else-if="pipeline.status === 'blocked'" class="flex flex-col flex-grow justify-center items-center p-2">
|
<PipelineInfo v-else-if="pipeline.status === 'blocked'">
|
||||||
<Icon name="status-blocked" class="w-16 h-16 text-wp-text-100 mb-4" />
|
<Icon name="status-blocked" class="w-16 h-16" />
|
||||||
<p class="text-xl text-wp-text-100 mb-4">{{ $t('repo.pipeline.protected.awaits') }}</p>
|
<span class="text-xl">{{ $t('repo.pipeline.protected.awaits') }}</span>
|
||||||
<div v-if="repoPermissions.push" class="flex space-x-4">
|
<div v-if="repoPermissions.push" class="flex gap-2 flex-wrap items-center justify-center">
|
||||||
|
<Button
|
||||||
|
color="blue"
|
||||||
|
:start-icon="forge ?? 'repo'"
|
||||||
|
:text="$t('repo.pipeline.protected.review')"
|
||||||
|
:is-loading="isApprovingPipeline"
|
||||||
|
:to="pipeline.link_url"
|
||||||
|
:title="message"
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
color="green"
|
color="green"
|
||||||
:text="$t('repo.pipeline.protected.approve')"
|
:text="$t('repo.pipeline.protected.approve')"
|
||||||
|
@ -31,12 +42,12 @@
|
||||||
@click="declinePipeline"
|
@click="declinePipeline"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</PipelineInfo>
|
||||||
|
|
||||||
<div v-else-if="pipeline.status === 'declined'" class="flex flex-col flex-grow justify-center items-center">
|
<PipelineInfo v-else-if="pipeline.status === 'declined'">
|
||||||
<Icon name="status-blocked" class="w-16 h-16 text-wp-text-100 mb-4" />
|
<Icon name="status-blocked" class="w-16 h-16" />
|
||||||
<p class="text-xl text-wp-text-100">{{ $t('repo.pipeline.protected.declined') }}</p>
|
<p class="text-xl">{{ $t('repo.pipeline.protected.declined') }}</p>
|
||||||
</div>
|
</PipelineInfo>
|
||||||
|
|
||||||
<PipelineLog
|
<PipelineLog
|
||||||
v-else-if="selectedStepId"
|
v-else-if="selectedStepId"
|
||||||
|
@ -61,7 +72,9 @@ import PipelineLog from '~/components/repo/pipeline/PipelineLog.vue';
|
||||||
import PipelineStepList from '~/components/repo/pipeline/PipelineStepList.vue';
|
import PipelineStepList from '~/components/repo/pipeline/PipelineStepList.vue';
|
||||||
import useApiClient from '~/compositions/useApiClient';
|
import useApiClient from '~/compositions/useApiClient';
|
||||||
import { useAsyncAction } from '~/compositions/useAsyncAction';
|
import { useAsyncAction } from '~/compositions/useAsyncAction';
|
||||||
|
import useConfig from '~/compositions/useConfig';
|
||||||
import useNotifications from '~/compositions/useNotifications';
|
import useNotifications from '~/compositions/useNotifications';
|
||||||
|
import usePipeline from '~/compositions/usePipeline';
|
||||||
import { Pipeline, PipelineStep, Repo, RepoPermissions } from '~/lib/api/types';
|
import { Pipeline, PipelineStep, Repo, RepoPermissions } from '~/lib/api/types';
|
||||||
import { findStep } from '~/utils/helpers';
|
import { findStep } from '~/utils/helpers';
|
||||||
|
|
||||||
|
@ -125,6 +138,9 @@ const selectedStepId = computed({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { forge } = useConfig();
|
||||||
|
const { message } = usePipeline(pipeline);
|
||||||
|
|
||||||
const selectedStep = computed(() => findStep(pipeline.value.workflows || [], selectedStepId.value || -1));
|
const selectedStep = computed(() => findStep(pipeline.value.workflows || [], selectedStepId.value || -1));
|
||||||
const error = computed(() => pipeline.value?.error || selectedStep.value?.error);
|
const error = computed(() => pipeline.value?.error || selectedStep.value?.error);
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
<template #title>{{ repo.full_name }}</template>
|
<template #title>{{ repo.full_name }}</template>
|
||||||
|
|
||||||
<template #titleActions>
|
<template #titleActions>
|
||||||
<div class="flex md:items-center flex-col gap-x-2 md:flex-row md:justify-between min-w-0">
|
<div class="flex md:items-center flex-col gap-2 md:flex-row md:justify-between min-w-0">
|
||||||
<div class="flex content-start gap-x-2 py-2 md:mr-2 min-w-0">
|
<div class="flex content-start gap-2 min-w-0">
|
||||||
<PipelineStatusIcon :status="pipeline.status" class="flex flex-shrink-0" />
|
<PipelineStatusIcon :status="pipeline.status" class="flex flex-shrink-0" />
|
||||||
<span class="flex-shrink-0 text-center">{{ $t('repo.pipeline.pipeline', { pipelineId }) }}</span>
|
<span class="flex-shrink-0 text-center">{{ $t('repo.pipeline.pipeline', { pipelineId }) }}</span>
|
||||||
<span class="hidden md:inline-block">-</span>
|
<span class="hidden md:inline-block">-</span>
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
}}</span>
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-if="repoPermissions.push">
|
<template v-if="repoPermissions.push && pipeline.status !== 'declined' && pipeline.status !== 'blocked'">
|
||||||
<div class="flex content-start gap-x-2">
|
<div class="flex content-start gap-x-2">
|
||||||
<Button
|
<Button
|
||||||
v-if="pipeline.status === 'pending' || pipeline.status === 'running'"
|
v-if="pipeline.status === 'pending' || pipeline.status === 'running'"
|
||||||
|
@ -31,7 +31,6 @@
|
||||||
@click="cancelPipeline"
|
@click="cancelPipeline"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
v-else-if="pipeline.status !== 'blocked' && pipeline.status !== 'declined'"
|
|
||||||
class="flex-shrink-0"
|
class="flex-shrink-0"
|
||||||
:text="$t('repo.pipeline.actions.restart')"
|
:text="$t('repo.pipeline.actions.restart')"
|
||||||
:is-loading="isRestartingPipeline"
|
:is-loading="isRestartingPipeline"
|
||||||
|
|
Loading…
Reference in a new issue