diff options
Diffstat (limited to 'app/assets/javascripts/jobs/components/table/jobs_table_app.vue')
-rw-r--r-- | app/assets/javascripts/jobs/components/table/jobs_table_app.vue | 81 |
1 files changed, 68 insertions, 13 deletions
diff --git a/app/assets/javascripts/jobs/components/table/jobs_table_app.vue b/app/assets/javascripts/jobs/components/table/jobs_table_app.vue index cf7970f41b1..2061b1f1eb2 100644 --- a/app/assets/javascripts/jobs/components/table/jobs_table_app.vue +++ b/app/assets/javascripts/jobs/components/table/jobs_table_app.vue @@ -1,6 +1,7 @@ <script> -import { GlAlert, GlSkeletonLoader } from '@gitlab/ui'; +import { GlAlert, GlPagination, GlSkeletonLoader } from '@gitlab/ui'; import { __ } from '~/locale'; +import { GRAPHQL_PAGE_SIZE, initialPaginationState } from './constants'; import GetJobs from './graphql/queries/get_jobs.query.graphql'; import JobsTable from './jobs_table.vue'; import JobsTableEmptyState from './jobs_table_empty_state.vue'; @@ -12,6 +13,7 @@ export default { }, components: { GlAlert, + GlPagination, GlSkeletonLoader, JobsTable, JobsTableEmptyState, @@ -28,10 +30,18 @@ export default { variables() { return { fullPath: this.fullPath, + first: this.pagination.first, + last: this.pagination.last, + after: this.pagination.nextPageCursor, + before: this.pagination.prevPageCursor, }; }, - update({ project }) { - return project?.jobs?.nodes || []; + update(data) { + const { jobs: { nodes: list = [], pageInfo = {} } = {} } = data.project || {}; + return { + list, + pageInfo, + }; }, error() { this.hasError = true; @@ -40,10 +50,11 @@ export default { }, data() { return { - jobs: null, + jobs: {}, hasError: false, isAlertDismissed: false, scope: null, + pagination: initialPaginationState, }; }, computed: { @@ -51,7 +62,16 @@ export default { return this.hasError && !this.isAlertDismissed; }, showEmptyState() { - return this.jobs.length === 0 && !this.scope; + return this.jobs.list.length === 0 && !this.scope; + }, + prevPage() { + return Math.max(this.pagination.currentPage - 1, 0); + }, + nextPage() { + return this.jobs.pageInfo?.hasNextPage ? this.pagination.currentPage + 1 : null; + }, + showPaginationControls() { + return Boolean(this.prevPage || this.nextPage) && !this.$apollo.loading; }, }, methods: { @@ -60,6 +80,24 @@ export default { this.$apollo.queries.jobs.refetch({ statuses: scope }); }, + handlePageChange(page) { + const { startCursor, endCursor } = this.jobs.pageInfo; + + if (page > this.pagination.currentPage) { + this.pagination = { + ...initialPaginationState, + nextPageCursor: endCursor, + currentPage: page, + }; + } else { + this.pagination = { + last: GRAPHQL_PAGE_SIZE, + first: null, + prevPageCursor: startCursor, + currentPage: page, + }; + } + }, }, }; </script> @@ -79,17 +117,34 @@ export default { <jobs-table-tabs @fetchJobsByStatus="fetchJobsByStatus" /> <div v-if="$apollo.loading" class="gl-mt-5"> - <gl-skeleton-loader - preserve-aspect-ratio="none" - equal-width-lines - :lines="5" - :width="600" - :height="66" - /> + <gl-skeleton-loader :width="1248" :height="73"> + <circle cx="748.031" cy="37.7193" r="15.0307" /> + <circle cx="787.241" cy="37.7193" r="15.0307" /> + <circle cx="827.759" cy="37.7193" r="15.0307" /> + <circle cx="866.969" cy="37.7193" r="15.0307" /> + <circle cx="380" cy="37" r="18" /> + <rect x="432" y="19" width="126.587" height="15" /> + <rect x="432" y="41" width="247" height="15" /> + <rect x="158" y="19" width="86.1" height="15" /> + <rect x="158" y="41" width="168" height="15" /> + <rect x="22" y="19" width="96" height="36" /> + <rect x="924" y="30" width="96" height="15" /> + <rect x="1057" y="20" width="166" height="35" /> + </gl-skeleton-loader> </div> <jobs-table-empty-state v-else-if="showEmptyState" /> - <jobs-table v-else :jobs="jobs" /> + <jobs-table v-else :jobs="jobs.list" /> + + <gl-pagination + v-if="showPaginationControls" + :value="pagination.currentPage" + :prev-page="prevPage" + :next-page="nextPage" + align="center" + class="gl-mt-3" + @input="handlePageChange" + /> </div> </template> |