work in progress on campaign edit

This commit is contained in:
Tomas Bures 2018-08-01 15:30:20 +05:30
parent 0e0fb944e3
commit ade0fc87f2
10 changed files with 231 additions and 81 deletions

View file

@ -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 = <StaticField id="source" className={styles.formDisabled} label={t('Content source')}>{this.sourceLabels[sourceTypeKey]}</StaticField>;
} else {
sourceEdit = <Dropdown id="source" label={t('Content source')} options={this.sourceOptions}/>
}
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 = <TableSelect id="data_sourceTemplate" label={t('Template')} withHeader dropdown dataUrl='rest/templates-table' columns={templatesColumns} selectionLabelIndex={1} />;
} 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 = <TableSelect id="data_sourceTemplate" label={t('Template')} withHeader dropdown dataUrl='rest/templates-table' columns={templatesColumns} selectionLabelIndex={1} help={help}/>;
} 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 = <div>
{isEdit
?
<StaticField id="data_sourceCustom_type" className={styles.formDisabled} label={t('Type')}>
<StaticField id="data_sourceCustom_type" className={styles.formDisabled} label={t('Custom template editor')}>
{customTemplateTypeKey && this.templateTypes[customTemplateTypeKey].typeName}
</StaticField>
:
<Dropdown id="data_sourceCustom_type" label={t('Type')} options={customTemplateTypeOptions}/>
<Dropdown id="data_sourceCustom_type" label={t('Type')} options={this.customTemplateTypeOptions}/>
}
{customTemplateTypeForm}
@ -414,7 +486,7 @@ export default class CUD extends Component {
</div>;
} else if (sourceTypeKey === CampaignSource.URL) {
templateEdit = <InputField id="data_sourceUrl" label={t('Render URL')}/>
templateEdit = <InputField id="data_sourceUrl" label={t('Render URL')} help={t('If a message is sent then this URL will be POSTed to using Merge Tags as POST body. Use this if you want to generate the HTML message yourself.')}/>
}
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(<CheckBox key={id + '_overriden'} id={id + '_overriden'} label={label} text={t('Override')}/>);
if (this.getFormValue(id + '_overriden')) {
sendSettings.push(<InputField key={id + '_override'} id={id + '_override'}/>);
} else {
sendSettings.push(
<StaticField key={id + '_original'} id={id + '_original'} className={styles.formDisabled}>
{this.state.sendConfiguration[id]}
</StaticField>
);
}
};
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 = <AlignedRow>{t('Loading send configuration ...')}</AlignedRow>
}
} else {
sendSettings = null;
}
return (
<div className={this.state.elementInFullscreen ? styles.withElementInFullscreen : ''}>
{canDelete &&
@ -455,41 +558,40 @@ export default class CUD extends Component {
deletedMsg={t('Campaign deleted')}/>
}
<Title>{isEdit ? t('Edit Campaign') : t('Create Campaign')}</Title>
<Title>{isEdit ? this.editTitles[this.getFormValue('type')] : this.createTitles[this.getFormValue('type')]}</Title>
<Form stateOwner={this} onSubmitAsync={::this.submitHandler}>
<InputField id="name" label={t('Name')}/>
<TextArea id="description" label={t('Description')}/>
<TableSelect id="list" label={t('List')} withHeader dropdown dataUrl='rest/lists-table' columns={listsColumns} selectionLabelIndex={1} />
<CheckBox id="useSegmentation" text={t('Use segmentation')}/>
{this.getFormValue('useSegmentation') &&
<TableSelect id="segment" label={t('Segment')} withHeader dropdown dataUrl='rest/segments-table' columns={segmentsColumns} selectionLabelIndex={1} />
}
{extraSettings}
<NamespaceSelect/>
<hr/>
<TableSelect id="list" label={t('List')} withHeader dropdown dataUrl='rest/lists-table' columns={listsColumns} selectionLabelIndex={1} />
<CheckBox id="useSegmentation" label={t('Segment')} text={t('Use a particular segment')}/>
{this.getFormValue('useSegmentation') &&
<TableSelect id="segment" withHeader dropdown dataUrl={`rest/segments-table/${this.getFormValue('list')}`} columns={segmentsColumns} selectionLabelIndex={1} />
}
<hr/>
<TableSelect id="send_configuration" label={t('Send configuration')} withHeader dropdown dataUrl='rest/send-configurations-table' columns={sendConfigurationsColumns} selectionLabelIndex={1} />
<CheckBox id="from_name_overriden" text={t('Override email "From" name')}/>
{ this.getFormValue('from_name_overriden') && <InputField id="from_name_override" label={t('Email "From" name')}/> }
<CheckBox id="from_email_overriden" text={t('Override email "From" address')}/>
{ this.getFormValue('from_email_overriden') && <InputField id="from_email_override" label={t('Email "From" address')}/> }
<CheckBox id="reply_to_overriden" text={t('Override email "Reply-to" address')}/>
{ this.getFormValue('reply_to_overriden') && <InputField id="reply_to_override" label={t('Email "Reply-to" address')}/> }
<CheckBox id="subject_overriden" text={t('Override email "Subject" line')}/>
{ this.getFormValue('subject_overriden') && <InputField id="subject_override" label={t('Email "Subject" line')}/> }
{sendSettings}
<hr/>
<CheckBox id="open_trackings_disabled" text={t('Disable opened tracking')}/>
<CheckBox id="click_tracking_disabled" text={t('Disable clicked tracking')}/>
<hr/>
{sourceEdit}
{templateEdit}
<ButtonRow>