Skip to content
Snippets Groups Projects

Add a user overage modal

Merged Diana Zubova requested to merge dz/348486-add-second-modal into master
Compare and Show latest version
8 files
+ 411
204
Compare changes
  • Side-by-side
  • Inline
Files
8
@@ -113,9 +113,9 @@ export default {
required: true,
},
subscriptionSeats: {
type: String,
type: Number,
required: false,
default: '',
default: 10,
},
},
data() {
@@ -134,7 +134,7 @@ export default {
isLoading: false,
mode: 'default',
hasOverage: false,
totalUserCount: 1, // TODO: calculate this value
totalUserCount: null,
};
},
computed: {
@@ -284,15 +284,16 @@ export default {
}
},
checkOverage() {
// TODO: add proper check
const triggersOverage = true;
if (triggersOverage) {
// add a more complex check in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78287
// totalUserCount should be calculated there
if (this.enabledOverageCheck) {
this.totalUserCount = 1;
this.hasOverage = true;
} else {
this.sendInvite();
}
},
handleCancel() {
handleBack() {
this.hasOverage = false;
},
trackinviteMembersForTask() {
@@ -426,201 +427,199 @@ export default {
};
</script>
<template>
<div>
<gl-modal
ref="modal"
:modal-id="modalId"
size="sm"
data-qa-selector="invite_members_modal_content"
data-testid="invite-members-modal"
:title="modalTitle"
:header-close-label="$options.labels.headerCloseLabel"
@hidden="resetFields"
@close="resetFields"
@hide="resetFields"
>
<div :class="{ 'gl-display-none': showOverageModal }">
<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>
<gl-modal
ref="modal"
:modal-id="modalId"
size="sm"
data-qa-selector="invite_members_modal_content"
data-testid="invite-members-modal"
:title="modalTitle"
:header-close-label="$options.labels.headerCloseLabel"
@hidden="resetFields"
@close="resetFields"
@hide="resetFields"
>
<div v-show="!showOverageModal">
<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"
:state="validationState"
:description="errorFieldDescription"
data-testid="members-form-group"
>
<label :id="$options.membersTokenSelectLabelId" class="col-form-label">{{
$options.labels[inviteeType].searchField
}}</label>
<members-token-select
v-if="!isInviteGroup"
v-model="newUsersToInvite"
class="gl-mb-2"
:validation-state="validationState"
:aria-labelledby="$options.membersTokenSelectLabelId"
:users-filter="usersFilter"
:filter-id="filterId"
@clear="handleMembersTokenSelectClear"
/>
<group-select
v-if="isInviteGroup"
v-model="groupToBeSharedWith"
:access-levels="accessLevels"
:groups-filter="groupSelectFilter"
:parent-group-id="groupSelectParentId"
@input="handleMembersTokenSelectClear"
/>
</gl-form-group>
<gl-form-group
:invalid-feedback="invalidFeedbackMessage"
:state="validationState"
:description="errorFieldDescription"
data-testid="members-form-group"
>
<label :id="$options.membersTokenSelectLabelId" class="col-form-label">{{
$options.labels[inviteeType].searchField
}}</label>
<members-token-select
v-if="!isInviteGroup"
v-model="newUsersToInvite"
class="gl-mb-2"
:validation-state="validationState"
:aria-labelledby="$options.membersTokenSelectLabelId"
:users-filter="usersFilter"
:filter-id="filterId"
@clear="handleMembersTokenSelectClear"
/>
<group-select
v-if="isInviteGroup"
v-model="groupToBeSharedWith"
:access-levels="accessLevels"
:groups-filter="groupSelectFilter"
:parent-group-id="groupSelectParentId"
@input="handleMembersTokenSelectClear"
/>
</gl-form-group>
<label class="gl-font-weight-bold">{{ $options.labels.accessLevel }}</label>
<div class="gl-mt-2 gl-w-half gl-xs-w-full">
<gl-dropdown
class="gl-shadow-none gl-w-full"
data-qa-selector="access_level_dropdown"
v-bind="$attrs"
:text="selectedRoleName"
>
<template v-for="(key, item) in accessLevels">
<gl-dropdown-item
:key="key"
active-class="is-active"
is-check-item
:is-checked="key === selectedAccessLevel"
@click="changeSelectedItem(key)"
>
<div>{{ item }}</div>
</gl-dropdown-item>
</template>
</gl-dropdown>
</div>
<label class="gl-font-weight-bold">{{ $options.labels.accessLevel }}</label>
<div class="gl-mt-2 gl-w-half gl-xs-w-full">
<gl-dropdown
class="gl-shadow-none gl-w-full"
data-qa-selector="access_level_dropdown"
v-bind="$attrs"
:text="selectedRoleName"
>
<template v-for="(key, item) in accessLevels">
<gl-dropdown-item
:key="key"
active-class="is-active"
is-check-item
:is-checked="key === selectedAccessLevel"
@click="changeSelectedItem(key)"
>
<div>{{ item }}</div>
</gl-dropdown-item>
</template>
</gl-dropdown>
</div>
<div class="gl-mt-2 gl-w-half gl-xs-w-full">
<gl-sprintf :message="$options.labels.readMoreText">
<template #link="{ content }">
<gl-link :href="helpLink" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</div>
<div class="gl-mt-2 gl-w-half gl-xs-w-full">
<gl-sprintf :message="$options.labels.readMoreText">
<template #link="{ content }">
<gl-link :href="helpLink" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</div>
<label class="gl-mt-5 gl-display-block" for="expires_at">{{
$options.labels.accessExpireDate
}}</label>
<div class="gl-mt-2 gl-w-half gl-xs-w-full gl-display-inline-block">
<gl-datepicker
v-model="selectedDate"
class="gl-display-inline!"
:min-date="new Date()"
:target="null"
>
<template #default="{ formattedDate }">
<gl-form-input
class="gl-w-full"
:value="formattedDate"
:placeholder="__(`YYYY-MM-DD`)"
/>
</template>
</gl-datepicker>
</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"
<label class="gl-mt-5 gl-display-block" for="expires_at">{{
$options.labels.accessExpireDate
}}</label>
<div class="gl-mt-2 gl-w-half gl-xs-w-full gl-display-inline-block">
<gl-datepicker
v-model="selectedDate"
class="gl-display-inline!"
:min-date="new Date()"
:target="null"
>
<template #default="{ formattedDate }">
<gl-form-input
class="gl-w-full"
:value="formattedDate"
:placeholder="__(`YYYY-MM-DD`)"
/>
<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>
<div :class="{ 'gl-display-none': !showOverageModal }">
{{ modalInfo }}
<gl-link :href="$options.i18n.url" target="_blank">{{ $options.i18n.linkText }}</gl-link>
</gl-datepicker>
</div>
<template #modal-footer>
<template v-if="!showOverageModal">
<gl-button data-testid="cancel-button" @click="closeModal">
{{ $options.labels.cancelButtonText }}
</gl-button>
<gl-button
:disabled="inviteDisabled"
:loading="isLoading"
variant="success"
data-qa-selector="invite_button"
data-testid="invite-button"
@click="checkOverage"
>
{{ $options.labels.inviteButtonText }}
</gl-button>
</template>
<template v-else>
<gl-button data-testid="overage-back-button" @click="handleCancel">
{{ $options.i18n.buttonLabel }}
</gl-button>
<gl-button
:disabled="inviteDisabled"
:loading="isLoading"
variant="success"
data-qa-selector="invite_with_overage_button"
data-testid="invite-with-overage-button"
@click="sendInvite"
>
{{ $options.labels.inviteButtonText }}
</gl-button>
<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>
<div v-if="showOverageModal">
{{ modalInfo }}
<gl-link :href="$options.i18n.url" target="_blank">{{ $options.i18n.linkText }}</gl-link>
</div>
<template #modal-footer>
<template v-if="!showOverageModal">
<gl-button data-testid="cancel-button" @click="closeModal">
{{ $options.labels.cancelButtonText }}
</gl-button>
<gl-button
:disabled="inviteDisabled"
:loading="isLoading"
variant="success"
data-qa-selector="invite_button"
data-testid="invite-button"
@click="checkOverage"
>
{{ $options.labels.inviteButtonText }}
</gl-button>
</template>
<template v-else>
<gl-button data-testid="overage-back-button" @click="handleBack">
{{ $options.i18n.buttonLabel }}
</gl-button>
<gl-button
:disabled="inviteDisabled"
:loading="isLoading"
variant="success"
data-qa-selector="invite_with_overage_button"
data-testid="invite-with-overage-button"
@click="sendInvite"
>
{{ $options.labels.inviteButtonText }}
</gl-button>
</template>
</gl-modal>
</div>
</template>
</gl-modal>
</template>
Loading