Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-09-15 18:10:08 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-09-15 18:10:08 +0300
commit06c127aa72cff78235426341081837cff0b6f78b (patch)
tree614c9d9e029adcac31f290d4f953fe8b02aaf0f1 /app/assets/javascripts/releases
parent33212c8ff1f99cdb896e8fc6f6450882287e0de5 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/releases')
-rw-r--r--app/assets/javascripts/releases/components/app_index.vue5
-rw-r--r--app/assets/javascripts/releases/mount_index.js5
-rw-r--r--app/assets/javascripts/releases/queries/all_releases.query.graphql69
-rw-r--r--app/assets/javascripts/releases/stores/modules/list/actions.js30
-rw-r--r--app/assets/javascripts/releases/util.js89
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 };
+};