diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-18 18:09:22 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-18 18:09:22 +0300 |
commit | 80d252c8e25dc88023e750cf2a22be6186cfd6aa (patch) | |
tree | ad932c5973af9081cbafb0dcbbd24a3a100105a6 /app/assets/javascripts/releases | |
parent | dc86d5615e92ad4dfad4e5b452e8623a552b308b (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/releases')
11 files changed, 133 insertions, 67 deletions
diff --git a/app/assets/javascripts/releases/components/app_index.vue b/app/assets/javascripts/releases/components/app_index.vue index b8cf6ce478f..e237db2cc6f 100644 --- a/app/assets/javascripts/releases/components/app_index.vue +++ b/app/assets/javascripts/releases/components/app_index.vue @@ -6,14 +6,10 @@ import { GlLink, GlButton, } from '@gitlab/ui'; -import { - getParameterByName, - historyPushState, - buildUrlWithCurrentLocation, -} from '~/lib/utils/common_utils'; +import { getParameterByName } from '~/lib/utils/common_utils'; import { __ } from '~/locale'; -import TablePagination from '~/vue_shared/components/pagination/table_pagination.vue'; import ReleaseBlock from './release_block.vue'; +import ReleasesPagination from './releases_pagination.vue'; export default { name: 'ReleasesApp', @@ -21,7 +17,7 @@ export default { GlSkeletonLoading, GlEmptyState, ReleaseBlock, - TablePagination, + ReleasesPagination, GlLink, GlButton, }, @@ -33,7 +29,6 @@ export default { 'isLoading', 'releases', 'hasError', - 'pageInfo', ]), shouldRenderEmptyState() { return !this.releases.length && !this.hasError && !this.isLoading; @@ -48,15 +43,23 @@ export default { }, }, created() { - this.fetchReleases({ - page: getParameterByName('page'), - }); + this.fetchReleases(); + + window.addEventListener('popstate', this.fetchReleases); }, methods: { - ...mapActions('list', ['fetchReleases']), - onChangePage(page) { - historyPushState(buildUrlWithCurrentLocation(`?page=${page}`)); - this.fetchReleases({ page }); + ...mapActions('list', { + fetchReleasesStoreAction: 'fetchReleases', + }), + fetchReleases() { + this.fetchReleasesStoreAction({ + // these two parameters are only used in "GraphQL mode" + before: getParameterByName('before'), + after: getParameterByName('after'), + + // this parameter is only used when in "REST mode" + page: getParameterByName('page'), + }); }, }, }; @@ -105,7 +108,7 @@ export default { /> </div> - <table-pagination v-if="!isLoading" :change="onChangePage" :page-info="pageInfo" /> + <releases-pagination v-if="!isLoading" /> </div> </template> <style> diff --git a/app/assets/javascripts/releases/components/releases_pagination_graphql.vue b/app/assets/javascripts/releases/components/releases_pagination_graphql.vue index a4fe407a5bd..cb6f1fa18a1 100644 --- a/app/assets/javascripts/releases/components/releases_pagination_graphql.vue +++ b/app/assets/javascripts/releases/components/releases_pagination_graphql.vue @@ -13,14 +13,14 @@ export default { }, }, methods: { - ...mapActions('list', ['fetchReleasesGraphQl']), + ...mapActions('list', ['fetchReleases']), onPrev(before) { historyPushState(buildUrlWithCurrentLocation(`?before=${before}`)); - this.fetchReleasesGraphQl({ before }); + this.fetchReleases({ before }); }, onNext(after) { historyPushState(buildUrlWithCurrentLocation(`?after=${after}`)); - this.fetchReleasesGraphQl({ after }); + this.fetchReleases({ after }); }, }, }; diff --git a/app/assets/javascripts/releases/components/releases_pagination_rest.vue b/app/assets/javascripts/releases/components/releases_pagination_rest.vue index 992cc4cd469..334458a2302 100644 --- a/app/assets/javascripts/releases/components/releases_pagination_rest.vue +++ b/app/assets/javascripts/releases/components/releases_pagination_rest.vue @@ -7,18 +7,18 @@ export default { name: 'ReleasesPaginationRest', components: { TablePagination }, computed: { - ...mapState('list', ['pageInfo']), + ...mapState('list', ['restPageInfo']), }, methods: { - ...mapActions('list', ['fetchReleasesRest']), + ...mapActions('list', ['fetchReleases']), onChangePage(page) { historyPushState(buildUrlWithCurrentLocation(`?page=${page}`)); - this.fetchReleasesRest({ page }); + this.fetchReleases({ page }); }, }, }; </script> <template> - <table-pagination :change="onChangePage" :page-info="pageInfo" /> + <table-pagination :change="onChangePage" :page-info="restPageInfo" /> </template> diff --git a/app/assets/javascripts/releases/constants.js b/app/assets/javascripts/releases/constants.js index 361cee70747..953e7b4189c 100644 --- a/app/assets/javascripts/releases/constants.js +++ b/app/assets/javascripts/releases/constants.js @@ -10,3 +10,5 @@ export const ASSET_LINK_TYPE = Object.freeze({ }); export const DEFAULT_ASSET_LINK_TYPE = ASSET_LINK_TYPE.OTHER; + +export const PAGE_SIZE = 20; diff --git a/app/assets/javascripts/releases/queries/all_releases.query.graphql b/app/assets/javascripts/releases/queries/all_releases.query.graphql index 7a99f32fdfa..e74b7769abe 100644 --- a/app/assets/javascripts/releases/queries/all_releases.query.graphql +++ b/app/assets/javascripts/releases/queries/all_releases.query.graphql @@ -1,7 +1,6 @@ -query allReleases($fullPath: ID!) { +query allReleases($fullPath: ID!, $first: Int, $last: Int, $before: String, $after: String) { project(fullPath: $fullPath) { - releases(first: 20) { - count + releases(first: $first, last: $last, before: $before, after: $after) { nodes { name tagName @@ -64,6 +63,12 @@ query allReleases($fullPath: ID!) { } } } + pageInfo { + startCursor + hasPreviousPage + hasNextPage + endCursor + } } } } diff --git a/app/assets/javascripts/releases/stores/getters.js b/app/assets/javascripts/releases/stores/getters.js new file mode 100644 index 00000000000..6a1da63289c --- /dev/null +++ b/app/assets/javascripts/releases/stores/getters.js @@ -0,0 +1,11 @@ +/** + * @returns {Boolean} `true` if all the feature flags + * required to enable the GraphQL endpoint are enabled + */ +export const useGraphQLEndpoint = rootState => { + return Boolean( + rootState.featureFlags.graphqlReleaseData && + rootState.featureFlags.graphqlReleasesPage && + rootState.featureFlags.graphqlMilestoneStats, + ); +}; diff --git a/app/assets/javascripts/releases/stores/index.js b/app/assets/javascripts/releases/stores/index.js index b2e93d789d7..cc8b586964f 100644 --- a/app/assets/javascripts/releases/stores/index.js +++ b/app/assets/javascripts/releases/stores/index.js @@ -1,7 +1,9 @@ import Vuex from 'vuex'; +import * as getters from './getters'; export default ({ modules, featureFlags }) => new Vuex.Store({ modules, state: { featureFlags }, + getters, }); diff --git a/app/assets/javascripts/releases/stores/modules/list/actions.js b/app/assets/javascripts/releases/stores/modules/list/actions.js index 945b093b983..a7bb6a3a1d0 100644 --- a/app/assets/javascripts/releases/stores/modules/list/actions.js +++ b/app/assets/javascripts/releases/stores/modules/list/actions.js @@ -9,54 +9,89 @@ import { } from '~/lib/utils/common_utils'; import allReleasesQuery from '~/releases/queries/all_releases.query.graphql'; import { gqClient, convertGraphQLResponse } from '../../../util'; +import { PAGE_SIZE } from '../../../constants'; /** - * Commits a mutation to update the state while the main endpoint is being requested. + * Gets a paginated list of releases from the server + * + * @param {Object} vuexParams + * @param {Object} actionParams + * @param {Number} [actionParams.page] The page number of results to fetch + * (this parameter is only used when fetching results from the REST API) + * @param {String} [actionParams.before] A GraphQL cursor. If provided, + * the items returned will proceed the provided cursor (this parameter is only + * used when fetching results from the GraphQL API). + * @param {String} [actionParams.after] A GraphQL cursor. If provided, + * the items returned will follow the provided cursor (this parameter is only + * used when fetching results from the GraphQL API). */ -export const requestReleases = ({ commit }) => commit(types.REQUEST_RELEASES); +export const fetchReleases = ({ dispatch, rootGetters }, { page = 1, before, after }) => { + if (rootGetters.useGraphQLEndpoint) { + dispatch('fetchReleasesGraphQl', { before, after }); + } else { + dispatch('fetchReleasesRest', { page }); + } +}; /** - * Fetches the main endpoint. - * Will dispatch requestNamespace action before starting the request. - * Will dispatch receiveNamespaceSuccess if the request is successful - * Will dispatch receiveNamesapceError if the request returns an error - * - * @param {String} projectId + * Gets a paginated list of releases from the GraphQL endpoint */ -export const fetchReleases = ({ dispatch, rootState, state }, { page = '1' }) => { - dispatch('requestReleases'); +export const fetchReleasesGraphQl = ( + { dispatch, commit, state }, + { before = null, after = null }, +) => { + commit(types.REQUEST_RELEASES); - if ( - rootState.featureFlags.graphqlReleaseData && - rootState.featureFlags.graphqlReleasesPage && - rootState.featureFlags.graphqlMilestoneStats - ) { - gqClient - .query({ - query: allReleasesQuery, - variables: { - fullPath: state.projectPath, - }, - }) - .then(response => { - dispatch('receiveReleasesSuccess', convertGraphQLResponse(response)); - }) - .catch(() => dispatch('receiveReleasesError')); + let paginationParams; + if (!before && !after) { + paginationParams = { first: PAGE_SIZE }; + } else if (before && !after) { + paginationParams = { last: PAGE_SIZE, before }; + } else if (!before && after) { + paginationParams = { first: PAGE_SIZE, after }; } else { - api - .releases(state.projectId, { page }) - .then(response => dispatch('receiveReleasesSuccess', response)) - .catch(() => dispatch('receiveReleasesError')); + throw new Error( + 'Both a `before` and an `after` parameter were provided to fetchReleasesGraphQl. These parameters cannot be used together.', + ); } + + gqClient + .query({ + query: allReleasesQuery, + variables: { + fullPath: state.projectPath, + ...paginationParams, + }, + }) + .then(response => { + const { data, paginationInfo: graphQlPageInfo } = convertGraphQLResponse(response); + + commit(types.RECEIVE_RELEASES_SUCCESS, { + data, + graphQlPageInfo, + }); + }) + .catch(() => dispatch('receiveReleasesError')); }; -export const receiveReleasesSuccess = ({ commit }, { data, headers }) => { - const pageInfo = parseIntPagination(normalizeHeaders(headers)); - const camelCasedReleases = convertObjectPropsToCamelCase(data, { deep: true }); - commit(types.RECEIVE_RELEASES_SUCCESS, { - data: camelCasedReleases, - pageInfo, - }); +/** + * Gets a paginated list of releases from the REST endpoint + */ +export const fetchReleasesRest = ({ dispatch, commit, state }, { page }) => { + commit(types.REQUEST_RELEASES); + + api + .releases(state.projectId, { page }) + .then(({ data, headers }) => { + const restPageInfo = parseIntPagination(normalizeHeaders(headers)); + const camelCasedReleases = convertObjectPropsToCamelCase(data, { deep: true }); + + commit(types.RECEIVE_RELEASES_SUCCESS, { + data: camelCasedReleases, + restPageInfo, + }); + }) + .catch(() => dispatch('receiveReleasesError')); }; export const receiveReleasesError = ({ commit }) => { diff --git a/app/assets/javascripts/releases/stores/modules/list/mutations.js b/app/assets/javascripts/releases/stores/modules/list/mutations.js index 99fc096264a..296487cfee2 100644 --- a/app/assets/javascripts/releases/stores/modules/list/mutations.js +++ b/app/assets/javascripts/releases/stores/modules/list/mutations.js @@ -17,11 +17,12 @@ export default { * @param {Object} state * @param {Object} resp */ - [types.RECEIVE_RELEASES_SUCCESS](state, { data, pageInfo }) { + [types.RECEIVE_RELEASES_SUCCESS](state, { data, restPageInfo, graphQlPageInfo }) { state.hasError = false; state.isLoading = false; state.releases = data; - state.pageInfo = pageInfo; + state.restPageInfo = restPageInfo; + state.graphQlPageInfo = graphQlPageInfo; }, /** @@ -35,5 +36,7 @@ export default { state.isLoading = false; state.releases = []; state.hasError = true; + state.restPageInfo = {}; + state.graphQlPageInfo = {}; }, }; diff --git a/app/assets/javascripts/releases/stores/modules/list/state.js b/app/assets/javascripts/releases/stores/modules/list/state.js index 9fe313745fc..0bffaa0f9db 100644 --- a/app/assets/javascripts/releases/stores/modules/list/state.js +++ b/app/assets/javascripts/releases/stores/modules/list/state.js @@ -14,5 +14,6 @@ export default ({ isLoading: false, hasError: false, releases: [], - pageInfo: {}, + restPageInfo: {}, + graphQlPageInfo: {}, }); diff --git a/app/assets/javascripts/releases/util.js b/app/assets/javascripts/releases/util.js index d7fac7a9b65..e890b4b008d 100644 --- a/app/assets/javascripts/releases/util.js +++ b/app/assets/javascripts/releases/util.js @@ -126,5 +126,9 @@ export const convertGraphQLResponse = response => { ...convertMilestones(r), })); - return { data: releases }; + const paginationInfo = { + ...response.data.project.releases.pageInfo, + }; + + return { data: releases, paginationInfo }; }; |