All files / ee/app/assets/javascripts/license_compliance/components license_component_links.vue

100% Statements 14/14
100% Branches 4/4
100% Functions 9/9
100% Lines 14/14

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  5x   5x   5x 5x                                               31x     47x     47x     47x     47x     31x 31x         31x         75x           381x                                                                                            
<script>
import { GlLink, GlIntersperse, GlModal, GlButton, GlModalDirective } from '@gitlab/ui';
import { uniqueId } from 'lodash';
import { sprintf, s__ } from '~/locale';
 
const MODAL_ID_PREFIX = 'license-component-link-modal-';
export const VISIBLE_COMPONENT_COUNT = 2;
 
export default {
  components: {
    GlIntersperse,
    GlLink,
    GlButton,
    GlModal,
  },
  directives: {
    GlModalDirective,
  },
  props: {
    title: {
      type: String,
      required: true,
    },
    components: {
      type: Array,
      required: true,
    },
  },
  computed: {
    modalId() {
      return uniqueId(MODAL_ID_PREFIX);
    },
    visibleComponents() {
      return this.components.slice(0, VISIBLE_COMPONENT_COUNT);
    },
    remainingComponentsCount() {
      return Math.max(0, this.components.length - VISIBLE_COMPONENT_COUNT);
    },
    hasComponentsInModal() {
      return this.remainingComponentsCount > 0;
    },
    lastSeparator() {
      return ` ${s__('SeriesFinalConjunction|and')} `;
    },
    modalButtonText() {
      const { remainingComponentsCount } = this;
      return sprintf(s__('Licenses|%{remainingComponentsCount} more'), {
        remainingComponentsCount,
      });
    },
    modalActionText() {
      return s__('Modal|Close');
    },
  },
  methods: {
    getComponentLabel({ name, version }) {
      return version ? `${name} (${version})` : name;
    },
  },
};
</script>
 
<template>
  <div>
    <gl-intersperse :last-separator="lastSeparator" class="js-component-links-component-list">
      <span
        v-for="(component, index) in visibleComponents"
        :key="index"
        class="js-component-links-component-list-item"
      >
        <gl-link v-if="component.blob_path" :href="component.blob_path" target="_blank">{{
          getComponentLabel(component)
        }}</gl-link>
        <template v-else>{{ getComponentLabel(component) }}</template>
      </span>
      <gl-button
        v-if="hasComponentsInModal"
        v-gl-modal-directive="modalId"
        variant="link"
        class="align-baseline js-component-links-modal-trigger"
      >
        {{ modalButtonText }}
      </gl-button>
    </gl-intersperse>
    <gl-modal
      v-if="hasComponentsInModal"
      :title="title"
      :modal-id="modalId"
      :ok-title="modalActionText"
      ok-only
      ok-variant="secondary"
    >
      <h5>{{ s__('Licenses|Components') }}</h5>
      <ul class="list-unstyled overflow-auto mh-50vh">
        <li
          v-for="component in components"
          :key="component.name"
          class="js-component-links-modal-item"
        >
          <gl-link v-if="component.blob_path" :href="component.blob_path" target="_blank">{{
            component.name
          }}</gl-link>
          <span v-else>{{ component.name }}</span>
        </li>
      </ul>
    </gl-modal>
  </div>
</template>