diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-30 15:09:14 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-30 15:09:14 +0300 |
commit | e672c333df6dc238e5050ab5eb709d6df5c87380 (patch) | |
tree | 3ac7828341ffa6dd4abbca6207be58129ceb4cfb /app/assets/javascripts/invite_members | |
parent | df2358a5f7a8fe32285ac62054314287fb871e49 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/invite_members')
4 files changed, 111 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 index da0c7860932..23225869636 100644 --- a/app/assets/javascripts/invite_members/components/invite_members_modal.vue +++ b/app/assets/javascripts/invite_members/components/invite_members_modal.vue @@ -24,6 +24,7 @@ import { responseMessageFromSuccess } from '../utils/response_message_parser'; import { getInvalidFeedbackMessage } from '../utils/get_invalid_feedback_message'; import ModalConfetti from './confetti.vue'; import MembersTokenSelect from './members_token_select.vue'; +import UserLimitNotification from './user_limit_notification.vue'; export default { name: 'InviteMembersModal', @@ -37,6 +38,7 @@ export default { InviteModalBase, MembersTokenSelect, ModalConfetti, + UserLimitNotification, }, inject: ['newProjectPath'], props: { @@ -308,6 +310,11 @@ export default { <span v-if="isCelebration">{{ $options.labels.modal.celebrate.intro }} </span> <modal-confetti v-if="isCelebration" /> </template> + + <template #user-limit-notification> + <user-limit-notification /> + </template> + <template #select="{ validationState, labelId }"> <members-token-select v-model="newUsersToInvite" 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 bafbe94b8bd..43cd889c9b3 100644 --- a/app/assets/javascripts/invite_members/components/invite_modal_base.vue +++ b/app/assets/javascripts/invite_members/components/invite_modal_base.vue @@ -215,6 +215,8 @@ export default { <slot name="intro-text-after"></slot> </div> + <slot name="user-limit-notification"></slot> + <gl-form-group :invalid-feedback="invalidFeedbackMessage" :state="validationState" diff --git a/app/assets/javascripts/invite_members/components/user_limit_notification.vue b/app/assets/javascripts/invite_members/components/user_limit_notification.vue new file mode 100644 index 00000000000..beef1aef8a1 --- /dev/null +++ b/app/assets/javascripts/invite_members/components/user_limit_notification.vue @@ -0,0 +1,97 @@ +<script> +import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui'; +import { s__, n__, sprintf } from '~/locale'; + +const CLOSE_TO_LIMIT_COUNT = 2; + +const WARNING_ALERT_TITLE = s__( + 'InviteMembersModal|You only have space for %{count} more %{members} in %{name}', +); + +const DANGER_ALERT_TITLE = s__( + "InviteMembersModal|You've reached your %{count} %{members} limit for %{name}", +); + +const CLOSE_TO_LIMIT_MESSAGE = s__( + 'InviteMembersModal|To get more members an owner of this namespace can %{trialLinkStart}start a trial%{trialLinkEnd} or %{upgradeLinkStart}upgrade%{upgradeLinkEnd} to a paid tier.', +); + +const REACHED_LIMIT_MESSAGE = s__( + 'InviteMembersModal|New members will be unable to participate. You can manage your members by removing ones you no longer need.', +).concat(' ', CLOSE_TO_LIMIT_MESSAGE); + +export default { + name: 'UserLimitNotification', + components: { GlAlert, GlSprintf, GlLink }, + inject: ['name', 'newTrialRegistrationPath', 'purchasePath', 'freeUsersLimit', 'membersCount'], + computed: { + reachedLimit() { + return this.isLimit(); + }, + closeToLimit() { + return this.isLimit(CLOSE_TO_LIMIT_COUNT); + }, + warningAlertTitle() { + return sprintf(WARNING_ALERT_TITLE, { + count: this.freeUsersLimit - this.membersCount, + members: this.pluralMembers(this.freeUsersLimit - this.membersCount), + name: this.name, + }); + }, + dangerAlertTitle() { + return sprintf(DANGER_ALERT_TITLE, { + count: this.freeUsersLimit, + members: this.pluralMembers(this.freeUsersLimit), + name: this.name, + }); + }, + variant() { + return this.reachedLimit ? 'danger' : 'warning'; + }, + title() { + return this.reachedLimit ? this.dangerAlertTitle : this.warningAlertTitle; + }, + message() { + if (this.reachedLimit) { + return this.$options.i18n.reachedLimitMessage; + } + + return this.$options.i18n.closeToLimitMessage; + }, + }, + methods: { + isLimit(deviation = 0) { + if (this.freeUsersLimit && this.membersCount) { + return this.membersCount >= this.freeUsersLimit - deviation; + } + + return false; + }, + pluralMembers(count) { + return n__('member', 'members', count); + }, + }, + i18n: { + reachedLimitMessage: REACHED_LIMIT_MESSAGE, + closeToLimitMessage: CLOSE_TO_LIMIT_MESSAGE, + }, +}; +</script> + +<template> + <gl-alert + v-if="reachedLimit || closeToLimit" + :variant="variant" + :dismissible="false" + :title="title" + > + <gl-sprintf :message="message"> + <template #trialLink="{ content }"> + <gl-link :href="newTrialRegistrationPath" class="gl-label-link">{{ content }}</gl-link> + </template> + <template #upgradeLink="{ content }"> + <gl-link :href="purchasePath" class="gl-label-link">{{ content }}</gl-link> + </template> + </gl-sprintf> + </gl-alert> +</template> 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 cb05798bb9d..958121ad735 100644 --- a/app/assets/javascripts/invite_members/init_invite_members_modal.js +++ b/app/assets/javascripts/invite_members/init_invite_members_modal.js @@ -24,7 +24,12 @@ export default (function initInviteMembersModal() { el, name: 'InviteMembersModalRoot', provide: { + name: el.dataset.name, newProjectPath: el.dataset.newProjectPath, + newTrialRegistrationPath: el.dataset.newTrialRegistrationPath, + purchasePath: el.dataset.purchasePath, + freeUsersLimit: el.dataset.freeUsersLimit && parseInt(el.dataset.freeUsersLimit, 10), + membersCount: el.dataset.membersCount && parseInt(el.dataset.membersCount, 10), }, render: (createElement) => createElement(InviteMembersModal, { |