All files / app/assets/javascripts/sidebar/components/assignees uncollapsed_assignee_list.vue

6.66% Statements 1/15
0% Branches 0/5
0% Functions 0/10
6.66% Lines 1/15

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                21x                                                                                                                                                                                                                      
<script>
import { GlButton } from '@gitlab/ui';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { TYPE_ISSUE, TYPE_MERGE_REQUEST } from '~/issues/constants';
import { __, sprintf } from '~/locale';
import AssigneeAvatarLink from './assignee_avatar_link.vue';
import UserNameWithStatus from './user_name_with_status.vue';
 
const DEFAULT_RENDER_COUNT = 5;
 
export default {
  components: {
    GlButton,
    AssigneeAvatarLink,
    UserNameWithStatus,
  },
  mixins: [glFeatureFlagsMixin()],
  props: {
    users: {
      type: Array,
      required: true,
    },
    issuableType: {
      type: String,
      required: false,
      default: TYPE_ISSUE,
    },
  },
  data() {
    return {
      showLess: true,
    };
  },
  computed: {
    firstUser() {
      return this.users[0];
    },
    hiddenAssigneesLabel() {
      const { numberOfHiddenAssignees } = this;
      return sprintf(__('+ %{numberOfHiddenAssignees} more'), { numberOfHiddenAssignees });
    },
    renderShowMoreSection() {
      return this.users.length > DEFAULT_RENDER_COUNT;
    },
    numberOfHiddenAssignees() {
      return this.users.length - DEFAULT_RENDER_COUNT;
    },
    uncollapsedUsers() {
      const uncollapsedLength = this.showLess
        ? Math.min(this.users.length, DEFAULT_RENDER_COUNT)
        : this.users.length;
      return this.showLess ? this.users.slice(0, uncollapsedLength) : this.users;
    },
    username() {
      return `@${this.firstUser.username}`;
    },
    isMergeRequest() {
      return this.issuableType === TYPE_MERGE_REQUEST;
    },
  },
  methods: {
    toggleShowLess() {
      this.showLess = !this.showLess;
    },
    userAvailability(u) {
      Iif (this.issuableType === TYPE_MERGE_REQUEST) {
        return u?.availability || '';
      }
      return u?.status?.availability || '';
    },
  },
};
</script>
 
<template>
  <div>
    <div class="gl-display-flex gl-flex-wrap">
      <div
        v-for="(user, index) in uncollapsedUsers"
        :key="user.id"
        :class="{
          'gl-mb-3': index !== users.length - 1 || users.length > 5,
        }"
        class="assignee-grid gl-display-grid gl-align-items-center gl-w-full"
      >
        <assignee-avatar-link
          :user="user"
          :issuable-type="issuableType"
          class="gl-word-break-word"
          data-css-area="user"
        >
          <div
            class="gl-ml-3 gl-line-height-normal gl-display-grid gl-align-items-center"
            data-testid="username"
          >
            <user-name-with-status :name="user.name" :availability="userAvailability(user)" />
          </div>
        </assignee-avatar-link>
      </div>
    </div>
    <div v-if="renderShowMoreSection" class="gl-hover-text-blue-800" data-testid="user-list-more">
      <gl-button
        category="tertiary"
        size="small"
        data-testid="user-list-more-button"
        @click="toggleShowLess"
      >
        <template v-if="showLess">
          {{ hiddenAssigneesLabel }}
        </template>
        <template v-else>{{ __('- show less') }}</template>
      </gl-button>
    </div>
  </div>
</template>