removed pouchdb-find plugin, WORKING.

This commit is contained in:
Jason Kulatunga 2022-10-06 18:30:55 -07:00
parent d9038f700c
commit b13d3b78e0
12 changed files with 94 additions and 58 deletions

View File

@ -30,6 +30,7 @@
"@panva/oauth4webapi": "^1.1.3",
"@swimlane/ngx-datatable": "^20.0.0",
"@types/pouchdb": "^6.4.0",
"@types/pouchdb-find": "^7.3.0",
"bootstrap": "^4.4.1",
"chart.js": "2.9.4",
"fhirclient": "^2.5.1",

View File

@ -148,7 +148,7 @@
<div class="media-body">
<h5>{{metadataSource[source.source_type]?.display}}</h5>
<p>
{{getPatientSummary(patientForSource[source.id]?.payload)}}
{{getPatientSummary(patientForSource[source.id]?.resource_raw)}}
</p>
</div>

View File

@ -1,12 +1,13 @@
import { Component, OnInit } from '@angular/core';
import {FastenApiService} from '../../services/fasten-api.service';
import {Source} from '../../models/fasten/source';
import {Source} from '../../../lib/models/database/source';
import {Router} from '@angular/router';
import {Summary} from '../../models/fasten/summary';
import {ResourceTypeCounts} from '../../models/fasten/source-summary';
import {ResourceFhir} from '../../models/fasten/resource_fhir';
import {ResourceFhir} from '../../../lib/models/database/resource_fhir';
import {forkJoin} from 'rxjs';
import {MetadataSource} from '../../models/fasten/metadata-source';
import {FastenDbService} from '../../services/fasten-db.service';
import {Summary} from '../../../lib/models/fasten/summary';
import {Base64} from '../../../lib/utils/base64';
@Component({
selector: 'app-dashboard',
@ -22,7 +23,11 @@ export class DashboardComponent implements OnInit {
metadataSource: { [name: string]: MetadataSource }
constructor(private fastenApi: FastenApiService, private router: Router) { }
constructor(
private fastenApi: FastenApiService,
private fastenDb: FastenDbService,
private router: Router
) { }
ngOnInit() {
@ -44,7 +49,7 @@ export class DashboardComponent implements OnInit {
// })
// })
forkJoin([this.fastenApi.getSummary(), this.fastenApi.getMetadataSources()]).subscribe(results => {
forkJoin([this.fastenDb.GetSummary(), this.fastenApi.getMetadataSources()]).subscribe(results => {
let summary = results[0] as Summary
let metadataSource = results[1] as { [name: string]: MetadataSource }
@ -59,7 +64,6 @@ export class DashboardComponent implements OnInit {
"enabled": true,
}
//calculate the number of records
summary.resource_type_counts.forEach((resourceTypeInfo) => {
this.recordsCount += resourceTypeInfo.count
@ -71,16 +75,13 @@ export class DashboardComponent implements OnInit {
summary.patients.forEach((resourceFhir) => {
this.patientForSource[resourceFhir.source_id] = resourceFhir
})
});
}
selectSource(selectedSource: Source){
this.router.navigateByUrl(`/source/${selectedSource.id}`, {
this.router.navigateByUrl(`/source/${Base64.Encode(selectedSource._id)}`, {
state: selectedSource
});
}

View File

@ -18,7 +18,7 @@
<div class="patient-row row">
<div class="col-7 patient-name"><h3 class="pull-left text-primary">{{getPatientName()}}</h3></div>
<div class="col-5">
<a routerLink="/source/{{selectedSource.id}}/resource/{{selectedPatient.source_resource_id}}" class="btn btn-indigo btn-icon float-right">
<a routerLink="/source/{{selectedSource._id}}/resource/{{selectedPatient.source_resource_id}}" class="btn btn-indigo btn-icon float-right">
<i class="fas fa-info-circle"></i>
</a>
</div>

View File

@ -1,9 +1,10 @@
import {Component, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {Source} from '../../models/fasten/source';
import {FastenApiService} from '../../services/fasten-api.service';
import {ResourceFhir} from '../../models/fasten/resource_fhir';
import {Source} from '../../../lib/models/database/source';
import {FastenDbService} from '../../services/fasten-db.service';
import {ResourceFhir} from '../../../lib/models/database/resource_fhir';
import {getPath} from '../../components/list-generic-resource/utils';
import {Base64} from '../../../lib/utils/base64';
@Component({
@ -19,7 +20,7 @@ export class SourceDetailComponent implements OnInit {
resourceTypeCounts: { [name: string]: number } = {}
constructor(private fastenApi: FastenApiService, private router: Router, private route: ActivatedRoute) {
constructor(private fastenDb: FastenDbService, private router: Router, private route: ActivatedRoute) {
//check if the current Source was sent over using the router state storage:
if(this.router.getCurrentNavigation().extras.state){
this.selectedSource = this.router.getCurrentNavigation().extras.state as Source
@ -28,7 +29,7 @@ export class SourceDetailComponent implements OnInit {
ngOnInit(): void {
//always request the source summary
this.fastenApi.getSourceSummary(this.route.snapshot.paramMap.get('source_id')).subscribe((sourceSummary) => {
this.fastenDb.GetSourceSummary(Base64.Decode(this.route.snapshot.paramMap.get('source_id'))).then((sourceSummary) => {
this.selectedSource = sourceSummary.source;
this.selectedPatient = sourceSummary.patient;
for(let resourceTypeCount of sourceSummary.resource_type_counts){
@ -47,24 +48,24 @@ export class SourceDetailComponent implements OnInit {
return `${getPath(this.selectedPatient?.payload, 'name.0.family')}, ${getPath(this.selectedPatient?.payload, 'name.0.given').join(' ')}`
}
getPatientGender(){
return getPath(this.selectedPatient?.payload, 'gender')
return getPath(this.selectedPatient?.resource_raw, 'gender')
}
getPatientMRN(){
return getPath(this.selectedPatient?.payload, 'identifier.0.value')
return getPath(this.selectedPatient?.resource_raw, 'identifier.0.value')
}
getPatientEmail(){
// @ts-ignore
return (this.selectedPatient?.payload?.telecom || []).filter(
return (this.selectedPatient?.resource_raw?.telecom || []).filter(
telecom => telecom.system === 'email',
)[0]?.value
}
getPatientDOB(){
return getPath(this.selectedPatient?.payload, 'birthDate')
return getPath(this.selectedPatient?.resource_raw, 'birthDate')
}
getPatientPhone(){
// @ts-ignore
return (this.selectedPatient?.payload?.telecom || []).filter(
return (this.selectedPatient?.resource_raw?.telecom || []).filter(
telecom => telecom.system === 'phone',
)[0]?.value
}
@ -72,9 +73,9 @@ export class SourceDetailComponent implements OnInit {
return ''
}
getPatientAddress(){
const line = getPath(this.selectedPatient?.payload, 'address.0.line')
const city = getPath(this.selectedPatient?.payload, 'address.0.city')
const state = getPath(this.selectedPatient?.payload, 'address.0.state')
const line = getPath(this.selectedPatient?.resource_raw, 'address.0.line')
const city = getPath(this.selectedPatient?.resource_raw, 'address.0.city')
const state = getPath(this.selectedPatient?.resource_raw, 'address.0.state')
return `${line}, ${city}, ${state}`
}

View File

@ -1,7 +1,7 @@
import {Source} from '../models/database/source';
import {IDatabasePaginatedResponse, IDatabaseDocument, IDatabaseRepository} from './interface';
import * as PouchDB from 'pouchdb/dist/pouchdb';
import PouchFind from 'pouchdb/dist/pouchdb.find';
// import * as PouchFind from 'pouchdb/dist/pouchdb.find';
// import * as PouchDB from 'pouchdb';
import {DocType} from './constants';
import {ResourceFhir} from '../models/database/resource_fhir';
@ -18,20 +18,20 @@ export class PouchdbRepository implements IDatabaseRepository {
localPouchDb: PouchDB.Database
constructor(public databaseName: string) {
//setup PouchDB Plugins
PouchDB.plugin(PouchFind); //https://pouchdb.com/guides/mango-queries.html
// PouchDB.plugin(PouchFind); //https://pouchdb.com/guides/mango-queries.html
this.localPouchDb = new PouchDB(databaseName);
//create any necessary indexes
// this index allows us to group by source_resource_type
this.localPouchDb.createIndex({
index: {fields: [
//global
'doc_type',
//only relevant for resource_fhir documents
'source_resource_type',
]}
}, (msg) => {console.log("DB createIndex complete", msg)});
// this.localPouchDb.createIndex({
// index: {fields: [
// //global
// 'doc_type',
// //only relevant for resource_fhir documents
// 'source_resource_type',
// ]}
// }, (msg) => {console.log("DB createIndex complete", msg)});
}
@ -48,24 +48,28 @@ export class PouchdbRepository implements IDatabaseRepository {
summary.sources = await this.GetSources()
.then((paginatedResp) => paginatedResp.rows)
summary.patients = await this.GetDB().find({
selector: {
doc_type: DocType.ResourceFhir,
source_resource_type: "Patient",
}
})
summary.patients = []
// summary.patients = await this.GetDB().find({
// selector: {
// doc_type: DocType.ResourceFhir,
// source_resource_type: "Patient",
// }
// })
summary.resource_type_counts = await this.findDocumentByPrefix(`${DocType.ResourceFhir}`, true)
summary.resource_type_counts = await this.findDocumentByPrefix(`${DocType.ResourceFhir}`, false)
.then((paginatedResp) => {
const lookup: {[name: string]: ResourceTypeCounts} = {}
paginatedResp?.rows.forEach((resource: ResourceFhir) => {
let currentResourceStats = lookup[resource.source_resource_type] || {
paginatedResp?.rows.forEach((resourceWrapper) => {
const resourceIdParts = resourceWrapper.id.split(':')
const resourceType = resourceIdParts[2]
let currentResourceStats = lookup[resourceType] || {
count: 0,
source_id: resource.source_id,
resource_type: resource.source_resource_type
source_id: Base64.Decode(resourceIdParts[1]),
resource_type: resourceType
}
currentResourceStats.count += 1
lookup[resource.source_resource_type] = currentResourceStats
lookup[resourceType] = currentResourceStats
})
const arr = []
@ -110,17 +114,20 @@ export class PouchdbRepository implements IDatabaseRepository {
sourceSummary.patient = await this.findDocumentByPrefix(`${DocType.ResourceFhir}:${Base64.Encode(source_id)}:Patient`, true)
.then((paginatedResp) => paginatedResp?.rows[0])
sourceSummary.resource_type_counts = await this.findDocumentByPrefix(`${DocType.ResourceFhir}:${Base64.Encode(source_id)}`, true)
sourceSummary.resource_type_counts = await this.findDocumentByPrefix(`${DocType.ResourceFhir}:${Base64.Encode(source_id)}`, false)
.then((paginatedResp) => {
const lookup: {[name: string]: ResourceTypeCounts} = {}
paginatedResp?.rows.forEach((resource: ResourceFhir) => {
let currentResourceStats = lookup[resource.source_resource_type] || {
paginatedResp?.rows.forEach((resourceWrapper) => {
const resourceIdParts = resourceWrapper.id.split(':')
const resourceType = resourceIdParts[2]
let currentResourceStats = lookup[resourceType] || {
count: 0,
source_id: resource.source_id,
resource_type: resource.source_resource_type
source_id: Base64.Decode(resourceIdParts[1]),
resource_type: resourceType
}
currentResourceStats.count += 1
lookup[resource.source_resource_type] = currentResourceStats
lookup[resourceType] = currentResourceStats
})
const arr = []

View File

@ -1,5 +1,5 @@
import {Source} from './source';
import {ResourceFhir} from './resource_fhir';
import {Source} from '../database/source';
import {ResourceFhir} from '../database/resource_fhir';
export class ResourceTypeCounts {
count: number

View File

@ -1,6 +1,6 @@
import {Source} from './source';
import {Source} from '../database/source';
import {ResourceTypeCounts} from './source-summary';
import {ResourceFhir} from './resource_fhir';
import {ResourceFhir} from '../database/resource_fhir';
export class Summary {
sources: Source[]

View File

@ -1,6 +1,7 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"skipLibCheck": true, //this is because fhirclient types.d.ts file includes reference to "http" (Node) library
"outDir": "./out-tsc/app",
"types": []
},

View File

@ -11,9 +11,11 @@
"module": "esnext",
"moduleResolution": "node",
"importHelpers": true,
"target": "esnext",
"typeRoots": ["node_modules/@types"],
"lib": [
"es2019",
"es2018",
"dom"
]

View File

@ -0,0 +1,16 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/worker",
"lib": [
"es2019",
"es2018",
"webworker"
],
"types": []
},
"include": [
"src/**/*.worker.ts"
]
}

View File

@ -1847,6 +1847,13 @@
dependencies:
"@types/pouchdb-core" "*"
"@types/pouchdb-find@^7.3.0":
version "7.3.0"
resolved "https://registry.yarnpkg.com/@types/pouchdb-find/-/pouchdb-find-7.3.0.tgz#b917030e9f4bf6e56bf8c3b9fe4b2a25e989009a"
integrity sha512-sFPli5tBjGX9UfXioik1jUzPdcN84eV82n0lmEFuoPepWqkLjQcyri0eOa++HYOaNPyMDhKFBqEALEZivK2dRg==
dependencies:
"@types/pouchdb-core" "*"
"@types/pouchdb-http@*":
version "6.1.3"
resolved "https://registry.yarnpkg.com/@types/pouchdb-http/-/pouchdb-http-6.1.3.tgz#09576c0d409da1f8dee34ec5b768415e2472ea52"