feat(email): allow dismissing entity suggestions
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 45s
Build and Push Docker Images / build-frontend (push) Successful in 1m16s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
Build and Push Docker Images / build-docs (push) Successful in 1m18s

This commit is contained in:
2026-09-08 09:54:56 +02:00
parent a09f770a63
commit 1890d1d97d
5 changed files with 107 additions and 5 deletions

View File

@@ -27,6 +27,7 @@ type Suggestion = Omit<EntityLink, "id"> & { confidence: "high" | "medium"; reas
const suggestions = ref<Suggestion[]>([])
const loadingSuggestions = ref(false)
const suggestionError = ref("")
const dismissingSuggestion = ref("")
let suggestionRequest = 0
let active = true
onBeforeUnmount(() => { active = false; suggestionRequest++ })
@@ -124,6 +125,31 @@ async function addLink(suggestion?: Suggestion) {
}
}
async function dismissSuggestion(suggestion: Suggestion) {
const key = `${suggestion.entityType}:${suggestion.entityId}`
const messageId = props.messageId
if (dismissingSuggestion.value) return
dismissingSuggestion.value = key
try {
await useNuxtApp().$api(
`/api/email/messages/${messageId}/entity-suggestions/${suggestion.entityType}/${suggestion.entityId}`,
{ method: "DELETE" },
)
if (!active || messageId !== props.messageId) return
suggestions.value = suggestions.value.filter(item =>
item.entityType !== suggestion.entityType || item.entityId !== suggestion.entityId,
)
} catch (err: any) {
toast.add({
title: "Ausblenden fehlgeschlagen",
description: err?.data?.error || err?.message,
color: "error",
})
} finally {
if (messageId === props.messageId) dismissingSuggestion.value = ""
}
}
async function removeLink(link: EntityLink) {
const messageId = props.messageId
saving.value = true
@@ -199,7 +225,21 @@ watch(selectedEntityType, loadEntityOptions, { immediate: true })
</div>
<p class="mt-1 text-dimmed">{{ suggestion.reason }}</p>
</div>
<UButton size="xs" icon="i-heroicons-link" :disabled="saving" @click="addLink(suggestion)">Übernehmen</UButton>
<div class="flex shrink-0 items-center gap-1">
<UButton
size="xs"
variant="ghost"
color="neutral"
icon="i-heroicons-eye-slash"
:loading="dismissingSuggestion === `${suggestion.entityType}:${suggestion.entityId}`"
:disabled="saving || Boolean(dismissingSuggestion)"
:aria-label="`${suggestion.entityName} ausblenden`"
@click="dismissSuggestion(suggestion)"
>
Ausblenden
</UButton>
<UButton size="xs" icon="i-heroicons-link" :disabled="saving || Boolean(dismissingSuggestion)" @click="addLink(suggestion)">Übernehmen</UButton>
</div>
</div>
</template>
</div>