From ade0fc87f27132551f270ac707fe7b009c144947 Mon Sep 17 00:00:00 2001 From: Tomas Bures Date: Wed, 1 Aug 2018 15:30:20 +0530 Subject: [PATCH] work in progress on campaign edit --- client/src/campaigns/CUD.js | 208 +++++++++++++----- client/src/campaigns/List.js | 13 +- client/src/lib/form.js | 8 +- client/src/lib/mosaico.js | 5 +- client/src/lib/styles.scss | 1 + client/src/templates/helpers.js | 30 ++- models/campaigns.js | 37 +++- models/templates.js | 2 +- routes/rest/campaigns.js | 2 +- .../20180718220444_upgrade_campaigns.js | 6 + 10 files changed, 231 insertions(+), 81 deletions(-) diff --git a/client/src/campaigns/CUD.js b/client/src/campaigns/CUD.js index 3216a3d4..82e4a82f 100644 --- a/client/src/campaigns/CUD.js +++ b/client/src/campaigns/CUD.js @@ -2,10 +2,7 @@ import React, {Component} from 'react'; import PropTypes from 'prop-types'; -import { - Trans, - translate -} from 'react-i18next'; +import {translate} from 'react-i18next'; import { NavButton, requiresAuthenticatedUser, @@ -13,7 +10,6 @@ import { withPageHelpers } from '../lib/page' import { - ACEEditor, AlignedRow, Button, ButtonRow, @@ -42,14 +38,18 @@ import { getTemplateTypes, getTypeForm } from '../templates/helpers'; -import {ActionLink} from "../lib/bootstrap-components"; import axios from '../lib/axios'; import styles from "../lib/styles.scss"; import {getUrl} from "../lib/urls"; -import {CampaignType, CampaignSource} from "../../../shared/campaigns"; +import { + CampaignSource, + CampaignType +} from "../../../shared/campaigns"; import moment from 'moment'; import {getMailerTypes} from "../send-configurations/helpers"; +import {ResourceType} from "../lib/mosaico"; +const overridables = ['from_name', 'from_email', 'reply_to', 'subject']; @translate() @withForm @@ -60,12 +60,44 @@ export default class CUD extends Component { constructor(props) { super(props); - this.templateTypes = getTemplateTypes(props.t, 'data_sourceCustom_'); + const t = props.t; + + this.templateTypes = getTemplateTypes(props.t, 'data_sourceCustom_', ResourceType.CAMPAIGN); this.mailerTypes = getMailerTypes(props.t); + this.createTitles = { + [CampaignType.REGULAR]: t('Create Regular Campaign'), + [CampaignType.RSS]: t('Create RSS Campaign'), + [CampaignType.TRIGGERED]: t('Create Triggered Campaign'), + }; + + this.editTitles = { + [CampaignType.REGULAR]: t('Edit Regular Campaign'), + [CampaignType.RSS]: t('Edit RSS Campaign'), + [CampaignType.TRIGGERED]: t('Edit Triggered Campaign'), + }; + + this.sourceLabels = { + [CampaignSource.TEMPLATE]: t('Template'), + [CampaignSource.CUSTOM_FROM_TEMPLATE]: t('Custom content'), + [CampaignSource.CUSTOM]: t('Custom content'), + [CampaignSource.URL]: t('URL') + }; + + this.sourceOptions = []; + for (const key in this.sourceLabels) { + this.sourceOptions.push({key, label: this.sourceLabels[key]}); + } + + this.customTemplateTypeOptions = []; + for (const key of mailtrainConfig.editors) { + this.customTemplateTypeOptions.push({key, label: this.templateTypes[key].typeName}); + } + this.state = { showMergeTagReference: false, elementInFullscreen: false, + sendConfiguration: null }; this.initForm({ @@ -82,7 +114,7 @@ export default class CUD extends Component { action: PropTypes.string.isRequired, wizard: PropTypes.string, entity: PropTypes.object, - type: PropTypes.number.isRequired + type: PropTypes.number } onCustomTemplateTypeChanged(mutState, key, oldType, type) { @@ -91,6 +123,24 @@ export default class CUD extends Component { } } + onSendConfigurationChanged(newState, key, oldValue, sendConfigurationId) { + newState.sendConfiguration = null; + this.fetchSendConfiguration(sendConfigurationId); + } + + @withAsyncErrorHandler + async fetchSendConfiguration(sendConfigurationId) { + this.fetchSendConfigurationId = sendConfigurationId; + + const result = await axios.get(getUrl(`rest/send-configurations-public/${sendConfigurationId}`)); + + if (sendConfigurationId === this.fetchSendConfigurationId) { + this.setState({ + sendConfiguration: result.data + }); + } + } + componentDidMount() { if (this.props.entity) { this.getFormValuesFromEntity(this.props.entity, data => { @@ -101,12 +151,12 @@ export default class CUD extends Component { } if (data.source === CampaignSource.CUSTOM || data.source === CampaignSource.CUSTOM_FROM_TEMPLATE) { - data.data_sourceCustom_type = data.data.source.type; - data.data_sourceCustom_data = data.data.source.data; - data.data_sourceCustom_html = data.data.source.html; - data.data_sourceCustom_text = data.data.source.text; + 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.type].afterLoad(data); + this.templateTypes[data.data.sourceCustom.type].afterLoad(data); } else { data.data_sourceCustom_type = null; @@ -128,12 +178,24 @@ export default class CUD extends Component { } data.useSegmentation = !!data.segment; - + + for (const overridable of overridables) { + data[overridable + '_overriden'] = !!data[overridable + '_override']; + } + this.fetchSendConfiguration(data.send_configuration); }); } else { + const data = {}; + for (const overridable of overridables) { + data[overridable + '_override'] = ''; + data[overridable + '_overriden'] = false; + } + this.populateFormValues({ + ...data, + type: this.props.type, name: '', @@ -143,14 +205,7 @@ export default class CUD extends Component { useSegmentation: false, send_configuration: null, namespace: mailtrainConfig.user.namespace, - from_name_override: '', - from_name_overriden: false, - from_email_override: '', - from_email_overriden: false, - reply_to_override: '', - reply_to_overriden: false, - subject_override: '', - subject_overriden: false, + click_tracking_disabled: false, open_trackings_disabled: false, @@ -285,7 +340,7 @@ export default class CUD extends Component { if (data.source === CampaignSource.CUSTOM || data.source === CampaignSource.CUSTOM_FROM_TEMPLATE) { this.templateTypes[data.data_sourceCustom_type].beforeSave(data); - data.data.source = { + data.data.sourceCustom = { type: data.data_sourceCustom_type, data: data.data_sourceCustom_data, html: data.data_sourceCustom_html, @@ -301,6 +356,13 @@ export default class CUD extends Component { data.data.feedUrl = data.data_feedUrl; } + for (const overridable of overridables) { + if (!data[overridable + '_overriden']) { + data[overridable + '_override'] = null; + } + delete data[overridable + '_overriden']; + } + for (const key in data) { if (key.startsWith('data_')) { delete data[key]; @@ -335,6 +397,8 @@ export default class CUD extends Component { this.disableForm(); + console.log(html); + const response = await axios.post(getUrl('rest/html-to-text', { html })); this.updateFormValue('data_sourceCustom_text', response.data.text); @@ -358,7 +422,6 @@ export default class CUD extends Component { const t = this.props.t; const isEdit = !!this.props.entity; const canDelete = isEdit && this.props.entity.permissions.includes('delete'); - const useSaveAndEditLabel = !isEdit; let templateEdit = null; let extraSettings = null; @@ -366,6 +429,15 @@ export default class CUD extends Component { const sourceTypeKey = this.getFormValue('source'); const campaignTypeKey = this.getFormValue('type'); + + let sourceEdit; + if (isEdit) { + sourceEdit = {this.sourceLabels[sourceTypeKey]}; + } else { + sourceEdit = + } + + if (sourceTypeKey === CampaignSource.TEMPLATE || (!isEdit && sourceTypeKey === CampaignSource.CUSTOM_FROM_TEMPLATE)) { const templatesColumns = [ { data: 1, title: t('Name') }, @@ -375,14 +447,14 @@ export default class CUD extends Component { { data: 5, title: t('Namespace') }, ]; - templateEdit = ; - - } else if (sourceTypeKey === CampaignSource.CUSTOM || (isEdit && sourceTypeKey === CampaignSource.CUSTOM_FROM_TEMPLATE)) { - const customTemplateTypeOptions = []; - for (const key of mailtrainConfig.editors) { - customTemplateTypeOptions.push({key, label: this.templateTypes[key].typeName}); + let help = null; + if (sourceTypeKey === CampaignSource.CUSTOM_FROM_TEMPLATE) { + help = t('Selecting a template creates a campaign specific copy from it.'); } + templateEdit = ; + + } else if (sourceTypeKey === CampaignSource.CUSTOM || (isEdit && sourceTypeKey === CampaignSource.CUSTOM_FROM_TEMPLATE)) { // TODO: Toggle HTML preview const customTemplateTypeKey = this.getFormValue('data_sourceCustom_type'); @@ -401,11 +473,11 @@ export default class CUD extends Component { templateEdit =
{isEdit ? - + {customTemplateTypeKey && this.templateTypes[customTemplateTypeKey].typeName} : - + } {customTemplateTypeForm} @@ -414,7 +486,7 @@ export default class CUD extends Component {
; } else if (sourceTypeKey === CampaignSource.URL) { - templateEdit = + templateEdit = } if (campaignTypeKey === CampaignType.RSS) { @@ -442,6 +514,37 @@ export default class CUD extends Component { { data: 5, title: t('Namespace') } ]; + let sendSettings; + if (this.getFormValue('send_configuration')) { + if (this.state.sendConfiguration) { + sendSettings = []; + + const addOverridable = (id, label) => { + sendSettings.push(); + + if (this.getFormValue(id + '_overriden')) { + sendSettings.push(); + } else { + sendSettings.push( + + {this.state.sendConfiguration[id]} + + ); + } + }; + + addOverridable('from_name', t('"From" name')); + addOverridable('from_email', t('"From" email address')); + addOverridable('reply_to', t('"Reply-to" email address')); + addOverridable('subject', t('"Subject" line')); + } else { + sendSettings = {t('Loading send configuration ...')} + } + } else { + sendSettings = null; + } + + return (
{canDelete && @@ -455,41 +558,40 @@ export default class CUD extends Component { deletedMsg={t('Campaign deleted')}/> } - {isEdit ? t('Edit Campaign') : t('Create Campaign')} + {isEdit ? this.editTitles[this.getFormValue('type')] : this.createTitles[this.getFormValue('type')]}