diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-02-23 03:18:11 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-02-23 03:18:11 +0300 |
commit | 6adb784bf2839a2b8a73de5602cbfe617836526c (patch) | |
tree | 164af2f582f674ef9ae06ab284cccf330e16b339 /app/assets/javascripts/jobs | |
parent | beeaef0da5d29621b12c54724a2eb2bf981407c9 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/jobs')
5 files changed, 68 insertions, 61 deletions
diff --git a/app/assets/javascripts/jobs/components/table/constants.js b/app/assets/javascripts/jobs/components/table/constants.js index 962979ba573..951d9324813 100644 --- a/app/assets/javascripts/jobs/components/table/constants.js +++ b/app/assets/javascripts/jobs/components/table/constants.js @@ -1,16 +1,6 @@ import { s__, __ } from '~/locale'; import { DEFAULT_TH_CLASSES } from '~/lib/utils/constants'; -export const GRAPHQL_PAGE_SIZE = 30; - -export const initialPaginationState = { - currentPage: 1, - prevPageCursor: '', - nextPageCursor: '', - first: GRAPHQL_PAGE_SIZE, - last: null, -}; - /* Error constants */ export const POST_FAILURE = 'post_failure'; export const DEFAULT = 'default'; diff --git a/app/assets/javascripts/jobs/components/table/graphql/cache_config.js b/app/assets/javascripts/jobs/components/table/graphql/cache_config.js new file mode 100644 index 00000000000..846efdf21ee --- /dev/null +++ b/app/assets/javascripts/jobs/components/table/graphql/cache_config.js @@ -0,0 +1,29 @@ +import { isEqual } from 'lodash'; + +export default { + typePolicies: { + Project: { + fields: { + jobs: { + keyArgs: false, + }, + }, + }, + CiJobConnection: { + merge(existing = {}, incoming, { args = {} }) { + let nodes; + + if (Object.keys(existing).length !== 0 && isEqual(existing?.statuses, args?.statuses)) { + nodes = [...existing.nodes, ...incoming.nodes]; + } else { + nodes = [...incoming.nodes]; + } + + return { + nodes, + statuses: Array.isArray(args.statuses) ? [...args.statuses] : args.statuses, + }; + }, + }, + }, +}; diff --git a/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql b/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql index 88937185a8c..151e49af87e 100644 --- a/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql +++ b/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql @@ -1,25 +1,22 @@ -query getJobs( - $fullPath: ID! - $first: Int - $last: Int - $after: String - $before: String - $statuses: [CiJobStatus!] -) { +query getJobs($fullPath: ID!, $after: String, $statuses: [CiJobStatus!]) { project(fullPath: $fullPath) { id - jobs(after: $after, before: $before, first: $first, last: $last, statuses: $statuses) { + __typename + jobs(after: $after, first: 30, statuses: $statuses) { pageInfo { endCursor hasNextPage hasPreviousPage startCursor + __typename } nodes { + __typename artifacts { nodes { downloadPath fileType + __typename } } allowFailure diff --git a/app/assets/javascripts/jobs/components/table/index.js b/app/assets/javascripts/jobs/components/table/index.js index f24daf90815..1b9c7cdcfdd 100644 --- a/app/assets/javascripts/jobs/components/table/index.js +++ b/app/assets/javascripts/jobs/components/table/index.js @@ -4,12 +4,18 @@ import VueApollo from 'vue-apollo'; import JobsTableApp from '~/jobs/components/table/jobs_table_app.vue'; import createDefaultClient from '~/lib/graphql'; import { parseBoolean } from '~/lib/utils/common_utils'; +import cacheConfig from './graphql/cache_config'; Vue.use(VueApollo); Vue.use(GlToast); const apolloProvider = new VueApollo({ - defaultClient: createDefaultClient(), + defaultClient: createDefaultClient( + {}, + { + cacheConfig, + }, + ), }); export default (containerId = 'js-jobs-table') => { 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 81f42c1e293..864e322eecd 100644 --- a/app/assets/javascripts/jobs/components/table/jobs_table_app.vue +++ b/app/assets/javascripts/jobs/components/table/jobs_table_app.vue @@ -1,7 +1,6 @@ <script> -import { GlAlert, GlPagination, GlSkeletonLoader } from '@gitlab/ui'; +import { GlAlert, GlSkeletonLoader, GlIntersectionObserver, GlLoadingIcon } from '@gitlab/ui'; import { __ } from '~/locale'; -import { GRAPHQL_PAGE_SIZE, initialPaginationState } from './constants'; import eventHub from './event_hub'; import GetJobs from './graphql/queries/get_jobs.query.graphql'; import JobsTable from './jobs_table.vue'; @@ -11,14 +10,16 @@ import JobsTableTabs from './jobs_table_tabs.vue'; export default { i18n: { errorMsg: __('There was an error fetching the jobs for your project.'), + loadingAriaLabel: __('Loading'), }, components: { GlAlert, - GlPagination, GlSkeletonLoader, JobsTable, JobsTableEmptyState, JobsTableTabs, + GlIntersectionObserver, + GlLoadingIcon, }, inject: { fullPath: { @@ -31,10 +32,6 @@ export default { variables() { return { fullPath: this.fullPath, - first: this.pagination.first, - last: this.pagination.last, - after: this.pagination.nextPageCursor, - before: this.pagination.prevPageCursor, }; }, update(data) { @@ -57,7 +54,7 @@ export default { hasError: false, isAlertDismissed: false, scope: null, - pagination: initialPaginationState, + firstLoad: true, }; }, computed: { @@ -67,14 +64,8 @@ export default { showEmptyState() { 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; + hasNextPage() { + return this.jobs?.pageInfo?.hasNextPage; }, }, mounted() { @@ -88,26 +79,22 @@ export default { this.$apollo.queries.jobs.refetch({ statuses: this.scope }); }, fetchJobsByStatus(scope) { + this.firstLoad = true; + this.scope = scope; this.$apollo.queries.jobs.refetch({ statuses: scope }); }, - handlePageChange(page) { - const { startCursor, endCursor } = this.jobs.pageInfo; + fetchMoreJobs() { + this.firstLoad = false; - 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, - }; + if (!this.$apollo.queries.jobs.loading) { + this.$apollo.queries.jobs.fetchMore({ + variables: { + fullPath: this.fullPath, + after: this.jobs?.pageInfo?.endCursor, + }, + }); } }, }, @@ -128,7 +115,7 @@ export default { <jobs-table-tabs @fetchJobsByStatus="fetchJobsByStatus" /> - <div v-if="$apollo.loading" class="gl-mt-5"> + <div v-if="$apollo.loading && firstLoad" class="gl-mt-5"> <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" /> @@ -149,14 +136,12 @@ export default { <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" - /> + <gl-intersection-observer v-if="hasNextPage" @appear="fetchMoreJobs"> + <gl-loading-icon + v-if="$apollo.loading" + size="md" + :aria-label="$options.i18n.loadingAriaLabel" + /> + </gl-intersection-observer> </div> </template> |