diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-15 18:10:08 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-15 18:10:08 +0300 |
commit | 06c127aa72cff78235426341081837cff0b6f78b (patch) | |
tree | 614c9d9e029adcac31f290d4f953fe8b02aaf0f1 /app/assets/javascripts/releases | |
parent | 33212c8ff1f99cdb896e8fc6f6450882287e0de5 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/releases')
5 files changed, 193 insertions, 5 deletions
diff --git a/app/assets/javascripts/releases/components/app_index.vue b/app/assets/javascripts/releases/components/app_index.vue index 22485a3344b..ba5342e993e 100644 --- a/app/assets/javascripts/releases/components/app_index.vue +++ b/app/assets/javascripts/releases/components/app_index.vue @@ -30,6 +30,10 @@ export default { type: String, required: true, }, + projectPath: { + type: String, + required: true, + }, documentationPath: { type: String, required: true, @@ -62,6 +66,7 @@ export default { this.fetchReleases({ page: getParameterByName('page'), projectId: this.projectId, + projectPath: this.projectPath, }); }, methods: { diff --git a/app/assets/javascripts/releases/mount_index.js b/app/assets/javascripts/releases/mount_index.js index 5f0bf3b6459..4023b905504 100644 --- a/app/assets/javascripts/releases/mount_index.js +++ b/app/assets/javascripts/releases/mount_index.js @@ -12,6 +12,11 @@ export default () => { modules: { list: listModule, }, + featureFlags: { + graphqlReleaseData: Boolean(gon.features?.graphqlReleaseData), + graphqlReleasesPage: Boolean(gon.features?.graphqlReleasesPage), + graphqlMilestoneStats: Boolean(gon.features?.graphqlMilestoneStats), + }, }), render: h => h(ReleaseListApp, { diff --git a/app/assets/javascripts/releases/queries/all_releases.query.graphql b/app/assets/javascripts/releases/queries/all_releases.query.graphql new file mode 100644 index 00000000000..7a99f32fdfa --- /dev/null +++ b/app/assets/javascripts/releases/queries/all_releases.query.graphql @@ -0,0 +1,69 @@ +query allReleases($fullPath: ID!) { + project(fullPath: $fullPath) { + releases(first: 20) { + count + nodes { + name + tagName + tagPath + descriptionHtml + releasedAt + upcomingRelease + assets { + count + sources { + nodes { + format + url + } + } + links { + nodes { + id + name + url + directAssetUrl + linkType + external + } + } + } + evidences { + nodes { + filepath + collectedAt + sha + } + } + links { + editUrl + issuesUrl + mergeRequestsUrl + selfUrl + } + commit { + sha + webUrl + title + } + author { + webUrl + avatarUrl + username + } + milestones { + nodes { + id + title + description + webPath + stats { + totalIssuesCount + closedIssuesCount + } + } + } + } + } + } +} diff --git a/app/assets/javascripts/releases/stores/modules/list/actions.js b/app/assets/javascripts/releases/stores/modules/list/actions.js index 90fba319e9f..3d28ef23fe7 100644 --- a/app/assets/javascripts/releases/stores/modules/list/actions.js +++ b/app/assets/javascripts/releases/stores/modules/list/actions.js @@ -7,6 +7,8 @@ import { parseIntPagination, convertObjectPropsToCamelCase, } from '~/lib/utils/common_utils'; +import allReleasesQuery from '~/releases/queries/all_releases.query.graphql'; +import { gqClient, convertGraphQLResponse } from '../../../util'; /** * Commits a mutation to update the state while the main endpoint is being requested. @@ -21,13 +23,31 @@ export const requestReleases = ({ commit }) => commit(types.REQUEST_RELEASES); * * @param {String} projectId */ -export const fetchReleases = ({ dispatch }, { page = '1', projectId }) => { +export const fetchReleases = ({ dispatch, rootState }, { page = '1', projectId, projectPath }) => { dispatch('requestReleases'); - api - .releases(projectId, { page }) - .then(response => dispatch('receiveReleasesSuccess', response)) - .catch(() => dispatch('receiveReleasesError')); + if ( + rootState.featureFlags.graphqlReleaseData && + rootState.featureFlags.graphqlReleasesPage && + rootState.featureFlags.graphqlMilestoneStats + ) { + gqClient + .query({ + query: allReleasesQuery, + variables: { + fullPath: projectPath, + }, + }) + .then(response => { + dispatch('receiveReleasesSuccess', convertGraphQLResponse(response)); + }) + .catch(() => dispatch('receiveReleasesError')); + } else { + api + .releases(projectId, { page }) + .then(response => dispatch('receiveReleasesSuccess', response)) + .catch(() => dispatch('receiveReleasesError')); + } }; export const receiveReleasesSuccess = ({ commit }, { data, headers }) => { diff --git a/app/assets/javascripts/releases/util.js b/app/assets/javascripts/releases/util.js index 842a423b142..d7fac7a9b65 100644 --- a/app/assets/javascripts/releases/util.js +++ b/app/assets/javascripts/releases/util.js @@ -1,3 +1,6 @@ +import { pick } from 'lodash'; +import createGqClient, { fetchPolicies } from '~/lib/graphql'; +import { truncateSha } from '~/lib/utils/text_utility'; import { convertObjectPropsToCamelCase, convertObjectPropsToSnakeCase, @@ -39,3 +42,89 @@ export const apiJsonToRelease = json => { return release; }; + +export const gqClient = createGqClient({}, { fetchPolicy: fetchPolicies.NO_CACHE }); + +const convertScalarProperties = graphQLRelease => + pick(graphQLRelease, [ + 'name', + 'tagName', + 'tagPath', + 'descriptionHtml', + 'releasedAt', + 'upcomingRelease', + ]); + +const convertAssets = graphQLRelease => ({ + assets: { + count: graphQLRelease.assets.count, + sources: [...graphQLRelease.assets.sources.nodes], + links: graphQLRelease.assets.links.nodes.map(l => ({ + ...l, + linkType: l.linkType?.toLowerCase(), + })), + }, +}); + +const convertEvidences = graphQLRelease => ({ + evidences: graphQLRelease.evidences.nodes.map(e => e), +}); + +const convertLinks = graphQLRelease => ({ + _links: { + ...graphQLRelease.links, + self: graphQLRelease.links?.selfUrl, + }, +}); + +const convertCommit = graphQLRelease => { + if (!graphQLRelease.commit) { + return {}; + } + + return { + commit: { + shortId: truncateSha(graphQLRelease.commit.sha), + title: graphQLRelease.commit.title, + }, + commitPath: graphQLRelease.commit.webUrl, + }; +}; + +const convertAuthor = graphQLRelease => ({ author: graphQLRelease.author }); + +const convertMilestones = graphQLRelease => ({ + milestones: graphQLRelease.milestones.nodes.map(m => ({ + ...m, + webUrl: m.webPath, + webPath: undefined, + issueStats: { + total: m.stats.totalIssuesCount, + closed: m.stats.closedIssuesCount, + }, + stats: undefined, + })), +}); + +/** + * Converts the response from the GraphQL endpoint into the + * same shape as is returned from the Releases REST API. + * + * This allows the release components to use the response + * from either endpoint interchangeably. + * + * @param response The response received from the GraphQL endpoint + */ +export const convertGraphQLResponse = response => { + const releases = response.data.project.releases.nodes.map(r => ({ + ...convertScalarProperties(r), + ...convertAssets(r), + ...convertEvidences(r), + ...convertLinks(r), + ...convertCommit(r), + ...convertAuthor(r), + ...convertMilestones(r), + })); + + return { data: releases }; +}; |