summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/invite_members
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-10-21 07:08:36 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-10-21 07:08:36 +0000
commit48aff82709769b098321c738f3444b9bdaa694c6 (patch)
treee00c7c43e2d9b603a5a6af576b1685e400410dee /app/assets/javascripts/invite_members
parent879f5329ee916a948223f8f43d77fba4da6cd028 (diff)
downloadgitlab-ce-48aff82709769b098321c738f3444b9bdaa694c6.tar.gz
Add latest changes from gitlab-org/gitlab@13-5-stable-eev13.5.0-rc42
Diffstat (limited to 'app/assets/javascripts/invite_members')
-rw-r--r--app/assets/javascripts/invite_members/components/invite_members_modal.vue224
-rw-r--r--app/assets/javascripts/invite_members/components/invite_members_trigger.vue38
-rw-r--r--app/assets/javascripts/invite_members/event_hub.js3
-rw-r--r--app/assets/javascripts/invite_members/init_invite_members_modal.js25
-rw-r--r--app/assets/javascripts/invite_members/init_invite_members_trigger.js20
5 files changed, 310 insertions, 0 deletions
diff --git a/app/assets/javascripts/invite_members/components/invite_members_modal.vue b/app/assets/javascripts/invite_members/components/invite_members_modal.vue
new file mode 100644
index 00000000000..d2ea14a658b
--- /dev/null
+++ b/app/assets/javascripts/invite_members/components/invite_members_modal.vue
@@ -0,0 +1,224 @@
+<script>
+import {
+ GlModal,
+ GlDropdown,
+ GlDropdownItem,
+ GlDatepicker,
+ GlLink,
+ GlSprintf,
+ GlSearchBoxByType,
+ GlButton,
+ GlFormInput,
+} from '@gitlab/ui';
+import eventHub from '../event_hub';
+import { s__, sprintf } from '~/locale';
+import Api from '~/api';
+
+export default {
+ name: 'InviteMembersModal',
+ components: {
+ GlDatepicker,
+ GlLink,
+ GlModal,
+ GlDropdown,
+ GlDropdownItem,
+ GlSprintf,
+ GlSearchBoxByType,
+ GlButton,
+ GlFormInput,
+ },
+ props: {
+ groupId: {
+ type: String,
+ required: true,
+ },
+ groupName: {
+ type: String,
+ required: true,
+ },
+ accessLevels: {
+ type: Object,
+ required: true,
+ },
+ defaultAccessLevel: {
+ type: String,
+ required: true,
+ },
+ helpLink: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ visible: true,
+ modalId: 'invite-members-modal',
+ selectedAccessLevel: this.defaultAccessLevel,
+ newUsersToInvite: '',
+ selectedDate: undefined,
+ };
+ },
+ computed: {
+ introText() {
+ return sprintf(s__("InviteMembersModal|You're inviting members to the %{group_name} group"), {
+ group_name: this.groupName,
+ });
+ },
+ toastOptions() {
+ return {
+ onComplete: () => {
+ this.selectedAccessLevel = this.defaultAccessLevel;
+ this.newUsersToInvite = '';
+ },
+ };
+ },
+ postData() {
+ return {
+ user_id: this.newUsersToInvite,
+ access_level: this.selectedAccessLevel,
+ expires_at: this.selectedDate,
+ format: 'json',
+ };
+ },
+ selectedRoleName() {
+ return Object.keys(this.accessLevels).find(
+ key => this.accessLevels[key] === Number(this.selectedAccessLevel),
+ );
+ },
+ },
+ mounted() {
+ eventHub.$on('openModal', this.openModal);
+ },
+ methods: {
+ openModal() {
+ this.$root.$emit('bv::show::modal', this.modalId);
+ },
+ closeModal() {
+ this.$root.$emit('bv::hide::modal', this.modalId);
+ },
+ sendInvite() {
+ this.submitForm(this.postData);
+ this.closeModal();
+ },
+ cancelInvite() {
+ this.selectedAccessLevel = this.defaultAccessLevel;
+ this.selectedDate = undefined;
+ this.newUsersToInvite = '';
+ this.closeModal();
+ },
+ changeSelectedItem(item) {
+ this.selectedAccessLevel = item;
+ },
+ submitForm(formData) {
+ return Api.inviteGroupMember(this.groupId, formData)
+ .then(() => {
+ this.showToastMessageSuccess();
+ })
+ .catch(error => {
+ this.showToastMessageError(error);
+ });
+ },
+ showToastMessageSuccess() {
+ this.$toast.show(this.$options.labels.toastMessageSuccessful, this.toastOptions);
+ },
+ showToastMessageError(error) {
+ const message = error.response.data.message || this.$options.labels.toastMessageUnsuccessful;
+
+ this.$toast.show(message, this.toastOptions);
+ },
+ },
+ labels: {
+ modalTitle: s__('InviteMembersModal|Invite team members'),
+ userToInvite: s__('InviteMembersModal|GitLab member or Email address'),
+ userPlaceholder: s__('InviteMembersModal|Search for members to invite'),
+ accessLevel: s__('InviteMembersModal|Choose a role permission'),
+ accessExpireDate: s__('InviteMembersModal|Access expiration date (optional)'),
+ toastMessageSuccessful: s__('InviteMembersModal|Users were succesfully added'),
+ toastMessageUnsuccessful: s__('InviteMembersModal|User not invited. Feature coming soon!'),
+ readMoreText: s__(`InviteMembersModal|%{linkStart}Read more%{linkEnd} about role permissions`),
+ inviteButtonText: s__('InviteMembersModal|Invite'),
+ cancelButtonText: s__('InviteMembersModal|Cancel'),
+ },
+};
+</script>
+<template>
+ <gl-modal :modal-id="modalId" size="sm" :title="$options.labels.modalTitle">
+ <div class="gl-ml-5 gl-mr-5">
+ <div>{{ introText }}</div>
+
+ <label class="gl-font-weight-bold gl-mt-5">{{ $options.labels.userToInvite }}</label>
+ <div class="gl-mt-2">
+ <gl-search-box-by-type
+ v-model="newUsersToInvite"
+ :placeholder="$options.labels.userPlaceholder"
+ type="text"
+ autocomplete="off"
+ autocorrect="off"
+ autocapitalize="off"
+ spellcheck="false"
+ />
+ </div>
+
+ <label class="gl-font-weight-bold gl-mt-5">{{ $options.labels.accessLevel }}</label>
+ <div class="gl-mt-2 gl-w-half gl-xs-w-full">
+ <gl-dropdown
+ menu-class="dropdown-menu-selectable"
+ class="gl-shadow-none gl-w-full"
+ v-bind="$attrs"
+ :text="selectedRoleName"
+ >
+ <template v-for="(key, item) in accessLevels">
+ <gl-dropdown-item
+ :key="key"
+ active-class="is-active"
+ :is-checked="key === selectedAccessLevel"
+ @click="changeSelectedItem(key)"
+ >
+ <div>{{ item }}</div>
+ </gl-dropdown-item>
+ </template>
+ </gl-dropdown>
+ </div>
+
+ <div class="gl-mt-2">
+ <gl-sprintf :message="$options.labels.readMoreText">
+ <template #link="{content}">
+ <gl-link :href="helpLink" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </div>
+
+ <label class="gl-font-weight-bold gl-mt-5" for="expires_at">{{
+ $options.labels.accessExpireDate
+ }}</label>
+ <div class="gl-mt-2 gl-w-half gl-xs-w-full gl-display-inline-block">
+ <gl-datepicker
+ v-model="selectedDate"
+ class="gl-display-inline!"
+ :min-date="new Date()"
+ :target="null"
+ >
+ <template #default="{ formattedDate }">
+ <gl-form-input
+ class="gl-w-full"
+ :value="formattedDate"
+ :placeholder="__(`YYYY-MM-DD`)"
+ />
+ </template>
+ </gl-datepicker>
+ </div>
+ </div>
+
+ <template #modal-footer>
+ <div class="gl-display-flex gl-flex-direction-row gl-justify-content-end gl-flex-wrap gl-p-3">
+ <gl-button ref="cancelButton" @click="cancelInvite">
+ {{ $options.labels.cancelButtonText }}
+ </gl-button>
+ <div class="gl-mr-3"></div>
+ <gl-button ref="inviteButton" variant="success" @click="sendInvite">{{
+ $options.labels.inviteButtonText
+ }}</gl-button>
+ </div>
+ </template>
+ </gl-modal>
+</template>
diff --git a/app/assets/javascripts/invite_members/components/invite_members_trigger.vue b/app/assets/javascripts/invite_members/components/invite_members_trigger.vue
new file mode 100644
index 00000000000..d133e3655e3
--- /dev/null
+++ b/app/assets/javascripts/invite_members/components/invite_members_trigger.vue
@@ -0,0 +1,38 @@
+<script>
+import { GlLink, GlIcon } from '@gitlab/ui';
+import { s__ } from '~/locale';
+import eventHub from '../event_hub';
+
+export default {
+ components: {
+ GlLink,
+ GlIcon,
+ },
+ props: {
+ displayText: {
+ type: String,
+ required: false,
+ default: s__('InviteMembers|Invite team members'),
+ },
+ icon: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ },
+ methods: {
+ openModal() {
+ eventHub.$emit('openModal');
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-link @click="openModal">
+ <div v-if="icon" class="nav-icon-container">
+ <gl-icon :size="16" :name="icon" />
+ </div>
+ <span class="nav-item-name"> {{ displayText }} </span>
+ </gl-link>
+</template>
diff --git a/app/assets/javascripts/invite_members/event_hub.js b/app/assets/javascripts/invite_members/event_hub.js
new file mode 100644
index 00000000000..e31806ad199
--- /dev/null
+++ b/app/assets/javascripts/invite_members/event_hub.js
@@ -0,0 +1,3 @@
+import createEventHub from '~/helpers/event_hub_factory';
+
+export default createEventHub();
diff --git a/app/assets/javascripts/invite_members/init_invite_members_modal.js b/app/assets/javascripts/invite_members/init_invite_members_modal.js
new file mode 100644
index 00000000000..92aa3187fc3
--- /dev/null
+++ b/app/assets/javascripts/invite_members/init_invite_members_modal.js
@@ -0,0 +1,25 @@
+import Vue from 'vue';
+import { GlToast } from '@gitlab/ui';
+import InviteMembersModal from '~/invite_members/components/invite_members_modal.vue';
+
+Vue.use(GlToast);
+
+export default function initInviteMembersModal() {
+ const el = document.querySelector('.js-invite-members-modal');
+
+ if (!el) {
+ return false;
+ }
+
+ return new Vue({
+ el,
+ render: createElement =>
+ createElement(InviteMembersModal, {
+ props: {
+ ...el.dataset,
+ accessLevels: JSON.parse(el.dataset.accessLevels),
+ groupName: el.dataset.groupName.toUpperCase(),
+ },
+ }),
+ });
+}
diff --git a/app/assets/javascripts/invite_members/init_invite_members_trigger.js b/app/assets/javascripts/invite_members/init_invite_members_trigger.js
new file mode 100644
index 00000000000..bee4f1c0f72
--- /dev/null
+++ b/app/assets/javascripts/invite_members/init_invite_members_trigger.js
@@ -0,0 +1,20 @@
+import Vue from 'vue';
+import InviteMembersTrigger from '~/invite_members/components/invite_members_trigger.vue';
+
+export default function initInviteMembersTrigger() {
+ const el = document.querySelector('.js-invite-members-trigger');
+
+ if (!el) {
+ return false;
+ }
+
+ return new Vue({
+ el,
+ render: createElement =>
+ createElement(InviteMembersTrigger, {
+ props: {
+ ...el.dataset,
+ },
+ }),
+ });
+}