diff --git a/src/ui/components/PatientViewer/FilterPresets.jsx b/src/ui/components/PatientViewer/FilterPresets.jsx
new file mode 100644
index 0000000..620fe52
--- /dev/null
+++ b/src/ui/components/PatientViewer/FilterPresets.jsx
@@ -0,0 +1,78 @@
+
+// map a list to a group of fhir ORs, eg [1,2,3] --> string "'1' | '2' | '3'"
+const fhirList = (list) => list.map(i => `'${i}'`).join(' | ');
+
+
+const DR_CONDITIONS = [
+ '44054006', // diabetes
+ '15777000', // prediabetes
+ '1551000119108', // NPDR
+ '1501000119109', // PDR
+ '97331000119101', // DME
+ '60951000119105', // blindness
+];
+
+const SDOH_CONDITIONS = [
+ '314529007',
+ '5251000175109',
+ '424393004',
+ '160903007',
+ '706893006',
+ '73595000',
+ '160904001',
+ '741062008',
+ '10939881000119105',
+ '422650009',
+ '423315002',
+ '706893006',
+ '266948004',
+ '5251000175109'
+];
+
+const FILTER_PRESETS = Object.freeze({
+ "Hide Resolved Conditions": {
+ description: "Hides conditions with an abatement date",
+ mode: 'exclude',
+ filterOnGroupByEncounter: false,
+ filters: {
+ Condition: ['Condition.abatement'] // is not null
+ }
+ },
+ "Hide Stopped Medications": {
+ description: "Hides medications with a status of 'stopped'",
+ mode: 'exclude',
+ filterOnGroupByEncounter: false,
+ filters: {
+ MedicationRequest: ["MedicationRequest.status = 'stopped'"]
+ }
+ },
+ 'Disease Focus: Diabetic Retinopathy': {
+ description: 'Keeps entries relevant to Diabetic Retinopathy',
+ mode: 'include',
+ filterOnGroupByEncounter: true,
+ filters: {
+ Encounter: ["Encounter.type.coding.code = '185349003'"],
+ Condition: [`Condition.code.coding.code in (${fhirList(DR_CONDITIONS)})`],
+ Observation: []
+ }
+ },
+ 'Hide SDOH Conditions': {
+ description: 'Hides most SDOH conditions, such as "stress", employment status, etc',
+ mode: 'exclude',
+ filterOnGroupByEncounter: true,
+ filters: {
+ Condition: [`Condition.code.coding.code in (${fhirList(SDOH_CONDITIONS)})`]
+ }
+ }
+ // Coming soon...
+ // 'Cardiology': {
+ // description: 'Keeps entries relevant to Cardiology',
+ // mode: 'include',
+ // filters: {
+
+ // }
+ // }
+
+});
+
+export default FILTER_PRESETS;
\ No newline at end of file
diff --git a/src/ui/components/PatientViewer/PatientViewer.jsx b/src/ui/components/PatientViewer/PatientViewer.jsx
index 435afaf..4b27468 100644
--- a/src/ui/components/PatientViewer/PatientViewer.jsx
+++ b/src/ui/components/PatientViewer/PatientViewer.jsx
@@ -48,6 +48,9 @@ import csvToFhir from './csvToFhir';
import { evaluateResource, appliesToResource } from '../../fhirpath_utils';
+import FILTER_PRESETS from './FilterPresets';
+
+
const getDropzone = (setLoading, callback) => {
const onDrop = files => {
const reader = new FileReader();
@@ -116,15 +119,16 @@ const PatientViewer = props => {
setIsLoading(false);
}
-
-
const [isGroupByEncounter, setIsGroupByEncounter] = useLocalStorage("group-by-encounter", false);
- const [filters, setFilters] = useLocalStorage("filters", {});
- const [filterMode, setFilterMode] = useLocalStorage("filter-mode", "include");
- // TODO: probably a better way to make these generic. don't want to pass around 100 variables for different settings
- const [hideStoppedMeds, setHideStoppedMeds] = useLocalStorage("Hide Stopped Medications", false);
- const [hideResolvedConditions, setHideResolvedConditions] = useLocalStorage("Hide Resolved Conditions", false);
+ const loadedPresets = [];
+ for (const presetKey of Object.keys(FILTER_PRESETS)) {
+ const [isPresetLoaded,] = useLocalStorage(presetKey, false);
+
+ if (isPresetLoaded) {
+ loadedPresets.push(presetKey);
+ }
+ }
useEffect(() => {
if (id && !bundle) {
@@ -152,14 +156,17 @@ const PatientViewer = props => {
let allResources = bundle.entry.map(e => e.resource);
- if (Object.keys(filters).length) {
+ for (const presetKey of loadedPresets) {
+ const preset = FILTER_PRESETS[presetKey];
+ if (isGroupByEncounter && !preset.filterOnGroupByEncounter) continue;
allResources = allResources.filter(r => {
- const filtersByResourceType = filters[r.resourceType];
+ const filtersByResourceType = preset.filters[r.resourceType];
if (!filtersByResourceType) return true;
const anyMatch = filtersByResourceType.some(f => appliesToResource(r, f));
- return filterMode === 'exclude' ? !anyMatch : anyMatch;
+ return preset.mode === 'exclude' ? !anyMatch : anyMatch;
});
+
}
const patient = allResources.find(r => r.resourceType === 'Patient');
@@ -186,9 +193,7 @@ const PatientViewer = props => {
<>