Refactor campaign 'save' button and add 'start' button to campaign page
This commit is contained in:
parent
ca19b50126
commit
ccd966a1f4
|
@ -199,8 +199,16 @@ class TheFormDef extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle create / edit form submission.
|
// Handle create / edit form submission.
|
||||||
handleSubmit = (e) => {
|
handleSubmit = (cb) => {
|
||||||
e.preventDefault()
|
if(this.state.loading) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!cb) {
|
||||||
|
// Set a fake callback.
|
||||||
|
cb = () => {}
|
||||||
|
}
|
||||||
|
|
||||||
this.props.form.validateFields((err, values) => {
|
this.props.form.validateFields((err, values) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return
|
return
|
||||||
|
@ -209,7 +217,7 @@ class TheFormDef extends React.PureComponent {
|
||||||
if(!values.tags) {
|
if(!values.tags) {
|
||||||
values.tags = []
|
values.tags = []
|
||||||
}
|
}
|
||||||
|
|
||||||
values.body = this.props.body
|
values.body = this.props.body
|
||||||
values.content_type = this.props.contentType
|
values.content_type = this.props.contentType
|
||||||
|
|
||||||
|
@ -222,9 +230,11 @@ class TheFormDef extends React.PureComponent {
|
||||||
description: `"${values["name"]}" created` })
|
description: `"${values["name"]}" created` })
|
||||||
|
|
||||||
this.props.route.history.push(cs.Routes.ViewCampaign.replace(":id", resp.data.data.id) + "#content")
|
this.props.route.history.push(cs.Routes.ViewCampaign.replace(":id", resp.data.data.id) + "#content")
|
||||||
|
cb(true)
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
notification["error"]({ placement: cs.MsgPosition, message: "Error", description: e.message })
|
notification["error"]({ placement: cs.MsgPosition, message: "Error", description: e.message })
|
||||||
this.setState({ loading: false })
|
this.setState({ loading: false })
|
||||||
|
cb(false)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.props.modelRequest(cs.ModelCampaigns, cs.Routes.UpdateCampaign, cs.MethodPut, { ...values, id: this.props.record.id }).then((resp) => {
|
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",
|
message: "Campaign updated",
|
||||||
description: `"${values["name"]}" updated` })
|
description: `"${values["name"]}" updated` })
|
||||||
this.setState({ loading: false })
|
this.setState({ loading: false })
|
||||||
|
cb(true)
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
notification["error"]({ placement: cs.MsgPosition, message: "Error", description: e.message })
|
notification["error"]({ placement: cs.MsgPosition, message: "Error", description: e.message })
|
||||||
this.setState({ loading: false })
|
this.setState({ loading: false })
|
||||||
|
cb(false)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -370,14 +382,6 @@ class TheFormDef extends React.PureComponent {
|
||||||
</Row>
|
</Row>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
{ !this.props.formDisabled &&
|
|
||||||
<Form.Item {...formItemTailLayout}>
|
|
||||||
<Button htmlType="submit" type="primary">
|
|
||||||
<Icon type="save" /> { !this.props.isSingle ? "Continue" : "Save changes" }
|
|
||||||
</Button>
|
|
||||||
</Form.Item>
|
|
||||||
}
|
|
||||||
|
|
||||||
{ this.props.isSingle &&
|
{ this.props.isSingle &&
|
||||||
<div>
|
<div>
|
||||||
<hr />
|
<hr />
|
||||||
|
@ -405,6 +409,7 @@ class Campaign extends React.PureComponent {
|
||||||
state = {
|
state = {
|
||||||
campaignID: this.props.route.match.params ? parseInt(this.props.route.match.params.campaignID, 10) : 0,
|
campaignID: this.props.route.match.params ? parseInt(this.props.route.match.params.campaignID, 10) : 0,
|
||||||
record: {},
|
record: {},
|
||||||
|
formRef: null,
|
||||||
contentType: "richtext",
|
contentType: "richtext",
|
||||||
previewRecord: null,
|
previewRecord: null,
|
||||||
body: "",
|
body: "",
|
||||||
|
@ -470,7 +475,7 @@ class Campaign extends React.PureComponent {
|
||||||
return (
|
return (
|
||||||
<section className="content campaign">
|
<section className="content campaign">
|
||||||
<Row>
|
<Row>
|
||||||
<Col span={22}>
|
<Col span={ 16 }>
|
||||||
{ !this.state.record.id && <h1>Create a campaign</h1> }
|
{ !this.state.record.id && <h1>Create a campaign</h1> }
|
||||||
{ this.state.record.id &&
|
{ this.state.record.id &&
|
||||||
<h1>
|
<h1>
|
||||||
|
@ -479,7 +484,43 @@ class Campaign extends React.PureComponent {
|
||||||
</h1>
|
</h1>
|
||||||
}
|
}
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={2}>
|
<Col span={ 8 } className="right">
|
||||||
|
{ !this.state.formDisabled && !this.state.loading &&
|
||||||
|
<div>
|
||||||
|
<Button type="primary" icon="save" onClick={() => {
|
||||||
|
this.state.formRef.handleSubmit()
|
||||||
|
}}>{ !this.state.record.id ? "Continue" : "Save changes" }</Button>
|
||||||
|
{" "}
|
||||||
|
|
||||||
|
{ ( this.state.record.status === cs.CampaignStatusDraft && this.state.record.send_at) &&
|
||||||
|
<Popconfirm title="The campaign will start automatically at the scheduled date and time. Schedule now?"
|
||||||
|
onConfirm={() => {
|
||||||
|
this.state.formRef.handleSubmit(() => {
|
||||||
|
this.props.route.history.push({
|
||||||
|
pathname: cs.Routes.ViewCampaigns,
|
||||||
|
state: { campaign: this.state.record, campaignStatus: cs.CampaignStatusScheduled }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}}>
|
||||||
|
<Button icon="clock-circle" type="primary">Schedule campaign</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
}
|
||||||
|
|
||||||
|
{ ( this.state.record.status === cs.CampaignStatusDraft && !this.state.record.send_at) &&
|
||||||
|
<Popconfirm title="Campaign properties cannot be changed once it starts. Save changes and start now?"
|
||||||
|
onConfirm={() => {
|
||||||
|
this.state.formRef.handleSubmit(() => {
|
||||||
|
this.props.route.history.push({
|
||||||
|
pathname: cs.Routes.ViewCampaigns,
|
||||||
|
state: { campaign: this.state.record, campaignStatus: cs.CampaignStatusRunning }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}}>
|
||||||
|
<Button icon="rocket" type="primary">Start campaign</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<br />
|
<br />
|
||||||
|
@ -492,6 +533,14 @@ class Campaign extends React.PureComponent {
|
||||||
<Tabs.TabPane tab="Campaign" key="form">
|
<Tabs.TabPane tab="Campaign" key="form">
|
||||||
<Spin spinning={ this.state.loading }>
|
<Spin spinning={ this.state.loading }>
|
||||||
<TheForm { ...this.props }
|
<TheForm { ...this.props }
|
||||||
|
wrappedComponentRef={ (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 <Media />
|
||||||
|
this.setState({ formRef: r })
|
||||||
|
}}
|
||||||
record={ this.state.record }
|
record={ this.state.record }
|
||||||
isSingle={ this.state.record.id ? true : false }
|
isSingle={ this.state.record.id ? true : false }
|
||||||
body={ this.state.body ? this.state.body : this.state.record.body }
|
body={ this.state.body ? this.state.body : this.state.record.body }
|
||||||
|
@ -506,10 +555,13 @@ class Campaign extends React.PureComponent {
|
||||||
{ this.state.record.id &&
|
{ this.state.record.id &&
|
||||||
<div>
|
<div>
|
||||||
<Editor { ...this.props }
|
<Editor { ...this.props }
|
||||||
ref={ (e) => {
|
ref={ (r) => {
|
||||||
|
if(!r) {
|
||||||
|
return
|
||||||
|
}
|
||||||
// Take the editor's reference and save it in the state
|
// Take the editor's reference and save it in the state
|
||||||
// so that it's insertMedia() function can be passed to <Media />
|
// so that it's insertMedia() function can be passed to <Media />
|
||||||
this.setState({ editor: e })
|
this.setState({ editor: r })
|
||||||
}}
|
}}
|
||||||
isSingle={ this.state.record.id ? true : false }
|
isSingle={ this.state.record.id ? true : false }
|
||||||
record={ this.state.record }
|
record={ this.state.record }
|
||||||
|
@ -517,9 +569,11 @@ class Campaign extends React.PureComponent {
|
||||||
toggleMedia={ this.toggleMedia }
|
toggleMedia={ this.toggleMedia }
|
||||||
setContent={ this.setContent }
|
setContent={ this.setContent }
|
||||||
formDisabled={ this.state.formDisabled }
|
formDisabled={ this.state.formDisabled }
|
||||||
/>
|
/>
|
||||||
<div className="content-actions">
|
<div className="content-actions">
|
||||||
<p><Button icon="search" onClick={() => this.handlePreview(this.state.record)}>Preview</Button></p>
|
<p>
|
||||||
|
<Button icon="search" onClick={() => this.handlePreview(this.state.record)}>Preview</Button>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@ -535,9 +589,9 @@ class Campaign extends React.PureComponent {
|
||||||
onCancel={ this.toggleMedia }
|
onCancel={ this.toggleMedia }
|
||||||
onOk={ this.toggleMedia }>
|
onOk={ this.toggleMedia }>
|
||||||
<Media { ...{ ...this.props,
|
<Media { ...{ ...this.props,
|
||||||
insertMedia: this.state.editor ? this.state.editor.insertMedia : null,
|
insertMedia: this.state.editor ? this.state.editor.insertMedia : null,
|
||||||
onCancel: this.toggleMedia,
|
onCancel: this.toggleMedia,
|
||||||
onOk: this.toggleMedia }} />
|
onOk: this.toggleMedia }} />
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
{ this.state.previewRecord &&
|
{ this.state.previewRecord &&
|
||||||
|
|
|
@ -251,6 +251,16 @@ class Campaigns extends React.PureComponent {
|
||||||
this.props.pageTitle("Campaigns")
|
this.props.pageTitle("Campaigns")
|
||||||
dayjs.extend(relativeTime)
|
dayjs.extend(relativeTime)
|
||||||
this.fetchRecords()
|
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() {
|
componentWillUnmount() {
|
||||||
|
|
|
@ -69,6 +69,7 @@ export const Routes = {
|
||||||
DeleteSubscribers: "/api/subscribers",
|
DeleteSubscribers: "/api/subscribers",
|
||||||
QuerySubscribersIntoLists: "/api/subscribers/lists",
|
QuerySubscribersIntoLists: "/api/subscribers/lists",
|
||||||
|
|
||||||
|
ViewCampaigns: "/campaigns",
|
||||||
ViewCampaign: "/campaigns/:id",
|
ViewCampaign: "/campaigns/:id",
|
||||||
GetCampaignMessengers: "/api/campaigns/messengers",
|
GetCampaignMessengers: "/api/campaigns/messengers",
|
||||||
GetCampaigns: "/api/campaigns",
|
GetCampaigns: "/api/campaigns",
|
||||||
|
|
|
@ -24,6 +24,10 @@ hr {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
.text-tiny {
|
.text-tiny {
|
||||||
font-size: 0.65em;
|
font-size: 0.65em;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue