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>2021-11-17 21:14:12 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-11-17 21:14:12 +0300
commit2c06e006d832757e90e5199112ab062b27df7433 (patch)
tree36811d1041a1a2b88b041ecac07e9d3aa41c6b1f /app/assets/javascripts/invite_members
parenta331169e6e84f93fd9b841b56465ac113b6d03f9 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/invite_members')
-rw-r--r--app/assets/javascripts/invite_members/components/confetti.vue33
-rw-r--r--app/assets/javascripts/invite_members/components/invite_members_modal.vue101
-rw-r--r--app/assets/javascripts/invite_members/constants.js119
3 files changed, 185 insertions, 68 deletions
diff --git a/app/assets/javascripts/invite_members/components/confetti.vue b/app/assets/javascripts/invite_members/components/confetti.vue
new file mode 100644
index 00000000000..2e5744afcd4
--- /dev/null
+++ b/app/assets/javascripts/invite_members/components/confetti.vue
@@ -0,0 +1,33 @@
+<script>
+import confetti from 'canvas-confetti';
+
+export default {
+ mounted() {
+ confetti.create(this.$refs.canvas, {
+ resize: true,
+ useWorker: true,
+ disableForReducedMotion: true,
+ });
+
+ this.basicCannon();
+ },
+ methods: {
+ basicCannon() {
+ confetti({
+ particleCount: 100,
+ spread: 70,
+ origin: { y: 0.2 },
+ scalar: 2,
+ shapes: ['square'],
+ colors: ['#FC6D26', '#6B4FBB', '#FDB997'],
+ zIndex: 1045,
+ gravity: 1.5,
+ });
+ },
+ },
+};
+</script>
+
+<template>
+ <canvas ref="canvas" width="0" height="0"></canvas>
+</template>
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 ee77ba110bb..cf4f434a7a8 100644
--- a/app/assets/javascripts/invite_members/components/invite_members_modal.vue
+++ b/app/assets/javascripts/invite_members/components/invite_members_modal.vue
@@ -18,19 +18,21 @@ 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 { sprintf } from '~/locale';
import {
INVITE_MEMBERS_IN_COMMENT,
GROUP_FILTERS,
USERS_FILTER_ALL,
MEMBER_AREAS_OF_FOCUS,
INVITE_MEMBERS_FOR_TASK,
+ MODAL_LABELS,
} from '../constants';
import eventHub from '../event_hub';
import {
responseMessageFromError,
responseMessageFromSuccess,
} from '../utils/response_message_parser';
+import ModalConfetti from './confetti.vue';
import GroupSelect from './group_select.vue';
import MembersTokenSelect from './members_token_select.vue';
@@ -50,6 +52,7 @@ export default {
GlFormCheckboxGroup,
MembersTokenSelect,
GroupSelect,
+ ModalConfetti,
},
inject: ['newProjectPath'],
props: {
@@ -129,22 +132,30 @@ export default {
source: 'unknown',
invalidFeedbackMessage: '',
isLoading: false,
+ mode: 'default',
};
},
computed: {
+ isCelebration() {
+ return this.mode === 'celebrate';
+ },
validationState() {
return this.invalidFeedbackMessage === '' ? null : false;
},
isInviteGroup() {
return this.inviteeType === 'group';
},
+ modalTitle() {
+ return this.$options.labels[this.inviteeType].modal[this.mode].title;
+ },
introText() {
- const inviteTo = this.isProject ? 'toProject' : 'toGroup';
-
- return sprintf(this.$options.labels[this.inviteeType][inviteTo].introText, {
+ return sprintf(this.$options.labels[this.inviteeType][this.inviteTo][this.mode].introText, {
name: this.name,
});
},
+ inviteTo() {
+ return this.isProject ? 'toProject' : 'toGroup';
+ },
toastOptions() {
return {
onComplete: () => {
@@ -234,7 +245,8 @@ export default {
usersToAddById.map((user) => user.id).join(','),
];
},
- openModal({ inviteeType, source }) {
+ openModal({ mode = 'default', inviteeType, source }) {
+ this.mode = mode;
this.inviteeType = inviteeType;
this.source = source;
@@ -381,60 +393,7 @@ export default {
return unescape(sanitize(message, { ALLOWED_TAGS: [] }));
},
},
- labels: {
- members: {
- modalTitle: s__('InviteMembersModal|Invite members'),
- searchField: s__('InviteMembersModal|GitLab member or email address'),
- placeHolder: s__('InviteMembersModal|Select members or type email addresses'),
- toGroup: {
- introText: s__(
- "InviteMembersModal|You're inviting members to the %{strongStart}%{name}%{strongEnd} group.",
- ),
- },
- toProject: {
- introText: s__(
- "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'),
- searchField: s__('InviteMembersModal|Select a group to invite'),
- placeHolder: s__('InviteMembersModal|Search for a group to invite'),
- toGroup: {
- introText: s__(
- "InviteMembersModal|You're inviting a group to the %{strongStart}%{name}%{strongEnd} group.",
- ),
- },
- toProject: {
- introText: s__(
- "InviteMembersModal|You're inviting a group to the %{strongStart}%{name}%{strongEnd} project.",
- ),
- },
- },
- accessLevel: s__('InviteMembersModal|Select a role'),
- accessExpireDate: s__('InviteMembersModal|Access expiration date (optional)'),
- toastMessageSuccessful: s__('InviteMembersModal|Members were successfully added'),
- invalidFeedbackMessageDefault: s__('InviteMembersModal|Something went wrong'),
- readMoreText: s__(`InviteMembersModal|%{linkStart}Read more%{linkEnd} about role permissions`),
- inviteButtonText: s__('InviteMembersModal|Invite'),
- cancelButtonText: s__('InviteMembersModal|Cancel'),
- headerCloseLabel: s__('InviteMembersModal|Close invite team members'),
- areasOfFocusLabel: s__(
- 'InviteMembersModal|What would you like new member(s) to focus on? (optional)',
- ),
- },
+ labels: MODAL_LABELS,
membersTokenSelectLabelId: 'invite-members-input',
};
</script>
@@ -445,20 +404,28 @@ export default {
size="sm"
data-qa-selector="invite_members_modal_content"
data-testid="invite-members-modal"
- :title="$options.labels[inviteeType].modalTitle"
+ :title="modalTitle"
:header-close-label="$options.labels.headerCloseLabel"
@hidden="resetFields"
@close="resetFields"
@hide="resetFields"
>
<div>
- <p ref="introText">
- <gl-sprintf :message="introText">
- <template #strong="{ content }">
- <strong>{{ content }}</strong>
- </template>
- </gl-sprintf>
- </p>
+ <div class="gl-display-flex">
+ <div v-if="isCelebration" class="gl-p-4 gl-font-size-h1"><gl-emoji data-name="tada" /></div>
+ <div>
+ <p ref="introText">
+ <gl-sprintf :message="introText">
+ <template #strong="{ content }">
+ <strong>{{ content }}</strong>
+ </template>
+ </gl-sprintf>
+ <br />
+ <span v-if="isCelebration">{{ $options.labels.members.modal.celebrate.intro }} </span>
+ <modal-confetti v-if="isCelebration" />
+ </p>
+ </div>
+ </div>
<gl-form-group
:invalid-feedback="invalidFeedbackMessage"
diff --git a/app/assets/javascripts/invite_members/constants.js b/app/assets/javascripts/invite_members/constants.js
index c1a1107ebe3..59d4c2f3077 100644
--- a/app/assets/javascripts/invite_members/constants.js
+++ b/app/assets/javascripts/invite_members/constants.js
@@ -1,4 +1,4 @@
-import { __ } from '~/locale';
+import { __, s__ } from '~/locale';
export const SEARCH_DELAY = 200;
@@ -27,3 +27,120 @@ export const USERS_FILTER_ALL = 'all';
export const USERS_FILTER_SAML_PROVIDER_ID = 'saml_provider_id';
export const TRIGGER_ELEMENT_BUTTON = 'button';
export const TRIGGER_ELEMENT_SIDE_NAV = 'side-nav';
+export const MEMBERS_MODAL_DEFAULT_TITLE = s__('InviteMembersModal|Invite members');
+export const MEMBERS_MODAL_CELEBRATE_TITLE = s__(
+ 'InviteMembersModal|GitLab is better with colleagues!',
+);
+export const MEMBERS_MODAL_CELEBRATE_INTRO = s__(
+ 'InviteMembersModal|How about inviting a colleague or two to join you?',
+);
+export const MEMBERS_TO_GROUP_DEFAULT_INTRO_TEXT = s__(
+ "InviteMembersModal|You're inviting members to the %{strongStart}%{name}%{strongEnd} group.",
+);
+
+export const MEMBERS_TO_PROJECT_DEFAULT_INTRO_TEXT = s__(
+ "InviteMembersModal|You're inviting members to the %{strongStart}%{name}%{strongEnd} project.",
+);
+export const MEMBERS_TO_PROJECT_CELEBRATE_INTRO_TEXT = s__(
+ "InviteMembersModal|Congratulations on creating your project, you're almost there!",
+);
+export const MEMBERS_SEARCH_FIELD = s__('InviteMembersModal|GitLab member or email address');
+export const MEMBERS_PLACEHOLDER = s__('InviteMembersModal|Select members or type email addresses');
+export const MEMBERS_TASKS_TO_BE_DONE_TITLE = s__(
+ 'InviteMembersModal|Create issues for your new team member to work on (optional)',
+);
+export const MEMBERS_TASKS_TO_BE_DONE_NO_PROJECTS = 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}',
+);
+export const MEMBERS_TASKS_PROJECTS_TITLE = s__(
+ 'InviteMembersModal|Choose a project for the issues',
+);
+
+export const GROUP_MODAL_DEFAULT_TITLE = s__('InviteMembersModal|Invite a group');
+export const GROUP_MODAL_TO_GROUP_DEFAULT_INTRO_TEXT = s__(
+ "InviteMembersModal|You're inviting a group to the %{strongStart}%{name}%{strongEnd} group.",
+);
+export const GROUP_MODAL_TO_PROJECT_DEFAULT_INTRO_TEXT = s__(
+ "InviteMembersModal|You're inviting a group to the %{strongStart}%{name}%{strongEnd} project.",
+);
+
+export const GROUP_SEARCH_FIELD = s__('InviteMembersModal|Select a group to invite');
+export const GROUP_PLACEHOLDER = s__('InviteMembersModal|Search for a group to invite');
+
+export const ACCESS_LEVEL = s__('InviteMembersModal|Select a role');
+export const ACCESS_EXPIRE_DATE = s__('InviteMembersModal|Access expiration date (optional)');
+export const TOAST_MESSAGE_SUCCESSFUL = s__('InviteMembersModal|Members were successfully added');
+export const INVALID_FEEDBACK_MESSAGE_DEFAULT = s__('InviteMembersModal|Something went wrong');
+export const READ_MORE_TEXT = s__(
+ `InviteMembersModal|%{linkStart}Read more%{linkEnd} about role permissions`,
+);
+export const INVITE_BUTTON_TEXT = s__('InviteMembersModal|Invite');
+export const CANCEL_BUTTON_TEXT = s__('InviteMembersModal|Cancel');
+export const HEADER_CLOSE_LABEL = s__('InviteMembersModal|Close invite team members');
+export const AREAS_OF_FOCUS_LABEL = s__(
+ 'InviteMembersModal|What would you like new member(s) to focus on? (optional)',
+);
+
+export const MODAL_LABELS = {
+ members: {
+ modal: {
+ default: {
+ title: MEMBERS_MODAL_DEFAULT_TITLE,
+ },
+ celebrate: {
+ title: MEMBERS_MODAL_CELEBRATE_TITLE,
+ intro: MEMBERS_MODAL_CELEBRATE_INTRO,
+ },
+ },
+ toGroup: {
+ default: {
+ introText: MEMBERS_TO_GROUP_DEFAULT_INTRO_TEXT,
+ },
+ },
+ toProject: {
+ default: {
+ introText: MEMBERS_TO_PROJECT_DEFAULT_INTRO_TEXT,
+ },
+ celebrate: {
+ introText: MEMBERS_TO_PROJECT_CELEBRATE_INTRO_TEXT,
+ },
+ },
+ searchField: MEMBERS_SEARCH_FIELD,
+ placeHolder: MEMBERS_PLACEHOLDER,
+ tasksToBeDone: {
+ title: MEMBERS_TASKS_TO_BE_DONE_TITLE,
+ noProjects: MEMBERS_TASKS_TO_BE_DONE_NO_PROJECTS,
+ },
+ tasksProject: {
+ title: MEMBERS_TASKS_PROJECTS_TITLE,
+ },
+ },
+ group: {
+ modal: {
+ default: {
+ title: GROUP_MODAL_DEFAULT_TITLE,
+ },
+ },
+ toGroup: {
+ default: {
+ introText: GROUP_MODAL_TO_GROUP_DEFAULT_INTRO_TEXT,
+ },
+ },
+ toProject: {
+ default: {
+ introText: GROUP_MODAL_TO_PROJECT_DEFAULT_INTRO_TEXT,
+ },
+ },
+ searchField: GROUP_SEARCH_FIELD,
+ placeHolder: GROUP_PLACEHOLDER,
+ },
+ accessLevel: ACCESS_LEVEL,
+ accessExpireDate: ACCESS_EXPIRE_DATE,
+ toastMessageSuccessful: TOAST_MESSAGE_SUCCESSFUL,
+ invalidFeedbackMessageDefault: INVALID_FEEDBACK_MESSAGE_DEFAULT,
+ readMoreText: READ_MORE_TEXT,
+ inviteButtonText: INVITE_BUTTON_TEXT,
+ cancelButtonText: CANCEL_BUTTON_TEXT,
+ headerCloseLabel: HEADER_CLOSE_LABEL,
+ areasOfFocusLabel: AREAS_OF_FOCUS_LABEL,
+};