summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue')
-rw-r--r--app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue128
1 files changed, 67 insertions, 61 deletions
diff --git a/app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue b/app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue
index e82a271d007..cbd68f2513a 100644
--- a/app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue
+++ b/app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue
@@ -1,15 +1,19 @@
<script>
-// NOTE! For the first iteration, we are simply copying the implementation of Assignees
-// It will soon be overhauled in Issue https://gitlab.com/gitlab-org/gitlab/-/issues/233736
-import { __, sprintf } from '~/locale';
+import { GlButton, GlTooltipDirective, GlIcon } from '@gitlab/ui';
import ReviewerAvatarLink from './reviewer_avatar_link.vue';
-const DEFAULT_RENDER_COUNT = 5;
+const LOADING_STATE = 'loading';
+const SUCCESS_STATE = 'success';
export default {
components: {
+ GlButton,
+ GlIcon,
ReviewerAvatarLink,
},
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
props: {
users: {
type: Array,
@@ -28,76 +32,78 @@ export default {
data() {
return {
showLess: true,
+ loadingStates: {},
};
},
- computed: {
- firstUser() {
- return this.users[0];
- },
- hasOneUser() {
- return this.users.length === 1;
- },
- hiddenReviewersLabel() {
- const { numberOfHiddenReviewers } = this;
- return sprintf(__('+ %{numberOfHiddenReviewers} more'), { numberOfHiddenReviewers });
- },
- renderShowMoreSection() {
- return this.users.length > DEFAULT_RENDER_COUNT;
- },
- numberOfHiddenReviewers() {
- 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}`;
+ watch: {
+ users: {
+ handler(users) {
+ this.loadingStates = users.reduce(
+ (acc, user) => ({
+ ...acc,
+ [user.id]: acc[user.id] || null,
+ }),
+ this.loadingStates,
+ );
+ },
+ immediate: true,
},
},
methods: {
toggleShowLess() {
this.showLess = !this.showLess;
},
+ reRequestReview(userId) {
+ this.loadingStates[userId] = LOADING_STATE;
+ this.$emit('request-review', { userId, callback: this.requestReviewComplete });
+ },
+ requestReviewComplete(userId, success) {
+ if (success) {
+ this.loadingStates[userId] = SUCCESS_STATE;
+
+ setTimeout(() => {
+ this.loadingStates[userId] = null;
+ }, 1500);
+ } else {
+ this.loadingStates[userId] = null;
+ }
+ },
},
+ LOADING_STATE,
+ SUCCESS_STATE,
};
</script>
<template>
- <reviewer-avatar-link
- v-if="hasOneUser"
- #default="{ user }"
- tooltip-placement="left"
- :tooltip-has-name="false"
- :user="firstUser"
- :root-path="rootPath"
- :issuable-type="issuableType"
- >
- <div class="gl-ml-3 gl-line-height-normal">
- <div class="author">{{ user.name }}</div>
- <div class="username">{{ username }}</div>
- </div>
- </reviewer-avatar-link>
- <div v-else>
- <div class="user-list">
- <div v-for="user in uncollapsedUsers" :key="user.id" class="user-item">
- <reviewer-avatar-link :user="user" :root-path="rootPath" :issuable-type="issuableType" />
- </div>
- </div>
- <div v-if="renderShowMoreSection" class="user-list-more">
- <button
- type="button"
- class="btn-link"
- data-qa-selector="more_reviewers_link"
- @click="toggleShowLess"
- >
- <template v-if="showLess">
- {{ hiddenReviewersLabel }}
- </template>
- <template v-else>{{ __('- show less') }}</template>
- </button>
+ <div>
+ <div
+ v-for="(user, index) in users"
+ :key="user.id"
+ :class="{ 'gl-mb-3': index !== users.length - 1 }"
+ data-testid="reviewer"
+ >
+ <reviewer-avatar-link :user="user" :root-path="rootPath" :issuable-type="issuableType">
+ <div class="gl-ml-3">@{{ user.username }}</div>
+ </reviewer-avatar-link>
+ <gl-icon
+ v-if="loadingStates[user.id] === $options.SUCCESS_STATE"
+ :size="24"
+ name="check"
+ class="float-right gl-text-green-500"
+ data-testid="re-request-success"
+ />
+ <gl-button
+ v-else-if="user.can_update_merge_request && user.reviewed"
+ v-gl-tooltip.left
+ :title="__('Re-request review')"
+ :loading="loadingStates[user.id] === $options.LOADING_STATE"
+ class="float-right gl-text-gray-500!"
+ size="small"
+ icon="redo"
+ variant="link"
+ data-testid="re-request-button"
+ @click="reRequestReview(user.id)"
+ />
</div>
</div>
</template>