Events module

General information

Events is a non-core plugin of PulseTile-RA. It is used to create, edit and review information about Events of the current patient. Actions, Reducer and Sagas required for the Events plugin are created automatically by React-Admin framework, because all operations are typical.

Events List

Events List
Events List
API URL
  /api/patients/{patientId}/events
GET response
  {
    dateCreated: 1454669420000,
    dateTime: 1452595820958,
    description: "Complications following surgery",
    name: "Transfer from ward to ICU",
    source: "ethercis",
    sourceId: "ethercis-be7d9647-3c6e-41dd-a1c9-4aaa0c60c81b",
    type: "Transfer",
  }
Component structure
import React from "react";
import { DateField, TextField } from "react-admin";

import ListTemplate from "../../../core/common/ResourseTemplates/ListTemplate";
import EventsCreate from "./EventsCreate";
import EventsEdit from "./EventsEdit";
import EventsShow from "./EventsShow";
import EventsTimeline from "./EventsTimeline";
import DatagridRow from "./fragments/DatagridRow";

const EventsList = ({ classes, ...rest }) => (
    <ListTemplate
            create={EventsCreate}
            edit={EventsEdit}
            show={EventsShow}
            resourceUrl="events"
            title="Events"
            hasTimetable={true}
            timelineBlock={EventsTimeline}
            CustomRow={DatagridRow}
            isCustomDatagrid={true}
            {...rest}
    >
        <TextField label="Event Name" source="noteType" />
        <TextField label="Event Type" source="author" />
        <DateField label="Date" source="dateCreated" />
    </ListTemplate>
);

export default EventsList;

Event Detail

Event Detail
Event Detail
API URL
  /api/patients/{patientId}/events/{sourceId}
GET response
  {
    author: "Dr. Smith",
    dateCreated: 1563464410000,
    dateTime: 1563447600000,
    description: "Needs nursing and supervisory care",
    name: "Discharge to care home",
    source: "ethercis",
    sourceId: "ethercis-bec0e163-6a1f-4f7a-bb13-1e1d5110b62e",
    type: "Discharge",
  }
Component structure
import React from "react";
import { TextField, DateField } from "react-admin";
import { withStyles } from '@material-ui/core/styles';

import ShowTemplate from "../../../core/common/ResourseTemplates/ShowTemplate";

const EventsShow = ({ classes, ...rest }) => (
    <ShowTemplate pageTitle="Event" {...rest}>
        <TextField source="name" label="Event Name" />
        <TextField source="type" label="Event Type" />
        <TextField source="description" label="Notes" />
        <DateField source="dateTime" label="Event Date" showTime />
    </ShowTemplate>
);

export default withStyles(styles)(EventsShow);

Event Edit Page

Event Edit
Event Edit
API URL
  /api/patients/{patientId}/events/{sourceId}
PUT data
{
    author: "Dr. Smith",
    dateCreated: 1563464410000,
    dateTime: "2019-07-18T11:00:00.000Z",
    description: "Needs nursing and supervisory care",
    id: "ethercis-bec0e163-6a1f-4f7a-bb13-1e1d5110b62e",
    name: "Discharge to care home",
    source: "ethercis",
    type: "Discharge",
    userId: "9999999801",
}
Component structure
import React from "react";

import EditTemplate from "../../../core/common/ResourseTemplates/EditTemplate";
import Form from "./fragments/Form";

const EventsEdit = props => (
    <EditTemplate isCustom={true} blockTitle="Event" {...props}>
        <Form {...props} />
    </EditTemplate>
);

export default EventsEdit;

Event Create Page

Event Create
Event Create
API URL
  /api/patients/{patientId}/events
POST data
  {
    author: "Robert Tweed",
    dateCreated: 1563966657000,
    dateTime: "2019-07-02T10:45:00.000Z",
    description: "Test",
    name: "Test",
    type: "Appointment",
    userId: "9999999801",
  }
Component structure
import React from "react";

import CreateTemplate from "../../../core/common/ResourseTemplates/CreateTemplate";
import Form from "./fragments/Form";

const EventsCreate = props => (
    <CreateTemplate isCustom={true} blockTitle="Event" {...props}>
        <Form isCreate={true} {...props} />
    </CreateTemplate>
);

export default EventsCreate;

Events Timeline

Events timeline presents a list of events for current patient, displayed as timeline. It can be open by selecting "Event Timeline" in the right corner of the Events list block. Events timeline use the same GET-request, which is used in Events table.

Event Timeline Switcher
Event Timeline Switcher
Event Create
import React from "react";
import _ from "lodash";
import get from "lodash/get";
import moment from "moment";
import { connect } from 'react-redux';
import { Toolbar } from "react-admin";

import {
    Timeline,
    Content,
    ContentYear,
    ContentBody,
} from 'vertical-timeline-component-react';

import { withStyles } from "@material-ui/core/styles";
import Typography from "@material-ui/core/Typography";

import CreateButton from "../../../core/common/Buttons/CreateButton";

const styles = theme => ({
    ...
    ...
    ...
});

const CustomHeader = ({ classes, items, history }) => {

    const dateAndTime = items[0];
    const events = items[1];
    const dateForPoint = moment.unix(dateAndTime).format('Do MMM')

    return (
        <Content>
            <ContentYear year={<EventDate classes={classes} label={dateForPoint} />} />
            <ContentBody>
                {
                    events.map(item => {
                        let eventRoute = '/events/' + get(item, 'sourceId', null);
                        let dateTime = moment(get(item, 'dateTime', null)).format('DD-MM-YYYY HH:mm');
                        return (
                            <div className={classes.eventBlock} onClick={() => history.push(eventRoute)}>
                                <Typography variant="body1" className={classes.eventType}>{get(item, 'type', null)}</Typography>
                                <div className={classes.eventDescription}>
                                    <Typography className={classes.eventTitle} variant="h1">{get(item, 'name', null)}</Typography>
                                    <<Typography variant="caption">{dateTime}</Typography>
                                </div>
                            </div>
                        )
                    })
                }
            </ContentBody>
        </Content>
    );
};

const EventDate = ({ classes, label }) => {
    const dateArray = label.split(' ');
    return (
        <div className={classes.eventDate}>
            <Typography variant="body1">{dateArray[0]}</Typography>
            <Typography variant="body1">{dateArray[1]}</Typography>
        </div>
    )
}

const EventsTimeline = ({ classes, eventsList, history, createUrl }) => {
    const eventsGroupByDate = _.mapValues(_.groupBy(eventsList, 'dateCreated'),
        clist => clist.map(event => _.omit(event, 'date')));
    const eventsGroupByDateArray = Object.entries(eventsGroupByDate);
    return (
        <React.Fragment>
            <div className={classes.timeline}>
                <Timeline>
                    { eventsGroupByDateArray.map(item => {
                        return (
                            <CustomHeader classes={classes} items={item} history={history} />
                        )
                    })}
                    <Content>
                        <ContentYear />
                    </Content>
                </Timeline>
            </div>
            {
                createUrl &&
                    <Toolbar className={classes.toolbar}>
                        <CreateButton history={history} redirectPath={createUrl} />
                    </Toolbar>
            }
        </React.Fragment>
    );
};

const mapStateToProps = state => {
    return {
        eventsList: get(state, 'admin.resources.events.data', []),
    };
};

export default connect(mapStateToProps, null)(withStyles(styles)(EventsTimeline));