diff --git a/frontend/my/src/Campaign.js b/frontend/my/src/Campaign.js
index ef990e3..fb4d408 100644
--- a/frontend/my/src/Campaign.js
+++ b/frontend/my/src/Campaign.js
@@ -199,8 +199,16 @@ class TheFormDef extends React.PureComponent {
}
// Handle create / edit form submission.
- handleSubmit = (e) => {
- e.preventDefault()
+ handleSubmit = (cb) => {
+ if(this.state.loading) {
+ return
+ }
+
+ if(!cb) {
+ // Set a fake callback.
+ cb = () => {}
+ }
+
this.props.form.validateFields((err, values) => {
if (err) {
return
@@ -209,7 +217,7 @@ class TheFormDef extends React.PureComponent {
if(!values.tags) {
values.tags = []
}
-
+
values.body = this.props.body
values.content_type = this.props.contentType
@@ -222,9 +230,11 @@ class TheFormDef extends React.PureComponent {
description: `"${values["name"]}" created` })
this.props.route.history.push(cs.Routes.ViewCampaign.replace(":id", resp.data.data.id) + "#content")
+ cb(true)
}).catch(e => {
notification["error"]({ placement: cs.MsgPosition, message: "Error", description: e.message })
this.setState({ loading: false })
+ cb(false)
})
} else {
this.props.modelRequest(cs.ModelCampaigns, cs.Routes.UpdateCampaign, cs.MethodPut, { ...values, id: this.props.record.id }).then((resp) => {
@@ -232,9 +242,11 @@ class TheFormDef extends React.PureComponent {
message: "Campaign updated",
description: `"${values["name"]}" updated` })
this.setState({ loading: false })
+ cb(true)
}).catch(e => {
notification["error"]({ placement: cs.MsgPosition, message: "Error", description: e.message })
this.setState({ loading: false })
+ cb(false)
})
}
})
@@ -370,14 +382,6 @@ class TheFormDef extends React.PureComponent {
- { !this.props.formDisabled &&
-
-
- { !this.props.isSingle ? "Continue" : "Save changes" }
-
-
- }
-
{ this.props.isSingle &&
@@ -405,6 +409,7 @@ class Campaign extends React.PureComponent {
state = {
campaignID: this.props.route.match.params ? parseInt(this.props.route.match.params.campaignID, 10) : 0,
record: {},
+ formRef: null,
contentType: "richtext",
previewRecord: null,
body: "",
@@ -470,7 +475,7 @@ class Campaign extends React.PureComponent {
return (
-
+
{ !this.state.record.id && Create a campaign }
{ this.state.record.id &&
@@ -479,7 +484,43 @@ class Campaign extends React.PureComponent {
}
-
+
+ { !this.state.formDisabled && !this.state.loading &&
+
+
{
+ this.state.formRef.handleSubmit()
+ }}>{ !this.state.record.id ? "Continue" : "Save changes" }
+ {" "}
+
+ { ( this.state.record.status === cs.CampaignStatusDraft && this.state.record.send_at) &&
+
{
+ this.state.formRef.handleSubmit(() => {
+ this.props.route.history.push({
+ pathname: cs.Routes.ViewCampaigns,
+ state: { campaign: this.state.record, campaignStatus: cs.CampaignStatusScheduled }
+ })
+ })
+ }}>
+ Schedule campaign
+
+ }
+
+ { ( this.state.record.status === cs.CampaignStatusDraft && !this.state.record.send_at) &&
+
{
+ this.state.formRef.handleSubmit(() => {
+ this.props.route.history.push({
+ pathname: cs.Routes.ViewCampaigns,
+ state: { campaign: this.state.record, campaignStatus: cs.CampaignStatusRunning }
+ })
+ })
+ }}>
+ Start campaign
+
+ }
+
+ }
@@ -492,6 +533,14 @@ class Campaign extends React.PureComponent {
{
+ if(!r) {
+ return
+ }
+ // Take the editor's reference and save it in the state
+ // so that it's insertMedia() function can be passed to
+ this.setState({ formRef: r })
+ }}
record={ this.state.record }
isSingle={ this.state.record.id ? true : false }
body={ this.state.body ? this.state.body : this.state.record.body }
@@ -506,10 +555,13 @@ class Campaign extends React.PureComponent {
{ this.state.record.id &&
{
+ ref={ (r) => {
+ if(!r) {
+ return
+ }
// Take the editor's reference and save it in the state
// so that it's insertMedia() function can be passed to
- this.setState({ editor: e })
+ this.setState({ editor: r })
}}
isSingle={ this.state.record.id ? true : false }
record={ this.state.record }
@@ -517,9 +569,11 @@ class Campaign extends React.PureComponent {
toggleMedia={ this.toggleMedia }
setContent={ this.setContent }
formDisabled={ this.state.formDisabled }
- />
+ />
-
this.handlePreview(this.state.record)}>Preview
+
+ this.handlePreview(this.state.record)}>Preview
+
}
@@ -535,9 +589,9 @@ class Campaign extends React.PureComponent {
onCancel={ this.toggleMedia }
onOk={ this.toggleMedia }>
+ insertMedia: this.state.editor ? this.state.editor.insertMedia : null,
+ onCancel: this.toggleMedia,
+ onOk: this.toggleMedia }} />
{ this.state.previewRecord &&
diff --git a/frontend/my/src/Campaigns.js b/frontend/my/src/Campaigns.js
index 6ce4508..789c3e2 100644
--- a/frontend/my/src/Campaigns.js
+++ b/frontend/my/src/Campaigns.js
@@ -251,6 +251,16 @@ class Campaigns extends React.PureComponent {
this.props.pageTitle("Campaigns")
dayjs.extend(relativeTime)
this.fetchRecords()
+
+ // Did we land here to start a campaign?
+ let loc = this.props.route.location
+ let state = loc.state
+ if(state && state.hasOwnProperty("campaign")) {
+ this.handleUpdateStatus(state.campaign, state.campaignStatus)
+ delete state.campaign
+ delete state.campaignStatus
+ this.props.route.history.replace({ ...loc, state })
+ }
}
componentWillUnmount() {
diff --git a/frontend/my/src/constants.js b/frontend/my/src/constants.js
index 1430593..23be61e 100644
--- a/frontend/my/src/constants.js
+++ b/frontend/my/src/constants.js
@@ -69,6 +69,7 @@ export const Routes = {
DeleteSubscribers: "/api/subscribers",
QuerySubscribersIntoLists: "/api/subscribers/lists",
+ ViewCampaigns: "/campaigns",
ViewCampaign: "/campaigns/:id",
GetCampaignMessengers: "/api/campaigns/messengers",
GetCampaigns: "/api/campaigns",
diff --git a/frontend/my/src/index.css b/frontend/my/src/index.css
index 49d6664..71da156 100644
--- a/frontend/my/src/index.css
+++ b/frontend/my/src/index.css
@@ -24,6 +24,10 @@ hr {
text-align: center;
}
+.right {
+ text-align: right;
+}
+
.text-tiny {
font-size: 0.65em;
}