Patients list
Patient list view

Searching by user last name
API URL
/mpi/Patient?name={lastname}
GET data
{ entry: [ 0: {....}, 1: {....}, 2: {....}, 3: { resource: { address: [ 0: { city: "City", country: "Country", district: "District", line: [ 0: "Baker street, 221-b", ], postalCode: 1234, }, 1: {....} ], birthDate: "1985-07-25", deceasedBoolean: false, gender: "female", id: "5024d12f-ec35-4619-b982-8f27d28ee71c", identifier: [ 0: { system: "https://fhir.nhs.uk/Id/nhs-number", value: 5555555541, } ], name: [ 0: { family: "Kolt", given: [ "Elise", ] prefix: "Lisa" } ], resourceType: "Patient", telecom: "7 093 243 3598", }, }, 4: {....}, 5: {....}, ], resourceType: "Bundle", token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......", }
Component structure
import React, { Component } from "react"; import get from "lodash/get"; import { connect } from 'react-redux'; import { TextField, DateField, setSidebarVisibility } from "react-admin"; import { withStyles } from '@material-ui/core/styles'; import CardMedia from "@material-ui/core/CardMedia"; import Typography from "@material-ui/core/Typography"; import TodayIcon from "@material-ui/icons/Today"; import CheckIcon from "@material-ui/icons/Check"; import { patientsCountAction } from "../../actions/patientsCountAction"; import image from "../../../version/images/pulsetile-logo.png"; import ListTemplate from "../../common/ResourseTemplates/ListTemplate"; import ViewButton from "../../common/Buttons/ViewButton"; import PatientCreate from "./PatientCreate"; import PatientEdit from "./PatientEdit"; import PatientShow from "./PatientShow"; import DatagridRow from "./fragments/DatagridRow"; import ColumnsTogglingPopover from "./fragments/ColumnsTogglingPopover"; import { themeCommonElements } from "../../../version/config/theme.config"; const styles = theme => ({ content: { width: "100%", height: "100%", backgroundImage: theme.patientSummaryPanel.container.background, backgroundSize: "cover", backgroundPosition: "center", }, imageBlock: { display: "flex", flexDirection: "row", justifyContent: "center", marginTop: "10%", }, image: { width: "30%", height: "30%", }, labelWithIcon: { marginBottom: 10, }, icon: { marginTop: 5, marginLeft: 5, }, }); const LabelWithIcon = ({ classes, title, icon }) => { return ( <Typography className={classes.labelWithIcon} variant="h1"> { title }{ icon } </Typography> ) }; const defaultHiddenColumns = [ 'ordersDate', 'resultsDate', 'vitalsDate', 'problemsDate', 'ordersCount', 'resultsCount', 'vitalsCount', 'problemsCount' ]; class PatientsList extends Component { state = { key: 0, }; componentDidMount() { this.props.setSidebarVisibility(false); } componentWillReceiveProps(newProps, prevList) { const { getPatientsCounts } = this.props; const prevPatientsIds = get(prevList, 'patientsIds', []); const newPatientsIds = get(newProps, 'patientsIds', []); const isPatientListCount = get(themeCommonElements, 'isPatientListCount', false); if (isPatientListCount && (prevPatientsIds !== newPatientsIds) && newPatientsIds.length > 0) { newPatientsIds.map(item => { getPatientsCounts(item); }); } } updateTableHead = () => { this.setState({ key: this.state.key + 1, }) }; isColumnHidden = columnName => { const { hiddenColumns } = this.props; return hiddenColumns.indexOf(columnName) === -1; }; render() { const { userSearch, userSearchID, classes } = this.props; if (!userSearch && !userSearchID) { return ( <div className={classes.content}> <div className={classes.imageBlock} > <CardMedia className={classes.image} component="img" alt="NHS Scotland" image={image} /> </div> </div> ) } return ( <React.Fragment> <ListTemplate basePath="/patients" create={PatientCreate} edit={PatientEdit} show={PatientShow} resourceUrl="patients" title="Patients List" headerFilterAbsent={true} CustomRow={DatagridRow} isCustomDatagrid={true} ColumnsTogglingPopover={ColumnsTogglingPopover} updateTableHead={this.updateTableHead} defaultHiddenColumns={defaultHiddenColumns} {...this.props} > <TextField source="name" label="Name"/> { this.isColumnHidden('address') && <TextField source="address" label="Address" /> } <TextField source="gender" label="Gender"/> <DateField source="birthDate" label="Born"/> { this.isColumnHidden('nhsNumber') && <TextField source="nhsNumber" label="NHS No." /> } { this.isColumnHidden('ordersDate') && <DateField source="ordersDate" label={<LabelWithIcon classes={classes} title="Orders" icon={<TodayIcon className={classes.icon}/>}/>} /> } { this.isColumnHidden('ordersCount') && <DateField source="ordersCount" label={<LabelWithIcon classes={classes} title="Orders" icon={<CheckIcon className={classes.icon}/>}/>} /> } { this.isColumnHidden('resultsDate') && <DateField source="resultsDate" label={<LabelWithIcon classes={classes} title="Results" icon={<TodayIcon className={classes.icon} />} />} /> } { this.isColumnHidden('resultsCount') && <DateField source="resultsCount" label={<LabelWithIcon classes={classes} title="Results" icon={<CheckIcon className={classes.icon} />} />} /> } { this.isColumnHidden('vitalsDate') && <DateField source="vitalsDate" label={<LabelWithIcon classes={classes} title="Vitals" icon={<TodayIcon className={classes.icon} />} />} /> } { this.isColumnHidden('vitalsCount') && <DateField source="vitalsCount" label={<LabelWithIcon classes={classes} title="Vitals" icon={<CheckIcon className={classes.icon}/>}/>} /> } { this.isColumnHidden('problemsDate') && <DateField source="problemsDate" label={<LabelWithIcon classes={classes} title="Problems" icon={<TodayIcon className={classes.icon} />} />}/> } { this.isColumnHidden('problemsCount') && <DateField source="problemsCount" label={<LabelWithIcon classes={classes} title="Problems" icon={<CheckIcon className={classes.icon} />} />} /> } <ViewButton /> </ListTemplate> </React.Fragment> ); } } const mapStateToProps = state => { return { userSearch: get(state, 'custom.userSearch.data', null), userSearchID: get(state, 'custom.userSearch.id', null), hiddenColumns: get(state, 'custom.toggleColumns.data.patients', []), patientsIds: get(state, 'admin.resources.patients.list.ids', []), } }; const mapDispatchToProps = dispatch => { return { setSidebarVisibility(params) { dispatch(setSidebarVisibility(params)); }, getPatientsCounts(patientId) { dispatch(patientsCountAction.request(patientId)); } } }; export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(PatientsList));
Patients list settings
It is possible to hide/show columns of the patient list table. If user clicks on the cog icon in the right of the block title, settings modal window will appear.

