From 24940b4e80315f94cb92bfcbf34300cf8ddc30ec Mon Sep 17 00:00:00 2001 From: Jack Meyer Date: Tue, 19 Nov 2019 22:33:51 -0600 Subject: [PATCH] feat(init): creates a generic repository class and refactors patient db --- package.json | 4 +- src/clients/db/PatientRepository.ts | 11 ++++ src/clients/db/Repository.ts | 78 +++++++++++++++++++++++++++++ src/clients/db/patients-db.ts | 63 ----------------------- src/containers/Patients.tsx | 2 +- src/containers/ViewPatient.tsx | 8 ++- src/slices/patient-slice.ts | 8 +-- src/slices/patients-slice.ts | 4 +- 8 files changed, 104 insertions(+), 74 deletions(-) create mode 100644 src/clients/db/PatientRepository.ts create mode 100644 src/clients/db/Repository.ts delete mode 100644 src/clients/db/patients-db.ts diff --git a/package.json b/package.json index ab83d5daec..fd56fb4dca 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,6 @@ "@semantic-release/changelog": "~3.0.4", "@semantic-release/git": "~7.0.16", "@semantic-release/release-notes-generator": "~7.3.0", - "@types/react-redux": "~7.1.5", - "@types/redux-logger": "~3.0.7", "bootstrap": "~4.3.1", "pouchdb": "~7.1.1", "react": "~16.12.0", @@ -49,8 +47,10 @@ "@types/pouchdb": "~6.4.0", "@types/react": "~16.9.6", "@types/react-dom": "~16.9.1", + "@types/react-redux": "^7.1.5", "@types/react-router": "~5.1.2", "@types/react-router-dom": "~5.1.0", + "@types/redux-logger": "^3.0.7", "@typescript-eslint/eslint-plugin": "~2.4.0", "@typescript-eslint/parser": "~2.4.0", "commitizen": "~4.0.3", diff --git a/src/clients/db/PatientRepository.ts b/src/clients/db/PatientRepository.ts new file mode 100644 index 0000000000..b58f346c84 --- /dev/null +++ b/src/clients/db/PatientRepository.ts @@ -0,0 +1,11 @@ +import Patient from 'model/Patient' +import Repository from './Repository' +import { patients } from '../../config/pouchdb' + +export class PatientRepsitory extends Repository { + constructor() { + super(patients) + } +} + +export default new PatientRepsitory() diff --git a/src/clients/db/Repository.ts b/src/clients/db/Repository.ts new file mode 100644 index 0000000000..eb2287c44d --- /dev/null +++ b/src/clients/db/Repository.ts @@ -0,0 +1,78 @@ +/* eslint "@typescript-eslint/camelcase": "off" */ + +import AbstractDBModel from 'model/AbstractDBModel' + +function mapRow(row: any): any { + const { value, doc } = row + const { id, _rev, _id, rev, ...restOfDoc } = doc + return { + id: _id, + rev: value.rev, + ...restOfDoc, + } +} + +function mapDocument(document: any): any { + const { _id, _rev, ...values } = document + return { + id: _id, + rev: _rev, + ...values, + } +} + +export default class Repository { + db: PouchDB.Database + + constructor(db: PouchDB.Database) { + this.db = db + } + + async find(id: string): Promise { + const document = await this.db.get(id) + return mapDocument(document) + } + + async findAll(): Promise { + const allPatients = await this.db.allDocs({ + include_docs: true, + }) + + return allPatients.rows.map(mapRow) + } + + async save(entity: T): Promise { + const { id, rev, ...valuesToSave } = entity + const savedEntity = await this.db.post({ ...valuesToSave }) + return this.find(savedEntity.id) + } + + async saveOrUpdate(entity: T): Promise { + const e = entity as any + try { + // try and get a patient, if the patient is missing it will throw an error + // and have a status of 404. + await this.db.get(e.id) + const { id, rev, ...restOfDocument } = e + const updatedDcoument = { + _id: id, + _rev: rev, + ...restOfDocument, + } + + await this.db.put(updatedDcoument) + return this.find(e.id) + } catch (error) { + if (error.status !== 404) { + throw Error(error) + } + + return this.save(e) + } + } + + async delete(entity: T): Promise { + const e = entity as any + return mapDocument(this.db.remove(e.id, e.rev)) + } +} diff --git a/src/clients/db/patients-db.ts b/src/clients/db/patients-db.ts deleted file mode 100644 index 3198a33627..0000000000 --- a/src/clients/db/patients-db.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* eslint-disable no-underscore-dangle, @typescript-eslint/camelcase */ -import Patient from '../../model/Patient' -import { patients } from '../../config/pouchdb' - -function mapRowToPatient(row: any): Patient { - return new Patient(row.id, row.value.rev, row.doc.firstName, row.doc.lastName) -} - -function mapDocumentToPatient(document: any): Patient { - return new Patient(document._id, document._rev, document.firstName, document.lastName) -} - -export async function get(id: string): Promise { - const document = await patients.get(id) - return mapDocumentToPatient(document as any) -} - -export async function getAll(): Promise { - const allPatients = await patients.allDocs({ - include_docs: true, - }) - - return allPatients.rows.map((r) => { - const row = r as any - return mapRowToPatient(row) - }) -} - -export async function save(patient: Patient): Promise { - const newPatient = await patients.post(patient) - return get(newPatient.id) -} - -export async function saveOrUpdate(patient: Patient) { - try { - // try and get a patient, if the patient is missing it will throw an error - // and have a status of 404. - await patients.get(patient.id) - const { id, rev, ...restOfPatient } = patient - const updatedDcoument = { - _id: id, - _rev: rev, - ...restOfPatient, - } - - await patients.put(updatedDcoument) - return get(patient.id) - } catch (error) { - if (error.status !== 404) { - throw Error(error) - } - - return save(patient) - } -} - -export async function deleteDocument(document: any) { - return patients.remove(document) -} - -export async function deleteDocumentById(id: string, revId: string) { - return patients.remove(id, revId) -} diff --git a/src/containers/Patients.tsx b/src/containers/Patients.tsx index ffbe12632c..1442d4d414 100644 --- a/src/containers/Patients.tsx +++ b/src/containers/Patients.tsx @@ -19,7 +19,7 @@ const Patients = () => { const list = (
    {patients.map((p) => ( - +
  • {p.firstName} {p.lastName}
  • diff --git a/src/containers/ViewPatient.tsx b/src/containers/ViewPatient.tsx index 87f7615dd8..484e4f81c9 100644 --- a/src/containers/ViewPatient.tsx +++ b/src/containers/ViewPatient.tsx @@ -12,6 +12,7 @@ interface Props extends RouteComponentProps { } const ViewPatient = (props: Props) => { + const [currentPatient, setCurrentPatient] = useState(new Patient('', '', '', '')) const { match } = props const { id } = match.params as any const dispatch = useDispatch() @@ -19,7 +20,9 @@ const ViewPatient = (props: Props) => { const { patient, isLoading, isUpdated } = useSelector((state: RootState) => state.patient) const onSaveButtonClick = async () => { - dispatch(updatePatient(patient)) + currentPatient.id = patient.id + currentPatient.rev = patient.rev + dispatch(updatePatient(currentPatient)) setIsEditable(false) } @@ -33,7 +36,8 @@ const ViewPatient = (props: Props) => { } const onFieldChange = (key: string, value: string) => { - ;(patient as any)[key] = value + ;(currentPatient as any)[key] = value + setCurrentPatient(currentPatient) } useEffect(() => { diff --git a/src/slices/patient-slice.ts b/src/slices/patient-slice.ts index 50ee9c3358..1511540abb 100644 --- a/src/slices/patient-slice.ts +++ b/src/slices/patient-slice.ts @@ -1,6 +1,6 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit' import Patient from '../model/Patient' -import * as patientsDb from '../clients/db/patients-db' +import PatientRepository from '../clients/db/PatientRepository' import { AppThunk } from '../store/store' interface PatientState { @@ -54,7 +54,7 @@ export const { export const fetchPatient = (id: string): AppThunk => async (dispatch) => { try { dispatch(getPatientStart()) - const patient = await patientsDb.get(id) + const patient = await PatientRepository.find(id) dispatch(getPatientSuccess(patient)) } catch (error) { console.log(error) @@ -63,7 +63,7 @@ export const fetchPatient = (id: string): AppThunk => async (dispatch) => { export const updatePatient = (patient: Patient): AppThunk => async (dispatch) => { try { - const updatedPatient = await patientsDb.saveOrUpdate(patient) + const updatedPatient = await PatientRepository.saveOrUpdate(patient) dispatch(updatePatientSuccess(updatedPatient)) } catch (error) { console.log(error) @@ -72,7 +72,7 @@ export const updatePatient = (patient: Patient): AppThunk => async (dispatch) => export const createPatient = (patient: Patient): AppThunk => async (dispatch) => { try { - const newPatient = await patientsDb.save(patient) + const newPatient = await PatientRepository.save(patient) dispatch(createPatientSuccess(newPatient)) } catch (error) { console.log(error) diff --git a/src/slices/patients-slice.ts b/src/slices/patients-slice.ts index e51e07036e..221e0036ab 100644 --- a/src/slices/patients-slice.ts +++ b/src/slices/patients-slice.ts @@ -1,6 +1,6 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit' import Patient from '../model/Patient' -import * as patientsDb from '../clients/db/patients-db' +import PatientRepository from '../clients/db/PatientRepository' import { AppThunk } from '../store/store' interface PatientsState { @@ -34,7 +34,7 @@ export const { getPatientsStart, getAllPatientsSuccess } = patientsSlice.actions export const fetchPatients = (): AppThunk => async (dispatch) => { try { dispatch(getPatientsStart()) - const patients = await patientsDb.getAll() + const patients = await PatientRepository.findAll() dispatch(getAllPatientsSuccess(patients)) } catch (error) { console.log(error)