Skip to content

Commit

Permalink
Refactor components around Assign Hearings Page (#14660)
Browse files Browse the repository at this point in the history
### Description

  * Organizing imports
  * Make functional components
  * Removing unused code

### Storybook Story

Unsure if these components will change in the near future, so I'm going to hold off on any storybook story or jest tests for now. I think for the tickets that come out of #14614, we can be more thorough in addressing tech debt/refactoring
  • Loading branch information
ferristseng authored Jul 13, 2020
1 parent 6aa5f93 commit 0fff49d
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 128 deletions.
29 changes: 22 additions & 7 deletions client/app/components/DataDropdowns/HearingDate.jsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import React from 'react';
import _ from 'lodash';

import { formatDateStr, getMinutesToMilliseconds } from '../../util/DateUtil';
import {
onReceiveDropdownData,
onFetchDropdownData,
onDropdownError
} from '../common/actions';
import ApiUtil from '../../util/ApiUtil';
import _ from 'lodash';
import { formatDateStr, getMinutesToMilliseconds } from '../../util/DateUtil';
import COPY from '../../../COPY';
import LoadingLabel from './LoadingLabel';
import SearchableDropdown from '../SearchableDropdown';
import COPY from '../../../COPY.json';

class HearingDateDropdown extends React.Component {
componentDidMount() {
Expand Down Expand Up @@ -127,7 +128,8 @@ class HearingDateDropdown extends React.Component {
onChange={this.onOptionSelected}
options={options}
errorMessage={errorMsg || errorMessage}
placeholder={placeholder} />
placeholder={placeholder}
/>
</React.Fragment>
);
}
Expand All @@ -136,12 +138,25 @@ class HearingDateDropdown extends React.Component {
HearingDateDropdown.propTypes = {
name: PropTypes.string,
label: PropTypes.string,
hearingDates: PropTypes.shape({
options: PropTypes.arrayOf(
PropTypes.shape({
value: PropTypes.any,
label: PropTypes.string,
})
),
isFetching: PropTypes.bool,
errorMsg: PropTypes.string
}),
regionalOffice: PropTypes.string.isRequired,
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.object
]),
onChange: PropTypes.func.isRequired,
onDropdownError: PropTypes.func,
onFetchDropdownData: PropTypes.func,
onReceiveDropdownData: PropTypes.func,
readOnly: PropTypes.bool,
placeholder: PropTypes.string,
errorMessage: PropTypes.string,
Expand Down
58 changes: 26 additions & 32 deletions client/app/components/DataDropdowns/HearingRoom.jsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,33 @@
import { HEARING_ROOM_OPTIONS } from './constants';

import React from 'react';
import PropTypes from 'prop-types';
import SearchableDropdown from '../SearchableDropdown';
import React from 'react';
import _ from 'lodash';

export default class HearingRoomDropdown extends React.Component {

getSelectedOption = () => {
const { value } = this.props;

return _.find(HEARING_ROOM_OPTIONS, (opt) => opt.value === value) ||
{
value: null,
label: null
};
}

render() {
const { name, label, onChange, readOnly, errorMessage, placeholder } = this.props;
import { HEARING_ROOM_OPTIONS } from './constants';
import SearchableDropdown from '../SearchableDropdown';

return (
<SearchableDropdown
name={name}
label={label}
strongLabel
readOnly={readOnly}
value={this.getSelectedOption()}
onChange={(option) => onChange((option || {}).value, (option || {}).label)}
options={HEARING_ROOM_OPTIONS}
errorMessage={errorMessage}
placeholder={placeholder} />
);
}
}
export const HearingRoomDropdown = (
{ name, label, value, onChange, readOnly, errorMessage, placeholder }
) => {
const selectedOption = _.find(HEARING_ROOM_OPTIONS, (opt) => opt.value === value) ||
{
value: null,
label: null
};

return (
<SearchableDropdown
name={name}
label={label}
strongLabel
readOnly={readOnly}
value={selectedOption}
onChange={(option) => onChange((option || {}).value, (option || {}).label)}
options={HEARING_ROOM_OPTIONS}
errorMessage={errorMessage}
placeholder={placeholder}
/>
);
};

HearingRoomDropdown.propTypes = {
name: PropTypes.string,
Expand Down
2 changes: 1 addition & 1 deletion client/app/components/DataDropdowns/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Dropdowns that require data from AJAX calls
**/

export { default as HearingRoomDropdown } from './HearingRoom';
export { HearingRoomDropdown } from './HearingRoom';
export { default as JudgeDropdown } from './Judge';
export { default as HearingCoordinatorDropdown } from './HearingCoordinator';
export { default as HearingDateDropdown } from './HearingDate';
Expand Down
71 changes: 50 additions & 21 deletions client/app/hearings/components/HearingDayEditModal.jsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
import React from 'react';
import { withRouter } from 'react-router-dom';
import connect from 'react-redux/es/connect/connect';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { css } from 'glamor';
import { withRouter } from 'react-router-dom';
import AppSegment from '@department-of-veterans-affairs/caseflow-frontend-toolkit/components/AppSegment';
import Button from '../../components/Button';
import Modal from '../../components/Modal';
import { fullWidth } from '../../queue/constants';
import PropTypes from 'prop-types';
import React from 'react';
import _ from 'lodash';
import connect from 'react-redux/es/connect/connect';

import {
HearingRoomDropdown,
JudgeDropdown,
HearingCoordinatorDropdown
} from '../../components/DataDropdowns';
import Checkbox from '../../components/Checkbox';
import TextareaField from '../../components/TextareaField';
import { bindActionCreators } from 'redux';
import { fullWidth } from '../../queue/constants';
import { selectHearingCoordinator,
selectVlj,
selectHearingRoom,
setNotes,
onHearingDayModified
} from '../actions/dailyDocketActions';
import HEARING_ROOMS_LIST from '../../../constants/HEARING_ROOMS_LIST.json';
import _ from 'lodash';
import Button from '../../components/Button';
import Checkbox from '../../components/Checkbox';
import HEARING_ROOMS_LIST from '../../../constants/HEARING_ROOMS_LIST';
import Modal from '../../components/Modal';
import TextareaField from '../../components/TextareaField';

const notesFieldStyling = css({
height: '100px',
Expand All @@ -43,11 +44,6 @@ class HearingDayEditModal extends React.Component {
componentDidMount = () => {
// find labels in options before passing values to modal
this.initialState();
if (this.props.dailyDocket.roomInfo) {
const roomInfo = this.props.dailyDocket.roomInfo.split(' ');

this.props.selectHearingRoom(roomInfo[0]);
}
};

componentDidUpdate(prevProps) {
Expand Down Expand Up @@ -197,10 +193,43 @@ class HearingDayEditModal extends React.Component {
}

HearingDayEditModal.propTypes = {
activeJudges: PropTypes.arrayOf(
PropTypes.shape({
value: PropTypes.any,
label: PropTypes.string,
})
),
activeCoordinators: PropTypes.arrayOf(
PropTypes.shape({
value: PropTypes.any,
label: PropTypes.string,
})
),
coordinator: PropTypes.shape({
value: PropTypes.string
}),
vlj: PropTypes.shape({
value: PropTypes.string
}),
dailyDocket: PropTypes.shape({
bvaPoc: PropTypes.string,
judgeId: PropTypes.number,
notes: PropTypes.string,
room: PropTypes.string
}),
hearingRoom: PropTypes.shape({
value: PropTypes.string
}),
notes: PropTypes.string,
userId: PropTypes.number,
userCssId: PropTypes.string,
closeModal: PropTypes.func,
cancelModal: PropTypes.func
cancelModal: PropTypes.func,
onHearingDayModified: PropTypes.func,
selectHearingCoordinator: PropTypes.func,
selectHearingRoom: PropTypes.func,
setNotes: PropTypes.func,
selectVlj: PropTypes.func
};

const mapStateToProps = (state) => ({
Expand All @@ -214,11 +243,11 @@ const mapStateToProps = (state) => ({
});

const mapDispatchToProps = (dispatch) => bindActionCreators({
selectVlj,
onHearingDayModified,
selectHearingCoordinator,
selectHearingRoom,
setNotes,
onHearingDayModified
selectVlj,
setNotes
}, dispatch);

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(HearingDayEditModal));
121 changes: 57 additions & 64 deletions client/app/hearings/components/assignHearings/AssignHearings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,30 +32,40 @@ const roSelectionStyling = css({ marginTop: '10px' });
const UpcomingHearingDaysNav = ({
upcomingHearingDays, selectedHearingDay,
onSelectedHearingDayChange
}) => (
<div className="usa-width-one-fourth" {...roSelectionStyling}>
<h3>Hearings to Schedule</h3>
<h4>Available Hearing Days</h4>
<ul className="usa-sidenav-list" {...sectionNavigationListStyling}>
{_.orderBy(Object.values(upcomingHearingDays), (hearingDay) => hearingDay.scheduledFor, 'asc').
map((hearingDay) => {
const dateSelected = selectedHearingDay &&
(selectedHearingDay.scheduledFor === hearingDay.scheduledFor &&
selectedHearingDay.room === hearingDay.room);
}) => {
const orderedHearingDays = _.orderBy(
Object.values(upcomingHearingDays),
(hearingDay) => hearingDay.scheduledFor, 'asc'
);

return <li key={hearingDay.id} >
<Button
styling={dateSelected ? buttonColorSelected : {}}
onClick={() => onSelectedHearingDayChange(hearingDay)}
linkStyling>
{`${moment(hearingDay.scheduledFor).format('ddd M/DD/YYYY')}
${hearingDay.room}`}
</Button>
</li>;
})}
</ul>
</div>
);
return (
<div className="usa-width-one-fourth" {...roSelectionStyling}>
<h3>Hearings to Schedule</h3>
<h4>Available Hearing Days</h4>
<ul className="usa-sidenav-list" {...sectionNavigationListStyling}>
{
orderedHearingDays.map(
(hearingDay) => {
const dateSelected = selectedHearingDay?.id === hearingDay?.id;

return (
<li key={hearingDay.id} >
<Button
styling={dateSelected ? buttonColorSelected : {}}
onClick={() => onSelectedHearingDayChange(hearingDay)}
linkStyling>
{`${moment(hearingDay.scheduledFor).format('ddd M/DD/YYYY')}
${hearingDay.room}`}
</Button>
</li>
);
}
)
}
</ul>
</div>
);
};

UpcomingHearingDaysNav.propTypes = {
upcomingHearingDays: PropTypes.object,
Expand All @@ -66,49 +76,32 @@ UpcomingHearingDaysNav.propTypes = {
onSelectedHearingDayChange: PropTypes.func
};

export default class AssignHearings extends React.Component {

room = () => {
const { selectedRegionalOffice, selectedHearingDay } = this.props;

// St. Petersburg, FL or Winston-Salem, NC
if (selectedRegionalOffice === 'RO17' || selectedRegionalOffice === 'RO18') {
if (selectedHearingDay) {
return selectedHearingDay.room;
}
}

return '';
};
export const AssignHearings = ({
upcomingHearingDays, selectedHearingDay, selectedRegionalOffice, onSelectedHearingDayChange
}) => {
// St. Petersburg, FL or Winston-Salem, NC
const room = selectedRegionalOffice === 'RO17' || selectedRegionalOffice === 'RO18' ?
selectedHearingDay?.room :
'';

render() {
const {
upcomingHearingDays,
selectedHearingDay,
selectedRegionalOffice,
onSelectedHearingDayChange
} = this.props;
const room = this.room();

if (_.isEmpty(upcomingHearingDays)) {
return <NoUpcomingHearingDayMessage />;
}

return (
<React.Fragment>
<UpcomingHearingDaysNav
upcomingHearingDays={upcomingHearingDays}
selectedHearingDay={selectedHearingDay}
onSelectedHearingDayChange={onSelectedHearingDayChange} />
<AssignHearingsTabs
selectedRegionalOffice={selectedRegionalOffice}
selectedHearingDay={selectedHearingDay}
room={room}
/>
</React.Fragment>
);
if (_.isEmpty(upcomingHearingDays)) {
return <NoUpcomingHearingDayMessage />;
}
}

return (
<React.Fragment>
<UpcomingHearingDaysNav
upcomingHearingDays={upcomingHearingDays}
selectedHearingDay={selectedHearingDay}
onSelectedHearingDayChange={onSelectedHearingDayChange} />
<AssignHearingsTabs
selectedRegionalOffice={selectedRegionalOffice}
selectedHearingDay={selectedHearingDay}
room={room}
/>
</React.Fragment>
);
};

AssignHearings.propTypes = {
selectedRegionalOffice: PropTypes.string,
Expand Down
Loading

0 comments on commit 0fff49d

Please sign in to comment.