feat: handle edit modals from advanced xblocks (#1445)
Adds new message types, updates message handlers, and implements a new modal iframe for legacy XBlock editing.
This commit is contained in:
34
src/generic/modal-iframe/ModalIframe.test.tsx
Normal file
34
src/generic/modal-iframe/ModalIframe.test.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { IFRAME_FEATURE_POLICY } from '../../constants';
|
||||
import ModalIframe, { SANDBOX_OPTIONS } from '.';
|
||||
|
||||
describe('ModalIframe Component', () => {
|
||||
const title = 'Legacy Edit Modal';
|
||||
const src = 'edit/xblock';
|
||||
|
||||
it('renders without crashing', async () => {
|
||||
const { getByRole } = render(<ModalIframe title={title} src={src} />);
|
||||
|
||||
expect(getByRole('dialog')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders iframe with correct src', () => {
|
||||
const { getByTitle } = render(<ModalIframe title={title} src={src} />);
|
||||
|
||||
const iframe = getByTitle(title);
|
||||
expect(iframe).toBeInTheDocument();
|
||||
expect(iframe).toHaveAttribute('src', src);
|
||||
expect(iframe).toHaveAttribute('allow', IFRAME_FEATURE_POLICY);
|
||||
expect(iframe).toHaveAttribute('class', 'modal-iframe');
|
||||
expect(iframe).toHaveAttribute('referrerpolicy', 'origin');
|
||||
expect(iframe).toHaveAttribute('sandbox', SANDBOX_OPTIONS);
|
||||
expect(iframe).toHaveAttribute('scrolling', 'no');
|
||||
});
|
||||
|
||||
it('does not render when showLegacyEditModal is false', () => {
|
||||
const { container } = render(<ModalIframe title={title} src={src} />);
|
||||
|
||||
expect(container.firstChild).not.toBeNull();
|
||||
});
|
||||
});
|
||||
13
src/generic/modal-iframe/index.scss
Normal file
13
src/generic/modal-iframe/index.scss
Normal file
@@ -0,0 +1,13 @@
|
||||
.modal-iframe {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: $zindex-modal;
|
||||
|
||||
iframe {
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
}
|
||||
}
|
||||
43
src/generic/modal-iframe/index.tsx
Normal file
43
src/generic/modal-iframe/index.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import { forwardRef, ForwardedRef, IframeHTMLAttributes } from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { IFRAME_FEATURE_POLICY } from '../../constants';
|
||||
|
||||
interface ModalIframeProps extends IframeHTMLAttributes<HTMLIFrameElement> {
|
||||
title: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const SANDBOX_OPTIONS = [
|
||||
'allow-forms',
|
||||
'allow-modals',
|
||||
'allow-popups',
|
||||
'allow-popups-to-escape-sandbox',
|
||||
'allow-presentation',
|
||||
'allow-same-origin',
|
||||
'allow-scripts',
|
||||
'allow-top-navigation-by-user-activation',
|
||||
].join(' ');
|
||||
|
||||
const ModalIframe = forwardRef<HTMLIFrameElement, ModalIframeProps>(
|
||||
({ title, className, ...props }, ref: ForwardedRef<HTMLIFrameElement>) => (
|
||||
<iframe
|
||||
title={title}
|
||||
className={classNames('modal-iframe', className)}
|
||||
allow={IFRAME_FEATURE_POLICY}
|
||||
referrerPolicy="origin"
|
||||
frameBorder="0"
|
||||
scrolling="no"
|
||||
ref={ref}
|
||||
role="dialog"
|
||||
sandbox={SANDBOX_OPTIONS}
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
);
|
||||
|
||||
ModalIframe.defaultProps = {
|
||||
className: '',
|
||||
};
|
||||
|
||||
export default ModalIframe;
|
||||
@@ -39,6 +39,7 @@ const SavingErrorAlert = ({
|
||||
<AlertMessage
|
||||
show={showAlert}
|
||||
variant="danger"
|
||||
data-testid="saving-error-alert"
|
||||
icon={WarningIcon}
|
||||
title={intl.formatMessage(messages.warningTitle)}
|
||||
description={
|
||||
|
||||
@@ -13,3 +13,4 @@
|
||||
@import "./configure-modal/ConfigureModal";
|
||||
@import "./drag-helper/SortableItem";
|
||||
@import "./block-type-utils";
|
||||
@import "./modal-iframe"
|
||||
|
||||
Reference in New Issue
Block a user