fix(frontend): Fix all type issues

This commit is contained in:
2025-11-15 08:40:09 +01:00
parent 1c8815d4ce
commit daf619d6eb
16 changed files with 88 additions and 56 deletions

View File

@@ -96,8 +96,11 @@ function getDropdownItems(formElementId: string, formElementPosition: number): D
function updateFormOptions(formOptions: FormOptionDto[], formElementIndex: number) { function updateFormOptions(formOptions: FormOptionDto[], formElementIndex: number) {
console.log('Updating form options for element index:', formElementIndex, formOptions) console.log('Updating form options for element index:', formElementIndex, formOptions)
const updatedModelValue = [...props.modelValue] const updatedModelValue = [...props.modelValue]
updatedModelValue[formElementIndex] = { ...updatedModelValue[formElementIndex], options: formOptions } const currentElement = updatedModelValue[formElementIndex]
emit('update:modelValue', updatedModelValue) if (currentElement) {
updatedModelValue[formElementIndex] = { ...currentElement, options: formOptions }
emit('update:modelValue', updatedModelValue)
}
} }
function toggleComments(formElementId: string) { function toggleComments(formElementId: string) {

View File

@@ -91,13 +91,13 @@ const statusLabel = computed(() => {
const badgeColor = computed(() => { const badgeColor = computed(() => {
switch (props.status) { switch (props.status) {
case ComplianceStatus.Critical: case ComplianceStatus.Critical:
return 'red' return 'error' as const
case ComplianceStatus.Warning: case ComplianceStatus.Warning:
return 'yellow' return 'warning' as const
case ComplianceStatus.NonCritical: case ComplianceStatus.NonCritical:
return 'green' return 'success' as const
default: default:
return 'green' return 'success' as const
} }
}) })

View File

@@ -8,6 +8,7 @@
:avatar="{ icon: 'i-lucide-bot' }" :avatar="{ icon: 'i-lucide-bot' }"
:content="comment.message" :content="comment.message"
role="user" role="user"
:parts="[{ type: 'text', text: comment.message }]"
:side="isCommentByUser(comment) ? 'right' : 'left'" :side="isCommentByUser(comment) ? 'right' : 'left'"
variant="subtle" variant="subtle"
:actions="createChatMessageActions(comment)" :actions="createChatMessageActions(comment)"

View File

@@ -65,9 +65,9 @@ const userStore = useUserStore()
const { user: keyCloakUser } = storeToRefs(userStore) const { user: keyCloakUser } = storeToRefs(userStore)
const user = ref({ const user = ref({
name: keyCloakUser.value.name, name: keyCloakUser.value?.name ?? 'UNKNOWN',
avatar: { avatar: {
alt: keyCloakUser.value.name alt: keyCloakUser.value?.name ?? 'UNKNOWN'
} }
}) })

View File

@@ -137,20 +137,20 @@ async function handleRestore() {
} }
} }
function getStatusColor(status: ApplicationFormStatus): string { function getStatusColor(status: ApplicationFormStatus) {
switch (status) { switch (status) {
case 'DRAFT': case 'DRAFT':
return 'gray' return 'neutral' as const
case 'SUBMITTED': case 'SUBMITTED':
return 'blue' return 'info' as const
case 'APPROVED': case 'APPROVED':
return 'green' return 'success' as const
case 'REJECTED': case 'REJECTED':
return 'red' return 'error' as const
case 'SIGNED': case 'SIGNED':
return 'primary' return 'primary' as const
default: default:
return 'gray' return 'neutral' as const
} }
} }

View File

@@ -14,15 +14,16 @@ const emit = defineEmits<{
}>() }>()
const modelValue = computed({ const modelValue = computed({
get: () => props.formOptions?.[0].value === 'true', get: () => props.formOptions[0]?.value === 'true',
set: (val) => { set: (val) => {
if (props.formOptions?.[0]) { const firstOption = props.formOptions[0]
if (firstOption) {
const updatedModelValue = [...props.formOptions] const updatedModelValue = [...props.formOptions]
updatedModelValue[0] = { ...updatedModelValue[0], value: val.toString() } updatedModelValue[0] = { ...firstOption, value: val.toString() }
emit('update:formOptions', updatedModelValue) emit('update:formOptions', updatedModelValue)
} }
} }
}) })
const label = computed(() => props.formOptions?.[0].label ?? '') const label = computed(() => props.formOptions[0]?.label ?? '')
</script> </script>

