Skip to content

Commit

Permalink
Merge branch 'main' into search-navigation-issues
Browse files Browse the repository at this point in the history
  • Loading branch information
staxly[bot] authored Jul 16, 2024
2 parents f62f7a3 + 7fee251 commit 3e5d481
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 7 deletions.
7 changes: 6 additions & 1 deletion src/app/content/components/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import ErrorBoundary from '../../errors/components/ErrorBoundary';
import Notifications from '../../notifications/components/Notifications';
import theme from '../../theme';
import { AppState } from '../../types';
import { Book } from '../types';
import HighlightsPopUp from '../highlights/components/HighlightsPopUp';
import KeyboardShortcutsPopup from '../keyboardShortcuts/components/KeyboardShortcutsPopup';
import PracticeQuestionsPopup from '../practiceQuestions/components/PracticeQuestionsPopup';
import { mobileToolbarOpen } from '../search/selectors';
import { book as bookSelector } from '../selectors';
import StudyguidesPopUp from '../studyGuides/components/StudyGuidesPopUp';
import Footer from './../../components/Footer';
import Attribution from './Attribution';
Expand All @@ -25,6 +27,7 @@ import {
topbarMobileHeight
} from './constants';
import ContentPane from './ContentPane';
import ContentWarning from './ContentWarning';
import LabsCTA from './LabsCall';
import NudgeStudyTools from './NudgeStudyTools';
import Page from './Page';
Expand Down Expand Up @@ -69,7 +72,7 @@ const OuterWrapper = styled.div`
`;

