-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add studio footer for studio mfes
- Loading branch information
Showing
8 changed files
with
1,091 additions
and
217 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
import React, { useContext, useState } from 'react'; | ||
import _ from 'lodash'; | ||
import { intlShape, injectIntl, FormattedMessage } from '@edx/frontend-platform/i18n'; | ||
import { ensureConfig } from '@edx/frontend-platform'; | ||
import { AppContext } from '@edx/frontend-platform/react'; | ||
import { | ||
ActionRow, | ||
Button, | ||
Container, | ||
Hyperlink, | ||
Image, | ||
TransitionReplace, | ||
} from '@edx/paragon'; | ||
import { ExpandLess, ExpandMore, Help } from '@edx/paragon/icons'; | ||
import messages from './messages'; | ||
|
||
ensureConfig([ | ||
'LMS_BASE_URL', | ||
'MARKETING_SITE_BASE_URL', | ||
'TERMS_OF_SERVICE_URL', | ||
'PRIVACY_POLICY_URL', | ||
'SUPPORT_EMAIL', | ||
'SITE_NAME', | ||
'STUDIO_BASE_URL', | ||
'SHOW_ACCESSIBILITY_PAGE', | ||
], 'Studio Footer component'); | ||
|
||
const StudioFooter = ({ | ||
// injected | ||
intl, | ||
}) => { | ||
const [isOpen, setIsOpen] = useState(false); | ||
const { config } = useContext(AppContext); | ||
|
||
return ( | ||
<> | ||
<div className="m-0 mt-6 row align-items-center justify-content-center"> | ||
<div className="col border-top mr-2" /> | ||
<Button | ||
data-testid="helpToggleButton" | ||
variant="outline-primary" | ||
onClick={() => setIsOpen(!isOpen)} | ||
iconBefore={Help} | ||
iconAfter={isOpen ? ExpandLess : ExpandMore} | ||
size="sm" | ||
> | ||
{isOpen ? intl.formatMessage(messages.closeHelpButtonLabel) | ||
: intl.formatMessage(messages.openHelpButtonLabel)} | ||
</Button> | ||
<div className="col border-top ml-2" /> | ||
</div> | ||
<Container size="xl" className="px-4"> | ||
<TransitionReplace> | ||
{isOpen ? ( | ||
<ActionRow key="help-link-button-row" className="py-4" data-testid="helpButtonRow"> | ||
<ActionRow.Spacer /> | ||
<Button as="a" href="https://docs.edx.org/" size="sm"> | ||
<FormattedMessage {...messages.edxDocumentationButtonLabel} /> | ||
</Button> | ||
<Button | ||
as="a" | ||
href="https://open.edx.org/" | ||
size="sm" | ||
data-testid="openEdXPortalButton" | ||
> | ||
<FormattedMessage {...messages.openEdxPortalButtonLabel} /> | ||
</Button> | ||
<Button | ||
as="a" | ||
href="https://www.edx.org/course/edx101-overview-of-creating-an-edx-course#.VO4eaLPF-n1" | ||
size="sm" | ||
> | ||
<FormattedMessage {...messages.edx101ButtonLabel} /> | ||
</Button> | ||
<Button | ||
as="a" | ||
href="https://www.edx.org/course/studiox-creating-a-course-with-edx-studio" | ||
size="sm" | ||
> | ||
<FormattedMessage {...messages.studioXButtonLabel} /> | ||
</Button> | ||
{!_.isEmpty(config.SUPPORT_EMAIL) && ( | ||
<Button | ||
as="a" | ||
href={`mailto:${config.SUPPORT_EMAIL}`} | ||
size="sm" | ||
data-testid="contactUsButton" | ||
> | ||
<FormattedMessage {...messages.contactUsButtonLabel} /> | ||
</Button> | ||
)} | ||
<ActionRow.Spacer /> | ||
</ActionRow> | ||
) : null} | ||
</TransitionReplace> | ||
<ActionRow className="pt-3 m-0 x-small"> | ||
© {new Date().getFullYear()} <Hyperlink destination={config.MARKETING_BASE_URL} target="_blank" className="ml-2">{config.SITE_NAME}</Hyperlink> | ||
<ActionRow.Spacer /> | ||
{!_.isEmpty(config.TERMS_OF_SERVICE_URL) && ( | ||
<Hyperlink destination={config.TERMS_OF_SERVICE_URL} data-testid="termsOfService"> | ||
{intl.formatMessage(messages.termsOfServiceLinkLabel)} | ||
</Hyperlink> | ||
)}{!_.isEmpty(config.PRIVACY_POLICY_URL) && ( | ||
<Hyperlink destination={config.PRIVACY_POLICY_URL} data-testid="privacyPolicy"> | ||
{intl.formatMessage(messages.privacyPolicyLinkLabel)} | ||
</Hyperlink> | ||
)} | ||
{config.SHOW_ACCESSIBILITY_PAGE === 'true' && ( | ||
<Hyperlink | ||
destination={`${config.STUDIO_BASE_URL}/accessibility`} | ||
data-testid="accessibilityRequest" | ||
> | ||
{intl.formatMessage(messages.accessibilityRequestLinkLabel)} | ||
</Hyperlink> | ||
)} | ||
<Hyperlink destination={config.LMS_BASE_URL}>LMS</Hyperlink> | ||
</ActionRow> | ||
<ActionRow className="mt-3 pb-4 x-small"> | ||
{/* | ||
Site operators: Please do not remove this paragraph! this attributes back to edX and | ||
makes your acknowledgement of edX's trademarks clear. | ||
Translators: 'edX' and 'Open edX' are trademarks of 'edX Inc.'. Please do not translate | ||
any of these trademarks and company names. | ||
*/} | ||
<FormattedMessage {...messages.trademarkMessage} /> | ||
<Hyperlink className="ml-1" destination="https://www.edx.org">edX Inc</Hyperlink>. | ||
<ActionRow.Spacer /> | ||
<Hyperlink destination="https://open.edx.org" className="float-right"> | ||
<Image | ||
width="120px" | ||
alt="Powered by Open edX" | ||
src="https://logos.openedx.org/open-edx-logo-tag.png" | ||
/> | ||
</Hyperlink> | ||
</ActionRow> | ||
</Container> | ||
</> | ||
); | ||
}; | ||
|
||
StudioFooter.propTypes = { | ||
// injected | ||
intl: intlShape.isRequired, | ||
}; | ||
|
||
export default injectIntl(StudioFooter); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
/* eslint-disable react/prop-types */ | ||
import React, { useMemo } from 'react'; | ||
import { fireEvent, render, screen } from '@testing-library/react'; | ||
import '@testing-library/jest-dom/extend-expect'; | ||
import { IntlProvider } from '@edx/frontend-platform/i18n'; | ||
import { AppContext } from '@edx/frontend-platform/react'; | ||
import StudioFooter from './StudioFooter'; | ||
import messages from './messages'; | ||
|
||
const config = { | ||
LMS_BASE_URL: process.env.LMS_BASE_URL, | ||
MARKETING_SITE_BASE_URL: process.env.MARKETING_SITE_BASE_URL, | ||
TERMS_OF_SERVICE_URL: process.env.TERMS_OF_SERVICE_URL, | ||
PRIVACY_POLICY_URL: process.env.PRIVACY_POLICY_URL, | ||
SUPPORT_EMAIL: process.env.SUPPORT_EMAIL, | ||
SITE_NAME: process.env.SITE_NAME, | ||
STUDIO_BASE_URL: process.env.STUDIO_BASE_URL, | ||
SHOW_ACCESSIBILITY_PAGE: process.env.SHOW_ACCESSIBILITY_PAGE, | ||
}; | ||
|
||
let currentConfig = config; | ||
const Component = ({ updateVariable }) => { | ||
if (updateVariable) { | ||
const [variable, value] = updateVariable; | ||
currentConfig = { | ||
...config, | ||
[variable]: value, | ||
}; | ||
} | ||
const contextValue = useMemo(() => ({ | ||
authenticatedUser: null, | ||
config: currentConfig, | ||
}), []); | ||
|
||
return ( | ||
<IntlProvider locale="en"> | ||
<AppContext.Provider value={contextValue}> | ||
<StudioFooter /> | ||
</AppContext.Provider> | ||
</IntlProvider> | ||
); | ||
}; | ||
|
||
jest.unmock('@edx/paragon'); | ||
|
||
describe('Footer', () => { | ||
describe('help section default view', () => { | ||
it('help button should read Looking for help with Studio?', () => { | ||
render(<Component />); | ||
expect(screen.getByText(messages.openHelpButtonLabel.defaultMessage)) | ||
.toBeVisible(); | ||
}); | ||
it('help button link row should not be visible', () => { | ||
render(<Component />); | ||
expect(screen.queryByTestId('helpButtonRow')).toBeNull(); | ||
}); | ||
}); | ||
describe('help section expanded view', () => { | ||
it('help button should read Hide Studio help', () => { | ||
render(<Component />); | ||
const helpToggleButton = screen.getByText(messages.openHelpButtonLabel.defaultMessage); | ||
fireEvent.click(helpToggleButton); | ||
expect(screen.getByText(messages.closeHelpButtonLabel.defaultMessage)) | ||
.toBeVisible(); | ||
}); | ||
it('help button link row should be visible', () => { | ||
render(<Component />); | ||
const helpToggleButton = screen.getByText(messages.openHelpButtonLabel.defaultMessage); | ||
fireEvent.click(helpToggleButton); | ||
expect(screen.getByTestId('helpButtonRow')).toBeVisible(); | ||
}); | ||
it('Open edX portal button should be visible', () => { | ||
render(<Component />); | ||
const helpToggleButton = screen.getByText(messages.openHelpButtonLabel.defaultMessage); | ||
fireEvent.click(helpToggleButton); | ||
expect(screen.getByTestId('openEdXPortalButton')).toBeVisible(); | ||
}); | ||
it('should not show contact us button', () => { | ||
render(<Component />); | ||
const helpToggleButton = screen.getByText(messages.openHelpButtonLabel.defaultMessage); | ||
fireEvent.click(helpToggleButton); | ||
expect(screen.queryByTestId('contactUsButton')).toBeNull(); | ||
}); | ||
it('should show contact us button', () => { | ||
render(<Component updateVariable={['SUPPORT_EMAIL', '[email protected]']} />); | ||
const helpToggleButton = screen.getByText(messages.openHelpButtonLabel.defaultMessage); | ||
fireEvent.click(helpToggleButton); | ||
expect(screen.getByTestId('contactUsButton')).toBeVisible(); | ||
}); | ||
}); | ||
describe('policy link row', () => { | ||
it('should only show LMS link', () => { | ||
render(<Component />); | ||
expect(screen.getByText('LMS')).toBeVisible(); | ||
expect(screen.queryByTestId('termsOfService')).toBeNull(); | ||
expect(screen.queryByTestId('privacyPolicy')).toBeNull(); | ||
expect(screen.queryByTestId('accessibilityRequest')).toBeNull(); | ||
}); | ||
it('should show terms of service link', () => { | ||
render(<Component updateVariable={['TERMS_OF_SERVICE_URL', 'termsofserviceurl']} />); | ||
expect(screen.getByText('LMS')).toBeVisible(); | ||
expect(screen.queryByTestId('termsOfService')).toBeVisible(); | ||
expect(screen.queryByTestId('privacyPolicy')).toBeNull(); | ||
expect(screen.queryByTestId('accessibilityRequest')).toBeNull(); | ||
}); | ||
it('should show privacy policy link', () => { | ||
render(<Component updateVariable={['PRIVACY_POLICY_URL', 'privacypolicyurl']} />); | ||
expect(screen.getByText('LMS')).toBeVisible(); | ||
expect(screen.queryByTestId('termsOfService')).toBeNull(); | ||
expect(screen.queryByTestId('privacyPolicy')).toBeVisible(); | ||
expect(screen.queryByTestId('accessibilityRequest')).toBeNull(); | ||
}); | ||
it('should show accessibilty request link', () => { | ||
render(<Component updateVariable={['SHOW_ACCESSIBILITY_PAGE', 'true']} />); | ||
expect(screen.getByText('LMS')).toBeVisible(); | ||
expect(screen.queryByTestId('termsOfService')).toBeNull(); | ||
expect(screen.queryByTestId('privacyPolicy')).toBeNull(); | ||
expect(screen.queryByTestId('accessibilityRequest')).toBeVisible(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import StudioFooter from './StudioFooter'; | ||
|
||
export default StudioFooter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { defineMessages } from '@edx/frontend-platform/i18n'; | ||
|
||
const messages = defineMessages({ | ||
openHelpButtonLabel: { | ||
id: 'authoring.footer.help.openHelp.button.label', | ||
defaultMessage: 'Looking for help with Studio?', | ||
description: 'Label for button that opens the collapsed section with help buttons', | ||
}, | ||
closeHelpButtonLabel: { | ||
id: 'authoring.footer.help.closeHelp.button.label', | ||
defaultMessage: 'Hide Studio help', | ||
description: 'Label for button that closes the collapsed section with help buttons', | ||
}, | ||
edxDocumentationButtonLabel: { | ||
id: 'authoring.footer.help.edxDocumentation.button.label', | ||
defaultMessage: 'edX documentation', | ||
description: 'Label for button that links to the edX documentation site', | ||
}, | ||
openEdxPortalButtonLabel: { | ||
id: 'authoring.footer.help.openEdxPortal.button.label', | ||
defaultMessage: 'Open edX portal', | ||
description: 'Label for button that links to the Open edX portal', | ||
}, | ||
edx101ButtonLabel: { | ||
id: 'authoring.footer.help.edx101.button.label', | ||
defaultMessage: 'Enroll in edX 101', | ||
description: 'Label for button that links to the edX 101 course', | ||
}, | ||
studioXButtonLabel: { | ||
id: 'authoring.footer.help.studioX.button.label', | ||
defaultMessage: 'Enroll in StudioX', | ||
description: 'Label for button that links to the edX StudioX course', | ||
}, | ||
contactUsButtonLabel: { | ||
id: 'authoring.footer.help.contactUs.button.label', | ||
defaultMessage: 'Contact us', | ||
description: 'Label for button that links to the email for partner support', | ||
}, | ||
termsOfServiceLinkLabel: { | ||
id: 'authoring.footer.termsOfService.link.label', | ||
defaultMessage: 'Terms of Service', | ||
description: 'Label for button that links to the terms of service page', | ||
}, | ||
privacyPolicyLinkLabel: { | ||
id: 'authoring.footer.privacyPolicy.link.label', | ||
defaultMessage: 'Privacy Policy', | ||
description: 'Label for button that links to the privacy policy page', | ||
}, | ||
accessibilityRequestLinkLabel: { | ||
id: 'authoring.footer.accessibilityRequest.link.label', | ||
defaultMessage: 'Accessibility Accomodation Request', | ||
description: 'Label for button that links to the accessibility accomodation requests page', | ||
}, | ||
trademarkMessage: { | ||
id: 'authoring.footer.trademark.message', | ||
defaultMessage: 'edX and Open edX, and the edX and Open edX logos are registered trademarks of', | ||
description: 'Message about the use of logos and names edX and Open edX', | ||
}, | ||
}); | ||
|
||
export default messages; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
import Footer, { EVENT_NAMES } from './components/Footer'; | ||
import messages from './i18n/index'; | ||
import StudioFooter from './components/studio-footer'; | ||
|
||
export default Footer; | ||
export { messages, EVENT_NAMES }; | ||
export { messages, EVENT_NAMES, StudioFooter }; |