Patient Details Page

API URL
/mpi/Patient/{patientId}
GET response
{ patient: { address: [ 0: { city: "City", country: "Country", district: "District", line: [ 0: "Baker street, 221-b", ], postalCode: 1234, }, 1: {....} ], birthDate: "1985-07-25", deceasedBoolean: false, gender: "female", id: "5024d12f-ec35-4619-b982-8f27d28ee71c", identifier: [ 0: { system: "https://fhir.nhs.uk/Id/nhs-number", value: 5555555541, } ], name: [ 0: { family: "Kolt", given: [ "Elise", ] prefix: "Lisa" } ], resourceType: "Patient", telecom: "7 093 243 3598", }, token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.....", }
Component structure
import React from "react"; import { TextField, DateField } from "react-admin"; import { withStyles } from '@material-ui/core/styles'; import ShowTemplate from "../../common/ResourseTemplates/ShowTemplate"; const PatientShow = ({ classes, ...rest }) => ( <ShowTemplate pageTitle="Patient" {...rest}> <TextField label="Name" source="name" /> <DateField label="Date of Birth" source="dateOfBirth" /> <TextField label="Gender" source="gender" /> <TextField label="Address" source="address" /> </ShowTemplate> ); export default withStyles(styles)(PatientShow);
Patient Edit Page

API URL
/mpi/Patient/{patientId}
PUT data
{ address: { city: "Redhill", country: "United Kingdom", district: "Surrey", line: "3 Cooper Walk", postalCode: "RH1 6SF", }, birthDate: "1956-11-10", gender: "male", id: "9999999801", name: { family: "Tweed", given: [ 0: "Rob", ], prefix: "Mr", telecom: "+779017 876" }, }
Component structure
import React from "react"; import EditTemplate from "../../common/ResourseTemplates/EditTemplate"; import FormInputs from "./fragments/FormInputs"; const PatientEdit = ({ classes, ...rest }) => ( <EditTemplate blockTitle="Patient" {...rest}> <FormInputs /> </EditTemplate> ); export default PatientEdit;
Patient Create Page

API URL
/mpi/Patient/{patientId}
POST data
address: { city: "Redhill", country: "United Kingdom", district: "Surrey", line: "3 Cooper Walk", postalCode: "RH1 6SF", }, birthDate: "1956-11-10", gender: "male", id: "9999999801", name: { family: "Tweed", given: [ 0: "Rob", ], prefix: "Mr", telecom: "+779017 876" },
Component structure
import React from "react"; import CreateTemplate from "../../common/ResourseTemplates/CreateTemplate"; import FormInputs from "./fragments/FormInputs"; const PatientCreate = props => ( <CreateTemplate blockTitle="Patient" {...props}> <FormInputs /> </CreateTemplate> ); export default PatientCreate;