Skip to content
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
5 changes: 3 additions & 2 deletions snprc_ehr/resources/queries/study/PotentialDams.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ SELECT d.id as Dam,
d.birth as BirthDate,
d.id.age.ageInYears as Age


FROM study.demographics AS d
INNER JOIN (
SELECT "min" AS minAdultAge, species, gender, label
Expand All @@ -26,8 +25,10 @@ FROM study.demographics AS d
UNION ALL
SELECT 223 as gestation, 'PT' as species
UNION ALL
SELECT 22 as gestation, 'MA' as species
UNION ALL
SELECT 185 as gestation, 'O' as species
) AS y ON CASE WHEN d.species.arc_species_code IN ('PC', 'CJ', 'MM', 'MF', 'PT') then d.species.arc_species_code ELSE 'O' END = y.species
) AS y ON CASE WHEN d.species.arc_species_code IN ('PC', 'CJ', 'MM', 'MF', 'PT','MA') then d.species.arc_species_code ELSE 'O' END = y.species

INNER JOIN study.acq_disp as ad on d.id = ad.id

Expand Down
4 changes: 3 additions & 1 deletion snprc_ehr/resources/queries/study/PotentialSires.sql
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ FROM study.demographics AS d
UNION ALL
SELECT 223 as gestation, 'PT' as species
UNION ALL
SELECT 22 as gestation, 'MA' as species
UNION ALL
SELECT 185 as gestation, 'O' as species
) AS y ON CASE WHEN d.species.arc_species_code IN ('PC', 'CJ', 'MM', 'MF', 'PT') then d.species.arc_species_code ELSE 'O' END = y.species
) AS y ON CASE WHEN d.species.arc_species_code IN ('PC', 'CJ', 'MM', 'MF', 'PT', 'MA') then d.species.arc_species_code ELSE 'O' END = y.species

INNER JOIN study.acq_disp as ad on d.id = ad.id

Expand Down
79 changes: 49 additions & 30 deletions snprc_ehr/src/client/NewAnimalPage/NewAnimalPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,15 @@ export default class NewAnimalPage extends React.Component {
}
};

handleNumAnimalChange = value => {
this.setState(
prevState => ({
...prevState,
numAnimals: value
})
)
}

