forked from USStateDept/State-TalentMAP
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #87 from MetaPhase-Consulting/feature/comparison-d…
…rawer Feature/comparison drawer
- Loading branch information
Showing
15 changed files
with
427 additions
and
52 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import FA from 'react-fontawesome'; | ||
import shortid from 'shortid'; | ||
import COMPARE_LIMIT from '../../Constants/Compare'; | ||
import { getPostName } from '../../utilities'; | ||
import { | ||
NO_GRADE, | ||
NO_POST, | ||
} from '../../Constants/SystemMessages'; | ||
import CompareCheck from '../CompareCheck'; | ||
import ViewComparisonLink from '../ViewComparisonLink/ViewComparisonLink'; | ||
import ResetComparisons from '../ResetComparisons/ResetComparisons'; | ||
import { COMPARE_LIST } from '../../Constants/PropTypes'; | ||
|
||
const CompareDrawer = ({ comparisons, isHidden }) => { | ||
const limit = 5; | ||
const compareArray = (comparisons || []).slice(0, COMPARE_LIMIT); | ||
const emptyArray = Array(limit - compareArray.length).fill(); | ||
return ( | ||
<div className={`compare-drawer ${isHidden ? 'drawer-hidden' : ''}`}> | ||
<div className="compare-drawer-inner-container"> | ||
{ | ||
compareArray.map(c => ( | ||
<div key={c.id} className="compare-item"> | ||
<div className="check-container"> | ||
<CompareCheck | ||
refKey={c.position_number} | ||
customElement={<FA name="close" />} | ||
interactiveElementProps={{ title: 'Remove this comparison' }} | ||
/> | ||
</div> | ||
<span className="data-point title"> | ||
<strong>{c.title}</strong> | ||
</span> | ||
<span className="data-point"> | ||
<strong>Grade:</strong> {c.grade || NO_GRADE} | ||
</span> | ||
<span className="data-point"> | ||
<strong>Post:</strong> {getPostName(c.post, NO_POST)} | ||
</span> | ||
</div> | ||
)) | ||
} | ||
{ | ||
emptyArray.map(() => ( | ||
<div | ||
key={shortid.generate()} | ||
className="compare-item compare-item-empty" | ||
/> | ||
)) | ||
} | ||
<div className="button-container"> | ||
<ViewComparisonLink /> | ||
<ResetComparisons | ||
className="reset-link" | ||
/> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
CompareDrawer.propTypes = { | ||
comparisons: COMPARE_LIST, | ||
isHidden: PropTypes.bool, | ||
}; | ||
|
||
CompareDrawer.defaultProps = { | ||
comparisons: [], | ||
isHidden: false, | ||
}; | ||
|
||
export default CompareDrawer; |
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,36 @@ | ||
import { shallow } from 'enzyme'; | ||
import React from 'react'; | ||
import CompareDrawer from './CompareDrawer'; | ||
import resultsObject from '../../__mocks__/resultsObject'; | ||
|
||
describe('CompareDrawer', () => { | ||
const props = { | ||
comparisons: resultsObject.results, | ||
isHidden: false, | ||
}; | ||
it('is defined', () => { | ||
const wrapper = shallow(<CompareDrawer {...props} />); | ||
expect(wrapper).toBeDefined(); | ||
}); | ||
|
||
it('applies correct css class when isHidden === true', () => { | ||
const wrapper = shallow(<CompareDrawer {...props} isHidden />); | ||
expect(wrapper.find('.drawer-hidden').exists()).toBe(true); | ||
}); | ||
|
||
it('does not apply new css class when isHidden === false', () => { | ||
const wrapper = shallow(<CompareDrawer {...props} isHidden={false} />); | ||
expect(wrapper.find('.drawer-hidden').exists()).toBe(false); | ||
}); | ||
|
||
it('displays the correct number of results data cards', () => { | ||
const wrapper = shallow(<CompareDrawer {...props} isHidden={false} />); | ||
expect(wrapper.find('.check-container').length).toBe(resultsObject.results.length); | ||
}); | ||
|
||
it('displays the correct number of empty cards', () => { | ||
const maxCards = 5; | ||
const wrapper = shallow(<CompareDrawer {...props} isHidden={false} />); | ||
expect(wrapper.find('.compare-item-empty').length).toBe(maxCards - resultsObject.results.length); | ||
}); | ||
}); |
117 changes: 117 additions & 0 deletions
117
src/Components/CompareDrawer/CompareDrawerContainer.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,117 @@ | ||
import React, { Component } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { connect } from 'react-redux'; | ||
import { isEqual, omit } from 'lodash'; | ||
import { comparisonsFetchData } from '../../actions/comparisons'; | ||
import CompareDrawer from './CompareDrawer'; | ||
import { COMPARE_LIST } from '../../Constants/PropTypes'; | ||
import { getScrollDistanceFromBottom } from '../../utilities'; | ||
|
||
class Compare extends Component { | ||
constructor(props) { | ||
super(props); | ||
this.lsListener = this.lsListener.bind(this); | ||
this.scrollListener = this.scrollListener.bind(this); | ||
|
||
/* set to 0 for now, but could change to the distance in px from the bottom of the screen | ||
that you want the drawer to hide at */ | ||
this.scrollDistance = 0; | ||
|
||
this.state = { | ||
prevComparisons: [], | ||
comparisons: [], | ||
isHidden: false, | ||
}; | ||
} | ||
|
||
componentWillMount() { | ||
// initialize with any existing comparison choices | ||
const ls = localStorage.getItem('compare') || '[]'; | ||
const initialArr = JSON.parse(ls); | ||
this.setState({ comparisons: initialArr }, () => { | ||
this.getComparisons(this.state.comparisons.toString()); | ||
}); | ||
|
||
// add listener on localStorage 'compare' key | ||
window.addEventListener('compare-ls', this.lsListener); | ||
|
||
// add listener for scroll location, to hide the comparison farther down the page | ||
window.addEventListener('scroll', this.scrollListener); | ||
} | ||
|
||
shouldComponentUpdate(nextProps, nextState) { | ||
// we ignore comparisons state, since its just tracking the user's choices | ||
return !(isEqual(nextProps, this.props)) || !(isEqual(omit(nextState, 'comparisons'), omit(this.state, 'comparisons'))); | ||
} | ||
|
||
componentWillUnmount() { | ||
window.removeEventListener('compare-ls', this.lsListener); | ||
} | ||
|
||
getComparisons(ids) { | ||
this.props.fetchData(ids); | ||
} | ||
|
||
lsListener() { | ||
const comparisons = JSON.parse(localStorage.getItem('compare') || []); | ||
this.setState({ prevComparisons: this.state.comparisons, comparisons }, () => { | ||
this.getComparisons(this.state.comparisons.toString()); | ||
}); | ||
} | ||
|
||
scrollListener() { | ||
const { isHidden } = this.state; | ||
|
||
// eslint-disable-next-line no-unused-expressions | ||
getScrollDistanceFromBottom() < this.scrollDistance ? | ||
!isHidden && this.setState({ isHidden: true }) | ||
: | ||
isHidden && this.setState({ isHidden: false }); | ||
} | ||
|
||
render() { | ||
const { isHidden, comparisons: comparisonsState, prevComparisons } = this.state; | ||
const { comparisons, hasErrored } = this.props; | ||
|
||
const comparisonsToUse = comparisonsState.length > prevComparisons.length | ||
? comparisonsState : prevComparisons; | ||
|
||
/* sort based on any prior compare list, so the cards don't get jumbled | ||
after one is removed, as it persists until the new request completes */ | ||
const sortedComparisons = comparisons.sort((a, b) => | ||
(comparisonsToUse.indexOf(a.position_number) > | ||
comparisonsToUse.indexOf(b.position_number) ? 1 : -1), | ||
); | ||
|
||
const isHidden$ = isHidden || !sortedComparisons.length; | ||
return ( | ||
<CompareDrawer | ||
comparisons={sortedComparisons} | ||
hasErrored={hasErrored} | ||
isHidden={isHidden$} | ||
/> | ||
); | ||
} | ||
} | ||
|
||
Compare.propTypes = { | ||
fetchData: PropTypes.func.isRequired, | ||
hasErrored: PropTypes.bool, | ||
comparisons: COMPARE_LIST, | ||
}; | ||
|
||
Compare.defaultProps = { | ||
comparisons: [], | ||
hasErrored: false, | ||
}; | ||
|
||
const mapStateToProps = state => ({ | ||
comparisons: state.comparisons, | ||
hasErrored: state.comparisonsHasErrored, | ||
}); | ||
|
||
export const mapDispatchToProps = dispatch => ({ | ||
fetchData: url => dispatch(comparisonsFetchData(url)), | ||
}); | ||
|
||
export default connect(mapStateToProps, mapDispatchToProps)(Compare); |
31 changes: 31 additions & 0 deletions
31
src/Components/CompareDrawer/CompareDrawerContainer.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,31 @@ | ||
import React from 'react'; | ||
import TestUtils from 'react-dom/test-utils'; | ||
import { Provider } from 'react-redux'; | ||
import { MemoryRouter } from 'react-router-dom'; | ||
import configureStore from 'redux-mock-store'; | ||
import thunk from 'redux-thunk'; | ||
import { testDispatchFunctions } from '../../testUtilities/testUtilities'; | ||
import CompareDrawerContainer, { mapDispatchToProps } from './CompareDrawerContainer'; | ||
import resultsObject from '../../__mocks__/resultsObject'; | ||
|
||
const middlewares = [thunk]; | ||
const mockStore = configureStore(middlewares); | ||
|
||
describe('CompareDrawerContainer', () => { | ||
it('is defined', () => { | ||
const compare = TestUtils.renderIntoDocument(<Provider store={mockStore({})}><MemoryRouter> | ||
<CompareDrawerContainer | ||
fetchData={() => {}} | ||
comparisons={resultsObject.results} | ||
/> | ||
</MemoryRouter></Provider>); | ||
expect(compare).toBeDefined(); | ||
}); | ||
}); | ||
|
||
describe('mapDispatchToProps', () => { | ||
const config = { | ||
fetchData: ['1,2'], | ||
}; | ||
testDispatchFunctions(mapDispatchToProps, config); | ||
}); |
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 './CompareDrawerContainer'; |
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.