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/related_issuable_item.vue')
-rw-r--r--app/assets/javascripts/issuable/components/related_issuable_item.vue201
1 files changed, 201 insertions, 0 deletions
diff --git a/app/assets/javascripts/issuable/components/related_issuable_item.vue b/app/assets/javascripts/issuable/components/related_issuable_item.vue
new file mode 100644
index 00000000000..2bb0e3c80f9
--- /dev/null
+++ b/app/assets/javascripts/issuable/components/related_issuable_item.vue
@@ -0,0 +1,201 @@
+<script>
+import '~/commons/bootstrap';
+import {
+ GlIcon,
+ GlTooltip,
+ GlTooltipDirective,
+ GlButton,
+ GlSafeHtmlDirective as SafeHtml,
+} from '@gitlab/ui';
+import IssueDueDate from '~/boards/components/issue_due_date.vue';
+import { sprintf } from '~/locale';
+import CiIcon from '~/vue_shared/components/ci_icon.vue';
+import relatedIssuableMixin from '../mixins/related_issuable_mixin';
+import IssueAssignees from './issue_assignees.vue';
+import IssueMilestone from './issue_milestone.vue';
+
+export default {
+ name: 'IssueItem',
+ components: {
+ IssueMilestone,
+ IssueAssignees,
+ CiIcon,
+ GlIcon,
+ GlTooltip,
+ IssueWeight: () => import('ee_component/boards/components/issue_card_weight.vue'),
+ IssueDueDate,
+ GlButton,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ SafeHtml,
+ },
+ mixins: [relatedIssuableMixin],
+ props: {
+ canReorder: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ isLocked: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ lockedMessage: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ },
+ computed: {
+ stateTitle() {
+ return sprintf(
+ '<span class="bold">%{state}</span> %{timeInWords}<br/><span class="text-tertiary">%{timestamp}</span>',
+ {
+ state: this.stateText,
+ timeInWords: this.stateTimeInWords,
+ timestamp: this.stateTimestamp,
+ },
+ );
+ },
+ iconClasses() {
+ return `${this.iconClass} ic-${this.iconName}`;
+ },
+ },
+};
+</script>
+
+<template>
+ <div
+ :class="{
+ 'issuable-info-container': !canReorder,
+ 'card-body': canReorder,
+ }"
+ class="item-body d-flex align-items-center py-2 px-3"
+ >
+ <div
+ class="item-contents gl-display-flex gl-align-items-center gl-flex-wrap gl-flex-grow-1 flex-xl-nowrap gl-min-h-7"
+ >
+ <!-- Title area: Status icon (XL) and title -->
+ <div class="item-title d-flex align-items-xl-center mb-xl-0 gl-min-w-0">
+ <div ref="iconElementXL">
+ <gl-icon
+ v-if="hasState"
+ ref="iconElementXL"
+ class="mr-2 d-block"
+ :class="iconClasses"
+ :name="iconName"
+ :title="stateTitle"
+ :aria-label="state"
+ />
+ </div>
+ <gl-tooltip :target="() => $refs.iconElementXL">
+ <span v-safe-html="stateTitle"></span>
+ </gl-tooltip>
+ <gl-icon
+ v-if="confidential"
+ v-gl-tooltip
+ name="eye-slash"
+ :title="__('Confidential')"
+ class="confidential-icon gl-mr-2 align-self-baseline align-self-md-auto mt-xl-0"
+ :aria-label="__('Confidential')"
+ />
+ <a :href="computedPath" class="sortable-link gl-font-weight-normal">{{ title }}</a>
+ </div>
+
+ <!-- Info area: meta, path, and assignees -->
+ <div class="item-info-area d-flex flex-xl-grow-1 flex-shrink-0">
+ <!-- Meta area: path and attributes -->
+ <!-- If there is no room beside the path, meta attributes are put ABOVE it (flex-wrap-reverse). -->
+ <!-- See design: https://gitlab-org.gitlab.io/gitlab-design/hosted/pedro/%2383-issue-mr-rows-cards-spec-previews/#artboard16 -->
+ <div
+ class="item-meta d-flex flex-wrap-reverse justify-content-start justify-content-md-between"
+ >
+ <!-- Path area: status icon (<XL), path, issue # -->
+ <div
+ class="item-path-area item-path-id d-flex align-items-center mr-2 mt-2 mt-xl-0 ml-xl-2"
+ >
+ <gl-tooltip :target="() => this.$refs.iconElement">
+ <span v-safe-html="stateTitle"></span>
+ </gl-tooltip>
+ <span v-gl-tooltip :title="itemPath" class="path-id-text d-inline-block">{{
+ itemPath
+ }}</span>
+ <span>{{ pathIdSeparator }}{{ itemId }}</span>
+ </div>
+
+ <!-- Attributes area: CI, epic count, weight, milestone -->
+ <!-- They have a different order on large screen sizes -->
+ <div class="item-attributes-area d-flex align-items-center mt-2 mt-xl-0">
+ <span v-if="hasPipeline" class="mr-ci-status order-md-last">
+ <a :href="pipelineStatus.details_path">
+ <ci-icon v-gl-tooltip :status="pipelineStatus" :title="pipelineStatusTooltip" />
+ </a>
+ </span>
+
+ <issue-milestone
+ v-if="hasMilestone"
+ :milestone="milestone"
+ class="d-flex align-items-center item-milestone order-md-first ml-md-0"
+ />
+
+ <!-- Flex order for slots is defined in the parent component: e.g. related_issues_block.vue -->
+ <span v-if="weight > 0" class="order-md-1">
+ <issue-weight
+ :weight="weight"
+ class="item-weight gl-display-flex gl-align-items-center"
+ tag-name="span"
+ />
+ </span>
+
+ <span v-if="dueDate" class="order-md-1">
+ <issue-due-date
+ :date="dueDate"
+ :closed="Boolean(closedAt)"
+ tooltip-placement="top"
+ css-class="item-due-date gl-display-flex gl-align-items-center"
+ />
+ </span>
+
+ <issue-assignees
+ v-if="hasAssignees"
+ :assignees="assignees"
+ class="item-assignees align-items-center align-self-end flex-shrink-0 order-md-2 d-none d-md-flex"
+ />
+ </div>
+ </div>
+
+ <!-- Assignees. On small layouts, these are put here, at the end of the card. -->
+ <issue-assignees
+ v-if="assignees.length !== 0"
+ :assignees="assignees"
+ class="item-assignees d-flex align-items-center align-self-end flex-shrink-0 d-md-none ml-2"
+ />
+ </div>
+ </div>
+
+ <span
+ v-if="isLocked"
+ ref="lockIcon"
+ v-gl-tooltip
+ class="gl-px-3 gl-display-inline-block gl-cursor-not-allowed"
+ :title="lockedMessage"
+ >
+ <gl-icon name="lock" />
+ </span>
+ <gl-button
+ v-else-if="canRemove"
+ ref="removeButton"
+ v-gl-tooltip
+ icon="close"
+ category="tertiary"
+ :disabled="removeDisabled"
+ class="js-issue-item-remove-button gl-ml-3"
+ data-qa-selector="remove_related_issue_button"
+ :title="__('Remove')"
+ :aria-label="__('Remove')"
+ @click="onRemoveRequest"
+ />
+ </div>
+</template>