Skip to content

Commit

Permalink
feat: add table references for demographics to filter (#943)
Browse files Browse the repository at this point in the history
  • Loading branch information
tada5hi authored Nov 28, 2024
1 parent dfe1683 commit 6b32464
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 6 deletions.
39 changes: 38 additions & 1 deletion packages/core/src/components/core/query/QueryPatientFilters.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<script lang="ts">
import { VCFormRangeMultiSlider } from '@vuecs/form-controls';
import { defineComponent, ref } from 'vue';
import { defineComponent, onUnmounted, ref } from 'vue';
import { QueryFilterURLKey } from '../../../constants';
import { injectHTTPClient } from '../../../core';
import type { Coding, PatientFilter } from '../../../domains';
import { isCoding, toCoding } from '../../../domains';
import { QueryEventBusEventName, injectQueryEventBus } from '../../../services';
import { useQueryFilterStore } from '../../../stores';
import QueryFilterBox from './QueryFilterBox.vue';
Expand All @@ -30,6 +31,7 @@ export default defineComponent({
emits: ['submit'],
async setup(props, { emit }) {
const store = useQueryFilterStore();
const eventBus = injectQueryEventBus();
const httpClient = injectHTTPClient();
const available = ref<PatientFilter>({});
Expand Down Expand Up @@ -156,6 +158,31 @@ export default defineComponent({
.then(() => load())
.then(() => init());
const listenForFilterUpdates = ref(true);
const removeFilterUpdatedHandler = eventBus.on(
QueryEventBusEventName.FILTER_UPDATED,
(key) => {
if (!listenForFilterUpdates.value) {
return;
}
if (
key !== QueryFilterURLKey.SITE &&
key !== QueryFilterURLKey.GENDER &&
key !== QueryFilterURLKey.AGE_MIN &&
key !== QueryFilterURLKey.AGE_MAX
) {
return;
}
listenForFilterUpdates.value = false;
init();
listenForFilterUpdates.value = true;
},
);
onUnmounted(() => removeFilterUpdatedHandler());
const handleAgeRangeChanged = (ctx: { min: number, max: number}) => {
if (!available.value.ageRange) {
return;
Expand All @@ -175,6 +202,8 @@ export default defineComponent({
age.value.min = minRounded;
age.value.max = maxRounded;
listenForFilterUpdates.value = false;
if (
available.value.ageRange.min &&
available.value.ageRange.min === age.value.min
Expand All @@ -192,6 +221,8 @@ export default defineComponent({
} else {
store.setItems(QueryFilterURLKey.AGE_MAX, [toCoding(age.value.max)]);
}
listenForFilterUpdates.value = true;
};
const handleGenderChanged = () => {
Expand All @@ -204,7 +235,9 @@ export default defineComponent({
data.push(...gender.value.map((el) => toCoding(el)));
}
listenForFilterUpdates.value = false;
store.setItems(QueryFilterURLKey.GENDER, data);
listenForFilterUpdates.value = true;
};
const handleVitalStatusChanged = () => {
Expand All @@ -217,7 +250,9 @@ export default defineComponent({
data.push(...vitalStatus.value.map((el) => toCoding(el)));
}
listenForFilterUpdates.value = false;
store.setItems(QueryFilterURLKey.VITAL_STATUS, data);
listenForFilterUpdates.value = true;
};
const handleSiteChanged = () => {
Expand All @@ -230,7 +265,9 @@ export default defineComponent({
data.push(...site.value.map((el) => toCoding(el)));
}
listenForFilterUpdates.value = false;
store.setItems(QueryFilterURLKey.SITE, data);
listenForFilterUpdates.value = true;
};
const submit = () => {
Expand Down
101 changes: 99 additions & 2 deletions packages/core/src/components/core/query/QuerySummaryDemographics.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<script lang="ts">
import { type PropType, defineComponent } from 'vue';
import type { QuerySummaryDemographics } from '../../../domains';
import { QueryFilterURLKey } from '../../../constants';
import type { Coding, QuerySummaryDemographics } from '../../../domains';
import { useQueryFilterStore } from '../../../stores';
import { DKVChartTableSwitch } from '../../utility';
export default defineComponent({
Expand All @@ -11,6 +13,93 @@ export default defineComponent({
required: true,
},
},
emits: ['navigate'],
setup(_props, { emit }) {
const queryFilterStore = useQueryFilterStore();
const handleLocationClick = (keys: Coding[]) => {
const [coding] = keys;
if (typeof coding === 'undefined') {
return;
}
let hasChanged : boolean;
if (queryFilterStore.hasItem(QueryFilterURLKey.SITE, coding)) {
hasChanged = false;
queryFilterStore.setItems(QueryFilterURLKey.SITE, []);
} else {
hasChanged = true;
queryFilterStore.setItems(QueryFilterURLKey.SITE, [coding]);
}
queryFilterStore.setActive('patient');
queryFilterStore.commit();
if (hasChanged) {
emit('navigate');
}
};
const handleGenderClick = (keys: Coding[]) => {
const [coding] = keys;
if (typeof coding === 'undefined') {
return;
}
let hasChanged : boolean;
if (queryFilterStore.hasItem(QueryFilterURLKey.GENDER, coding)) {
hasChanged = false;
queryFilterStore.setItems(QueryFilterURLKey.GENDER, []);
} else {
hasChanged = true;
queryFilterStore.setItems(QueryFilterURLKey.GENDER, [coding]);
}
queryFilterStore.setActive('patient');
queryFilterStore.commit();
if (hasChanged) {
emit('navigate');
}
};
const handleAgeClick = (keys: Coding[]) => {
const [min, max] = keys;
if (typeof min === 'undefined' || typeof max === 'undefined') {
return;
}
let hasChanged : boolean;
if (
queryFilterStore.hasItem(QueryFilterURLKey.AGE_MIN, min) ||
queryFilterStore.hasItem(QueryFilterURLKey.AGE_MAX, max)
) {
hasChanged = false;
queryFilterStore.setItems(QueryFilterURLKey.AGE_MIN, []);
queryFilterStore.setItems(QueryFilterURLKey.AGE_MAX, []);
} else {
hasChanged = true;
queryFilterStore.setItems(QueryFilterURLKey.AGE_MIN, [min]);
queryFilterStore.setItems(QueryFilterURLKey.AGE_MAX, [max]);
}
queryFilterStore.setActive('patient');
queryFilterStore.commit();
if (hasChanged) {
emit('navigate');
}
};
return {
handleLocationClick,
handleGenderClick,
handleAgeClick,
};
},
});
</script>
<template>
Expand All @@ -25,6 +114,8 @@ export default defineComponent({
<DKVChartTableSwitch
:type="'doughnut'"
:data="entity.siteDistribution.elements"
:clickable="true"
@clicked="handleLocationClick"
/>
</div>

Expand All @@ -35,6 +126,8 @@ export default defineComponent({
<DKVChartTableSwitch
:type="'doughnut'"
:data="entity.genderDistribution.elements"
:clickable="true"
@clicked="handleGenderClick"
/>
</div>
</div>
Expand All @@ -43,7 +136,11 @@ export default defineComponent({
<h6>
Altersverteilung
</h6>
<DKVChartTableSwitch :data="entity.ageDistribution.elements" />
<DKVChartTableSwitch
:data="entity.ageDistribution.elements"
:clickable="true"
@clicked="handleAgeClick"
/>
</div>
</div>
</template>
7 changes: 6 additions & 1 deletion packages/core/src/components/utility/kv-table/DKVTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { BTable } from 'bootstrap-vue-next';
import type { PropType } from 'vue';
import { computed, defineComponent } from 'vue';
import type { Coding, KeyValueRecord } from '../../../domains';
import { isCoding, isConceptCount } from '../../../domains';
import { isCoding, isConceptCount, isMinMaxRange } from '../../../domains';
import { generateChartLabelsForKeyValueRecord } from '../chart/utils';

export default defineComponent({
Expand Down Expand Up @@ -101,6 +101,11 @@ export default defineComponent({
return;
}

if (isMinMaxRange(itemKey)) {
emit('clicked', [{ code: itemKey.min }, { code: itemKey.max }]);
return;
}

if (typeof itemKey === 'string') {
emit('clicked', [{ code: itemKey } satisfies Coding]);
return;
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/domains/coding/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Coding } from './types';

export function isCoding(input: unknown) : input is Coding {
return isObject(input) &&
typeof input.code === 'string';
(typeof input.code === 'string' || typeof input.code === 'number');
}

export function toCoding(input: number | string | Coding) : Coding {
Expand Down Expand Up @@ -129,7 +129,7 @@ export function buildCodingsRecord(input: Record<string, any>) : Record<string,

export function serializeCoding(coding: Coding) {
const parts: string[] = [];
parts.push(coding.code);
parts.push(`${coding.code}`);
if (coding.system) {
parts.push(coding.system);

Expand Down
1 change: 1 addition & 0 deletions packages/core/src/stores/query-filter/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export function buildQueryFilterURLValue(items: QueryFilterItem[]) {
const output : string[] = [];
for (let i = 0; i < items.length; i++) {
const item = items[i];

if (isCoding(item)) {
output.push(serializeCoding(item));
} else {
Expand Down

0 comments on commit 6b32464

Please sign in to comment.