// tslint:disable-next-line:variable-name
const Content = ({mobileExpanded}: {mobileExpanded: boolean}) => <Layout>
const Content = ({mobileExpanded, book}: {mobileExpanded: boolean; book: Book}) => <Layout>
<ScrollOffset
desktopOffset={
bookBannerDesktopMiniHeight
Expand All @@ -96,6 +99,7 @@ const Content = ({mobileExpanded}: {mobileExpanded: boolean}) => <Layout>
<Navigation />
<ContentPane>
<ContentNotifications mobileExpanded={mobileExpanded} />
<ContentWarning book={book} />
<Page>
<PrevNextBar />
<LabsCTA />
Expand All @@ -113,5 +117,6 @@ const Content = ({mobileExpanded}: {mobileExpanded: boolean}) => <Layout>
export default connect(
(state: AppState) => ({
mobileExpanded: mobileToolbarOpen(state),
book: bookSelector(state),
})
)(Content);
48 changes: 48 additions & 0 deletions src/app/content/components/ContentWarning.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import { renderToDom } from '../../../test/reactutils';
import ContentWarning from './ContentWarning';
import { useServices } from '../../context/Services';
import { OSWebBook } from '../../../gateways/createOSWebLoader';
import { BookWithOSWebData } from '../types';
import { act } from 'react-dom/test-utils';
import TestContainer from '../../../test/TestContainer';
import ReactTestUtils from 'react-dom/test-utils';

const dummyBook = ({
id: 'dummy-id',
} as unknown) as BookWithOSWebData;

const dummyBookInfo = ({
content_warning_text: 'some warning text',
id: 72,
} as unknown) as OSWebBook;

const services = {
osWebLoader: {
getBookFromId: jest.fn(() => Promise.resolve(dummyBookInfo)),
},
};

jest.mock('../../context/Services', () => ({
...jest.requireActual('../../context/Services'),
useServices: jest.fn(),
}));

(useServices as jest.Mock).mockReturnValue(services);

describe('ContentWarning', () => {
it('renders warning modal', async() => {
renderToDom(<TestContainer><ContentWarning book={dummyBook} /></TestContainer>);

expect(services.osWebLoader.getBookFromId).toBeCalledWith(dummyBook.id);

await act(() => new Promise((resolve) => setTimeout(resolve, 1)));

const root = document?.body;
const b = root?.querySelector('button');

expect(b).toBeTruthy();
act(() => ReactTestUtils.Simulate.click(b!));
expect(root?.querySelector('button')).toBeFalsy();
});
});
88 changes: 88 additions & 0 deletions src/app/content/components/ContentWarning.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import React from 'react';
import { useServices } from '../../context/Services';
import { OSWebBook } from '../../../gateways/createOSWebLoader';
import { Book } from '../types';
import { HTMLDivElement } from '@openstax/types/lib.dom';
import styled from 'styled-components/macro';
import Button from '../../components/Button';
import Modal from './Modal';
import theme from '../../theme';
import Cookies from 'js-cookie';
import { useTrapTabNavigation } from '../../reactUtils';

// tslint:disable-next-line
const WarningDiv = styled.div`
display: flex;
flex-direction: column;
gap: 4rem;
justify-content: center;
align-items: center;
font-size: 1.8rem;
padding: 2rem;
min-height: 50vh;
top: 25vh;
z-index: 4;
> div {
max-width: 80rem;
}
`;

function WarningDivWithTrap({
text,
dismiss,
}: {
text: string;
dismiss: () => void;
}) {
const ref = React.useRef<HTMLDivElement>(null);

React.useEffect(() => ref.current?.focus(), []);

useTrapTabNavigation(ref);

return (
<WarningDiv tabIndex='-1' ref={ref}>
<div>{text}</div>
<Button type='button' onClick={dismiss}>
Ok
</Button>
</WarningDiv>
);
}

export default function ContentWarning({ book }: { book: Book }) {
const services = useServices();
const [bookInfo, setBookInfo] = React.useState<OSWebBook | undefined>();
const cookieKey = `content-warning-${bookInfo?.id}`;
const dismiss = React.useCallback(() => {
// This is only called when bookInfo is populated
Cookies.set(cookieKey, 'true', { expires: 28 });
setBookInfo(undefined);
}, [cookieKey]);

React.useEffect(() => {
services.osWebLoader.getBookFromId(book.id).then(setBookInfo);
}, [book, services]);

if (!bookInfo?.content_warning_text || Cookies.get(cookieKey)) {
return null;
}

return (
<Modal
ariaLabel='Content warning'
tabIndex='-1'
scrollLockProps={{
mediumScreensOnly: false,
overlay: true,
zIndex: theme.zIndex.highlightSummaryPopup,
}}
>
<WarningDivWithTrap
text={bookInfo.content_warning_text}
dismiss={dismiss}
/>
</Modal>
);
}
2 changes: 2 additions & 0 deletions src/app/content/hooks/locationChange.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ describe('contentRouteHookBody', () => {
polish_site_link: '',
promote_image: null,
publish_date: '2012-06-21',
content_warning_text: '',
id: 72,
};

beforeEach(() => {
Expand Down
2 changes: 2 additions & 0 deletions src/app/content/utils/seoUtils.spec.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ export const mockOsWebBook: OSWebBook = {
cnx_id: '',
amazon_link: '',
polish_site_link: '',
content_warning_text: '',
id: 72,
};

export const emptyPage = {
Expand Down
7 changes: 4 additions & 3 deletions src/app/reactUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import theme from './theme';
import { assertDefined, assertDocument, assertWindow } from './utils';

export const useDrawFocus = <E extends HTMLElement = HTMLElement>() => {
const ref = React.useRef<E | null>(null);
const ref = React.useRef<E>(null);

React.useEffect(() => {
if (ref && ref.current) {
Expand Down Expand Up @@ -99,10 +99,11 @@ export function createTrapTab(...elements: HTMLElement[]) {
return;
}
const trapTab = createTrapTab(el);
const document = assertDocument();

el.addEventListener('keydown', trapTab, true);
document.body.addEventListener('keydown', trapTab, true);

return () => el.removeEventListener('keydown', trapTab, true);
return () => document.body.removeEventListener('keydown', trapTab, true);
},
[ref, otherDep]
);
Expand Down
4 changes: 4 additions & 0 deletions src/gateways/createOSWebLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export interface OSWebBook {
cnx_id: string;
amazon_link: string;
polish_site_link: string;
content_warning_text: string | null;
id: number;
}

interface OSWebResponse {
Expand All @@ -41,6 +43,8 @@ export const fields = [
'promote_image',
'book_subjects',
'book_categories',
'content_warning_text',
'id',
].join(',');

interface Options {
Expand Down
3 changes: 1 addition & 2 deletions src/setupProxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* this file is shared between webpack-dev-server and the pre-renderer
*/
const url = require('url');
const util = require('util');
const fs = require('fs');
const path = require('path');
const proxy = require('http-proxy-middleware');
Expand Down Expand Up @@ -32,7 +31,7 @@ const { default: createOSWebLoader } = require('./gateways/createOSWebLoader');
const archiveLoader = createArchiveLoader({
archivePrefix: ARCHIVE_URL
});
const osWebLoader = createOSWebLoader(`${ARCHIVE_URL}${REACT_APP_OS_WEB_API_URL}`);
const osWebLoader = createOSWebLoader(`${OS_WEB_URL}${REACT_APP_OS_WEB_API_URL}`);

const archivePaths = [
'/apps/archive',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"cover_color": "blue",
"authors": [{"value": {"name": "Bam Bammerson"}}],
"publish_date": "2012-06-21",
"book_state": "live"
"book_state": "live",
"content_warning_text": "sensitive material is covered",
"id": 72
}
]
}
2 changes: 2 additions & 0 deletions src/test/mocks/osWebLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export const mockCmsBook: OSWebBook = {
},
promote_image: null,
publish_date: '2012-06-21',
content_warning_text: '',
id: 72,
};

export default () => ({
Expand Down

0 comments on commit 3e5d481

Please sign in to comment.