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/issues_list/components/issue_card_time_info.vue')
-rw-r--r--app/assets/javascripts/issues_list/components/issue_card_time_info.vue124
1 files changed, 124 insertions, 0 deletions
diff --git a/app/assets/javascripts/issues_list/components/issue_card_time_info.vue b/app/assets/javascripts/issues_list/components/issue_card_time_info.vue
new file mode 100644
index 00000000000..8d00d337bac
--- /dev/null
+++ b/app/assets/javascripts/issues_list/components/issue_card_time_info.vue
@@ -0,0 +1,124 @@
+<script>
+import { GlLink, GlIcon, GlTooltipDirective } from '@gitlab/ui';
+import {
+ dateInWords,
+ getTimeRemainingInWords,
+ isInFuture,
+ isInPast,
+ isToday,
+} from '~/lib/utils/datetime_utility';
+import { convertToCamelCase } from '~/lib/utils/text_utility';
+import { __ } from '~/locale';
+
+export default {
+ components: {
+ GlLink,
+ GlIcon,
+ IssueHealthStatus: () =>
+ import('ee_component/related_items_tree/components/issue_health_status.vue'),
+ WeightCount: () => import('ee_component/issues/components/weight_count.vue'),
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ inject: {
+ hasIssuableHealthStatusFeature: {
+ default: false,
+ },
+ },
+ props: {
+ issue: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ milestoneDate() {
+ if (this.issue.milestone?.dueDate) {
+ const { dueDate, startDate } = this.issue.milestone;
+ const date = dateInWords(new Date(dueDate), true);
+ const remainingTime = this.milestoneRemainingTime(dueDate, startDate);
+ return `${date} (${remainingTime})`;
+ }
+ return __('Milestone');
+ },
+ dueDate() {
+ return this.issue.dueDate && dateInWords(new Date(this.issue.dueDate), true);
+ },
+ isDueDateInPast() {
+ return isInPast(new Date(this.issue.dueDate));
+ },
+ timeEstimate() {
+ return this.issue.timeStats?.humanTimeEstimate;
+ },
+ showHealthStatus() {
+ return this.hasIssuableHealthStatusFeature && this.issue.healthStatus;
+ },
+ healthStatus() {
+ return convertToCamelCase(this.issue.healthStatus);
+ },
+ },
+ methods: {
+ milestoneRemainingTime(dueDate, startDate) {
+ const due = new Date(dueDate);
+ const start = new Date(startDate);
+
+ if (dueDate && isInPast(due)) {
+ return __('Past due');
+ } else if (dueDate && isToday(due)) {
+ return __('Today');
+ } else if (startDate && isInFuture(start)) {
+ return __('Upcoming');
+ } else if (dueDate) {
+ return getTimeRemainingInWords(due);
+ }
+ return '';
+ },
+ },
+};
+</script>
+
+<template>
+ <span>
+ <span
+ v-if="issue.milestone"
+ class="issuable-milestone gl-display-none gl-sm-display-inline-block! gl-mr-3"
+ data-testid="issuable-milestone"
+ >
+ <gl-link v-gl-tooltip :href="issue.milestone.webUrl" :title="milestoneDate">
+ <gl-icon name="clock" />
+ {{ issue.milestone.title }}
+ </gl-link>
+ </span>
+ <span
+ v-if="issue.dueDate"
+ v-gl-tooltip
+ class="issuable-due-date gl-display-none gl-sm-display-inline-block! gl-mr-3"
+ :class="{ 'gl-text-red-500': isDueDateInPast }"
+ :title="__('Due date')"
+ data-testid="issuable-due-date"
+ >
+ <gl-icon name="calendar" />
+ {{ dueDate }}
+ </span>
+ <span
+ v-if="timeEstimate"
+ v-gl-tooltip
+ class="gl-display-none gl-sm-display-inline-block! gl-mr-3"
+ :title="__('Estimate')"
+ data-testid="time-estimate"
+ >
+ <gl-icon name="timer" />
+ {{ timeEstimate }}
+ </span>
+ <weight-count
+ class="gl-display-none gl-sm-display-inline-block gl-mr-3"
+ :weight="issue.weight"
+ />
+ <issue-health-status
+ v-if="showHealthStatus"
+ class="gl-display-none gl-sm-display-inline-block"
+ :health-status="healthStatus"
+ />
+ </span>
+</template>