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>2019-12-05 03:07:50 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-12-05 03:07:50 +0300
commit54cbcea92909e69248abc9e6b92c7d14db3308a5 (patch)
tree1276f1c57b5ab1064db7197c2d28a8837d68d02d /app/assets/javascripts/releases
parent71221554dd9ddf30f73035c89f78164e001aa96d (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/releases')
-rw-r--r--app/assets/javascripts/releases/list/components/release_block.vue46
-rw-r--r--app/assets/javascripts/releases/list/components/release_block_milestone_info.vue136
-rw-r--r--app/assets/javascripts/releases/list/constants.js7
3 files changed, 172 insertions, 17 deletions
diff --git a/app/assets/javascripts/releases/list/components/release_block.vue b/app/assets/javascripts/releases/list/components/release_block.vue
index 2ae6b1a595f..09ef857ae4a 100644
--- a/app/assets/javascripts/releases/list/components/release_block.vue
+++ b/app/assets/javascripts/releases/list/components/release_block.vue
@@ -12,6 +12,7 @@ import { scrollToElement } from '~/lib/utils/common_utils';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import ReleaseBlockFooter from './release_block_footer.vue';
import EvidenceBlock from './evidence_block.vue';
+import ReleaseBlockMilestoneInfo from './release_block_milestone_info.vue';
export default {
name: 'ReleaseBlock',
@@ -23,6 +24,7 @@ export default {
Icon,
UserAvatarLink,
ReleaseBlockFooter,
+ ReleaseBlockMilestoneInfo,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -90,6 +92,12 @@ export default {
shouldShowFooter() {
return this.glFeatures.releaseIssueSummary;
},
+ shouldRenderReleaseMetaData() {
+ return !this.glFeatures.releaseIssueSummary;
+ },
+ shouldRenderMilestoneInfo() {
+ return Boolean(this.glFeatures.releaseIssueSummary && !_.isEmpty(this.release.milestones));
+ },
},
mounted() {
const hash = getLocationHash();
@@ -106,26 +114,30 @@ export default {
</script>
<template>
<div :id="id" :class="{ 'bg-line-target-blue': isHighlighted }" class="card release-block">
+ <div class="card-header d-flex align-items-center bg-white pr-0">
+ <h2 class="card-title my-2 mr-auto gl-font-size-20">
+ {{ release.name }}
+ <gl-badge v-if="release.upcoming_release" variant="warning" class="align-middle">{{
+ __('Upcoming Release')
+ }}</gl-badge>
+ </h2>
+ <gl-link
+ v-if="shouldShowEditButton"
+ v-gl-tooltip
+ class="btn btn-default append-right-10 js-edit-button ml-2"
+ :title="__('Edit this release')"
+ :href="release._links.edit_url"
+ >
+ <icon name="pencil" />
+ </gl-link>
+ </div>
<div class="card-body">
- <div class="d-flex align-items-start">
- <h2 class="card-title mt-0 mr-auto">
- {{ release.name }}
- <gl-badge v-if="release.upcoming_release" variant="warning" class="align-middle">{{
- __('Upcoming Release')
- }}</gl-badge>
- </h2>
- <gl-link
- v-if="shouldShowEditButton"
- v-gl-tooltip
- class="btn btn-default js-edit-button ml-2"
- :title="__('Edit this release')"
- :href="release._links.edit_url"
- >
- <icon name="pencil" />
- </gl-link>
+ <div v-if="shouldRenderMilestoneInfo">
+ <release-block-milestone-info :milestones="release.milestones" />
+ <hr class="mb-3 mt-0" />
</div>
- <div class="card-subtitle d-flex flex-wrap text-secondary">
+ <div v-if="shouldRenderReleaseMetaData" class="card-subtitle d-flex flex-wrap text-secondary">
<div class="append-right-8">
<icon name="commit" class="align-middle" />
<gl-link v-if="commitUrl" v-gl-tooltip.bottom :title="commit.title" :href="commitUrl">
diff --git a/app/assets/javascripts/releases/list/components/release_block_milestone_info.vue b/app/assets/javascripts/releases/list/components/release_block_milestone_info.vue
new file mode 100644
index 00000000000..d3e354d6157
--- /dev/null
+++ b/app/assets/javascripts/releases/list/components/release_block_milestone_info.vue
@@ -0,0 +1,136 @@
+<script>
+import { GlProgressBar, GlLink, GlBadge, GlButton, GlTooltipDirective } from '@gitlab/ui';
+import { __, n__, sprintf } from '~/locale';
+import { MAX_MILESTONES_TO_DISPLAY } from '../constants';
+
+/** Sums the values of an array. For use with Array.reduce. */
+const sumReducer = (acc, curr) => acc + curr;
+
+export default {
+ name: 'ReleaseBlockMilestoneInfo',
+ components: {
+ GlProgressBar,
+ GlLink,
+ GlBadge,
+ GlButton,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ props: {
+ milestones: {
+ type: Array,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ showAllMilestones: false,
+ };
+ },
+ computed: {
+ percentCompleteText() {
+ return sprintf(__('%{percent}%{percentSymbol} complete'), {
+ percent: this.percentComplete,
+ percentSymbol: '%',
+ });
+ },
+ percentComplete() {
+ const percent = Math.round((this.closedIssuesCount / this.totalIssuesCount) * 100);
+ return Number.isNaN(percent) ? 0 : percent;
+ },
+ allIssueStats() {
+ return this.milestones.map(m => m.issue_stats || {});
+ },
+ openIssuesCount() {
+ return this.allIssueStats.map(stats => stats.opened || 0).reduce(sumReducer);
+ },
+ closedIssuesCount() {
+ return this.allIssueStats.map(stats => stats.closed || 0).reduce(sumReducer);
+ },
+ totalIssuesCount() {
+ return this.openIssuesCount + this.closedIssuesCount;
+ },
+ milestoneLabelText() {
+ return n__('Milestone', 'Milestones', this.milestones.length);
+ },
+ issueCountsText() {
+ return sprintf(__('Open: %{open} • Closed: %{closed}'), {
+ open: this.openIssuesCount,
+ closed: this.closedIssuesCount,
+ });
+ },
+ milestonesToDisplay() {
+ return this.showAllMilestones
+ ? this.milestones
+ : this.milestones.slice(0, MAX_MILESTONES_TO_DISPLAY);
+ },
+ showMoreLink() {
+ return this.milestones.length > MAX_MILESTONES_TO_DISPLAY;
+ },
+ moreText() {
+ return this.showAllMilestones
+ ? __('show fewer')
+ : sprintf(__('show %{count} more'), {
+ count: this.milestones.length - MAX_MILESTONES_TO_DISPLAY,
+ });
+ },
+ },
+ methods: {
+ toggleShowAll() {
+ this.showAllMilestones = !this.showAllMilestones;
+ },
+ shouldRenderBullet(milestoneIndex) {
+ return Boolean(milestoneIndex !== this.milestonesToDisplay.length - 1 || this.showMoreLink);
+ },
+ shouldRenderShowMoreLink(milestoneIndex) {
+ return Boolean(milestoneIndex === this.milestonesToDisplay.length - 1 && this.showMoreLink);
+ },
+ },
+};
+</script>
+<template>
+ <div class="release-block-milestone-info d-flex align-items-start flex-wrap">
+ <div
+ v-gl-tooltip
+ class="milestone-progress-bar-container js-milestone-progress-bar-container d-flex flex-column align-items-start flex-shrink-1 mr-4 mb-3"
+ :title="__('Closed issues')"
+ >
+ <span class="mb-2">{{ percentCompleteText }}</span>
+ <span class="w-100">
+ <gl-progress-bar :value="closedIssuesCount" :max="totalIssuesCount" variant="success" />
+ </span>
+ </div>
+ <div class="d-flex flex-column align-items-start mr-4 mb-3 js-milestone-list-container">
+ <span class="mb-1">{{ milestoneLabelText }}</span>
+ <div class="d-flex flex-wrap align-items-end">
+ <template v-for="(milestone, index) in milestonesToDisplay">
+ <gl-link
+ :key="milestone.id"
+ v-gl-tooltip
+ :title="milestone.description"
+ :href="milestone.web_url"
+ class="append-right-4"
+ >
+ {{ milestone.title }}
+ </gl-link>
+ <template v-if="shouldRenderBullet(index)">
+ <span :key="'bullet-' + milestone.id" class="append-right-4">&bull;</span>
+ </template>
+ <template v-if="shouldRenderShowMoreLink(index)">
+ <gl-button :key="'more-button-' + milestone.id" variant="link" @click="toggleShowAll">
+ {{ moreText }}
+ </gl-button>
+ </template>
+ </template>
+ </div>
+ </div>
+ <div class="d-flex flex-column align-items-start flex-shrink-0 mr-4 mb-3 js-issues-container">
+ <span class="mb-1">
+ {{ __('Issues') }}
+ <gl-badge pill variant="light" class="font-weight-bold">{{ totalIssuesCount }}</gl-badge>
+ </span>
+ {{ issueCountsText }}
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/releases/list/constants.js b/app/assets/javascripts/releases/list/constants.js
new file mode 100644
index 00000000000..defcd917465
--- /dev/null
+++ b/app/assets/javascripts/releases/list/constants.js
@@ -0,0 +1,7 @@
+/* eslint-disable import/prefer-default-export */
+// This eslint-disable ^^^ can be removed when at least
+// one more constant is added to this file. Currently
+// constants.js files with only a single constant
+// are flagged by this rule.
+
+export const MAX_MILESTONES_TO_DISPLAY = 5;