summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/diffs/components/diff_gutter_avatars.vue
blob: 7e50a0aed84424fe011946a6111bb4e1d9a8eefd (plain)
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
<script>
import { mapActions } from 'vuex';
import Icon from '~/vue_shared/components/icon.vue';
import tooltip from '~/vue_shared/directives/tooltip';
import { pluralize, truncate } from '~/lib/utils/text_utility';
import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
import { COUNT_OF_AVATARS_IN_GUTTER, LENGTH_OF_AVATAR_TOOLTIP } from '../constants';

export default {
  directives: {
    tooltip,
  },
  components: {
    Icon,
    UserAvatarImage,
  },
  props: {
    discussions: {
      type: Array,
      required: true,
    },
  },
  computed: {
    discussionsExpanded() {
      return this.discussions.every(discussion => discussion.expanded);
    },
    allDiscussions() {
      return this.discussions.reduce((acc, note) => acc.concat(note.notes), []);
    },
    notesInGutter() {
      return this.allDiscussions.slice(0, COUNT_OF_AVATARS_IN_GUTTER).map(n => ({
        note: n.note,
        author: n.author,
      }));
    },
    moreCount() {
      return this.allDiscussions.length - this.notesInGutter.length;
    },
    moreText() {
      if (this.moreCount === 0) {
        return '';
      }

      return pluralize(`${this.moreCount} more comment`, this.moreCount);
    },
  },
  methods: {
    ...mapActions(['toggleDiscussion']),
    getTooltipText(noteData) {
      let { note } = noteData;

      if (note.length > LENGTH_OF_AVATAR_TOOLTIP) {
        note = truncate(note, LENGTH_OF_AVATAR_TOOLTIP);
      }

      return `${noteData.author.name}: ${note}`;
    },
    toggleDiscussions() {
      this.discussions.forEach(discussion => {
        this.toggleDiscussion({
          discussionId: discussion.id,
        });
      });
    },
  },
};
</script>

<template>
  <div class="diff-comment-avatar-holders">
    <button
      v-if="discussionsExpanded"
      type="button"
      aria-label="Show comments"
      class="diff-notes-collapse js-diff-comment-avatar js-diff-comment-button"
      @click="toggleDiscussions"
    >
      <icon
        :size="12"
        name="collapse"
      />
    </button>
    <template v-else>
      <user-avatar-image
        v-for="note in notesInGutter"
        :key="note.id"
        :img-src="note.author.avatar_url"
        :tooltip-text="getTooltipText(note)"
        :size="19"
        class="diff-comment-avatar js-diff-comment-avatar"
        @click.native="toggleDiscussions"
      />
      <span
        v-tooltip
        v-if="moreText"
        :title="moreText"
        class="diff-comments-more-count has-tooltip js-diff-comment-avatar js-diff-comment-plus"
        data-container="body"
        data-placement="top"
        role="button"
        @click="toggleDiscussions"
      >+{{ moreCount }}</span>
    </template>
  </div>
</template>