Updated frontend-build to v12 (#962)

* feat: rebase previous frontend-build upgrade

* chore: make welcome message to default to empty
This commit is contained in:
Bilal Qamar
2023-01-30 22:20:07 +05:00
committed by GitHub
parent b500546e8d
commit b3d33667d4
164 changed files with 847 additions and 798 deletions

View File

@@ -12,13 +12,14 @@ import { LOADED, LOADING } from '../course-home/data/slice';
import PageLoading from './PageLoading';
import messages from '../tab-page/messages';
function CourseAccessErrorPage({ intl }) {
const CourseAccessErrorPage = ({ intl }) => {
const { courseId } = useParams();
const dispatch = useDispatch();
const activeEnterpriseAlert = useActiveEnterpriseAlert(courseId);
useEffect(() => {
dispatch(fetchDiscussionTab(courseId));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [courseId]);
const {
@@ -54,7 +55,7 @@ function CourseAccessErrorPage({ intl }) {
<Footer />
</>
);
}
};
CourseAccessErrorPage.propTypes = {
intl: intlShape.isRequired,

View File

@@ -11,7 +11,9 @@ jest.mock('react-redux', () => ({
useDispatch: () => mockDispatch,
useSelector: () => ({ courseStatus: mockCourseStatus }),
}));
jest.mock('./PageLoading', () => () => <div data-testid="page-loading" />);
jest.mock('./PageLoading', () => function () {
return <div data-testid="page-loading" />;
});
describe('CourseAccessErrorPage', () => {
let courseId;

View File

@@ -10,6 +10,7 @@ import { getNotices } from './api';
*/
const NoticesProvider = ({ children }) => {
const [isRedirected, setIsRedirected] = useState();
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(async () => {
if (getConfig().ENABLE_NOTICES) {
const data = await getNotices();

View File

@@ -6,7 +6,7 @@ import classNames from 'classnames';
import useIndexOfLastVisibleChild from './useIndexOfLastVisibleChild';
export default function Tabs({ children, className, ...attrs }) {
const Tabs = ({ children, className, ...attrs }) => {
const [
indexOfLastVisibleChild,
containerElementRef,
@@ -52,7 +52,7 @@ export default function Tabs({ children, className, ...attrs }) {
),
);
return wrappedChildren;
}, [children, indexOfLastVisibleChild]);
}, [children, indexOfLastVisibleChild, invisibleStyle, overflowElementRef]);
return (
<nav
@@ -63,7 +63,7 @@ export default function Tabs({ children, className, ...attrs }) {
{tabChildren}
</nav>
);
}
};
Tabs.propTypes = {
children: PropTypes.node,
@@ -74,3 +74,5 @@ Tabs.defaultProps = {
children: null,
className: undefined,
};
export default Tabs;

View File

@@ -70,6 +70,7 @@ export default function useIndexOfLastVisibleChild() {
});
setIndexOfLastVisibleChild(nextIndexOfLastVisibleChild);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [windowSize, containerElementRef.current]);
return [indexOfLastVisibleChild, containerElementRef, invisibleStyle, overflowElementRef];

View File

@@ -4,7 +4,7 @@ import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import messages from './messages';
function FormattedPricing(props) {
const FormattedPricing = (props) => {
const {
inline,
intl,
@@ -57,7 +57,7 @@ function FormattedPricing(props) {
</span>
</>
);
}
};
FormattedPricing.defaultProps = {
inline: false,

View File

@@ -5,7 +5,7 @@ import { Button } from '@edx/paragon';
import FormattedPricing from './FormattedPricing';
function UpgradeButton(props) {
const UpgradeButton = (props) => {
const {
intl,
offer,
@@ -41,7 +41,7 @@ function UpgradeButton(props) {
</div>
</Button>
);
}
};
UpgradeButton.defaultProps = {
offer: null,

View File

@@ -5,7 +5,7 @@ import { Button } from '@edx/paragon';
import FormattedPricing from './FormattedPricing';
function UpgradeNowButton(props) {
const UpgradeNowButton = (props) => {
const {
intl,
offer,
@@ -39,7 +39,7 @@ function UpgradeNowButton(props) {
/>
</Button>
);
}
};
UpgradeNowButton.defaultProps = {
offer: null,

View File

@@ -13,27 +13,23 @@ import {
SupportMissionBullet,
} from '../upsell-bullets/UpsellBullets';
function UpsellNoFBECardContent() {
return (
<ul className="fa-ul upgrade-notification-ul pt-0">
<VerifiedCertBullet />
<SupportMissionBullet />
</ul>
);
}
const UpsellNoFBECardContent = () => (
<ul className="fa-ul upgrade-notification-ul pt-0">
<VerifiedCertBullet />
<SupportMissionBullet />
</ul>
);
function UpsellFBEFarAwayCardContent() {
return (
<ul className="fa-ul upgrade-notification-ul">
<VerifiedCertBullet />
<UnlockGradedBullet />
<FullAccessBullet />
<SupportMissionBullet />
</ul>
);
}
const UpsellFBEFarAwayCardContent = () => (
<ul className="fa-ul upgrade-notification-ul">
<VerifiedCertBullet />
<UnlockGradedBullet />
<FullAccessBullet />
<SupportMissionBullet />
</ul>
);
function UpsellFBESoonCardContent({ accessExpirationDate, timezoneFormatArgs }) {
const UpsellFBESoonCardContent = ({ accessExpirationDate, timezoneFormatArgs }) => {
const includingAnyProgress = (
<span className="font-weight-bold">
<FormattedMessage
@@ -83,7 +79,7 @@ function UpsellFBESoonCardContent({ accessExpirationDate, timezoneFormatArgs })
</p>
</div>
);
}
};
UpsellFBESoonCardContent.propTypes = {
accessExpirationDate: PropTypes.PropTypes.instanceOf(Date).isRequired,
@@ -96,22 +92,20 @@ UpsellFBESoonCardContent.defaultProps = {
timezoneFormatArgs: {},
};
function PastExpirationCardContent() {
return (
<div className="upgrade-notification-text">
<p>
<FormattedMessage
id="learning.generic.upgradeNotification.pastExpiration.content"
defaultMessage="The upgrade deadline for this course passed. To upgrade, enroll in the next available session."
/>
</p>
</div>
);
}
const PastExpirationCardContent = () => (
<div className="upgrade-notification-text">
<p>
<FormattedMessage
id="learning.generic.upgradeNotification.pastExpiration.content"
defaultMessage="The upgrade deadline for this course passed. To upgrade, enroll in the next available session."
/>
</p>
</div>
);
function ExpirationCountdown({
const ExpirationCountdown = ({
courseId, hoursToExpiration, setupgradeNotificationCurrentState, type,
}) {
}) => {
let expirationText;
if (hoursToExpiration >= 24) { // More than 1 day left
// setupgradeNotificationCurrentState is available in NotificationTray (not course home)
@@ -179,7 +173,7 @@ function ExpirationCountdown({
);
}
return (<div className="upsell-warning">{expirationText}</div>);
}
};
ExpirationCountdown.propTypes = {
courseId: PropTypes.string.isRequired,
@@ -192,9 +186,9 @@ ExpirationCountdown.defaultProps = {
type: null,
};
function AccessExpirationDateBanner({
const AccessExpirationDateBanner = ({
courseId, accessExpirationDate, timezoneFormatArgs, setupgradeNotificationCurrentState,
}) {
}) => {
if (setupgradeNotificationCurrentState) {
setupgradeNotificationCurrentState('accessDateView');
setLocalStorage(`upgradeNotificationCurrentState.${courseId}`, 'accessDateView');
@@ -218,7 +212,7 @@ function AccessExpirationDateBanner({
/>
</div>
);
}
};
AccessExpirationDateBanner.propTypes = {
courseId: PropTypes.string.isRequired,
@@ -234,9 +228,9 @@ AccessExpirationDateBanner.defaultProps = {
setupgradeNotificationCurrentState: null,
};
function PastExpirationDateBanner({
const PastExpirationDateBanner = ({
courseId, accessExpirationDate, timezoneFormatArgs, setupgradeNotificationCurrentState,
}) {
}) => {
if (setupgradeNotificationCurrentState) {
setupgradeNotificationCurrentState('PastExpirationDate');
setLocalStorage(`upgradeNotificationCurrentState.${courseId}`, 'PastExpirationDate');
@@ -260,7 +254,7 @@ function PastExpirationDateBanner({
/>
</div>
);
}
};
PastExpirationDateBanner.propTypes = {
courseId: PropTypes.string.isRequired,
@@ -276,7 +270,7 @@ PastExpirationDateBanner.defaultProps = {
setupgradeNotificationCurrentState: null,
};
function UpgradeNotification({
const UpgradeNotification = ({
accessExpiration,
contentTypeGatingEnabled,
marketingUrl,
@@ -289,17 +283,13 @@ function UpgradeNotification({
upsellPageName,
userTimezone,
verifiedMode,
}) {
}) => {
const dateNow = Date.now();
const timezoneFormatArgs = userTimezone ? { timeZone: userTimezone } : {};
const correctedTime = new Date(dateNow + timeOffsetMillis);
const accessExpirationDate = accessExpiration ? new Date(accessExpiration.expirationDate) : null;
const pastExpirationDeadline = accessExpiration ? new Date(dateNow) > accessExpirationDate : false;
if (!verifiedMode) {
return null;
}
const eventProperties = {
org_key: org,
courserun_key: courseId,
@@ -316,8 +306,13 @@ function UpgradeNotification({
useEffect(() => {
sendTrackingLogEvent('edx.bi.course.upgrade.sidebarupsell.displayed', eventProperties);
sendTrackEvent('Promotion Viewed', promotionEventProperties);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
if (!verifiedMode) {
return null;
}
const logClick = () => {
sendTrackingLogEvent('edx.bi.course.upgrade.sidebarupsell.clicked', eventProperties);
sendTrackingLogEvent('edx.course.enrollment.upgrade.clicked', {
@@ -502,7 +497,7 @@ function UpgradeNotification({
</div>
</section>
);
}
};
UpgradeNotification.propTypes = {
courseId: PropTypes.string.isRequired,

View File

@@ -4,14 +4,12 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { FormattedMessage } from '@edx/frontend-platform/i18n';
import { getConfig } from '@edx/frontend-platform';
function CheckmarkBullet() {
return (
<span className="fa-li"><FontAwesomeIcon icon={faCheck} /></span>
);
}
const CheckmarkBullet = () => (
<span className="fa-li"><FontAwesomeIcon icon={faCheck} /></span>
);
// Must be child of a <ul className="fa-ul">
export function VerifiedCertBullet() {
export const VerifiedCertBullet = () => {
const verifiedCertLink = (
<a className="inline-link-underline font-weight-bold" rel="noopener noreferrer" target="_blank" href={`${getConfig().MARKETING_SITE_BASE_URL}/verified-certificate`}>
<FormattedMessage
@@ -32,10 +30,10 @@ export function VerifiedCertBullet() {
/>
</li>
);
}
};
// Must be child of a <ul className="fa-ul">
export function UnlockGradedBullet() {
export const UnlockGradedBullet = () => {
const gradedAssignmentsInBoldText = (
<span className="font-weight-bold">
<FormattedMessage
@@ -56,10 +54,10 @@ export function UnlockGradedBullet() {
/>
</li>
);
}
};
// Must be child of a <ul className="fa-ul">
export function FullAccessBullet() {
export const FullAccessBullet = () => {
const fullAccessInBoldText = (
<span className="font-weight-bold">
<FormattedMessage
@@ -80,10 +78,10 @@ export function FullAccessBullet() {
/>
</li>
);
}
};
// Must be child of a <ul className="fa-ul">
export function SupportMissionBullet() {
export const SupportMissionBullet = () => {
const missionInBoldText = (
<span className="font-weight-bold">
<FormattedMessage
@@ -104,4 +102,4 @@ export function SupportMissionBullet() {
/>
</li>
);
}
};

View File

@@ -29,22 +29,20 @@ function getAlertIcon(type) {
}
}
function Alert({
const Alert = ({
type, dismissible, children, onDismiss, stacked,
}) {
return (
<ParagonAlert
data-testid={`alert-container-${type}`}
variant={getAlertVariant(type)}
icon={getAlertIcon(type)}
dismissible={dismissible}
onClose={onDismiss}
stacked={stacked}
>
{children}
</ParagonAlert>
);
}
}) => (
<ParagonAlert
data-testid={`alert-container-${type}`}
variant={getAlertVariant(type)}
icon={getAlertIcon(type)}
dismissible={dismissible}
onClose={onDismiss}
stacked={stacked}
>
{children}
</ParagonAlert>
);
Alert.propTypes = {
type: PropTypes.oneOf([

View File

@@ -4,9 +4,9 @@ import PropTypes from 'prop-types';
import UserMessagesContext from './UserMessagesContext';
import Alert from './Alert';
export default function AlertList({
const AlertList = ({
topic, className, customAlerts, customProps,
}) {
}) => {
const { remove, messages } = useContext(UserMessagesContext);
const getAlertComponent = useCallback(
(code) => (customAlerts[code] !== undefined ? customAlerts[code] : Alert),
@@ -38,7 +38,7 @@ export default function AlertList({
})}
</div>
);
}
};
AlertList.propTypes = {
className: PropTypes.string,
@@ -60,3 +60,5 @@ AlertList.defaultProps = {
customAlerts: {},
customProps: {},
};
export default AlertList;

View File

@@ -1,4 +1,6 @@
import React, { useState, useRef, useEffect } from 'react';
import React, {
useState, useRef, useEffect, useMemo,
} from 'react';
import PropTypes from 'prop-types';
import UserMessagesContext from './UserMessagesContext';
@@ -27,7 +29,7 @@ function popFlashMessages() {
return popLocalStorage(FLASH_MESSAGES_LOCAL_STORAGE_KEY) || [];
}
export default function UserMessagesProvider({ children }) {
const UserMessagesProvider = ({ children }) => {
// Note: The callbacks (add, remove, clear) below interact with useState in very subtle ways.
// When we call setMessages, we always do so with the function-based form of the handler, making
// use of the "current" state and not relying on lexical scoping to access the state exposed
@@ -81,20 +83,20 @@ export default function UserMessagesProvider({ children }) {
flashMessages.forEach(flashMessage => add(flashMessage));
}, []);
const value = {
const value = useMemo(() => ({
add,
addFlash,
remove,
clear,
messages,
};
}), [messages]);
return (
<UserMessagesContext.Provider value={value}>
{children}
</UserMessagesContext.Provider>
);
}
};
UserMessagesProvider.propTypes = {
children: PropTypes.node,
@@ -103,3 +105,5 @@ UserMessagesProvider.propTypes = {
UserMessagesProvider.defaultProps = {
children: null,
};
export default UserMessagesProvider;

View File

@@ -31,5 +31,6 @@ export function useAlert(isVisible, {
return () => {
remove(cleanupId);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isVisible, code, text, topic, type, payload, dismissible]);
}