public/js/components/CommonsDivisions/CommonsDivision.js (151 lines of code) (raw):
import React from 'react';
import {CommonsDivisionPropType} from '../../actions/ParliamentActions/getLatestCommonsDivisions.js';
import {atomPropType} from '../../constants/atomPropType';
import AtomsApi from '../../services/AtomsApi';
import {commonsDivision} from '../../services/Parliament';
import moment from 'moment';
const StatusTypes = {
DISPLAY: "DISPLAY", //display either "Create atom" button or "Edit atom" link
RETRIEVE_VOTES: "RETRIEVE_VOTES", //getting the vote data from parliament api
CREATE: "CREATE", //creating a new default atom
UPDATE: "UPDATE", //adding the vote data to the atom
ERROR: "ERROR"
};
class CommonsDivision extends React.Component {
static propTypes = {
division: CommonsDivisionPropType,
atom: atomPropType
};
state = {
status: StatusTypes.DISPLAY,
division: this.props.division,
atom: this.props.atom
};
//Order by second name while building up the MP lists.
compareSecondNames = (a, b) => a.split(" ").pop() > b.split(" ").pop();
insertMP(mp, arr, start, end) {
if (start >= end) {
if (arr[start] && this.compareSecondNames(mp.name, arr[start].name)) arr.splice(start+1, 0, mp);
else arr.splice(start, 0, mp);
} else {
const pivot = Math.floor((start + end) / 2);
if (this.compareSecondNames(mp.name, arr[pivot].name)) this.insertMP(mp, arr, pivot+1, end);
else this.insertMP(mp, arr, start, pivot-1);
}
}
cleanPartyName(name) {
switch (name) {
case "Labour (Co-op)":
return "Labour";
default:
return name;
}
}
retrieveVotes(id) {
this.setState(Object.assign({}, this.state, {
status: StatusTypes.RETRIEVE_VOTES
}));
//Add the votes to the division then create an atom
commonsDivision(id).then(data => {
const raw = data.result.primaryTopic;
const parliamentId = raw["_about"].split("/").pop();
const division = {
parliamentId: parliamentId,
date: raw.date["_value"],
title: raw.title,
votes: {
ayes: [],
noes: []
}
};
raw.vote.forEach(vote => {
const type = vote.type.split("#").pop();
const mp = {
name: vote.memberPrinted["_value"],
party: this.cleanPartyName(vote.memberParty)
};
if (type === "AyeVote") this.insertMP(mp, division.votes.ayes, 0, division.votes.ayes.length-1);
else if (type === "NoVote") this.insertMP(mp, division.votes.noes, 0, division.votes.noes.length-1);
});
this.setState(Object.assign({}, this.state, {
division: division,
status: StatusTypes.CREATE
}));
this.createAtom();
});
}
createAtom() {
const id = `division-${this.state.division.parliamentId}`;
AtomsApi.createAtom("commonsdivision", {
title: this.state.division.title,
id: id,
commissioningDesks: []
}).then(res => res.json())
.then(atom => {
this.setState(Object.assign({}, this.state, {
atom: atom,
status: StatusTypes.UPDATE
}));
this.updateAtom();
});
}
updateAtom() {
const date = moment(this.state.division.date, "YYYY-MM-DD", true);
const updatedAtom = Object.assign({}, this.state.atom, {
data: {
commonsDivision: {
parliamentId: this.state.division.parliamentId,
date: date.valueOf(),
votes: this.state.division.votes
}
}
});
AtomsApi.updateAtom(updatedAtom)
.then(res => res.json())
.then(atom => {
this.setState(Object.assign({}, this.state, {
atom: atom,
status: StatusTypes.DISPLAY
}));
});
}
renderAtomLink(atom) {
const workshopUrl = `/atoms/commonsdivision/${atom.id}/edit`;
return (
<a className="atom-list__link" href={workshopUrl}>Edit atom</a>
);
}
renderCreateButton(id) {
return (
<button className="btn" onClick={this.retrieveVotes.bind(this, id)}>Create atom</button>
);
}
/**
* Depending on the current state, the management div may contain:
* 1. 'Create atom' button
* 2. 'Edit atom' link
* 3. A status message indicating progress of atom creation from parliament api data
*/
renderManagement() {
switch (this.state.status) {
case StatusTypes.RETRIEVE_VOTES:
return (<div>Retrieving votes...</div>);
case StatusTypes.CREATE:
return (<div>Creating atom...</div>);
case StatusTypes.UPDATE:
return (<div>Adding votes...</div>);
case StatusTypes.DISPLAY:
return (
<div
className="divisions-action"> {
this.state.atom ? this.renderAtomLink(this.state.atom) : this.renderCreateButton(this.state.division.parliamentId)
}
</div>
);
case StatusTypes.ERROR:
return (<div>Error creating atom</div>);
}
}
render() {
return (
<li className="divisions-list__item" key={this.state.division.parliamentId}>
<div className="divisions-description">{this.state.division.date} - <span className="divisions-list__item__title">{this.state.division.title}</span></div>
{this.renderManagement.bind(this)()}
</li>
);
}
}
export default CommonsDivision;