Skip to content

Commit

Permalink
fix: update subscription expiration messaging and styles (#568)
Browse files Browse the repository at this point in the history
* fix: update messaging and styles

* fix: ENT-4047 - remove duplicate user hydration call

* refactor: split expiring and expired modals into separate components

* docs: add jsdocs to document purpose of component

* fix: bulk enrollment tests to not have all expired plans

* fix: lint

* fix: expiration modal padding
  • Loading branch information
adamstankiewicz authored Jun 2, 2021
1 parent 54c5590 commit 546f785
Show file tree
Hide file tree
Showing 20 changed files with 469 additions and 313 deletions.
28 changes: 17 additions & 11 deletions src/components/BulkEnrollmentPage/index.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import userEvent from '@testing-library/user-event';
import { renderWithRouter } from '../test/testUtils';
import '@testing-library/jest-dom';

import BulkEnrollmentPage from './index';
import '../../../__mocks__/react-instantsearch-dom';

import { SUBSCRIPTION_DAYS_REMAINING_MODERATE } from '../subscriptions/data/constants';
import LicenseManagerApiService from '../../data/services/LicenseManagerAPIService';
import { ROUTE_NAMES } from '../EnterpriseApp/constants';
import { ADD_COURSES_TITLE } from './stepper/constants';
import '@testing-library/jest-dom';
import { renderWithRouter } from '../test/testUtils';
import '../../../__mocks__/react-instantsearch-dom';

jest.mock('../../data/services/LicenseManagerAPIService', () => ({
__esModule: true,
Expand All @@ -26,26 +29,33 @@ const sub1 = {
uuid: 'foo',
title: 'horse subscription',
enterpriseSlug: testSlug,
startDate: 1621347682,
expirationDate: 1721547682,
startDate: '01-01-2021',
expirationDate: '04-21-2021',
daysUntilExpiration: 0,
licenses: {
allocated: 5,
total: 20,
},
enterpriseCatalogUuid: 'blarghl2',
};

// force the expiration modal to not expire by default to avoid
// needing to close it in unrelated tests
const numDaysUntilExpiration = SUBSCRIPTION_DAYS_REMAINING_MODERATE + 1;
const futureExpirationDate = new Date();
futureExpirationDate.setDate(futureExpirationDate.getDate() + numDaysUntilExpiration);
const sub2 = {
uuid: 'bearz',
title: 'bear subscription',
enterpriseSlug: testSlug,
startDate: 1621347682,
expirationDate: 1721547682,
startDate: '02-01-2021',
expirationDate: futureExpirationDate.toLocaleString(),
licenses: {
allocated: 15,
total: 40,
},
enterpriseCatalogUuid: 'blarghl',
daysUntilExpiration: numDaysUntilExpiration,
};

const mockSubscriptionCount = Promise.resolve({
Expand Down Expand Up @@ -119,10 +129,6 @@ describe('<BulkEnrollmentPage />', () => {
it('renders course search page when navigating via subscription picker', async () => {
renderWithRouter(<BulkEnrollmentWrapper />, { route: `/${testSlug}/admin/${ROUTE_NAMES.bulkEnrollment}` });
await act(() => subscriptions);
// The expiration modal makes the enroll learners link inaccessible, so we need to dismiss it first.
const modalButton = await screen.getByRole('button', { name: 'OK' });
userEvent.click(modalButton);

const sub1Button = screen.getAllByRole('link', { name: 'Enroll learners' })[0];
userEvent.click(sub1Button);
expect(screen.getByRole('heading', { level: 2 })).toHaveTextContent(ADD_COURSES_TITLE);
Expand Down
12 changes: 2 additions & 10 deletions src/components/Header/index.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, { useEffect } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import {
Dropdown, Navbar, AvatarButton, Nav,
} from '@edx/paragon';
import { getProxyLoginUrl } from '@edx/frontend-enterprise-logistration';

import {
getAuthenticatedUser, hydrateAuthenticatedUser, getLogoutRedirectUrl,
getAuthenticatedUser, getLogoutRedirectUrl,
} from '@edx/frontend-platform/auth';
import SidebarToggle from '../../containers/SidebarToggle';
import Img from '../Img';
Expand Down Expand Up @@ -83,14 +83,6 @@ const Header = ({
hasSidebarToggle, enterpriseName, enterpriseLogo, enterpriseSlug,
}) => {
const user = getAuthenticatedUser();
useEffect(() => {
// if there is no email, the user data has not been hydrated
if (user && !user.email) {
hydrateAuthenticatedUser();
}
// rehydrate if the username changes
}, [user?.username, user?.id]);

return (
<header className="container-fluid border-bottom">
<Navbar aria-label="header" className="px-0 py-1 justify-content-between">
Expand Down
18 changes: 9 additions & 9 deletions src/components/subscriptions/SubscriptionCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ const SubscriptionCard = ({
return (
<Card className="subscription-card w-100">
<Card.Body>
<Card.Title>
<Card.Title className="mb-0">
{title}
{isExpired && (
<div className="ml-2">
<Badge variant="danger">
Expired
</Badge>
</div>
)}
</Card.Title>
<p className="small">
{isExpired && (
<div>
<Badge variant="danger">
Expired
</Badge>
</div>
)}
<p className="mt-2 small">
{formattedStartDate} - {formattedExpirationDate}
</p>
<p className="mt-3 mb-0 small">
Expand Down
4 changes: 2 additions & 2 deletions src/components/subscriptions/SubscriptionDetailPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { Redirect } from 'react-router-dom';

import SubscriptionExpirationBanner from './expiration/SubscriptionExpirationBanner';
import SubscriptionExpirationModal from './expiration/SubscriptionExpirationModal';
import SubscriptionExpirationModals from './expiration/SubscriptionExpirationModals';
import SubscriptionDetails from './SubscriptionDetails';
import LicenseAllocationDetails from './licenses/LicenseAllocationDetails';
import SubscriptionDetailContextProvider from './SubscriptionDetailContextProvider';
Expand All @@ -30,7 +30,7 @@ const SubscriptionDetailPage = ({ match }) => {
return (
<SubscriptionDetailContextProvider subscription={subscription}>
<SubscriptionExpirationBanner />
<SubscriptionExpirationModal />
<SubscriptionExpirationModals />
<SubscriptionDetails />
<LicenseAllocationDetails />
</SubscriptionDetailContextProvider>
Expand Down
11 changes: 6 additions & 5 deletions src/components/subscriptions/SubscriptionDetails.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { connect } from 'react-redux';
import moment from 'moment';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faAngleLeft } from '@fortawesome/free-solid-svg-icons';
import { Row, Col } from '@edx/paragon';
import { Button, Row, Col } from '@edx/paragon';

import { SubscriptionDetailContext } from './SubscriptionDetailContextProvider';
import { TAB_ALL_USERS, TAB_PENDING_USERS } from './data/constants';
Expand All @@ -26,10 +26,11 @@ const SubscriptionDetails = ({ enterpriseSlug }) => {
<>
{hasMultipleSubscriptions && (
<Row className="ml-0 mb-3">
<Link to={`/${enterpriseSlug}/admin/subscriptions`} className="btn btn-outline-primary">
<FontAwesomeIcon icon={faAngleLeft} />
{' '}
Back to subscriptions
<Link to={`/${enterpriseSlug}/admin/subscriptions`}>
<Button variant="outline-primary">
<FontAwesomeIcon icon={faAngleLeft} className="mr-2" />
Back to subscriptions
</Button>
</Link>
</Row>
)}
Expand Down
9 changes: 9 additions & 0 deletions src/components/subscriptions/data/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { SEEN_SUBSCRIPTION_EXPIRATION_MODAL_COOKIE_PREFIX } from './constants';

// eslint-disable-next-line import/prefer-default-export
export const getSubscriptionExpiringCookieName = ({
expirationThreshold, enterpriseId,
}) => {
const cookieName = `${SEEN_SUBSCRIPTION_EXPIRATION_MODAL_COOKIE_PREFIX}${expirationThreshold}-${enterpriseId}`;
return cookieName;
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, { useContext } from 'react';
import { SubscriptionContext } from '../SubscriptionData';
import SubscriptionDetailContextProvider from '../SubscriptionDetailContextProvider';
import SubscriptionExpirationBanner from './SubscriptionExpirationBanner';
import SubscriptionExpirationModal from './SubscriptionExpirationModal';
import SubscriptionExpirationModals from './SubscriptionExpirationModals';

const SubscriptionExpiration = () => {
const { data } = useContext(SubscriptionContext);
Expand All @@ -17,7 +17,7 @@ const SubscriptionExpiration = () => {
{subscriptionFurthestFromExpiration.daysUntilExpiration > 0 && (
<SubscriptionExpirationBanner />
)}
<SubscriptionExpirationModal />
<SubscriptionExpirationModals />
</SubscriptionDetailContextProvider>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const SubscriptionExpirationBanner = () => {
<>
{hasMultipleSubscriptions && daysUntilExpiration <= 0 ? (
<>
This batch has expired. You are able to view the statuses of your invited learners.
This subscription cohort has expired. You may still view the statuses of learners who participated.
</>
) : (
<>
Expand Down

This file was deleted.

Loading

0 comments on commit 546f785

Please sign in to comment.