Skip to content

Commit

Permalink
feat: Course unit - Rendering xblocks in iframes (#201)
Browse files Browse the repository at this point in the history
* feat: added xblock render engine

* feat: connected iframe template

* feat: CSS and JS transfering

* feat: show video xblock

* feat: added multiply xblocks

* feat: rendering advanced components

* fix: add solution for request from within the iframe

* feat: iframe height

* refactor: code refactoring

* fix: fixed platform ajax prefix

* refactor: global refactoring

* refactor: show LTI xblock

* refactor: removed old xblock-content

* refactor: code refactoring

* refactor: some refactoring

* refactor: refactoring

* refactor: code refactoring

* refactor: refactoring after review

---------

Co-authored-by: monteri <lansevermore>
  • Loading branch information
PKulkoRaccoonGang authored and monteri committed Apr 1, 2024
1 parent ad17c45 commit 7dacbd5
Show file tree
Hide file tree
Showing 52 changed files with 1,090 additions and 633 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,4 @@ HOTJAR_DEBUG=false
INVITE_STUDENTS_EMAIL_TO=''
AI_TRANSLATIONS_BASE_URL=''
ENABLE_CHECKLIST_QUALITY=''
SECURE_ORIGIN_XBLOCK_BOOTSTRAP_HTML_URL=null
1 change: 1 addition & 0 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ HOTJAR_DEBUG=true
INVITE_STUDENTS_EMAIL_TO="[email protected]"
AI_TRANSLATIONS_BASE_URL='http://localhost:18760'
ENABLE_CHECKLIST_QUALITY=true
SECURE_ORIGIN_XBLOCK_BOOTSTRAP_HTML_URL=/xblock-bootstrap.html
1 change: 1 addition & 0 deletions .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ ENABLE_TAGGING_TAXONOMY_PAGES=true
BBB_LEARN_MORE_URL=''
INVITE_STUDENTS_EMAIL_TO="[email protected]"
ENABLE_CHECKLIST_QUALITY=true
SECURE_ORIGIN_XBLOCK_BOOTSTRAP_HTML_URL=/xblock-bootstrap.html
126 changes: 124 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
"@testing-library/user-event": "^13.2.1",
"axios": "^0.27.2",
"axios-mock-adapter": "1.22.0",
"copy-webpack-plugin": "^11.0.0",
"eslint-import-resolver-webpack": "^0.13.8",
"glob": "7.2.3",
"husky": "7.0.4",
Expand Down
31 changes: 25 additions & 6 deletions src/course-unit/course-xblock/CourseXBlock.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,27 @@ import { EditOutline as EditIcon, MoreVert as MoveVertIcon } from '@openedx/para
import { useIntl } from '@edx/frontend-platform/i18n';
import { useDispatch, useSelector } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import { find } from 'lodash';

import DeleteModal from '../../generic/delete-modal/DeleteModal';
import ConfigureModal from '../../generic/configure-modal/ConfigureModal';
import ConditionalSortableElement from '../../generic/drag-helper/ConditionalSortableElement';
import { scrollToElement } from '../../course-outline/utils';
import { COURSE_BLOCK_NAMES } from '../../constants';
import { getCanEdit, getCourseId } from '../data/selectors';
import { copyToClipboard } from '../../generic/data/thunks';
import {
getCanEdit,
getCourseId,
getXBlockIFrameHtmlAndResources,
} from '../data/selectors';
import {
copyToClipboard,
} from '../../generic/data/thunks';
import { getHandlerUrl } from '../data/api';
import { fetchXBlockIFrameHtmlAndResourcesQuery } from '../data/thunk';
import { COMPONENT_TYPES } from '../constants';
import XBlockContent from './xblock-content/XBlockContent';
import XBlockMessages from './xblock-messages/XBlockMessages';
import RenderErrorAlert from './render-error-alert';
import { getIFrameUrl } from './urls';
import { XBlockContent } from './xblock-content';
import messages from './messages';

const CourseXBlock = ({
Expand All @@ -34,12 +42,17 @@ const CourseXBlock = ({
const courseId = useSelector(getCourseId);
const canEdit = useSelector(getCanEdit);
const intl = useIntl();
const iframeUrl = getIFrameUrl({ blockId: id });
const xblockIFrameHtmlAndResources = useSelector(getXBlockIFrameHtmlAndResources);
const xblockInstanceHtmlAndResources = find(xblockIFrameHtmlAndResources, { xblockId: id });

const visibilityMessage = userPartitionInfo.selectedGroupsLabel
? intl.formatMessage(messages.visibilityMessage, { selectedGroupsLabel: userPartitionInfo.selectedGroupsLabel })
: null;

useEffect(() => {
dispatch(fetchXBlockIFrameHtmlAndResourcesQuery(id));
}, []);

const currentItemData = {
category: COURSE_BLOCK_NAMES.component.id,
displayName: title,
Expand Down Expand Up @@ -140,7 +153,13 @@ const CourseXBlock = ({
{renderError ? <RenderErrorAlert errorMessage={renderError} /> : (
<>
<XBlockMessages validationMessages={validationMessages} />
<XBlockContent id={id} title={title} elementId={id} iframeUrl={iframeUrl} />
{xblockInstanceHtmlAndResources && (
<XBlockContent
getHandlerUrl={getHandlerUrl}
view={xblockInstanceHtmlAndResources}
type={type}
/>
)}
</>
)}
</Card.Section>
Expand Down
2 changes: 2 additions & 0 deletions src/course-unit/course-xblock/CourseXBlock.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@import "xblock-content/XBlockContent";

.course-unit {
.course-unit__xblocks {
.course-unit__xblock:not(:first-child) {
Expand Down
4 changes: 2 additions & 2 deletions src/course-unit/course-xblock/CourseXBlock.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -323,14 +323,14 @@ describe('<CourseXBlock />', () => {
const errorAlertDescription = renderErrorAlertMessages.alertRenderErrorDescription.defaultMessage;
const errorAlertMessage = renderErrorAlertMessages.alertRenderErrorMessage.defaultMessage
.replace('{message}', renderErrorMessage);
const contentIframe = queryByTestId('content-iframe-test-id');
const contentIFrame = queryByTestId('content-iframe-test-id');

expect(getByText(errorAlertTitle)).toBeInTheDocument();
expect(getByText(errorAlertDescription)).toBeInTheDocument();
expect(getByText(errorAlertMessage)).toBeInTheDocument();
expect(getByText(name)).toBeInTheDocument();
expect(getByLabelText(messages.blockAltButtonEdit.defaultMessage)).toBeInTheDocument();
expect(getByLabelText(messages.blockActionsDropdownAlt.defaultMessage)).toBeInTheDocument();
expect(contentIframe).not.toBeInTheDocument();
expect(contentIFrame).not.toBeInTheDocument();
});
});
27 changes: 21 additions & 6 deletions src/course-unit/course-xblock/constants.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
export const MESSAGE_TYPES = {
modal: 'plugin.modal',
resize: 'plugin.resize',
videoFullScreen: 'plugin.videoFullScreen',
};
import PropTypes from 'prop-types';

export const IFRAME_FEATURE_POLICY = (
'microphone *; camera *; midi *; geolocation *; encrypted-media *, clipboard-write *'
'accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture;'
);

export const MESSAGE_ERROR_TYPES = {
error: 'error',
warning: 'warning',
};

export const IFRAME_LOADING_STATUS = {
STANDBY: 'standby', // Structure has been created but is not yet loading.
LOADING: 'loading',
LOADED: 'loaded',
FAILED: 'failed',
};

export const statusShape = PropTypes.oneOf(Object.values(IFRAME_LOADING_STATUS));

export const fetchable = (valueShape) => PropTypes.shape({
status: statusShape,
value: valueShape,
});

export const blockViewShape = PropTypes.shape({
content: PropTypes.string.isRequired,
resources: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
});
3 changes: 0 additions & 3 deletions src/course-unit/course-xblock/hooks/index.js

This file was deleted.

27 changes: 0 additions & 27 deletions src/course-unit/course-xblock/hooks/useEventListener.js

This file was deleted.

17 changes: 0 additions & 17 deletions src/course-unit/course-xblock/hooks/useEventListener.test.jsx

This file was deleted.

Loading

0 comments on commit 7dacbd5

Please sign in to comment.