handleDataChange = (property, value) => {
this.setState(
prevState => ({
Expand Down Expand Up @@ -294,46 +303,53 @@ export default class NewAnimalPage extends React.Component {
onSaveClick = () => {
console.log('Saving...')

// run async save then dismiss modal
uploadAnimalData(this.state.newAnimalData)
.then(data => {
if (data.success === true) {
this.setState(
prevState => ({
// Multiple animals can be added for hamsters, which are often acquired and assigned in bulk
const numAnimals = this.state.numAnimals ? this.state.numAnimals : 1

for (let i = 0; i < numAnimals; i++) {
// run async save then dismiss modal
uploadAnimalData(this.state.newAnimalData)
.then(data => {
if (data.success === true) {
this.setState(
prevState => ({
...prevState,
newAnimalData: {
...prevState.newAnimalData,
id: data.Id,
},
showSaveModal: false,
summaryData: [
...prevState.summaryData,
{ ...prevState.newAnimalData, id: data.Id },
],
}),
this.handleSaveReset()
)
} else {
this.setState(prevState => ({
...prevState,
newAnimalData: {
...prevState.newAnimalData,
id: data.Id,
},
errorMessage: data.message,
showSaveModal: false,
summaryData: [
...prevState.summaryData,
{ ...prevState.newAnimalData, id: data.Id },
],
}),
this.handleSaveReset()
)
} else {
}))
}
})
.catch(error => {
this.setState(prevState => ({
...prevState,
errorMessage: data.message,
errorMessage: error.exception,
showSaveModal: false,
}))
}
})
.catch(error => {
this.setState(prevState => ({
...prevState,
errorMessage: error.exception,
showSaveModal: false,
}))
})
})
}

};

handleSaveReset = () => {
this.setState(prevState => ({
...prevState,
currentPanel: 1,
numAnimals: undefined,
newAnimalData: {
...prevState.newAnimalData,
...(prevState.selectedOption === 'Acquisition' && {
Expand All @@ -349,7 +365,7 @@ export default class NewAnimalPage extends React.Component {
cage: prevState.newAnimalData.cage

})
|| {
|| {
sire: undefined,
dam: undefined,
cage: { value: undefined }
Expand Down Expand Up @@ -489,9 +505,11 @@ export default class NewAnimalPage extends React.Component {
this.state.acquisitionTypeList
}
disabled={ this.disableFirstPanel() }
handleDataChange={ this.handleDataChange }
numAnimals={ this.state.numAnimals }
newAnimalData={ this.state.newAnimalData }
handleDataChange={ this.handleDataChange }
preventNext={ this.preventNext }
handleNumAnimalChange={ this.handleNumAnimalChange }
/>
</div>
</div>
Expand Down Expand Up @@ -685,6 +703,7 @@ export default class NewAnimalPage extends React.Component {
{/* Save Modal */ }
<SaveModal
newAnimalData={ this.state.newAnimalData }
numAnimals={ this.state.numAnimals }
onCloseClick={ this.onCloseClick }
onSaveClick={ this.onSaveClick }
show={ this.state.showSaveModal }
Expand Down
172 changes: 118 additions & 54 deletions snprc_ehr/src/client/NewAnimalPage/components/AcquisitionPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,70 +3,134 @@ import Select from 'react-select'
import moment from 'moment'
import WrappedDatePicker from '../../Shared/components/WrappedDatePicker'
import InfoPanel from '../../Shared/components/InfoPanel'
import { validateNumAnimals } from '../services/validation'
import constants from '../constants/index'

export default class AcquisitionPanel extends React.Component {
componentDidMount = () => {
this.props.preventNext() // prevent/Allow Next button
}
state = {
errorMessage: undefined,
infoMessage: undefined
}

componentDidMount = () => {
this.props.preventNext() // prevent/Allow Next button
}

handleAcquisitionChange = option => {
this.props.handleDataChange('acquisitionType', option)
}

handleAcquisitionDateChange = date => {
this.props.handleDataChange('acqDate', { date: moment(date) })
}

handleAcquisitionChange = option => {
this.props.handleDataChange('acquisitionType', option)
handleNumAnimalChange = e => {
const numAnimals = e.target.value

const errorMessage = validateNumAnimals(numAnimals)
if (errorMessage === undefined) {
this.props.handleNumAnimalChange(numAnimals)
}

handleAcquisitionDateChange = date => {
this.props.handleDataChange('acqDate', { date: moment(date) })
this.setState(prevState => (
{
...prevState,
errorMessage
}
))
}

isInteger = e => {
const i = e.key // which ? e.which : e.keyCode;
const isInteger = (i >= 0 && i <= 9)
if (!isInteger) {
e.preventDefault()
}

render() {
const { acquisitionType, acqDate } = this.props.newAnimalData
return isInteger
}

handlePaste = e => {
e.preventDefault()
}

return (
<>
<div className="wizard-panel__rows">
<div className="wizard-panel__row">
<div className="wizard-panel__col">
<WrappedDatePicker
dateFormat="Pp"
render() {
const { acquisitionType, acqDate, species } = this.props.newAnimalData
const numAnimals = this.props.numAnimals

return (
<>
<div className="wizard-panel__rows">
<div className="wizard-panel__row">
<div className="wizard-panel__col">
<WrappedDatePicker
dateFormat="Pp"
disabled={ this.props.disabled }
id="acquisition-datepicker"
label="Acquisition Date"
maxDate={ moment().toDate() }
onChange={ this.handleAcquisitionDateChange }
onSelect={ this.handleAcquisitionDateChange }
selected={ acqDate.date.toDate() }
showTimeSelect
timeFormat="p"
timeIntervals={ 30 }
todayButton="Today"
/>
</div>
</div>
<div className="wizard-panel__row">
<div className="wizard-panel__col">
<label className="field-label">Acquisition Code</label>
<Select
autoFocus
className="shared-dropdown"
classNamePrefix="shared-select"
id="acquisition-select"
isClearable
isDisabled={ this.props.disabled }
isLoading={ this.props.acquisitionTypeList.length === 0 }
onChange={ this.handleAcquisitionChange }
options={ this.props.acquisitionTypeList }
placeholder="Select Acquisition Type"
value={ acquisitionType || null }
/>
</div>
</div>
{ species && species.arcSpeciesCode === 'MA' && (
<div className="wizard-panel__row">
<div className="wizard-panel__col">
<label className="field-label">Number of Animals</label>

<input
className="acq-input"
defaultValue={ numAnimals ? numAnimals : 1 }
disabled={ this.props.disabled }
id="acquisition-datepicker"
label="Acquisition Date"
maxDate={ moment().toDate() }
onChange={ this.handleAcquisitionDateChange }
onSelect={ this.handleAcquisitionDateChange }
selected={ acqDate.date.toDate() }
showTimeSelect
timeFormat="p"
timeIntervals={ 30 }
todayButton="Today"
onKeyPress={ this.isInteger }
onPasteCapture={ this.handlePaste }
type="text"
onChange={ this.handleNumAnimalChange }
max="100"
min="1"
type="number"
/>
</div>

</div>
<div className="wizard-panel__row">
<div className="wizard-panel__col">
<label className="field-label">Acquisition Code</label>
<Select
autoFocus
className="shared-dropdown"
classNamePrefix="shared-select"
id="acquisition-select"
isClearable
isDisabled={ this.props.disabled }
isLoading={ this.props.acquisitionTypeList.length === 0 }
onChange={ this.handleAcquisitionChange }
options={ this.props.acquisitionTypeList }
placeholder="Select Acquisition Type"
value={ acquisitionType || null }
/>
</div>
</div>

</div>
<InfoPanel
messages={
[{ propTest: !acquisitionType, colName: 'Acquisition Code' }]
}
/>
</>
)
}
) }
</div>
<InfoPanel
errorMessages={
[{ propTest: this.state.errorMessage, colName: this.state.errorMessage }]
}
messages={
[{ propTest: !acquisitionType, colName: 'Acquisition Code' }]
}
infoMessages={species && species.arcSpeciesCode === 'MA' && numAnimals && numAnimals != 1 && [
{key: 1, value: constants.hamsterWarnings}
]}
/>
</>
)
}
}
6 changes: 4 additions & 2 deletions snprc_ehr/src/client/NewAnimalPage/components/SaveModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ export default class SaveModal extends React.PureComponent {

<Modal.Body>
<SummaryPanel
infoMessages={ [{ key: 1, value: 'Please review data before saving.' },
{ key: 2, value: 'Hover cursor over fields for full text.' }] }
infoMessages={ [...(this.props.numAnimals && this.props.numAnimals != 1 ? [{ key: 1, value: 'Multiple animals are being addeded!' }] : []),
{ key: 2, value: 'Please review data before saving.' },
{ key: 3, value: 'Hover cursor over fields for full text.' }] }
newAnimalData={ this.props.newAnimalData }
numAnimals= { this.props.numAnimals }
/>
</Modal.Body>

Expand Down
15 changes: 15 additions & 0 deletions snprc_ehr/src/client/NewAnimalPage/components/SummaryPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default class SummaryPanel extends React.Component {
render() {
const { acquisitionType, acqDate, birthDate, gender, dam, sire, animalAccount,
colony, pedigree, iacuc, ownerInstitution, responsibleInstitution, room, cage, diet } = this.props.newAnimalData
const numAnimals = this.props.numAnimals

return (
<>
Expand Down Expand Up @@ -51,6 +52,19 @@ export default class SummaryPanel extends React.Component {
/>
</OverlayTrigger>
</div>
{ numAnimals && numAnimals != 1 &&
<div className="summary-panel__col ">
<label className="summary-label summary-label-red">Number of Animals</label>
<OverlayTrigger overlay={ <SummaryPopover message={ numAnimals && numAnimals } title="Number of animals" /> }>
<input
className="summary-text-input summary-text-input-red"
defaultValue={ numAnimals }
onKeyPress={ this.handleKeyPress }
onPasteCapture={ this.handlePaste }
/>
</OverlayTrigger>
</div>
}
</div>
<div className="section-header">Demographics</div>
<div className="summary-panel__row"> {/* Demographics */}
Expand Down Expand Up @@ -270,6 +284,7 @@ export default class SummaryPanel extends React.Component {
</div>
<InfoPanel
infoMessages={ this.props.infoMessages }
includeBullets={ true }
/>
</div>
</>
Expand Down
Loading