mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2026-04-15 01:41:56 +00:00
add back repos without pipelines and apply to orgRepos
This commit is contained in:
@@ -50,6 +50,7 @@
|
||||
<SvgIcon v-else-if="name === 'auto-scroll-off'" :path="mdiDownloadOff" size="24" />
|
||||
<SvgIcon v-else-if="name === 'pause'" :path="mdiPause" size="24" />
|
||||
<SvgIcon v-else-if="name === 'remove'" :path="mdiClose" size="24" />
|
||||
<SvgIcon v-else-if="name === 'new'" :path="mdiCircleOutline" size="24" />
|
||||
|
||||
<SvgIcon v-else-if="name === 'forgejo'" :path="siForgejo.path" size="32" />
|
||||
<SvgIcon v-else-if="name === 'gitea'" :path="siGitea.path" size="32" />
|
||||
@@ -119,6 +120,7 @@ import {
|
||||
mdiTagOutline,
|
||||
mdiTimelapse,
|
||||
mdiTrashCanOutline,
|
||||
mdiCircleOutline,
|
||||
} from '@mdi/js';
|
||||
import { siForgejo, siGitea } from 'simple-icons';
|
||||
|
||||
@@ -175,7 +177,8 @@ export type IconNames =
|
||||
| 'attention'
|
||||
| 'spinner'
|
||||
| 'error'
|
||||
| 'remove';
|
||||
| 'remove'
|
||||
| 'new';
|
||||
|
||||
defineProps<{
|
||||
name: IconNames;
|
||||
|
||||
82
web/src/components/repo/RepoItems.vue
Normal file
82
web/src/components/repo/RepoItems.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<router-link v-if="repo" :to="{ name: 'repo', params: { repoId: repo.id } }">
|
||||
<div
|
||||
class="flex flex-col border rounded-md bg-wp-background-100 overflow-hidden p-4 border-wp-background-400 dark:bg-wp-background-200 cursor-pointer hover:shadow-md hover:bg-wp-background-300 dark:hover:bg-wp-background-300"
|
||||
>
|
||||
<div class="grid grid-cols-[1.5rem,auto,1fr] gap-2 items-center">
|
||||
<PipelineStatusIcon v-if="pipeline" :status="pipeline.status" />
|
||||
<Icon v-else name="new" class="text-wp-text-100" />
|
||||
<span class="text-wp-text-100 text-lg">{{ `${repo.owner} / ${repo.name}` }}</span>
|
||||
<span class="ml-auto">
|
||||
<Badge
|
||||
v-if="repo.visibility === RepoVisibility.Public"
|
||||
:label="$t('repo.settings.general.visibility.public.public')"
|
||||
/>
|
||||
</span>
|
||||
|
||||
<div class="col-start-2 col-span-2 text-wp-text-100">
|
||||
<div v-if="pipeline" class="flex gap-1 items-center">
|
||||
<span :title="pipelineEventTitle">
|
||||
<Icon v-if="pipeline.event === 'pull_request'" name="pull-request" />
|
||||
<Icon v-else-if="pipeline.event === 'pull_request_closed'" name="pull-request-closed" />
|
||||
<Icon v-else-if="pipeline.event === 'deployment'" name="deployment" />
|
||||
<Icon v-else-if="pipeline.event === 'tag' || pipeline.event === 'release'" name="tag" />
|
||||
<Icon v-else-if="pipeline.event === 'cron'" name="push" />
|
||||
<Icon v-else-if="pipeline.event === 'manual'" name="manual-pipeline" />
|
||||
<Icon v-else name="push" />
|
||||
</span>
|
||||
<span class="whitespace-nowrap overflow-hidden overflow-ellipsis">{{ shortMessage }}</span>
|
||||
<span class="ml-auto hidden sm:inline-block flex-shrink-0">{{ since }}</span>
|
||||
</div>
|
||||
|
||||
<div v-else class="flex gap-2">
|
||||
<span>{{ $t('repo.pipeline.no_pipelines') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, toRef } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import Icon from '~/components/atomic/Icon.vue';
|
||||
import Badge from '~/components/atomic/Badge.vue';
|
||||
import PipelineStatusIcon from '~/components/repo/pipeline/PipelineStatusIcon.vue';
|
||||
import usePipeline from '~/compositions/usePipeline';
|
||||
import type { Repo } from '~/lib/api/types';
|
||||
import { RepoVisibility } from '~/lib/api/types';
|
||||
|
||||
const props = defineProps<{
|
||||
repo: Repo;
|
||||
}>();
|
||||
|
||||
const repo = props.repo;
|
||||
const pipeline = toRef(repo.last_pipeline);
|
||||
const { since, shortMessage } = usePipeline(pipeline);
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const pipelineEventTitle = computed(() => {
|
||||
switch (pipeline.value.event) {
|
||||
case 'pull_request':
|
||||
return t('repo.pipeline.event.pr');
|
||||
case 'pull_request_closed':
|
||||
return t('repo.pipeline.event.pr_closed');
|
||||
case 'deployment':
|
||||
return t('repo.pipeline.event.deploy');
|
||||
case 'tag':
|
||||
return t('repo.pipeline.event.tag');
|
||||
case 'release':
|
||||
return t('repo.pipeline.event.release');
|
||||
case 'cron':
|
||||
return t('repo.pipeline.event.cron');
|
||||
case 'manual':
|
||||
return t('repo.pipeline.event.manual');
|
||||
default:
|
||||
return t('repo.pipeline.event.push');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -1,47 +0,0 @@
|
||||
<template>
|
||||
<router-link v-if="repo && pipeline" :to="{ name: 'repo', params: { repoId: repo.id } }">
|
||||
<div
|
||||
class="flex flex-col border rounded-md bg-wp-background-100 overflow-hidden p-4 border-wp-background-400 dark:bg-wp-background-200 cursor-pointer hover:shadow-md hover:bg-wp-background-300 dark:hover:bg-wp-background-300"
|
||||
>
|
||||
<div class="grid item grid-cols-[1.5rem,auto,1fr] gap-2">
|
||||
<PipelineStatusIcon :status="pipeline.status" class="flex items-center" />
|
||||
<span class="text-wp-text-100 text-lg">{{ `${repo.owner} / ${repo.name}` }}</span>
|
||||
<span class="ml-auto">
|
||||
<Badge
|
||||
v-if="repo.visibility === RepoVisibility.Public"
|
||||
:label="$t('repo.settings.general.visibility.public.public')"
|
||||
/>
|
||||
</span>
|
||||
|
||||
<div class="col-start-2 col-span-2 text-wp-text-100">
|
||||
<div v-if="pipeline" class="flex gap-2 items-center">
|
||||
<span class="whitespace-nowrap overflow-hidden overflow-ellipsis">{{ shortMessage }}</span>
|
||||
<span class="ml-auto hidden sm:inline-block flex-shrink-0">{{ since }}</span>
|
||||
</div>
|
||||
|
||||
<div v-else class="flex gap-2">
|
||||
<span>{{ $t('repo.pipeline.no_pipelines') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { toRef } from 'vue';
|
||||
|
||||
import Badge from '~/components/atomic/Badge.vue';
|
||||
import PipelineStatusIcon from '~/components/repo/pipeline/PipelineStatusIcon.vue';
|
||||
import usePipeline from '~/compositions/usePipeline';
|
||||
import type { Repo } from '~/lib/api/types';
|
||||
import { RepoVisibility } from '~/lib/api/types';
|
||||
|
||||
const props = defineProps<{
|
||||
repo: Repo;
|
||||
}>();
|
||||
|
||||
const repo = props.repo;
|
||||
const pipeline = toRef(repo.last_pipeline);
|
||||
const { since, shortMessage } = usePipeline(pipeline);
|
||||
</script>
|
||||
@@ -19,7 +19,7 @@ const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: '',
|
||||
name: 'repos',
|
||||
component: (): Component => import('~/views/RepoList.vue'),
|
||||
component: (): Component => import('~/views/Repos.vue'),
|
||||
meta: { authentication: 'required' },
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
<template>
|
||||
<Scaffold v-model:search="search">
|
||||
<template #title>
|
||||
{{ $t('repositories') }}
|
||||
</template>
|
||||
|
||||
<template #titleActions>
|
||||
<Button :to="{ name: 'repo-add' }" start-icon="plus" :text="$t('repo.add')" />
|
||||
</template>
|
||||
|
||||
<div class="flex flex-col gap-12">
|
||||
<div class="gap-4 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2">
|
||||
<RepoListItem v-for="repo in repoListAccess" :key="repo.id" :repo="repo" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
<RepoListItem v-for="repo in repoListActivity" :key="repo.id" :repo="repo" />
|
||||
</div>
|
||||
</div>
|
||||
</Scaffold>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import Button from '~/components/atomic/Button.vue';
|
||||
import Scaffold from '~/components/layout/scaffold/Scaffold.vue';
|
||||
import RepoListItem from '~/components/repo/RepoListItem.vue';
|
||||
import useRepos from '~/compositions/useRepos';
|
||||
import { useRepoSearch } from '~/compositions/useRepoSearch';
|
||||
import { useRepoStore } from '~/store/repos';
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const repoStore = useRepoStore();
|
||||
const repos = computed(() => Object.values(repoStore.ownedRepos));
|
||||
const search = ref('');
|
||||
|
||||
const { searchedRepos } = useRepoSearch(repos, search);
|
||||
const { sortReposByLastAccess, sortReposByLastActivity } = useRepos();
|
||||
|
||||
const repoListAccess = computed(() => sortReposByLastAccess(repos.value || []));
|
||||
const repoListActivity = computed(() => sortReposByLastActivity(searchedRepos.value || []));
|
||||
|
||||
router.beforeEach(async () => {
|
||||
await repoStore.loadRepos();
|
||||
});
|
||||
</script>
|
||||
@@ -10,60 +10,40 @@
|
||||
|
||||
<div class="flex flex-col gap-12">
|
||||
<div class="gap-4 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2">
|
||||
<router-link v-for="repo in repoListAccess" :key="repo.id" :to="{ name: 'repo', params: { repoId: repo.id } }">
|
||||
<div
|
||||
class="flex flex-col border rounded-md bg-wp-background-100 overflow-hidden p-4 border-wp-background-400 dark:bg-wp-background-200 cursor-pointer hover:shadow-md hover:bg-wp-background-300 dark:hover:bg-wp-background-300"
|
||||
>
|
||||
<div class="flex items-center gap-4">
|
||||
<img v-if="repo.avatar_url" :src="repo.avatar_url" class="w-8 h-8 rounded-md" alt="..." />
|
||||
<Icon v-else name="repo" class="text-wp-text-100" />
|
||||
<span class="text-wp-text-100 text-lg">{{ `${repo.owner} / ${repo.name}` }}</span>
|
||||
<Badge v-if="repo.visibility === RepoVisibility.Public" :label="$t('repo.settings.general.visibility.public.public')" class="ml-auto" />
|
||||
</div>
|
||||
</div>
|
||||
</router-link>
|
||||
<RepoItems v-for="repo in repoListAccess" :key="repo.id" :repo="repo" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
<router-link v-for="repo in searchedRepos" :key="repo.id" :to="{ name: 'repo', params: { repoId: repo.id } }">
|
||||
<div
|
||||
class="flex flex-col border rounded-md bg-wp-background-100 overflow-hidden p-4 border-wp-background-400 dark:bg-wp-background-200 cursor-pointer hover:shadow-md hover:bg-wp-background-300 dark:hover:bg-wp-background-300"
|
||||
>
|
||||
<div class="flex items-center gap-4">
|
||||
<img v-if="repo.avatar_url" :src="repo.avatar_url" class="w-8 h-8 rounded-md" alt="..." />
|
||||
<Icon v-else name="repo" class="text-wp-text-100" />
|
||||
<span class="text-wp-text-100 text-lg">{{ `${repo.owner} / ${repo.name}` }}</span>
|
||||
<Badge v-if="repo.visibility === RepoVisibility.Public" :label="$t('repo.settings.general.visibility.public.public')" class="ml-auto" />
|
||||
</div>
|
||||
</div>
|
||||
</router-link>
|
||||
<RepoItems v-for="repo in repoListActivity" :key="repo.id" :repo="repo" />
|
||||
</div>
|
||||
</div>
|
||||
</Scaffold>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import Badge from '~/components/atomic/Badge.vue';
|
||||
import Button from '~/components/atomic/Button.vue';
|
||||
import Icon from '~/components/atomic/Icon.vue';
|
||||
import Scaffold from '~/components/layout/scaffold/Scaffold.vue';
|
||||
import RepoItems from '~/components/repo/RepoItems.vue';
|
||||
import useRepos from '~/compositions/useRepos';
|
||||
import { useRepoSearch } from '~/compositions/useRepoSearch';
|
||||
import { RepoVisibility } from '~/lib/api/types';
|
||||
import { useRepoStore } from '~/store/repos';
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const repoStore = useRepoStore();
|
||||
const repos = computed(() => Object.values(repoStore.ownedRepos));
|
||||
const search = ref('');
|
||||
|
||||
const { searchedRepos } = useRepoSearch(repos, search);
|
||||
const { sortReposByLastAccess } = useRepos();
|
||||
const { sortReposByLastAccess, sortReposByLastActivity } = useRepos();
|
||||
|
||||
const repoListAccess = computed(() => sortReposByLastAccess(repos.value || []));
|
||||
const repoListActivity = computed(() => sortReposByLastActivity(searchedRepos.value || []));
|
||||
|
||||
onMounted(async () => {
|
||||
router.beforeEach(async () => {
|
||||
await repoStore.loadRepos();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -14,9 +14,7 @@
|
||||
</template>
|
||||
|
||||
<div class="space-y-4">
|
||||
<ListItem v-for="repo in searchedRepos" :key="repo.id" :to="{ name: 'repo', params: { repoId: repo.id } }">
|
||||
<span class="text-wp-text-100">{{ `${repo.owner} / ${repo.name}` }}</span>
|
||||
</ListItem>
|
||||
<RepoItems v-for="repo in searchedRepos" :key="repo.id" :repo="repo" />
|
||||
</div>
|
||||
<div v-if="(searchedRepos || []).length <= 0" class="text-center">
|
||||
<span class="text-wp-text-100 m-auto">{{ $t('repo.user_none') }}</span>
|
||||
@@ -28,7 +26,7 @@
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
|
||||
import IconButton from '~/components/atomic/IconButton.vue';
|
||||
import ListItem from '~/components/atomic/ListItem.vue';
|
||||
import RepoItems from '~/components/repo/RepoItems.vue';
|
||||
import Scaffold from '~/components/layout/scaffold/Scaffold.vue';
|
||||
import { inject } from '~/compositions/useInjectProvide';
|
||||
import { useRepoSearch } from '~/compositions/useRepoSearch';
|
||||
|
||||
Reference in New Issue
Block a user