Skip to content

Commit

Permalink
Merge pull request #444 from MetaPhase-Consulting/feature/pv-details-…
Browse files Browse the repository at this point in the history
…page

Projected Vacancy Details Page
  • Loading branch information
rtirserio authored Sep 26, 2019
2 parents 93fe689 + 786e5a9 commit 85990c6
Show file tree
Hide file tree
Showing 31 changed files with 989 additions and 412 deletions.
3 changes: 2 additions & 1 deletion public/config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"static_content": true,
"notifications": true,
"complete_bidding": true,
"data_sync_admin": true
"data_sync_admin": true,
"available_positions": false
}
}
3 changes: 2 additions & 1 deletion public/config/config_dev.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"static_content": true,
"notifications": true,
"complete_bidding": true,
"data_sync_admin": true
"data_sync_admin": true,
"available_positions": false
}
}
2 changes: 1 addition & 1 deletion src/Components/CompareList/CompareList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ class CompareList extends Component {
{
compareArray.map(c => (
<td key={shortId.generate()}>
{propOrDefault(c.position, 'current_assignment.estimated_end_date') ? formatDate(c.position.current_assignment.estimated_end_date) : NO_DATE }
{propOrDefault(c, 'ted') ? formatDate(c.ted) : NO_DATE }
</td>
))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ exports[`CompareListComponent matches snapshot 1`] = `
None listed
</td>
<td>
03/13/2020
None listed
</td>
<td
className="empty"
Expand Down Expand Up @@ -745,7 +745,7 @@ exports[`CompareListComponent matches snapshot when there is an obc id 1`] = `
None listed
</td>
<td>
03/13/2020
None listed
</td>
<td
className="empty"
Expand Down
11 changes: 6 additions & 5 deletions src/Components/CondensedCardData/CondensedCardData.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React from 'react';
import { get } from 'lodash';
import { POSITION_DETAILS } from '../../Constants/PropTypes';
import { NO_DATE, NO_GRADE, NO_SKILL } from '../../Constants/SystemMessages';
import LanguageList from '../LanguageList';
import CondensedCardDataPoint from './CondensedCardDataPoint';
import { formatDate, propOrDefault } from '../../utilities';

const CondensedCardData = ({ position }) => {
const estimatedEndDate = propOrDefault(position, 'current_assignment.estimated_end_date') ?
formatDate(position.current_assignment.estimated_end_date) : NO_DATE;
const estimatedEndDate = propOrDefault(position, 'ted') ?
formatDate(position.ted) : NO_DATE;
return (
<div className="usa-grid-full condensed-card-data">
<CondensedCardDataPoint
Expand All @@ -17,17 +18,17 @@ const CondensedCardData = ({ position }) => {
/>
<CondensedCardDataPoint
title="Skill"
content={position.skill || NO_SKILL}
content={get(position, 'position.skill', NO_SKILL)}
hasFixedTitleWidth
/>
<CondensedCardDataPoint
title="Grade"
content={position.grade || NO_GRADE}
content={get(position, 'position.grade', NO_GRADE)}
hasFixedTitleWidth
/>
<CondensedCardDataPoint
title="Language"
content={<LanguageList languages={position.languages} propToUse="representation" />}
content={<LanguageList languages={get(position, 'position.languages')} propToUse="representation" />}
hasFixedTitleWidth
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ exports[`CondensedCardDataComponent matches snapshot 1`] = `
title="TED"
/>
<CondensedCardDataPoint
content="None listed"
content="OFFICE MANAGEMENT (9017)"
hasFixedTitleWidth={true}
title="Skill"
/>
<CondensedCardDataPoint
content="None listed"
content="06"
hasFixedTitleWidth={true}
title="Grade"
/>
Expand All @@ -42,12 +42,12 @@ exports[`CondensedCardDataComponent matches snapshot with an empty estimated end
title="TED"
/>
<CondensedCardDataPoint
content="None listed"
content="OFFICE MANAGEMENT (9017)"
hasFixedTitleWidth={true}
title="Skill"
/>
<CondensedCardDataPoint
content="None listed"
content="06"
hasFixedTitleWidth={true}
title="Grade"
/>
Expand All @@ -74,12 +74,12 @@ exports[`CondensedCardDataComponent matches snapshot with an empty skill 1`] = `
title="TED"
/>
<CondensedCardDataPoint
content="None listed"
content="OFFICE MANAGEMENT (9017)"
hasFixedTitleWidth={true}
title="Skill"
/>
<CondensedCardDataPoint
content="None listed"
content="06"
hasFixedTitleWidth={true}
title="Grade"
/>
Expand Down
9 changes: 7 additions & 2 deletions src/Components/PositionDetails/PositionDetails.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class PositionDetails extends Component {
highlightPosition,
onHighlight,
userProfileIsLoading,
isProjectedVacancy,
} = this.props;

const isReady = details.id && userProfile.id && !isLoading && !hasErrored;
Expand All @@ -76,20 +77,22 @@ class PositionDetails extends Component {
editWebsiteContent={editWebsiteContent}
resetDescriptionEditMessages={resetDescriptionEditMessages}
userProfile={userProfile}
isProjectedVacancy={isProjectedVacancy}
/>
<PositionDetailsItem
details={position}
details={details}
editDescriptionContent={this.editDescriptionContent}
editPocContent={editPocContent}
editWebsiteContent={editWebsiteContent}
resetDescriptionEditMessages={resetDescriptionEditMessages}
userProfile={userProfile}
highlightPosition={highlightPosition}
onHighlight={onHighlight}
isProjectedVacancy={isProjectedVacancy}
/>
<hr />
<Row className="position-details-description-container padded-main-content" fluid>
<PositionSimilarPositions id={details.id} />
{ !isProjectedVacancy && <PositionSimilarPositions id={details.id} /> }
</Row>
</div>}
{isLoading$ && <Spinner type="position-details" size="big" />}
Expand Down Expand Up @@ -118,6 +121,7 @@ PositionDetails.propTypes = {
editWebsiteContent: PropTypes.func.isRequired,
highlightPosition: HIGHLIGHT_POSITION,
onHighlight: PropTypes.func.isRequired,
isProjectedVacancy: PropTypes.bool,
};

PositionDetails.defaultProps = {
Expand All @@ -131,6 +135,7 @@ PositionDetails.defaultProps = {
descriptionEditSuccess: false,
highlightPosition: DEFAULT_HIGHLIGHT_POSITION,
onHighlight: EMPTY_FUNCTION,
isProjectedVacancy: false,
};

export default PositionDetails;
54 changes: 31 additions & 23 deletions src/Components/PositionDetailsItem/PositionDetailsItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,22 @@ const PositionDetailsItem = (props) => {
userProfile,
highlightPosition,
onHighlight,
isProjectedVacancy,
} = props;

const { position } = details;

const isHighlightLoading = highlightPosition.loading;
const tourEndDate = propOrDefault(details, 'current_assignment.estimated_end_date');
const tourEndDate = propOrDefault(details, 'ted');
const formattedTourEndDate = tourEndDate ? formatDate(tourEndDate) : NO_END_DATE;

const formattedBureau = details.bureau || NO_BUREAU;
const formattedTOD = propOrDefault(details, 'post.tour_of_duty') || NO_TOUR_OF_DUTY;
const formattedBureau = get(position, 'bureau', NO_BUREAU);
const formattedTOD = propOrDefault(position, 'post.tour_of_duty') || NO_TOUR_OF_DUTY;

const postDifferential = getDifferentialPercentage(propOrDefault(details, 'post.differential_rate'), NO_POST_DIFFERENTIAL);
const dangerPay = getDifferentialPercentage(propOrDefault(details, 'post.danger_pay'), NO_DANGER_PAY);
const postDifferential = getDifferentialPercentage(propOrDefault(position, 'post.differential_rate'), NO_POST_DIFFERENTIAL);
const dangerPay = getDifferentialPercentage(propOrDefault(position, 'post.danger_pay'), NO_DANGER_PAY);

const OBCUrl$ = propOrDefault(details, 'post.post_bidding_considerations_url');
const OBCUrl$ = propOrDefault(position, 'post.post_bidding_considerations_url');
const getFormattedObcData = (prefix) => {
if (OBCUrl$) {
return (<span> {prefix} | <OBCUrl url={OBCUrl$} type="post-data" label="View OBC Data" /></span>);
Expand All @@ -73,26 +76,26 @@ const PositionDetailsItem = (props) => {
return prefix;
};

const incumbent = propOrDefault(details, 'current_assignment.user', NO_USER_LISTED);
const incumbent = propOrDefault(position, 'current_assignment.user', NO_USER_LISTED);

const getPostedDate = () => {
const posted = get(details, COMMON_PROPERTIES.posted);
const posted = get(position, COMMON_PROPERTIES.posted);
if (posted) {
return formatDate(posted);
}
return NO_UPDATE_DATE;
};
const postedDate = getPostedDate();

const stats = getBidStatisticsObject(details.bid_statistics);
const stats = getBidStatisticsObject(get(position, 'bid_statistics'));

const isHighlighted = get(details, 'is_highlighted');
const isHighlighted = get(position, 'is_highlighted');
return (
<div className="usa-grid-full padded-main-content position-details-outer-container">
<div className="handshake-offset-container">
<Flag
name="flags.bidding"
render={() => renderHandshake(stats, details)}
render={() => renderHandshake(stats, position)}
/>
{
isHighlighted && <Featured cutSide="both" className="ribbon-position-details" />
Expand All @@ -102,7 +105,7 @@ const PositionDetailsItem = (props) => {
<div className="usa-width-two-thirds about-section-left">
<h2>About the Position</h2>
<PositionDetailsDescription
details={details}
details={position}
editDescriptionContent={editDescriptionContent}
resetDescriptionEditMessages={resetDescriptionEditMessages}
/>
Expand All @@ -121,12 +124,12 @@ const PositionDetailsItem = (props) => {
</div>
}
<div className="usa-grid-full data-point-section">
<CondensedCardDataPoint ariaLabel={getAccessiblePositionNumber(details.position_number)} title="Position number" content={details.position_number} />
<CondensedCardDataPoint title="Skill" content={details.skill || NO_SKILL} />
<CondensedCardDataPoint title="Grade" content={details.grade || NO_GRADE} />
<CondensedCardDataPoint ariaLabel={getAccessiblePositionNumber(position.position_number)} title="Position number" content={position.position_number} />
<CondensedCardDataPoint title="Skill" content={position.skill || NO_SKILL} />
<CondensedCardDataPoint title="Grade" content={position.grade || NO_GRADE} />
<CondensedCardDataPoint title="Bureau" content={formattedBureau} />
<CondensedCardDataPoint title="Tour of duty" content={formattedTOD} />
<CondensedCardDataPoint title="Language" content={<LanguageList languages={details.languages} propToUse="representation" />} />
<CondensedCardDataPoint title="Language" content={<LanguageList languages={position.languages} propToUse="representation" />} />
<CondensedCardDataPoint title="Post differential" content={getFormattedObcData(postDifferential)} />
<CondensedCardDataPoint title="Danger pay" content={getFormattedObcData(dangerPay)} />
<CondensedCardDataPoint title="TED" content={formattedTourEndDate} />
Expand All @@ -136,17 +139,20 @@ const PositionDetailsItem = (props) => {
</div>
<div className="usa-width-one-third position-details-contact-container">
<PositionDetailsContact
details={details}
details={position}
editWebsiteContent={editWebsiteContent}
editPocContent={editPocContent}
resetDescriptionEditMessages={resetDescriptionEditMessages}
/>
<ServiceNeededToggle
userProfile={userProfile}
position={details}
loading={isHighlightLoading}
onChange={onHighlight}
/>
{
!isProjectedVacancy &&
<ServiceNeededToggle
userProfile={userProfile}
position={details}
loading={isHighlightLoading}
onChange={onHighlight}
/>
}
</div>
</div>
</div>
Expand All @@ -162,13 +168,15 @@ PositionDetailsItem.propTypes = {
userProfile: USER_PROFILE,
highlightPosition: HIGHLIGHT_POSITION,
onHighlight: PropTypes.func.isRequired,
isProjectedVacancy: PropTypes.bool,
};

PositionDetailsItem.defaultProps = {
details: null,
userProfile: {},
highlightPosition: DEFAULT_HIGHLIGHT_POSITION,
onHighlight: EMPTY_FUNCTION,
isProjectedVacancy: false,
};

export default PositionDetailsItem;
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { shallow } from 'enzyme';
import React from 'react';
import toJSON from 'enzyme-to-json';
import PositionDetailsItem, { renderHandshake } from './PositionDetailsItem';
import detailsObject from '../../__mocks__/detailsObject';
import resultsObject from '../../__mocks__/resultsObject';

const detailsObject = resultsObject.results[0];

describe('PositionDetailsItem', () => {
const props = {
Expand All @@ -17,7 +19,7 @@ describe('PositionDetailsItem', () => {
const wrapper = shallow(
<PositionDetailsItem {...props} />,
);
expect(wrapper.instance().props.details.id).toBe(6);
expect(wrapper.instance().props.details.id).toBe(1);
});

it('renders handshake', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React, { Component } from 'react';
import FontAwesome from 'react-fontawesome';
import PropTypes from 'prop-types';

import { get } from 'lodash';
import { checkFlag } from '../../../flags';
import InteractiveElement from '../../InteractiveElement';

import {
Expand All @@ -10,6 +11,8 @@ import {
USER_PROFILE,
} from '../../../Constants/PropTypes';

const getUseAP = () => checkFlag('flags.available_positions');

export default class ServiceNeededToggle extends Component {
constructor(props) {
super(props);
Expand All @@ -18,12 +21,13 @@ export default class ServiceNeededToggle extends Component {

onClick() {
const { position, onChange } = this.props;
onChange(position.id, !this.checked);
const id = getUseAP() ? position.id : get(position, 'position.id');
onChange(id, !this.checked);
}

get checked() {
const { position } = this.props;
return (position.is_highlighted || false);
return get(position, 'position.is_highlighted', false);
}

get text() {
Expand Down
Loading

0 comments on commit 85990c6

Please sign in to comment.