Integrated CKEditor for templates. We might need to move it to a sandbox later to make it secure.
This commit is contained in:
parent
508d6b3b2f
commit
ba75623f86
5 changed files with 129 additions and 110 deletions
|
@ -28,6 +28,7 @@
|
||||||
"querystringify": "^1.0.0",
|
"querystringify": "^1.0.0",
|
||||||
"react": "^15.6.1",
|
"react": "^15.6.1",
|
||||||
"react-ace": "^5.1.0",
|
"react-ace": "^5.1.0",
|
||||||
|
"react-ckeditor-component": "^1.0.7",
|
||||||
"react-day-picker": "^6.1.0",
|
"react-day-picker": "^6.1.0",
|
||||||
"react-dnd-html5-backend": "^2.4.1",
|
"react-dnd-html5-backend": "^2.4.1",
|
||||||
"react-dnd-touch-backend": "^0.3.13",
|
"react-dnd-touch-backend": "^0.3.13",
|
||||||
|
|
|
@ -863,7 +863,9 @@ class CKEditor extends Component {
|
||||||
|
|
||||||
return wrapInput(id, htmlId, owner, props.format, '', props.label, props.help,
|
return wrapInput(id, htmlId, owner, props.format, '', props.label, props.help,
|
||||||
<CKEditorRaw
|
<CKEditorRaw
|
||||||
onChange={evt => owner.updateFormValue(id, evt.editor.getData())}
|
events={{
|
||||||
|
"change": evt => owner.updateFormValue(id, evt.editor.getData())
|
||||||
|
}}
|
||||||
content={owner.getFormValue(id)}
|
content={owner.getFormValue(id)}
|
||||||
config={{width: '100%', height: props.height}}
|
config={{width: '100%', height: props.height}}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -159,37 +159,9 @@ export default class CUD extends Component {
|
||||||
|
|
||||||
const typeKey = this.getFormValue('type');
|
const typeKey = this.getFormValue('type');
|
||||||
|
|
||||||
return (
|
let editForm = null;
|
||||||
<div>
|
if (isEdit && typeKey) {
|
||||||
{canDelete &&
|
editForm = <div>
|
||||||
<DeleteModalDialog
|
|
||||||
stateOwner={this}
|
|
||||||
visible={this.props.action === 'delete'}
|
|
||||||
deleteUrl={`/rest/templates/${this.props.entity.id}`}
|
|
||||||
cudUrl={`/templates/${this.props.entity.id}/edit`}
|
|
||||||
listUrl="/templates"
|
|
||||||
deletingMsg={t('Deleting template ...')}
|
|
||||||
deletedMsg={t('Template deleted')}/>
|
|
||||||
}
|
|
||||||
|
|
||||||
<Title>{isEdit ? t('Edit Template') : t('Create Template')}</Title>
|
|
||||||
|
|
||||||
<Form stateOwner={this} onSubmitAsync={::this.submitHandler}>
|
|
||||||
<InputField id="name" label={t('Name')}/>
|
|
||||||
<TextArea id="description" label={t('Description')} help={t('HTML is allowed')}/>
|
|
||||||
|
|
||||||
{isEdit
|
|
||||||
?
|
|
||||||
<StaticField id="type" className={styles.formDisabled} label={t('Type')}>
|
|
||||||
{typeKey && this.templateTypes[typeKey].typeName}
|
|
||||||
</StaticField>
|
|
||||||
:
|
|
||||||
<Dropdown id="type" label={t('Type')} options={typeOptions}/>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
<NamespaceSelect/>
|
|
||||||
|
|
||||||
<AlignedRow>
|
<AlignedRow>
|
||||||
<Button className="btn-default" onClickAsync={::this.toggleMergeTagReference} label={t('Merge tag reference')}/>
|
<Button className="btn-default" onClickAsync={::this.toggleMergeTagReference} label={t('Merge tag reference')}/>
|
||||||
{this.state.showMergeTagReference &&
|
{this.state.showMergeTagReference &&
|
||||||
|
@ -294,9 +266,45 @@ export default class CUD extends Component {
|
||||||
</div>}
|
</div>}
|
||||||
</AlignedRow>
|
</AlignedRow>
|
||||||
|
|
||||||
<ACEEditor id="text" height="400px" mode="text" label={t('Template content (plain text)')} help={<Trans>To extract the text from HTML click <ActionLink onClickAsync={::this.extractPlainText}>here</ActionLink>. Please note that your existing plaintext in the field above will be overwritten. This feature uses the <a href="http://premailer.dialect.ca/api">Premailer API</a>, a third party service. Their Terms of Service and Privacy Policy apply.</Trans>}/>
|
{this.templateTypes[typeKey].form}
|
||||||
|
|
||||||
{isEdit && typeKey && this.templateTypes[typeKey].form}
|
<ACEEditor id="text" height="400px" mode="text" label={t('Template content (plain text)')} help={<Trans>To extract the text from HTML click <ActionLink onClickAsync={::this.extractPlainText}>here</ActionLink>. Please note that your existing plaintext in the field above will be overwritten. This feature uses the <a href="http://premailer.dialect.ca/api">Premailer API</a>, a third party service. Their Terms of Service and Privacy Policy apply.</Trans>}/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{canDelete &&
|
||||||
|
<DeleteModalDialog
|
||||||
|
stateOwner={this}
|
||||||
|
visible={this.props.action === 'delete'}
|
||||||
|
deleteUrl={`/rest/templates/${this.props.entity.id}`}
|
||||||
|
cudUrl={`/templates/${this.props.entity.id}/edit`}
|
||||||
|
listUrl="/templates"
|
||||||
|
deletingMsg={t('Deleting template ...')}
|
||||||
|
deletedMsg={t('Template deleted')}/>
|
||||||
|
}
|
||||||
|
|
||||||
|
<Title>{isEdit ? t('Edit Template') : t('Create Template')}</Title>
|
||||||
|
|
||||||
|
<Form stateOwner={this} onSubmitAsync={::this.submitHandler}>
|
||||||
|
<InputField id="name" label={t('Name')}/>
|
||||||
|
<TextArea id="description" label={t('Description')} help={t('HTML is allowed')}/>
|
||||||
|
|
||||||
|
{isEdit
|
||||||
|
?
|
||||||
|
<StaticField id="type" className={styles.formDisabled} label={t('Type')}>
|
||||||
|
{typeKey && this.templateTypes[typeKey].typeName}
|
||||||
|
</StaticField>
|
||||||
|
:
|
||||||
|
<Dropdown id="type" label={t('Type')} options={typeOptions}/>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
<NamespaceSelect/>
|
||||||
|
|
||||||
|
{editForm}
|
||||||
|
|
||||||
<ButtonRow>
|
<ButtonRow>
|
||||||
<Button type="submit" className="btn-primary" icon="ok" label={isEdit ? t('Save') : t('Save and edit template')}/>
|
<Button type="submit" className="btn-primary" icon="ok" label={isEdit ? t('Save') : t('Save and edit template')}/>
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {ACEEditor, SummernoteEditor} from "../lib/form";
|
import {
|
||||||
|
ACEEditor,
|
||||||
|
CKEditor
|
||||||
|
} from "../lib/form";
|
||||||
import 'brace/mode/text';
|
import 'brace/mode/text';
|
||||||
import 'brace/mode/html'
|
import 'brace/mode/html'
|
||||||
|
|
||||||
|
@ -19,7 +22,7 @@ export function getTemplateTypes(t) {
|
||||||
|
|
||||||
templateTypes.ckeditor = {
|
templateTypes.ckeditor = {
|
||||||
typeName: t('CKEditor'),
|
typeName: t('CKEditor'),
|
||||||
form: <SummernoteEditor id="html" height="600px" label={t('Template content (HTML)')}/>
|
form: <CKEditor id="html" height="600px" label={t('Template content (HTML)')}/>
|
||||||
};
|
};
|
||||||
|
|
||||||
templateTypes.codeeditor = {
|
templateTypes.codeeditor = {
|
||||||
|
|
|
@ -52,9 +52,14 @@ module.exports = {
|
||||||
},
|
},
|
||||||
'sass-loader' ]
|
'sass-loader' ]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
test: /\.(woff|ttf|eot)$/,
|
||||||
|
use: [ 'url-loader' ]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
externals: {
|
externals: {
|
||||||
|
$: "jQuery",
|
||||||
jquery: 'jQuery',
|
jquery: 'jQuery',
|
||||||
csfrToken: 'csfrToken',
|
csfrToken: 'csfrToken',
|
||||||
mailtrainConfig: 'mailtrainConfig'
|
mailtrainConfig: 'mailtrainConfig'
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue