-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Export button to Bidder Portfolio (#142)
- Loading branch information
Showing
14 changed files
with
392 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
src/Components/BidderPortfolio/ExportLink/ExportLink.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import React, { Component } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { connect } from 'react-redux'; | ||
import { CSVLink } from 'react-csv'; | ||
import { get } from 'lodash'; | ||
import { bidderPortfolioFetchDataFromLastQuery } from '../../../actions/bidderPortfolio'; | ||
import { EMPTY_FUNCTION } from '../../../Constants/PropTypes'; | ||
|
||
// Mapping columns to data fields | ||
const HEADERS = [ | ||
{ label: 'Last Name', key: 'user.last_name' }, | ||
{ label: 'First Name', key: 'user.first_name' }, | ||
{ label: 'Email', key: 'user.email' }, | ||
{ label: 'Username', key: 'user.username' }, | ||
{ label: 'Grade', key: 'grade' }, | ||
{ label: 'Primary Nationality', key: 'primary_nationality' }, | ||
{ label: 'Secondary Nationality', key: 'secondary_nationality' }, | ||
{ label: 'Current Assignment', key: 'current_assignment' }, | ||
{ label: 'Language', key: 'language_qualifications[0].representation' }, | ||
]; | ||
|
||
// Processes results before sending to the download component to allow for custom formatting. | ||
const processData = data => ( | ||
data.map(entry => ({ | ||
...entry, | ||
// any other processing we may want to do here | ||
})) | ||
); | ||
|
||
export class ExportLink extends Component { | ||
constructor(props) { | ||
super(props); | ||
this.onClick = this.onClick.bind(this); | ||
this.state = { | ||
data: '', | ||
isLoading: false, | ||
}; | ||
} | ||
|
||
componentWillReceiveProps(nextProps) { | ||
if (!nextProps.isLoading) { | ||
this.setState({ isLoading: false }); | ||
} | ||
if (this.props.isLoading && !nextProps.isLoading && !nextProps.hasErrored) { | ||
const data = processData(nextProps.data.results); | ||
this.setState({ data, isLoading: false }, () => { | ||
if (get(this.csvLink, 'link.click')) { | ||
this.csvLink.link.click(); | ||
} | ||
}); | ||
} | ||
} | ||
|
||
onClick() { | ||
const { isLoading } = this.state; | ||
const { fetchData } = this.props; | ||
if (!isLoading) { | ||
this.setState({ | ||
isLoading: true, | ||
}, () => { | ||
fetchData(); | ||
}); | ||
} | ||
} | ||
|
||
render() { | ||
const { data, isLoading } = this.state; | ||
return ( | ||
<div className="export-button-container"> | ||
<button className="usa-button-secondary" onClick={this.onClick}> | ||
{isLoading && <span className="ds-c-spinner spinner-blue" />}<span>Export</span> | ||
</button> | ||
<CSVLink ref={(x) => { this.csvLink = x; }} target="_blank" filename={this.props.filename} data={data} headers={HEADERS} /> | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
ExportLink.propTypes = { | ||
filename: PropTypes.string, | ||
hasErrored: PropTypes.bool, | ||
isLoading: PropTypes.bool, | ||
data: PropTypes.shape({ results: PropTypes.arrayOf(PropTypes.shape({})) }), | ||
fetchData: PropTypes.func, | ||
}; | ||
|
||
ExportLink.defaultProps = { | ||
filename: 'TalentMap_bidder_portfolio_export.csv', | ||
hasErrored: false, | ||
isLoading: false, | ||
data: {}, | ||
fetchData: EMPTY_FUNCTION, | ||
}; | ||
|
||
const mapStateToProps = state => ({ | ||
hasErrored: state.lastBidderPortfolioHasErrored, | ||
isLoading: state.lastBidderPortfolioIsLoading, | ||
data: state.lastBidderPortfolio, | ||
}); | ||
|
||
export const mapDispatchToProps = dispatch => ({ | ||
fetchData: () => dispatch(bidderPortfolioFetchDataFromLastQuery()), | ||
}); | ||
|
||
export default connect(mapStateToProps, mapDispatchToProps)(ExportLink); |
40 changes: 40 additions & 0 deletions
40
src/Components/BidderPortfolio/ExportLink/ExportLink.test.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { shallow } from 'enzyme'; | ||
import React from 'react'; | ||
import toJSON from 'enzyme-to-json'; | ||
import { ExportLink, mapDispatchToProps } from './ExportLink'; | ||
import { testDispatchFunctions } from '../../../testUtilities/testUtilities'; | ||
|
||
describe('SearchResultsExportLink', () => { | ||
it('is defined', () => { | ||
const wrapper = shallow(<ExportLink />); | ||
expect(wrapper).toBeDefined(); | ||
}); | ||
|
||
it('calls onClick on button click', () => { | ||
const wrapper = shallow(<ExportLink />); | ||
expect(wrapper.instance().state.isLoading).toBe(false); | ||
wrapper.find('button').simulate('click'); | ||
expect(wrapper.instance().state.isLoading).toBe(true); | ||
}); | ||
|
||
it('sets state when data is done loading', () => { | ||
const wrapper = shallow(<ExportLink isLoading />); | ||
const instance = wrapper.instance(); | ||
const data = { results: [] }; | ||
wrapper.setProps({ isLoading: false, hasErrored: false, data }); | ||
expect(instance.state.isLoading).toBe(false); | ||
expect(instance.state.data).toEqual(data.results); | ||
}); | ||
|
||
it('matches snapshot', () => { | ||
const wrapper = shallow(<ExportLink />); | ||
expect(toJSON(wrapper)).toMatchSnapshot(); | ||
}); | ||
}); | ||
|
||
describe('mapDispatchToProps', () => { | ||
const config = { | ||
fetchData: [], | ||
}; | ||
testDispatchFunctions(mapDispatchToProps, config); | ||
}); |
64 changes: 64 additions & 0 deletions
64
src/Components/BidderPortfolio/ExportLink/__snapshots__/ExportLink.test.jsx.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`SearchResultsExportLink matches snapshot 1`] = ` | ||
<div | ||
className="export-button-container" | ||
> | ||
<button | ||
className="usa-button-secondary" | ||
onClick={[Function]} | ||
> | ||
<span> | ||
Export | ||
</span> | ||
</button> | ||
<CSVLink | ||
asyncOnClick={false} | ||
data="" | ||
filename="TalentMap_bidder_portfolio_export.csv" | ||
headers={ | ||
Array [ | ||
Object { | ||
"key": "user.last_name", | ||
"label": "Last Name", | ||
}, | ||
Object { | ||
"key": "user.first_name", | ||
"label": "First Name", | ||
}, | ||
Object { | ||
"key": "user.email", | ||
"label": "Email", | ||
}, | ||
Object { | ||
"key": "user.username", | ||
"label": "Username", | ||
}, | ||
Object { | ||
"key": "grade", | ||
"label": "Grade", | ||
}, | ||
Object { | ||
"key": "primary_nationality", | ||
"label": "Primary Nationality", | ||
}, | ||
Object { | ||
"key": "secondary_nationality", | ||
"label": "Secondary Nationality", | ||
}, | ||
Object { | ||
"key": "current_assignment", | ||
"label": "Current Assignment", | ||
}, | ||
Object { | ||
"key": "language_qualifications[0].representation", | ||
"label": "Language", | ||
}, | ||
] | ||
} | ||
separator="," | ||
target="_blank" | ||
uFEFF={true} | ||
/> | ||
</div> | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from './ExportLink'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.