diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-17 14:33:21 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-17 14:33:21 +0300 |
commit | 7021455bd1ed7b125c55eb1b33c5a01f2bc55ee0 (patch) | |
tree | 5bdc2229f5198d516781f8d24eace62fc7e589e9 /app/assets/javascripts/admin/users/components | |
parent | 185b095e93520f96e9cfc31d9c3e69b498cdab7c (diff) |
Add latest changes from gitlab-org/gitlab@15-6-stable-eev15.6.0-rc42
Diffstat (limited to 'app/assets/javascripts/admin/users/components')
6 files changed, 151 insertions, 11 deletions
diff --git a/app/assets/javascripts/admin/users/components/actions/delete.vue b/app/assets/javascripts/admin/users/components/actions/delete.vue index ae0c6731271..d4f9ff4e529 100644 --- a/app/assets/javascripts/admin/users/components/actions/delete.vue +++ b/app/assets/javascripts/admin/users/components/actions/delete.vue @@ -12,6 +12,10 @@ export default { type: String, required: true, }, + userId: { + type: Number, + required: true, + }, paths: { type: Object, required: true, diff --git a/app/assets/javascripts/admin/users/components/actions/delete_with_contributions.vue b/app/assets/javascripts/admin/users/components/actions/delete_with_contributions.vue index a39df1cbfb6..413804c9a3b 100644 --- a/app/assets/javascripts/admin/users/components/actions/delete_with_contributions.vue +++ b/app/assets/javascripts/admin/users/components/actions/delete_with_contributions.vue @@ -1,17 +1,26 @@ <script> -import { GlDropdownItem } from '@gitlab/ui'; -import { s__ } from '~/locale'; +import { GlDropdownItem, GlLoadingIcon } from '@gitlab/ui'; +import { s__, __ } from '~/locale'; +import { associationsCount } from '~/api/user_api'; import eventHub, { EVENT_OPEN_DELETE_USER_MODAL } from '../modals/delete_user_modal_event_hub'; export default { + i18n: { + loading: __('Loading'), + }, components: { GlDropdownItem, + GlLoadingIcon, }, props: { username: { type: String, required: true, }, + userId: { + type: Number, + required: true, + }, paths: { type: Object, required: true, @@ -22,21 +31,38 @@ export default { default: () => [], }, }, + data() { + return { + loading: false, + }; + }, methods: { - onClick() { + async onClick() { + this.loading = true; + try { + const { data: associationsCountData } = await associationsCount(this.userId); + this.openModal(associationsCountData); + } catch (error) { + this.openModal(new Error()); + } finally { + this.loading = false; + } + }, + openModal(associationsCountData) { const { username, paths, userDeletionObstacles } = this; eventHub.$emit(EVENT_OPEN_DELETE_USER_MODAL, { username, blockPath: paths.block, deletePath: paths.deleteWithContributions, userDeletionObstacles, + associationsCount: associationsCountData, i18n: { title: s__('AdminUsers|Delete User %{username} and contributions?'), primaryButtonLabel: s__('AdminUsers|Delete user and contributions'), - messageBody: s__(`AdminUsers|You are about to permanently delete the user %{username}. This will delete all of the issues, - merge requests, and groups linked to them. To avoid data loss, - consider using the %{strongStart}block user%{strongEnd} feature instead. Once you %{strongStart}Delete user%{strongEnd}, - it cannot be undone or recovered.`), + messageBody: s__(`AdminUsers|You are about to permanently delete the user %{username}. This will delete all issues, + merge requests, groups, and projects linked to them. To avoid data loss, + consider using the %{strongStart}Block user%{strongEnd} feature instead. After you %{strongStart}Delete user%{strongEnd}, + you cannot undo this action or recover the data.`), }, }); }, @@ -45,8 +71,12 @@ export default { </script> <template> - <gl-dropdown-item @click="onClick"> - <span class="gl-text-red-500"> + <gl-dropdown-item :disabled="loading" :aria-busy="loading" @click.capture.native.stop="onClick"> + <div v-if="loading" class="gl-display-flex gl-align-items-center"> + <gl-loading-icon class="gl-mr-3" /> + {{ $options.i18n.loading }} + </div> + <span v-else class="gl-text-red-500"> <slot></slot> </span> </gl-dropdown-item> diff --git a/app/assets/javascripts/admin/users/components/associations/associations_list.vue b/app/assets/javascripts/admin/users/components/associations/associations_list.vue new file mode 100644 index 00000000000..12f98a02809 --- /dev/null +++ b/app/assets/javascripts/admin/users/components/associations/associations_list.vue @@ -0,0 +1,65 @@ +<script> +import { GlAlert } from '@gitlab/ui'; +import { s__ } from '~/locale'; +import AssociationsListItem from './associations_list_item.vue'; + +export default { + i18n: { + errorMessage: s__( + "AdminUsers|An error occurred while fetching this user's contributions, and the request cannot return the number of issues, merge requests, groups, and projects linked to this user. If you proceed with deleting the user, all their contributions will still be deleted.", + ), + }, + components: { + AssociationsListItem, + GlAlert, + }, + props: { + associationsCount: { + type: [Object, Error], + required: true, + }, + }, + computed: { + hasError() { + return this.associationsCount instanceof Error; + }, + hasAssociations() { + return Object.values(this.associationsCount).some((count) => count > 0); + }, + }, +}; +</script> + +<template> + <gl-alert v-if="hasError" class="gl-mb-5" variant="danger" :dismissible="false">{{ + $options.i18n.errorMessage + }}</gl-alert> + <ul v-else-if="hasAssociations" class="gl-mb-5"> + <associations-list-item + v-if="associationsCount.groups_count" + :message="n__('%{count} group', '%{count} groups', associationsCount.groups_count)" + :count="associationsCount.groups_count" + /> + <associations-list-item + v-if="associationsCount.projects_count" + :message="n__('%{count} project', '%{count} projects', associationsCount.projects_count)" + :count="associationsCount.projects_count" + /> + <associations-list-item + v-if="associationsCount.issues_count" + :message="n__('%{count} issue', '%{count} issues', associationsCount.issues_count)" + :count="associationsCount.issues_count" + /> + <associations-list-item + v-if="associationsCount.merge_requests_count" + :message=" + n__( + '%{count} merge request', + '%{count} merge requests', + associationsCount.merge_requests_count, + ) + " + :count="associationsCount.merge_requests_count" + /> + </ul> +</template> diff --git a/app/assets/javascripts/admin/users/components/associations/associations_list_item.vue b/app/assets/javascripts/admin/users/components/associations/associations_list_item.vue new file mode 100644 index 00000000000..88cb24aaf8f --- /dev/null +++ b/app/assets/javascripts/admin/users/components/associations/associations_list_item.vue @@ -0,0 +1,27 @@ +<script> +import { GlSprintf } from '@gitlab/ui'; + +export default { + components: { GlSprintf }, + props: { + message: { + type: String, + required: true, + }, + count: { + type: Number, + required: true, + }, + }, +}; +</script> + +<template> + <li> + <gl-sprintf :message="message"> + <template #count> + <strong>{{ count }}</strong> + </template> + </gl-sprintf> + </li> +</template> diff --git a/app/assets/javascripts/admin/users/components/modals/delete_user_modal.vue b/app/assets/javascripts/admin/users/components/modals/delete_user_modal.vue index 31fe86775ee..7f02d6dd5b1 100644 --- a/app/assets/javascripts/admin/users/components/modals/delete_user_modal.vue +++ b/app/assets/javascripts/admin/users/components/modals/delete_user_modal.vue @@ -2,6 +2,7 @@ import { GlModal, GlButton, GlFormInput, GlSprintf } from '@gitlab/ui'; import { s__, sprintf } from '~/locale'; import UserDeletionObstaclesList from '~/vue_shared/components/user_deletion_obstacles/user_deletion_obstacles_list.vue'; +import AssociationsList from '../associations/associations_list.vue'; import eventHub, { EVENT_OPEN_DELETE_USER_MODAL } from './delete_user_modal_event_hub'; export default { @@ -11,6 +12,7 @@ export default { GlFormInput, GlSprintf, UserDeletionObstaclesList, + AssociationsList, }, props: { csrfToken: { @@ -25,6 +27,7 @@ export default { blockPath: '', deletePath: '', userDeletionObstacles: [], + associationsCount: {}, i18n: { title: '', primaryButtonLabel: '', @@ -53,11 +56,19 @@ export default { eventHub.$off(EVENT_OPEN_DELETE_USER_MODAL, this.onOpenEvent); }, methods: { - onOpenEvent({ username, blockPath, deletePath, userDeletionObstacles, i18n }) { + onOpenEvent({ + username, + blockPath, + deletePath, + userDeletionObstacles, + associationsCount = {}, + i18n, + }) { this.username = username; this.blockPath = blockPath; this.deletePath = deletePath; this.userDeletionObstacles = userDeletionObstacles; + this.associationsCount = associationsCount; this.i18n = i18n; this.openModal(); }, @@ -100,8 +111,10 @@ export default { :user-name="trimmedUsername" /> + <associations-list :associations-count="associationsCount" /> + <p> - <gl-sprintf :message="s__('AdminUsers|To confirm, type %{username}')"> + <gl-sprintf :message="s__('AdminUsers|To confirm, type %{username}.')"> <template #username> <code data-testid="confirm-username" class="gl-white-space-pre-wrap">{{ trimmedUsername diff --git a/app/assets/javascripts/admin/users/components/user_actions.vue b/app/assets/javascripts/admin/users/components/user_actions.vue index 691a292673c..c1fb80959cf 100644 --- a/app/assets/javascripts/admin/users/components/user_actions.vue +++ b/app/assets/javascripts/admin/users/components/user_actions.vue @@ -139,6 +139,7 @@ export default { :key="action" :paths="userPaths" :username="user.name" + :user-id="user.id" :user-deletion-obstacles="obstaclesForUserDeletion" :data-testid="`delete-${action}`" > |