add several features for ai chat

This commit is contained in:
einhornimmond 2025-03-18 12:49:25 +01:00
parent 689f7dfcfc
commit 3e7b4fb357
5 changed files with 78 additions and 15 deletions

BIN
admin/public/img/Crea.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
admin/public/img/Crea.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,34 +1,47 @@
<template>
<div class="chat-container">
<b-button class="chat-toggle-button" :variant="toggleButtonVariant" @click="toggleChat">
{{ isChatOpen ? $t('close') : $t('ai.chat-open') }}
</b-button>
<b-button
v-if="!isChatOpen"
:class="['chat-toggle-button', 'bg-crea-img', { 'slide-up-animation': !hasBeenOpened }]"
:variant="light"
@click="openChat"
></b-button>
<div v-if="isChatOpen" class="chat-window">
<div ref="chatContainer" class="messages-scroll-container">
<TransitionGroup class="messages" tag="div" name="chat">
<div v-for="(message, index) in messages" :key="index" :class="['message', message.role]">
<div class="message-content">
{{ message.content }}
<span v-html="message.content.replace(/\n/g, '<br>')"></span>
</div>
</div>
</TransitionGroup>
</div>
<div class="d-flex justify-content-end position-absolute top-0 start-0">
<b-button variant="light" class="chat-close-button mt-1 ms-1 btn-sm" @click="closeChat">
<IIcBaselineClose />
</b-button>
</div>
<div class="input-area">
<BFormTextarea
v-model="newMessage"
class="fs-6"
:placeholder="$t('ai.chat-placeholder')"
:placeholder="textareaPlaceholder"
rows="2"
no-resize
:disabled="loading"
@keyup.enter="sendMessage"
@keydown.ctrl.enter="sendMessage"
></BFormTextarea>
<b-button variant="primary" :disabled="loading" @click="sendMessage">
<b-button variant="light" :disabled="loading" @click="sendMessage">
{{ buttonText }}
</b-button>
</div>
<div class="d-flex justify-content-start">
<b-button variant="light" class="chat-clear-button" @click="clearChat">
{{ $t('ai.chat-clear') }}
</b-button>
</div>
</div>
</div>
</template>
@ -56,15 +69,27 @@ const newMessage = ref('')
const threadId = ref('')
const messages = ref([])
const loading = ref(false)
const hasBeenOpened = ref(false)
const buttonText = computed(() => t('send') + (loading.value ? '...' : ''))
const toggleButtonVariant = computed(() => (isChatOpen.value ? 'secondary' : 'primary'))
const textareaPlaceholder = computed(() =>
loading.value ? t('ai.chat-placeholder-loading') : t('ai.chat-placeholder'),
)
const toggleChat = () => {
isChatOpen.value = !isChatOpen.value
if (isChatOpen.value && messages.value.length > 0) {
function openChat() {
isChatOpen.value = true
if (messages.value.length > 0) {
scrollDown()
}
if (!isChatOpen.value && threadId.value && threadId.value.length > 0) {
}
function closeChat() {
hasBeenOpened.value = true
isChatOpen.value = false
}
// clear
function clearChat() {
if (threadId.value && threadId.value.length > 0) {
// delete thread on closing chat
deleteResponse
.mutate({ threadId: threadId.value })
@ -73,6 +98,8 @@ const toggleChat = () => {
messages.value = []
if (result.data.deleteThread) {
toastSuccess(t('ai.chat-thread-deleted'))
newMessage.value = t('ai.start-prompt')
sendMessage()
}
})
.catch((error) => {
@ -123,8 +150,11 @@ onMounted(async () => {
threadId.value = messagesFromServer[0].threadId
messages.value = messagesFromServer
scrollDown()
loading.value = false
} else {
newMessage.value = t('ai.start-prompt')
sendMessage()
}
loading.value = false
}
})
</script>
@ -145,6 +175,19 @@ onMounted(async () => {
border: 1px solid darkblue;
}
.chat-clear-button {
font-size: 12px;
}
.bg-crea-img {
background-image: url('../../public/img/Crea.webp');
background-size: cover;
background-position: center;
width: 250px;
height: 142px;
z-index: 100;
}
.chat-window {
width: 550px;
height: 300px;
@ -230,4 +273,18 @@ onMounted(async () => {
transform: translateY(0);
opacity: 1;
}
.slide-up-animation {
animation: slideUp 1s ease-out;
opacity: 1;
}
@keyframes slideUp {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
</style>

View File

@ -4,9 +4,12 @@
"ai": {
"chat": "Chat",
"chat-open": "Chat öffnen",
"chat-clear": "Chat-Verlauf löschen",
"chat-placeholder": "Schreibe eine Nachricht...",
"chat-placeholder-loading": "Warte, ich denke nach...",
"chat-thread-deleted": "Chatverlauf gelöscht",
"error-chat-thread-deleted": "Fehler beim Löschen des Chatverlaufs: {error}"
"error-chat-thread-deleted": "Fehler beim Löschen des Chatverlaufs: {error}",
"start-prompt": "Sprache: Deutsch\nTonfall: Freundlich, per Du\nKontext: Du bist \"Crea\", ein Support-Assistent im Admin-Interface des Gradido-Kontos. Deine Aufgabe ist es, Moderatoren bei der Bearbeitung von Gemeinwohl-Beiträgen zu unterstützen.\nBegrüßung:\n\"Hallo, ich bin Crea! Ich unterstütze Dich bei der Beantwortung der eingereichten Gemeinwohl-Beiträge. Damit ich Deine Antworten personalisieren kann, nenne mir bitte Deinen Namen. 😊\"\nWarte nun die Eingabe des Namens ab!\nNach Eingabe des Namens:\n\"Danke, [Name]! Schön, mit Dir zusammenzuarbeiten. 😊 Kopiere nun bitte einen oder mehrere Gemeinwohl-Beiträge in das Textfeld, und ich helfe Dir bei der Bearbeitung.\""
},
"alias": "Alias",
"all_emails": "Alle Nutzer",

View File

@ -4,9 +4,12 @@
"ai": {
"chat": "Chat",
"chat-open": "Open chat",
"chat-clear": "Clear chat",
"chat-placeholder": "Type your message here...",
"chat-placeholder-loading": "Wait, I think...",
"chat-thread-deleted": "Chat thread has been deleted",
"error-chat-thread-deleted": "Error while deleting chat thread: {error}"
"error-chat-thread-deleted": "Error while deleting chat thread: {error}",
"start-prompt": "Language: English\nTone of voice: Friendly, on a first-name basis\nContext: You are \"Crea\", a support assistant in the admin interface of the Gradido account. Your task is to support moderators in editing contributions for the common good.\nGreeting:\n\"Hello, I'm Crea! I support you in answering the contributions for the common good. So that I can personalize your answers, please tell me your name. 😊\"\nNow wait for the name to be entered!\nAfter entering the name:\n\"Thank you, [name]! Nice to work with you. 😊 Now please copy one or more contributions for the common good into the text field and I'll help you edit them.\""
},
"alias": "Alias",
"all_emails": "All users",