2016-04-12 10:24:16 +12:00
|
|
|
import React from 'react';
|
|
|
|
import { bindActionCreators } from 'redux';
|
|
|
|
import { connect } from 'react-redux';
|
2016-04-12 09:15:04 +12:00
|
|
|
import * as recordActions from 'state/records/actions';
|
|
|
|
import * as campaignActions from 'state/campaign/actions';
|
2016-04-12 10:24:16 +12:00
|
|
|
import SilverStripeComponent from 'silverstripe-component';
|
|
|
|
import Accordion from 'components/accordion/index';
|
|
|
|
import AccordionGroup from 'components/accordion/group';
|
|
|
|
import AccordionItem from 'components/accordion/item';
|
|
|
|
import NorthHeader from 'components/north-header/index';
|
2016-04-12 09:15:04 +12:00
|
|
|
import FormAction from 'components/form-action/index';
|
2016-04-12 10:24:16 +12:00
|
|
|
import CampaignItem from './item';
|
|
|
|
import CampaignPreview from './preview';
|
2016-04-12 09:15:04 +12:00
|
|
|
import i18n from 'i18n';
|
2016-04-12 10:24:16 +12:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Represents a campaign list view
|
|
|
|
*/
|
|
|
|
class CampaignListContainer extends SilverStripeComponent {
|
|
|
|
|
2016-04-12 09:15:04 +12:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
this.handlePublish = this.handlePublish.bind(this);
|
|
|
|
}
|
|
|
|
|
2016-04-12 10:24:16 +12:00
|
|
|
componentDidMount() {
|
|
|
|
const fetchURL = this.props.itemListViewEndpoint.replace(/:id/, this.props.campaignId);
|
|
|
|
super.componentDidMount();
|
2016-04-12 09:15:04 +12:00
|
|
|
this.props.recordActions.fetchRecord('ChangeSet', 'get', fetchURL);
|
2016-04-12 10:24:16 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Renders a list of items in a Campaign.
|
|
|
|
*
|
|
|
|
* @return object
|
|
|
|
*/
|
|
|
|
render() {
|
|
|
|
const itemID = 1; // todo - hook up to "click" handler for changesetitems
|
|
|
|
const campaignId = this.props.campaignId;
|
|
|
|
|
|
|
|
// Trigger different layout when preview is enabled
|
|
|
|
const previewUrl = this.previewURLForItem(itemID);
|
|
|
|
const itemGroups = this.groupItemsForSet();
|
|
|
|
const classNames = previewUrl ? 'cms-middle with-preview' : 'cms-middle no-preview';
|
|
|
|
|
|
|
|
// Get items in this set
|
|
|
|
let accordionGroups = [];
|
|
|
|
|
|
|
|
Object.keys(itemGroups).forEach(className => {
|
|
|
|
const group = itemGroups[className];
|
|
|
|
const groupCount = group.items.length;
|
|
|
|
|
|
|
|
let accordionItems = [];
|
|
|
|
let title = `${groupCount} ${groupCount === 1 ? group.singular : group.plural}`;
|
|
|
|
let groupid = `Set_${campaignId}_Group_${className}`;
|
|
|
|
|
|
|
|
// Create items for this group
|
|
|
|
group.items.forEach(item => {
|
|
|
|
// Add extra css class for published items
|
|
|
|
let itemClassName = '';
|
|
|
|
|
|
|
|
if (item.ChangeType === 'none') {
|
|
|
|
itemClassName = 'list-group-item--published';
|
|
|
|
}
|
|
|
|
|
|
|
|
accordionItems.push(
|
|
|
|
<AccordionItem key={item.ID} className={itemClassName}>
|
|
|
|
<CampaignItem item={item} />
|
|
|
|
</AccordionItem>
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
// Merge into group
|
|
|
|
accordionGroups.push(
|
|
|
|
<AccordionGroup key={groupid} groupid={groupid} title={title}>
|
|
|
|
{accordionItems}
|
|
|
|
</AccordionGroup>
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className={classNames}>
|
|
|
|
<div className="cms-campaigns collapse in" aria-expanded="true">
|
|
|
|
<NorthHeader />
|
|
|
|
<div className="col-md-12 campaign-items">
|
|
|
|
<Accordion>
|
|
|
|
{accordionGroups}
|
|
|
|
</Accordion>
|
|
|
|
</div>
|
2016-04-12 09:15:04 +12:00
|
|
|
<div className="cms-south-actions">
|
|
|
|
{this.renderButtonToolbar()}
|
|
|
|
</div>
|
2016-04-12 10:24:16 +12:00
|
|
|
</div>
|
|
|
|
{ previewUrl && <CampaignPreview previewUrl={previewUrl} /> }
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-04-12 09:15:04 +12:00
|
|
|
renderButtonToolbar() {
|
|
|
|
const items = this.getItems(this.props.campaignId);
|
|
|
|
|
|
|
|
let itemSummaryLabel;
|
|
|
|
if (items) {
|
|
|
|
itemSummaryLabel = i18n.sprintf(
|
|
|
|
(items.length === 1) ?
|
|
|
|
i18n._t('Campaigns.ITEM_SUMMARY_SINGULAR')
|
|
|
|
: i18n._t('Campaigns.ITEM_SUMMARY_PLURAL'),
|
|
|
|
items.length
|
|
|
|
);
|
|
|
|
|
|
|
|
let button;
|
|
|
|
if (this.props.record.State === 'open') {
|
|
|
|
button = (
|
|
|
|
<FormAction
|
|
|
|
label={i18n._t('Campaigns.PUBLISHCAMPAIGN')}
|
|
|
|
style={'success'}
|
|
|
|
handleClick={this.handlePublish}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
} else if (this.props.record.State === 'published') {
|
|
|
|
// TODO Implement "revert" feature
|
|
|
|
button = (
|
|
|
|
<FormAction
|
|
|
|
label={i18n._t('Campaigns.PUBLISHCAMPAIGN')}
|
|
|
|
style={'success'}
|
|
|
|
disabled
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className="btn-toolbar">
|
|
|
|
{button}
|
|
|
|
<span className="text-muted">
|
|
|
|
<span className="label label-warning label--empty"> </span>
|
|
|
|
{itemSummaryLabel}
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return <div className="btn-toolbar"></div>;
|
|
|
|
}
|
2016-04-12 10:24:16 +12:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets preview URL for itemid
|
|
|
|
* @param int id
|
|
|
|
* @returns string
|
|
|
|
*/
|
|
|
|
previewURLForItem(id) {
|
|
|
|
if (!id) {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
|
|
|
// hard code in baseurl for any itemid preview url
|
|
|
|
return document.getElementsByTagName('base')[0].href;
|
|
|
|
}
|
|
|
|
|
2016-04-12 09:15:04 +12:00
|
|
|
/**
|
|
|
|
* @return {Array}
|
|
|
|
*/
|
|
|
|
getItems() {
|
|
|
|
if (this.props.record && this.props.record._embedded) {
|
|
|
|
return this.props.record._embedded.ChangeSetItems;
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-04-12 10:24:16 +12:00
|
|
|
/**
|
|
|
|
* Group items for changeset display
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
groupItemsForSet() {
|
|
|
|
const groups = {};
|
2016-04-12 09:15:04 +12:00
|
|
|
const items = this.getItems();
|
|
|
|
if (!items) {
|
2016-04-12 10:24:16 +12:00
|
|
|
return groups;
|
|
|
|
}
|
|
|
|
|
|
|
|
// group by whatever
|
|
|
|
items.forEach(item => {
|
|
|
|
// Create new group if needed
|
|
|
|
const classname = item.BaseClass;
|
|
|
|
|
|
|
|
if (!groups[classname]) {
|
|
|
|
groups[classname] = {
|
|
|
|
singular: item.Singular,
|
|
|
|
plural: item.Plural,
|
|
|
|
items: [],
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
// Push items
|
|
|
|
groups[classname].items.push(item);
|
|
|
|
});
|
|
|
|
|
|
|
|
return groups;
|
|
|
|
}
|
|
|
|
|
2016-04-12 09:15:04 +12:00
|
|
|
handlePublish(e) {
|
|
|
|
e.preventDefault();
|
|
|
|
this.props.campaignActions.publishCampaign(
|
|
|
|
this.props.publishApi,
|
|
|
|
this.props.campaignId
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-04-12 10:24:16 +12:00
|
|
|
}
|
|
|
|
|
2016-04-12 09:15:04 +12:00
|
|
|
CampaignListContainer.propTypes = {
|
|
|
|
publishApi: React.PropTypes.func.isRequired,
|
|
|
|
};
|
|
|
|
|
2016-04-12 10:24:16 +12:00
|
|
|
function mapStateToProps(state, ownProps) {
|
|
|
|
// Find record specific to this item
|
|
|
|
let record = null;
|
|
|
|
if (state.records && state.records.ChangeSet && ownProps.campaignId) {
|
2016-04-13 10:12:14 +12:00
|
|
|
record = state.records.ChangeSet[parseInt(ownProps.campaignId, 10)];
|
2016-04-12 10:24:16 +12:00
|
|
|
}
|
|
|
|
return {
|
|
|
|
record: record || [],
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function mapDispatchToProps(dispatch) {
|
|
|
|
return {
|
2016-04-12 09:15:04 +12:00
|
|
|
recordActions: bindActionCreators(recordActions, dispatch),
|
|
|
|
campaignActions: bindActionCreators(campaignActions, dispatch),
|
2016-04-12 10:24:16 +12:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(CampaignListContainer);
|