diff --git a/frontend/src/components/Pager.vue b/frontend/src/components/Pager.vue new file mode 100644 index 0000000..c738ced --- /dev/null +++ b/frontend/src/components/Pager.vue @@ -0,0 +1,113 @@ + + + + + diff --git a/frontend/src/stores/nodes.ts b/frontend/src/stores/nodes.ts index 03ebd63..9af5242 100644 --- a/frontend/src/stores/nodes.ts +++ b/frontend/src/stores/nodes.ts @@ -4,6 +4,8 @@ import {internalApi} from "@/utils/Api"; interface NodesStoreState { nodes: EnhancedNode[]; + page: number; + nodesPerPage: number; totalNodes: number; } @@ -12,6 +14,8 @@ export const useNodesStore = defineStore({ state(): NodesStoreState { return { nodes: [], + page: 1, + nodesPerPage: 20, totalNodes: 0, }; }, @@ -22,16 +26,29 @@ export const useNodesStore = defineStore({ getTotalNodes(state: NodesStoreState): number { return state.totalNodes; - } + }, + + getNodesPerPage(state: NodesStoreState): number { + return state.nodesPerPage + }, + + getPage(state: NodesStoreState): number { + return state.page + }, }, actions: { - async refresh(): Promise { + async refresh(page: number, nodesPerPage: number): Promise { + // TODO: Handle paging const result = await internalApi.getPagedList( "nodes", - isEnhancedNode + isEnhancedNode, + page, + nodesPerPage, ); this.nodes = result.entries; this.totalNodes = result.total; + this.page = page; + this.nodesPerPage = nodesPerPage; }, }, }); diff --git a/frontend/src/utils/Api.ts b/frontend/src/utils/Api.ts index a7308ea..2e437a2 100644 --- a/frontend/src/utils/Api.ts +++ b/frontend/src/utils/Api.ts @@ -23,12 +23,22 @@ class Api { } } - private toURL(path: string): string { - return this.baseURL + this.apiPrefix + path; + private toURL(path: string, queryParams?: object): string { + let queryString = ""; + if (queryParams) { + const queryStrings: string[] = []; + for (const [key, value] of Object.entries(queryParams)) { + queryStrings.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`); + } + if (queryStrings.length > 0) { + queryString = `?${queryStrings.join("&")}`; + } + } + return this.baseURL + this.apiPrefix + path + queryString; } - private async doGet(path: string, isT: TypeGuard): Promise> { - const url = this.toURL(path); + private async doGet(path: string, isT: TypeGuard, queryParams?: object): Promise> { + const url = this.toURL(path, queryParams); const result = await fetch(url); const json = await result.json(); @@ -48,8 +58,16 @@ class Api { return response.result; } - async getPagedList(path: string, isT: TypeGuard): Promise> { - const response = await this.doGet(path, toIsArray(isT)); + async getPagedList( + path: string, + isT: TypeGuard, + page: number, + itemsPerPage: number, + ): Promise> { + const response = await this.doGet(path, toIsArray(isT), { + _page: page, + _perPage: itemsPerPage, + }); const totalStr = response.headers.get("x-total-count"); const total = parseInteger(totalStr, 10); diff --git a/frontend/src/views/AdminNodesView.vue b/frontend/src/views/AdminNodesView.vue index 29fda3c..7373ad2 100644 --- a/frontend/src/views/AdminNodesView.vue +++ b/frontend/src/views/AdminNodesView.vue @@ -1,19 +1,19 @@