View File

@@ -17,11 +17,12 @@ const emit = defineEmits<{
}>() }>()
const modelValue = computed({ const modelValue = computed({
get: () => props.formOptions?.[0].value ?? '', get: () => props.formOptions[0]?.value ?? '',
set: (val) => { set: (val) => {
if (val && props.formOptions?.[0].value) { const firstOption = props.formOptions[0]
if (val && firstOption) {
const updatedModelValue = [...props.formOptions] const updatedModelValue = [...props.formOptions]
updatedModelValue[0] = { ...updatedModelValue[0], value: val.toString() } updatedModelValue[0] = { ...firstOption, value: val.toString() }
emit('update:formOptions', updatedModelValue) emit('update:formOptions', updatedModelValue)
} }
} }

View File

@@ -14,15 +14,16 @@ const emit = defineEmits<{
}>() }>()
const modelValue = computed({ const modelValue = computed({
get: () => props.formOptions?.[0].value === 'true', get: () => props.formOptions[0]?.value === 'true',
set: (val) => { set: (val) => {
if (props.formOptions?.[0]) { const firstOption = props.formOptions[0]
if (firstOption) {
const updatedModelValue = [...props.formOptions] const updatedModelValue = [...props.formOptions]
updatedModelValue[0] = { ...updatedModelValue[0], value: val.toString() } updatedModelValue[0] = { ...firstOption, value: val.toString() }
emit('update:formOptions', updatedModelValue) emit('update:formOptions', updatedModelValue)
} }
} }
}) })
const label = computed(() => props.formOptions?.[0].label ?? '') const label = computed(() => props.formOptions[0]?.label ?? '')
</script> </script>

View File

@@ -23,33 +23,39 @@ const SEPARATOR = '|||'
const title = computed({ const title = computed({
get: () => { get: () => {
const currentValue = props.formOptions?.[0]?.value ?? '' const currentValue = props.formOptions[0]?.value ?? ''
return splitValue(currentValue).title return splitValue(currentValue).title
}, },
set: (newTitle: string) => { set: (newTitle: string) => {
const currentValue = props.formOptions?.[0]?.value ?? '' const firstOption = props.formOptions[0]
const { body: currentBody } = splitValue(currentValue) if (firstOption) {
const combinedValue = joinValue(newTitle, currentBody) const currentValue = firstOption.value ?? ''
const { body: currentBody } = splitValue(currentValue)
const combinedValue = joinValue(newTitle, currentBody)
const updatedModelValue = [...props.formOptions] const updatedModelValue = [...props.formOptions]
updatedModelValue[0] = { ...updatedModelValue[0], value: combinedValue } updatedModelValue[0] = { ...firstOption, value: combinedValue }
emit('update:formOptions', updatedModelValue) emit('update:formOptions', updatedModelValue)
}
} }
}) })
const body = computed({ const body = computed({
get: () => { get: () => {
const currentValue = props.formOptions?.[0]?.value ?? '' const currentValue = props.formOptions[0]?.value ?? ''
return splitValue(currentValue).body return splitValue(currentValue).body
}, },
set: (newBody: string) => { set: (newBody: string) => {
const currentValue = props.formOptions?.[0]?.value ?? '' const firstOption = props.formOptions[0]
const { title: currentTitle } = splitValue(currentValue) if (firstOption) {
const combinedValue = joinValue(currentTitle, newBody) const currentValue = firstOption.value ?? ''
const { title: currentTitle } = splitValue(currentValue)
const combinedValue = joinValue(currentTitle, newBody)
const updatedModelValue = [...props.formOptions] const updatedModelValue = [...props.formOptions]
updatedModelValue[0] = { ...updatedModelValue[0], value: combinedValue } updatedModelValue[0] = { ...firstOption, value: combinedValue }
emit('update:formOptions', updatedModelValue) emit('update:formOptions', updatedModelValue)
}
} }
}) })

View File

@@ -92,7 +92,7 @@ export const useNotification = () => {
try { try {
await markNotificationAsRead(notificationId, organizationId.value) await markNotificationAsRead(notificationId, organizationId.value)
const index = notifications.value.findIndex((n) => n.id === notificationId) const index = notifications.value.findIndex((n) => n.id === notificationId)
if (index !== -1) { if (index !== -1 && notifications.value[index]) {
notifications.value[index].isRead = true notifications.value[index].isRead = true
} }
// Remove from unread notifications // Remove from unread notifications

View File

@@ -10,7 +10,7 @@ export function useApplicationFormValidator() {
const highestComplianceNumber = Math.max( const highestComplianceNumber = Math.max(
...complianceStatusValues.map((complianceStatus) => Object.values(ComplianceStatus).indexOf(complianceStatus)) ...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<FormElementId, ComplianceStatus> { function validateFormElements(formElements: FormElementDto[]): Map<FormElementId, ComplianceStatus> {

View File

@@ -3,7 +3,7 @@ export const isChecking = ref(false)
export const lastCheckTime = ref<Date | null>(null) export const lastCheckTime = ref<Date | null>(null)
export function useServerHealth() { export function useServerHealth() {
const checkInterval = ref<NodeJS.Timeout | null>(null) const checkInterval = ref<ReturnType<typeof setInterval> | null>(null)
const healthCheckUrl = '/api/actuator/health' const healthCheckUrl = '/api/actuator/health'
async function checkServerHealth(): Promise<boolean> { async function checkServerHealth(): Promise<boolean> {

View File

@@ -32,7 +32,7 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
console.info('access token expired, refreshing') console.info('access token expired, refreshing')
await useRequestFetch()('/api/jwt/refresh', { await useRequestFetch()('/api/jwt/refresh', {
method: 'POST', method: 'POST',
onResponse({ response: { headers } }) { onResponse({ response: { headers } }: { response: { headers: any } }) {
// Forward the Set-Cookie header to the main server event // Forward the Set-Cookie header to the main server event
if (import.meta.server && serverEvent) { if (import.meta.server && serverEvent) {
for (const setCookie of headers.getSetCookie()) { for (const setCookie of headers.getSetCookie()) {

View File

@@ -120,7 +120,10 @@ const selectedOrganizationId = computed({
}, },
set(item) { set(item) {
// TODO: USelect triggers multiple times after single selection // 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
}
} }
}) })

View File

@@ -59,9 +59,12 @@ export const useCommentStore = defineStore('Comment', () => {
try { try {
const updatedComment = await commentApi.updateComment(id, commentDto) const updatedComment = await commentApi.updateComment(id, commentDto)
const formElementId = updatedComment.formElementId const formElementId = updatedComment.formElementId
const index = comments.value?.[formElementId]?.findIndex((comment) => comment.id === id) ?? -1 const formElementComments = comments.value?.[formElementId]
if (index !== -1 && comments.value?.[formElementId][index]) { if (formElementComments) {
comments.value[formElementId][index] = updatedComment const index = formElementComments.findIndex((comment) => comment.id === id)
if (index !== -1 && formElementComments[index]) {
formElementComments[index] = updatedComment
}
} }
return updatedComment return updatedComment
} catch (e: unknown) { } catch (e: unknown) {
@@ -78,10 +81,13 @@ export const useCommentStore = defineStore('Comment', () => {
try { try {
await commentApi.deleteCommentById(id) await commentApi.deleteCommentById(id)
for (const formElementId in comments.value) { for (const formElementId in comments.value) {
const index = comments.value[formElementId].findIndex((comment) => comment.id === id) const formElementComments = comments.value[formElementId]
if (index !== -1) { if (formElementComments) {
comments.value[formElementId].splice(index, 1) const index = formElementComments.findIndex((comment) => comment.id === id)
break if (index !== -1) {
formElementComments.splice(index, 1)
break
}
} }
} }
} catch (e: unknown) { } catch (e: unknown) {

View File

@@ -2,11 +2,21 @@ import type { Organization } from '~~/types/keycloak'
export const useUserStore = defineStore('Organization', () => { export const useUserStore = defineStore('Organization', () => {
const { user } = useUserSession() const { user } = useUserSession()
const selectedOrganization = computed<Organization | null>(() => { const _selectedOrganization = ref<Organization | null>(null)
if (!user.value?.organizations || user.value.organizations.length === 0) {
return null const selectedOrganization = computed<Organization | null>({
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 { return {