Fix moving page editor to the control panel.
This commit is contained in:
parent
8fcf9c3cbc
commit
7e319e3b20
|
@ -31,6 +31,8 @@ import {adminStore} from './store';
|
||||||
flexBasis: ControlPanel.SIDEBAR_SIZE,
|
flexBasis: ControlPanel.SIDEBAR_SIZE,
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
|
|
||||||
|
width: ControlPanel.SIDEBAR_SIZE,
|
||||||
|
|
||||||
transitionProperty: 'all',
|
transitionProperty: 'all',
|
||||||
transitionDuration: '0.5s',
|
transitionDuration: '0.5s',
|
||||||
transitionTimingFunction: 'ease-in-out',
|
transitionTimingFunction: 'ease-in-out',
|
||||||
|
|
|
@ -8,9 +8,72 @@ Page editor component
|
||||||
|
|
||||||
import {h, Component} from 'preact'; /** @jsx h*/
|
import {h, Component} from 'preact'; /** @jsx h*/
|
||||||
|
|
||||||
|
import {observer} from 'mobx-observer';
|
||||||
|
|
||||||
|
import {Button} from 'reactstrap';
|
||||||
|
import FontAwesome from 'react-fontawesome';
|
||||||
|
|
||||||
|
import {pageStore, siteStore} from '../stores';
|
||||||
|
|
||||||
|
import CodeMirror from 'react-codemirror2';
|
||||||
|
import 'codemirror/mode/markdown/markdown';
|
||||||
|
|
||||||
|
@observer
|
||||||
export class PageEditor extends Component {
|
export class PageEditor extends Component {
|
||||||
|
// TODO: Add support for HTML / Markdown
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
displayContent: pageStore.content || "Please wait while we load this page's entry.",
|
||||||
|
originalContent: pageStore.content || "Please wait while we load this page's entry.",
|
||||||
|
};
|
||||||
|
this.handleSaveContent = this.handleSaveContent.bind(this);
|
||||||
|
this.handleResetContent = this.handleResetContent.bind(this);
|
||||||
|
this.handleUpdateCode = this.handleUpdateCode.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleUpdateCode(editor, metadata, newCode) {
|
||||||
|
pageStore.content = newCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleResetContent() {
|
||||||
|
// TODO: Use the page store instead... (And keep backups...)
|
||||||
|
this.setState({displayContent: this.state.originalContent});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSaveContent() {
|
||||||
|
// # TODO Start using proper models for page and json
|
||||||
|
let pageContent = {
|
||||||
|
id: pageStore.slug || siteStore.landingPage,
|
||||||
|
// TODO: Add support for internally saved title?
|
||||||
|
title: pageStore.title,
|
||||||
|
content: pageStore.content,
|
||||||
|
};
|
||||||
|
pageStore.savePage(pageContent);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (<div>Page Editor</div>)
|
// TODO Add suppport switchable editor themes.
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Page Editor</h1>
|
||||||
|
<CodeMirror
|
||||||
|
value={ pageStore.content }
|
||||||
|
onChange={ this.handleUpdateCode }
|
||||||
|
options={{
|
||||||
|
mode: 'markdown',
|
||||||
|
theme: 'monokai',
|
||||||
|
lineWrapping: true,
|
||||||
|
lineNumbers: true,
|
||||||
|
}} />
|
||||||
|
<Button onClick={ this.handleSaveContent }>
|
||||||
|
<FontAwesome name='save'/> Save
|
||||||
|
</Button>
|
||||||
|
<Button onClick={ this.handleResetContent }>
|
||||||
|
<FontAwesome name='undo'/> Reset
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,21 +14,8 @@ import {observer} from 'mobx-observer';
|
||||||
|
|
||||||
import markdown from 'markdown-it';
|
import markdown from 'markdown-it';
|
||||||
import highlighter from 'highlight.js';
|
import highlighter from 'highlight.js';
|
||||||
import {Button, Collapse} from 'reactstrap';
|
|
||||||
import FontAwesome from 'react-fontawesome';
|
|
||||||
|
|
||||||
import {pageStore, siteStore, userStore} from '../stores';
|
import {pageStore, siteStore} from '../stores';
|
||||||
|
|
||||||
import CodeMirror from 'react-codemirror2';
|
|
||||||
import 'codemirror/mode/markdown/markdown';
|
|
||||||
|
|
||||||
|
|
||||||
// # TODO Remove and rework to allow for two flags, rather than a single state?
|
|
||||||
export const EditorPaneState = {
|
|
||||||
hidden: 0,
|
|
||||||
editableClosed: 1,
|
|
||||||
editableOpen: 2
|
|
||||||
};
|
|
||||||
|
|
||||||
export class MarkdownBlock extends Component {
|
export class MarkdownBlock extends Component {
|
||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
|
@ -65,20 +52,6 @@ export class PageBlock extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
displayContent: pageStore.content || "Please wait while we load this page's entry.",
|
|
||||||
originalContent: pageStore.content || "Please wait while we load this page's entry.",
|
|
||||||
editorPaneState: EditorPaneState.hidden
|
|
||||||
};
|
|
||||||
this.handleSaveContent = this.handleSaveContent.bind(this);
|
|
||||||
this.handleToggleEditorPane = this.handleToggleEditorPane.bind(this);
|
|
||||||
this.handleSaveContent = this.handleSaveContent.bind(this);
|
|
||||||
this.handleResetContent = this.handleResetContent.bind(this);
|
|
||||||
this.handleUpdateCode = this.handleUpdateCode.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
let pageToLoad = this.props.match.params.pageId;
|
let pageToLoad = this.props.match.params.pageId;
|
||||||
if (pageToLoad === undefined) {
|
if (pageToLoad === undefined) {
|
||||||
|
@ -86,7 +59,6 @@ export class PageBlock extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
pageStore.fetchPage(pageToLoad);
|
pageStore.fetchPage(pageToLoad);
|
||||||
this.updateEditAllowance(userStore.isUserLoggedIn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
|
@ -100,93 +72,11 @@ export class PageBlock extends Component {
|
||||||
|
|
||||||
pageStore.fetchPage(pageToLoad);
|
pageStore.fetchPage(pageToLoad);
|
||||||
}
|
}
|
||||||
this.updateEditAllowance(userStore.isUserLoggedIn)
|
|
||||||
}
|
|
||||||
|
|
||||||
handleUpdateCode(editor, metadata, newCode) {
|
|
||||||
pageStore.content = newCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleToggleEditorPane() {
|
|
||||||
let nextEditorState = this.state.editorPaneState;
|
|
||||||
if (this.state.editorPaneState === EditorPaneState.editableOpen) {
|
|
||||||
nextEditorState = EditorPaneState.editableClosed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.state.editorPaneState === EditorPaneState.editableClosed) {
|
|
||||||
nextEditorState = EditorPaneState.editableOpen;
|
|
||||||
}
|
|
||||||
this.setState({editorPaneState: nextEditorState});
|
|
||||||
}
|
|
||||||
|
|
||||||
isEditorPaneOpen() {
|
|
||||||
return this.state.editorPaneState === EditorPaneState.editableOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleResetContent() {
|
|
||||||
// TODO: Use the page store instead... (And keep backups...)
|
|
||||||
this.setState({displayContent: this.state.originalContent});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSaveContent() {
|
|
||||||
// # TODO Start using proper models for page and json
|
|
||||||
let pageContent = {
|
|
||||||
id: this.props.match.params.pageId || siteStore.landingPage,
|
|
||||||
// TODO: Add support for internally saved title?
|
|
||||||
title: pageStore.title,
|
|
||||||
content: pageStore.content,
|
|
||||||
};
|
|
||||||
pageStore.savePage(pageContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateEditAllowance(allowEdits) {
|
|
||||||
let editorState = this.state.editorPaneState;
|
|
||||||
if (!allowEdits) {
|
|
||||||
editorState = EditorPaneState.hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allowEdits && this.state.editorPaneState === EditorPaneState.hidden) {
|
|
||||||
editorState = EditorPaneState.editableClosed;
|
|
||||||
}
|
|
||||||
this.setState({editorPaneState: editorState});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
// # TODO Factor the view into something nicer.
|
|
||||||
let showEditorButton = (
|
|
||||||
<Button onClick={ this.handleToggleEditorPane }>
|
|
||||||
<FontAwesome name='edit'/> Edit
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
|
|
||||||
// TODO Add in ability to display mhessages outside the collapsible pane
|
|
||||||
// TODO Add suppport switchable editor themes.
|
|
||||||
let showPanel = (
|
|
||||||
<Collapse isOpen={ this.isEditorPaneOpen() }>
|
|
||||||
<CodeMirror
|
|
||||||
value={ pageStore.content }
|
|
||||||
onChange={ this.handleUpdateCode }
|
|
||||||
options={{ mode: 'markdown', theme: 'monokai' }} />
|
|
||||||
<Button onClick={ this.handleSaveContent }>
|
|
||||||
<FontAwesome name='save'/> Save
|
|
||||||
</Button>
|
|
||||||
<Button onClick={ this.handleResetContent }>
|
|
||||||
<FontAwesome name='undo'/> Reset
|
|
||||||
</Button>
|
|
||||||
</Collapse>
|
|
||||||
);
|
|
||||||
|
|
||||||
if (this.state.editorPaneState === EditorPaneState.hidden) {
|
|
||||||
showEditorButton = (<div />);
|
|
||||||
showPanel = (<div />);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
|
||||||
<MarkdownBlock slug={ pageStore.slug } content={ pageStore.content } />
|
<MarkdownBlock slug={ pageStore.slug } content={ pageStore.content } />
|
||||||
{ showEditorButton }
|
|
||||||
{ showPanel }
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue