Skip to content
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

Projected Vacancy Details Page #444

Merged
merged 5 commits into from
Sep 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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