All files / app/assets/javascripts/mr_popover/components mr_popover.vue

68.18% Statements 15/22
66.67% Branches 8/12
80% Functions 8/10
68.18% Lines 15/22

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116    15x 15x 15x 15x 15x                                                           4x           2x     2x     2x           2x       2x           2x       6x     6x                                       66x                                                
<script>
/* eslint-disable @gitlab/vue-require-i18n-strings */
import { GlPopover, GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui';
import CiIcon from '../../vue_shared/components/ci_icon.vue';
import timeagoMixin from '../../vue_shared/mixins/timeago';
import { mrStates, humanMRStates } from '../constants';
import query from '../queries/merge_request.query.graphql';
 
export default {
  // name: 'MRPopover' is a false positive: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/25
  name: 'MRPopover', // eslint-disable-line @gitlab/require-i18n-strings
  components: {
    GlPopover,
    GlSkeletonLoading,
    CiIcon,
  },
  mixins: [timeagoMixin],
  props: {
    target: {
      type: HTMLAnchorElement,
      required: true,
    },
    projectPath: {
      type: String,
      required: true,
    },
    mergeRequestIID: {
      type: String,
      required: true,
    },
    mergeRequestTitle: {
      type: String,
      required: true,
    },
  },
  data() {
    return {
      mergeRequest: {},
    };
  },
  computed: {
    detailedStatus() {
      return this.mergeRequest.headPipeline && this.mergeRequest.headPipeline.detailedStatus;
    },
    formattedTime() {
      return this.timeFormatted(this.mergeRequest.createdAt);
    },
    statusBoxClass() {
      switch (this.mergeRequest.state) {
        case mrStates.merged:
          return 'status-box-mr-merged';
        case mrStates.closed:
          return 'status-box-closed';
        default:
          return 'status-box-open';
      }
    },
    stateHumanName() {
      switch (this.mergeRequest.state) {
        case mrStates.merged:
          return humanMRStates.merged;
        case mrStates.closed:
          return humanMRStates.closed;
        default:
          return humanMRStates.open;
      }
    },
    title() {
      return this.mergeRequest?.title || this.mergeRequestTitle;
    },
    showDetails() {
      return Object.keys(this.mergeRequest).length > 0;
    },
  },
  apollo: {
    mergeRequest: {
      query,
      update: (data) => data.project.mergeRequest,
      variables() {
        const { projectPath, mergeRequestIID } = this;
 
        return {
          projectPath,
          mergeRequestIID,
        };
      },
    },
  },
};
</script>
 
<template>
  <gl-popover :target="target" boundary="viewport" placement="top" show>
    <div class="mr-popover">
      <div v-if="$apollo.queries.mergeRequest.loading">
        <gl-skeleton-loading :lines="1" class="animation-container-small mt-1" />
      </div>
      <div v-else-if="showDetails" class="d-flex align-items-center justify-content-between">
        <div class="d-inline-flex align-items-center">
          <div :class="`issuable-status-box status-box ${statusBoxClass}`">
            {{ stateHumanName }}
          </div>
          <span class="gl-text-secondary">Opened <time v-text="formattedTime"></time></span>
        </div>
        <ci-icon v-if="detailedStatus" :status="detailedStatus" />
      </div>
      <h5 v-if="!$apollo.queries.mergeRequest.loading" class="my-2">{{ title }}</h5>
      <!-- eslint-disable @gitlab/vue-require-i18n-strings -->
      <div class="gl-text-secondary">
        {{ `${projectPath}!${mergeRequestIID}` }}
      </div>
      <!-- eslint-enable @gitlab/vue-require-i18n-strings -->
    </div>
  </gl-popover>
</template>