kopia lustrzana https://github.com/wagtail/wagtail
Add Draftail error handling component
rodzic
7841f54fe8
commit
7740d2d615
|
@ -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';
|
||||
|
||||
|
|
|
@ -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;
|
|
@ -0,0 +1,4 @@
|
|||
.EditorFallback__textarea {
|
||||
resize: vertical;
|
||||
min-height: 150px;
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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.',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -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 = {
|
||||
|
|
Ładowanie…
Reference in New Issue