-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add coverage dates using API for WCCF feature #3270
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -108,6 +108,12 @@ function ContributionsByState() { | |
'history', | ||
2020 // election year / cycle | ||
]; | ||
// Where to find candidate's coverage dates | ||
this.basePath_candidateCoverageDatesPath = [ | ||
'candidate', | ||
'000', //candidate ID | ||
'totals' | ||
]; | ||
// Where to find the highest-earning candidates: | ||
this.basePath_highestRaising = ['candidates', 'totals']; | ||
// Where to find the list of states: | ||
|
@@ -377,6 +383,87 @@ ContributionsByState.prototype.loadCandidateDetails = function(cand_id) { | |
.catch(function() {}); | ||
}; | ||
|
||
/** | ||
* Format the dates into MM/DD/YYYY format. | ||
* Pads single digits with leading 0. | ||
*/ | ||
ContributionsByState.prototype.formatDate = function(date) { | ||
// Adds one since js month uses zero based index | ||
let month = date.getMonth() + 1; | ||
if (month < 10) { | ||
month = '0' + month; | ||
} | ||
let day = date.getDate(); | ||
if (day < 10) { | ||
day = '0' + day; | ||
} | ||
return month + '/' + day + '/' + date.getFullYear(); | ||
}; | ||
|
||
/** | ||
* Queries the API for the candidate's coverage dates for the currently-selected election | ||
* Called by {@see displayUpdatedData_candidate() } and {@see displayUpdatedData_states() } | ||
*/ | ||
ContributionsByState.prototype.loadCandidateCoverageDates = function() { | ||
let instance = this; | ||
this.basePath_candidateCoverageDatesPath[1] = this.candidateDetails.candidate_id; | ||
|
||
let coverageDatesQuery = Object.assign( | ||
{}, | ||
{ | ||
per_page: 100, | ||
cycle: this.baseStatesQuery.cycle, | ||
election_full: true | ||
} | ||
); | ||
|
||
let theFetchUrl = buildUrl( | ||
instance.basePath_candidateCoverageDatesPath, | ||
coverageDatesQuery | ||
); | ||
|
||
window | ||
.fetch(theFetchUrl, instance.fetchInitObj) | ||
.then(function(response) { | ||
if (response.status !== 200) | ||
throw new Error('The network rejected the states request.'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I saw this the other day. I missed all of them. ...could you update the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks @rfultz, I've updated the comments for this, can you take a look to see if it's more accurate now? |
||
// else if (response.type == 'cors') throw new Error('CORS error'); | ||
response.json().then(data => { | ||
if (data.results.length === 1) { | ||
document | ||
.querySelector('.states-table-timestamp') | ||
.removeAttribute('style'); | ||
// Parse coverage date from API that is formatted like this: 2019-06-30T00:00:00+00:00 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I love comments that explain what we get back from somewhere else |
||
// into a string without timezone | ||
let coverage_start_date = new Date( | ||
data.results[0].coverage_start_date.substring(0, 19) | ||
); | ||
let coverage_end_date = new Date( | ||
data.results[0].coverage_end_date.substring(0, 19) | ||
); | ||
|
||
// Remember the in-page elements | ||
let theStartTimeElement = document.querySelector( | ||
'.js-cycle-start-time' | ||
); | ||
let theEndTimeElement = document.querySelector('.js-cycle-end-time'); | ||
// Format the date and put it into the start time | ||
theStartTimeElement.innerText = instance.formatDate( | ||
coverage_start_date | ||
); | ||
// Format the date and put it into the end time | ||
theEndTimeElement.innerText = instance.formatDate(coverage_end_date); | ||
} else { | ||
// Hide coverage dates display when there are zero results | ||
document | ||
.querySelector('.states-table-timestamp') | ||
.setAttribute('style', 'opacity: 0;'); | ||
} | ||
}); | ||
}) | ||
.catch(function() {}); | ||
}; | ||
|
||
/** | ||
* Asks the API for the details of the candidate's committees for the currently-selected election | ||
* Called by {@see displayUpdatedData_candidate() } | ||
|
@@ -559,6 +646,8 @@ ContributionsByState.prototype.displayUpdatedData_candidate = function() { | |
this.baseStatesQuery.cycle | ||
); | ||
|
||
this.loadCandidateCoverageDates(); | ||
|
||
// Now that we have the candidate's personal details, | ||
// we need to get the committee data | ||
this.loadCandidateCommitteeDetails(); | ||
|
@@ -617,8 +706,8 @@ ContributionsByState.prototype.displayUpdatedData_states = function() { | |
theTableBody.innerHTML = theTbodyString; | ||
} | ||
|
||
// Update the time stamp above the states list | ||
this.updateCycleTimeStamp(); | ||
// Update candidate's coverage dates above the states list | ||
this.loadCandidateCoverageDates(); | ||
|
||
// Update the Individual Contributions button/link at the bottom | ||
this.updateBrowseIndivContribsButton(); | ||
|
@@ -649,42 +738,6 @@ ContributionsByState.prototype.displayUpdatedData_total = function(data) { | |
else statesHolder.setAttribute('style', 'opacity: 0;'); | ||
}; | ||
|
||
/** | ||
* Reads the date and office type and puts the correct date into the paqe, above the list of states | ||
* Called from inside {@see displayUpdatedData_states() } | ||
*/ | ||
ContributionsByState.prototype.updateCycleTimeStamp = function() { | ||
let electionYear = this.baseStatesQuery.cycle; | ||
|
||
// Remember the in-page elements | ||
let theStartTimeElement = document.querySelector('.js-cycle-start-time'); | ||
let theEndTimeElement = document.querySelector('.js-cycle-end-time'); | ||
|
||
// If the election type is P, the start date is 1 January, three years previous | ||
// Likewise, five years previous if S, or just one year previous for H | ||
let theStartDate; | ||
if (this.candidateDetails.office == 'P') | ||
theStartDate = new Date(electionYear - 3, 1, 1); | ||
else if (this.candidateDetails.office == 'S') | ||
theStartDate = new Date(electionYear - 5, 1, 1); | ||
else theStartDate = new Date(electionYear - 1, 1, 1); | ||
theStartTimeElement.setAttribute( | ||
'datetime', | ||
theStartDate.getFullYear() + '-01-01' | ||
); | ||
// Put it into the start time | ||
theStartTimeElement.innerText = `01/01/${theStartDate.getFullYear()}`; | ||
|
||
// And the end date is just 31 December of the election_year | ||
let theEndDate = new Date(electionYear, 1, 1); | ||
theEndTimeElement.setAttribute( | ||
'datetime', | ||
theEndDate.getFullYear() + '-12-31' | ||
); | ||
// Finally put the ending year into the end time element | ||
theEndTimeElement.innerText = `12/31/${theEndDate.getFullYear()}`; | ||
}; | ||
|
||
/** | ||
* Called when the typeahead element dispatches "typeahead:select" | ||
* @param {jQuery.Event} e 'typeahead:select' event | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really good or bad but since this is a pure function and we aren't referencing any particular ContributionsByState instance, we could define this as
function formatDate(date) {
rather than assign it to the class. But it works fine the way it is.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided to move the formatDate function to be locally scoped within the loadCandidateCoverageDates function for now since that's the only place it's used. If we need it later on, we can move it back out again.