diff options
Diffstat (limited to 'app/assets/javascripts/members/components/action_buttons')
10 files changed, 431 insertions, 0 deletions
diff --git a/app/assets/javascripts/members/components/action_buttons/access_request_action_buttons.vue b/app/assets/javascripts/members/components/action_buttons/access_request_action_buttons.vue new file mode 100644 index 00000000000..10078d5cd64 --- /dev/null +++ b/app/assets/javascripts/members/components/action_buttons/access_request_action_buttons.vue @@ -0,0 +1,59 @@ +<script> +import ActionButtonGroup from './action_button_group.vue'; +import RemoveMemberButton from './remove_member_button.vue'; +import ApproveAccessRequestButton from './approve_access_request_button.vue'; +import { s__, sprintf } from '~/locale'; + +export default { + name: 'AccessRequestActionButtons', + components: { ActionButtonGroup, RemoveMemberButton, ApproveAccessRequestButton }, + props: { + member: { + type: Object, + required: true, + }, + permissions: { + type: Object, + required: true, + }, + isCurrentUser: { + type: Boolean, + required: true, + }, + }, + computed: { + message() { + const { user, source } = this.member; + + if (this.isCurrentUser) { + return sprintf( + s__('Members|Are you sure you want to withdraw your access request for "%{source}"'), + { source: source.name }, + ); + } + + return sprintf( + s__('Members|Are you sure you want to deny %{usersName}\'s request to join "%{source}"'), + { usersName: user.name, source: source.name }, + ); + }, + }, +}; +</script> + +<template> + <action-button-group> + <div v-if="permissions.canUpdate" class="gl-px-1"> + <approve-access-request-button :member-id="member.id" /> + </div> + <div v-if="permissions.canRemove" class="gl-px-1"> + <remove-member-button + :member-id="member.id" + :message="message" + :title="s__('Member|Deny access')" + :is-access-request="true" + icon="close" + /> + </div> + </action-button-group> +</template> diff --git a/app/assets/javascripts/members/components/action_buttons/action_button_group.vue b/app/assets/javascripts/members/components/action_buttons/action_button_group.vue new file mode 100644 index 00000000000..8356fdb60b1 --- /dev/null +++ b/app/assets/javascripts/members/components/action_buttons/action_button_group.vue @@ -0,0 +1,11 @@ +<script> +export default { + name: 'ActionButtonGroup', +}; +</script> + +<template> + <div class="gl-display-flex gl-flex-align-items-center gl-justify-content-end gl-mx-n1"> + <slot></slot> + </div> +</template> diff --git a/app/assets/javascripts/members/components/action_buttons/approve_access_request_button.vue b/app/assets/javascripts/members/components/action_buttons/approve_access_request_button.vue new file mode 100644 index 00000000000..e8a53ff173d --- /dev/null +++ b/app/assets/javascripts/members/components/action_buttons/approve_access_request_button.vue @@ -0,0 +1,42 @@ +<script> +import { mapState } from 'vuex'; +import { GlButton, GlForm, GlTooltipDirective } from '@gitlab/ui'; +import csrf from '~/lib/utils/csrf'; +import { __ } from '~/locale'; + +export default { + name: 'ApproveAccessRequestButton', + csrf, + title: __('Grant access'), + components: { GlButton, GlForm }, + directives: { + GlTooltip: GlTooltipDirective, + }, + props: { + memberId: { + type: Number, + required: true, + }, + }, + computed: { + ...mapState(['memberPath']), + approvePath() { + return this.memberPath.replace(/:id$/, `${this.memberId}/approve_access_request`); + }, + }, +}; +</script> + +<template> + <gl-form :action="approvePath" method="post"> + <input :value="$options.csrf.token" type="hidden" name="authenticity_token" /> + <gl-button + v-gl-tooltip.hover + :title="$options.title" + :aria-label="$options.title" + icon="check" + variant="success" + type="submit" + /> + </gl-form> +</template> diff --git a/app/assets/javascripts/members/components/action_buttons/group_action_buttons.vue b/app/assets/javascripts/members/components/action_buttons/group_action_buttons.vue new file mode 100644 index 00000000000..2aebfe80db5 --- /dev/null +++ b/app/assets/javascripts/members/components/action_buttons/group_action_buttons.vue @@ -0,0 +1,27 @@ +<script> +import ActionButtonGroup from './action_button_group.vue'; +import RemoveGroupLinkButton from './remove_group_link_button.vue'; + +export default { + name: 'GroupActionButtons', + components: { ActionButtonGroup, RemoveGroupLinkButton }, + props: { + member: { + type: Object, + required: true, + }, + permissions: { + type: Object, + required: true, + }, + }, +}; +</script> + +<template> + <action-button-group> + <div v-if="permissions.canRemove" class="gl-px-1"> + <remove-group-link-button :group-link="member" /> + </div> + </action-button-group> +</template> diff --git a/app/assets/javascripts/members/components/action_buttons/invite_action_buttons.vue b/app/assets/javascripts/members/components/action_buttons/invite_action_buttons.vue new file mode 100644 index 00000000000..2b0a75640e2 --- /dev/null +++ b/app/assets/javascripts/members/components/action_buttons/invite_action_buttons.vue @@ -0,0 +1,48 @@ +<script> +import ActionButtonGroup from './action_button_group.vue'; +import RemoveMemberButton from './remove_member_button.vue'; +import ResendInviteButton from './resend_invite_button.vue'; +import { s__, sprintf } from '~/locale'; + +export default { + name: 'InviteActionButtons', + components: { ActionButtonGroup, RemoveMemberButton, ResendInviteButton }, + props: { + member: { + type: Object, + required: true, + }, + permissions: { + type: Object, + required: true, + }, + }, + computed: { + message() { + const { invite, source } = this.member; + + return sprintf( + s__( + 'Members|Are you sure you want to revoke the invitation for %{inviteEmail} to join "%{source}"', + ), + { inviteEmail: invite.email, source: source.name }, + ); + }, + }, +}; +</script> + +<template> + <action-button-group> + <div v-if="permissions.canResend" class="gl-px-1"> + <resend-invite-button :member-id="member.id" /> + </div> + <div v-if="permissions.canRemove" class="gl-px-1"> + <remove-member-button + :member-id="member.id" + :message="message" + :title="s__('Member|Revoke invite')" + /> + </div> + </action-button-group> +</template> diff --git a/app/assets/javascripts/members/components/action_buttons/leave_button.vue b/app/assets/javascripts/members/components/action_buttons/leave_button.vue new file mode 100644 index 00000000000..443a962e0cf --- /dev/null +++ b/app/assets/javascripts/members/components/action_buttons/leave_button.vue @@ -0,0 +1,40 @@ +<script> +import { GlButton, GlModalDirective, GlTooltipDirective } from '@gitlab/ui'; +import { __ } from '~/locale'; +import LeaveModal from '../modals/leave_modal.vue'; +import { LEAVE_MODAL_ID } from '../../constants'; + +export default { + name: 'LeaveButton', + title: __('Leave'), + modalId: LEAVE_MODAL_ID, + components: { + GlButton, + LeaveModal, + }, + directives: { + GlModal: GlModalDirective, + GlTooltip: GlTooltipDirective, + }, + props: { + member: { + type: Object, + required: true, + }, + }, +}; +</script> + +<template> + <div> + <gl-button + v-gl-tooltip.hover + v-gl-modal="$options.modalId" + :title="$options.title" + :aria-label="$options.title" + icon="leave" + variant="danger" + /> + <leave-modal :member="member" /> + </div> +</template> diff --git a/app/assets/javascripts/members/components/action_buttons/remove_group_link_button.vue b/app/assets/javascripts/members/components/action_buttons/remove_group_link_button.vue new file mode 100644 index 00000000000..9d89cb40676 --- /dev/null +++ b/app/assets/javascripts/members/components/action_buttons/remove_group_link_button.vue @@ -0,0 +1,36 @@ +<script> +import { mapActions } from 'vuex'; +import { GlButton, GlTooltipDirective } from '@gitlab/ui'; +import { s__ } from '~/locale'; + +export default { + name: 'RemoveGroupLinkButton', + i18n: { + buttonTitle: s__('Members|Remove group'), + }, + components: { GlButton }, + directives: { + GlTooltip: GlTooltipDirective, + }, + props: { + groupLink: { + type: Object, + required: true, + }, + }, + methods: { + ...mapActions(['showRemoveGroupLinkModal']), + }, +}; +</script> + +<template> + <gl-button + v-gl-tooltip.hover + variant="danger" + :title="$options.i18n.buttonTitle" + :aria-label="$options.i18n.buttonTitle" + icon="remove" + @click="showRemoveGroupLinkModal(groupLink)" + /> +</template> diff --git a/app/assets/javascripts/members/components/action_buttons/remove_member_button.vue b/app/assets/javascripts/members/components/action_buttons/remove_member_button.vue new file mode 100644 index 00000000000..b0b7ff4ce9a --- /dev/null +++ b/app/assets/javascripts/members/components/action_buttons/remove_member_button.vue @@ -0,0 +1,57 @@ +<script> +import { mapState } from 'vuex'; +import { GlButton, GlTooltipDirective } from '@gitlab/ui'; + +export default { + name: 'RemoveMemberButton', + components: { GlButton }, + directives: { + GlTooltip: GlTooltipDirective, + }, + props: { + memberId: { + type: Number, + required: true, + }, + message: { + type: String, + required: true, + }, + title: { + type: String, + required: true, + }, + icon: { + type: String, + required: false, + default: 'remove', + }, + isAccessRequest: { + type: Boolean, + required: false, + default: false, + }, + }, + computed: { + ...mapState(['memberPath']), + computedMemberPath() { + return this.memberPath.replace(':id', this.memberId); + }, + }, +}; +</script> + +<template> + <gl-button + v-gl-tooltip.hover + class="js-remove-member-button" + variant="danger" + :title="title" + :aria-label="title" + :icon="icon" + :data-member-path="computedMemberPath" + :data-is-access-request="isAccessRequest" + :data-message="message" + data-qa-selector="delete_member_button" + /> +</template> diff --git a/app/assets/javascripts/members/components/action_buttons/resend_invite_button.vue b/app/assets/javascripts/members/components/action_buttons/resend_invite_button.vue new file mode 100644 index 00000000000..1cc3fd17e98 --- /dev/null +++ b/app/assets/javascripts/members/components/action_buttons/resend_invite_button.vue @@ -0,0 +1,41 @@ +<script> +import { mapState } from 'vuex'; +import { GlButton, GlTooltipDirective } from '@gitlab/ui'; +import csrf from '~/lib/utils/csrf'; +import { __ } from '~/locale'; + +export default { + name: 'ResendInviteButton', + csrf, + title: __('Resend invite'), + components: { GlButton }, + directives: { + GlTooltip: GlTooltipDirective, + }, + props: { + memberId: { + type: Number, + required: true, + }, + }, + computed: { + ...mapState(['memberPath']), + resendPath() { + return this.memberPath.replace(/:id$/, `${this.memberId}/resend_invite`); + }, + }, +}; +</script> + +<template> + <form :action="resendPath" method="post"> + <input :value="$options.csrf.token" type="hidden" name="authenticity_token" /> + <gl-button + v-gl-tooltip.hover + :title="$options.title" + :aria-label="$options.title" + icon="paper-airplane" + type="submit" + /> + </form> +</template> diff --git a/app/assets/javascripts/members/components/action_buttons/user_action_buttons.vue b/app/assets/javascripts/members/components/action_buttons/user_action_buttons.vue new file mode 100644 index 00000000000..f2bc9c7e876 --- /dev/null +++ b/app/assets/javascripts/members/components/action_buttons/user_action_buttons.vue @@ -0,0 +1,70 @@ +<script> +import ActionButtonGroup from './action_button_group.vue'; +import RemoveMemberButton from './remove_member_button.vue'; +import LeaveButton from './leave_button.vue'; +import { s__, sprintf } from '~/locale'; + +export default { + name: 'UserActionButtons', + components: { + ActionButtonGroup, + RemoveMemberButton, + LeaveButton, + LdapOverrideButton: () => + import('ee_component/members/components/ldap/ldap_override_button.vue'), + }, + props: { + member: { + type: Object, + required: true, + }, + isCurrentUser: { + type: Boolean, + required: true, + }, + permissions: { + type: Object, + required: true, + }, + }, + computed: { + message() { + const { user, source } = this.member; + + if (user) { + return sprintf( + s__('Members|Are you sure you want to remove %{usersName} from "%{source}"'), + { + usersName: user.name, + source: source.name, + }, + ); + } + + return sprintf( + s__('Members|Are you sure you want to remove this orphaned member from "%{source}"'), + { + source: source.name, + }, + ); + }, + }, +}; +</script> + +<template> + <action-button-group> + <div v-if="permissions.canRemove" class="gl-px-1"> + <leave-button v-if="isCurrentUser" :member="member" /> + <remove-member-button + v-else + :member-id="member.id" + :message="message" + :title="s__('Member|Remove member')" + /> + </div> + <div v-else-if="permissions.canOverride && !member.isOverridden" class="gl-px-1"> + <ldap-override-button :member="member" /> + </div> + </action-button-group> +</template> |