diff options
Diffstat (limited to 'app/assets/javascripts/releases/stores/modules/index')
5 files changed, 194 insertions, 0 deletions
diff --git a/app/assets/javascripts/releases/stores/modules/index/actions.js b/app/assets/javascripts/releases/stores/modules/index/actions.js new file mode 100644 index 00000000000..f1add54626a --- /dev/null +++ b/app/assets/javascripts/releases/stores/modules/index/actions.js @@ -0,0 +1,109 @@ +import api from '~/api'; +import { deprecatedCreateFlash as createFlash } from '~/flash'; +import { + normalizeHeaders, + parseIntPagination, + convertObjectPropsToCamelCase, +} from '~/lib/utils/common_utils'; +import { __ } from '~/locale'; +import allReleasesQuery from '~/releases/queries/all_releases.query.graphql'; +import { PAGE_SIZE } from '../../../constants'; +import { gqClient, convertAllReleasesGraphQLResponse } from '../../../util'; +import * as types from './mutation_types'; + +/** + * 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 fetchReleases = ({ dispatch, rootGetters }, { page = 1, before, after }) => { + if (rootGetters.useGraphQLEndpoint) { + dispatch('fetchReleasesGraphQl', { before, after }); + } else { + dispatch('fetchReleasesRest', { page }); + } +}; + +/** + * Gets a paginated list of releases from the GraphQL endpoint + */ +export const fetchReleasesGraphQl = ( + { dispatch, commit, state }, + { before = null, after = null }, +) => { + commit(types.REQUEST_RELEASES); + + const { sort, orderBy } = state.sorting; + const orderByParam = orderBy === 'created_at' ? 'created' : orderBy; + const sortParams = `${orderByParam}_${sort}`.toUpperCase(); + + 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 { + 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, + sort: sortParams, + ...paginationParams, + }, + }) + .then((response) => { + const { data, paginationInfo: graphQlPageInfo } = convertAllReleasesGraphQLResponse(response); + + commit(types.RECEIVE_RELEASES_SUCCESS, { + data, + graphQlPageInfo, + }); + }) + .catch(() => dispatch('receiveReleasesError')); +}; + +/** + * Gets a paginated list of releases from the REST endpoint + */ +export const fetchReleasesRest = ({ dispatch, commit, state }, { page }) => { + commit(types.REQUEST_RELEASES); + + const { sort, orderBy } = state.sorting; + + api + .releases(state.projectId, { page, sort, order_by: orderBy }) + .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 }) => { + commit(types.RECEIVE_RELEASES_ERROR); + createFlash(__('An error occurred while fetching the releases. Please try again.')); +}; + +export const setSorting = ({ commit }, data) => commit(types.SET_SORTING, data); diff --git a/app/assets/javascripts/releases/stores/modules/index/index.js b/app/assets/javascripts/releases/stores/modules/index/index.js new file mode 100644 index 00000000000..d5ca191153a --- /dev/null +++ b/app/assets/javascripts/releases/stores/modules/index/index.js @@ -0,0 +1,10 @@ +import * as actions from './actions'; +import mutations from './mutations'; +import createState from './state'; + +export default (initialState) => ({ + namespaced: true, + actions, + mutations, + state: createState(initialState), +}); diff --git a/app/assets/javascripts/releases/stores/modules/index/mutation_types.js b/app/assets/javascripts/releases/stores/modules/index/mutation_types.js new file mode 100644 index 00000000000..669168efb88 --- /dev/null +++ b/app/assets/javascripts/releases/stores/modules/index/mutation_types.js @@ -0,0 +1,4 @@ +export const REQUEST_RELEASES = 'REQUEST_RELEASES'; +export const RECEIVE_RELEASES_SUCCESS = 'RECEIVE_RELEASES_SUCCESS'; +export const RECEIVE_RELEASES_ERROR = 'RECEIVE_RELEASES_ERROR'; +export const SET_SORTING = 'SET_SORTING'; diff --git a/app/assets/javascripts/releases/stores/modules/index/mutations.js b/app/assets/javascripts/releases/stores/modules/index/mutations.js new file mode 100644 index 00000000000..e1aaa2e2a19 --- /dev/null +++ b/app/assets/javascripts/releases/stores/modules/index/mutations.js @@ -0,0 +1,46 @@ +import * as types from './mutation_types'; + +export default { + /** + * Sets isLoading to true while the request is being made. + * @param {Object} state + */ + [types.REQUEST_RELEASES](state) { + state.isLoading = true; + }, + + /** + * Sets isLoading to false. + * Sets hasError to false. + * Sets the received data + * Sets the received pagination information + * @param {Object} state + * @param {Object} resp + */ + [types.RECEIVE_RELEASES_SUCCESS](state, { data, restPageInfo, graphQlPageInfo }) { + state.hasError = false; + state.isLoading = false; + state.releases = data; + state.restPageInfo = restPageInfo; + state.graphQlPageInfo = graphQlPageInfo; + }, + + /** + * Sets isLoading to false. + * Sets hasError to true. + * Resets the data + * @param {Object} state + * @param {Object} data + */ + [types.RECEIVE_RELEASES_ERROR](state) { + state.isLoading = false; + state.releases = []; + state.hasError = true; + state.restPageInfo = {}; + state.graphQlPageInfo = {}; + }, + + [types.SET_SORTING](state, sorting) { + state.sorting = { ...state.sorting, ...sorting }; + }, +}; diff --git a/app/assets/javascripts/releases/stores/modules/index/state.js b/app/assets/javascripts/releases/stores/modules/index/state.js new file mode 100644 index 00000000000..164a496d450 --- /dev/null +++ b/app/assets/javascripts/releases/stores/modules/index/state.js @@ -0,0 +1,25 @@ +import { DESCENDING_ORDER, RELEASED_AT } from '../../../constants'; + +export default ({ + projectId, + projectPath, + documentationPath, + illustrationPath, + newReleasePath = '', +}) => ({ + projectId, + projectPath, + documentationPath, + illustrationPath, + newReleasePath, + + isLoading: false, + hasError: false, + releases: [], + restPageInfo: {}, + graphQlPageInfo: {}, + sorting: { + sort: DESCENDING_ORDER, + orderBy: RELEASED_AT, + }, +}); |