diff --git a/.eslintrc.js b/.eslintrc.js index 51d0db6..ff21a0c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -7,20 +7,28 @@ const config = createConfig('eslint', { 'import/no-named-as-default-member': 'off', 'import/no-import-module-exports': 'off', 'import/no-self-import': 'off', - 'spaced-comment': ['error', 'always', { 'block': { 'exceptions': ['*'] } }], + 'spaced-comment': ['error', 'always', { block: { exceptions: ['*'] } }], 'react-hooks/rules-of-hooks': 'off', - "react/forbid-prop-types": ["error", { "forbid": ["any", "array"] }], // arguable object proptype is use when I do not care about the shape of the object + 'react/forbid-prop-types': ['error', { forbid: ['any', 'array'] }], // arguable object proptype is use when I do not care about the shape of the object 'no-import-assign': 'off', 'no-promise-executor-return': 'off', 'import/no-cycle': 'off', }, + overrides: [ + { + files: ['**/*.test.{js,jsx,ts,tsx}'], + rules: { + 'react/prop-types': 'off', + }, + }, + ], }); config.settings = { - "import/resolver": { + 'import/resolver': { node: { - paths: ["src", "node_modules"], - extensions: [".js", ".jsx"], + paths: ['src', 'node_modules'], + extensions: ['.js', '.jsx'], }, }, }; diff --git a/src/App.test.jsx b/src/App.test.jsx index aa86ae4..f1bf077 100644 --- a/src/App.test.jsx +++ b/src/App.test.jsx @@ -1,5 +1,6 @@ import { screen } from '@testing-library/react'; import { selectors } from 'data/redux'; + import { renderWithIntl } from './testUtils'; import { App, mapStateToProps } from './App'; @@ -22,6 +23,14 @@ jest.mock('containers/DemoWarning', () => function DemoWarning() { return
Demo Warning
; }); +jest.mock('@edx/frontend-component-header', () => ({ + LearningHeader: ({ courseTitle, courseNumber, courseOrg }) => ( +
+ Header - {courseTitle} {courseNumber} {courseOrg} +
+ ), +})); + jest.mock('data/redux', () => ({ selectors: { app: { @@ -53,7 +62,7 @@ describe('App component', () => { renderWithIntl(); const org = screen.getByText((text) => text.includes('test-org')); expect(org).toBeInTheDocument(); - const title = screen.getByText('Test Course'); + const title = screen.getByText((content) => content.includes('Test Course')); expect(title).toBeInTheDocument(); }); diff --git a/src/components/ConfirmModal.test.jsx b/src/components/ConfirmModal.test.jsx index 03e6cd3..3c0fc99 100644 --- a/src/components/ConfirmModal.test.jsx +++ b/src/components/ConfirmModal.test.jsx @@ -1,5 +1,6 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import { ConfirmModal } from './ConfirmModal'; describe('ConfirmModal', () => { @@ -18,24 +19,40 @@ describe('ConfirmModal', () => { }); it('should not render content when modal is closed', () => { - render(); + render( + + + , + ); expect(screen.queryByText(props.content)).toBeNull(); }); it('should display content when modal is open', () => { - render(); + render( + + + , + ); expect(screen.getByText(props.content)).toBeInTheDocument(); }); it('should call onCancel when cancel button is clicked', async () => { - render(); + render( + + + , + ); const user = userEvent.setup(); await user.click(screen.getByText(props.cancelText)); expect(props.onCancel).toHaveBeenCalledTimes(1); }); it('should call onConfirm when confirm button is clicked', async () => { - render(); + render( + + + , + ); const user = userEvent.setup(); await user.click(screen.getByText(props.confirmText)); expect(props.onConfirm).toHaveBeenCalledTimes(1); diff --git a/src/components/InfoPopover/index.jsx b/src/components/InfoPopover/index.jsx index 5ba81b7..59e5f5e 100644 --- a/src/components/InfoPopover/index.jsx +++ b/src/components/InfoPopover/index.jsx @@ -27,7 +27,7 @@ export const InfoPopover = ( return ( diff --git a/src/containers/ListView/ListView.scss b/src/containers/ListView/ListView.scss index 58b029d..1c286f4 100644 --- a/src/containers/ListView/ListView.scss +++ b/src/containers/ListView/ListView.scss @@ -23,4 +23,14 @@ span.pgn__icon.breadcrumb-arrow { margin-bottom: 0; } } + + @media (--pgn-size-breakpoint-max-width-xs) { + .badge { + white-space: normal; + } + + .pgn__table-actions > div:first-of-type { + z-index: var(--pgn-elevation-modal-zindex) !important; + } + } } diff --git a/src/containers/ReviewActions/ReviewActions.scss b/src/containers/ReviewActions/ReviewActions.scss index e368eba..32e82ca 100644 --- a/src/containers/ReviewActions/ReviewActions.scss +++ b/src/containers/ReviewActions/ReviewActions.scss @@ -33,3 +33,10 @@ padding-bottom:var(--pgn-spacing-spacer-3); } } + + +@media (--pgn-size-breakpoint-max-width-xs) { + .overlay-help-popover { + max-width: calc(100% - 60px) !important; + } +} diff --git a/src/containers/ReviewActions/index.jsx b/src/containers/ReviewActions/index.jsx index 3383972..3633894 100644 --- a/src/containers/ReviewActions/index.jsx +++ b/src/containers/ReviewActions/index.jsx @@ -30,7 +30,7 @@ export const ReviewActions = ({ { gradingStatus && ( )} - + {pointsPossible && ( { isOpen, closeConfirmModalProps, } = hooks.rendererHooks({ dispatch, intl }); + + const isMobile = useMediaQuery({ query: '(max-width: 768px)' }); + return ( {title} : title} isOpen={isOpen} beforeBodyNode={( <>