From bd7473363226720cb7d1778e78082f1f8ea86166 Mon Sep 17 00:00:00 2001 From: kolaente Date: Thu, 4 Sep 2025 18:04:05 +0200 Subject: [PATCH] fix: show pagination controls for task comments (#1413) Resolves https://community.vikunja.io/t/task-comment-pagination-in-1-0-0-rc1/3988 --- .../e2e/task/comment-pagination.spec.ts | 34 +++++++++++++++++++ .../components/tasks/partials/Comments.vue | 16 ++++++--- frontend/src/stores/config.ts | 2 ++ pkg/routes/api/v1/info.go | 2 ++ 4 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 frontend/cypress/e2e/task/comment-pagination.spec.ts diff --git a/frontend/cypress/e2e/task/comment-pagination.spec.ts b/frontend/cypress/e2e/task/comment-pagination.spec.ts new file mode 100644 index 000000000..42901ee40 --- /dev/null +++ b/frontend/cypress/e2e/task/comment-pagination.spec.ts @@ -0,0 +1,34 @@ +import {createFakeUserAndLogin} from '../../support/authenticateUser' +import {ProjectFactory} from '../../factories/project' +import {TaskFactory} from '../../factories/task' +import {TaskCommentFactory} from '../../factories/task_comment' +import {createDefaultViews} from '../project/prepareProjects' + +describe('Task comment pagination', () => { + createFakeUserAndLogin() + + beforeEach(() => { + ProjectFactory.create(1) + createDefaultViews(1) + TaskFactory.create(1, {id: 1}) + TaskCommentFactory.truncate() + }) + + it('shows pagination when more comments than configured page size', () => { + cy.request(`${Cypress.env('API_URL')}/info`).then((response) => { + const pageSize = response.body.max_items_per_page + TaskCommentFactory.create(pageSize + 10) + cy.visit('/tasks/1') + cy.get('.task-view .comments nav.pagination').should('exist') + }) + }) + + it('hides pagination when comments equal or fewer than configured page size', () => { + cy.request(`${Cypress.env('API_URL')}/info`).then((response) => { + const pageSize = response.body.max_items_per_page + TaskCommentFactory.create(Math.max(1, pageSize - 10)) + cy.visit('/tasks/1') + cy.get('.task-view .comments nav.pagination').should('not.exist') + }) + }) +}) diff --git a/frontend/src/components/tasks/partials/Comments.vue b/frontend/src/components/tasks/partials/Comments.vue index 11b06a260..c48c8840d 100644 --- a/frontend/src/components/tasks/partials/Comments.vue +++ b/frontend/src/components/tasks/partials/Comments.vue @@ -299,6 +299,7 @@ const currentPage = ref(1) const commentsRef = ref(null) + async function attachmentUpload(files: File[] | FileList): (Promise) { const uploadPromises: Promise[] = [] @@ -321,12 +322,19 @@ async function loadComments(taskId: ITask['id']) { return } + if (currentPage.value === 1) { + taskCommentService.totalPages = 0 + taskCommentService.resultCount = 0 + } + commentEdit.taskId = taskId commentToDelete.taskId = taskId - - if(typeof props.initialComments !== 'undefined' && currentPage.value === 1) { - comments.value = props.initialComments - return + + if (typeof props.initialComments !== 'undefined' && currentPage.value === 1) { + if (props.initialComments.length < configStore.maxItemsPerPage) { + comments.value = props.initialComments + return + } } comments.value = await taskCommentService.getAll({taskId}, {}, currentPage.value) diff --git a/frontend/src/stores/config.ts b/frontend/src/stores/config.ts index aae73f3c5..f759b07df 100644 --- a/frontend/src/stores/config.ts +++ b/frontend/src/stores/config.ts @@ -15,6 +15,7 @@ export interface ConfigState { motd: string, linkSharingEnabled: boolean, maxFileSize: string, + maxItemsPerPage: number, availableMigrators: Array, taskAttachmentsEnabled: boolean, totpEnabled: boolean, @@ -52,6 +53,7 @@ export const useConfigStore = defineStore('config', () => { motd: '', linkSharingEnabled: true, maxFileSize: '20MB', + maxItemsPerPage: 50, availableMigrators: [], taskAttachmentsEnabled: true, totpEnabled: true, diff --git a/pkg/routes/api/v1/info.go b/pkg/routes/api/v1/info.go index ddd0a2075..3bd8f4956 100644 --- a/pkg/routes/api/v1/info.go +++ b/pkg/routes/api/v1/info.go @@ -38,6 +38,7 @@ type vikunjaInfos struct { Motd string `json:"motd"` LinkSharingEnabled bool `json:"link_sharing_enabled"` MaxFileSize string `json:"max_file_size"` + MaxItemsPerPage int `json:"max_items_per_page"` AvailableMigrators []string `json:"available_migrators"` TaskAttachmentsEnabled bool `json:"task_attachments_enabled"` EnabledBackgroundProviders []string `json:"enabled_background_providers"` @@ -92,6 +93,7 @@ func Info(c echo.Context) error { Motd: config.ServiceMotd.GetString(), LinkSharingEnabled: config.ServiceEnableLinkSharing.GetBool(), MaxFileSize: config.FilesMaxSize.GetString(), + MaxItemsPerPage: config.ServiceMaxItemsPerPage.GetInt(), TaskAttachmentsEnabled: config.ServiceEnableTaskAttachments.GetBool(), TotpEnabled: config.ServiceEnableTotp.GetBool(), CaldavEnabled: config.ServiceEnableCaldav.GetBool(),