improve pagination

This commit is contained in:
Anbraten 2024-04-17 11:37:19 +02:00
parent d316e3c5cb
commit 3880844a79
6 changed files with 69 additions and 22 deletions

View file

@ -7,8 +7,8 @@
</p>
<br/>
<p align="center">
<a href="https://ci.woodpecker-ci.org/repos/3780" title="Build Status">
<img src="https://ci.woodpecker-ci.org/api/badges/3780/status.svg" alt="Build Status">
<a href="https://ci.woodpecker-ci.org/repos/3780" title="Pipeline Status">
<img src="https://ci.woodpecker-ci.org/api/badges/3780/status.svg" alt="Pipeline Status">
</a>
<a href="https://codecov.io/gh/woodpecker-ci/woodpecker">
<img src="https://codecov.io/gh/woodpecker-ci/woodpecker/branch/main/graph/badge.svg" alt="Code coverage">

1
web/components.d.ts vendored
View file

@ -85,6 +85,7 @@ declare module 'vue' {
Navbar: typeof import('./src/components/layout/header/Navbar.vue')['default']
NumberField: typeof import('./src/components/form/NumberField.vue')['default']
OrgSecretsTab: typeof import('./src/components/org/settings/OrgSecretsTab.vue')['default']
Pagination: typeof import('./src/components/layout/Pagination.vue')['default']
Panel: typeof import('./src/components/layout/Panel.vue')['default']
PipelineFeedItem: typeof import('./src/components/pipeline-feed/PipelineFeedItem.vue')['default']
PipelineFeedSidebar: typeof import('./src/components/pipeline-feed/PipelineFeedSidebar.vue')['default']

View file

@ -0,0 +1,38 @@
<template>
<div>
<div v-if="loading">loading ...</div>
<div v-else>
<slot />
</div>
<Button v-if="hasMore" :is-loading="loading" text="Load more" class="mx-auto mt-4" @click="nextPage" />
</div>
</template>
<script lang="ts" setup>
import { computed, nextTick } from 'vue';
import Button from '~/components/atomic/Button.vue';
import { usePagination } from '~/compositions/usePaginate';
const props = defineProps<{
pagination: ReturnType<typeof usePagination>;
}>();
const loading = computed(() => props.pagination.loading.value);
const hasMore = computed(() => props.pagination.hasMore.value);
function scrollDown() {
window.scrollTo({
top: document.body.scrollHeight,
behavior: 'smooth',
});
}
function nextPage() {
props.pagination.nextPage();
nextTick(() => {
setTimeout(scrollDown, 100);
});
}
</script>

View file

@ -14,14 +14,15 @@
<Button v-else :text="$t('repo.settings.secrets.add')" start-icon="plus" @click="showAddSecret" />
</template>
<SecretList
v-if="!selectedSecret"
:model-value="secrets"
i18n-prefix="repo.settings.secrets."
:is-deleting="isDeleting"
@edit="editSecret"
@delete="deleteSecret"
/>
<Pagination v-if="!selectedSecret" :pagination="secretsPagination">
<SecretList
:model-value="secrets"
i18n-prefix="repo.settings.secrets."
:is-deleting="isDeleting"
@edit="editSecret"
@delete="deleteSecret"
/>
</Pagination>
<SecretEdit
v-else
@ -81,9 +82,12 @@ async function loadSecrets(page: number, level: 'repo' | 'org' | 'global'): Prom
}
}
const { resetPage, data: _secrets } = usePagination(loadSecrets, () => !selectedSecret.value, {
const secretsPagination = usePagination(loadSecrets, () => !selectedSecret.value, {
each: ['repo', 'org', 'global'],
scrollElement: null,
pageSize: 50,
});
const { resetPage, data: _secrets } = secretsPagination;
const secrets = computed(() => {
const secretsList: Record<string, Secret & { edit?: boolean; level: 'repo' | 'org' | 'global' }> = {};

View file

@ -18,11 +18,15 @@ export async function usePaginate<T>(getSingle: (page: number) => Promise<T[]>):
export function usePagination<T, S = unknown>(
_loadData: (page: number, arg: S) => Promise<T[] | null>,
isActive: () => boolean = () => true,
{ scrollElement: _scrollElement, each: _each }: { scrollElement?: Ref<HTMLElement | null>; each?: S[] } = {},
{
scrollElement: _scrollElement,
each: _each,
pageSize: _pageSize,
}: { scrollElement?: Ref<HTMLElement | null> | null; each?: S[]; pageSize?: number } = {},
) {
const scrollElement = _scrollElement ?? ref(document.getElementById('scroll-component'));
const scrollElement = _scrollElement === null ? null : ref(document.getElementById('scroll-component'));
const page = ref(1);
const pageSize = ref(0);
const pageSize = ref(_pageSize ?? 0);
const hasMore = ref(true);
const data = ref<T[]>([]) as Ref<T[]>;
const loading = ref(false);
@ -33,8 +37,6 @@ export function usePagination<T, S = unknown>(
return;
}
console.log('loadData', page.value, each.value);
loading.value = true;
const newData = (await _loadData(page.value, each.value?.[0] as S)) ?? [];
hasMore.value = newData.length >= pageSize.value && newData.length > 0;
@ -42,14 +44,14 @@ export function usePagination<T, S = unknown>(
data.value.push(...newData);
}
console.log('loadData1', page.value, hasMore.value, each.value);
console.log('loadData', each.value?.[0], page.value);
// last page and each has more
if (!hasMore.value && each.value.length > 0) {
// use next each element
each.value.shift();
page.value = 1;
pageSize.value = 0;
pageSize.value = _pageSize ?? 0;
hasMore.value = each.value.length > 0;
if (hasMore.value) {
loading.value = false;
@ -69,13 +71,15 @@ export function usePagination<T, S = unknown>(
}
}
useInfiniteScroll(scrollElement, nextPage, { distance: 10 });
if (scrollElement !== null) {
useInfiniteScroll(scrollElement, nextPage, { distance: 10 });
}
async function resetPage() {
const _page = page.value;
page.value = 1;
pageSize.value = 0;
pageSize.value = _pageSize ?? 0;
hasMore.value = true;
data.value = [];
loading.value = false;

View file

@ -20,7 +20,7 @@
<Tab id="secrets" :title="$t('repo.settings.secrets.secrets')">
<SecretsTab />
</Tab>
<Tab id="registries" :title="$t('repo.settings.registries.registries')">
<!-- <Tab id="registries" :title="$t('repo.settings.registries.registries')">
<RegistriesTab />
</Tab>
<Tab id="crons" :title="$t('repo.settings.crons.crons')">
@ -31,7 +31,7 @@
</Tab>
<Tab id="actions" :title="$t('repo.settings.actions.actions')">
<ActionsTab />
</Tab>
</Tab> -->
</Scaffold>
</template>