From 8ada43f313e46b57101274be9ccfc17fa7fa74e4 Mon Sep 17 00:00:00 2001 From: inportb Date: Mon, 8 May 2023 22:55:20 -0400 Subject: [PATCH] Report viewer --- htdocs/App.vue | 7 ++ htdocs/RoutePatient.vue | 3 +- htdocs/RoutePatientReports.vue | 147 +++++++++++++++++++++++++++++++++ htdocs/vistax.mjs | 18 ++++ 4 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 htdocs/RoutePatientReports.vue diff --git a/htdocs/App.vue b/htdocs/App.vue index 3c45940..5b4f44d 100644 --- a/htdocs/App.vue +++ b/htdocs/App.vue @@ -21,6 +21,7 @@ import RoutePatientDetail from './RoutePatientDetail.vue'; import RoutePatientVisits from './RoutePatientVisits.vue'; import RoutePatientOrders from './RoutePatientOrders.vue'; + import RoutePatientReports from './RoutePatientReports.vue'; import RoutePlanner from './RoutePlanner.vue'; import RouteRecall from './RouteRecall.vue'; import RouteInbox from './RouteInbox.vue'; @@ -63,6 +64,12 @@ { path: '', component: RoutePatientDetail }, { path: 'visits', component: RoutePatientVisits }, { path: 'orders', component: RoutePatientOrders }, + { path: 'reports', component: RoutePatientReports }, + { path: 'reports/bloodbank', component: RoutePatientReports, props: { report_name: 'Blood Bank' } }, + { path: 'reports/microbiology', component: RoutePatientReports, props: { report_name: 'Microbiology' } }, + { path: 'reports/pathology', component: RoutePatientReports, props: { report_name: 'Pathology' } }, + { path: 'reports/radiology', component: RoutePatientReports, props: { report_name: 'Radiology' } }, + { path: 'reports/notes', component: RoutePatientReports, props: { report_name: 'Notes' } }, ] }, { path: '/planner', component: RoutePlanner }, { path: '/recall', component: RouteRecall }, diff --git a/htdocs/RoutePatient.vue b/htdocs/RoutePatient.vue index 56bba5a..629852f 100644 --- a/htdocs/RoutePatient.vue +++ b/htdocs/RoutePatient.vue @@ -51,7 +51,8 @@ items: [ { name: 'Patient', href: '/patient/' + this.patient_dfn + (this.sensitive && '?viewsensitive' || '') }, { name: 'Visits', href: '/patient/' + this.patient_dfn + '/visits' + (this.sensitive && '?viewsensitive' || '') }, - { name: 'Orders', href: '/patient/' + this.patient_dfn + '/orders' + (this.sensitive && '?viewsensitive' || '') } + { name: 'Orders', href: '/patient/' + this.patient_dfn + '/orders' + (this.sensitive && '?viewsensitive' || '') }, + { name: 'Reports', href: '/patient/' + this.patient_dfn + '/reports' + (this.sensitive && '?viewsensitive' || '') }, ] } : null; } diff --git a/htdocs/RoutePatientReports.vue b/htdocs/RoutePatientReports.vue new file mode 100644 index 0000000..1f9bb93 --- /dev/null +++ b/htdocs/RoutePatientReports.vue @@ -0,0 +1,147 @@ + + + + + diff --git a/htdocs/vistax.mjs b/htdocs/vistax.mjs index ac6ff5e..0e1da02 100644 --- a/htdocs/vistax.mjs +++ b/htdocs/vistax.mjs @@ -170,6 +170,22 @@ export const d_parse_notifications_fastuser = data => d_split(data, '^', 'info', return row; }); +export const d_parse_multireport = data => { + if(data.length < 1) return []; + var brk, max = 0, grp; + for(var i = 0; i < data.length; ++i) { + brk = (grp = data[i]).indexOf('^'); + if(brk >= 0) { + grp = +grp.substring(0, brk); + if(grp >= max) max = grp; + else break; + } else return [data]; + } + var res = [], data = data.slice(), max = max + '^', grp = x => x.startsWith(max); + while(((brk = data.findIndex(grp)) >= 0) || (brk = data.length)) res.push(data.splice(0, brk + 1)); + return res; +}; + export function memoized(fn) { var cache = {}; return async function(...args) { @@ -268,6 +284,8 @@ export function Client(cid, secret) { this.ORWLRR_INTERIM = aflow((...args) => this.call({ method: 'ORWLRR_INTERIM', context: ['OR CPRS GUI CHART'], ttl: 60, stale: false }, ...args), d_log, d_unwrap, lab_parse); this.ORWLRR_INTERIM_RESULTS = async (...args) => lab_reparse_results(await this.ORWLRR_INTERIM(...args)); + this.ORWRP_REPORT_TEXT = aflow((...args) => this.call({ method: 'ORWRP_REPORT_TEXT', context: ['OR CPRS GUI CHART'], ttl: 60, stale: false }, ...args), d_log, d_unwrap, d_parse_array, d_parse_multireport); + this.ORWORDG_ALLTREE = memoized(aflow(() => this.callctx(['OR CPRS GUI CHART'], 'ORWORDG_ALLTREE'), d_log, d_unwrap, f_split('^', 'ien', 'name', 'parent', 'has_children'))); this.ORWORDG_REVSTS = memoized(aflow(() => this.callctx(['OR CPRS GUI CHART'], 'ORWORDG_REVSTS'), d_log, d_unwrap, f_split('^', 'ien', 'name', 'parent', 'has_children'))); this.ORWORR_AGET = memoized(aflow((...args) => this.callctx(['OR CPRS GUI CHART'], 'ORWORR_AGET', ...args), d_log, d_unwrap, f_slice(1), f_split('^', 'ifn', 'dgrp', 'time')));