From bd2007245518e84797cd357539ed40750bbe0193 Mon Sep 17 00:00:00 2001 From: Tomas Bures Date: Thu, 22 Nov 2018 20:53:44 +0100 Subject: [PATCH] Save button for template editors --- client/src/campaigns/Content.js | 36 ++++++++++++++------- client/src/lib/sandboxed-ckeditor.js | 3 ++ client/src/lib/sandboxed-codeeditor-root.js | 23 ++++++++++++- client/src/lib/sandboxed-codeeditor.js | 3 +- client/src/lib/sandboxed-grapesjs.js | 3 ++ client/src/lib/sandboxed-mosaico.js | 3 ++ client/src/templates/CUD.js | 11 ++++--- client/src/templates/helpers.js | 8 +++++ 8 files changed, 73 insertions(+), 17 deletions(-) diff --git a/client/src/campaigns/Content.js b/client/src/campaigns/Content.js index cec4eaa6..f963ce56 100644 --- a/client/src/campaigns/Content.js +++ b/client/src/campaigns/Content.js @@ -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(); diff --git a/client/src/lib/sandboxed-ckeditor.js b/client/src/lib/sandboxed-ckeditor.js index 73ac8369..33e8f010 100644 --- a/client/src/lib/sandboxed-ckeditor.js +++ b/client/src/lib/sandboxed-ckeditor.js @@ -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 {
{this.props.title}
+ {this.props.canSave ? : } this.contentNode = node} className={styles.host} singleToken={true} contentProps={editorData} contentSrc="ckeditor/editor" tokenMethod="ckeditor" tokenParams={editorData}/> diff --git a/client/src/lib/sandboxed-codeeditor-root.js b/client/src/lib/sandboxed-codeeditor-root.js index bba57b0f..44cc57f5 100644 --- a/client/src/lib/sandboxed-codeeditor-root.js +++ b/client/src/lib/sandboxed-codeeditor-root.js @@ -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, ``); + return (
@@ -185,7 +206,7 @@ class CodeEditorSandbox extends Component { { this.state.preview &&
- +
}
diff --git a/client/src/lib/sandboxed-codeeditor.js b/client/src/lib/sandboxed-codeeditor.js index d067ec50..44a737d8 100644 --- a/client/src/lib/sandboxed-codeeditor.js +++ b/client/src/lib/sandboxed-codeeditor.js @@ -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 } diff --git a/client/src/lib/sandboxed-grapesjs.js b/client/src/lib/sandboxed-grapesjs.js index 3ff265db..8250c657 100644 --- a/client/src/lib/sandboxed-grapesjs.js +++ b/client/src/lib/sandboxed-grapesjs.js @@ -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 {
{this.props.title}
+ {this.props.canSave ? : }
this.contentNode = node} className={styles.host} singleToken={true} contentProps={editorData} contentSrc="grapesjs/editor" tokenMethod="grapesjs" tokenParams={tokenData}/> diff --git a/client/src/lib/sandboxed-mosaico.js b/client/src/lib/sandboxed-mosaico.js index 0a4b6819..2046bed8 100644 --- a/client/src/lib/sandboxed-mosaico.js +++ b/client/src/lib/sandboxed-mosaico.js @@ -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 {
{this.props.title}
+ {this.props.canSave ? : } this.contentNode = node} className={styles.host} singleToken={true} contentProps={editorData} contentSrc="mosaico/editor" tokenMethod="mosaico" tokenParams={tokenData}/> diff --git a/client/src/templates/CUD.js b/client/src/templates/CUD.js index 021df195..d7599fb2 100644 --- a/client/src/templates/CUD.js +++ b/client/src/templates/CUD.js @@ -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')); diff --git a/client/src/templates/helpers.js b/client/src/templates/helpers.js index c91a201a..3ab378b2 100644 --- a/client/src/templates/helpers.js +++ b/client/src/templates/helpers.js @@ -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} />