Commit 89356357 authored by Diana Zubova's avatar Diana Zubova Committed by Miguel Rincon

Add transition between invite members modal

Smooth UX transition

EE: true
parent d94c5986
......@@ -131,10 +131,13 @@ export default {
return this.glFeatures.overageMembersModal;
},
modalInfo() {
if (this.totalUserCount) {
const infoText = this.$options.i18n.infoText(this.subscriptionSeats);
const infoWarning = this.$options.i18n.infoWarning(this.totalUserCount, this.name);
return `${infoText} ${infoWarning}`;
}
return '';
},
modalTitleLabel() {
return this.showOverageModal ? this.$options.i18n.OVERAGE_MODAL_TITLE : this.modalTitle;
......@@ -243,7 +246,13 @@ export default {
@close="reset"
@hide="reset"
>
<div v-show="!showOverageModal">
<div class="gl-display-grid">
<transition name="invite-modal-transition">
<div
v-show="!showOverageModal"
class="invite-modal-content"
data-testid="invite-modal-initial-content"
>
<div class="gl-display-flex" data-testid="modal-base-intro-text">
<slot name="intro-text-before"></slot>
<p>
......@@ -320,12 +329,20 @@ export default {
</div>
<slot name="form-after"></slot>
</div>
<div v-if="showOverageModal">
</transition>
<transition name="invite-modal-transition">
<div
v-show="showOverageModal"
class="invite-modal-content"
data-testid="invite-modal-overage-content"
>
{{ modalInfo }}
<gl-link :href="$options.i18n.OVERAGE_MODAL_LINK" target="_blank">{{
$options.i18n.OVERAGE_MODAL_LINK_TEXT
}}</gl-link>
</div>
</transition>
</div>
<template #modal-footer>
<template v-if="!showOverageModal">
<gl-button data-testid="cancel-button" @click="closeModal">
......
......@@ -42,3 +42,34 @@
svg g { fill: $gray-600; }
}
}
.invite-modal-content {
grid-row: 1;
grid-column: 1;
}
$max-invite-modal-height: 600px;
// Custom styles for invite-modal-transition
// Used by Vue Transition API
.invite-modal-transition-enter-active,
.invite-modal-transition-leave-active {
transition-property: max-height, opacity;
transition-timing-function: ease-in-out;
@include gl-transition-slow;
overflow: hidden;
}
.invite-modal-transition-enter,
.invite-modal-transition-leave-to {
max-height: 0;
opacity: 0;
}
.invite-modal-transition-enter-to,
.invite-modal-transition-leave {
max-height: px-to-rem($max-invite-modal-height);
}
......@@ -16,7 +16,6 @@ import {
OVERAGE_MODAL_CONTINUE_BUTTON,
OVERAGE_MODAL_BACK_BUTTON,
} from 'ee/invite_members/constants';
import waitForPromises from 'helpers/wait_for_promises';
import { propsData } from 'jest/invite_members/mock_data/modal_base';
describe('InviteModalBase', () => {
......@@ -63,6 +62,8 @@ describe('InviteModalBase', () => {
const findInviteButton = () => wrapper.findByTestId('invite-button');
const findBackButton = () => wrapper.findByTestId('overage-back-button');
const findOverageInviteButton = () => wrapper.findByTestId('invite-with-overage-button');
const findInitialModalContent = () => wrapper.findByTestId('invite-modal-initial-content');
const findOverageModalContent = () => wrapper.findByTestId('invite-modal-overage-content');
const clickInviteButton = () => findInviteButton().vm.$emit('click');
const clickBackButton = () => findBackButton().vm.$emit('click');
......@@ -102,25 +103,23 @@ describe('InviteModalBase', () => {
});
});
describe('rendering the help link', () => {
it('renders the correct link', () => {
expect(findLink().attributes('href')).toBe(propsData.helpLink);
});
});
describe('rendering the access expiration date field', () => {
it('renders the datepicker', () => {
expect(findDatepicker().exists()).toBe(true);
});
it("doesn't show the overage content", () => {
expect(findOverageModalContent().isVisible()).toBe(false);
});
});
describe('displays overage modal', () => {
beforeEach(async () => {
beforeEach(() => {
createComponent({}, {}, { glFeatures: { overageMembersModal: true } });
clickInviteButton();
await waitForPromises();
});
it('renders the modal with the correct title', () => {
......@@ -141,11 +140,21 @@ describe('InviteModalBase', () => {
);
});
it('switches back to the intial modal', async () => {
clickBackButton();
await waitForPromises();
it('doesn\t show the initial modal content', () => {
expect(findInitialModalContent().isVisible()).toBe(false);
});
describe('when switches back to the initial modal', () => {
beforeEach(() => clickBackButton());
it('shows the initial modal', () => {
expect(wrapper.findComponent(GlModal).props('title')).toBe('_modal_title_');
expect(findInitialModalContent().isVisible()).toBe(true);
});
it("doesn't show the overage content", () => {
expect(findOverageModalContent().isVisible()).toBe(false);
});
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment