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:
Diffstat (limited to 'app/assets/javascripts/issuable/components/issue_milestone.vue')
-rw-r--r--app/assets/javascripts/issuable/components/issue_milestone.vue91
1 files changed, 91 insertions, 0 deletions
diff --git a/app/assets/javascripts/issuable/components/issue_milestone.vue b/app/assets/javascripts/issuable/components/issue_milestone.vue
new file mode 100644
index 00000000000..6a0c21602bd
--- /dev/null
+++ b/app/assets/javascripts/issuable/components/issue_milestone.vue
@@ -0,0 +1,91 @@
+<script>
+import { GlTooltip, GlIcon } from '@gitlab/ui';
+import { timeFor, parsePikadayDate, dateInWords } from '~/lib/utils/datetime_utility';
+import { __, sprintf } from '~/locale';
+import timeagoMixin from '~/vue_shared/mixins/timeago';
+
+export default {
+ components: {
+ GlIcon,
+ GlTooltip,
+ },
+ mixins: [timeagoMixin],
+ props: {
+ milestone: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ milestoneDue() {
+ const dueDate = this.milestone.due_date || this.milestone.dueDate;
+
+ return dueDate ? parsePikadayDate(dueDate) : null;
+ },
+ milestoneStart() {
+ const startDate = this.milestone.start_date || this.milestone.startDate;
+
+ return startDate ? parsePikadayDate(startDate) : null;
+ },
+ isMilestoneStarted() {
+ if (!this.milestoneStart) {
+ return false;
+ }
+ return Date.now() > this.milestoneStart;
+ },
+ isMilestonePastDue() {
+ if (!this.milestoneDue) {
+ return false;
+ }
+ return Date.now() > this.milestoneDue;
+ },
+ milestoneDatesAbsolute() {
+ if (this.milestoneDue) {
+ return `(${dateInWords(this.milestoneDue)})`;
+ } else if (this.milestoneStart) {
+ return `(${dateInWords(this.milestoneStart)})`;
+ }
+ return '';
+ },
+ milestoneDatesHuman() {
+ if (this.milestoneStart || this.milestoneDue) {
+ if (this.milestoneDue) {
+ return timeFor(
+ this.milestoneDue,
+ sprintf(__('Expired %{expiredOn}'), {
+ expiredOn: this.timeFormatted(this.milestoneDue),
+ }),
+ );
+ }
+
+ return sprintf(
+ this.isMilestoneStarted ? __('Started %{startsIn}') : __('Starts %{startsIn}'),
+ {
+ startsIn: this.timeFormatted(this.milestoneStart),
+ },
+ );
+ }
+ return '';
+ },
+ },
+};
+</script>
+<template>
+ <div ref="milestoneDetails" class="issue-milestone-details">
+ <gl-icon :size="16" class="gl-mr-2" name="clock" />
+ <span class="milestone-title d-inline-block">{{ milestone.title }}</span>
+ <gl-tooltip :target="() => $refs.milestoneDetails" placement="bottom" class="js-item-milestone">
+ <span class="bold">{{ __('Milestone') }}</span> <br />
+ <span>{{ milestone.title }}</span> <br />
+ <span
+ v-if="milestoneStart || milestoneDue"
+ :class="{
+ 'text-danger-muted': isMilestonePastDue,
+ 'text-tertiary': !isMilestonePastDue,
+ }"
+ ><span>{{ milestoneDatesHuman }}</span
+ ><br /><span>{{ milestoneDatesAbsolute }}</span>
+ </span>
+ </gl-tooltip>
+ </div>
+</template>