Commit d1f311c1 authored by peterhegman's avatar peterhegman

Fix "Confirm user" button on tabs other than "Account"

Fixes the "Confirm user" button in the admin area on all tabs other
than "Account".

Changelog: fixed
parent 003f4531
...@@ -20,3 +20,9 @@ export const I18N_USER_ACTIONS = { ...@@ -20,3 +20,9 @@ export const I18N_USER_ACTIONS = {
ban: s__('AdminUsers|Ban user'), ban: s__('AdminUsers|Ban user'),
unban: s__('AdminUsers|Unban user'), unban: s__('AdminUsers|Unban user'),
}; };
export const CONFIRM_DELETE_BUTTON_SELECTOR = '.js-delete-user-modal-button';
export const MODAL_TEXTS_CONTAINER_SELECTOR = '#js-modal-texts';
export const MODAL_MANAGER_SELECTOR = '#js-delete-user-modal';
...@@ -2,7 +2,14 @@ import Vue from 'vue'; ...@@ -2,7 +2,14 @@ import Vue from 'vue';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql'; import createDefaultClient from '~/lib/graphql';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import csrf from '~/lib/utils/csrf';
import AdminUsersApp from './components/app.vue'; import AdminUsersApp from './components/app.vue';
import ModalManager from './components/modals/user_modal_manager.vue';
import {
CONFIRM_DELETE_BUTTON_SELECTOR,
MODAL_TEXTS_CONTAINER_SELECTOR,
MODAL_MANAGER_SELECTOR,
} from './constants';
Vue.use(VueApollo); Vue.use(VueApollo);
...@@ -29,3 +36,45 @@ export const initAdminUsersApp = (el = document.querySelector('#js-admin-users-a ...@@ -29,3 +36,45 @@ export const initAdminUsersApp = (el = document.querySelector('#js-admin-users-a
}), }),
}); });
}; };
export const initDeleteUserModals = () => {
const modalsMountElement = document.querySelector(MODAL_TEXTS_CONTAINER_SELECTOR);
if (!modalsMountElement) {
return;
}
const modalConfiguration = Array.from(modalsMountElement.children).reduce((accumulator, node) => {
const { modal, ...config } = node.dataset;
return {
...accumulator,
[modal]: {
title: node.dataset.title,
...config,
content: node.innerHTML,
},
};
}, {});
// eslint-disable-next-line no-new
new Vue({
el: MODAL_MANAGER_SELECTOR,
functional: true,
methods: {
show(...args) {
this.$refs.manager.show(...args);
},
},
render(h) {
return h(ModalManager, {
ref: 'manager',
props: {
selector: CONFIRM_DELETE_BUTTON_SELECTOR,
modalConfiguration,
csrfToken: csrf.token,
},
});
},
});
};
import { initExpiresAtField } from '~/access_tokens'; import { initExpiresAtField } from '~/access_tokens';
import initConfirmModal from '~/confirm_modal';
initExpiresAtField(); initExpiresAtField();
initConfirmModal();
import Vue from 'vue'; import { initAdminUsersApp, initDeleteUserModals } from '~/admin/users';
import { initAdminUsersApp } from '~/admin/users';
import initConfirmModal from '~/confirm_modal'; import initConfirmModal from '~/confirm_modal';
import csrf from '~/lib/utils/csrf';
import Translate from '~/vue_shared/translate';
import ModalManager from './components/user_modal_manager.vue';
const CONFIRM_DELETE_BUTTON_SELECTOR = '.js-delete-user-modal-button';
const MODAL_TEXTS_CONTAINER_SELECTOR = '#js-modal-texts';
const MODAL_MANAGER_SELECTOR = '#js-delete-user-modal';
function loadModalsConfigurationFromHtml(modalsElement) {
const modalsConfiguration = {};
if (!modalsElement) {
/* eslint-disable-next-line @gitlab/require-i18n-strings */
throw new Error('Modals content element not found!');
}
Array.from(modalsElement.children).forEach((node) => {
const { modal, ...config } = node.dataset;
modalsConfiguration[modal] = {
title: node.dataset.title,
...config,
content: node.innerHTML,
};
});
return modalsConfiguration;
}
document.addEventListener('DOMContentLoaded', () => {
Vue.use(Translate);
initAdminUsersApp();
const modalConfiguration = loadModalsConfigurationFromHtml(
document.querySelector(MODAL_TEXTS_CONTAINER_SELECTOR),
);
// eslint-disable-next-line no-new
new Vue({
el: MODAL_MANAGER_SELECTOR,
functional: true,
methods: {
show(...args) {
this.$refs.manager.show(...args);
},
},
render(h) {
return h(ModalManager, {
ref: 'manager',
props: {
selector: CONFIRM_DELETE_BUTTON_SELECTOR,
modalConfiguration,
csrfToken: csrf.token,
},
});
},
});
initConfirmModal(); initAdminUsersApp();
}); initDeleteUserModals();
initConfirmModal();
...@@ -372,4 +372,36 @@ RSpec.describe 'Admin::Users::User' do ...@@ -372,4 +372,36 @@ RSpec.describe 'Admin::Users::User' do
end end
end end
end end
context 'when user has an unconfirmed email', :js do
let(:unconfirmed_user) { create(:user, :unconfirmed) }
where(:path_helper) do
[
[-> (user) { admin_user_path(user) }],
[-> (user) { projects_admin_user_path(user) }],
[-> (user) { keys_admin_user_path(user) }],
[-> (user) { admin_user_identities_path(user) }],
[-> (user) { admin_user_impersonation_tokens_path(user) }]
]
end
with_them do
it "allows an admin to force confirmation of the user's email" do
visit path_helper.call(unconfirmed_user)
click_button 'Confirm user'
page.within('[role="dialog"]') do
expect(page).to have_content("Confirm user #{unconfirmed_user.name}?")
expect(page).to have_content('This user has an unconfirmed email address. You may force a confirmation.')
click_button 'Confirm user'
end
expect(page).to have_content('Successfully confirmed')
expect(page).not_to have_button('Confirm user')
end
end
end
end end
import { GlButton, GlFormInput } from '@gitlab/ui'; import { GlButton, GlFormInput } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import DeleteUserModal from '~/pages/admin/users/components/delete_user_modal.vue'; import DeleteUserModal from '~/admin/users/components/modals/delete_user_modal.vue';
import OncallSchedulesList from '~/vue_shared/components/oncall_schedules_list.vue'; import OncallSchedulesList from '~/vue_shared/components/oncall_schedules_list.vue';
import ModalStub from './stubs/modal_stub'; import ModalStub from './stubs/modal_stub';
......
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import UserModalManager from '~/pages/admin/users/components/user_modal_manager.vue'; import UserModalManager from '~/admin/users/components/modals/user_modal_manager.vue';
import ModalStub from './stubs/modal_stub'; import ModalStub from './stubs/modal_stub';
describe('Users admin page Modal Manager', () => { describe('Users admin page Modal Manager', () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment