Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-10-10 03:06:44 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-10-10 03:06:44 +0300
commit308146dc398fd4c13453048105498018459e0985 (patch)
treed843eb63c1672e4b18c483907e2cd4aa7fca708e /app/assets/javascripts/pages/admin
parent4b28d5ae770c6bd332283a3f13ceae06329c409b (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/pages/admin')
-rw-r--r--app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue113
-rw-r--r--app/assets/javascripts/pages/admin/users/components/user_modal_manager.vue77
-rw-r--r--app/assets/javascripts/pages/admin/users/components/user_operation_confirmation_modal.vue70
-rw-r--r--app/assets/javascripts/pages/admin/users/index.js75
4 files changed, 237 insertions, 98 deletions
diff --git a/app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue b/app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue
index e8905b479ee..78aaa9df0ec 100644
--- a/app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue
+++ b/app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue
@@ -1,37 +1,46 @@
<script>
import _ from 'underscore';
-import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue';
+import { GlModal, GlButton, GlFormInput } from '@gitlab/ui';
import { s__, sprintf } from '~/locale';
export default {
components: {
- DeprecatedModal,
+ GlModal,
+ GlButton,
+ GlFormInput,
},
props: {
+ title: {
+ type: String,
+ required: true,
+ },
+ content: {
+ type: String,
+ required: true,
+ },
+ action: {
+ type: String,
+ required: true,
+ },
+ secondaryAction: {
+ type: String,
+ required: true,
+ },
deleteUserUrl: {
type: String,
- required: false,
- default: '',
+ required: true,
},
blockUserUrl: {
type: String,
- required: false,
- default: '',
- },
- deleteContributions: {
- type: Boolean,
- required: false,
- default: false,
+ required: true,
},
username: {
type: String,
- required: false,
- default: '',
+ required: true,
},
csrfToken: {
type: String,
- required: false,
- default: '',
+ required: true,
},
},
data() {
@@ -40,32 +49,12 @@ export default {
};
},
computed: {
- title() {
- const keepContributionsTitle = s__('AdminUsers|Delete User %{username}?');
- const deleteContributionsTitle = s__('AdminUsers|Delete User %{username} and contributions?');
-
- return sprintf(
- this.deleteContributions ? deleteContributionsTitle : keepContributionsTitle,
- {
- username: `'${_.escape(this.username)}'`,
- },
- false,
- );
+ modalTitle() {
+ return sprintf(this.title, { username: this.username });
},
text() {
- const keepContributionsText = s__(`AdminArea|
- You are about to permanently delete the user %{username}.
- Issues, merge requests, and groups linked to them will be transferred to a system-wide "Ghost-user".
- To avoid data loss, consider using the %{strong_start}block user%{strong_end} feature instead.
- Once you %{strong_start}Delete user%{strong_end}, it cannot be undone or recovered.`);
-
- const deleteContributionsText = s__(`AdminArea|
- 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 %{strong_start}block user%{strong_end} feature instead.
- Once you %{strong_start}Delete user%{strong_end}, it cannot be undone or recovered.`);
return sprintf(
- this.deleteContributions ? deleteContributionsText : keepContributionsText,
+ this.content,
{
username: `<strong>${_.escape(this.username)}</strong>`,
strong_start: '<strong>',
@@ -83,12 +72,7 @@ export default {
false,
);
},
- primaryButtonLabel() {
- const keepContributionsLabel = s__('AdminUsers|Delete user');
- const deleteContributionsLabel = s__('AdminUsers|Delete user and contributions');
- return this.deleteContributions ? deleteContributionsLabel : keepContributionsLabel;
- },
secondaryButtonLabel() {
return s__('AdminUsers|Block user');
},
@@ -97,8 +81,12 @@ export default {
},
},
methods: {
+ show() {
+ this.$refs.modal.show();
+ },
onCancel() {
this.enteredUsername = '';
+ this.$refs.modal.hide();
},
onSecondaryAction() {
const { form } = this.$refs;
@@ -117,43 +105,28 @@ export default {
</script>
<template>
- <deprecated-modal
- id="delete-user-modal"
- :title="title"
- :text="text"
- :primary-button-label="primaryButtonLabel"
- :secondary-button-label="secondaryButtonLabel"
- :submit-disabled="!canSubmit"
- kind="danger"
- @submit="onSubmit"
- @cancel="onCancel"
- >
- <template slot="body" slot-scope="props">
- <p v-html="props.text"></p>
+ <gl-modal ref="modal" modal-id="delete-user-modal" :title="modalTitle" kind="danger">
+ <template>
+ <p v-html="text"></p>
<p v-html="confirmationTextLabel"></p>
<form ref="form" :action="deleteUserUrl" method="post">
<input ref="method" type="hidden" name="_method" value="delete" />
<input :value="csrfToken" type="hidden" name="authenticity_token" />
- <input
+ <gl-form-input
v-model="enteredUsername"
+ autofocus
type="text"
name="username"
- class="form-control"
- aria-labelledby="input-label"
autocomplete="off"
/>
</form>
</template>
- <template slot="secondary-button">
- <button
- :disabled="!canSubmit"
- type="button"
- class="btn js-secondary-button btn-warning"
- data-dismiss="modal"
- @click="onSecondaryAction"
- >
- {{ secondaryButtonLabel }}
- </button>
+ <template slot="modal-footer">
+ <gl-button variant="secondary" @click="onCancel">{{ s__('Cancel') }}</gl-button>
+ <gl-button :disabled="!canSubmit" variant="warning" @click="onSecondaryAction">
+ {{ secondaryAction }}
+ </gl-button>
+ <gl-button :disabled="!canSubmit" variant="danger" @click="onSubmit">{{ action }}</gl-button>
</template>
- </deprecated-modal>
+ </gl-modal>
</template>
diff --git a/app/assets/javascripts/pages/admin/users/components/user_modal_manager.vue b/app/assets/javascripts/pages/admin/users/components/user_modal_manager.vue
new file mode 100644
index 00000000000..a08d32028c3
--- /dev/null
+++ b/app/assets/javascripts/pages/admin/users/components/user_modal_manager.vue
@@ -0,0 +1,77 @@
+<script>
+export default {
+ props: {
+ modalConfiguration: {
+ required: true,
+ type: Object,
+ },
+ actionModals: {
+ required: true,
+ type: Object,
+ },
+ csrfToken: {
+ required: true,
+ type: String,
+ },
+ },
+ data() {
+ return {
+ currentModalData: null,
+ };
+ },
+ computed: {
+ activeModal() {
+ if (!this.currentModalData) return null;
+ const { glModalAction: action } = this.currentModalData;
+
+ return this.actionModals[action];
+ },
+
+ modalProps() {
+ const { glModalAction: requestedAction } = this.currentModalData;
+ return {
+ ...this.modalConfiguration[requestedAction],
+ ...this.currentModalData,
+ csrfToken: this.csrfToken,
+ };
+ },
+ },
+
+ mounted() {
+ document.addEventListener('click', this.handleClick);
+ },
+
+ beforeDestroy() {
+ document.removeEventListener('click', this.handleClick);
+ },
+
+ methods: {
+ handleClick(e) {
+ const { glModalAction: action } = e.target.dataset;
+ if (!action) return;
+
+ this.show(e.target.dataset);
+ e.preventDefault();
+ },
+
+ show(modalData) {
+ const { glModalAction: requestedAction } = modalData;
+ if (!this.actionModals[requestedAction]) {
+ throw new Error(`Requested non-existing modal action ${requestedAction}`);
+ }
+ if (!this.modalConfiguration[requestedAction]) {
+ throw new Error(`Modal action ${requestedAction} has no configuration in HTML`);
+ }
+
+ this.currentModalData = modalData;
+
+ return this.$nextTick().then(() => {
+ this.$refs.modal.show();
+ });
+ },
+ },
+};
+</script>
+<template>
+ <div :is="activeModal" v-if="activeModal" ref="modal" v-bind="modalProps" />
+</template>
diff --git a/app/assets/javascripts/pages/admin/users/components/user_operation_confirmation_modal.vue b/app/assets/javascripts/pages/admin/users/components/user_operation_confirmation_modal.vue
new file mode 100644
index 00000000000..4c335cfb018
--- /dev/null
+++ b/app/assets/javascripts/pages/admin/users/components/user_operation_confirmation_modal.vue
@@ -0,0 +1,70 @@
+<script>
+import { GlModal } from '@gitlab/ui';
+import { sprintf } from '~/locale';
+
+export default {
+ components: {
+ GlModal,
+ },
+ props: {
+ title: {
+ type: String,
+ required: true,
+ },
+ content: {
+ type: String,
+ required: true,
+ },
+ action: {
+ type: String,
+ required: true,
+ },
+ url: {
+ type: String,
+ required: true,
+ },
+ username: {
+ type: String,
+ required: true,
+ },
+ csrfToken: {
+ type: String,
+ required: true,
+ },
+ method: {
+ type: String,
+ required: false,
+ default: 'put',
+ },
+ },
+ computed: {
+ modalTitle() {
+ return sprintf(this.title, { username: this.username });
+ },
+ },
+ methods: {
+ show() {
+ this.$refs.modal.show();
+ },
+ submit() {
+ this.$refs.form.submit();
+ },
+ },
+};
+</script>
+<template>
+ <gl-modal
+ ref="modal"
+ modal-id="user-operation-modal"
+ :title="modalTitle"
+ ok-variant="warning"
+ :ok-title="action"
+ @ok="submit"
+ >
+ <form ref="form" :action="url" method="post">
+ <span v-html="content"></span>
+ <input ref="method" type="hidden" name="_method" :value="method" />
+ <input :value="csrfToken" type="hidden" name="authenticity_token" />
+ </form>
+ </gl-modal>
+</template>
diff --git a/app/assets/javascripts/pages/admin/users/index.js b/app/assets/javascripts/pages/admin/users/index.js
index 45046688b57..bc96e88351b 100644
--- a/app/assets/javascripts/pages/admin/users/index.js
+++ b/app/assets/javascripts/pages/admin/users/index.js
@@ -1,46 +1,65 @@
-import $ from 'jquery';
import Vue from 'vue';
import Translate from '~/vue_shared/translate';
+import ModalManager from './components/user_modal_manager.vue';
+import DeleteUserModal from './components/delete_user_modal.vue';
+import UserOperationConfirmationModal from './components/user_operation_confirmation_modal.vue';
import csrf from '~/lib/utils/csrf';
-import deleteUserModal from './components/delete_user_modal.vue';
+const MODAL_TEXTS_CONTAINER_SELECTOR = '#modal-texts';
+const MODAL_MANAGER_SELECTOR = '#user-modal';
+const ACTION_MODALS = {
+ deactivate: UserOperationConfirmationModal,
+ block: UserOperationConfirmationModal,
+ delete: DeleteUserModal,
+ 'delete-with-contributions': DeleteUserModal,
+};
+
+function loadModalsConfigurationFromHtml(modalsElement) {
+ const modalsConfiguration = {};
+
+ if (!modalsElement) {
+ /* eslint-disable-next-line @gitlab/i18n/no-non-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);
- const deleteUserModalEl = document.getElementById('delete-user-modal');
+ const modalConfiguration = loadModalsConfigurationFromHtml(
+ document.querySelector(MODAL_TEXTS_CONTAINER_SELECTOR),
+ );
- const deleteModal = new Vue({
- el: deleteUserModalEl,
- data: {
- deleteUserUrl: '',
- blockUserUrl: '',
- deleteContributions: '',
- username: '',
+ // eslint-disable-next-line no-new
+ new Vue({
+ el: MODAL_MANAGER_SELECTOR,
+ functional: true,
+ methods: {
+ show(...args) {
+ this.$refs.manager.show(...args);
+ },
},
- render(createElement) {
- return createElement(deleteUserModal, {
+ render(h) {
+ return h(ModalManager, {
+ ref: 'manager',
props: {
- deleteUserUrl: this.deleteUserUrl,
- blockUserUrl: this.blockUserUrl,
- deleteContributions: this.deleteContributions,
- username: this.username,
+ modalConfiguration,
+ actionModals: ACTION_MODALS,
csrfToken: csrf.token,
},
});
},
});
-
- $(document).on('shown.bs.modal', event => {
- if (event.relatedTarget.classList.contains('delete-user-button')) {
- const buttonProps = event.relatedTarget.dataset;
- deleteModal.deleteUserUrl = buttonProps.deleteUserUrl;
- deleteModal.blockUserUrl = buttonProps.blockUserUrl;
- deleteModal.deleteContributions = event.relatedTarget.hasAttribute(
- 'data-delete-contributions',
- );
- deleteModal.username = buttonProps.username;
- }
- });
});