From 82b0f67f1119bae377f7180d3ca7dc79d0c4a954 Mon Sep 17 00:00:00 2001 From: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com> Date: Thu, 8 Jun 2023 13:32:53 -0400 Subject: [PATCH] feat: add returnUrl prop to editors (#341) --- src/editors/Editor.jsx | 5 ++++- src/editors/EditorPage.jsx | 4 ++++ src/editors/__snapshots__/Editor.test.jsx.snap | 1 + src/editors/__snapshots__/EditorPage.test.jsx.snap | 2 ++ .../__snapshots__/index.test.jsx.snap | 4 ++++ src/editors/containers/EditorContainer/hooks.js | 11 +++++++++-- src/editors/containers/EditorContainer/index.jsx | 12 ++++++++++-- .../containers/EditorContainer/index.test.jsx | 2 ++ .../__snapshots__/index.test.jsx.snap | 2 ++ .../components/EditProblemView/index.jsx | 5 +++++ src/editors/containers/ProblemEditor/index.jsx | 7 +++++-- .../TextEditor/__snapshots__/index.test.jsx.snap | 4 ++++ src/editors/containers/TextEditor/index.jsx | 4 ++++ .../VideoEditor/__snapshots__/index.test.jsx.snap | 2 ++ src/editors/containers/VideoEditor/index.jsx | 4 ++++ src/editors/hooks.js | 7 +++++++ src/editors/hooks.test.jsx | 10 ++++++++++ 17 files changed, 79 insertions(+), 7 deletions(-) diff --git a/src/editors/Editor.jsx b/src/editors/Editor.jsx index 6668e5eb3..d1b14cb38 100644 --- a/src/editors/Editor.jsx +++ b/src/editors/Editor.jsx @@ -15,6 +15,7 @@ export const Editor = ({ lmsEndpointUrl, studioEndpointUrl, onClose, + returnFunction, }) => { const dispatch = useDispatch(); hooks.initializeApp({ @@ -37,7 +38,7 @@ export const Editor = ({ aria-label={blockType} > {(EditorComponent !== undefined) - ? + ? : } @@ -48,6 +49,7 @@ Editor.defaultProps = { learningContextId: null, lmsEndpointUrl: null, onClose: null, + returnFunction: null, studioEndpointUrl: null, }; @@ -57,6 +59,7 @@ Editor.propTypes = { learningContextId: PropTypes.string, lmsEndpointUrl: PropTypes.string, onClose: PropTypes.func, + returnFunction: PropTypes.func, studioEndpointUrl: PropTypes.string, }; diff --git a/src/editors/EditorPage.jsx b/src/editors/EditorPage.jsx index 098e404ba..2b717d411 100644 --- a/src/editors/EditorPage.jsx +++ b/src/editors/EditorPage.jsx @@ -13,6 +13,7 @@ export const EditorPage = ({ lmsEndpointUrl, studioEndpointUrl, onClose, + returnFunction, }) => ( @@ -39,6 +41,7 @@ EditorPage.defaultProps = { courseId: null, lmsEndpointUrl: null, onClose: null, + returnFunction: null, studioEndpointUrl: null, }; @@ -48,6 +51,7 @@ EditorPage.propTypes = { courseId: PropTypes.string, lmsEndpointUrl: PropTypes.string, onClose: PropTypes.func, + returnFunction: PropTypes.func, studioEndpointUrl: PropTypes.string, }; diff --git a/src/editors/__snapshots__/Editor.test.jsx.snap b/src/editors/__snapshots__/Editor.test.jsx.snap index de3f18a95..8c929ec63 100644 --- a/src/editors/__snapshots__/Editor.test.jsx.snap +++ b/src/editors/__snapshots__/Editor.test.jsx.snap @@ -29,6 +29,7 @@ exports[`Editor render snapshot: renders correct editor given blockType (html -> > diff --git a/src/editors/__snapshots__/EditorPage.test.jsx.snap b/src/editors/__snapshots__/EditorPage.test.jsx.snap index 49bcd6fd2..c5b2a5995 100644 --- a/src/editors/__snapshots__/EditorPage.test.jsx.snap +++ b/src/editors/__snapshots__/EditorPage.test.jsx.snap @@ -22,6 +22,7 @@ exports[`Editor Page snapshots props besides blockType default to null 1`] = ` learningContextId={null} lmsEndpointUrl={null} onClose={null} + returnFunction={null} studioEndpointUrl={null} /> @@ -50,6 +51,7 @@ exports[`Editor Page snapshots rendering correctly with expected Input 1`] = ` learningContextId="course-v1:edX+DemoX+Demo_Course" lmsEndpointUrl="evenfakerurl.com" onClose={[MockFunction props.onClose]} + returnFunction={null} studioEndpointUrl="fakeurl.com" /> diff --git a/src/editors/containers/EditorContainer/__snapshots__/index.test.jsx.snap b/src/editors/containers/EditorContainer/__snapshots__/index.test.jsx.snap index 59752ed01..8991786da 100644 --- a/src/editors/containers/EditorContainer/__snapshots__/index.test.jsx.snap +++ b/src/editors/containers/EditorContainer/__snapshots__/index.test.jsx.snap @@ -13,6 +13,7 @@ exports[`EditorContainer component render snapshot: initialized. enable save and Object { "handleCancel": Object { "onClose": [MockFunction props.onClose], + "returnFunction": [MockFunction props.returnFunction], }, } } @@ -73,6 +74,7 @@ exports[`EditorContainer component render snapshot: initialized. enable save and "handleSaveClicked": Object { "dispatch": [MockFunction react-redux.dispatch], "getContent": [MockFunction props.getContent], + "returnFunction": [MockFunction props.returnFunction], "validateEntry": [MockFunction props.validateEntry], }, } @@ -94,6 +96,7 @@ exports[`EditorContainer component render snapshot: not initialized. disable sav Object { "handleCancel": Object { "onClose": [MockFunction props.onClose], + "returnFunction": [MockFunction props.returnFunction], }, } } @@ -150,6 +153,7 @@ exports[`EditorContainer component render snapshot: not initialized. disable sav "handleSaveClicked": Object { "dispatch": [MockFunction react-redux.dispatch], "getContent": [MockFunction props.getContent], + "returnFunction": [MockFunction props.returnFunction], "validateEntry": [MockFunction props.validateEntry], }, } diff --git a/src/editors/containers/EditorContainer/hooks.js b/src/editors/containers/EditorContainer/hooks.js index ce378ea6d..f31e2bbbb 100644 --- a/src/editors/containers/EditorContainer/hooks.js +++ b/src/editors/containers/EditorContainer/hooks.js @@ -19,7 +19,12 @@ export const state = StrictDict({ isCancelConfirmModalOpen: (val) => useState(val), }); -export const handleSaveClicked = ({ dispatch, getContent, validateEntry }) => { +export const handleSaveClicked = ({ + dispatch, + getContent, + validateEntry, + returnFunction, +}) => { const destination = useSelector(selectors.app.returnUrl); const analytics = useSelector(selectors.app.analytics); @@ -28,6 +33,7 @@ export const handleSaveClicked = ({ dispatch, getContent, validateEntry }) => { content: getContent({ dispatch }), destination, dispatch, + returnFunction, validateEntry, }); }; @@ -41,11 +47,12 @@ export const cancelConfirmModalToggle = () => { }; }; -export const handleCancel = ({ onClose }) => { +export const handleCancel = ({ onClose, returnFunction }) => { if (onClose) { return onClose; } return navigateCallback({ + returnFunction, destination: useSelector(selectors.app.returnUrl), analyticsEvent: analyticsEvt.editorCancelClick, analytics: useSelector(selectors.app.analytics), diff --git a/src/editors/containers/EditorContainer/index.jsx b/src/editors/containers/EditorContainer/index.jsx index f085e7ad6..b114137cb 100644 --- a/src/editors/containers/EditorContainer/index.jsx +++ b/src/editors/containers/EditorContainer/index.jsx @@ -19,13 +19,14 @@ export const EditorContainer = ({ getContent, onClose, validateEntry, + returnFunction, // injected intl, }) => { const dispatch = useDispatch(); const isInitialized = hooks.isInitialized(); const { isCancelConfirmOpen, openCancelConfirmModal, closeCancelConfirmModal } = hooks.cancelConfirmModalToggle(); - const handleCancel = hooks.handleCancel({ onClose }); + const handleCancel = hooks.handleCancel({ onClose, returnFunction }); return (
@@ -73,12 +79,14 @@ export const EditorContainer = ({ }; EditorContainer.defaultProps = { onClose: null, + returnFunction: null, validateEntry: null, }; EditorContainer.propTypes = { children: PropTypes.node.isRequired, getContent: PropTypes.func.isRequired, onClose: PropTypes.func, + returnFunction: PropTypes.func, validateEntry: PropTypes.func, // injected intl: intlShape.isRequired, diff --git a/src/editors/containers/EditorContainer/index.test.jsx b/src/editors/containers/EditorContainer/index.test.jsx index d4bdbb8da..2ca5f70d1 100644 --- a/src/editors/containers/EditorContainer/index.test.jsx +++ b/src/editors/containers/EditorContainer/index.test.jsx @@ -9,6 +9,7 @@ const props = { getContent: jest.fn().mockName('props.getContent'), onClose: jest.fn().mockName('props.onClose'), validateEntry: jest.fn().mockName('props.validateEntry'), + returnFunction: jest.fn().mockName('props.returnFunction'), // inject intl: { formatMessage }, }; @@ -51,6 +52,7 @@ describe('EditorContainer component', () => { dispatch: useDispatch(), getContent: props.getContent, validateEntry: props.validateEntry, + returnFunction: props.returnFunction, }); expect(el.children().at(3) .props().onSave).toEqual(expected); diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/__snapshots__/index.test.jsx.snap b/src/editors/containers/ProblemEditor/components/EditProblemView/__snapshots__/index.test.jsx.snap index 92c9ce13e..c5759ebc7 100644 --- a/src/editors/containers/ProblemEditor/components/EditProblemView/__snapshots__/index.test.jsx.snap +++ b/src/editors/containers/ProblemEditor/components/EditProblemView/__snapshots__/index.test.jsx.snap @@ -3,6 +3,7 @@ exports[`EditorProblemView component renders raw editor 1`] = ` ); + return (); } - return (); + return (); }; ProblemEditor.defaultProps = { assetsFinished: null, + returnFunction: null, }; ProblemEditor.propTypes = { onClose: PropTypes.func.isRequired, + returnFunction: PropTypes.func, // redux assetsFinished: PropTypes.bool, advancedSettingsFinished: PropTypes.bool.isRequired, diff --git a/src/editors/containers/TextEditor/__snapshots__/index.test.jsx.snap b/src/editors/containers/TextEditor/__snapshots__/index.test.jsx.snap index a7171499c..81166806a 100644 --- a/src/editors/containers/TextEditor/__snapshots__/index.test.jsx.snap +++ b/src/editors/containers/TextEditor/__snapshots__/index.test.jsx.snap @@ -20,6 +20,7 @@ exports[`TextEditor snapshots block failed to load, Toast is shown 1`] = ` } } onClose={[MockFunction props.onClose]} + returnFunction={null} >
@@ -85,9 +87,11 @@ TextEditor.defaultProps = { isRaw: null, assetsFinished: null, assets: null, + returnFunction: null, }; TextEditor.propTypes = { onClose: PropTypes.func.isRequired, + returnFunction: PropTypes.func, // redux blockValue: PropTypes.shape({ data: PropTypes.shape({ data: PropTypes.string }), diff --git a/src/editors/containers/VideoEditor/__snapshots__/index.test.jsx.snap b/src/editors/containers/VideoEditor/__snapshots__/index.test.jsx.snap index beddeae9e..7d75a561a 100644 --- a/src/editors/containers/VideoEditor/__snapshots__/index.test.jsx.snap +++ b/src/editors/containers/VideoEditor/__snapshots__/index.test.jsx.snap @@ -6,6 +6,7 @@ exports[`VideoEditor snapshots renders as expected with default behavior 1`] = ` >
{studioViewFinished ? ( @@ -59,9 +61,11 @@ export const VideoEditor = ({ VideoEditor.defaultProps = { onClose: null, + returnFunction: null, }; VideoEditor.propTypes = { onClose: PropTypes.func, + returnFunction: PropTypes.func, // injected intl: intlShape.isRequired, // redux diff --git a/src/editors/hooks.js b/src/editors/hooks.js index b9c99e617..c9dc77665 100644 --- a/src/editors/hooks.js +++ b/src/editors/hooks.js @@ -17,6 +17,7 @@ export const navigateTo = (destination) => { }; export const navigateCallback = ({ + returnFunction, destination, analyticsEvent, analytics, @@ -24,6 +25,10 @@ export const navigateCallback = ({ if (process.env.NODE_ENV !== 'development' && analyticsEvent && analytics) { sendTrackEvent(analyticsEvent, analytics); } + if (returnFunction) { + returnFunction(); + return; + } module.navigateTo(destination); }; @@ -34,6 +39,7 @@ export const saveBlock = ({ content, destination, dispatch, + returnFunction, validateEntry, }) => { if (!content) { @@ -53,6 +59,7 @@ export const saveBlock = ({ destination, analyticsEvent: analyticsEvt.editorSaveClick, analytics, + returnFunction, }), content, })); diff --git a/src/editors/hooks.test.jsx b/src/editors/hooks.test.jsx index 18e19f096..5fc21b04a 100644 --- a/src/editors/hooks.test.jsx +++ b/src/editors/hooks.test.jsx @@ -74,6 +74,7 @@ describe('hooks', () => { let output; const SAVED_ENV = process.env; const destination = 'hOmE'; + const returnFunction = jest.fn(); beforeEach(() => { jest.resetModules(); process.env = { ...SAVED_ENV }; @@ -100,6 +101,15 @@ describe('hooks', () => { output(); expect(spy).toHaveBeenCalledWith(destination); }); + it('should call returnFunction and return null', () => { + output = hooks.navigateCallback({ + destination, + returnFunction, + }); + const returnedOutput = output(); + expect(returnFunction).toHaveBeenCalled(); + expect(returnedOutput).toEqual(undefined); + }); }); describe('nullMethod', () => {