Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useDispatch, useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import { useNavigate } from 'react-router-dom';
import { Button } from '@openedx/paragon';
import { Button, ButtonGroup } from '@openedx/paragon';
import { Plus as PlusIcon, ContentPasteGo as ContentPasteGoIcon } from '@openedx/paragon/icons';
import { useIntl } from '@edx/frontend-platform/i18n';

Expand Down Expand Up @@ -49,7 +49,7 @@ const SequenceNavigationTabs = ({
return (
<div className="sequence-navigation-tabs-wrapper">
<div className="sequence-navigation-tabs-container d-flex" ref={containerRef}>
<div
<ButtonGroup
className="sequence-navigation-tabs d-flex flex-grow-1"
style={shouldDisplayDropdown ? invisibleStyle : null}
>
Expand Down Expand Up @@ -80,7 +80,7 @@ const SequenceNavigationTabs = ({
{intl.formatMessage(messages.pasteAsNewUnitLink)}
</Button>
)}
</div>
</ButtonGroup>
</div>
{shouldDisplayDropdown && (
<SequenceNavigationDropdown
Expand Down
6 changes: 2 additions & 4 deletions src/editors/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React from 'react';
import { useDispatch } from 'react-redux';

import * as hooks from './hooks';
import { useEditorContext } from './EditorContext';

import supportedEditors from './supportedEditors';
import type { EditorComponent } from './EditorComponent';
Expand All @@ -13,20 +14,17 @@ export interface Props extends EditorComponent {
blockType: string;
blockId: string | null;
learningContextId: string | null;
lmsEndpointUrl: string | null;
studioEndpointUrl: string | null;
}

const Editor: React.FC<Props> = ({
learningContextId,
blockType,
blockId,
lmsEndpointUrl,
studioEndpointUrl,
onClose = null,
returnFunction = null,
}) => {
const dispatch = useDispatch();
const { lmsEndpointUrl, studioEndpointUrl } = useEditorContext();
const loading = hooks.useInitializeApp({
dispatch,
data: {
Expand Down
12 changes: 12 additions & 0 deletions src/editors/EditorContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@ export interface EditorContext {
learningContextId: string;
/** Is the so-called "Markdown" problem editor available in this learning context? */
isMarkdownEditorEnabledForContext: boolean;
/** e.g. "http://studio.local.openedx.io:8001" */
studioEndpointUrl?: string | null;
/** e.g. "http://local.openedx.io:8000" */
lmsEndpointUrl?: string | null;
}

export type EditorContextInit = {
learningContextId: string;
studioEndpointUrl?: string | null;
lmsEndpointUrl?: string | null;
};

const context = React.createContext<EditorContext | undefined>(undefined);
Expand All @@ -36,17 +42,23 @@ export function useEditorContext() {
export const EditorContextProvider: React.FC<{ children: React.ReactNode; } & EditorContextInit> = ({
children,
learningContextId,
studioEndpointUrl,
lmsEndpointUrl,
}) => {
const courseIdIfCourse = isCourseKey(learningContextId) ? learningContextId : undefined;
const isMarkdownEditorEnabledForContext = useWaffleFlags(courseIdIfCourse).useReactMarkdownEditor;

const ctx: EditorContext = React.useMemo(() => ({
learningContextId,
isMarkdownEditorEnabledForContext,
studioEndpointUrl,
lmsEndpointUrl,
}), [
// Dependencies - make sure we update the context object if any of these values change:
learningContextId,
isMarkdownEditorEnabledForContext,
studioEndpointUrl,
lmsEndpointUrl,
]);
return <context.Provider value={ctx}>{children}</context.Provider>;
};
8 changes: 5 additions & 3 deletions src/editors/EditorPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,17 @@ const EditorPage: React.FC<Props> = ({
studioEndpointUrl,
}}
>
<EditorContextProvider learningContextId={courseId}>
<EditorContextProvider
learningContextId={courseId}
studioEndpointUrl={studioEndpointUrl}
lmsEndpointUrl={lmsEndpointUrl}
>
<Editor
{...{
onClose,
learningContextId: courseId,
blockType,
blockId,
lmsEndpointUrl,
studioEndpointUrl,
returnFunction,
}}
/>
Expand Down
29 changes: 29 additions & 0 deletions src/editors/PluggableEditors.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import supportedEditors, { registerEditor } from './supportedEditors';

describe('Pluggable Editors', () => {
it('should allow registering a new editor', () => {
const MockEditor = () => <div>Mock Editor</div>;
const newBlockType = 'test-block-type';

expect(supportedEditors[newBlockType]).toBeUndefined();

registerEditor(newBlockType, MockEditor);

expect(supportedEditors[newBlockType]).toBe(MockEditor);
});

it('should allow overwriting an existing editor', () => {
const MockEditor = () => <div>New Mock Editor</div>;
const existingBlockType = 'html'; // Assuming 'html' exists

const originalEditor = supportedEditors[existingBlockType];
expect(originalEditor).toBeDefined();

registerEditor(existingBlockType, MockEditor);

expect(supportedEditors[existingBlockType]).toBe(MockEditor);

// Restore original editor for other tests
registerEditor(existingBlockType, originalEditor);
});
});
8 changes: 6 additions & 2 deletions src/editors/supportedEditors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ import GameEditor from './containers/GameEditor';

import { blockTypes } from './data/constants/app';

const supportedEditors = {
const supportedEditors: Record<string, any> = {
[blockTypes.html]: TextEditor,
[blockTypes.video]: VideoEditor,
[blockTypes.problem]: ProblemEditor,
[blockTypes.video_upload]: VideoUploadEditor,
// ADDED_EDITORS GO BELOW
[blockTypes.game]: GameEditor,
} as const;
};

export const registerEditor = (blockType: string, editorComponent: any) => {
supportedEditors[blockType] = editorComponent;
};

export default supportedEditors;