Save button for template editors
This commit is contained in:
parent
3bb235a585
commit
bd20072455
8 changed files with 73 additions and 17 deletions
|
@ -63,15 +63,17 @@ export default class CustomContent extends Component {
|
|||
entity: PropTypes.object
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getFormValuesFromEntity(this.props.entity, data => {
|
||||
data.data_sourceCustom_type = data.data.sourceCustom.type;
|
||||
data.data_sourceCustom_data = data.data.sourceCustom.data;
|
||||
data.data_sourceCustom_html = data.data.sourceCustom.html;
|
||||
data.data_sourceCustom_text = data.data.sourceCustom.text;
|
||||
loadFromEntityMutator(data) {
|
||||
data.data_sourceCustom_type = data.data.sourceCustom.type;
|
||||
data.data_sourceCustom_data = data.data.sourceCustom.data;
|
||||
data.data_sourceCustom_html = data.data.sourceCustom.html;
|
||||
data.data_sourceCustom_text = data.data.sourceCustom.text;
|
||||
|
||||
this.templateTypes[data.data.sourceCustom.type].afterLoad(data);
|
||||
});
|
||||
this.templateTypes[data.data.sourceCustom.type].afterLoad(data);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getFormValuesFromEntity(this.props.entity, data => this.loadFromEntityMutator(data));
|
||||
}
|
||||
|
||||
localValidateFormValues(state) {
|
||||
|
@ -84,7 +86,15 @@ export default class CustomContent extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
async save() {
|
||||
await this.doSave(true);
|
||||
}
|
||||
|
||||
async submitHandler() {
|
||||
await this.doSave(false);
|
||||
}
|
||||
|
||||
async doSave(stayOnPage) {
|
||||
const t = this.props.t;
|
||||
|
||||
const customTemplateTypeKey = this.getFormValue('data_sourceCustom_type');
|
||||
|
@ -115,10 +125,14 @@ export default class CustomContent extends Component {
|
|||
});
|
||||
|
||||
if (submitResponse) {
|
||||
if (this.props.entity) {
|
||||
this.navigateToWithFlashMessage('/campaigns', 'success', t('campaignSaved'));
|
||||
if (stayOnPage) {
|
||||
await this.getFormValuesFromURL(`rest/campaigns-content/${this.props.entity.id}`, data => this.loadFromEntityMutator(data));
|
||||
this.enableForm();
|
||||
this.clearFormStatusMessage();
|
||||
this.setFlashMessage('success', t('campaignSaved'));
|
||||
|
||||
} else {
|
||||
this.navigateToWithFlashMessage(`/campaigns/${submitResponse}/edit`, 'success', t('campaignSaved'));
|
||||
this.navigateToWithFlashMessage('/campaigns', 'success', t('campaignSaved'));
|
||||
}
|
||||
} else {
|
||||
this.enableForm();
|
||||
|
|
|
@ -31,6 +31,8 @@ export class CKEditorHost extends Component {
|
|||
entity: PropTypes.object,
|
||||
initialSource: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
onSave: PropTypes.func,
|
||||
canSave: PropTypes.bool,
|
||||
onTestSend: PropTypes.func,
|
||||
onFullscreenAsync: PropTypes.func
|
||||
}
|
||||
|
@ -91,6 +93,7 @@ export class CKEditorHost extends Component {
|
|||
<div className={styles.title}>{this.props.title}</div>
|
||||
<a className={styles.btn} onClick={::this.toggleFullscreenAsync}><Icon icon="fullscreen"/></a>
|
||||
<a className={styles.btn} onClick={this.props.onTestSend}><Icon icon="send"/></a>
|
||||
{this.props.canSave ? <a className={styles.btn} onClick={this.props.onSave}><Icon icon="floppy-disk"/></a> : <span className={styles.btnDisabled}><Icon icon="floppy-disk"/></span>}
|
||||
</div>
|
||||
<UntrustedContentHost ref={node => this.contentNode = node} className={styles.host} singleToken={true} contentProps={editorData} contentSrc="ckeditor/editor" tokenMethod="ckeditor" tokenParams={editorData}/>
|
||||
</div>
|
||||
|
|
|
@ -91,6 +91,9 @@ class CodeEditorSandbox extends Component {
|
|||
|
||||
this.refreshHandler = ::this.refresh;
|
||||
this.refreshTimeoutId = null;
|
||||
|
||||
this.onMessageFromPreviewHandler = ::this.onMessageFromPreview;
|
||||
this.previewScroll = {x: 0, y: 0};
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
|
@ -128,6 +131,8 @@ class CodeEditorSandbox extends Component {
|
|||
parentRPC.setMethodHandler('exportState', ::this.exportState);
|
||||
parentRPC.setMethodHandler('setPreview', ::this.setPreview);
|
||||
parentRPC.setMethodHandler('setWrap', ::this.setWrap);
|
||||
|
||||
window.addEventListener('message', this.onMessageFromPreviewHandler, false);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
@ -156,6 +161,12 @@ class CodeEditorSandbox extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
onMessageFromPreview(evt) {
|
||||
if (evt.data.type === 'scroll') {
|
||||
this.previewScroll = evt.data.data;
|
||||
}
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.refreshTimeoutId = null;
|
||||
|
||||
|
@ -165,6 +176,16 @@ class CodeEditorSandbox extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const previewScript =
|
||||
'(function() {\n' +
|
||||
' function reportScroll() { window.parent.postMessage({type: \'scroll\', data: {x: window.scrollX, y: window.scrollY}}, \'*\'); }\n' +
|
||||
' reportScroll();\n' +
|
||||
' window.addEventListener(\'scroll\', reportScroll);\n' +
|
||||
' window.addEventListener(\'load\', function(evt) { window.scrollTo(' + this.previewScroll.x + ',' + this.previewScroll.y +'); });\n' +
|
||||
'})();\n';
|
||||
|
||||
const previewContents = this.state.previewContents.replace(/<\s*head\s*>/i, `<head><script>${previewScript}</script>`);
|
||||
|
||||
return (
|
||||
<div className={styles.sandbox}>
|
||||
<div className={this.state.preview ? styles.aceEditorWithPreview : styles.aceEditorWithoutPreview}>
|
||||
|
@ -185,7 +206,7 @@ class CodeEditorSandbox extends Component {
|
|||
{
|
||||
this.state.preview &&
|
||||
<div className={styles.preview}>
|
||||
<iframe ref={node => this.previewNode = node} src={"data:text/html;charset=utf-8," + escape(this.state.previewContents)}></iframe>
|
||||
<iframe ref={node => this.previewNode = node} src={"data:text/html;charset=utf-8," + escape(previewContents)}></iframe>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -29,8 +29,9 @@ export class CodeEditorHost extends Component {
|
|||
initialSource: PropTypes.string,
|
||||
sourceType: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
onTestSend: PropTypes.func,
|
||||
onSave: PropTypes.func,
|
||||
canSave: PropTypes.bool,
|
||||
onTestSend: PropTypes.func,
|
||||
onFullscreenAsync: PropTypes.func
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@ export class GrapesJSHost extends Component {
|
|||
initialStyle: PropTypes.string,
|
||||
sourceType: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
onSave: PropTypes.func,
|
||||
canSave: PropTypes.bool,
|
||||
onTestSend: PropTypes.func,
|
||||
onFullscreenAsync: PropTypes.func
|
||||
}
|
||||
|
@ -67,6 +69,7 @@ export class GrapesJSHost extends Component {
|
|||
<div className={styles.title}>{this.props.title}</div>
|
||||
<a className={styles.btn} onClick={::this.toggleFullscreenAsync}><Icon icon="fullscreen"/></a>
|
||||
<a className={styles.btn} onClick={this.props.onTestSend}><Icon icon="send"/></a>
|
||||
{this.props.canSave ? <a className={styles.btn} onClick={this.props.onSave}><Icon icon="floppy-disk"/></a> : <span className={styles.btnDisabled}><Icon icon="floppy-disk"/></span>}
|
||||
</div>
|
||||
<UntrustedContentHost ref={node => this.contentNode = node} className={styles.host} singleToken={true} contentProps={editorData} contentSrc="grapesjs/editor" tokenMethod="grapesjs" tokenParams={tokenData}/>
|
||||
</div>
|
||||
|
|
|
@ -26,6 +26,8 @@ export class MosaicoHost extends Component {
|
|||
entityTypeId: PropTypes.string,
|
||||
entity: PropTypes.object,
|
||||
title: PropTypes.string,
|
||||
onSave: PropTypes.func,
|
||||
canSave: PropTypes.bool,
|
||||
onTestSend: PropTypes.func,
|
||||
onFullscreenAsync: PropTypes.func,
|
||||
templateId: PropTypes.number,
|
||||
|
@ -70,6 +72,7 @@ export class MosaicoHost extends Component {
|
|||
<div className={styles.title}>{this.props.title}</div>
|
||||
<a className={styles.btn} onClick={::this.toggleFullscreenAsync}><Icon icon="fullscreen"/></a>
|
||||
<a className={styles.btn} onClick={this.props.onTestSend}><Icon icon="send"/></a>
|
||||
{this.props.canSave ? <a className={styles.btn} onClick={this.props.onSave}><Icon icon="floppy-disk"/></a> : <span className={styles.btnDisabled}><Icon icon="floppy-disk"/></span>}
|
||||
</div>
|
||||
<UntrustedContentHost ref={node => this.contentNode = node} className={styles.host} singleToken={true} contentProps={editorData} contentSrc="mosaico/editor" tokenMethod="mosaico" tokenParams={tokenData}/>
|
||||
</div>
|
||||
|
|
|
@ -52,7 +52,7 @@ export default class CUD extends Component {
|
|||
this.state = {
|
||||
showMergeTagReference: false,
|
||||
elementInFullscreen: false,
|
||||
showTestSendModal: false
|
||||
showTestSendModal: false,
|
||||
};
|
||||
|
||||
this.initForm({
|
||||
|
@ -76,11 +76,13 @@ export default class CUD extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
loadFromEntityMutator(data) {
|
||||
this.templateTypes[data.type].afterLoad(data);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.entity) {
|
||||
this.getFormValuesFromEntity(this.props.entity, data => {
|
||||
this.templateTypes[data.type].afterLoad(data);
|
||||
});
|
||||
this.getFormValuesFromEntity(this.props.entity, data => this.loadFromEntityMutator(data));
|
||||
} else {
|
||||
this.populateFormValues({
|
||||
name: '',
|
||||
|
@ -146,6 +148,7 @@ export default class CUD extends Component {
|
|||
|
||||
if (submitResponse) {
|
||||
if (stayOnPage) {
|
||||
await this.getFormValuesFromURL(`rest/templates/${this.props.entity.id}`, data => this.loadFromEntityMutator(data));
|
||||
this.enableForm();
|
||||
this.clearFormStatusMessage();
|
||||
this.setFlashMessage('success', t('templateSaved'));
|
||||
|
|
|
@ -121,6 +121,8 @@ export function getTemplateTypes(t, prefix = '', entityTypeId = ResourceType.TEM
|
|||
templateId={owner.getFormValue(prefix + 'mosaicoTemplate')}
|
||||
entityTypeId={entityTypeId}
|
||||
title={t('mosaicoTemplateDesigner')}
|
||||
onSave={::owner.save}
|
||||
canSave={owner.isFormWithoutErrors()}
|
||||
onTestSend={::owner.showTestSendModal}
|
||||
onFullscreenAsync={::owner.setElementInFullscreen}
|
||||
/>
|
||||
|
@ -194,6 +196,8 @@ export function getTemplateTypes(t, prefix = '', entityTypeId = ResourceType.TEM
|
|||
templatePath={getSandboxUrl(`static/mosaico/templates/${owner.getFormValue(prefix + 'mosaicoFsTemplate')}/index.html`)}
|
||||
entityTypeId={entityTypeId}
|
||||
title={t('mosaicoTemplateDesigner')}
|
||||
onSave={::owner.save}
|
||||
canSave={owner.isFormWithoutErrors()}
|
||||
onTestSend={::owner.showTestSendModal}
|
||||
onFullscreenAsync={::owner.setElementInFullscreen}
|
||||
/>
|
||||
|
@ -270,6 +274,8 @@ export function getTemplateTypes(t, prefix = '', entityTypeId = ResourceType.TEM
|
|||
initialStyle={owner.getFormValue(prefix + 'grapesJSData').style}
|
||||
sourceType={owner.getFormValue(prefix + 'grapesJSSourceType')}
|
||||
title={t('grapesJsTemplateDesigner')}
|
||||
onSave={::owner.save}
|
||||
canSave={owner.isFormWithoutErrors()}
|
||||
onTestSend={::owner.showTestSendModal}
|
||||
onFullscreenAsync={::owner.setElementInFullscreen}
|
||||
/>
|
||||
|
@ -322,6 +328,8 @@ export function getTemplateTypes(t, prefix = '', entityTypeId = ResourceType.TEM
|
|||
initialSource={owner.getFormValue(prefix + 'ckeditor4Data').source}
|
||||
entityTypeId={entityTypeId}
|
||||
title={t('ckEditor4TemplateDesigner')}
|
||||
onSave={::owner.save}
|
||||
canSave={owner.isFormWithoutErrors()}
|
||||
onTestSend={::owner.showTestSendModal}
|
||||
onFullscreenAsync={::owner.setElementInFullscreen}
|
||||
/>
|
||||
|
|
Loading…
Reference in a new issue