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>2023-11-14 11:41:52 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-11-14 11:41:52 +0300
commit585826cb22ecea5998a2c2a4675735c94bdeedac (patch)
tree5b05f0b30d33cef48963609e8a18a4dff260eab3 /app/assets/javascripts/invite_members
parentdf221d036e5d0c6c0ee4d55b9c97f481ee05dee8 (diff)
Add latest changes from gitlab-org/gitlab@16-6-stable-eev16.6.0-rc42
Diffstat (limited to 'app/assets/javascripts/invite_members')
-rw-r--r--app/assets/javascripts/invite_members/components/invite_groups_modal.vue2
-rw-r--r--app/assets/javascripts/invite_members/components/invite_members_modal.vue80
-rw-r--r--app/assets/javascripts/invite_members/components/invite_modal_base.vue10
-rw-r--r--app/assets/javascripts/invite_members/components/members_token_select.vue12
-rw-r--r--app/assets/javascripts/invite_members/components/project_select.vue1
-rw-r--r--app/assets/javascripts/invite_members/init_invite_members_modal.js3
-rw-r--r--app/assets/javascripts/invite_members/utils/member_utils.js4
7 files changed, 93 insertions, 19 deletions
diff --git a/app/assets/javascripts/invite_members/components/invite_groups_modal.vue b/app/assets/javascripts/invite_members/components/invite_groups_modal.vue
index 4b492e48095..ceb9200dfad 100644
--- a/app/assets/javascripts/invite_members/components/invite_groups_modal.vue
+++ b/app/assets/javascripts/invite_members/components/invite_groups_modal.vue
@@ -1,7 +1,7 @@
<script>
-import * as Sentry from '@sentry/browser';
import { GlAlert } from '@gitlab/ui';
import { uniqueId } from 'lodash';
+import * as Sentry from '~/sentry/sentry_browser_wrapper';
import Api from '~/api';
import { BV_SHOW_MODAL, BV_HIDE_MODAL } from '~/lib/utils/constants';
import InviteModalBase from 'ee_else_ce/invite_members/components/invite_modal_base.vue';
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 509efd31dcd..1a10130e969 100644
--- a/app/assets/javascripts/invite_members/components/invite_members_modal.vue
+++ b/app/assets/javascripts/invite_members/components/invite_members_modal.vue
@@ -1,13 +1,17 @@
<script>
-import { GlAlert, GlButton, GlCollapse, GlIcon } from '@gitlab/ui';
+import { GlAlert, GlButton, GlCollapse, GlLink, GlIcon, GlSprintf } from '@gitlab/ui';
import { partition, isString, uniqueId, isEmpty } from 'lodash';
import SafeHtml from '~/vue_shared/directives/safe_html';
import InviteModalBase from 'ee_else_ce/invite_members/components/invite_modal_base.vue';
import Api from '~/api';
import Tracking from '~/tracking';
import { BV_SHOW_MODAL, BV_HIDE_MODAL } from '~/lib/utils/constants';
-import { n__, sprintf } from '~/locale';
-import { memberName, triggerExternalAlert } from 'ee_else_ce/invite_members/utils/member_utils';
+import { n__, s__, sprintf } from '~/locale';
+import {
+ memberName,
+ triggerExternalAlert,
+ inviteMembersTrackingOptions,
+} from 'ee_else_ce/invite_members/utils/member_utils';
import { captureException } from '~/ci/runner/sentry_utils';
import {
USERS_FILTER_ALL,
@@ -31,7 +35,9 @@ export default {
GlAlert,
GlButton,
GlCollapse,
+ GlLink,
GlIcon,
+ GlSprintf,
InviteModalBase,
MembersTokenSelect,
ModalConfetti,
@@ -43,6 +49,17 @@ export default {
SafeHtml,
},
mixins: [Tracking.mixin({ category: INVITE_MEMBER_MODAL_TRACKING_CATEGORY })],
+ inject: {
+ isCurrentUserAdmin: {
+ default: false,
+ },
+ isEmailSignupEnabled: {
+ default: true,
+ },
+ newUsersUrl: {
+ default: '',
+ },
+ },
props: {
id: {
type: String,
@@ -122,6 +139,12 @@ export default {
isCelebration() {
return this.mode === 'celebrate';
},
+ baseTrackingDetails() {
+ return { label: this.source, celebrate: this.isCelebration };
+ },
+ isTextForAdmin() {
+ return this.isCurrentUserAdmin && Boolean(this.newUsersUrl);
+ },
modalTitle() {
return this.$options.labels.modal[this.mode].title;
},
@@ -131,6 +154,11 @@ export default {
labelIntroText() {
return this.$options.labels[this.inviteTo][this.mode].introText;
},
+ labelSearchField() {
+ return this.isEmailSignupEnabled
+ ? this.$options.labels.searchField
+ : s__('InviteMembersModal|Username');
+ },
isEmptyInvites() {
return Boolean(this.newUsersToInvite.length);
},
@@ -144,6 +172,14 @@ export default {
this.errorList.length,
);
},
+ signupDisabledText() {
+ return s__(
+ "InviteMembersModal|Administrators can %{linkStart}add new users by email manually%{linkEnd}. After they've been added, you can invite them to this group with their username.",
+ );
+ },
+ signupDisabledTitle() {
+ return s__('InviteMembersModal|Inviting users by email is disabled');
+ },
showUserLimitNotification() {
return !isEmpty(this.usersLimitDataset.alertVariant);
},
@@ -173,8 +209,13 @@ export default {
count: this.errorsExpanded.length,
});
},
+ formGroupDescriptionText() {
+ return this.isEmailSignupEnabled
+ ? this.$options.labels.placeHolder
+ : s__('InviteMembersModal|Select members');
+ },
formGroupDescription() {
- return this.invalidFeedbackMessage ? null : this.$options.labels.placeHolder;
+ return this.invalidFeedbackMessage ? null : this.formGroupDescriptionText;
},
},
watch: {
@@ -218,13 +259,13 @@ export default {
this.source = source;
this.$root.$emit(BV_SHOW_MODAL, this.modalId);
- this.track('render', { label: this.source });
+ this.track('render', inviteMembersTrackingOptions(this.baseTrackingDetails));
},
closeModal() {
this.$root.$emit(BV_HIDE_MODAL, this.modalId);
},
showEmptyInvitesAlert() {
- this.invalidFeedbackMessage = this.$options.labels.placeHolder;
+ this.invalidFeedbackMessage = this.formGroupDescriptionText;
this.shouldShowEmptyInvitesAlert = true;
this.$refs.alerts.focus();
},
@@ -287,10 +328,10 @@ export default {
return this.newUsersToInvite.find((member) => memberName(member) === username)?.name;
},
onCancel() {
- this.track('click_cancel', { label: this.source });
+ this.track('click_cancel', inviteMembersTrackingOptions(this.baseTrackingDetails));
},
onClose() {
- this.track('click_x', { label: this.source });
+ this.track('click_x', inviteMembersTrackingOptions(this.baseTrackingDetails));
},
resetFields() {
this.clearValidation();
@@ -299,7 +340,7 @@ export default {
this.newUsersToInvite = [];
},
onInviteSuccess() {
- this.track('invite_successful', { label: this.source });
+ this.track('invite_successful', inviteMembersTrackingOptions(this.baseTrackingDetails));
if (this.reloadPageOnSubmit) {
reloadOnInvitationSuccess();
@@ -345,7 +386,7 @@ export default {
:default-access-level="defaultAccessLevel"
:help-link="helpLink"
:label-intro-text="labelIntroText"
- :label-search-field="$options.labels.searchField"
+ :label-search-field="labelSearchField"
:form-group-description="formGroupDescription"
:invalid-feedback-message="invalidFeedbackMessage"
:is-loading="isLoading"
@@ -429,6 +470,24 @@ export default {
</gl-button>
</template>
</gl-alert>
+ <gl-alert
+ v-if="!isEmailSignupEnabled"
+ id="signup-disabled-alert"
+ :dismissible="false"
+ :title="signupDisabledTitle"
+ class="gl-mb-4"
+ variant="warning"
+ data-testid="email-signup-disabled-alert"
+ >
+ <gl-sprintf :message="signupDisabledText">
+ <template #link="{ content }">
+ <gl-link v-if="isTextForAdmin" :href="newUsersUrl" target="_blank">{{
+ content
+ }}</gl-link>
+ <span v-else>{{ content }}</span>
+ </template>
+ </gl-sprintf>
+ </gl-alert>
<user-limit-notification
v-else-if="showUserLimitNotification"
class="gl-mb-5"
@@ -447,6 +506,7 @@ export default {
v-model="newUsersToInvite"
class="gl-mb-2"
aria-labelledby="empty-invites-alert"
+ :can-use-email-token="isEmailSignupEnabled"
:input-id="inputId"
:exception-state="exceptionState"
:users-filter="usersFilter"
diff --git a/app/assets/javascripts/invite_members/components/invite_modal_base.vue b/app/assets/javascripts/invite_members/components/invite_modal_base.vue
index 18d22395104..a14dcd38aa7 100644
--- a/app/assets/javascripts/invite_members/components/invite_modal_base.vue
+++ b/app/assets/javascripts/invite_members/components/invite_modal_base.vue
@@ -297,7 +297,7 @@ export default {
</gl-form-group>
<gl-form-group
- class="gl-w-half gl-xs-w-full"
+ class="gl-sm-w-half gl-w-full"
:label="$options.ACCESS_LEVEL"
:label-for="dropdownId"
>
@@ -317,7 +317,7 @@ export default {
</gl-form-group>
<gl-form-group
- class="gl-w-half gl-xs-w-full"
+ class="gl-sm-w-half gl-w-full"
:label="$options.ACCESS_EXPIRE_DATE"
:label-for="datepickerId"
>
@@ -338,10 +338,10 @@ export default {
<template #modal-footer>
<div
- class="gl-m-0 gl-xs-w-full gl-display-flex gl-xs-flex-direction-column! gl-flex-direction-row-reverse"
+ class="gl-m-0 gl-w-full gl-display-flex gl-xs-flex-direction-column! gl-flex-direction-row-reverse"
>
<gl-button
- class="gl-xs-w-full gl-xs-mb-3! gl-sm-ml-3!"
+ class="gl-w-full gl-sm-w-auto gl-xs-mb-3! gl-sm-ml-3!"
data-testid="invite-modal-submit"
v-bind="actionPrimary.attributes"
@click="onSubmit"
@@ -350,7 +350,7 @@ export default {
</gl-button>
<gl-button
- class="gl-xs-w-full"
+ class="gl-w-full gl-sm-w-auto"
data-testid="invite-modal-cancel"
v-bind="actionCancel.attributes"
@click="onCancel"
diff --git a/app/assets/javascripts/invite_members/components/members_token_select.vue b/app/assets/javascripts/invite_members/components/members_token_select.vue
index 8493787f075..0be04b7af35 100644
--- a/app/assets/javascripts/invite_members/components/members_token_select.vue
+++ b/app/assets/javascripts/invite_members/components/members_token_select.vue
@@ -21,6 +21,11 @@ export default {
GlSprintf,
},
props: {
+ canUseEmailToken: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
placeholder: {
type: String,
required: false,
@@ -68,6 +73,10 @@ export default {
},
computed: {
emailIsValid() {
+ if (!this.canUseEmailToken) {
+ return false;
+ }
+
const regex = /^\S+@\S+$/;
return this.originalInput.match(regex) !== null;
@@ -137,9 +146,8 @@ export default {
username: token.username,
avatar_url: token.avatar_url,
}));
- this.loading = false;
})
- .catch(() => {
+ .finally(() => {
this.loading = false;
});
}, SEARCH_DELAY),
diff --git a/app/assets/javascripts/invite_members/components/project_select.vue b/app/assets/javascripts/invite_members/components/project_select.vue
index 640df5cdb88..6c2f53afe3c 100644
--- a/app/assets/javascripts/invite_members/components/project_select.vue
+++ b/app/assets/javascripts/invite_members/components/project_select.vue
@@ -115,7 +115,6 @@ export default {
:search-placeholder="$options.i18n.searchPlaceholder"
:no-results-text="$options.i18n.emptySearchResult"
data-testid="project-select-dropdown"
- data-qa-selector="project_select_dropdown"
class="gl-collapsible-listbox-w-full"
@search="searchTerm = $event"
@select="selectProject"
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 41ed0179364..8dfe697e2cb 100644
--- a/app/assets/javascripts/invite_members/init_invite_members_modal.js
+++ b/app/assets/javascripts/invite_members/init_invite_members_modal.js
@@ -25,6 +25,9 @@ export default (function initInviteMembersModal() {
name: 'InviteMembersModalRoot',
provide: {
name: el.dataset.name,
+ newUsersUrl: el.dataset.newUsersUrl,
+ isCurrentUserAdmin: parseBoolean(el.dataset.isCurrentUserAdmin),
+ isEmailSignupEnabled: parseBoolean(el.dataset.isSignupEnabled),
},
render: (createElement) =>
createElement(InviteMembersModal, {
diff --git a/app/assets/javascripts/invite_members/utils/member_utils.js b/app/assets/javascripts/invite_members/utils/member_utils.js
index 7998cb69445..52fb5e98f27 100644
--- a/app/assets/javascripts/invite_members/utils/member_utils.js
+++ b/app/assets/javascripts/invite_members/utils/member_utils.js
@@ -6,3 +6,7 @@ export function memberName(member) {
export function triggerExternalAlert() {
return false;
}
+
+export function inviteMembersTrackingOptions(options) {
+ return { label: options.label };
+}