Skip to content

Commit 714c364

Browse files
committed
MORE-Platform#252: add possible filter
- moitoring & data request for "erhobene daten" doesn't take any observation groups - monitoring & data "studiendaten herunterladen" takes observation groups in api but the object in download json doesn't have an observation group id - timeline only takes one value for observation group id -> extended timeline with simple filter logic
1 parent ed8a65b commit 714c364

7 files changed

Lines changed: 214 additions & 85 deletions

File tree

src/components/ParticipationDataList.vue

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Licensed under the Elastic License 2.0. */
4545
import { useGlobalStore } from '../stores/globalStore';
4646
import { DropdownOption } from '../models/Common';
4747
import { useStudyGroupStore } from '../stores/studyGroupStore';
48+
import { useObservationGroupStore } from '../stores/observationGroupStore';
4849
import useLoader from '../composable/useLoader';
4950
import { ComponentFactory, Participant } from '@gs/models';
5051
@@ -57,6 +58,7 @@ Licensed under the Elastic License 2.0. */
5758
const dateFormat = useGlobalStore().getDateFormat;
5859
const studyStore = useStudyStore();
5960
const studyGroupStore = useStudyGroupStore();
61+
const observationGroupStore = useObservationGroupStore();
6062
6163
const props = defineProps({
6264
studyId: {
@@ -101,6 +103,23 @@ Licensed under the Elastic License 2.0. */
101103
),
102104
);
103105
106+
const observationGroupOptions: Ref<DropdownOption[]> = ref([
107+
{
108+
label: t('global.placeholder.entireStudy'),
109+
value: undefined,
110+
} as DropdownOption,
111+
]);
112+
113+
observationGroupOptions.value.push(
114+
...observationGroupStore.observationGroups.map(
115+
(observationGroup) =>
116+
({
117+
label: observationGroup.title,
118+
value: observationGroup.observationGroupId?.toString(),
119+
}) as DropdownOption,
120+
),
121+
);
122+
104123
let participantsList: Participant[] = [];
105124
const participantOptions: Ref<DropdownOption[]> = ref([
106125
{

src/components/TimelineList.vue

Lines changed: 75 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ Licensed under the Elastic License 2.0. */
1717
import {
1818
ComponentFactory,
1919
InterventionTimelineEvent,
20-
ListComponentsComponentTypeEnum,
20+
ListComponentsComponentTypeEnum, ObservationGroup,
2121
ObservationTimelineEvent,
2222
Participant,
2323
StudyGroup,
24-
StudyTimeline,
24+
StudyTimeline
2525
} from '@gs';
2626
import { useStudyStore } from '../stores/studyStore';
2727
import {
@@ -48,11 +48,13 @@ Licensed under the Elastic License 2.0. */
4848
const props = defineProps({
4949
studyId: { type: Number, required: true },
5050
studyGroups: { type: Array as PropType<Array<StudyGroup>>, required: true },
51+
observationGroups: { type: Array as PropType<Array<ObservationGroup>>, required: true }
5152
});
5253
5354
const vueCalLocale = locale.value.split('-')[0];
5455
const filterRelativeStartDate = ref();
5556
const filterStudyGroup = ref();
57+
const filterObservationGroup = ref();
5658
const filterParticipant = ref();
5759
const filterObservationAndIntervention = ref();
5860
const showFullTimeline = ref(false);
@@ -98,6 +100,23 @@ Licensed under the Elastic License 2.0. */
98100
),
99101
);
100102
103+
const observationGroupOptions: Ref<DropdownOption[]> = ref([
104+
{
105+
label: t('global.placeholder.entireStudy'),
106+
value: undefined,
107+
} as DropdownOption,
108+
]);
109+
110+
observationGroupOptions.value.push(
111+
...props.observationGroups.map(
112+
(observationGroup) =>
113+
({
114+
label: observationGroup.title,
115+
value: observationGroup.observationGroupId?.toString(),
116+
}) as DropdownOption,
117+
),
118+
);
119+
101120
const events: ComputedRef<Event[]> = computed(() => {
102121
return timelineEventsList.value.filter((event: Event) => {
103122
const eventDetail = getEventDetailByEventCid(event.cId);
@@ -276,44 +295,61 @@ Licensed under the Elastic License 2.0. */
276295
return translation;
277296
}
278297
279-
function onStudyGroupFilterChange(e: DropdownChangeEvent): void {
280-
const filteredOptions: DropdownOption[] = [];
281-
const filteredParticipants: Participant[] = [];
298+
type ParticipantGroupField = 'studyGroupId' | 'observationGroupId';
282299
283-
filteredOptions.push({
284-
label: t('participants.placeholder.allParticipants'),
285-
value: undefined,
286-
} as DropdownOption);
300+
function rebuildParticipantOptionsByGroup(
301+
field: ParticipantGroupField,
302+
selectedId?: string | undefined, // kommt aus Dropdown als string
303+
): void {
304+
const id = selectedId ? parseInt(selectedId) : undefined;
287305
288-
if (e.value) {
289-
filteredParticipants.push(
290-
...participantsList.filter(
291-
(participant) => participant.studyGroupId === parseInt(e.value),
292-
),
293-
);
294-
} else {
295-
filteredParticipants.push(...participantsList);
296-
}
306+
const filteredParticipants = id
307+
? participantsList.filter((p) => (p as any)[field] === id)
308+
: participantsList;
297309
298-
filteredOptions.push(
310+
participantOptions.value = [
311+
{
312+
label: t('participants.placeholder.allParticipants'),
313+
value: undefined,
314+
} as DropdownOption,
299315
...filteredParticipants.map(
300-
(filteredParticipant) =>
316+
(p) =>
301317
({
302-
label: filteredParticipant.alias,
303-
value: filteredParticipant.participantId?.toString(),
318+
label: p.alias,
319+
value: p.participantId?.toString(),
304320
}) as DropdownOption,
305321
),
306-
);
322+
];
307323
308-
participantOptions.value = filteredOptions;
309-
listTimeline();
324+
// reset falls ungültig
325+
if (
326+
filterParticipant.value &&
327+
!filteredParticipants.some(
328+
(p) => p.participantId?.toString() === filterParticipant.value,
329+
)
330+
) {
331+
filterParticipant.value = undefined;
332+
}
310333
}
311334
335+
312336
function onParticipantFilterChange(e: DropdownChangeEvent): void {
313337
filterStudyGroup.value = getStudyGroupIdByParticipantId(parseInt(e.value));
314338
listTimeline();
315339
}
316340
341+
function onObservationGroupFilterChange(e: DropdownChangeEvent): void {
342+
filterObservationGroup.value = e.value;
343+
rebuildParticipantOptionsByGroup('observationGroupId', e.value);
344+
listTimeline();
345+
}
346+
347+
function onStudyGroupFilterChange(e: DropdownChangeEvent): void {
348+
filterStudyGroup.value = e.value;
349+
rebuildParticipantOptionsByGroup('studyGroupId', e.value);
350+
listTimeline();
351+
}
352+
317353
function onEventClick(vueCalEvent: VueCalEvent, e: MouseEvent): void {
318354
const eventDetail: EventDetail | undefined = getEventDetailByEventCid(
319355
vueCalEvent.cId,
@@ -354,6 +390,7 @@ Licensed under the Elastic License 2.0. */
354390
function clearAllFilters(): void {
355391
filterRelativeStartDate.value = undefined;
356392
filterStudyGroup.value = undefined;
393+
filterObservationGroup.value = undefined;
357394
filterParticipant.value = undefined;
358395
filterObservationAndIntervention.value = [];
359396
listTimeline();
@@ -422,6 +459,7 @@ Licensed under the Elastic License 2.0. */
422459
props.studyId,
423460
filterParticipant.value,
424461
filterStudyGroup.value,
462+
filterObservationGroup.value,
425463
filterRelativeStartDate.value,
426464
studyStartDate,
427465
studyEndDate,
@@ -514,6 +552,18 @@ Licensed under the Elastic License 2.0. */
514552
@change="onStudyGroupFilterChange"
515553
/>
516554
</div>
555+
<div class="flex-row-center">
556+
{{ $t('observationGroup.singular') }}:
557+
<Dropdown
558+
v-model="filterObservationGroup"
559+
:options="observationGroupOptions"
560+
option-label="label"
561+
option-value="value"
562+
:placeholder="$t('observationGroup.placeholder.chooseGroup')"
563+
class="ml-1"
564+
@change="onObservationGroupFilterChange"
565+
/>
566+
</div>
517567
<div class="flex-row-center">
518568
{{ $t('participants.singular') }}:
519569
<Dropdown

0 commit comments

Comments
 (0)