- 15 Nov 2023
- 14 Minutes to read
- Print
- DarkLight
VHR Configuration
- Updated on 15 Nov 2023
- 14 Minutes to read
- Print
- DarkLight
VHR comes with five configurable files. Some of the elements within the files are not configurable and should not be changed. If there is any question if information can be changed, contact professional services.
hl7-abnormal-lab-flags.json
// This file is to assist in mapping more user friendly labels from the normality data provided in lab concepts
// Normality fields
{
"N": {
"name": "",
"image": "/branding/images/lab-flags/blank.gif"
},
...
"Neg": {
"name": "Negative",
"desc": "Drug results and discrete microbiology",
"image": "/branding/images/lab-flags/negative.png"
},
"Pos": {
"name": "Positive",
"desc": "Drug results and discrete microbiology",
"image": "/branding/images/lab-flags/positive.png"
}
}
hl7-record-type-labels.json
// This file is to assist in mapping more user friendly labels from HL7 data. The file has a subset of ADT trigger events.
{
"A01": "Admit/visit notification",
"A02": "Transfer a patient",
...
"A28": "Patient visit/encounter",
"S12": "Patient visit check in"
}
vhr-app.json
WARNING: Comments, indicated by //, are not valid in the actual json file and are here for instructional purposes only.
// The vhr-app.json can be edited in the files section of the Configuration section of the Admin Console.
// The reportId is the compound query report id that provides data for the page.
// The groups label is to indicate which groups have access if the page is a limited-access page. The default is empty, [], so all users have access.
{
"customerAppName": "IMAT-VHR", // The name as it appears on the browser tab after the page name
"customerHelpLink": "/ui/documentation/#/guides/vhr", // The link to the help document, the link provided here is IMAT's VHR user guide
"customerPrintSource": "IMAT Print Source", // The source that appears at the top of printed views of individual records
"reportDebugMode": true, // debug report with polling config
"includes": { // DO NOT change any of the items in "includes"
"fields": "vhr-fields.json",
"grids": "vhr-grids.json",
"abnormalLabFlags": "hl7-abnormal-lab-flags.json",
"hl7Labels": "hl7-record-type-labels.json",
"widgets": "vhr-widgets.json"
},
"landingPages": { // This is the page the user lands on after searching for a patient
"searchappliance_vhr_admin": "patient-details",
"searchappliance_vhr": "patient-details",
"searchappliance_vhr_adt": "patient-details",
"searchappliance_vhr_lab": "lab",
"searchappliance_vhr_radiology": "radiology"
},
"dates": { // Where "mediumDate" and "medium" are shorthand formats defined within Angular. See https://code.angularjs.org/1.4.9/docs/api/ng/filter/date for more information. See below for more date examples.
"date": "mediumDate",
"datetime": "medium"
},
"records": {View preview
"reportId": "vhr_recordLookup"
},
"hieMockData": false, // This is added to 7.5 and 8.0.2 releases. If it is set to true, then you can click through HIE screens with fake data to preview screens without being connected to a service.
"pages": { // Tells which items appear in the navigation menu and the configuration options for each page
"lookup": {
"label": "Patient Lookup",
"type": "lookup",
"forcePHIAccessPrompts": true, // forces the PHI access prompts to show up every time you select a new row even if you have already attested to view PHI data for that patient
"groups": [], // If the page is a limited-access page, it shows which groups have access. The default is empty, [], so all have access.
"reportId": "vhr_patientLookup", // The compound query report id that provides data for the page
"grids": ["lookup"],
"parameters": {
"limit": 20
},
"ccd": {
"label": "CCD", // This is CCD data provided by the customer
"icon": "list", // Any Material Design icon can be used for any of the VHR pages. Insert the icon name and surround it by quotation marks.
"type": "grid",
"groups": [
"searchappliance_vhr"
],
"reportId": "ij3UeBO2",
"parameters": {
"limit": 10000
},
"grids": [
"ccds"
]
},
"ondemand-ccd": { // This is an IMAT-generated CCD document based on data, such as ADTs and labs, found in the IMAT system
"attest": true,
"label": "CCD - On Demand",
"docLabel": "CCD",
"icon": "list",
"type": "patient.ccda",
"groups": [],
"reportId": "vhr_ccdGenerationMockData"
},
"adt": {
"label": "Admits/Discharges/Registrations",
"icon": "ps:adt",
"type": "grid",
"groups": [
"searchappliance_vhr"
"searchappliance_vhr_adt"
],
"reportId": "vhr_recordTypeReports",
"parameters": {
"record_types": [
"ADT"
],
"limit": 10000
},
"grids": [
"adt"
]
},
...
},
"links": {
"label": "State Connections", // Choose a name for the page as it should appear in the side navigation and in the page header
"icon": "open_in_new"
"type": "links",
"groups": [],
"links": [{
"url": "https://www.tncsmd.com/Login.aspx?ReturnUrl=%2default.aspx", // Change the url to match your needs
"label": "CSMD", // Give the link a name
"type": "material-icon", // This line MUST NOT be changed
"icon": "open_in_browser" // This line MUST NOT be changed
}]
},
...
},
"pageOrder": [ // This determines the order on the navigation pane to the left, the pages must be listed here in order to appear
"lookup",
"adt",
"all",
"lab",
"ccda",
"patient-details",
"radiology",
"links",
"patient-summary",
"transcriptions"]
}
Date Formatting
Using "dates" is not required; however, they are used in the vhr-fields.json file, where it is no longer necessary to define the format for the date or datetime. Note that "dates" is an object that should use "date" and "datetime" properties to define how dates and datetimes are displayed. For example:
"dates": {"date": "MM/dd/yyyy", "datetime": "MM/dd/yyyy hh:mm:ss a"}
It is possible to define any other properties for use in field configurations in vhr-fields.json:
"dates": {"date": "MM/dd/yyyy", "datetime": "MM/dd/yyyy hh:mm:ss a", "myReadableDate": "MMM dd, y"}
Patient Lookup Form Customization
Adjust the vhr-app.json file to configure the VHR patient lookup screen.
The changes should be attached to the "lookup" page configuration in vhr-app.json as a "formArrangement" or "formRequirements" block:
"lookup": {
"label": "Patient Lookup",
"type": "lookup",
"groups": [],
"reportId": "vhr_patientLookup",
"grids": ["lookup"],
"parameters": {
"limit": 20
},
"formArrangement" : [
["date_of_birth", "last_name", "first_name"],
["gender"],
["mrn"]
...
],
"formRequirements" : [
["date_of_birth", "last_name"],
["mrn"]
],
"paramRequirements": [
["mrn"]
]
},
formArrangement and formRequirements
The "formArrangement" and "formRequirements" properties control searching via the lookup form. In both "formArrangement" and "formRequirements", each interior array is a row and each element is a field on that row. To display more than one field per line, put multiple fields in the same array in the "formArrangement" block.
The field value indicates which field to display and should be entered as a string matching the name property of the fields report parameter and should be found in the report defined by the "reportId".
Configuration for "formArrangement" has the following characteristics:
- Applies only when defined as an array with elements; otherwise fields display vertically down the screen.
- Displays only listed fields, all others are hidden.*
- Displays a widget appropriate to the parameter definition.*
Configuration for "formRequirements" has the following characteristics:
- Applies only when defined and only for non-administrators; administrative accounts ignore requirements.*
- Requires all listed fields.
- Requires users to interact with required fields marked with an asterisk.
- Displays input alternatives as a list with no fields marked as required if there are two or more defined field groups; the form can be submitted without any input and problems are conveyed via toaster message after submission.
Note the example above requires either both the date of birth and the last name or the MRN. Multiple fields in the same array require all fields in that array to be completed. To require only one of the three fields, enter the three fields as their own array: [["date_of_birth"], ["first_name"], ["mrn"]]
.
*These exceptions apply:
- Fields hidden by the report found in "reportId" remain hidden regardless of these configurations.
- Fields required by the report found in "reportID" remain required (and visible) regardless of these configurations, even for administrators.
- Fields that are named in the page configuration's "parameters" property are optional and hidden—their values are set automatically.
- VHR currently supports only the textbox, single select dropdown, datepicker, and checkbox widgets.
paramRequirements
The "paramRequirements" property controls searching via the URL (bypassing the form), but is otherwise identical to "formRequirements".
When executed, a non-interactive search occurs and the user is redirected to patient records if the following criteria are met:
- All of the URL query parameters are valid report parameters.
- All of the URL query parameters are found in a single group defined in this setting.*
- The search result is a single patient.
- The user passes PHI access checks.
*It may be the case that parameters named in the page configuration's "parameters" property can be excluded.
If the search fails, the user is shown the blank search form and a pop-up message explanation such as "Redirect failed".
An example of the search is found below:
https://<ip_address>/ui/#/vhr/?mrn=5523
vhr-fields.json
WARNING: Comments, indicated by //, are not valid in the actual json file and are here for instructional purposes only.
// Changes the display name of fields
{
"abnormalLab": {"field": "has_abnormal", "displayName": "AB IND", "minWidth": 40, "maxWidth": 75, "cellClass": "abnormal-indicator-column", "transform": {"type": "icon", "translation": {"true": "error_outline", "false": ""}}},
"abnormalLabIndicators": {"field": "_normality", "displayName": " ", "transform": {"type": "image", "translation": "abnormalLabFlags", "path": "image", "unknown": "/branding/images/lab-flags/blank.gif"}}, // "type":"icon" works like a "type":"material-icon"
except that the value must be (or translated into) the src value of an img tag instead of the name of an icon
"ageRange": {"field": "age", "displayName": "Age", "transform": {"translation": { "18:54": null, "55:": "Senior", "2:17": "Child", ":1": "Infant" }, "translationKeys": "range"}}, // See below for more information on the translation keys
"admitDate": {"field": "admit_date", "displayName": "Admit Date", "transform": {"type": "date"}}, // "date" format is defined in the vhr-app.json file; see below for more examples
"adt": {"field": "adt", "displayName": "ADT", "transform": {"type": "text", "translation": "hl7Labels"}},
"createDate": {"field": "createDate", "displayName": "Creation Time", "width": "20%", "transform": {"type": "datetime"}},
"labNotes": {"field": "_normality", "displayName": "Notes", "transform": {"type": "footnote"}}, // If there is any information in the footnote field, a notification appears saying "See Note 1" (or corresponding number) and the note appears at the end of the table.
// It is not recommended to have more than one "type":"footnote" on the same grid. This type should not include other properties (translation, unknown, format).
// Two cells with the same content reference the same note number.
...
"result": {"field": "result", "displayName": "Result", "transform": {"type": "text", "translation": "hl7Labels"}},
"store": {"field": "store", "displayName": "Store", "visible": false},
"uri": {"field": "uri", "displayName": "URI", "visible": false}
}
Date Formatting
Use type with any predefined format from vhr-app.json:
"admitDate": {"field": "admit_date", "displayName": "Admit Date", "transform": {"type": "date", "format": "myReadableDate"}}
Or use type with any arbitrary inline format:
"admitDate": {"field": "admit_date", "displayName": "Admit Date", "transform": {"type": "datetime", "format": "MMM dd, y h:mm:ss"}}
Translation Keys
Use "translationKeys": "range" as part of the "transform" property to signify that the translation keys are to be interpreted as ranges and not compared literally. The keys therefore should convey range boundaries, and the syntax for that is as follows (using arbitrary digits):
"1:6" - definite range: matches if the number is between 1 and 6, inclusive
"7:" - no upper boundary: matches if the number is 7 or higher
":8" - no lower boundary: matches if the number is 8 or lower
"9" - exact match (shorthand for "9:9")
With this change, a report value can be assigned a new value according to the defined range into which it falls; patient age is a good example of a use-case scenario (see "ageRange" in the code above). This works only for report values that are integers (including negative). In the example in the vhr-fields code, the result grid would have a column labeled "Age" and, instead of displaying the age in years (e.g., 14), it would display the specified label (e.g., "Child").
Gaps between ranges is acceptable, but care should be taken not to overlap ranges to avoid unpredictable matching.
vhr-grids.json
WARNING: Comments, indicated by //, are not valid in the actual json file and are here for instructional purposes only.
// Use field names (not the display name) from vhr_fields.json to create grids
// Attach a grid to the page
{
"all": {
"fieldOrder": ["store", "uri", "abnormalLab", "result", "orderedBy", "clinicalDate", "facility", "attendingPhysician", "pcp"]
},
"adt": {
"fieldOrder": ["store", "uri", "adt", "facility", "admitDate", "dischargeDate", "attending", "pcp"]
},
...
"transcription-summary": {
"fieldOrder": ["store", "uri", "clinicalDate", "messageNameOrType", "facility", "ordering"]
},
"concepts-lab": {
"fieldOrder": ["observation", "abnormalLabIndicators", "labValue", "labNormalRange", "labUnits", "labNotes"]
}
}
vhr-records.json
WARNING: Comments, indicated by //, are not valid in the actual json file and are here for instructional purposes only.
// Label, report, parameters and title format all have the same comments; therefore, the comments are only added to the first section listed.
// Refer to the ADT section for any questions. VHR components often contain a grid of records results that match that component.
// Clicking on a record in the grid open a detail view. The vhr-records.json file controls how those record details display.
{
"RECORD_TYPE": { // This line MUST NOT be changed, removed, or extended
"ADT": {
"identifiers": ["adt", "siu"], // See below for more instructions on identifiers
"label": "ADT", // This defines an arbitrary string shown instead of the type key (e.g., "ADVANCE_DIRECTIVE") in places where it is exposed to the user.
This is currently used in the recently viewed dropdown (where it has "Record" appended).
"report": "vhr_recordLookup", // This property configures which report to use.
"parameters": {}, // This property configures which parameters to send when retrieving record details.
"titleFormat": "ADT results from {{facility}}" // This is an arbitrary string with {{token}} replacement using the value of the field named in the token. The string appears
as the header title of the record's view, both on the modal window and when printed. If any token specifies a field that is undefined for the record, the title falls back to the
configured label with "Record" appended. If there is no label defined, it defaults to the bucket name with "Record" appended ("UNKNOWN Record", for example).
},
"ADVANCE_DIRECTIVE": { // This line MUST NOT be changed, removed, or extended
"identifiers": ["advanceDirective"], // See below for more instructions on identifiers
"label": "Advance Directive",
"report": "vhr_advanceDirectives",
"parameters": {},
"titleFormat": "Advance Directive [{{print_label}}] from {{facility}}"
},
"LAB": { // This line MUST NOT be changed, removed, or extended
"identifiers": [{"store": "labs"}], // See below for more instructions on identifiers
"label": "Lab",
"report": "vhr_recordLookup",
"parameters": {},
"titleFormat": "Lab results from {{facility}}"
},
"MED_ADMINISTER": { // A record that represents the administration of medication by a provider to the patient
"identifiers": ["MedicationAdministration"],
"label": "Administered Medication",
"report": "vhr_recordLookup",
"parameters": {},
"titleFormat": "Administered Medication [{{print_label}}] from {{facility}}"
},
"MED_DISPENSE": { // A record that represents the fulfillment of a prescription by a pharmacy
"identifiers": [],
"label": "Dispensed Medication",
"report": "vhr_recordLookup",
"parameters": {},
"titleFormat": "Dispensed Medication [{{print_label}}] from {{facility}}"
},
"MED_REQUEST": { // A record that represents a request that a patient self-administer some medication. Bronx is calling this "prescriptions," but the concept is broader than that – not all medicines/remedies are prescribed.
"identifiers": ["MedicationRequest"],
"label": "Prescribed Medication",
"report": "vhr_recordLookup",
"parameters": {},
"titleFormat": "Prescribed Medication [{{print_label}}] from {{facility}}"
},
"MED_STATEMENT": { // A record that represents what a patient has taken or is taking; the information is from whatever source, not necessarily from the patient or the provider
"identifiers": ["Medication"],
"label": "Medication",
"report": "vhr_recordLookup",
"parameters": {},
"titleFormat": "Medication [{{print_label}}] from {{facility}}"
},
"PATHOLOGY": { // This line MUST NOT be changed, removed, or extended
"identifiers": ["pathology"], // See below for more instructions on identifiers
"label": "Pathology",
"report": "vhr_recordLookup",
"parameters": {},
"titleFormat": "Pathology results from {{facility}}"
},
"RADIOLOGY": { // This line MUST NOT be changed, removed, or extended
"identifiers": ["radiology"], // See below for more instructions on identifiers
"label": "Radiology",
"report": "vhr_recordLookup",
"parameters": {},
"titleFormat": "Radiology results from {{facility}}"
},
"TRANSCRIPTION": { // This line MUST NOT be changed, removed, or extended
"identifiers": ["report", {"store": "records", "record_type": "lab"}], // See below for more instructions on identifiers
"label": "Transcription",
"report": "vhr_recordLookup",
"parameters": {},
"titleFormat": "Transcription results from {{facility}}"
},
"UNKNOWN": { // This line MUST NOT be changed, removed, or extended
// Avoid using this bucket. It produces an unstyled dump of the record's field names and values.
"identifiers": [], // See below for more instructions on identifiers
"label": "Unknown",
"report": "vhr_recordLookup",
"parameters": {},
"titleFormat": "Unknown record from {{facility}}"
}
}
}
Identifiers
The ordering of items in the identifiers arrays is irrelevant.
The items in the identifiers arrays can be one or more of the following (listed from least to most specific):
- An object with a store property having a string value that is an exact match for a store name.
- A string matching a full or partial record_type value (case ignored). In other words, the string should produce a match for
record_type.match(/^str/i)
. - An object with both store and record_type properties, with values treated as above.
The algorithm for assigning a record to a VHR bucket is below:
- The bucket configured to match the record's type/store pair
- The bucket configured to match the record's type
- The bucket configured to match the record's store
- The UNKNOWN bucket
If any identifier is exactly duplicated (within a bucket or across buckets), the configuration is ambiguous and any records that would match the identifier (and not a more specific identifier) are treated as UNKNOWN. Exact duplication is evaluated at the specificity level (for example, a type/store object and a type string are not duplicates even when the type for both is "lab").
Longer identifier type strings are more specific and therefore matched earlier than shorter strings. For example, the following code snippet shows how to dump SIU S12 records into ADT and all other SIU records into TRANSCRIPTION:
ADT: { identifiers: ["siu s12"], ... },
TRANSCRIPTION: { identifiers: ["siu"], ...}