diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-11-17 21:14:12 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-11-17 21:14:12 +0300 |
commit | 2c06e006d832757e90e5199112ab062b27df7433 (patch) | |
tree | 36811d1041a1a2b88b041ecac07e9d3aa41c6b1f /app/assets/javascripts/invite_members | |
parent | a331169e6e84f93fd9b841b56465ac113b6d03f9 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/invite_members')
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, +}; |