From 5ec3f5534ca9cf32ac36547c18b28694ff975c99 Mon Sep 17 00:00:00 2001 From: iaigner Date: Thu, 12 Jun 2025 11:57:01 +0200 Subject: [PATCH 01/94] #560: add warning for broken observation links on intervention actions --- src/components/InterventionsList.vue | 87 ++++++++++++++++++- .../shared/ObservationPropertyInput.vue | 48 +++++++++- src/components/shared/MoreTable.vue | 40 ++++++++- src/i18n/de.json | 3 +- src/i18n/en.json | 3 +- 5 files changed, 173 insertions(+), 8 deletions(-) diff --git a/src/components/InterventionsList.vue b/src/components/InterventionsList.vue index c053712e..1302c791 100644 --- a/src/components/InterventionsList.vue +++ b/src/components/InterventionsList.vue @@ -5,7 +5,7 @@ Oesterreichische Vereinigung zur Foerderung der wissenschaftlichen Forschung). Licensed under the Elastic License 2.0. */ + + diff --git a/src/components/shared/MoreTable.vue b/src/components/shared/MoreTable.vue index 0f2f8cce..91bb861b 100644 --- a/src/components/shared/MoreTable.vue +++ b/src/components/shared/MoreTable.vue @@ -33,6 +33,7 @@ Licensed under the Elastic License 2.0. */ import { ComponentFactory, StudyRole, StudyStatus, Visibility } from '@gs'; import { shortenText } from '../../utils/commonUtils'; import { useGlobalStore } from '../../stores/globalStore'; + import ExclamationIcon from './ExclamationIcon.vue'; import { ACTION_ID_QR_CODE } from '../../constants'; @@ -465,35 +466,8 @@ Licensed under the Elastic License 2.0. */
- - - - - - - - - - - + + {{ data[field]}} @@ -744,7 +718,7 @@ Licensed under the Elastic License 2.0. */ padding: 5px; } - .title-has-warning, .title-has-warning svg { + .title-has-warning, .title-has-warning #exclamationIcon { height: 18px; width: auto; } diff --git a/src/components/subComponents/CronScheduleInfo.vue b/src/components/subComponents/CronScheduleInfo.vue index e055c750..75d9c877 100644 --- a/src/components/subComponents/CronScheduleInfo.vue +++ b/src/components/subComponents/CronScheduleInfo.vue @@ -5,6 +5,7 @@ Oesterreichische Vereinigung zur Foerderung der wissenschaftlichen Forschung). Licensed under the Elastic License 2.0. */ + + + + diff --git a/src/composable/useApi.ts b/src/composable/useApi.ts index 4a1dbacf..b501f3ac 100644 --- a/src/composable/useApi.ts +++ b/src/composable/useApi.ts @@ -20,6 +20,7 @@ import { DataApi, ConfigurationApi, CalendarApi, + AuditlogApi } from '@gs'; const apiConfig = { @@ -41,6 +42,7 @@ let calendarApi: CalendarApi; let importExportApi: ImportExportApi; let dataApi: DataApi; let uiConfigApi: ConfigurationApi; +let auditlogApi: AuditlogApi; export function useStudiesApi(): { studiesApi: StudiesApi; @@ -149,3 +151,13 @@ export function useUiConfigApi(): { uiConfigApi, }; } + + +export function useAuditlogApi(): { + auditlogApi: AuditlogApi; +} { + auditlogApi = auditlogApi || new AuditlogApi(apiConfig); + return { + auditlogApi, + }; +} diff --git a/src/i18n/de.json b/src/i18n/de.json index 1b9d4187..6a9a644d 100644 --- a/src/i18n/de.json +++ b/src/i18n/de.json @@ -61,6 +61,13 @@ "dataDownload": { "description": "Hier können die Studiendaten basierend auf diverse Filter heruntergeladen werden.", "title": "Studiendaten herunterladen" + }, + "auditlogDownload": { + "title": "Auditlog herunterladen", + "description": "Hier kann der aktuelle Auditlog heruntergeladen werden.", + "btnLabel": "Aktuellen Auditlog herunterladen", + "notStartedInfo": "Auditlog-Daten werden erst bei einer aktiven Studie aufgezeichnet.", + "noDataInfo": "Die Studie hat noch keine Auditlog-Daten aufgezeichnet." } }, "global": { @@ -384,7 +391,8 @@ "tabs": { "dataDownload": "Studiendaten herunterladen", "lastDataPoints": "Letzte Datenpunkte", - "recordedObservation": "Erhobene Daten" + "recordedObservation": "Erhobene Daten", + "auditlog": "Auditlog herunterladen" } }, "moreTable": { diff --git a/src/i18n/en.json b/src/i18n/en.json index 235d484c..840b7dea 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -61,6 +61,13 @@ "dataDownload": { "description": "Here you can download the study data based on various filters.", "title": "Download study data" + }, + "auditlogDownload": { + "title": "Download auditlog", + "description": "Here you can download the current auditlog.", + "btnLabel": "Download current auditlog", + "notStartedInfo": "Audit log data is only recorded when a study is active.", + "noDataInfo": "The study has not recorded any audit log data yet." } }, "global": { @@ -384,7 +391,8 @@ "tabs": { "dataDownload": "Export study data", "lastDataPoints": "Latest Data Points", - "recordedObservation": "Recorded Observations" + "recordedObservation": "Recorded Observations", + "auditlog": "Download Auditlog" } }, "moreTable": { diff --git a/src/stores/studyStore.ts b/src/stores/studyStore.ts index d0905e6d..09df6555 100644 --- a/src/stores/studyStore.ts +++ b/src/stores/studyStore.ts @@ -8,8 +8,8 @@ */ import { computed, ComputedRef, ref, Ref } from 'vue'; import { defineStore } from 'pinia'; -import { Study, StudyRole, StudyStatus } from '@gs'; -import { useImportExportApi, useStudiesApi } from '../composable/useApi'; +import { AuditlogMetadata, Study, StudyRole, StudyStatus } from '@gs'; +import { useAuditlogApi, useImportExportApi, useStudiesApi } from '../composable/useApi'; import { AxiosError, AxiosResponse } from 'axios'; import { useErrorHandling } from '../composable/useErrorHandling'; import { useStudyGroupStore } from './studyGroupStore'; @@ -19,12 +19,14 @@ import { useToastService } from '../composable/toastService'; export const useStudyStore = defineStore('study', () => { const { studiesApi } = useStudiesApi(); const { importExportApi } = useImportExportApi(); + const { auditlogApi } = useAuditlogApi(); const { handleIndividualError } = useErrorHandling(); const studyGroupStore = useStudyGroupStore(); const { handleToastErrors } = useToastService(); // State const study: Ref = ref({}); const studies: Ref = ref([]); + const auditlogMetadata: Ref = ref(); // Actions async function getStudy(studyId: number): Promise { @@ -170,6 +172,19 @@ export const useStudyStore = defineStore('study', () => { }); } + async function exportCurrentAuditlog(studyId: number): Promise { + await auditlogApi.exportLastAuditlog(studyId) + .then((rs) => { + window.open(rs.headers.location); + }) + .catch((e: AxiosError) => { + handleIndividualError( + e, + 'cannot generate download token to export study data', + ); + }); + } + function downloadJSON(filename: string, file: File): void { const fileJSON = JSON.stringify(file); const link = document.createElement('a'); @@ -186,6 +201,13 @@ export const useStudyStore = defineStore('study', () => { } } + async function getAuditlogMetadata(studyId: number): Promise { + auditlogMetadata.value = await auditlogApi.getAuditlogMetadata(studyId) + .then((response: AxiosResponse) => response.data) + + return auditlogMetadata.value; + } + // Getters const studyUserRoles: ComputedRef> = computed(() => [ ...(study.value.userRoles || []), @@ -211,5 +233,8 @@ export const useStudyStore = defineStore('study', () => { studyUserRoles, studyStatus, studyId, + auditlogMetadata, + getAuditlogMetadata, + exportCurrentAuditlog }; }); diff --git a/src/views/MonitoringData.vue b/src/views/MonitoringData.vue index 87a6219b..7e117247 100644 --- a/src/views/MonitoringData.vue +++ b/src/views/MonitoringData.vue @@ -13,12 +13,16 @@ Licensed under the Elastic License 2.0. */ import TabPanel from 'primevue/tabpanel'; import DatapointList from '../components/subComponents/DatapointList.vue'; import ParticipationDataList from '../components/ParticipationDataList.vue'; + import AuditlogDownload from '../components/subComponents/AuditlogDownload.vue'; + import { ref } from 'vue'; const studyStore = useStudyStore(); const accessRoles: StudyRole[] = [ StudyRole.StudyAdmin, StudyRole.StudyViewer, ]; + + const activeIndex = ref(0) - diff --git a/src/components/subComponents/SchedulerInfoBlock.vue b/src/components/subComponents/SchedulerInfoBlock.vue index 5601c285..7ea1e17c 100644 --- a/src/components/subComponents/SchedulerInfoBlock.vue +++ b/src/components/subComponents/SchedulerInfoBlock.vue @@ -336,7 +336,7 @@ Licensed under the Elastic License 2.0. */
- diff --git a/src/components/StudyApplicationManager.vue b/src/components/StudyApplicationManager.vue index 8fc9777a..42a5cb1d 100644 --- a/src/components/StudyApplicationManager.vue +++ b/src/components/StudyApplicationManager.vue @@ -4,36 +4,18 @@ Prevention -- A research institute of the Ludwig Boltzmann Gesellschaft, Oesterreichische Vereinigung zur Foerderung der wissenschaftlichen Forschung). Licensed under the Elastic License 2.0. */ diff --git a/src/components/dialog/ParticipantInfoDialog.vue b/src/components/dialog/ParticipantInfoDialog.vue index fabafac0..f564c2ab 100644 --- a/src/components/dialog/ParticipantInfoDialog.vue +++ b/src/components/dialog/ParticipantInfoDialog.vue @@ -1,8 +1,9 @@ + + diff --git a/src/i18n/de.json b/src/i18n/de.json index d241acc4..387c1472 100644 --- a/src/i18n/de.json +++ b/src/i18n/de.json @@ -124,6 +124,7 @@ "scheduleType": "Zeitplan-Typ", "setPause": "Pausieren", "start": "Start", + "success": "Erfolgreich", "time": "Zeit", "to": "zu", "leavePage": "Möchten Sie die Seite wirklich verlassen?", @@ -601,6 +602,7 @@ "noAccess": "Bisher wurde kein Anwendungszugriff gewährt.", "addTooltip": "Keine weiteren Anwendungen für diese Studie verfügbar. Gewähren Sie Zugriff auf Anwendungen über den Reiter 'Studie'." }, + "loadingData": "Teilnehmer:innendaten laden...", "dialog": { "updated": "Teilnehmer:in erfolgreich gespeichert", "updateFailed": "Fehler beim Speichern der Teilnehmer:in!", diff --git a/src/i18n/en.json b/src/i18n/en.json index ece787a7..e7c58236 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -124,6 +124,7 @@ "scheduleType": "Schedule Type", "setPause": "Pause", "start": "Start", + "success": "Success", "time": "Time", "to": "to", "leavePage": "Do you really want to leave the page?", @@ -601,6 +602,7 @@ "noAccess": "No application access granted yet.", "addTooltip": "No more applications available for this study. Grant access to applications via the study tab." }, + "loadingData": "Loading participant data...", "dialog": { "updated": "Participant saved successfully", "updateFailed": "Failed to update participant data!", diff --git a/src/stores/studyStore.ts b/src/stores/studyStore.ts index e18a157d..e9f33d72 100644 --- a/src/stores/studyStore.ts +++ b/src/stores/studyStore.ts @@ -8,8 +8,24 @@ */ import { computed, ComputedRef, ref, Ref } from 'vue'; import { defineStore } from 'pinia'; -import { AuditLogMetadata, AuditLogEntry, Study, StudyRole, StudyStatus, DataExportInner, OccurredObservation, ObservationTimelineEvent, StudyTimeline} from '@gs'; -import { useAuditLogApi, useCalendarApi, useImportExportApi, useStudiesApi, useOccurredObservationsApi } from '../composable/useApi'; +import { + AuditLogEntry, + AuditLogMetadata, + DataExportInner, + ObservationTimelineEvent, + OccurredObservation, + Study, + StudyRole, + StudyStatus, + StudyTimeline +} from '@gs'; +import { + useAuditLogApi, + useCalendarApi, + useImportExportApi, + useOccurredObservationsApi, + useStudiesApi +} from '../composable/useApi'; import { AxiosError, AxiosResponse } from 'axios'; import { useErrorHandling } from '../composable/useErrorHandling'; import { useStudyGroupStore } from './studyGroupStore'; @@ -17,6 +33,16 @@ import { useObservationGroupStore } from './observationGroupStore'; import { DownloadData } from '../models/DataDownloadModel'; import { useToastService } from '../composable/toastService'; +const accessEditRoles: StudyRole[] = [ + StudyRole.StudyAdmin, + StudyRole.StudyOperator, +]; +const editableStatuses: StudyStatus[] = [ + StudyStatus.Draft, + StudyStatus.Paused, + StudyStatus.PausedPreview, +]; + export const useStudyStore = defineStore('study', () => { const { studiesApi } = useStudiesApi(); const { importExportApi } = useImportExportApi(); @@ -33,16 +59,35 @@ export const useStudyStore = defineStore('study', () => { const auditLogMetadata: Ref = ref(); const auditLogEntries: Ref> = ref([]); const occurredObservations: Ref> = ref([]); - const participantTimelineObservations: Ref> = ref([]); + const participantTimelineObservations: Ref> = + ref([]); + + const studyIsUpdating = ref(false); + // Getters + const studyUserRoles: ComputedRef> = computed(() => [ + ...(study.value.userRoles || []), + ]); + const studyStatus: ComputedRef = computed( + () => study.value.status || StudyStatus.Draft, + ); + const studyId: ComputedRef = computed(() => study.value.studyId || 0); + const hasCriticalRoles = computed((): boolean => + studyUserRoles.value.some((role) => accessEditRoles.includes(role)), + ); + + const studyIsEditable = computed( + (): boolean => + hasCriticalRoles.value && editableStatuses.includes(studyStatus.value), + ); // Actions async function getStudy(studyId: number): Promise { study.value = await studiesApi .getStudy(studyId) .then((response) => { if (response.data?.studyId) - observationGroupStore.getObservationGroups(response.data.studyId) - return response.data + observationGroupStore.getObservationGroups(response.data.studyId); + return response.data; }) .catch((e: AxiosError) => { handleIndividualError(e, 'cannot fetch study'); @@ -66,7 +111,8 @@ export const useStudyStore = defineStore('study', () => { } async function updateStudyStatus(status: StudyStatus): Promise { - if (study.value.studyId) { + if (!studyIsUpdating.value && study.value.studyId) { + studyIsUpdating.value = true; await studiesApi .setStatus(study.value.studyId, { status }) .then(() => { @@ -78,6 +124,9 @@ export const useStudyStore = defineStore('study', () => { `Could not update study status ${study.value.studyId}`, ); handleToastErrors(e.response?.data); + }) + .finally(() => { + studyIsUpdating.value = false; }); } } @@ -135,31 +184,58 @@ export const useStudyStore = defineStore('study', () => { } } - async function listOccurredObservations(studyId: number, participantId?: number, observationId?: number, from?: string, to?: string): Promise { - await occurredObservationsApi.listOccurredObservations(studyId, participantId, observationId, from, to) - .then((response: AxiosResponse) => occurredObservations.value = response.data) + async function listOccurredObservations( + studyId: number, + participantId?: number, + observationId?: number, + from?: string, + to?: string, + ): Promise { + await occurredObservationsApi + .listOccurredObservations(studyId, participantId, observationId, from, to) + .then( + (response: AxiosResponse) => + (occurredObservations.value = response.data), + ) .catch((e: AxiosError) => - handleIndividualError(e, `cannot get occuredObservation on study ${studyId} (participant: ${participantId}, observation: ${observationId}, from: ${from}, to: ${to})`) + handleIndividualError( + e, + `cannot get occuredObservation on study ${studyId} (participant: ${participantId}, observation: ${observationId}, from: ${from}, to: ${to})`, + ), ); } - async function listParticipantObservationsInTimeline(studyId: number, participantId: number, studyGroup?: number, observationGroup?: number, referenceDate?: string, studyStartDate?: string, studyEndDate?: string): Promise { - await calendarApi.getStudyTimeline( - studyId, - participantId, - studyGroup, - observationGroup, - referenceDate, - studyStartDate, - studyEndDate, - undefined, - ) - .then((response: AxiosResponse) => - participantTimelineObservations.value = response.data?.observations ?? [] + async function listParticipantObservationsInTimeline( + studyId: number, + participantId: number, + studyGroup?: number, + observationGroup?: number, + referenceDate?: string, + studyStartDate?: string, + studyEndDate?: string, + ): Promise { + await calendarApi + .getStudyTimeline( + studyId, + participantId, + studyGroup, + observationGroup, + referenceDate, + studyStartDate, + studyEndDate, + undefined, ) - .catch((e: AxiosError) => - handleIndividualError(e, `cannot get observations in timeline for study ${studyId}, participant ${participantId}`) + .then( + (response: AxiosResponse) => + (participantTimelineObservations.value = + response.data?.observations ?? []), ) + .catch((e: AxiosError) => + handleIndividualError( + e, + `cannot get observations in timeline for study ${studyId}, participant ${participantId}`, + ), + ); } const importStudy = (importedStudy: File): Promise => @@ -259,7 +335,10 @@ export const useStudyStore = defineStore('study', () => { }); } - function downloadJSON(filename: string, file: File | AuditLogEntry[] | DataExportInner[]): void { + function downloadJSON( + filename: string, + file: File | AuditLogEntry[] | DataExportInner[], + ): void { const fileJSON = JSON.stringify(file); const link = document.createElement('a'); if (link) { @@ -281,15 +360,6 @@ export const useStudyStore = defineStore('study', () => { .then((response: AxiosResponse) => response.data); } - // Getters - const studyUserRoles: ComputedRef> = computed(() => [ - ...(study.value.userRoles || []), - ]); - const studyStatus: ComputedRef = computed( - () => study.value.status || StudyStatus.Draft, - ); - const studyId: ComputedRef = computed(() => study.value.studyId || 0); - return { study, studies, @@ -308,11 +378,14 @@ export const useStudyStore = defineStore('study', () => { studyUserRoles, studyStatus, studyId, + studyIsEditable, + studyIsUpdating, + hasCriticalRoles, auditLogMetadata, auditLogEntries, getAuditLogMetadata, exportAuditLog, listParticipantObservationsInTimeline, - participantTimelineObservations + participantTimelineObservations, }; }); diff --git a/src/views/Participants.vue b/src/views/Participants.vue index 74ceae2d..c4ed2c59 100644 --- a/src/views/Participants.vue +++ b/src/views/Participants.vue @@ -7,25 +7,18 @@ Licensed under the Elastic License 2.0. */ import MoreTabNav from '../components/shared/MoreTabNav.vue'; import ParticipantList from '../components/ParticipantList.vue'; import StudyHeader from '../components/shared/StudyHeader.vue'; - import { StudyRole } from '@gs'; import { useStudyStore } from '../stores/studyStore'; - import { useStudyGroupStore } from '../stores/studyGroupStore'; import { useObservationGroupStore } from '../stores/observationGroupStore'; import { onMounted } from 'vue'; + const studyStore = useStudyStore(); - const studyGroupStore = useStudyGroupStore(); const observationGroupStore = useObservationGroupStore(); - const accessRoles: StudyRole[] = [ - StudyRole.StudyAdmin, - StudyRole.StudyOperator, - ]; - -onMounted(() => { - if(observationGroupStore.observationGroups.length === 0) { - observationGroupStore.getObservationGroups(studyStore.studyId) - } -}) + onMounted(() => { + if (observationGroupStore.observationGroups.length === 0) { + observationGroupStore.getObservationGroups(studyStore.studyId); + } + }); diff --git a/src/views/StudyOverview.vue b/src/views/StudyOverview.vue index 4fb71d1a..a6698d38 100644 --- a/src/views/StudyOverview.vue +++ b/src/views/StudyOverview.vue @@ -69,11 +69,7 @@ Licensed under the Elastic License 2.0. */ :study-status="studyStore.studyStatus" /> - + Date: Thu, 26 Mar 2026 15:46:43 +0100 Subject: [PATCH 77/94] #634: Fixed an import issue --- openapitools.json | 2 +- src/components/StudyGroupList.vue | 16 ++-- .../dialog/ParticipantDetailsDialog.vue | 57 +++++++----- src/components/dialog/StudyDialog.vue | 37 ++++---- src/components/shared/RelativeScheduler.vue | 92 ++++++++++--------- src/utils/durationUtils.ts | 22 ++--- src/utils/studyUtils.ts | 6 +- tsconfig.json | 2 +- 8 files changed, 122 insertions(+), 112 deletions(-) diff --git a/openapitools.json b/openapitools.json index bfc9403e..4614a010 100644 --- a/openapitools.json +++ b/openapitools.json @@ -12,7 +12,7 @@ "supportsES6": true, "withSeparateModelsAndApi": true, "withInterfaces": true, - "withoutPrefixEnums": true, + "withoutPrefixEnums": false, "apiPackage": "api", "modelPackage": "models", "enumPropertyNaming": "PascalCase" diff --git a/src/components/StudyGroupList.vue b/src/components/StudyGroupList.vue index 0fc9d166..0c54a061 100644 --- a/src/components/StudyGroupList.vue +++ b/src/components/StudyGroupList.vue @@ -8,16 +8,16 @@ Licensed under the Elastic License 2.0. */ import { MoreStudyGroupTableMap, MoreTableAction, - MoreTableColumn, MoreTableChoice, + MoreTableColumn, MoreTableFieldType, - MoreTableRowActionResult, - } from '../models/MoreTableModel'; + MoreTableRowActionResult + } from '@/models/MoreTableModel'; import { StudyGroup, StudyRole, StudyStatus } from '@gs'; - import { UnitEnum } from '@gs/models/duration'; + import { DurationUnitEnum } from '@gs/models/duration'; import MoreTable from './shared/MoreTable.vue'; import ConfirmDialog from 'primevue/confirmdialog'; - import { useStudyGroupStore } from '../stores/studyGroupStore'; + import { useStudyGroupStore } from '@/stores/studyGroupStore'; import { useI18n } from 'vue-i18n'; import { useDialog } from 'primevue/usedialog'; import DeleteMoreTableRowDialog from './dialog/DeleteMoreTableRowDialog.vue'; @@ -49,15 +49,15 @@ Licensed under the Elastic License 2.0. */ }, { label: t('scheduler.preview.unit.MINUTE'), - value: UnitEnum.Minute, + value: DurationUnitEnum.Minute, }, { label: t('scheduler.preview.unit.HOUR'), - value: UnitEnum.Hour, + value: DurationUnitEnum.Hour, }, { label: t('scheduler.preview.unit.DAY'), - value: UnitEnum.Day, + value: DurationUnitEnum.Day, }, ]; diff --git a/src/components/dialog/ParticipantDetailsDialog.vue b/src/components/dialog/ParticipantDetailsDialog.vue index a05a9b45..e94a0624 100644 --- a/src/components/dialog/ParticipantDetailsDialog.vue +++ b/src/components/dialog/ParticipantDetailsDialog.vue @@ -2,10 +2,10 @@ import { computed, inject, onMounted } from 'vue'; import Button from 'primevue/button'; import { - DataHealthIndicatorEnum, OccurredObservation, + OccurredObservationStateEnum, Participant, - StateEnum, + ParticipantDataHealthIndicatorEnum, } from '@gs'; import { useStudyStore } from '../../stores/studyStore'; import { useI18n } from 'vue-i18n'; @@ -54,11 +54,11 @@ const dataHealthIndicatorBtn = computed(() => { if (participant.dataHealthIndicator) { switch (participant.dataHealthIndicator) { - case DataHealthIndicatorEnum.Green: + case ParticipantDataHealthIndicatorEnum.Green: return 'btn-accepted'; - case DataHealthIndicatorEnum.Orange: + case ParticipantDataHealthIndicatorEnum.Orange: return 'btn-warn'; - case DataHealthIndicatorEnum.Red: + case ParticipantDataHealthIndicatorEnum.Red: return 'btn-important'; default: return 'btn-warn'; @@ -69,11 +69,11 @@ const dataHealthIndicatorIcon = computed(() => { if (participant.dataHealthIndicator) { switch (participant.dataHealthIndicator) { - case DataHealthIndicatorEnum.Green: + case ParticipantDataHealthIndicatorEnum.Green: return 'pi pi-check'; - case DataHealthIndicatorEnum.Orange: + case ParticipantDataHealthIndicatorEnum.Orange: return 'pi pi-exclamation-triangle'; - case DataHealthIndicatorEnum.Red: + case ParticipantDataHealthIndicatorEnum.Red: return 'pi pi-times'; default: return 'pi pi-exclamation-triangle'; @@ -82,17 +82,19 @@ return 'pi pi-exclamation-triangle'; }); - function getDataHealthIndicatorColor(state: StateEnum): string { + function getDataHealthIndicatorColor( + state: OccurredObservationStateEnum, + ): string { switch (state) { - case StateEnum.Completed: + case OccurredObservationStateEnum.Completed: return 'bg-[var(--green-500)]'; default: return 'bg-[var(--orange-500)]'; } } - function getDataHealthIcon(state: StateEnum): string { + function getDataHealthIcon(state: OccurredObservationStateEnum): string { switch (state) { - case StateEnum.Completed: + case OccurredObservationStateEnum.Completed: return 'pi pi-check'; default: return 'pi pi-exclamation-triangle'; @@ -192,20 +194,25 @@ -