Add Draftail error handling component

pull/4318/head
Thibaud Colas 2018-02-27 17:34:22 +02:00
rodzic 7841f54fe8
commit 7740d2d615
6 zmienionych plików z 130 dodań i 24 usunięć

Wyświetl plik

@ -17,6 +17,7 @@ $draftail-editor-font-family: $font-serif;
@import '../../../../node_modules/draftail/lib/index';
@import './Tooltip/Tooltip';
@import './EditorFallback/EditorFallback';
@import './decorators/TooltipEntity';

Wyświetl plik

@ -0,0 +1,86 @@
import PropTypes from 'prop-types';
import React, { PureComponent } from 'react';
import { convertFromRaw } from 'draft-js';
import { STRINGS } from '../../../config/wagtailConfig';
class EditorFallback extends PureComponent {
constructor(props) {
super(props);
const { field } = props;
this.state = {
error: null,
isContentShown: false,
initialContent: field.value,
};
this.renderError = this.renderError.bind(this);
this.toggleContent = this.toggleContent.bind(this);
}
componentDidCatch(error) {
const { field } = this.props;
const { initialContent } = this.state;
this.setState({ error });
field.value = initialContent;
}
toggleContent() {
const { isContentShown } = this.state;
this.setState({ isContentShown: !isContentShown });
}
renderError() {
const { field } = this.props;
const { isContentShown } = this.state;
const content = field.rawContentState && convertFromRaw(field.rawContentState).getPlainText();
return (
<div className="Draftail-Editor">
<div className="Draftail-Toolbar">
<button
type="button"
className="Draftail-ToolbarButton"
onClick={() => window.location.reload(false)}
>
{STRINGS.RELOAD_PAGE}
</button>
{content && (
<button
type="button"
className="Draftail-ToolbarButton"
onClick={this.toggleContent}
>
{STRINGS.SHOW_LATEST_CONTENT}
</button>
)}
</div>
<div className="DraftEditor-root">
<div className="public-DraftEditorPlaceholder-inner">
{STRINGS.EDITOR_CRASH}
</div>
</div>
{isContentShown && (
<textarea className="EditorFallback__textarea" value={content} readOnly />
)}
</div>
);
}
render() {
const { children } = this.props;
const { error } = this.state;
return error ? this.renderError() : children;
}
}
EditorFallback.propTypes = {
children: PropTypes.node.isRequired,
};
export default EditorFallback;

Wyświetl plik

@ -0,0 +1,4 @@
.EditorFallback__textarea {
resize: vertical;
min-height: 150px;
}

Wyświetl plik

@ -13,6 +13,8 @@ export { default as EmbedBlock } from './blocks/EmbedBlock';
export { default as ModalWorkflowSource } from './sources/ModalWorkflowSource';
import EditorFallback from './EditorFallback/EditorFallback';
// 1024x1024 SVG path rendering of the "↵" character, that renders badly in MS Edge.
const BR_ICON = 'M.436 633.471l296.897-296.898v241.823h616.586V94.117h109.517v593.796H297.333v242.456z';
@ -61,6 +63,7 @@ const initEditor = (selector, options, currentScript) => {
field.parentNode.appendChild(editorWrapper);
const serialiseInputValue = rawContentState => {
field.rawContentState = rawContentState;
field.value = JSON.stringify(rawContentState);
};
@ -80,34 +83,40 @@ const initEditor = (selector, options, currentScript) => {
} : false;
const rawContentState = JSON.parse(field.value);
field.rawContentState = rawContentState;
const editorRef = (ref) => {
// Bind editor instance to its field so it can be accessed imperatively elsewhere.
field.draftailEditor = ref;
};
const editor = (
<DraftailEditor
rawContentState={rawContentState}
onSave={serialiseInputValue}
placeholder={STRINGS.WRITE_HERE}
spellCheck={true}
enableLineBreak={{
description: STRINGS.LINE_BREAK,
icon: BR_ICON,
}}
showUndoControl={{ description: STRINGS.UNDO }}
showRedoControl={{ description: STRINGS.REDO }}
maxListNesting={4}
// Draft.js + IE 11 presents some issues with pasting rich text. Disable rich paste there.
stripPastedStyles={IS_IE11}
{...options}
blockTypes={blockTypes.map(wrapWagtailIcon)}
inlineStyles={inlineStyles.map(wrapWagtailIcon)}
entityTypes={entityTypes}
enableHorizontalRule={enableHorizontalRule}
/>
<EditorFallback field={field}>
<DraftailEditor
ref={editorRef}
rawContentState={rawContentState}
onSave={serialiseInputValue}
placeholder={STRINGS.WRITE_HERE}
spellCheck={true}
enableLineBreak={{
description: STRINGS.LINE_BREAK,
icon: BR_ICON,
}}
showUndoControl={{ description: STRINGS.UNDO }}
showRedoControl={{ description: STRINGS.REDO }}
maxListNesting={4}
// Draft.js + IE 11 presents some issues with pasting rich text. Disable rich paste there.
stripPastedStyles={IS_IE11}
{...options}
blockTypes={blockTypes.map(wrapWagtailIcon)}
inlineStyles={inlineStyles.map(wrapWagtailIcon)}
entityTypes={entityTypes}
enableHorizontalRule={enableHorizontalRule}
/>
</EditorFallback>
);
const draftailEditor = ReactDOM.render(editor, editorWrapper);
// Bind editor instance to its field so it can be accessed imperatively elsewhere.
field.draftailEditor = draftailEditor;
ReactDOM.render(editor, editorWrapper);
};
export default {

Wyświetl plik

@ -36,6 +36,9 @@ global.wagtailConfig = {
LINE_BREAK: 'Line break',
UNDO: 'Undo',
REDO: 'Redo',
RELOAD_PAGE: 'Reload the page',
SHOW_LATEST_CONTENT: 'Show latest content',
EDITOR_CRASH: 'The editor just crashed. Content has been reset to the last saved version.',
},
};

Wyświetl plik

@ -44,6 +44,9 @@
LINE_BREAK: "{% trans 'Line break' %}",
UNDO: "{% trans 'Undo' %}",
REDO: "{% trans 'Redo' %}",
RELOAD_PAGE: "{% trans 'Reload the page' %}",
SHOW_LATEST_CONTENT: "{% trans 'Show latest content' %}",
EDITOR_CRASH: "{% trans 'The editor just crashed. Content has been reset to the last saved version.' %}",
};
wagtailConfig.ADMIN_URLS = {