diff --git a/components/Element/ChatbotShare.vue b/components/Element/ChatbotShare.vue new file mode 100644 index 0000000..9c6470f --- /dev/null +++ b/components/Element/ChatbotShare.vue @@ -0,0 +1,117 @@ +<template> + <component :is="'link'" v-if="shouldPreloadIframe" rel="preload" :href="iframeSrc" as="fetch" /> + <div class="flex flex-col space-y-6"> + <h1 class="text-2xl font-semibold mb-4 border-b-primary border-b-2">Embed</h1> + + <template v-if="!chatbotIframeEnabled"> + <p class="text-lg"><Icon name="ph:warning-circle-bold" class="text-2xl text-pink-700" /> {{ $t('CHATBOT_IFRAME_DISABLED') }}</p> + <button class="mx-auto px-5 py-1.5 button rounded-lg" @click="enableChatbotIframe"> + <Icon name="ph:check-square-fill" /> + <span>{{ $t('ENABLE') }}</span> + </button> + </template> + + <p class="text-lg">{{ $t('ADD_CHATBOT_IFRAME') }}:</p> + <code ref="codeArea" class="w-full flex-1 bg-slate-300 p-2 rounded-md"> + <iframe<br /> +   src="{{ protocol }}//{{ host }}/chatbot-iframe/{{ uuid }}"<br /> +   style="height: 30rem; width: 24rem" <br /> + ><br /> + </iframe> + </code> + <button class="mx-auto px-5 py-1.5 button rounded-lg" @click="copyCode"> + <Icon :name="!copiedToClip ? 'ph:copy-bold' : 'ph:copy-simple-fill'" /> + <span v-if="!copiedToClip">{{ $t('COPY') }}</span> + <span v-else>{{ $t('COPY') }}!</span> + </button> + <template v-if="chatbotIframeEnabled"> + <p v-if="chatbotIframeEnabled" class="text-lg">{{ $t('BUBBLE_TRY_CHATBOT') }}</p> + <div class="absolute bottom-12 right-6 flex flex-col space-y-6"> + <Transition name="iframe" appear> + <div v-if="iframeVisible" class="shadow-md border-0.5 border-slate-700 rounded-md bg-white z-50"> + <h1 class="pl-6 py-0.5 shadow-sm text-xl font-bold">{{ name }}</h1> + <iframe class="h-[30rem] w-96 rounded-md center" :src="iframeSrc" sandbox="allow-same-origin allow-scripts allow-forms"> </iframe> + </div> + </Transition> + <div class="flex flex-row self-end"> + <button + class="bg-primary text-white rounded-full transform hover:scale-110 transition duration-300 hover:opacity-95" + @click="iframeVisible = !iframeVisible" + > + <Icon :name="!iframeVisible ? 'ph:chat-circle-text-bold' : 'ph:arrow-down-bold'" class="text-3xl m-4" /> + </button> + </div> + </div> + </template> + </div> +</template> + +<script setup lang="ts"> +const props = defineProps({ + uuid: { type: String, default: '' }, + name: { type: String, default: '' }, +}); + +const host = window.location.host; +const protocol = window.location.protocol; +const iframeSrc = ref('/chatbot-iframe/' + props.uuid); +const iframeVisible = ref(false); +const shouldPreloadIframe = ref(true); +const codeArea = ref(); +const copiedToClip = ref(false); +const statesStore = useStatesStore(); +const collection = statesStore.collection as any; +const chatbotIframeEnabled = computed(() => !!collection.cmetadata?.brevia_app?.public_iframe); + +onMounted(() => { + setTimeout(() => { + shouldPreloadIframe.value = false; + }, 5000); +}); + +const copyCode = () => { + navigator.clipboard.writeText(codeArea.value.textContent).then(() => { + copiedToClip.value = true; + setTimeout(() => (copiedToClip.value = false), 500); + }); +}; + +const enableChatbotIframe = async () => { + const brevia_app = collection.cmetadata.brevia_app || {}; + brevia_app.public_iframe = true; + collection.cmetadata.brevia_app = brevia_app; + + const integration = useIntegration(); + await $fetch(`/api/${integration}/collections/${statesStore?.collection?.uuid}`, { + method: 'PATCH', + body: collection, + }); + + statesStore.collection = collection; +}; +</script> + +<style> +.iframe-leave { + scale: 100%; +} + +.iframe-enter { + scale: 0%; +} + +.iframe-leave-to { + scale: 0%; + transform-origin: bottom right; +} + +.iframe-enter-to { + scale: 100%; + transform-origin: bottom right; +} + +.iframe-leave-active, +.iframe-enter-active { + transition: scale 0.5s ease; +} +</style> diff --git a/locales/en/messages.json b/locales/en/messages.json index 114ffa7..4eaec5c 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -5,6 +5,8 @@ "ACCOUNT_ACTIVATION_PAGE": "Account activation page", "ACCOUNT_DELETED": "Your account has been successfully deleted.", "ADD": "Add", + "ADD_CHATBOT_IFRAME": "To add your chatbot anywhere on your site, add this iframe to your html", + "ADVANCED": "Advanced", "ALL_DOWNLOADED_DOCUMENTS_RELATED_TO_THIS": "all uploaded documents related to this", "ALL_RELATED_TO_THIS": "All {items} related to this", "ALREADY_REGISTERED": "Already have an account?", @@ -15,6 +17,7 @@ "ANSWER_IN": "Answer in", "ANSWER_TYPE": "Answer type", "ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS": "Are you sure you want to remove this", + "BUBBLE_TRY_CHATBOT": "Click on the bubble at the bottom right to try the chatbot", "BULLET_LIST_SUMMARY": "Bullet list summary", "CAN_ACCESS_NOW": "You can now log in with your new account", "CANCEL": "Cancel", @@ -24,6 +27,7 @@ "CHAT_HISTORY_EMPTY": "There are no chats in the selected date range", "CHAT_HISTORY_PREVIEW": "Chat history preview", "CHATBOT_HISTORY": "Chatbot messages history", + "CHATBOT_IFRAME_DISABLED": "Chatbot publishing via iframe is currently disabled. Click below to enable it.", "CHECKING": "Checking", "CHECK_YOUR_INBOX": "Check your inbox and follow the instructions to active the account", "CHECK_YOUR_INBOX_RESET": "Check your inbox and follow the instructions to reset your password", @@ -43,6 +47,7 @@ "CONFIRM_READ": "I confirm that I have read the", "CONFIRM_READ_ACCEPT": "I confirm that I have read and accepted the", "COOKIE_OPTIONS": "Cookie Options", + "COPY": "Copy", "CREATE": "Create", "CREATE_NEW_CHATBOT": "Create a new chatbot", "CURRENT_PASSWORD": "Current password", @@ -53,6 +58,7 @@ "DOCUMENT_LANGUAGE": "Document language", "DOCUMENT": "Document", "DOCUMENTS_FOUND": "Documents found", + "DONE": "Done", "DOWNLOAD": "Download", "DOWNLOAD_ANALYSIS": "Download analysis", "DOWNLOAD_SUMMARY": "Download summary", @@ -60,6 +66,7 @@ "EDIT": "Edit", "EDIT_CHATBOT": "Edit chatbot", "EDIT_METADATA": "Edit metadata", + "ENABLE": "Enable", "EXIT": "Exit", "ELAPSED_TIME": "Elapsed time", "ELEMENTS_FOUND": "elements found", @@ -96,6 +103,7 @@ "ERROR_LINKS": "Links with error status" }, "LINK_PLACEHOLDER": "Write here a valid link to a webpage", + "LINKS": "Links", "LOGIN_PLACEHOLDER": "Enter your email or username", "LOGOUT": "Logout", "MAIL_TO": "An email has been sent to ", @@ -142,6 +150,7 @@ "SEND": "Send", "SET_NEW_PASSWORD": "Set the new password", "SETTINGS": "Settings", + "SHARE": "Share", "SHOW_FILTERED": "Show", "SHOW_DOCUMENTS_FOUND": "Show documents found", "SHOW_PASSWORD": "Show Password", diff --git a/locales/it/messages.json b/locales/it/messages.json index fe5dc25..07753d0 100644 --- a/locales/it/messages.json +++ b/locales/it/messages.json @@ -5,6 +5,8 @@ "ACCOUNT_ACTIVATION_PAGE": "Pagina di attivazione dell'account", "ACCOUNT_DELETED": "Il tuo account è stato cancellato con successo.", "ADD": "Aggiungi", + "ADD_CHATBOT_IFRAME": "Per aggiungere il tuo chatbot ovunque nel tuo sito, aggiungi questo iframe al tuo html", + "ADVANCED": "Avanzate", "ALL_DOWNLOADED_DOCUMENTS_RELATED_TO_THIS": "tutti i documenti caricati associati a questo", "ALL_RELATED_TO_THIS": "Tutti i {items} associati a questo", "ALREADY_REGISTERED": "Sei già registrato?", @@ -15,6 +17,7 @@ "ANSWER_TYPE": "Tipo di risposta", "ANSWER_PLACEHOLDER": "Write down here the suggested the chatbot answer", "ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS": "Sei sicuro di voler eliminare questo", + "BUBBLE_TRY_CHATBOT": "Premi sulla bubble in fondo a destra per provare il chatbot", "BULLET_LIST_SUMMARY": "Sommario a punti", "CAN_ACCESS_NOW": "Puoi accedere ora con il tuo nuovo account", "CANCEL": "Annulla", @@ -24,6 +27,7 @@ "CHAT_HISTORY_EMPTY": "Non ci sono chat nell'intervallo selezionato", "CHAT_HISTORY_PREVIEW": "Anteprima delle chat", "CHATBOT_HISTORY": "Archivio messaggi chatbot", + "CHATBOT_IFRAME_DISABLED": "La pubblicazione del chatbot via iframe è disabilitata. Premi qui sotto per attivarla.", "CHECKING": "Controllo in corso", "CHECK_YOUR_INBOX": "Controlla la tua casella di posta e segui le istruzioni per completare la registrazione", "CHECK_YOUR_INBOX_RESET": "Controlla la tua casella di posta e segui le istruzioni per resettare la tua password", @@ -43,6 +47,7 @@ "CONFIRM_READ": "Confermo di avere preso visione della", "CONFIRM_READ_ACCEPT": "Confermo di avere letto e accettato", "COOKIE_OPTIONS": "Opzioni Cookie", + "COPY": "Copia", "CREATE": "Crea", "CREATE_NEW_CHATBOT": "Crea un nuovo chatbot", "CURRENT_PASSWORD": "Password corrente", @@ -53,6 +58,7 @@ "DOCUMENT_LANGUAGE": "Lingua del documento", "DOCUMENT": "Documento", "DOCUMENTS_FOUND": "Documenti trovati", + "DONE": "Fatto", "DOWNLOAD": "Download", "DOWNLOAD_ANALYSIS": "Scarica l'analisi", "DOWNLOAD_SUMMARY": "Scarica il riassunto", @@ -60,6 +66,7 @@ "EDIT": "Modifica", "EDIT_CHATBOT": "Modifica chatbot", "EDIT_METADATA": "Modifica metadati", + "ENABLE": "Attiva", "EXIT": "Esci", "ELAPSED_TIME": "Tempo trascorso", "ELEMENTS_FOUND": "elementi trovati", @@ -90,12 +97,13 @@ "NON_INDEXED_LINKS": "Link non indicizzati", "ERROR_LINKS": "Link in stato di errore" }, + "LINK_PLACEHOLDER": "Scrivi qui un link valido a una pagina web", + "LINKS": "Link", "HELLO": "Ciao {name}", "INDEXING_SUCCESS": "Contenuto indicizzato correttamente!", "INDEXING_FAILURE": "Si è verificato un errore durante l'indicizzazione. Riprova più tardi.", "ITALIAN": "Italiano", "JOBS_LEFT": "Analisi rimanenti", - "LINK_PLACEHOLDER": "Scrivi qui un link valido a una pagina web", "LOGIN_PLACEHOLDER": "Email o nome utente", "LOGOUT": "Esci", "MAIL_TO": "Una email è stata inviata all'indirizzo ", @@ -142,6 +150,7 @@ "SEND": "Invia", "SETTINGS": "Impostazioni", "SET_NEW_PASSWORD": "Applica la nuova password", + "SHARE": "Condividi", "SHOW_FILTERED": "Mostra", "SHOW_DOCUMENTS_FOUND": "Mostra i documenti trovati", "SHOW_PASSWORD": "Mostra password", diff --git a/pages/chatbot/edit-[id].vue b/pages/chatbot/edit-[id].vue index 8eccea0..8917c8b 100644 --- a/pages/chatbot/edit-[id].vue +++ b/pages/chatbot/edit-[id].vue @@ -9,7 +9,7 @@ </div> <div class="space-y-8"> - <UIXTabs v-if="isAdmin" :tabs="[t('OVERVIEW'), t('ADVANCED'), t('FILES'), 'Q & A', t('LINKS')]"> + <UIXTabs v-if="isAdmin" :tabs="[t('OVERVIEW'), t('ADVANCED'), t('FILES'), 'Q & A', t('LINKS'), t('SHARE')]"> <template #0> <FormChatbot @save-title="collection.cmetadata.title = $event" @save-descriprion="collection.cmetadata.description = $event" /> </template> @@ -25,6 +25,9 @@ <template #4> <ElementChatbotLinks /> </template> + <template #5> + <ElementChatbotShare :uuid="collection.uuid" :name="collection.cmetadata?.title" /> + </template> </UIXTabs> <UIXTabs v-else :tabs="[t('OVERVIEW'), t('FILES'), 'Q & A', t('LINKS')]"> <template #0> @@ -47,6 +50,7 @@ <script lang="ts" setup> const config = useRuntimeConfig(); +const { $openModal } = useNuxtApp(); useHead({ title: `Edit Chatbot | ${config.public.appName}` }); const { t } = useI18n();