Pin page size (#3946)

Co-authored-by: Lauris BH <lauris@nix.lv>
This commit is contained in:
qwerty287 2024-07-21 09:27:24 +02:00 committed by GitHub
parent 8a277e7bd9
commit 0c98f49b1e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 23 additions and 8 deletions

View file

@ -48,6 +48,10 @@ For reference see [Configuration Cheat Sheet](https://docs.gitea.io/en-us/config
![gitea oauth setup](gitea_oauth.gif) ![gitea oauth setup](gitea_oauth.gif)
:::warning
Make sure your Gitea configuration allows requesting the API with a fixed page length of 50. The default value for the maximum page size is 50, but if you set a value lower than 50, some Woodpecker features will not work properly. Also see the [Configuration Cheat Sheet](https://docs.gitea.com/administration/config-cheat-sheet#api-api).
:::
## Configuration ## Configuration
This is a full list of configuration options. Please note that many of these options use default configuration values that should work for the majority of installations. This is a full list of configuration options. Please note that many of these options use default configuration values that should work for the majority of installations.

View file

@ -50,6 +50,10 @@ For reference see [Configuration Cheat Sheet](https://forgejo.org/docs/latest/ad
![forgejo oauth setup](gitea_oauth.gif) ![forgejo oauth setup](gitea_oauth.gif)
:::warning
Make sure your Forgejo configuration allows requesting the API with a fixed page length of 50. The default value for the maximum page size is 50, but if you set a value lower than 50, some Woodpecker features will not work properly. Also see the [Configuration Cheat Sheet](https://forgejo.org/docs/latest/admin/config-cheat-sheet/#api-api).
:::
## Configuration ## Configuration
This is a full list of configuration options. Please note that many of these options use default configuration values that should work for the majority of installations. This is a full list of configuration options. Please note that many of these options use default configuration values that should work for the majority of installations.

View file

@ -72,7 +72,6 @@ async function loadSecrets(page: number, level: 'repo' | 'org' | 'global'): Prom
const { resetPage, data: _secrets } = usePagination(loadSecrets, () => !selectedSecret.value, { const { resetPage, data: _secrets } = usePagination(loadSecrets, () => !selectedSecret.value, {
each: ['repo', 'org', 'global'], each: ['repo', 'org', 'global'],
pageSize: 50,
}); });
const secrets = computed(() => { const secrets = computed(() => {
const secretsList: Record<string, Secret & { edit?: boolean; level: 'repo' | 'org' | 'global' }> = {}; const secretsList: Record<string, Secret & { edit?: boolean; level: 'repo' | 'org' | 'global' }> = {};

View file

@ -48,6 +48,7 @@ describe('usePaginate', () => {
usePaginationComposition = usePagination<{ name: string }>( usePaginationComposition = usePagination<{ name: string }>(
async (page) => repoSecrets[page - 1], async (page) => repoSecrets[page - 1],
() => true, () => true,
{ pageSize: 3 },
); );
}); });
await waitForState(usePaginationComposition.loading, true); await waitForState(usePaginationComposition.loading, true);
@ -63,6 +64,7 @@ describe('usePaginate', () => {
usePaginationComposition = usePagination<{ name: string }>( usePaginationComposition = usePagination<{ name: string }>(
async (page) => repoSecrets[page - 1], async (page) => repoSecrets[page - 1],
() => true, () => true,
{ pageSize: 3 },
); );
}); });
await waitForState(usePaginationComposition.loading, true); await waitForState(usePaginationComposition.loading, true);
@ -86,7 +88,7 @@ describe('usePaginate', () => {
return orgSecrets[page - 1]; return orgSecrets[page - 1];
}, },
() => true, () => true,
{ each: ['repo', 'org'] }, { each: ['repo', 'org'], pageSize: 3 },
); );
}); });
await waitForState(usePaginationComposition.loading, true); await waitForState(usePaginationComposition.loading, true);
@ -111,6 +113,7 @@ describe('usePaginate', () => {
usePaginationComposition = usePagination<{ name: string }>( usePaginationComposition = usePagination<{ name: string }>(
async (page) => repoSecrets[page - 1], async (page) => repoSecrets[page - 1],
() => true, () => true,
{ pageSize: 3 },
); );
}); });
await waitForState(usePaginationComposition.loading, true); await waitForState(usePaginationComposition.loading, true);
@ -132,6 +135,7 @@ describe('usePaginate', () => {
usePaginationComposition = usePagination<{ name: string }>( usePaginationComposition = usePagination<{ name: string }>(
async (page) => repoSecrets[page - 1], async (page) => repoSecrets[page - 1],
() => true, () => true,
{ pageSize: 3 },
); );
}); });
await waitForState(usePaginationComposition.loading, true); await waitForState(usePaginationComposition.loading, true);

View file

@ -1,19 +1,26 @@
import { useInfiniteScroll } from '@vueuse/core'; import { useInfiniteScroll } from '@vueuse/core';
import { onMounted, ref, watch, type Ref, type UnwrapRef } from 'vue'; import { onMounted, ref, watch, type Ref, type UnwrapRef } from 'vue';
export async function usePaginate<T>(getSingle: (page: number) => Promise<T[]>): Promise<T[]> { const defaultPageSize = 50;
// usePaginate loads all pages
export async function usePaginate<T>(
getSingle: (page: number) => Promise<T[]>,
pageSize: number = defaultPageSize,
): Promise<T[]> {
let hasMore = true; let hasMore = true;
let page = 1; let page = 1;
const result: T[] = []; const result: T[] = [];
while (hasMore) { while (hasMore) {
const singleRes = await getSingle(page); const singleRes = await getSingle(page);
result.push(...singleRes); result.push(...singleRes);
hasMore = singleRes.length !== 0; hasMore = singleRes.length >= pageSize;
page += 1; page += 1;
} }
return result; return result;
} }
// usePagination loads pages on demand
export function usePagination<T, S = unknown>( export function usePagination<T, S = unknown>(
_loadData: (page: number, arg: S) => Promise<T[] | null>, _loadData: (page: number, arg: S) => Promise<T[] | null>,
isActive: () => boolean = () => true, isActive: () => boolean = () => true,
@ -25,7 +32,7 @@ export function usePagination<T, S = unknown>(
) { ) {
const scrollElement = _scrollElement === null ? null : ref(document.getElementById('scroll-component')); const scrollElement = _scrollElement === null ? null : ref(document.getElementById('scroll-component'));
const page = ref(1); const page = ref(1);
const pageSize = ref(_pageSize ?? 0); const pageSize = ref(_pageSize ?? defaultPageSize);
const hasMore = ref(true); const hasMore = ref(true);
const data = ref<T[]>([]) as Ref<T[]>; const data = ref<T[]>([]) as Ref<T[]>;
const loading = ref(false); const loading = ref(false);
@ -48,14 +55,12 @@ export function usePagination<T, S = unknown>(
// use next each element // use next each element
each.value.shift(); each.value.shift();
page.value = 1; page.value = 1;
pageSize.value = _pageSize ?? 0;
hasMore.value = each.value.length > 0; hasMore.value = each.value.length > 0;
if (hasMore.value) { if (hasMore.value) {
loading.value = false; loading.value = false;
await loadData(); await loadData();
} }
} }
pageSize.value = newData.length;
loading.value = false; loading.value = false;
} }
@ -76,7 +81,6 @@ export function usePagination<T, S = unknown>(
const _page = page.value; const _page = page.value;
page.value = 1; page.value = 1;
pageSize.value = _pageSize ?? 0;
hasMore.value = true; hasMore.value = true;
data.value = []; data.value = [];
loading.value = false; loading.value = false;