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:
Diffstat (limited to 'app/assets/javascripts/invite_members')
-rw-r--r--app/assets/javascripts/invite_members/components/invite_members_modal.vue120
-rw-r--r--app/assets/javascripts/invite_members/constants.js6
-rw-r--r--app/assets/javascripts/invite_members/init_invite_members_modal.js5
3 files changed, 130 insertions, 1 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
index cd0b413265b..a64af2da517 100644
--- a/app/assets/javascripts/invite_members/components/invite_members_modal.vue
+++ b/app/assets/javascripts/invite_members/components/invite_members_modal.vue
@@ -1,5 +1,6 @@
<script>
import {
+ GlAlert,
GlFormGroup,
GlModal,
GlDropdown,
@@ -16,12 +17,14 @@ import Api from '~/api';
import ExperimentTracking from '~/experimentation/experiment_tracking';
import { sanitize } from '~/lib/dompurify';
import { BV_SHOW_MODAL } from '~/lib/utils/constants';
+import { getParameterValues } from '~/lib/utils/url_utility';
import { s__, sprintf } from '~/locale';
import {
INVITE_MEMBERS_IN_COMMENT,
GROUP_FILTERS,
USERS_FILTER_ALL,
MEMBER_AREAS_OF_FOCUS,
+ INVITE_MEMBERS_FOR_TASK,
} from '../constants';
import eventHub from '../event_hub';
import {
@@ -34,6 +37,7 @@ import MembersTokenSelect from './members_token_select.vue';
export default {
name: 'InviteMembersModal',
components: {
+ GlAlert,
GlFormGroup,
GlDatepicker,
GlLink,
@@ -47,6 +51,7 @@ export default {
MembersTokenSelect,
GroupSelect,
},
+ inject: ['newProjectPath'],
props: {
id: {
type: String,
@@ -100,6 +105,14 @@ export default {
type: Array,
required: true,
},
+ tasksToBeDoneOptions: {
+ type: Array,
+ required: true,
+ },
+ projects: {
+ type: Array,
+ required: true,
+ },
},
data() {
return {
@@ -110,6 +123,8 @@ export default {
newUsersToInvite: [],
selectedDate: undefined,
selectedAreasOfFocus: [],
+ selectedTasksToBeDone: [],
+ selectedTaskProject: this.projects[0],
groupToBeSharedWith: {},
source: 'unknown',
invalidFeedbackMessage: '',
@@ -156,7 +171,7 @@ export default {
);
},
areasOfFocusEnabled() {
- return this.areasOfFocusOptions.length !== 0;
+ return !this.tasksToBeDoneEnabled && this.areasOfFocusOptions.length !== 0;
},
areasOfFocusForPost() {
if (this.selectedAreasOfFocus.length === 0 && this.areasOfFocusEnabled) {
@@ -172,12 +187,40 @@ export default {
return this.$options.labels[this.inviteeType].placeHolder;
},
+ tasksToBeDoneEnabled() {
+ return (
+ getParameterValues('open_modal')[0] === 'invite_members_for_task' &&
+ this.tasksToBeDoneOptions.length
+ );
+ },
+ showTasksToBeDone() {
+ return (
+ this.tasksToBeDoneEnabled &&
+ this.selectedAccessLevel >= INVITE_MEMBERS_FOR_TASK.minimum_access_level
+ );
+ },
+ showTaskProjects() {
+ return !this.isProject && this.selectedTasksToBeDone.length;
+ },
+ tasksToBeDoneForPost() {
+ return this.showTasksToBeDone ? this.selectedTasksToBeDone : [];
+ },
+ tasksProjectForPost() {
+ return this.showTasksToBeDone && this.selectedTasksToBeDone.length
+ ? this.selectedTaskProject.id
+ : '';
+ },
},
mounted() {
eventHub.$on('openModal', (options) => {
this.openModal(options);
this.trackEvent(MEMBER_AREAS_OF_FOCUS.name, MEMBER_AREAS_OF_FOCUS.view);
});
+
+ if (this.tasksToBeDoneEnabled) {
+ this.openModal({ inviteeType: 'members', source: 'in_product_marketing_email' });
+ this.trackEvent(INVITE_MEMBERS_FOR_TASK.name, INVITE_MEMBERS_FOR_TASK.view);
+ }
},
methods: {
partitionNewUsersToInvite() {
@@ -219,6 +262,12 @@ export default {
this.trackEvent(MEMBER_AREAS_OF_FOCUS.name, MEMBER_AREAS_OF_FOCUS.submit);
},
+ trackinviteMembersForTask() {
+ const label = 'selected_tasks_to_be_done';
+ const property = this.selectedTasksToBeDone.join(',');
+ const tracking = new ExperimentTracking(INVITE_MEMBERS_FOR_TASK.name, { label, property });
+ tracking.event(INVITE_MEMBERS_FOR_TASK.submit);
+ },
resetFields() {
this.isLoading = false;
this.selectedAccessLevel = this.defaultAccessLevel;
@@ -227,10 +276,15 @@ export default {
this.groupToBeSharedWith = {};
this.invalidFeedbackMessage = '';
this.selectedAreasOfFocus = [];
+ this.selectedTasksToBeDone = [];
+ [this.selectedTaskProject] = this.projects;
},
changeSelectedItem(item) {
this.selectedAccessLevel = item;
},
+ changeSelectedTaskProject(project) {
+ this.selectedTaskProject = project;
+ },
submitShareWithGroup() {
const apiShareWithGroup = this.isProject
? Api.projectShareWithGroup.bind(Api)
@@ -263,6 +317,7 @@ export default {
promises.push(apiAddByUserId(this.id, this.addByUserIdPostData(usersToAddById)));
}
this.trackInvite();
+ this.trackinviteMembersForTask();
Promise.all(promises)
.then(this.conditionallyShowToastSuccess)
@@ -275,6 +330,8 @@ export default {
access_level: this.selectedAccessLevel,
invite_source: this.source,
areas_of_focus: this.areasOfFocusForPost,
+ tasks_to_be_done: this.tasksToBeDoneForPost,
+ tasks_project_id: this.tasksProjectForPost,
};
},
addByUserIdPostData(usersToAddById) {
@@ -284,6 +341,8 @@ export default {
access_level: this.selectedAccessLevel,
invite_source: this.source,
areas_of_focus: this.areasOfFocusForPost,
+ tasks_to_be_done: this.tasksToBeDoneForPost,
+ tasks_project_id: this.tasksProjectForPost,
};
},
shareWithGroupPostData(groupToBeSharedWith) {
@@ -337,6 +396,17 @@ export default {
"InviteMembersModal|You're inviting members to the %{strongStart}%{name}%{strongEnd} project.",
),
},
+ tasksToBeDone: {
+ title: s__(
+ 'InviteMembersModal|Create issues for your new team member to work on (optional)',
+ ),
+ noProjects: s__(
+ 'InviteMembersModal|To assign issues to a new team member, you need a project for the issues. %{linkStart}Create a project to get started.%{linkEnd}',
+ ),
+ },
+ tasksProject: {
+ title: s__('InviteMembersModal|Choose a project for the issues'),
+ },
},
group: {
modalTitle: s__('InviteMembersModal|Invite a group'),
@@ -476,6 +546,54 @@ export default {
data-testid="area-of-focus-checks"
/>
</div>
+ <div v-if="showTasksToBeDone" data-testid="invite-members-modal-tasks-to-be-done">
+ <label class="gl-mt-5">
+ {{ $options.labels.members.tasksToBeDone.title }}
+ </label>
+ <template v-if="projects.length">
+ <gl-form-checkbox-group
+ v-model="selectedTasksToBeDone"
+ :options="tasksToBeDoneOptions"
+ data-testid="invite-members-modal-tasks"
+ />
+ <template v-if="showTaskProjects">
+ <label class="gl-mt-5 gl-display-block">
+ {{ $options.labels.members.tasksProject.title }}
+ </label>
+ <gl-dropdown
+ class="gl-w-half gl-xs-w-full"
+ :text="selectedTaskProject.title"
+ data-testid="invite-members-modal-project-select"
+ >
+ <template v-for="project in projects">
+ <gl-dropdown-item
+ :key="project.id"
+ active-class="is-active"
+ is-check-item
+ :is-checked="project.id === selectedTaskProject.id"
+ @click="changeSelectedTaskProject(project)"
+ >
+ {{ project.title }}
+ </gl-dropdown-item>
+ </template>
+ </gl-dropdown>
+ </template>
+ </template>
+ <gl-alert
+ v-else-if="tasksToBeDoneEnabled"
+ variant="tip"
+ :dismissible="false"
+ data-testid="invite-members-modal-no-projects-alert"
+ >
+ <gl-sprintf :message="$options.labels.members.tasksToBeDone.noProjects">
+ <template #link="{ content }">
+ <gl-link :href="newProjectPath" target="_blank" class="gl-label-link">
+ {{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </gl-alert>
+ </div>
</div>
<template #modal-footer>
diff --git a/app/assets/javascripts/invite_members/constants.js b/app/assets/javascripts/invite_members/constants.js
index d7daf83e26b..02f38bfd3c5 100644
--- a/app/assets/javascripts/invite_members/constants.js
+++ b/app/assets/javascripts/invite_members/constants.js
@@ -8,6 +8,12 @@ export const MEMBER_AREAS_OF_FOCUS = {
view: 'view',
submit: 'submit',
};
+export const INVITE_MEMBERS_FOR_TASK = {
+ minimum_access_level: 30,
+ name: 'invite_members_for_task',
+ view: 'modal_opened_from_email',
+ submit: 'submit',
+};
export const GROUP_FILTERS = {
ALL: 'all',
diff --git a/app/assets/javascripts/invite_members/init_invite_members_modal.js b/app/assets/javascripts/invite_members/init_invite_members_modal.js
index c1dfaa25dc7..85339af161a 100644
--- a/app/assets/javascripts/invite_members/init_invite_members_modal.js
+++ b/app/assets/javascripts/invite_members/init_invite_members_modal.js
@@ -14,6 +14,9 @@ export default function initInviteMembersModal() {
return new Vue({
el,
+ provide: {
+ newProjectPath: el.dataset.newProjectPath,
+ },
render: (createElement) =>
createElement(InviteMembersModal, {
props: {
@@ -24,6 +27,8 @@ export default function initInviteMembersModal() {
groupSelectFilter: el.dataset.groupsFilter,
groupSelectParentId: parseInt(el.dataset.parentId, 10),
areasOfFocusOptions: JSON.parse(el.dataset.areasOfFocusOptions),
+ tasksToBeDoneOptions: JSON.parse(el.dataset.tasksToBeDoneOptions || '[]'),
+ projects: JSON.parse(el.dataset.projects || '[]'),
noSelectionAreasOfFocus: JSON.parse(el.dataset.noSelectionAreasOfFocus),
usersFilter: el.dataset.usersFilter,
filterId: parseInt(el.dataset.filterId, 10),