From daf619d6ebf712c9d28334aaf712531a6155ce66 Mon Sep 17 00:00:00 2001 From: Denis Lugowski Date: Sat, 15 Nov 2025 08:40:09 +0100 Subject: [PATCH] fix(frontend): Fix all type issues --- legalconsenthub/app/components/FormEngine.vue | 7 ++-- .../components/FormValidationIndicator.vue | 8 ++--- legalconsenthub/app/components/TheComment.vue | 1 + legalconsenthub/app/components/UserMenu.vue | 4 +-- .../app/components/VersionHistory.vue | 14 ++++---- .../components/formelements/TheCheckbox.vue | 9 ++--- .../app/components/formelements/TheInput.vue | 7 ++-- .../app/components/formelements/TheSwitch.vue | 9 ++--- .../formelements/TheTitleBodyInput.vue | 34 +++++++++++-------- .../notification/useNotification.ts | 2 +- .../useApplicationFormValidator.ts | 2 +- .../app/composables/useServerHealth.ts | 2 +- .../app/middleware/refreshToken.global.ts | 2 +- legalconsenthub/app/pages/index.vue | 5 ++- legalconsenthub/stores/useCommentStore.ts | 20 +++++++---- legalconsenthub/stores/useUserStore.ts | 18 +++++++--- 16 files changed, 88 insertions(+), 56 deletions(-) diff --git a/legalconsenthub/app/components/FormEngine.vue b/legalconsenthub/app/components/FormEngine.vue index d61dc8f..9cca2df 100644 --- a/legalconsenthub/app/components/FormEngine.vue +++ b/legalconsenthub/app/components/FormEngine.vue @@ -96,8 +96,11 @@ function getDropdownItems(formElementId: string, formElementPosition: number): D function updateFormOptions(formOptions: FormOptionDto[], formElementIndex: number) { console.log('Updating form options for element index:', formElementIndex, formOptions) const updatedModelValue = [...props.modelValue] - updatedModelValue[formElementIndex] = { ...updatedModelValue[formElementIndex], options: formOptions } - emit('update:modelValue', updatedModelValue) + const currentElement = updatedModelValue[formElementIndex] + if (currentElement) { + updatedModelValue[formElementIndex] = { ...currentElement, options: formOptions } + emit('update:modelValue', updatedModelValue) + } } function toggleComments(formElementId: string) { diff --git a/legalconsenthub/app/components/FormValidationIndicator.vue b/legalconsenthub/app/components/FormValidationIndicator.vue index 751041a..19d865b 100644 --- a/legalconsenthub/app/components/FormValidationIndicator.vue +++ b/legalconsenthub/app/components/FormValidationIndicator.vue @@ -91,13 +91,13 @@ const statusLabel = computed(() => { const badgeColor = computed(() => { switch (props.status) { case ComplianceStatus.Critical: - return 'red' + return 'error' as const case ComplianceStatus.Warning: - return 'yellow' + return 'warning' as const case ComplianceStatus.NonCritical: - return 'green' + return 'success' as const default: - return 'green' + return 'success' as const } }) diff --git a/legalconsenthub/app/components/TheComment.vue b/legalconsenthub/app/components/TheComment.vue index 7c8811c..38730dc 100644 --- a/legalconsenthub/app/components/TheComment.vue +++ b/legalconsenthub/app/components/TheComment.vue @@ -8,6 +8,7 @@ :avatar="{ icon: 'i-lucide-bot' }" :content="comment.message" role="user" + :parts="[{ type: 'text', text: comment.message }]" :side="isCommentByUser(comment) ? 'right' : 'left'" variant="subtle" :actions="createChatMessageActions(comment)" diff --git a/legalconsenthub/app/components/UserMenu.vue b/legalconsenthub/app/components/UserMenu.vue index b140ea3..32a0b2c 100644 --- a/legalconsenthub/app/components/UserMenu.vue +++ b/legalconsenthub/app/components/UserMenu.vue @@ -65,9 +65,9 @@ const userStore = useUserStore() const { user: keyCloakUser } = storeToRefs(userStore) const user = ref({ - name: keyCloakUser.value.name, + name: keyCloakUser.value?.name ?? 'UNKNOWN', avatar: { - alt: keyCloakUser.value.name + alt: keyCloakUser.value?.name ?? 'UNKNOWN' } }) diff --git a/legalconsenthub/app/components/VersionHistory.vue b/legalconsenthub/app/components/VersionHistory.vue index 3604ed6..2465888 100644 --- a/legalconsenthub/app/components/VersionHistory.vue +++ b/legalconsenthub/app/components/VersionHistory.vue @@ -137,20 +137,20 @@ async function handleRestore() { } } -function getStatusColor(status: ApplicationFormStatus): string { +function getStatusColor(status: ApplicationFormStatus) { switch (status) { case 'DRAFT': - return 'gray' + return 'neutral' as const case 'SUBMITTED': - return 'blue' + return 'info' as const case 'APPROVED': - return 'green' + return 'success' as const case 'REJECTED': - return 'red' + return 'error' as const case 'SIGNED': - return 'primary' + return 'primary' as const default: - return 'gray' + return 'neutral' as const } } diff --git a/legalconsenthub/app/components/formelements/TheCheckbox.vue b/legalconsenthub/app/components/formelements/TheCheckbox.vue index 374cbb2..ec45510 100644 --- a/legalconsenthub/app/components/formelements/TheCheckbox.vue +++ b/legalconsenthub/app/components/formelements/TheCheckbox.vue @@ -14,15 +14,16 @@ const emit = defineEmits<{ }>() const modelValue = computed({ - get: () => props.formOptions?.[0].value === 'true', + get: () => props.formOptions[0]?.value === 'true', set: (val) => { - if (props.formOptions?.[0]) { + const firstOption = props.formOptions[0] + if (firstOption) { const updatedModelValue = [...props.formOptions] - updatedModelValue[0] = { ...updatedModelValue[0], value: val.toString() } + updatedModelValue[0] = { ...firstOption, value: val.toString() } emit('update:formOptions', updatedModelValue) } } }) -const label = computed(() => props.formOptions?.[0].label ?? '') +const label = computed(() => props.formOptions[0]?.label ?? '') diff --git a/legalconsenthub/app/components/formelements/TheInput.vue b/legalconsenthub/app/components/formelements/TheInput.vue index 0a43c9d..23c8473 100644 --- a/legalconsenthub/app/components/formelements/TheInput.vue +++ b/legalconsenthub/app/components/formelements/TheInput.vue @@ -17,11 +17,12 @@ const emit = defineEmits<{ }>() const modelValue = computed({ - get: () => props.formOptions?.[0].value ?? '', + get: () => props.formOptions[0]?.value ?? '', set: (val) => { - if (val && props.formOptions?.[0].value) { + const firstOption = props.formOptions[0] + if (val && firstOption) { const updatedModelValue = [...props.formOptions] - updatedModelValue[0] = { ...updatedModelValue[0], value: val.toString() } + updatedModelValue[0] = { ...firstOption, value: val.toString() } emit('update:formOptions', updatedModelValue) } } diff --git a/legalconsenthub/app/components/formelements/TheSwitch.vue b/legalconsenthub/app/components/formelements/TheSwitch.vue index 7bc0065..349aa54 100644 --- a/legalconsenthub/app/components/formelements/TheSwitch.vue +++ b/legalconsenthub/app/components/formelements/TheSwitch.vue @@ -14,15 +14,16 @@ const emit = defineEmits<{ }>() const modelValue = computed({ - get: () => props.formOptions?.[0].value === 'true', + get: () => props.formOptions[0]?.value === 'true', set: (val) => { - if (props.formOptions?.[0]) { + const firstOption = props.formOptions[0] + if (firstOption) { const updatedModelValue = [...props.formOptions] - updatedModelValue[0] = { ...updatedModelValue[0], value: val.toString() } + updatedModelValue[0] = { ...firstOption, value: val.toString() } emit('update:formOptions', updatedModelValue) } } }) -const label = computed(() => props.formOptions?.[0].label ?? '') +const label = computed(() => props.formOptions[0]?.label ?? '') diff --git a/legalconsenthub/app/components/formelements/TheTitleBodyInput.vue b/legalconsenthub/app/components/formelements/TheTitleBodyInput.vue index a71f1e7..0f8cdfc 100644 --- a/legalconsenthub/app/components/formelements/TheTitleBodyInput.vue +++ b/legalconsenthub/app/components/formelements/TheTitleBodyInput.vue @@ -23,33 +23,39 @@ const SEPARATOR = '|||' const title = computed({ get: () => { - const currentValue = props.formOptions?.[0]?.value ?? '' + const currentValue = props.formOptions[0]?.value ?? '' return splitValue(currentValue).title }, set: (newTitle: string) => { - const currentValue = props.formOptions?.[0]?.value ?? '' - const { body: currentBody } = splitValue(currentValue) - const combinedValue = joinValue(newTitle, currentBody) + const firstOption = props.formOptions[0] + if (firstOption) { + const currentValue = firstOption.value ?? '' + const { body: currentBody } = splitValue(currentValue) + const combinedValue = joinValue(newTitle, currentBody) - const updatedModelValue = [...props.formOptions] - updatedModelValue[0] = { ...updatedModelValue[0], value: combinedValue } - emit('update:formOptions', updatedModelValue) + const updatedModelValue = [...props.formOptions] + updatedModelValue[0] = { ...firstOption, value: combinedValue } + emit('update:formOptions', updatedModelValue) + } } }) const body = computed({ get: () => { - const currentValue = props.formOptions?.[0]?.value ?? '' + const currentValue = props.formOptions[0]?.value ?? '' return splitValue(currentValue).body }, set: (newBody: string) => { - const currentValue = props.formOptions?.[0]?.value ?? '' - const { title: currentTitle } = splitValue(currentValue) - const combinedValue = joinValue(currentTitle, newBody) + const firstOption = props.formOptions[0] + if (firstOption) { + const currentValue = firstOption.value ?? '' + const { title: currentTitle } = splitValue(currentValue) + const combinedValue = joinValue(currentTitle, newBody) - const updatedModelValue = [...props.formOptions] - updatedModelValue[0] = { ...updatedModelValue[0], value: combinedValue } - emit('update:formOptions', updatedModelValue) + const updatedModelValue = [...props.formOptions] + updatedModelValue[0] = { ...firstOption, value: combinedValue } + emit('update:formOptions', updatedModelValue) + } } }) diff --git a/legalconsenthub/app/composables/notification/useNotification.ts b/legalconsenthub/app/composables/notification/useNotification.ts index f4aec79..68e9c05 100644 --- a/legalconsenthub/app/composables/notification/useNotification.ts +++ b/legalconsenthub/app/composables/notification/useNotification.ts @@ -92,7 +92,7 @@ export const useNotification = () => { try { await markNotificationAsRead(notificationId, organizationId.value) const index = notifications.value.findIndex((n) => n.id === notificationId) - if (index !== -1) { + if (index !== -1 && notifications.value[index]) { notifications.value[index].isRead = true } // Remove from unread notifications diff --git a/legalconsenthub/app/composables/useApplicationFormValidator.ts b/legalconsenthub/app/composables/useApplicationFormValidator.ts index d95ab40..0f23376 100644 --- a/legalconsenthub/app/composables/useApplicationFormValidator.ts +++ b/legalconsenthub/app/composables/useApplicationFormValidator.ts @@ -10,7 +10,7 @@ export function useApplicationFormValidator() { const highestComplianceNumber = Math.max( ...complianceStatusValues.map((complianceStatus) => Object.values(ComplianceStatus).indexOf(complianceStatus)) ) - return Object.values(ComplianceStatus)[highestComplianceNumber] + return Object.values(ComplianceStatus)[highestComplianceNumber] ?? ComplianceStatus.NonCritical } function validateFormElements(formElements: FormElementDto[]): Map { diff --git a/legalconsenthub/app/composables/useServerHealth.ts b/legalconsenthub/app/composables/useServerHealth.ts index 0ba5c2a..a136a7c 100644 --- a/legalconsenthub/app/composables/useServerHealth.ts +++ b/legalconsenthub/app/composables/useServerHealth.ts @@ -3,7 +3,7 @@ export const isChecking = ref(false) export const lastCheckTime = ref(null) export function useServerHealth() { - const checkInterval = ref(null) + const checkInterval = ref | null>(null) const healthCheckUrl = '/api/actuator/health' async function checkServerHealth(): Promise { diff --git a/legalconsenthub/app/middleware/refreshToken.global.ts b/legalconsenthub/app/middleware/refreshToken.global.ts index f29caee..c98ba01 100644 --- a/legalconsenthub/app/middleware/refreshToken.global.ts +++ b/legalconsenthub/app/middleware/refreshToken.global.ts @@ -32,7 +32,7 @@ export default defineNuxtRouteMiddleware(async (to, from) => { console.info('access token expired, refreshing') await useRequestFetch()('/api/jwt/refresh', { method: 'POST', - onResponse({ response: { headers } }) { + onResponse({ response: { headers } }: { response: { headers: any } }) { // Forward the Set-Cookie header to the main server event if (import.meta.server && serverEvent) { for (const setCookie of headers.getSetCookie()) { diff --git a/legalconsenthub/app/pages/index.vue b/legalconsenthub/app/pages/index.vue index 98abe9b..c02a77b 100644 --- a/legalconsenthub/app/pages/index.vue +++ b/legalconsenthub/app/pages/index.vue @@ -120,7 +120,10 @@ const selectedOrganizationId = computed({ }, set(item) { // TODO: USelect triggers multiple times after single selection - selectedOrganization.value = organizations.value.find((i: Organization) => i.id === item) ?? null + const foundOrg = organizations.value?.find((i: Organization) => i.id === item) ?? null + if (foundOrg !== undefined) { + selectedOrganization.value = foundOrg + } } }) diff --git a/legalconsenthub/stores/useCommentStore.ts b/legalconsenthub/stores/useCommentStore.ts index 7f6fddb..65fdbbb 100644 --- a/legalconsenthub/stores/useCommentStore.ts +++ b/legalconsenthub/stores/useCommentStore.ts @@ -59,9 +59,12 @@ export const useCommentStore = defineStore('Comment', () => { try { const updatedComment = await commentApi.updateComment(id, commentDto) const formElementId = updatedComment.formElementId - const index = comments.value?.[formElementId]?.findIndex((comment) => comment.id === id) ?? -1 - if (index !== -1 && comments.value?.[formElementId][index]) { - comments.value[formElementId][index] = updatedComment + const formElementComments = comments.value?.[formElementId] + if (formElementComments) { + const index = formElementComments.findIndex((comment) => comment.id === id) + if (index !== -1 && formElementComments[index]) { + formElementComments[index] = updatedComment + } } return updatedComment } catch (e: unknown) { @@ -78,10 +81,13 @@ export const useCommentStore = defineStore('Comment', () => { try { await commentApi.deleteCommentById(id) for (const formElementId in comments.value) { - const index = comments.value[formElementId].findIndex((comment) => comment.id === id) - if (index !== -1) { - comments.value[formElementId].splice(index, 1) - break + const formElementComments = comments.value[formElementId] + if (formElementComments) { + const index = formElementComments.findIndex((comment) => comment.id === id) + if (index !== -1) { + formElementComments.splice(index, 1) + break + } } } } catch (e: unknown) { diff --git a/legalconsenthub/stores/useUserStore.ts b/legalconsenthub/stores/useUserStore.ts index 5a2caa3..44aae7c 100644 --- a/legalconsenthub/stores/useUserStore.ts +++ b/legalconsenthub/stores/useUserStore.ts @@ -2,11 +2,21 @@ import type { Organization } from '~~/types/keycloak' export const useUserStore = defineStore('Organization', () => { const { user } = useUserSession() - const selectedOrganization = computed(() => { - if (!user.value?.organizations || user.value.organizations.length === 0) { - return null + const _selectedOrganization = ref(null) + + const selectedOrganization = computed({ + get: () => { + if (_selectedOrganization.value) { + return _selectedOrganization.value + } + if (!user.value?.organizations || user.value.organizations.length === 0) { + return null + } + return user.value.organizations[0] + }, + set: (value: Organization | null) => { + _selectedOrganization.value = value } - return user.value.organizations[0] }) return {