@8wave/ai-elements 0.73.0 → 0.74.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -15
- package/dist/_chunks/{PkToolShowArtifact-D-dU41VG.js → PkToolShowArtifact-c_vCWUpQ.js} +2 -2
- package/dist/_chunks/{PkToolShowArtifact-D-dU41VG.js.map → PkToolShowArtifact-c_vCWUpQ.js.map} +1 -1
- package/dist/_chunks/{PkToolShowCalendarEvent-B33fWbkk.js → PkToolShowCalendarEvent-D2VHu1V3.js} +3 -3
- package/dist/_chunks/{PkToolShowCalendarEvent-B33fWbkk.js.map → PkToolShowCalendarEvent-D2VHu1V3.js.map} +1 -1
- package/dist/_chunks/{PkToolShowComparison-CcKHsr36.js → PkToolShowComparison-C2ZUH0w4.js} +3 -3
- package/dist/_chunks/{PkToolShowComparison-CcKHsr36.js.map → PkToolShowComparison-C2ZUH0w4.js.map} +1 -1
- package/dist/_chunks/{PkToolShowContactForm-SmOSbCsp.js → PkToolShowContactForm-6C4uWDtf.js} +3 -3
- package/dist/_chunks/{PkToolShowContactForm-SmOSbCsp.js.map → PkToolShowContactForm-6C4uWDtf.js.map} +1 -1
- package/dist/_chunks/{PkToolShowEmail-BOivL2p_.js → PkToolShowEmail-BuyCHUU5.js} +3 -3
- package/dist/_chunks/{PkToolShowEmail-BOivL2p_.js.map → PkToolShowEmail-BuyCHUU5.js.map} +1 -1
- package/dist/_chunks/{PkToolShowImageGallery-Dy0vFEU-.js → PkToolShowImageGallery-ByldZ0nj.js} +2 -2
- package/dist/_chunks/{PkToolShowImageGallery-Dy0vFEU-.js.map → PkToolShowImageGallery-ByldZ0nj.js.map} +1 -1
- package/dist/_chunks/{PkToolShowLocation-US6u26ra.js → PkToolShowLocation-BCFnC5c7.js} +3 -3
- package/dist/_chunks/{PkToolShowLocation-US6u26ra.js.map → PkToolShowLocation-BCFnC5c7.js.map} +1 -1
- package/dist/_chunks/{PkToolShowMessage-Cjslxq94.js → PkToolShowMessage-6Bsfi3BC.js} +3 -3
- package/dist/_chunks/{PkToolShowMessage-Cjslxq94.js.map → PkToolShowMessage-6Bsfi3BC.js.map} +1 -1
- package/dist/_chunks/{PkToolShowMultipleChoice-BEwiJCLu.js → PkToolShowMultipleChoice-BLNTD2lK.js} +3 -3
- package/dist/_chunks/{PkToolShowMultipleChoice-BEwiJCLu.js.map → PkToolShowMultipleChoice-BLNTD2lK.js.map} +1 -1
- package/dist/_chunks/{PkToolShowProductList-D3Qe8yQM.js → PkToolShowProductList-B4S5_m-f.js} +2 -2
- package/dist/_chunks/{PkToolShowProductList-D3Qe8yQM.js.map → PkToolShowProductList-B4S5_m-f.js.map} +1 -1
- package/dist/_chunks/{PkToolShowQrCode-B64sdI0N.js → PkToolShowQrCode-BVZlzYDq.js} +3 -3
- package/dist/_chunks/{PkToolShowQrCode-B64sdI0N.js.map → PkToolShowQrCode-BVZlzYDq.js.map} +1 -1
- package/dist/_chunks/{PkToolShowSources-B2rf94fU.js → PkToolShowSources-BQo5DRwt.js} +2 -2
- package/dist/_chunks/{PkToolShowSources-B2rf94fU.js.map → PkToolShowSources-BQo5DRwt.js.map} +1 -1
- package/dist/_chunks/{PkToolShowSuggestedReply-BGWA08C7.js → PkToolShowSuggestedReply-BxDI6yp_.js} +2 -2
- package/dist/_chunks/{PkToolShowSuggestedReply-BGWA08C7.js.map → PkToolShowSuggestedReply-BxDI6yp_.js.map} +1 -1
- package/dist/_chunks/{PkToolShowWeather-ClMzD04y.js → PkToolShowWeather-DR6egBIP.js} +3 -3
- package/dist/_chunks/{PkToolShowWeather-ClMzD04y.js.map → PkToolShowWeather-DR6egBIP.js.map} +1 -1
- package/dist/_chunks/{PkToolShowWebPages-BCqywwEK.js → PkToolShowWebPages-D8RngE-F.js} +2 -2
- package/dist/_chunks/{PkToolShowWebPages-BCqywwEK.js.map → PkToolShowWebPages-D8RngE-F.js.map} +1 -1
- package/dist/_chunks/{index.es-Z3Hu-QIb.js → index.es-BGFmj59S.js} +2429 -1559
- package/dist/_chunks/{index.es-Z3Hu-QIb.js.map → index.es-BGFmj59S.js.map} +1 -1
- package/dist/ai-elements.es.js +2908 -2711
- package/dist/ai-elements.es.js.map +1 -1
- package/dist-vue/PkChatbot.js +1 -1
- package/dist-vue/PkChatbotFeedbackForm.js +1 -1
- package/dist-vue/PkChatbotFilePreview.js +1 -1
- package/dist-vue/PkChatbotInput.js +1 -1
- package/dist-vue/PkChatbotMessages.js +1 -1
- package/dist-vue/PkChatbotViewChat.js +1 -1
- package/dist-vue/PkChatbotViewConversations.js +1 -1
- package/dist-vue/PkChatbotViewProfile.js +1 -1
- package/dist-vue/_chunks/PkChatbot-woRkjgP5.js +190 -0
- package/dist-vue/_chunks/{PkChatbot-D5_ytfqS.js.map → PkChatbot-woRkjgP5.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotFeedbackForm-CUnS-WyR.js → PkChatbotFeedbackForm-D-lx1URv.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotFeedbackForm-CUnS-WyR.js.map → PkChatbotFeedbackForm-D-lx1URv.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotFilePreview-JSpi3pmN.js → PkChatbotFilePreview-DHzuGtz5.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotFilePreview-JSpi3pmN.js.map → PkChatbotFilePreview-DHzuGtz5.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotInput-ODPhsqZt.js → PkChatbotInput-LHE0HZ9z.js} +3 -3
- package/dist-vue/_chunks/{PkChatbotInput-ODPhsqZt.js.map → PkChatbotInput-LHE0HZ9z.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotMessages-CMLqkhmb.js → PkChatbotMessages-BxTeEm3j.js} +15 -15
- package/dist-vue/_chunks/{PkChatbotMessages-CMLqkhmb.js.map → PkChatbotMessages-BxTeEm3j.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotViewChat-wLCypxNG.js → PkChatbotViewChat-BoEfZeco.js} +9 -9
- package/dist-vue/_chunks/{PkChatbotViewChat-wLCypxNG.js.map → PkChatbotViewChat-BoEfZeco.js.map} +1 -1
- package/dist-vue/_chunks/PkChatbotViewConversations-DvVc1arX.js +163 -0
- package/dist-vue/_chunks/PkChatbotViewConversations-DvVc1arX.js.map +1 -0
- package/dist-vue/_chunks/{PkChatbotViewProfile-CXmmVXrD.js → PkChatbotViewProfile-Dev_6pki.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotViewProfile-CXmmVXrD.js.map → PkChatbotViewProfile-Dev_6pki.js.map} +1 -1
- package/dist-vue/_chunks/{PkRelativeTime-jP41qAJ5.js → PkRelativeTime-WZ2aPcp_.js} +1 -1
- package/dist-vue/_chunks/{PkRelativeTime-jP41qAJ5.js.map → PkRelativeTime-WZ2aPcp_.js.map} +1 -1
- package/dist-vue/_chunks/{PkStreamingMarkdown-CtiMH6FD.js → PkStreamingMarkdown-B4gnJ4hk.js} +1 -1
- package/dist-vue/_chunks/{PkStreamingMarkdown-CtiMH6FD.js.map → PkStreamingMarkdown-B4gnJ4hk.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowArtifact-C2DgB_1z.js → PkToolShowArtifact-EvbUZSOf.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowArtifact-C2DgB_1z.js.map → PkToolShowArtifact-EvbUZSOf.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowContactForm-BzzbXuhh.js → PkToolShowContactForm-CsDOqSJK.js} +3 -3
- package/dist-vue/_chunks/{PkToolShowContactForm-BzzbXuhh.js.map → PkToolShowContactForm-CsDOqSJK.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowImageGallery-DQXrJYop.js → PkToolShowImageGallery-B7Bt6ZGv.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowImageGallery-DQXrJYop.js.map → PkToolShowImageGallery-B7Bt6ZGv.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowLocation-McDIqI8y.js → PkToolShowLocation-DteWf0Cs.js} +1 -1
- package/dist-vue/_chunks/{PkToolShowLocation-McDIqI8y.js.map → PkToolShowLocation-DteWf0Cs.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowMultipleChoice-DW3m6VbJ.js → PkToolShowMultipleChoice-DZXfWtQp.js} +1 -1
- package/dist-vue/_chunks/{PkToolShowMultipleChoice-DW3m6VbJ.js.map → PkToolShowMultipleChoice-DZXfWtQp.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowProductList-BDSJs7bn.js → PkToolShowProductList-CtqWK0x4.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowProductList-BDSJs7bn.js.map → PkToolShowProductList-CtqWK0x4.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowSources-D5cBZxwQ.js → PkToolShowSources-ZtXFkIHt.js} +3 -3
- package/dist-vue/_chunks/{PkToolShowSources-D5cBZxwQ.js.map → PkToolShowSources-ZtXFkIHt.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowSuggestedReply-Dm3BTWYg.js → PkToolShowSuggestedReply-30m9yWDL.js} +1 -1
- package/dist-vue/_chunks/{PkToolShowSuggestedReply-Dm3BTWYg.js.map → PkToolShowSuggestedReply-30m9yWDL.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowWebPages-DnYVhLVU.js → PkToolShowWebPages-DZIdrdWs.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowWebPages-DnYVhLVU.js.map → PkToolShowWebPages-DZIdrdWs.js.map} +1 -1
- package/dist-vue/_chunks/{PkUrl-CH4pWBR8.js → PkUrl-CGbSBfuP.js} +1 -1
- package/dist-vue/_chunks/{PkUrl-CH4pWBR8.js.map → PkUrl-CGbSBfuP.js.map} +1 -1
- package/dist-vue/_chunks/{createChatbotApiClient-2ynLWELM.js → createChatbotApiClient-YJegM3ni.js} +140 -118
- package/dist-vue/_chunks/createChatbotApiClient-YJegM3ni.js.map +1 -0
- package/dist-vue/_chunks/{dist-Bs6dYy7x.js → dist-21vPGg1O.js} +3 -3
- package/dist-vue/_chunks/{dist-Bs6dYy7x.js.map → dist-21vPGg1O.js.map} +1 -1
- package/dist-vue/_chunks/{dist-Bb1zRSg4.js → dist-BGXTbYew2.js} +4 -4
- package/dist-vue/_chunks/dist-BGXTbYew2.js.map +1 -0
- package/dist-vue/_chunks/{dist-BrlD3co0.js → dist-BL9cumqH.js} +2 -2
- package/dist-vue/_chunks/{dist-BrlD3co0.js.map → dist-BL9cumqH.js.map} +1 -1
- package/dist-vue/_chunks/{dist-B9Pw4_a5.js → dist-BU-VgsYM.js} +3 -3
- package/dist-vue/_chunks/{dist-B9Pw4_a5.js.map → dist-BU-VgsYM.js.map} +1 -1
- package/dist-vue/_chunks/{dist-D-tjAaHK.js → dist-BU5m1pTR.js} +3 -3
- package/dist-vue/_chunks/{dist-D-tjAaHK.js.map → dist-BU5m1pTR.js.map} +1 -1
- package/dist-vue/_chunks/{dist-Dn0cKZ5Q.js → dist-BbP2I_Or.js} +2 -2
- package/dist-vue/_chunks/{dist-Dn0cKZ5Q.js.map → dist-BbP2I_Or.js.map} +1 -1
- package/dist-vue/_chunks/{dist-Cvsv0YEw.js → dist-BvmTki6w.js} +3 -3
- package/dist-vue/_chunks/{dist-Cvsv0YEw.js.map → dist-BvmTki6w.js.map} +1 -1
- package/dist-vue/_chunks/{dist-QzbLuLIV.js → dist-C3dPzENq.js} +3 -3
- package/dist-vue/_chunks/{dist-QzbLuLIV.js.map → dist-C3dPzENq.js.map} +1 -1
- package/dist-vue/_chunks/{dist-BMWOJZqC.js → dist-C6AWJq9a.js} +2 -2
- package/dist-vue/_chunks/{dist-BMWOJZqC.js.map → dist-C6AWJq9a.js.map} +1 -1
- package/dist-vue/_chunks/{dist-BQCdUoYc.js → dist-CGNGkvWf.js} +4 -4
- package/dist-vue/_chunks/{dist-BQCdUoYc.js.map → dist-CGNGkvWf.js.map} +1 -1
- package/dist-vue/_chunks/{dist-JOgG1zY3.js → dist-CIN_Avbm.js} +1 -1
- package/dist-vue/_chunks/{dist-JOgG1zY3.js.map → dist-CIN_Avbm.js.map} +1 -1
- package/dist-vue/_chunks/{dist-NKG-Bt-Q.js → dist-CePpgudw.js} +3 -3
- package/dist-vue/_chunks/{dist-NKG-Bt-Q.js.map → dist-CePpgudw.js.map} +1 -1
- package/dist-vue/_chunks/{dist-C13mHkC-.js → dist-CtMo7ig_.js} +2 -2
- package/dist-vue/_chunks/{dist-C13mHkC-.js.map → dist-CtMo7ig_.js.map} +1 -1
- package/dist-vue/_chunks/{dist-DucfoJQX.js → dist-CwG072cD.js} +3 -3
- package/dist-vue/_chunks/{dist-DucfoJQX.js.map → dist-CwG072cD.js.map} +1 -1
- package/dist-vue/_chunks/{dist-_4yQQX_L.js → dist-DFvVVU0-.js} +2 -2
- package/dist-vue/_chunks/{dist-_4yQQX_L.js.map → dist-DFvVVU0-.js.map} +1 -1
- package/dist-vue/_chunks/{dist-C_tRbeXQ.js → dist-DGz57kzK.js} +2 -2
- package/dist-vue/_chunks/{dist-C_tRbeXQ.js.map → dist-DGz57kzK.js.map} +1 -1
- package/dist-vue/_chunks/{dist-C2tC3pDh.js → dist-DT30Xa-D.js} +2 -2
- package/dist-vue/_chunks/{dist-C2tC3pDh.js.map → dist-DT30Xa-D.js.map} +1 -1
- package/dist-vue/_chunks/{dist-DNn7FqmI.js → dist-DoRhRpjL.js} +2 -2
- package/dist-vue/_chunks/{dist-DNn7FqmI.js.map → dist-DoRhRpjL.js.map} +1 -1
- package/dist-vue/_chunks/{dist-CQmgfFIN.js → dist-GnhLE5-A.js} +4 -4
- package/dist-vue/_chunks/{dist-CQmgfFIN.js.map → dist-GnhLE5-A.js.map} +1 -1
- package/dist-vue/_chunks/{dist-1ToEz3Zq.js → dist-QzWOn2Kx.js} +3 -3
- package/dist-vue/_chunks/{dist-1ToEz3Zq.js.map → dist-QzWOn2Kx.js.map} +1 -1
- package/dist-vue/_chunks/{dist-e9UFeG14.js → dist-uYEYs0EJ.js} +2 -2
- package/dist-vue/_chunks/{dist-e9UFeG14.js.map → dist-uYEYs0EJ.js.map} +1 -1
- package/dist-vue/_chunks/{dist-BpT8aqtS.js → dist-ukeBjdwq.js} +4 -4
- package/dist-vue/_chunks/{dist-BpT8aqtS.js.map → dist-ukeBjdwq.js.map} +1 -1
- package/dist-vue/_chunks/{dist-BHTSdHeX.js → dist-wLB8N32T.js} +3 -3
- package/dist-vue/_chunks/{dist-BHTSdHeX.js.map → dist-wLB8N32T.js.map} +1 -1
- package/dist-vue/_chunks/{index.es-BnOT0fHY.js → index.es-CrPSzhoZ.js} +1 -1
- package/dist-vue/_chunks/{index.es-BnOT0fHY.js.map → index.es-CrPSzhoZ.js.map} +1 -1
- package/dist-vue/_chunks/{useChatbotStore-Im8Xjwte.js → useChatbotStore-DGL81KJa.js} +720 -704
- package/dist-vue/_chunks/{useChatbotStore-Im8Xjwte.js.map → useChatbotStore-DGL81KJa.js.map} +1 -1
- package/dist-vue/_chunks/{useLightbox-BiZUwsmB.js → useLightbox-1sB7fmFb.js} +1 -1
- package/dist-vue/_chunks/{useLightbox-BiZUwsmB.js.map → useLightbox-1sB7fmFb.js.map} +1 -1
- package/dist-vue/_chunks/{utils-DO7emdsn.js → utils-BegUBK7s.js} +1 -1
- package/dist-vue/_chunks/{utils-DO7emdsn.js.map → utils-BegUBK7s.js.map} +1 -1
- package/dist-vue/api.js +1 -1
- package/dist-vue/apps/web-component/src/composables/useChatbotAgent.d.ts +3 -1
- package/dist-vue/composables.js +3 -3
- package/dist-vue/index.js +3552 -3512
- package/dist-vue/index.js.map +1 -1
- package/dist-vue/locales.js +56 -20
- package/dist-vue/packages/components/src/PkEditorPrompt.d.ts +2 -0
- package/dist-vue/packages/components/src/chat/PkAgentSettingsPanel.d.ts +6 -3
- package/dist-vue/packages/components/src/chat/PkEditorChannels.d.ts +16 -0
- package/dist-vue/packages/composable/src/chatbot/api/createChatbotApiClient.d.ts +2 -0
- package/dist-vue/packages/models/src/schema/Agent.d.ts +10 -0
- package/dist-vue/packages/models/src/schema/Chat.d.ts +6 -0
- package/dist-vue/packages/models/src/schema/ReasoningChat.d.ts +3 -1
- package/dist-vue/packages/models/src/schema/SubAgent.d.ts +3 -1
- package/dist-vue/style.css +1 -1
- package/package.json +1 -1
- package/dist-vue/_chunks/PkChatbot-D5_ytfqS.js +0 -190
- package/dist-vue/_chunks/PkChatbotViewConversations-B5qBiqo4.js +0 -40
- package/dist-vue/_chunks/PkChatbotViewConversations-B5qBiqo4.js.map +0 -1
- package/dist-vue/_chunks/createChatbotApiClient-2ynLWELM.js.map +0 -1
- package/dist-vue/_chunks/dist-Bb1zRSg4.js.map +0 -1
package/dist-vue/_chunks/{PkChatbotViewChat-wLCypxNG.js.map → PkChatbotViewChat-BoEfZeco.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PkChatbotViewChat-wLCypxNG.js","names":["$n","$t"],"sources":["../../../../packages/components/src/chat/PkToolRequestGeolocation.vue","../../../../packages/components/src/chat/PkToolRequestGeolocation.vue","../../../../packages/components/src/chat/PkChatbotViewChat.vue","../../../../packages/components/src/chat/PkChatbotViewChat.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, onMounted } from 'vue'\n import { useI18n } from 'vue-i18n'\n\n import type { ReverseGeocodeFn } from 'utils/src/device-context'\n\n type GeolocationOutput =\n | {\n latitude: number\n longitude: number\n accuracy?: number\n city?: string\n }\n | { error: 'permission_denied' | 'position_unavailable' | 'timeout' }\n\n const props = defineProps<{\n part: unknown\n reverseGeocode?: ReverseGeocodeFn\n }>()\n\n const emit = defineEmits<{\n result: [output: GeolocationOutput]\n }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const toolPart = computed(() => {\n return props.part as {\n state?: string\n input?: { reason?: string }\n output?: GeolocationOutput\n }\n })\n\n const state = computed(() => toolPart.value.state ?? 'unknown')\n\n const isOutputAvailable = computed(() => state.value === 'output-available')\n\n const successOutput = computed(() => {\n const out = toolPart.value.output\n if (!out || 'error' in out) {\n return undefined\n }\n return out\n })\n\n const errorOutput = computed(() => {\n const out = toolPart.value.output\n if (!out || !('error' in out)) {\n return undefined\n }\n return out\n })\n\n /** Maps GeolocationPositionError.code to a typed string */\n function mapGeolocationError(\n code: number,\n ): 'permission_denied' | 'position_unavailable' | 'timeout' {\n if (code === 1) {\n return 'permission_denied'\n }\n if (code === 3) {\n return 'timeout'\n }\n return 'position_unavailable'\n }\n\n onMounted(() => {\n if (state.value !== 'input-available') {\n return\n }\n\n if (!navigator.geolocation) {\n emit('result', { error: 'position_unavailable' })\n return\n }\n\n navigator.geolocation.getCurrentPosition(\n async (position) => {\n const { latitude, longitude, accuracy } = position.coords\n const city = props.reverseGeocode\n ? await props\n .reverseGeocode(latitude, longitude)\n .catch(() => undefined)\n : undefined\n emit('result', { latitude, longitude, accuracy, city })\n },\n (error) => {\n emit('result', { error: mapGeolocationError(error.code) })\n },\n { timeout: 15000 },\n )\n })\n</script>\n\n<template>\n <div\n class=\"flex items-center gap-6 text-12 text-word-3 border border-surface-3 rounded-xl px-sm py-10\">\n <!-- Loading state -->\n <template v-if=\"!isOutputAvailable\">\n <VvIcon name=\"line-md:loading-loop\" class=\"text-16\" />\n <span>{{ $t('messagePart.requestGeolocation') }}</span>\n </template>\n\n <!-- Success state -->\n <template v-else-if=\"successOutput\">\n <VvIcon name=\"ri:map-pin-line\" class=\"text-16\" />\n <span>\n {{\n $n(successOutput.latitude, {\n style: 'decimal',\n minimumFractionDigits: 5,\n maximumFractionDigits: 5,\n })\n }},\n {{\n $n(successOutput.longitude, {\n style: 'decimal',\n minimumFractionDigits: 5,\n maximumFractionDigits: 5,\n })\n }}\n <template v-if=\"successOutput.accuracy !== undefined\">\n (±{{\n $n(successOutput.accuracy, {\n style: 'unit',\n unit: 'meter',\n })\n }})\n </template>\n </span>\n </template>\n\n <!-- Error state -->\n <template v-else-if=\"errorOutput\">\n <span class=\"i-vv-alert-circle text-16 shrink-0 text-danger\" />\n <span>\n {{\n errorOutput.error === 'permission_denied'\n ? $t('message.geolocationPermissionDenied')\n : $t('message.geolocationUnavailable')\n }}\n </span>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, onMounted } from 'vue'\n import { useI18n } from 'vue-i18n'\n\n import type { ReverseGeocodeFn } from 'utils/src/device-context'\n\n type GeolocationOutput =\n | {\n latitude: number\n longitude: number\n accuracy?: number\n city?: string\n }\n | { error: 'permission_denied' | 'position_unavailable' | 'timeout' }\n\n const props = defineProps<{\n part: unknown\n reverseGeocode?: ReverseGeocodeFn\n }>()\n\n const emit = defineEmits<{\n result: [output: GeolocationOutput]\n }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const toolPart = computed(() => {\n return props.part as {\n state?: string\n input?: { reason?: string }\n output?: GeolocationOutput\n }\n })\n\n const state = computed(() => toolPart.value.state ?? 'unknown')\n\n const isOutputAvailable = computed(() => state.value === 'output-available')\n\n const successOutput = computed(() => {\n const out = toolPart.value.output\n if (!out || 'error' in out) {\n return undefined\n }\n return out\n })\n\n const errorOutput = computed(() => {\n const out = toolPart.value.output\n if (!out || !('error' in out)) {\n return undefined\n }\n return out\n })\n\n /** Maps GeolocationPositionError.code to a typed string */\n function mapGeolocationError(\n code: number,\n ): 'permission_denied' | 'position_unavailable' | 'timeout' {\n if (code === 1) {\n return 'permission_denied'\n }\n if (code === 3) {\n return 'timeout'\n }\n return 'position_unavailable'\n }\n\n onMounted(() => {\n if (state.value !== 'input-available') {\n return\n }\n\n if (!navigator.geolocation) {\n emit('result', { error: 'position_unavailable' })\n return\n }\n\n navigator.geolocation.getCurrentPosition(\n async (position) => {\n const { latitude, longitude, accuracy } = position.coords\n const city = props.reverseGeocode\n ? await props\n .reverseGeocode(latitude, longitude)\n .catch(() => undefined)\n : undefined\n emit('result', { latitude, longitude, accuracy, city })\n },\n (error) => {\n emit('result', { error: mapGeolocationError(error.code) })\n },\n { timeout: 15000 },\n )\n })\n</script>\n\n<template>\n <div\n class=\"flex items-center gap-6 text-12 text-word-3 border border-surface-3 rounded-xl px-sm py-10\">\n <!-- Loading state -->\n <template v-if=\"!isOutputAvailable\">\n <VvIcon name=\"line-md:loading-loop\" class=\"text-16\" />\n <span>{{ $t('messagePart.requestGeolocation') }}</span>\n </template>\n\n <!-- Success state -->\n <template v-else-if=\"successOutput\">\n <VvIcon name=\"ri:map-pin-line\" class=\"text-16\" />\n <span>\n {{\n $n(successOutput.latitude, {\n style: 'decimal',\n minimumFractionDigits: 5,\n maximumFractionDigits: 5,\n })\n }},\n {{\n $n(successOutput.longitude, {\n style: 'decimal',\n minimumFractionDigits: 5,\n maximumFractionDigits: 5,\n })\n }}\n <template v-if=\"successOutput.accuracy !== undefined\">\n (±{{\n $n(successOutput.accuracy, {\n style: 'unit',\n unit: 'meter',\n })\n }})\n </template>\n </span>\n </template>\n\n <!-- Error state -->\n <template v-else-if=\"errorOutput\">\n <span class=\"i-vv-alert-circle text-16 shrink-0 text-danger\" />\n <span>\n {{\n errorOutput.error === 'permission_denied'\n ? $t('message.geolocationPermissionDenied')\n : $t('message.geolocationUnavailable')\n }}\n </span>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, useTemplateRef } from 'vue'\n import { useDropZone } from '@vueuse/core'\n import { storeToRefs } from 'pinia'\n import PkChatbotMessages from './PkChatbotMessages.vue'\n import PkChatbotInput from './PkChatbotInput.vue'\n import PkToolShowMultipleChoice from './PkToolShowMultipleChoice.vue'\n import PkToolShowContactForm from './PkToolShowContactForm.vue'\n import PkToolShowSuggestedReply from './PkToolShowSuggestedReply.vue'\n import PkToolShowSources from './PkToolShowSources.vue'\n import PkToolRequestGeolocation from './PkToolRequestGeolocation.vue'\n import PkToolShowLocation from './PkToolShowLocation.vue'\n import { useLocalizedString } from '../composables/useLocalizedString'\n import { useChatbotStore } from 'composables'\n import type { UIChatMessage } from 'models'\n\n const props = defineProps<{ agentId: string }>()\n\n const emit = defineEmits<{\n 'show-info': [message: UIChatMessage]\n revise: [message: UIChatMessage]\n }>()\n\n const store = useChatbotStore(props.agentId)\n\n const {\n name,\n agentInterface,\n agentFileUpload,\n actions,\n revisedAnswers,\n messages,\n chat,\n messageFeedbacks,\n feedbackDialogMessage,\n isFeedbackSubmitting,\n isFeedbackSubmitted,\n feedbackSubmitError,\n isLeadSubmitted,\n isLoadingSubmitLead,\n submitLeadError,\n input,\n inputMessagePlaceholder,\n isConversationBlocked,\n baseUrl,\n pendingAttachments,\n apiClient,\n } = storeToRefs(store)\n\n const {\n handleSubmit: storeHandleSubmit,\n stopGeneration,\n regenerate,\n onUpvote,\n onDownvote,\n onFeedback,\n onFeedbackSubmit,\n onLeadSubmit,\n startNewChat,\n addToolOutput,\n handleFileSelect,\n } = store\n\n const dismissableNotice = useLocalizedString(\n () => agentInterface.value?.dismissableNotice,\n )\n\n const chatViewEl = useTemplateRef<HTMLDivElement>('chatViewEl')\n\n const handleExpandSourceContext = async (payload: {\n documentId: string\n chunkIndex: number\n }) => {\n const result = await apiClient.value.expandSourceContext(\n props.agentId,\n payload.documentId,\n payload.chunkIndex,\n )\n return result.content\n }\n\n const handleDownloadSource = async (documentId: string) => {\n const result = await apiClient.value.downloadSourceDocument(\n props.agentId,\n documentId,\n )\n window.open(result.downloadUrl, '_blank')\n }\n\n const handleFileDrop = (files: File[] | null) => {\n if (!agentFileUpload.value?.enabled || !files) {\n return\n }\n for (const file of files) {\n handleFileSelect(file)\n }\n }\n\n const { isOverDropZone } = useDropZone(chatViewEl, {\n dataTypes: computed(\n () => agentFileUpload.value?.allowedMimeTypes ?? [],\n ),\n onDrop: handleFileDrop,\n })\n</script>\n\n<template>\n <div\n ref=\"chatViewEl\"\n class=\"pk-chatbot-view-chat\"\n :class=\"{\n 'pk-chatbot-view-chat--dragover':\n isOverDropZone && agentFileUpload?.enabled,\n }\">\n <!-- #region messages -->\n <PkChatbotMessages\n class=\"flex flex-col flex-1 min-h-0 p-md overflow-y-auto\"\n :name=\"name\"\n :messages=\"messages\"\n :status=\"chat.status\"\n :error=\"chat.error\"\n :main-color=\"agentInterface?.mainColor\"\n :text-color=\"agentInterface?.textColor\"\n :revised-answers=\"revisedAnswers\"\n :actions=\"actions\"\n :logo=\"agentInterface?.logo\"\n :message-feedbacks=\"messageFeedbacks\"\n :feedback-message-id=\"feedbackDialogMessage?.id\"\n :feedback-loading=\"isFeedbackSubmitting\"\n :feedback-submitted=\"isFeedbackSubmitted\"\n :feedback-error=\"feedbackSubmitError\"\n @feedback-submit=\"onFeedbackSubmit($event)\"\n @feedback-close=\"feedbackDialogMessage = undefined\"\n @regenerate=\"regenerate\"\n @auto-retry=\"regenerate\"\n @reset-chat=\"startNewChat\"\n @show-info=\"emit('show-info', $event)\"\n @revise=\"emit('revise', $event)\"\n @upvote=\"onUpvote\"\n @downvote=\"onDownvote\"\n @feedback=\"onFeedback\">\n <template #tool-showContactForm=\"{ part }\">\n <PkToolShowContactForm\n :part\n :readonly=\"!baseUrl\"\n :submitted=\"isLeadSubmitted\"\n :loading=\"isLoadingSubmitLead\"\n :error=\"submitLeadError\"\n :privacy-policy-notice=\"agentInterface?.privacyPolicyNotice\"\n @submit=\"onLeadSubmit\" />\n </template>\n <template #tool-showSuggestedReply=\"{ part }\">\n <PkToolShowSuggestedReply\n :part\n @select=\"\n ($event) => {\n input = $event\n storeHandleSubmit()\n }\n \" />\n </template>\n <template #tool-showSources=\"{ part }\">\n <PkToolShowSources\n :part\n :on-expand-context=\"handleExpandSourceContext\"\n :on-download=\"handleDownloadSource\" />\n </template>\n <template #tool-showMultipleChoice=\"{ part }\">\n <transition mode=\"out-in\">\n <PkToolShowMultipleChoice\n :part\n @select=\"\n addToolOutput({\n tool: 'showMultipleChoice',\n toolCallId: (part as any).toolCallId,\n output: $event,\n })\n \" />\n </transition>\n </template>\n <template #tool-requestGeolocation=\"{ part }\">\n <PkToolRequestGeolocation\n :part\n :reverse-geocode=\"\n (lat: number, lon: number) =>\n apiClient.reverseGeocode(lat, lon)\n \"\n @result=\"\n addToolOutput({\n tool: 'requestGeolocation',\n toolCallId: (part as any).toolCallId,\n output: $event,\n })\n \" />\n </template>\n <template #tool-showLocation=\"{ part }\">\n <PkToolShowLocation\n :part\n :forward-geocode=\"\n (query: string, lang?: string) =>\n apiClient.forwardGeocode(query, lang)\n \" />\n </template>\n </PkChatbotMessages>\n <!-- #endregion -->\n\n <!-- #region input -->\n <div\n v-if=\"isConversationBlocked\"\n class=\"p-md border-t border-surface-3 text-center text-12 text-danger-darken-2 bg-surface-danger\">\n {{ $t('message.chatErrorConversationBlocked') }}\n </div>\n <PkChatbotInput\n v-else\n v-model=\"input\"\n v-model:pending-attachments=\"pendingAttachments\"\n :placeholder=\"inputMessagePlaceholder\"\n :dismissable-notice=\"\n dismissableNotice && chat.messages.length <= 1\n ? dismissableNotice\n : undefined\n \"\n :status=\"chat.status\"\n :max-message-length=\"agentInterface?.maxMessageLength\"\n :file-upload=\"agentFileUpload\"\n @stop-generation=\"stopGeneration\"\n @submit=\"storeHandleSubmit\"\n @file-select=\"handleFileSelect\" />\n <!-- #endregion -->\n <Transition>\n <div\n v-if=\"isOverDropZone && agentFileUpload?.enabled\"\n class=\"pk-chatbot-view-chat__drop-overlay\">\n <VvIcon\n name=\"ri:upload-cloud-2-line\"\n class=\"pk-chatbot-view-chat__drop-overlay-icon\" />\n <span>{{ $t('action.dropFile') }}</span>\n </div>\n </Transition>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-view-chat {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n\n &__drop-overlay {\n position: absolute;\n inset: var(--spacing-sm) var(--spacing-sm) var(--spacing-sm)\n var(--spacing-sm);\n z-index: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-xs);\n background-color: color-mix(\n in srgb,\n var(--color-surface) 85%,\n transparent\n );\n border-radius: var(--rounded-xl);\n border: var(--spacing-2) dashed var(--color-surface-5);\n pointer-events: none;\n color: var(--color-word-3);\n\n &-icon {\n font-size: var(--spacing-32);\n }\n }\n }\n</style>\n","<script setup lang=\"ts\">\n import { computed, useTemplateRef } from 'vue'\n import { useDropZone } from '@vueuse/core'\n import { storeToRefs } from 'pinia'\n import PkChatbotMessages from './PkChatbotMessages.vue'\n import PkChatbotInput from './PkChatbotInput.vue'\n import PkToolShowMultipleChoice from './PkToolShowMultipleChoice.vue'\n import PkToolShowContactForm from './PkToolShowContactForm.vue'\n import PkToolShowSuggestedReply from './PkToolShowSuggestedReply.vue'\n import PkToolShowSources from './PkToolShowSources.vue'\n import PkToolRequestGeolocation from './PkToolRequestGeolocation.vue'\n import PkToolShowLocation from './PkToolShowLocation.vue'\n import { useLocalizedString } from '../composables/useLocalizedString'\n import { useChatbotStore } from 'composables'\n import type { UIChatMessage } from 'models'\n\n const props = defineProps<{ agentId: string }>()\n\n const emit = defineEmits<{\n 'show-info': [message: UIChatMessage]\n revise: [message: UIChatMessage]\n }>()\n\n const store = useChatbotStore(props.agentId)\n\n const {\n name,\n agentInterface,\n agentFileUpload,\n actions,\n revisedAnswers,\n messages,\n chat,\n messageFeedbacks,\n feedbackDialogMessage,\n isFeedbackSubmitting,\n isFeedbackSubmitted,\n feedbackSubmitError,\n isLeadSubmitted,\n isLoadingSubmitLead,\n submitLeadError,\n input,\n inputMessagePlaceholder,\n isConversationBlocked,\n baseUrl,\n pendingAttachments,\n apiClient,\n } = storeToRefs(store)\n\n const {\n handleSubmit: storeHandleSubmit,\n stopGeneration,\n regenerate,\n onUpvote,\n onDownvote,\n onFeedback,\n onFeedbackSubmit,\n onLeadSubmit,\n startNewChat,\n addToolOutput,\n handleFileSelect,\n } = store\n\n const dismissableNotice = useLocalizedString(\n () => agentInterface.value?.dismissableNotice,\n )\n\n const chatViewEl = useTemplateRef<HTMLDivElement>('chatViewEl')\n\n const handleExpandSourceContext = async (payload: {\n documentId: string\n chunkIndex: number\n }) => {\n const result = await apiClient.value.expandSourceContext(\n props.agentId,\n payload.documentId,\n payload.chunkIndex,\n )\n return result.content\n }\n\n const handleDownloadSource = async (documentId: string) => {\n const result = await apiClient.value.downloadSourceDocument(\n props.agentId,\n documentId,\n )\n window.open(result.downloadUrl, '_blank')\n }\n\n const handleFileDrop = (files: File[] | null) => {\n if (!agentFileUpload.value?.enabled || !files) {\n return\n }\n for (const file of files) {\n handleFileSelect(file)\n }\n }\n\n const { isOverDropZone } = useDropZone(chatViewEl, {\n dataTypes: computed(\n () => agentFileUpload.value?.allowedMimeTypes ?? [],\n ),\n onDrop: handleFileDrop,\n })\n</script>\n\n<template>\n <div\n ref=\"chatViewEl\"\n class=\"pk-chatbot-view-chat\"\n :class=\"{\n 'pk-chatbot-view-chat--dragover':\n isOverDropZone && agentFileUpload?.enabled,\n }\">\n <!-- #region messages -->\n <PkChatbotMessages\n class=\"flex flex-col flex-1 min-h-0 p-md overflow-y-auto\"\n :name=\"name\"\n :messages=\"messages\"\n :status=\"chat.status\"\n :error=\"chat.error\"\n :main-color=\"agentInterface?.mainColor\"\n :text-color=\"agentInterface?.textColor\"\n :revised-answers=\"revisedAnswers\"\n :actions=\"actions\"\n :logo=\"agentInterface?.logo\"\n :message-feedbacks=\"messageFeedbacks\"\n :feedback-message-id=\"feedbackDialogMessage?.id\"\n :feedback-loading=\"isFeedbackSubmitting\"\n :feedback-submitted=\"isFeedbackSubmitted\"\n :feedback-error=\"feedbackSubmitError\"\n @feedback-submit=\"onFeedbackSubmit($event)\"\n @feedback-close=\"feedbackDialogMessage = undefined\"\n @regenerate=\"regenerate\"\n @auto-retry=\"regenerate\"\n @reset-chat=\"startNewChat\"\n @show-info=\"emit('show-info', $event)\"\n @revise=\"emit('revise', $event)\"\n @upvote=\"onUpvote\"\n @downvote=\"onDownvote\"\n @feedback=\"onFeedback\">\n <template #tool-showContactForm=\"{ part }\">\n <PkToolShowContactForm\n :part\n :readonly=\"!baseUrl\"\n :submitted=\"isLeadSubmitted\"\n :loading=\"isLoadingSubmitLead\"\n :error=\"submitLeadError\"\n :privacy-policy-notice=\"agentInterface?.privacyPolicyNotice\"\n @submit=\"onLeadSubmit\" />\n </template>\n <template #tool-showSuggestedReply=\"{ part }\">\n <PkToolShowSuggestedReply\n :part\n @select=\"\n ($event) => {\n input = $event\n storeHandleSubmit()\n }\n \" />\n </template>\n <template #tool-showSources=\"{ part }\">\n <PkToolShowSources\n :part\n :on-expand-context=\"handleExpandSourceContext\"\n :on-download=\"handleDownloadSource\" />\n </template>\n <template #tool-showMultipleChoice=\"{ part }\">\n <transition mode=\"out-in\">\n <PkToolShowMultipleChoice\n :part\n @select=\"\n addToolOutput({\n tool: 'showMultipleChoice',\n toolCallId: (part as any).toolCallId,\n output: $event,\n })\n \" />\n </transition>\n </template>\n <template #tool-requestGeolocation=\"{ part }\">\n <PkToolRequestGeolocation\n :part\n :reverse-geocode=\"\n (lat: number, lon: number) =>\n apiClient.reverseGeocode(lat, lon)\n \"\n @result=\"\n addToolOutput({\n tool: 'requestGeolocation',\n toolCallId: (part as any).toolCallId,\n output: $event,\n })\n \" />\n </template>\n <template #tool-showLocation=\"{ part }\">\n <PkToolShowLocation\n :part\n :forward-geocode=\"\n (query: string, lang?: string) =>\n apiClient.forwardGeocode(query, lang)\n \" />\n </template>\n </PkChatbotMessages>\n <!-- #endregion -->\n\n <!-- #region input -->\n <div\n v-if=\"isConversationBlocked\"\n class=\"p-md border-t border-surface-3 text-center text-12 text-danger-darken-2 bg-surface-danger\">\n {{ $t('message.chatErrorConversationBlocked') }}\n </div>\n <PkChatbotInput\n v-else\n v-model=\"input\"\n v-model:pending-attachments=\"pendingAttachments\"\n :placeholder=\"inputMessagePlaceholder\"\n :dismissable-notice=\"\n dismissableNotice && chat.messages.length <= 1\n ? dismissableNotice\n : undefined\n \"\n :status=\"chat.status\"\n :max-message-length=\"agentInterface?.maxMessageLength\"\n :file-upload=\"agentFileUpload\"\n @stop-generation=\"stopGeneration\"\n @submit=\"storeHandleSubmit\"\n @file-select=\"handleFileSelect\" />\n <!-- #endregion -->\n <Transition>\n <div\n v-if=\"isOverDropZone && agentFileUpload?.enabled\"\n class=\"pk-chatbot-view-chat__drop-overlay\">\n <VvIcon\n name=\"ri:upload-cloud-2-line\"\n class=\"pk-chatbot-view-chat__drop-overlay-icon\" />\n <span>{{ $t('action.dropFile') }}</span>\n </div>\n </Transition>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-view-chat {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n\n &__drop-overlay {\n position: absolute;\n inset: var(--spacing-sm) var(--spacing-sm) var(--spacing-sm)\n var(--spacing-sm);\n z-index: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-xs);\n background-color: color-mix(\n in srgb,\n var(--color-surface) 85%,\n transparent\n );\n border-radius: var(--rounded-xl);\n border: var(--spacing-2) dashed var(--color-surface-5);\n pointer-events: none;\n color: var(--color-word-3);\n\n &-icon {\n font-size: var(--spacing-32);\n }\n }\n }\n</style>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PkChatbotViewChat-BoEfZeco.js","names":["$n","$t"],"sources":["../../../../packages/components/src/chat/PkToolRequestGeolocation.vue","../../../../packages/components/src/chat/PkToolRequestGeolocation.vue","../../../../packages/components/src/chat/PkChatbotViewChat.vue","../../../../packages/components/src/chat/PkChatbotViewChat.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, onMounted } from 'vue'\n import { useI18n } from 'vue-i18n'\n\n import type { ReverseGeocodeFn } from 'utils/src/device-context'\n\n type GeolocationOutput =\n | {\n latitude: number\n longitude: number\n accuracy?: number\n city?: string\n }\n | { error: 'permission_denied' | 'position_unavailable' | 'timeout' }\n\n const props = defineProps<{\n part: unknown\n reverseGeocode?: ReverseGeocodeFn\n }>()\n\n const emit = defineEmits<{\n result: [output: GeolocationOutput]\n }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const toolPart = computed(() => {\n return props.part as {\n state?: string\n input?: { reason?: string }\n output?: GeolocationOutput\n }\n })\n\n const state = computed(() => toolPart.value.state ?? 'unknown')\n\n const isOutputAvailable = computed(() => state.value === 'output-available')\n\n const successOutput = computed(() => {\n const out = toolPart.value.output\n if (!out || 'error' in out) {\n return undefined\n }\n return out\n })\n\n const errorOutput = computed(() => {\n const out = toolPart.value.output\n if (!out || !('error' in out)) {\n return undefined\n }\n return out\n })\n\n /** Maps GeolocationPositionError.code to a typed string */\n function mapGeolocationError(\n code: number,\n ): 'permission_denied' | 'position_unavailable' | 'timeout' {\n if (code === 1) {\n return 'permission_denied'\n }\n if (code === 3) {\n return 'timeout'\n }\n return 'position_unavailable'\n }\n\n onMounted(() => {\n if (state.value !== 'input-available') {\n return\n }\n\n if (!navigator.geolocation) {\n emit('result', { error: 'position_unavailable' })\n return\n }\n\n navigator.geolocation.getCurrentPosition(\n async (position) => {\n const { latitude, longitude, accuracy } = position.coords\n const city = props.reverseGeocode\n ? await props\n .reverseGeocode(latitude, longitude)\n .catch(() => undefined)\n : undefined\n emit('result', { latitude, longitude, accuracy, city })\n },\n (error) => {\n emit('result', { error: mapGeolocationError(error.code) })\n },\n { timeout: 15000 },\n )\n })\n</script>\n\n<template>\n <div\n class=\"flex items-center gap-6 text-12 text-word-3 border border-surface-3 rounded-xl px-sm py-10\">\n <!-- Loading state -->\n <template v-if=\"!isOutputAvailable\">\n <VvIcon name=\"line-md:loading-loop\" class=\"text-16\" />\n <span>{{ $t('messagePart.requestGeolocation') }}</span>\n </template>\n\n <!-- Success state -->\n <template v-else-if=\"successOutput\">\n <VvIcon name=\"ri:map-pin-line\" class=\"text-16\" />\n <span>\n {{\n $n(successOutput.latitude, {\n style: 'decimal',\n minimumFractionDigits: 5,\n maximumFractionDigits: 5,\n })\n }},\n {{\n $n(successOutput.longitude, {\n style: 'decimal',\n minimumFractionDigits: 5,\n maximumFractionDigits: 5,\n })\n }}\n <template v-if=\"successOutput.accuracy !== undefined\">\n (±{{\n $n(successOutput.accuracy, {\n style: 'unit',\n unit: 'meter',\n })\n }})\n </template>\n </span>\n </template>\n\n <!-- Error state -->\n <template v-else-if=\"errorOutput\">\n <span class=\"i-vv-alert-circle text-16 shrink-0 text-danger\" />\n <span>\n {{\n errorOutput.error === 'permission_denied'\n ? $t('message.geolocationPermissionDenied')\n : $t('message.geolocationUnavailable')\n }}\n </span>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, onMounted } from 'vue'\n import { useI18n } from 'vue-i18n'\n\n import type { ReverseGeocodeFn } from 'utils/src/device-context'\n\n type GeolocationOutput =\n | {\n latitude: number\n longitude: number\n accuracy?: number\n city?: string\n }\n | { error: 'permission_denied' | 'position_unavailable' | 'timeout' }\n\n const props = defineProps<{\n part: unknown\n reverseGeocode?: ReverseGeocodeFn\n }>()\n\n const emit = defineEmits<{\n result: [output: GeolocationOutput]\n }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const toolPart = computed(() => {\n return props.part as {\n state?: string\n input?: { reason?: string }\n output?: GeolocationOutput\n }\n })\n\n const state = computed(() => toolPart.value.state ?? 'unknown')\n\n const isOutputAvailable = computed(() => state.value === 'output-available')\n\n const successOutput = computed(() => {\n const out = toolPart.value.output\n if (!out || 'error' in out) {\n return undefined\n }\n return out\n })\n\n const errorOutput = computed(() => {\n const out = toolPart.value.output\n if (!out || !('error' in out)) {\n return undefined\n }\n return out\n })\n\n /** Maps GeolocationPositionError.code to a typed string */\n function mapGeolocationError(\n code: number,\n ): 'permission_denied' | 'position_unavailable' | 'timeout' {\n if (code === 1) {\n return 'permission_denied'\n }\n if (code === 3) {\n return 'timeout'\n }\n return 'position_unavailable'\n }\n\n onMounted(() => {\n if (state.value !== 'input-available') {\n return\n }\n\n if (!navigator.geolocation) {\n emit('result', { error: 'position_unavailable' })\n return\n }\n\n navigator.geolocation.getCurrentPosition(\n async (position) => {\n const { latitude, longitude, accuracy } = position.coords\n const city = props.reverseGeocode\n ? await props\n .reverseGeocode(latitude, longitude)\n .catch(() => undefined)\n : undefined\n emit('result', { latitude, longitude, accuracy, city })\n },\n (error) => {\n emit('result', { error: mapGeolocationError(error.code) })\n },\n { timeout: 15000 },\n )\n })\n</script>\n\n<template>\n <div\n class=\"flex items-center gap-6 text-12 text-word-3 border border-surface-3 rounded-xl px-sm py-10\">\n <!-- Loading state -->\n <template v-if=\"!isOutputAvailable\">\n <VvIcon name=\"line-md:loading-loop\" class=\"text-16\" />\n <span>{{ $t('messagePart.requestGeolocation') }}</span>\n </template>\n\n <!-- Success state -->\n <template v-else-if=\"successOutput\">\n <VvIcon name=\"ri:map-pin-line\" class=\"text-16\" />\n <span>\n {{\n $n(successOutput.latitude, {\n style: 'decimal',\n minimumFractionDigits: 5,\n maximumFractionDigits: 5,\n })\n }},\n {{\n $n(successOutput.longitude, {\n style: 'decimal',\n minimumFractionDigits: 5,\n maximumFractionDigits: 5,\n })\n }}\n <template v-if=\"successOutput.accuracy !== undefined\">\n (±{{\n $n(successOutput.accuracy, {\n style: 'unit',\n unit: 'meter',\n })\n }})\n </template>\n </span>\n </template>\n\n <!-- Error state -->\n <template v-else-if=\"errorOutput\">\n <span class=\"i-vv-alert-circle text-16 shrink-0 text-danger\" />\n <span>\n {{\n errorOutput.error === 'permission_denied'\n ? $t('message.geolocationPermissionDenied')\n : $t('message.geolocationUnavailable')\n }}\n </span>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, useTemplateRef } from 'vue'\n import { useDropZone } from '@vueuse/core'\n import { storeToRefs } from 'pinia'\n import PkChatbotMessages from './PkChatbotMessages.vue'\n import PkChatbotInput from './PkChatbotInput.vue'\n import PkToolShowMultipleChoice from './PkToolShowMultipleChoice.vue'\n import PkToolShowContactForm from './PkToolShowContactForm.vue'\n import PkToolShowSuggestedReply from './PkToolShowSuggestedReply.vue'\n import PkToolShowSources from './PkToolShowSources.vue'\n import PkToolRequestGeolocation from './PkToolRequestGeolocation.vue'\n import PkToolShowLocation from './PkToolShowLocation.vue'\n import { useLocalizedString } from '../composables/useLocalizedString'\n import { useChatbotStore } from 'composables'\n import type { UIChatMessage } from 'models'\n\n const props = defineProps<{ agentId: string }>()\n\n const emit = defineEmits<{\n 'show-info': [message: UIChatMessage]\n revise: [message: UIChatMessage]\n }>()\n\n const store = useChatbotStore(props.agentId)\n\n const {\n name,\n agentInterface,\n agentFileUpload,\n actions,\n revisedAnswers,\n messages,\n chat,\n messageFeedbacks,\n feedbackDialogMessage,\n isFeedbackSubmitting,\n isFeedbackSubmitted,\n feedbackSubmitError,\n isLeadSubmitted,\n isLoadingSubmitLead,\n submitLeadError,\n input,\n inputMessagePlaceholder,\n isConversationBlocked,\n baseUrl,\n pendingAttachments,\n apiClient,\n } = storeToRefs(store)\n\n const {\n handleSubmit: storeHandleSubmit,\n stopGeneration,\n regenerate,\n onUpvote,\n onDownvote,\n onFeedback,\n onFeedbackSubmit,\n onLeadSubmit,\n startNewChat,\n addToolOutput,\n handleFileSelect,\n } = store\n\n const dismissableNotice = useLocalizedString(\n () => agentInterface.value?.dismissableNotice,\n )\n\n const chatViewEl = useTemplateRef<HTMLDivElement>('chatViewEl')\n\n const handleExpandSourceContext = async (payload: {\n documentId: string\n chunkIndex: number\n }) => {\n const result = await apiClient.value.expandSourceContext(\n props.agentId,\n payload.documentId,\n payload.chunkIndex,\n )\n return result.content\n }\n\n const handleDownloadSource = async (documentId: string) => {\n const result = await apiClient.value.downloadSourceDocument(\n props.agentId,\n documentId,\n )\n window.open(result.downloadUrl, '_blank')\n }\n\n const handleFileDrop = (files: File[] | null) => {\n if (!agentFileUpload.value?.enabled || !files) {\n return\n }\n for (const file of files) {\n handleFileSelect(file)\n }\n }\n\n const { isOverDropZone } = useDropZone(chatViewEl, {\n dataTypes: computed(\n () => agentFileUpload.value?.allowedMimeTypes ?? [],\n ),\n onDrop: handleFileDrop,\n })\n</script>\n\n<template>\n <div\n ref=\"chatViewEl\"\n class=\"pk-chatbot-view-chat\"\n :class=\"{\n 'pk-chatbot-view-chat--dragover':\n isOverDropZone && agentFileUpload?.enabled,\n }\">\n <!-- #region messages -->\n <PkChatbotMessages\n class=\"flex flex-col flex-1 min-h-0 p-md overflow-y-auto\"\n :name=\"name\"\n :messages=\"messages\"\n :status=\"chat.status\"\n :error=\"chat.error\"\n :main-color=\"agentInterface?.mainColor\"\n :text-color=\"agentInterface?.textColor\"\n :revised-answers=\"revisedAnswers\"\n :actions=\"actions\"\n :logo=\"agentInterface?.logo\"\n :message-feedbacks=\"messageFeedbacks\"\n :feedback-message-id=\"feedbackDialogMessage?.id\"\n :feedback-loading=\"isFeedbackSubmitting\"\n :feedback-submitted=\"isFeedbackSubmitted\"\n :feedback-error=\"feedbackSubmitError\"\n @feedback-submit=\"onFeedbackSubmit($event)\"\n @feedback-close=\"feedbackDialogMessage = undefined\"\n @regenerate=\"regenerate\"\n @auto-retry=\"regenerate\"\n @reset-chat=\"startNewChat\"\n @show-info=\"emit('show-info', $event)\"\n @revise=\"emit('revise', $event)\"\n @upvote=\"onUpvote\"\n @downvote=\"onDownvote\"\n @feedback=\"onFeedback\">\n <template #tool-showContactForm=\"{ part }\">\n <PkToolShowContactForm\n :part\n :readonly=\"!baseUrl\"\n :submitted=\"isLeadSubmitted\"\n :loading=\"isLoadingSubmitLead\"\n :error=\"submitLeadError\"\n :privacy-policy-notice=\"agentInterface?.privacyPolicyNotice\"\n @submit=\"onLeadSubmit\" />\n </template>\n <template #tool-showSuggestedReply=\"{ part }\">\n <PkToolShowSuggestedReply\n :part\n @select=\"\n ($event) => {\n input = $event\n storeHandleSubmit()\n }\n \" />\n </template>\n <template #tool-showSources=\"{ part }\">\n <PkToolShowSources\n :part\n :on-expand-context=\"handleExpandSourceContext\"\n :on-download=\"handleDownloadSource\" />\n </template>\n <template #tool-showMultipleChoice=\"{ part }\">\n <transition mode=\"out-in\">\n <PkToolShowMultipleChoice\n :part\n @select=\"\n addToolOutput({\n tool: 'showMultipleChoice',\n toolCallId: (part as any).toolCallId,\n output: $event,\n })\n \" />\n </transition>\n </template>\n <template #tool-requestGeolocation=\"{ part }\">\n <PkToolRequestGeolocation\n :part\n :reverse-geocode=\"\n (lat: number, lon: number) =>\n apiClient.reverseGeocode(lat, lon)\n \"\n @result=\"\n addToolOutput({\n tool: 'requestGeolocation',\n toolCallId: (part as any).toolCallId,\n output: $event,\n })\n \" />\n </template>\n <template #tool-showLocation=\"{ part }\">\n <PkToolShowLocation\n :part\n :forward-geocode=\"\n (query: string, lang?: string) =>\n apiClient.forwardGeocode(query, lang)\n \" />\n </template>\n </PkChatbotMessages>\n <!-- #endregion -->\n\n <!-- #region input -->\n <div\n v-if=\"isConversationBlocked\"\n class=\"p-md border-t border-surface-3 text-center text-12 text-danger-darken-2 bg-surface-danger\">\n {{ $t('message.chatErrorConversationBlocked') }}\n </div>\n <PkChatbotInput\n v-else\n v-model=\"input\"\n v-model:pending-attachments=\"pendingAttachments\"\n :placeholder=\"inputMessagePlaceholder\"\n :dismissable-notice=\"\n dismissableNotice && chat.messages.length <= 1\n ? dismissableNotice\n : undefined\n \"\n :status=\"chat.status\"\n :max-message-length=\"agentInterface?.maxMessageLength\"\n :file-upload=\"agentFileUpload\"\n @stop-generation=\"stopGeneration\"\n @submit=\"storeHandleSubmit\"\n @file-select=\"handleFileSelect\" />\n <!-- #endregion -->\n <Transition>\n <div\n v-if=\"isOverDropZone && agentFileUpload?.enabled\"\n class=\"pk-chatbot-view-chat__drop-overlay\">\n <VvIcon\n name=\"ri:upload-cloud-2-line\"\n class=\"pk-chatbot-view-chat__drop-overlay-icon\" />\n <span>{{ $t('action.dropFile') }}</span>\n </div>\n </Transition>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-view-chat {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n\n &__drop-overlay {\n position: absolute;\n inset: var(--spacing-sm) var(--spacing-sm) var(--spacing-sm)\n var(--spacing-sm);\n z-index: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-xs);\n background-color: color-mix(\n in srgb,\n var(--color-surface) 85%,\n transparent\n );\n border-radius: var(--rounded-xl);\n border: var(--spacing-2) dashed var(--color-surface-5);\n pointer-events: none;\n color: var(--color-word-3);\n\n &-icon {\n font-size: var(--spacing-32);\n }\n }\n }\n</style>\n","<script setup lang=\"ts\">\n import { computed, useTemplateRef } from 'vue'\n import { useDropZone } from '@vueuse/core'\n import { storeToRefs } from 'pinia'\n import PkChatbotMessages from './PkChatbotMessages.vue'\n import PkChatbotInput from './PkChatbotInput.vue'\n import PkToolShowMultipleChoice from './PkToolShowMultipleChoice.vue'\n import PkToolShowContactForm from './PkToolShowContactForm.vue'\n import PkToolShowSuggestedReply from './PkToolShowSuggestedReply.vue'\n import PkToolShowSources from './PkToolShowSources.vue'\n import PkToolRequestGeolocation from './PkToolRequestGeolocation.vue'\n import PkToolShowLocation from './PkToolShowLocation.vue'\n import { useLocalizedString } from '../composables/useLocalizedString'\n import { useChatbotStore } from 'composables'\n import type { UIChatMessage } from 'models'\n\n const props = defineProps<{ agentId: string }>()\n\n const emit = defineEmits<{\n 'show-info': [message: UIChatMessage]\n revise: [message: UIChatMessage]\n }>()\n\n const store = useChatbotStore(props.agentId)\n\n const {\n name,\n agentInterface,\n agentFileUpload,\n actions,\n revisedAnswers,\n messages,\n chat,\n messageFeedbacks,\n feedbackDialogMessage,\n isFeedbackSubmitting,\n isFeedbackSubmitted,\n feedbackSubmitError,\n isLeadSubmitted,\n isLoadingSubmitLead,\n submitLeadError,\n input,\n inputMessagePlaceholder,\n isConversationBlocked,\n baseUrl,\n pendingAttachments,\n apiClient,\n } = storeToRefs(store)\n\n const {\n handleSubmit: storeHandleSubmit,\n stopGeneration,\n regenerate,\n onUpvote,\n onDownvote,\n onFeedback,\n onFeedbackSubmit,\n onLeadSubmit,\n startNewChat,\n addToolOutput,\n handleFileSelect,\n } = store\n\n const dismissableNotice = useLocalizedString(\n () => agentInterface.value?.dismissableNotice,\n )\n\n const chatViewEl = useTemplateRef<HTMLDivElement>('chatViewEl')\n\n const handleExpandSourceContext = async (payload: {\n documentId: string\n chunkIndex: number\n }) => {\n const result = await apiClient.value.expandSourceContext(\n props.agentId,\n payload.documentId,\n payload.chunkIndex,\n )\n return result.content\n }\n\n const handleDownloadSource = async (documentId: string) => {\n const result = await apiClient.value.downloadSourceDocument(\n props.agentId,\n documentId,\n )\n window.open(result.downloadUrl, '_blank')\n }\n\n const handleFileDrop = (files: File[] | null) => {\n if (!agentFileUpload.value?.enabled || !files) {\n return\n }\n for (const file of files) {\n handleFileSelect(file)\n }\n }\n\n const { isOverDropZone } = useDropZone(chatViewEl, {\n dataTypes: computed(\n () => agentFileUpload.value?.allowedMimeTypes ?? [],\n ),\n onDrop: handleFileDrop,\n })\n</script>\n\n<template>\n <div\n ref=\"chatViewEl\"\n class=\"pk-chatbot-view-chat\"\n :class=\"{\n 'pk-chatbot-view-chat--dragover':\n isOverDropZone && agentFileUpload?.enabled,\n }\">\n <!-- #region messages -->\n <PkChatbotMessages\n class=\"flex flex-col flex-1 min-h-0 p-md overflow-y-auto\"\n :name=\"name\"\n :messages=\"messages\"\n :status=\"chat.status\"\n :error=\"chat.error\"\n :main-color=\"agentInterface?.mainColor\"\n :text-color=\"agentInterface?.textColor\"\n :revised-answers=\"revisedAnswers\"\n :actions=\"actions\"\n :logo=\"agentInterface?.logo\"\n :message-feedbacks=\"messageFeedbacks\"\n :feedback-message-id=\"feedbackDialogMessage?.id\"\n :feedback-loading=\"isFeedbackSubmitting\"\n :feedback-submitted=\"isFeedbackSubmitted\"\n :feedback-error=\"feedbackSubmitError\"\n @feedback-submit=\"onFeedbackSubmit($event)\"\n @feedback-close=\"feedbackDialogMessage = undefined\"\n @regenerate=\"regenerate\"\n @auto-retry=\"regenerate\"\n @reset-chat=\"startNewChat\"\n @show-info=\"emit('show-info', $event)\"\n @revise=\"emit('revise', $event)\"\n @upvote=\"onUpvote\"\n @downvote=\"onDownvote\"\n @feedback=\"onFeedback\">\n <template #tool-showContactForm=\"{ part }\">\n <PkToolShowContactForm\n :part\n :readonly=\"!baseUrl\"\n :submitted=\"isLeadSubmitted\"\n :loading=\"isLoadingSubmitLead\"\n :error=\"submitLeadError\"\n :privacy-policy-notice=\"agentInterface?.privacyPolicyNotice\"\n @submit=\"onLeadSubmit\" />\n </template>\n <template #tool-showSuggestedReply=\"{ part }\">\n <PkToolShowSuggestedReply\n :part\n @select=\"\n ($event) => {\n input = $event\n storeHandleSubmit()\n }\n \" />\n </template>\n <template #tool-showSources=\"{ part }\">\n <PkToolShowSources\n :part\n :on-expand-context=\"handleExpandSourceContext\"\n :on-download=\"handleDownloadSource\" />\n </template>\n <template #tool-showMultipleChoice=\"{ part }\">\n <transition mode=\"out-in\">\n <PkToolShowMultipleChoice\n :part\n @select=\"\n addToolOutput({\n tool: 'showMultipleChoice',\n toolCallId: (part as any).toolCallId,\n output: $event,\n })\n \" />\n </transition>\n </template>\n <template #tool-requestGeolocation=\"{ part }\">\n <PkToolRequestGeolocation\n :part\n :reverse-geocode=\"\n (lat: number, lon: number) =>\n apiClient.reverseGeocode(lat, lon)\n \"\n @result=\"\n addToolOutput({\n tool: 'requestGeolocation',\n toolCallId: (part as any).toolCallId,\n output: $event,\n })\n \" />\n </template>\n <template #tool-showLocation=\"{ part }\">\n <PkToolShowLocation\n :part\n :forward-geocode=\"\n (query: string, lang?: string) =>\n apiClient.forwardGeocode(query, lang)\n \" />\n </template>\n </PkChatbotMessages>\n <!-- #endregion -->\n\n <!-- #region input -->\n <div\n v-if=\"isConversationBlocked\"\n class=\"p-md border-t border-surface-3 text-center text-12 text-danger-darken-2 bg-surface-danger\">\n {{ $t('message.chatErrorConversationBlocked') }}\n </div>\n <PkChatbotInput\n v-else\n v-model=\"input\"\n v-model:pending-attachments=\"pendingAttachments\"\n :placeholder=\"inputMessagePlaceholder\"\n :dismissable-notice=\"\n dismissableNotice && chat.messages.length <= 1\n ? dismissableNotice\n : undefined\n \"\n :status=\"chat.status\"\n :max-message-length=\"agentInterface?.maxMessageLength\"\n :file-upload=\"agentFileUpload\"\n @stop-generation=\"stopGeneration\"\n @submit=\"storeHandleSubmit\"\n @file-select=\"handleFileSelect\" />\n <!-- #endregion -->\n <Transition>\n <div\n v-if=\"isOverDropZone && agentFileUpload?.enabled\"\n class=\"pk-chatbot-view-chat__drop-overlay\">\n <VvIcon\n name=\"ri:upload-cloud-2-line\"\n class=\"pk-chatbot-view-chat__drop-overlay-icon\" />\n <span>{{ $t('action.dropFile') }}</span>\n </div>\n </Transition>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-view-chat {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n\n &__drop-overlay {\n position: absolute;\n inset: var(--spacing-sm) var(--spacing-sm) var(--spacing-sm)\n var(--spacing-sm);\n z-index: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-xs);\n background-color: color-mix(\n in srgb,\n var(--color-surface) 85%,\n transparent\n );\n border-radius: var(--rounded-xl);\n border: var(--spacing-2) dashed var(--color-surface-5);\n pointer-events: none;\n color: var(--color-word-3);\n\n &-icon {\n font-size: var(--spacing-32);\n }\n }\n }\n</style>\n"],"mappings":"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"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { m as e, s as t } from "./src-EtGd6cRz.js";
|
|
2
|
+
import { t as n } from "./useChatbotStore-DGL81KJa.js";
|
|
3
|
+
import { t as r } from "./PkRelativeTime-WZ2aPcp_.js";
|
|
4
|
+
import { Fragment as i, createCommentVNode as a, createElementBlock as o, createElementVNode as s, createTextVNode as c, createVNode as l, defineComponent as u, h as d, mergeProps as f, nextTick as p, normalizeClass as m, openBlock as h, ref as g, renderList as _, toDisplayString as v, unref as y, vModelText as ee, withCtx as b, withDirectives as te, withKeys as x, withModifiers as S } from "vue";
|
|
5
|
+
import { VvButton as C, VvButtonGroup as w, VvDialog as T, VvDropdown as E, VvDropdownAction as D, VvIcon as O, VvInputText as k } from "@volverjs/ui-vue/components";
|
|
6
|
+
import { useI18n as A } from "vue-i18n";
|
|
7
|
+
import { storeToRefs as j } from "pinia";
|
|
8
|
+
//#region ../../packages/composable/src/useDialog.ts
|
|
9
|
+
var M = g(!1), N = g(), P = g(), F = g(), I = g(!1), L = g(), R = g(), z = () => {
|
|
10
|
+
let e = (e) => {
|
|
11
|
+
M.value = e;
|
|
12
|
+
}, t = () => {
|
|
13
|
+
N.value = void 0, P.value = void 0, F.value = void 0, I.value = void 0, L.value = void 0, R.value = void 0;
|
|
14
|
+
};
|
|
15
|
+
return {
|
|
16
|
+
PkGlobalDialog: u({
|
|
17
|
+
name: "PkGlobalDialog",
|
|
18
|
+
render: () => d(T, {
|
|
19
|
+
modelValue: M.value,
|
|
20
|
+
title: N.value,
|
|
21
|
+
transition: P.value,
|
|
22
|
+
size: F.value,
|
|
23
|
+
keepOpen: I.value,
|
|
24
|
+
role: L.value,
|
|
25
|
+
"onUpdate:modelValue": e,
|
|
26
|
+
onAfterLeave: t
|
|
27
|
+
}, R.value)
|
|
28
|
+
}),
|
|
29
|
+
openDialog: (e, t) => (N.value = e?.title, P.value = e?.transition, F.value = e?.size, I.value = e?.keepOpen ?? !1, L.value = e?.role, R.value = t, p(() => {
|
|
30
|
+
M.value = !0;
|
|
31
|
+
}), M),
|
|
32
|
+
isOpen: M
|
|
33
|
+
};
|
|
34
|
+
}, B = () => {
|
|
35
|
+
let { openDialog: e } = z(), { t } = A({ useScope: "global" });
|
|
36
|
+
return { openDialogConfirm: ({ emitReject: n = !1, confirmLabel: r, cancelLabel: i, questionLabel: a, onlyConfirm: o = !1, passphrase: s, passphraseLabel: c, passphraseHint: l } = {}) => new Promise((u, f) => {
|
|
37
|
+
let p = g(), m = e({
|
|
38
|
+
role: "alertdialog",
|
|
39
|
+
size: "small",
|
|
40
|
+
keepOpen: !0
|
|
41
|
+
}, {
|
|
42
|
+
default: () => d("div", [d("div", { class: "mb-sm" }, a ?? t("message.confirm")), s ? d(k, {
|
|
43
|
+
modelValue: p.value,
|
|
44
|
+
"onUpdate:modelValue": (e) => {
|
|
45
|
+
p.value = e;
|
|
46
|
+
},
|
|
47
|
+
type: "text",
|
|
48
|
+
name: "passphrase",
|
|
49
|
+
class: "mb-0",
|
|
50
|
+
floating: !0,
|
|
51
|
+
label: c ?? t("label.passphrase"),
|
|
52
|
+
hintLabel: l ?? t("hint.passphrase", { passphrase: s })
|
|
53
|
+
}) : void 0]),
|
|
54
|
+
footer: () => d(w, () => {
|
|
55
|
+
let e = [];
|
|
56
|
+
return o || e.push(d(C, {
|
|
57
|
+
label: i ?? t("action.cancel"),
|
|
58
|
+
modifiers: "ghost",
|
|
59
|
+
onClick: () => {
|
|
60
|
+
n && f(), u(!1), m.value = !1;
|
|
61
|
+
}
|
|
62
|
+
})), e.push(d(C, {
|
|
63
|
+
label: r ?? t("action.proceed"),
|
|
64
|
+
disabled: s ? s !== p.value : !1,
|
|
65
|
+
onClick: () => {
|
|
66
|
+
u(!0), m.value = !1;
|
|
67
|
+
}
|
|
68
|
+
})), e;
|
|
69
|
+
})
|
|
70
|
+
});
|
|
71
|
+
}) };
|
|
72
|
+
}, V = { class: "flex flex-col flex-1 min-h-0 overflow-y-auto p-md gap-sm relative" }, H = {
|
|
73
|
+
key: 0,
|
|
74
|
+
class: "flex justify-center p-lg text-word-3 text-sm"
|
|
75
|
+
}, U = {
|
|
76
|
+
key: 1,
|
|
77
|
+
class: "flex flex-col min-h-0 gap-8 overflow-auto px-8 pb-8 light-scrollbar pb-64"
|
|
78
|
+
}, W = ["onClick"], G = { class: "flex items-center gap-8" }, K = ["placeholder", "onKeydown"], q = { class: "font-bold truncate block flex-1" }, J = {
|
|
79
|
+
key: 0,
|
|
80
|
+
class: "text-12 text-word-4 line-clamp-2"
|
|
81
|
+
}, Y = { class: "absolute bottom-0 left-0 right-0 flex justify-center px-16 pb-16 pt-32 bg-gradient-to-t" }, X = /* @__PURE__ */ u({
|
|
82
|
+
__name: "PkChatbotViewConversations",
|
|
83
|
+
props: { agentId: {} },
|
|
84
|
+
setup(u) {
|
|
85
|
+
let d = u, { t: w } = A({ useScope: "global" }), T = n(d.agentId), { conversations: k, localChatId: M } = j(T), { navigate: N, startNewChat: P, renameChatTitle: F, deleteChat: I } = T, L = g(null), R = g(""), z = g(), X = (e) => {
|
|
86
|
+
L.value || (M.value = e, N("chat"));
|
|
87
|
+
}, Z = (e) => M.value === e.id, Q = (n, r) => e(t(n.filter((e) => e.role === r).slice(-1)[0]) || ""), ne = (t) => {
|
|
88
|
+
L.value = t.id, R.value = e(t.title) || Q(t.messages, "assistant") || "", p(() => {
|
|
89
|
+
z.value?.[0] && (z.value?.[0]?.focus(), z.value?.[0]?.select());
|
|
90
|
+
});
|
|
91
|
+
}, $ = async (e) => {
|
|
92
|
+
let t = R.value.trim();
|
|
93
|
+
if (L.value = null, t && t.length <= 255) try {
|
|
94
|
+
await F(e, t);
|
|
95
|
+
} catch {}
|
|
96
|
+
}, re = () => {
|
|
97
|
+
L.value = null;
|
|
98
|
+
}, { openDialogConfirm: ie } = B(), ae = async (e) => {
|
|
99
|
+
try {
|
|
100
|
+
if (!await ie()) return;
|
|
101
|
+
await I(e);
|
|
102
|
+
} catch {}
|
|
103
|
+
};
|
|
104
|
+
return (t, n) => {
|
|
105
|
+
let u = C, d = O, p = D, g = E;
|
|
106
|
+
return h(), o("div", V, [y(k).length === 0 ? (h(), o("div", H, v(y(w)("message.noConversations")), 1)) : (h(), o("ul", U, [(h(!0), o(i, null, _(y(k), (t) => (h(), o("li", { key: t.id }, [s("button", {
|
|
107
|
+
type: "button",
|
|
108
|
+
class: m(["rounded-md border p-10 cursor-pointer block w-full transition-colors text-14 leading-relaxed border-b border-surface-3 hover:border-surface-5 hover:bg-surface-1 focus-within:border-word", { "bg-surface-2 border-surface-5": Z(t) }]),
|
|
109
|
+
onClick: (e) => X(t.id)
|
|
110
|
+
}, [s("div", G, [L.value === t.id ? (h(), o(i, { key: 0 }, [te(s("input", {
|
|
111
|
+
ref_for: !0,
|
|
112
|
+
ref_key: "renameInputEl",
|
|
113
|
+
ref: z,
|
|
114
|
+
"onUpdate:modelValue": n[0] ||= (e) => R.value = e,
|
|
115
|
+
class: "flex-1 placeholder:text-word-4 leading-none",
|
|
116
|
+
placeholder: y(w)("placeholder.insert"),
|
|
117
|
+
maxlength: 255,
|
|
118
|
+
onClick: n[1] ||= S(() => {}, ["stop"]),
|
|
119
|
+
onKeydown: [x(S((e) => $(t.id), ["prevent"]), ["enter"]), n[2] ||= x(S((e) => re(), ["prevent"]), ["esc"])]
|
|
120
|
+
}, null, 40, K), [[ee, R.value]]), l(u, {
|
|
121
|
+
icon: "ri:save-line",
|
|
122
|
+
label: y(w)("action.save"),
|
|
123
|
+
modifiers: "action-small",
|
|
124
|
+
onClick: S((e) => $(t.id), ["stop"])
|
|
125
|
+
}, null, 8, ["label", "onClick"])], 64)) : (h(), o(i, { key: 1 }, [
|
|
126
|
+
s("strong", q, v(y(e)(t.title) || Q(t.messages, "assistant")), 1),
|
|
127
|
+
l(r, {
|
|
128
|
+
class: "text-word-4 text-smaller shrink-0",
|
|
129
|
+
date: t.lastMessageAt
|
|
130
|
+
}, null, 8, ["date"]),
|
|
131
|
+
s("div", { onClick: n[3] ||= S(() => {}, ["stop"]) }, [l(g, f({ ref_for: !0 }, {
|
|
132
|
+
placement: "bottom-end",
|
|
133
|
+
modifiers: "menu",
|
|
134
|
+
flip: !0,
|
|
135
|
+
offset: 3
|
|
136
|
+
}), {
|
|
137
|
+
items: b(() => [l(p, { onClick: (e) => ne(t) }, {
|
|
138
|
+
default: b(() => [l(d, { name: "ri:pencil-line" }), c(" " + v(y(w)("action.renameChat")), 1)]),
|
|
139
|
+
_: 1
|
|
140
|
+
}, 8, ["onClick"]), l(p, { onClick: (e) => ae(t.id) }, {
|
|
141
|
+
default: b(() => [l(d, { name: "ri:delete-bin-line" }), c(" " + v(y(w)("action.delete")), 1)]),
|
|
142
|
+
_: 1
|
|
143
|
+
}, 8, ["onClick"])]),
|
|
144
|
+
default: b(() => [l(u, {
|
|
145
|
+
icon: "ri:more-2-fill",
|
|
146
|
+
title: y(w)("action.moreActions"),
|
|
147
|
+
modifiers: "action-quiet-small"
|
|
148
|
+
}, null, 8, ["title"])]),
|
|
149
|
+
_: 2
|
|
150
|
+
}, 1040)])
|
|
151
|
+
], 64))]), L.value === t.id ? a("", !0) : (h(), o("span", J, v(y(e)(t.summary) || Q(t.messages, "user")), 1))], 10, W)]))), 128))])), s("div", Y, [l(u, {
|
|
152
|
+
class: "text-14",
|
|
153
|
+
modifiers: "rounded",
|
|
154
|
+
label: y(w)("action.startNewChat"),
|
|
155
|
+
onClick: n[4] ||= S((e) => y(P)(), ["stop"])
|
|
156
|
+
}, null, 8, ["label"])])]);
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
//#endregion
|
|
161
|
+
export { B as n, X as t };
|
|
162
|
+
|
|
163
|
+
//# sourceMappingURL=PkChatbotViewConversations-DvVc1arX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PkChatbotViewConversations-DvVc1arX.js","names":[],"sources":["../../../../packages/composable/src/useDialog.ts","../../../../packages/composable/src/useDialogConfirm.ts","../../../../packages/components/src/chat/PkChatbotViewConversations.vue","../../../../packages/components/src/chat/PkChatbotViewConversations.vue"],"sourcesContent":["import { VvDialog } from '@volverjs/ui-vue/components'\nimport { defineComponent, h, nextTick, ref, type VNode } from 'vue'\n\ntype DialogProps = {\n title?: string\n transition?: string\n size?: 'small' | 'standard' | 'fullscreen'\n role?: 'alert' | 'alertdialog'\n keepOpen?: boolean\n}\n\ntype DialogSlots = {\n footer?: () => VNode | string\n header?: () => VNode | string\n default?: () => VNode | string | VNode[] | string[]\n}\n\nconst isOpen = ref(false)\nconst title = ref<DialogProps['title']>()\nconst transition = ref<DialogProps['transition']>()\nconst size = ref<DialogProps['size']>()\nconst keepOpen = ref<DialogProps['keepOpen']>(false)\nconst role = ref<DialogProps['role']>()\nconst slots = ref<DialogSlots>()\n\nexport const useDialog = () => {\n const onUpdateModelValue = (value: boolean) => {\n isOpen.value = value\n }\n\n const onAfterLeave = () => {\n title.value = undefined\n transition.value = undefined\n size.value = undefined\n keepOpen.value = undefined\n role.value = undefined\n slots.value = undefined\n }\n\n const PkGlobalDialog = defineComponent({\n name: 'PkGlobalDialog',\n render: () =>\n h(\n VvDialog,\n {\n modelValue: isOpen.value,\n title: title.value,\n transition: transition.value,\n size: size.value,\n keepOpen: keepOpen.value,\n role: role.value,\n 'onUpdate:modelValue': onUpdateModelValue,\n onAfterLeave: onAfterLeave,\n },\n slots.value,\n ),\n })\n\n const openDialog = (newProps: DialogProps, newSlots?: DialogSlots) => {\n title.value = newProps?.title\n transition.value = newProps?.transition\n size.value = newProps?.size\n keepOpen.value = newProps?.keepOpen ?? false\n role.value = newProps?.role\n slots.value = newSlots\n nextTick(() => {\n isOpen.value = true\n })\n return isOpen\n }\n\n return { PkGlobalDialog, openDialog, isOpen }\n}\n","import { h, ref, VNode } from 'vue'\nimport { useI18n } from 'vue-i18n'\nimport {\n VvButton,\n VvButtonGroup,\n VvInputText,\n} from '@volverjs/ui-vue/components'\nimport { useDialog } from './useDialog'\n\nexport const useDialogConfirm = () => {\n const { openDialog } = useDialog()\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const openDialogConfirm = ({\n emitReject = false,\n confirmLabel,\n cancelLabel,\n questionLabel,\n onlyConfirm = false,\n passphrase,\n passphraseLabel,\n passphraseHint,\n }: {\n emitReject?: boolean\n confirmLabel?: string\n cancelLabel?: string\n questionLabel?: string\n onlyConfirm?: boolean\n passphrase?: string\n passphraseLabel?: string\n passphraseHint?: string\n } = {}) => {\n return new Promise<boolean>((resolve, reject) => {\n const passphraseText = ref<string>()\n const isOpen = openDialog(\n {\n role: 'alertdialog',\n size: 'small',\n keepOpen: true,\n },\n {\n default: () =>\n h('div', [\n h(\n 'div',\n { class: 'mb-sm' },\n questionLabel ?? $t('message.confirm'),\n ),\n passphrase\n ? h(VvInputText, {\n modelValue: passphraseText.value,\n 'onUpdate:modelValue': (\n value: string,\n ) => {\n passphraseText.value = value\n },\n type: 'text',\n name: 'passphrase',\n class: 'mb-0',\n floating: true,\n label:\n passphraseLabel ??\n $t('label.passphrase'),\n hintLabel:\n passphraseHint ??\n $t('hint.passphrase', { passphrase }),\n })\n : undefined,\n ]),\n footer: () =>\n h(VvButtonGroup, () => {\n const toReturn: VNode[] = []\n if (!onlyConfirm) {\n toReturn.push(\n h(VvButton, {\n label:\n cancelLabel ?? $t('action.cancel'),\n modifiers: 'ghost',\n onClick: () => {\n if (emitReject) {\n reject()\n }\n resolve(false)\n isOpen.value = false\n },\n }),\n )\n }\n toReturn.push(\n h(VvButton, {\n label: confirmLabel ?? $t('action.proceed'),\n disabled: passphrase\n ? passphrase !== passphraseText.value\n : false,\n onClick: () => {\n resolve(true)\n isOpen.value = false\n },\n }),\n )\n return toReturn\n }),\n },\n )\n })\n }\n\n return { openDialogConfirm }\n}\n","<script setup lang=\"ts\">\n import { ref, nextTick } from 'vue'\n import { storeToRefs } from 'pinia'\n import { useI18n } from 'vue-i18n'\n import type { Chat as Conversation, UIChatMessage } from 'models'\n import { stripMarkdown, getTextPart } from 'utils'\n import { useChatbotStore, useDialogConfirm } from 'composables'\n import PkRelativeTime from '../PkRelativeTime.vue'\n\n const props = defineProps<{ agentId: string }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const store = useChatbotStore(props.agentId)\n const { conversations, localChatId } = storeToRefs(store)\n const { navigate, startNewChat, renameChatTitle, deleteChat } = store\n\n const editingId = ref<string | null>(null)\n const editingTitle = ref('')\n const renameInputEl = ref<HTMLInputElement[]>()\n\n const openConversation = (id: string) => {\n if (editingId.value) {\n return\n }\n localChatId.value = id\n navigate('chat')\n }\n\n const isCurrentConversation = (conversation: Conversation) => {\n return localChatId.value === conversation.id\n }\n\n const getLastMessage = (\n messages: UIChatMessage[],\n role: 'user' | 'assistant',\n ) => {\n return stripMarkdown(\n getTextPart(messages.filter((m) => m.role === role).slice(-1)[0]) ||\n '',\n )\n }\n\n const startEdit = (conversation: Conversation) => {\n editingId.value = conversation.id\n editingTitle.value =\n stripMarkdown(conversation.title) ||\n getLastMessage(conversation.messages, 'assistant') ||\n ''\n nextTick(() => {\n if (renameInputEl.value?.[0]) {\n renameInputEl.value?.[0]?.focus()\n renameInputEl.value?.[0]?.select()\n }\n })\n }\n\n const confirmEdit = async (id: string) => {\n const trimmed = editingTitle.value.trim()\n editingId.value = null\n if (trimmed && trimmed.length <= 255) {\n try {\n await renameChatTitle(id, trimmed)\n } catch {\n // Revert optimistically: reload will pick up server state\n }\n }\n }\n\n const cancelEdit = () => {\n editingId.value = null\n }\n\n const { openDialogConfirm } = useDialogConfirm()\n const handleDelete = async (id: string) => {\n try {\n const proceed = await openDialogConfirm()\n if (!proceed) {\n return\n }\n await deleteChat(id)\n } catch {\n // Silently fail: next load will reconcile\n }\n }\n</script>\n\n<template>\n <div\n class=\"flex flex-col flex-1 min-h-0 overflow-y-auto p-md gap-sm relative\">\n <div\n v-if=\"conversations.length === 0\"\n class=\"flex justify-center p-lg text-word-3 text-sm\">\n {{ $t('message.noConversations') }}\n </div>\n <ul\n v-else\n class=\"flex flex-col min-h-0 gap-8 overflow-auto px-8 pb-8 light-scrollbar pb-64\">\n <li v-for=\"conversation in conversations\" :key=\"conversation.id\">\n <button\n type=\"button\"\n class=\"rounded-md border p-10 cursor-pointer block w-full transition-colors text-14 leading-relaxed border-b border-surface-3 hover:border-surface-5 hover:bg-surface-1 focus-within:border-word\"\n :class=\"{\n 'bg-surface-2 border-surface-5':\n isCurrentConversation(conversation),\n }\"\n @click=\"openConversation(conversation.id)\">\n <div class=\"flex items-center gap-8\">\n <template v-if=\"editingId === conversation.id\">\n <input\n ref=\"renameInputEl\"\n v-model=\"editingTitle\"\n class=\"flex-1 placeholder:text-word-4 leading-none\"\n :placeholder=\"$t('placeholder.insert')\"\n :maxlength=\"255\"\n @click.stop\n @keydown.enter.prevent=\"\n confirmEdit(conversation.id)\n \"\n @keydown.esc.prevent=\"cancelEdit()\" />\n <VvButton\n icon=\"ri:save-line\"\n :label=\"$t('action.save')\"\n modifiers=\"action-small\"\n @click.stop=\"confirmEdit(conversation.id)\" />\n </template>\n <template v-else>\n <strong class=\"font-bold truncate block flex-1\">\n {{\n stripMarkdown(conversation.title) ||\n getLastMessage(\n conversation.messages,\n 'assistant',\n )\n }}\n </strong>\n <PkRelativeTime\n class=\"text-word-4 text-smaller shrink-0\"\n :date=\"conversation.lastMessageAt\" />\n <div @click.stop>\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n }\">\n <VvButton\n icon=\"ri:more-2-fill\"\n :title=\"$t('action.moreActions')\"\n modifiers=\"action-quiet-small\" />\n <template #items>\n <VvDropdownAction\n @click=\"startEdit(conversation)\">\n <VvIcon name=\"ri:pencil-line\" />\n {{ $t('action.renameChat') }}\n </VvDropdownAction>\n <VvDropdownAction\n @click=\"\n handleDelete(conversation.id)\n \">\n <VvIcon name=\"ri:delete-bin-line\" />\n {{ $t('action.delete') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </div>\n </template>\n </div>\n <span\n v-if=\"editingId !== conversation.id\"\n class=\"text-12 text-word-4 line-clamp-2\">\n {{\n stripMarkdown(conversation.summary) ||\n getLastMessage(conversation.messages, 'user')\n }}\n </span>\n </button>\n </li>\n </ul>\n <div\n class=\"absolute bottom-0 left-0 right-0 flex justify-center px-16 pb-16 pt-32 bg-gradient-to-t\">\n <VvButton\n class=\"text-14\"\n modifiers=\"rounded\"\n :label=\"$t('action.startNewChat')\"\n @click.stop=\"startNewChat()\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { ref, nextTick } from 'vue'\n import { storeToRefs } from 'pinia'\n import { useI18n } from 'vue-i18n'\n import type { Chat as Conversation, UIChatMessage } from 'models'\n import { stripMarkdown, getTextPart } from 'utils'\n import { useChatbotStore, useDialogConfirm } from 'composables'\n import PkRelativeTime from '../PkRelativeTime.vue'\n\n const props = defineProps<{ agentId: string }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const store = useChatbotStore(props.agentId)\n const { conversations, localChatId } = storeToRefs(store)\n const { navigate, startNewChat, renameChatTitle, deleteChat } = store\n\n const editingId = ref<string | null>(null)\n const editingTitle = ref('')\n const renameInputEl = ref<HTMLInputElement[]>()\n\n const openConversation = (id: string) => {\n if (editingId.value) {\n return\n }\n localChatId.value = id\n navigate('chat')\n }\n\n const isCurrentConversation = (conversation: Conversation) => {\n return localChatId.value === conversation.id\n }\n\n const getLastMessage = (\n messages: UIChatMessage[],\n role: 'user' | 'assistant',\n ) => {\n return stripMarkdown(\n getTextPart(messages.filter((m) => m.role === role).slice(-1)[0]) ||\n '',\n )\n }\n\n const startEdit = (conversation: Conversation) => {\n editingId.value = conversation.id\n editingTitle.value =\n stripMarkdown(conversation.title) ||\n getLastMessage(conversation.messages, 'assistant') ||\n ''\n nextTick(() => {\n if (renameInputEl.value?.[0]) {\n renameInputEl.value?.[0]?.focus()\n renameInputEl.value?.[0]?.select()\n }\n })\n }\n\n const confirmEdit = async (id: string) => {\n const trimmed = editingTitle.value.trim()\n editingId.value = null\n if (trimmed && trimmed.length <= 255) {\n try {\n await renameChatTitle(id, trimmed)\n } catch {\n // Revert optimistically: reload will pick up server state\n }\n }\n }\n\n const cancelEdit = () => {\n editingId.value = null\n }\n\n const { openDialogConfirm } = useDialogConfirm()\n const handleDelete = async (id: string) => {\n try {\n const proceed = await openDialogConfirm()\n if (!proceed) {\n return\n }\n await deleteChat(id)\n } catch {\n // Silently fail: next load will reconcile\n }\n }\n</script>\n\n<template>\n <div\n class=\"flex flex-col flex-1 min-h-0 overflow-y-auto p-md gap-sm relative\">\n <div\n v-if=\"conversations.length === 0\"\n class=\"flex justify-center p-lg text-word-3 text-sm\">\n {{ $t('message.noConversations') }}\n </div>\n <ul\n v-else\n class=\"flex flex-col min-h-0 gap-8 overflow-auto px-8 pb-8 light-scrollbar pb-64\">\n <li v-for=\"conversation in conversations\" :key=\"conversation.id\">\n <button\n type=\"button\"\n class=\"rounded-md border p-10 cursor-pointer block w-full transition-colors text-14 leading-relaxed border-b border-surface-3 hover:border-surface-5 hover:bg-surface-1 focus-within:border-word\"\n :class=\"{\n 'bg-surface-2 border-surface-5':\n isCurrentConversation(conversation),\n }\"\n @click=\"openConversation(conversation.id)\">\n <div class=\"flex items-center gap-8\">\n <template v-if=\"editingId === conversation.id\">\n <input\n ref=\"renameInputEl\"\n v-model=\"editingTitle\"\n class=\"flex-1 placeholder:text-word-4 leading-none\"\n :placeholder=\"$t('placeholder.insert')\"\n :maxlength=\"255\"\n @click.stop\n @keydown.enter.prevent=\"\n confirmEdit(conversation.id)\n \"\n @keydown.esc.prevent=\"cancelEdit()\" />\n <VvButton\n icon=\"ri:save-line\"\n :label=\"$t('action.save')\"\n modifiers=\"action-small\"\n @click.stop=\"confirmEdit(conversation.id)\" />\n </template>\n <template v-else>\n <strong class=\"font-bold truncate block flex-1\">\n {{\n stripMarkdown(conversation.title) ||\n getLastMessage(\n conversation.messages,\n 'assistant',\n )\n }}\n </strong>\n <PkRelativeTime\n class=\"text-word-4 text-smaller shrink-0\"\n :date=\"conversation.lastMessageAt\" />\n <div @click.stop>\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n }\">\n <VvButton\n icon=\"ri:more-2-fill\"\n :title=\"$t('action.moreActions')\"\n modifiers=\"action-quiet-small\" />\n <template #items>\n <VvDropdownAction\n @click=\"startEdit(conversation)\">\n <VvIcon name=\"ri:pencil-line\" />\n {{ $t('action.renameChat') }}\n </VvDropdownAction>\n <VvDropdownAction\n @click=\"\n handleDelete(conversation.id)\n \">\n <VvIcon name=\"ri:delete-bin-line\" />\n {{ $t('action.delete') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </div>\n </template>\n </div>\n <span\n v-if=\"editingId !== conversation.id\"\n class=\"text-12 text-word-4 line-clamp-2\">\n {{\n stripMarkdown(conversation.summary) ||\n getLastMessage(conversation.messages, 'user')\n }}\n </span>\n </button>\n </li>\n </ul>\n <div\n class=\"absolute bottom-0 left-0 right-0 flex justify-center px-16 pb-16 pt-32 bg-gradient-to-t\">\n <VvButton\n class=\"text-14\"\n modifiers=\"rounded\"\n :label=\"$t('action.startNewChat')\"\n @click.stop=\"startNewChat()\" />\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
package/dist-vue/_chunks/{PkChatbotViewProfile-CXmmVXrD.js → PkChatbotViewProfile-Dev_6pki.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as e } from "./useChatbotStore-
|
|
1
|
+
import { t as e } from "./useChatbotStore-DGL81KJa.js";
|
|
2
2
|
import { createBlock as t, createCommentVNode as n, createElementBlock as r, createElementVNode as i, createSlots as a, createTextVNode as o, createVNode as s, defineComponent as c, openBlock as l, renderSlot as u, toDisplayString as d, unref as f, withCtx as p } from "vue";
|
|
3
3
|
import { VvAvatar as m } from "@volverjs/ui-vue/components";
|
|
4
4
|
import { useI18n as h } from "vue-i18n";
|
|
@@ -49,4 +49,4 @@ var _ = /* @__PURE__ */ c({
|
|
|
49
49
|
//#endregion
|
|
50
50
|
export { _ as n, S as t };
|
|
51
51
|
|
|
52
|
-
//# sourceMappingURL=PkChatbotViewProfile-
|
|
52
|
+
//# sourceMappingURL=PkChatbotViewProfile-Dev_6pki.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PkChatbotViewProfile-
|
|
1
|
+
{"version":3,"file":"PkChatbotViewProfile-Dev_6pki.js","names":[],"sources":["../../../../packages/components/src/chat/PkAvatar.vue","../../../../packages/components/src/chat/PkAvatar.vue","../../../../packages/components/src/chat/PkChatbotViewProfile.vue","../../../../packages/components/src/chat/PkChatbotViewProfile.vue"],"sourcesContent":["<script setup lang=\"ts\">\n defineProps<{\n name?: string\n imgSrc?: string | null\n modifiers?: string\n }>()\n const getInitials = (name?: string) => {\n if (!name) {\n return ''\n }\n return name\n .split(' ')\n .slice(0, 2)\n .map((n) => n.charAt(0).toUpperCase())\n .join('')\n }\n</script>\n\n<template>\n <VvAvatar\n :img-src=\"imgSrc ? imgSrc : undefined\"\n :modifiers=\"`rounded ${!imgSrc ? modifiers : 'transparent'}`\">\n <template v-if=\"name && !imgSrc\" #default>\n {{ getInitials(name) }}\n </template>\n </VvAvatar>\n</template>\n","<script setup lang=\"ts\">\n defineProps<{\n name?: string\n imgSrc?: string | null\n modifiers?: string\n }>()\n const getInitials = (name?: string) => {\n if (!name) {\n return ''\n }\n return name\n .split(' ')\n .slice(0, 2)\n .map((n) => n.charAt(0).toUpperCase())\n .join('')\n }\n</script>\n\n<template>\n <VvAvatar\n :img-src=\"imgSrc ? imgSrc : undefined\"\n :modifiers=\"`rounded ${!imgSrc ? modifiers : 'transparent'}`\">\n <template v-if=\"name && !imgSrc\" #default>\n {{ getInitials(name) }}\n </template>\n </VvAvatar>\n</template>\n","<script setup lang=\"ts\">\n import { storeToRefs } from 'pinia'\n import { useI18n } from 'vue-i18n'\n import PkAvatar from './PkAvatar.vue'\n import { useChatbotStore } from 'composables'\n\n const props = defineProps<{ agentId: string }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const store = useChatbotStore(props.agentId)\n const { name, agentInterface } = storeToRefs(store)\n</script>\n\n<template>\n <div class=\"flex flex-col flex-1 min-h-0 overflow-y-auto p-md gap-md\">\n <p class=\"text-sm font-semibold text-word-2\">\n {{ $t('label.profile') }}\n </p>\n\n <div class=\"flex flex-col items-center gap-sm p-lg\">\n <PkAvatar\n modifiers=\"surface ring\"\n class=\"w-48 h-48\"\n :name=\"name\"\n :img-src=\"agentInterface?.logo\" />\n <strong v-if=\"name\" class=\"text-base font-semibold text-word-1\">\n {{ name }}\n </strong>\n </div>\n\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { storeToRefs } from 'pinia'\n import { useI18n } from 'vue-i18n'\n import PkAvatar from './PkAvatar.vue'\n import { useChatbotStore } from 'composables'\n\n const props = defineProps<{ agentId: string }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const store = useChatbotStore(props.agentId)\n const { name, agentInterface } = storeToRefs(store)\n</script>\n\n<template>\n <div class=\"flex flex-col flex-1 min-h-0 overflow-y-auto p-md gap-md\">\n <p class=\"text-sm font-semibold text-word-2\">\n {{ $t('label.profile') }}\n </p>\n\n <div class=\"flex flex-col items-center gap-sm p-lg\">\n <PkAvatar\n modifiers=\"surface ring\"\n class=\"w-48 h-48\"\n :name=\"name\"\n :img-src=\"agentInterface?.logo\" />\n <strong v-if=\"name\" class=\"text-base font-semibold text-word-1\">\n {{ name }}\n </strong>\n </div>\n\n <slot />\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;EAMI,IAAM,KAAe,MACZ,IAGE,EACF,MAAM,IAAG,CACT,MAAM,GAAG,EAAC,CACV,KAAK,MAAM,EAAE,OAAO,EAAE,CAAC,aAAa,CAAA,CACpC,KAAK,GAAE,GAND;;;eAWf,EAMW,GAAA;IALN,WAAS,EAAA,SAAS,EAAA,SAAS,KAAA;IAC3B,WAAS,WAAc,EAAA,SAAkB,gBAAT,EAAA;mBACjB,EAAA,QAAI,CAAK,EAAA,SAAA;UAAS;gBACP,CAAA,EAAA,EAApB,EAAY,EAAA,KAAI,CAAA,EAAA,EAAA,CAAA,CAAA;;;;;;;;;;;;EEjB3B,IAAM,IAAQ,GAER,EAAE,GAAG,MAAO,EAAQ,EAAE,UAAU,UAAU,CAAA,EAG1C,EAAE,SAAM,sBAAmB,EADnB,EAAgB,EAAM,QACS,CAAK;yBAIlD,EAiBM,OAjBN,GAiBM;GAhBF,EAEI,KAFJ,GAEI,EADG,EAAA,EAAE,CAAA,gBAAA,CAAA,EAAA,EAAA;GAGT,EASM,OATN,GASM,CARF,EAIsC,GAAA;IAHlC,WAAU;IACV,OAAM;IACL,MAAM,EAAA,EAAI;IACV,WAAS,EAAA,EAAc,EAAE;qCAChB,EAAA,EAAI,IAAA,GAAA,EAAlB,EAES,UAFT,GAES,EADF,EAAA,EAAI,CAAA,EAAA,EAAA,IAAA,EAAA,IAAA,GAAA,CAAA,CAAA;GAIf,EAAQ,EAAA,QAAA,UAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PkRelativeTime-jP41qAJ5.js","names":[],"sources":["../../../../packages/composable/src/useTime.ts","../../../../packages/components/src/PkRelativeTime.vue","../../../../packages/components/src/PkRelativeTime.vue"],"sourcesContent":["import { useI18n } from 'vue-i18n'\n\nexport const useTime = () => {\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const formatDelta = (delta?: number) => {\n if (!delta)\n return {\n value: 0,\n unit: $t('time.unit.second', 0),\n }\n const seconds = Math.floor(delta / 1000)\n const minutes = Math.floor(delta / (1000 * 60))\n const hours = Math.floor(delta / (1000 * 60 * 60))\n const days = Math.floor(delta / (1000 * 60 * 60 * 24))\n\n if (seconds < 60) {\n return {\n value: seconds,\n unit: $t('time.unit.second', seconds),\n }\n }\n\n if (minutes < 60) {\n return {\n value: minutes,\n unit: $t('time.unit.minute', minutes),\n }\n }\n\n if (hours < 24) {\n return {\n value: hours,\n unit: $t('time.unit.hour', hours),\n }\n }\n\n return {\n value: days,\n unit: $t('time.unit.day', days),\n }\n }\n\n const formatDeltaToString = (delta?: number) => {\n const { value, unit } = formatDelta(delta)\n return `${value} ${unit}`\n }\n\n return {\n formatDelta,\n formatDeltaToString,\n }\n}\n","<script setup lang=\"ts\">\n import { computed, onMounted, onUnmounted, ref } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useTime } from 'composables/src/useTime'\n\n const props = withDefaults(\n defineProps<{\n date: Date | string | number\n endDate?: Date | string | number\n autoUpdate?: boolean\n updateInterval?: number\n }>(),\n {\n endDate: undefined,\n autoUpdate: true,\n updateInterval: 1000,\n },\n )\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const now = ref(Date.now())\n let intervalId: ReturnType<typeof setTimeout> | null = null\n\n const targetDate = computed(() => {\n if (props.date instanceof Date) {\n return props.date.getTime()\n }\n if (typeof props.date === 'string') {\n return new Date(props.date).getTime()\n }\n return props.date\n })\n\n const targetEndDate = computed(() => {\n if (props.endDate === undefined) {\n return null\n }\n if (props.endDate instanceof Date) {\n return props.endDate.getTime()\n }\n if (typeof props.endDate === 'string') {\n return new Date(props.endDate).getTime()\n }\n return props.endDate\n })\n\n const deltaMs = computed(() => {\n const reference = targetEndDate.value ?? now.value\n return targetDate.value - reference\n })\n\n const isInFuture = computed(() => {\n return deltaMs.value > 0\n })\n\n const absoluteDelta = computed(() => {\n return Math.abs(deltaMs.value)\n })\n\n const { formatDelta } = useTime()\n const formattedTime = computed(() => {\n const delta = absoluteDelta.value\n return formatDelta(delta)\n })\n\n const displayText = computed(() => {\n const { value, unit } = formattedTime.value\n\n if (props.endDate) {\n return `${value} ${unit}`\n }\n\n if (isInFuture.value) {\n return `${$t('time.future')} ${value} ${unit}`\n }\n\n return `${value} ${unit} ${$t('time.past')}`\n })\n\n const dateTimeAttribute = computed(() => {\n return new Date(targetDate.value).toISOString()\n })\n\n const getAdaptiveInterval = () => {\n const delta = Math.abs(Date.now() - targetDate.value)\n if (delta < 60_000) {\n return props.updateInterval\n }\n if (delta < 3_600_000) {\n return 60_000\n }\n return 3_600_000\n }\n\n const updateNow = () => {\n now.value = Date.now()\n if (props.autoUpdate && !props.endDate) {\n intervalId = setTimeout(updateNow, getAdaptiveInterval())\n }\n }\n\n onMounted(() => {\n if (props.autoUpdate && !props.endDate) {\n intervalId = setTimeout(updateNow, getAdaptiveInterval())\n }\n })\n\n onUnmounted(() => {\n if (intervalId) {\n clearTimeout(intervalId)\n }\n })\n</script>\n\n<template>\n <time :datetime=\"dateTimeAttribute\">\n {{ displayText }}\n </time>\n</template>\n","<script setup lang=\"ts\">\n import { computed, onMounted, onUnmounted, ref } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useTime } from 'composables/src/useTime'\n\n const props = withDefaults(\n defineProps<{\n date: Date | string | number\n endDate?: Date | string | number\n autoUpdate?: boolean\n updateInterval?: number\n }>(),\n {\n endDate: undefined,\n autoUpdate: true,\n updateInterval: 1000,\n },\n )\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const now = ref(Date.now())\n let intervalId: ReturnType<typeof setTimeout> | null = null\n\n const targetDate = computed(() => {\n if (props.date instanceof Date) {\n return props.date.getTime()\n }\n if (typeof props.date === 'string') {\n return new Date(props.date).getTime()\n }\n return props.date\n })\n\n const targetEndDate = computed(() => {\n if (props.endDate === undefined) {\n return null\n }\n if (props.endDate instanceof Date) {\n return props.endDate.getTime()\n }\n if (typeof props.endDate === 'string') {\n return new Date(props.endDate).getTime()\n }\n return props.endDate\n })\n\n const deltaMs = computed(() => {\n const reference = targetEndDate.value ?? now.value\n return targetDate.value - reference\n })\n\n const isInFuture = computed(() => {\n return deltaMs.value > 0\n })\n\n const absoluteDelta = computed(() => {\n return Math.abs(deltaMs.value)\n })\n\n const { formatDelta } = useTime()\n const formattedTime = computed(() => {\n const delta = absoluteDelta.value\n return formatDelta(delta)\n })\n\n const displayText = computed(() => {\n const { value, unit } = formattedTime.value\n\n if (props.endDate) {\n return `${value} ${unit}`\n }\n\n if (isInFuture.value) {\n return `${$t('time.future')} ${value} ${unit}`\n }\n\n return `${value} ${unit} ${$t('time.past')}`\n })\n\n const dateTimeAttribute = computed(() => {\n return new Date(targetDate.value).toISOString()\n })\n\n const getAdaptiveInterval = () => {\n const delta = Math.abs(Date.now() - targetDate.value)\n if (delta < 60_000) {\n return props.updateInterval\n }\n if (delta < 3_600_000) {\n return 60_000\n }\n return 3_600_000\n }\n\n const updateNow = () => {\n now.value = Date.now()\n if (props.autoUpdate && !props.endDate) {\n intervalId = setTimeout(updateNow, getAdaptiveInterval())\n }\n }\n\n onMounted(() => {\n if (props.autoUpdate && !props.endDate) {\n intervalId = setTimeout(updateNow, getAdaptiveInterval())\n }\n })\n\n onUnmounted(() => {\n if (intervalId) {\n clearTimeout(intervalId)\n }\n })\n</script>\n\n<template>\n <time :datetime=\"dateTimeAttribute\">\n {{ displayText }}\n </time>\n</template>\n"],"mappings":";;;AAEA,IAAa,UAAgB;CACzB,IAAM,EAAE,GAAG,MAAO,EAAQ,EACtB,UAAU,UACb,CAAC,EAEI,KAAe,MAAmB;AACpC,MAAI,CAAC,EACD,QAAO;GACH,OAAO;GACP,MAAM,EAAG,oBAAoB,EAAE;GAClC;EACL,IAAM,IAAU,KAAK,MAAM,IAAQ,IAAK,EAClC,IAAU,KAAK,MAAM,KAAS,MAAO,IAAI,EACzC,IAAQ,KAAK,MAAM,KAAS,MAAO,KAAK,IAAI,EAC5C,IAAO,KAAK,MAAM,KAAS,MAAO,KAAK,KAAK,IAAI;AAuBtD,SArBI,IAAU,KACH;GACH,OAAO;GACP,MAAM,EAAG,oBAAoB,EAAQ;GACxC,GAGD,IAAU,KACH;GACH,OAAO;GACP,MAAM,EAAG,oBAAoB,EAAQ;GACxC,GAGD,IAAQ,KACD;GACH,OAAO;GACP,MAAM,EAAG,kBAAkB,EAAM;GACpC,GAGE;GACH,OAAO;GACP,MAAM,EAAG,iBAAiB,EAAK;GAClC;;AAQL,QAAO;EACH;EACA,sBAPyB,MAAmB;GAC5C,IAAM,EAAE,UAAO,YAAS,EAAY,EAAM;AAC1C,UAAO,GAAG,EAAM,GAAG;;EAMtB;;;;;;;;;;;;;EChDD,IAAM,IAAQ,GAcR,EAAE,GAAG,MAAO,EAAQ,EACtB,UAAU,UACb,CAAA,EAEK,IAAM,EAAI,KAAK,KAAK,CAAA,EACtB,IAAmD,MAEjD,IAAa,QACX,EAAM,gBAAgB,OACf,EAAM,KAAK,SAAQ,GAE1B,OAAO,EAAM,QAAS,WACf,IAAI,KAAK,EAAM,KAAK,CAAC,SAAQ,GAEjC,EAAM,KAChB,EAEK,IAAgB,QACd,EAAM,YAAY,KAAA,IACX,OAEP,EAAM,mBAAmB,OAClB,EAAM,QAAQ,SAAQ,GAE7B,OAAO,EAAM,WAAY,WAClB,IAAI,KAAK,EAAM,QAAQ,CAAC,SAAQ,GAEpC,EAAM,QAChB,EAEK,IAAU,QAAe;GAC3B,IAAM,IAAY,EAAc,SAAS,EAAI;AAC7C,UAAO,EAAW,QAAQ;IAC7B,EAEK,IAAa,QACR,EAAQ,QAAQ,EAC1B,EAEK,IAAgB,QACX,KAAK,IAAI,EAAQ,MAAK,CAChC,EAEK,EAAE,mBAAgB,GAAQ,EAC1B,IAAgB,QAAe;GACjC,IAAM,IAAQ,EAAc;AAC5B,UAAO,EAAY,EAAK;IAC3B,EAEK,IAAc,QAAe;GAC/B,IAAM,EAAE,UAAO,YAAS,EAAc;AAUtC,UARI,EAAM,UACC,GAAG,EAAM,GAAG,MAGnB,EAAW,QACJ,GAAG,EAAG,cAAc,CAAC,GAAG,EAAM,GAAG,MAGrC,GAAG,EAAM,GAAG,EAAK,GAAG,EAAG,YAAY;IAC7C,EAEK,IAAoB,QACf,IAAI,KAAK,EAAW,MAAM,CAAC,aAAY,CACjD,EAEK,UAA4B;GAC9B,IAAM,IAAQ,KAAK,IAAI,KAAK,KAAK,GAAG,EAAW,MAAK;AAOpD,UANI,IAAQ,MACD,EAAM,iBAEb,IAAQ,OACD,MAEJ;KAGL,UAAkB;AAEpB,GADA,EAAI,QAAQ,KAAK,KAAI,EACjB,EAAM,cAAc,CAAC,EAAM,YAC3B,IAAa,WAAW,GAAW,GAAqB,CAAA;;SAIhE,QAAgB;AACZ,GAAI,EAAM,cAAc,CAAC,EAAM,YAC3B,IAAa,WAAW,GAAW,GAAqB,CAAA;IAE/D,EAED,QAAkB;AACd,GAAI,KACA,aAAa,EAAU;IAE9B,kBAID,EAEO,QAAA,EAFA,UAAU,EAAA,OAAiB,EAAA,EAC3B,EAAA,MAAW,EAAA,GAAA,EAAA"}
|
|
1
|
+
{"version":3,"file":"PkRelativeTime-WZ2aPcp_.js","names":[],"sources":["../../../../packages/composable/src/useTime.ts","../../../../packages/components/src/PkRelativeTime.vue","../../../../packages/components/src/PkRelativeTime.vue"],"sourcesContent":["import { useI18n } from 'vue-i18n'\n\nexport const useTime = () => {\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const formatDelta = (delta?: number) => {\n if (!delta)\n return {\n value: 0,\n unit: $t('time.unit.second', 0),\n }\n const seconds = Math.floor(delta / 1000)\n const minutes = Math.floor(delta / (1000 * 60))\n const hours = Math.floor(delta / (1000 * 60 * 60))\n const days = Math.floor(delta / (1000 * 60 * 60 * 24))\n\n if (seconds < 60) {\n return {\n value: seconds,\n unit: $t('time.unit.second', seconds),\n }\n }\n\n if (minutes < 60) {\n return {\n value: minutes,\n unit: $t('time.unit.minute', minutes),\n }\n }\n\n if (hours < 24) {\n return {\n value: hours,\n unit: $t('time.unit.hour', hours),\n }\n }\n\n return {\n value: days,\n unit: $t('time.unit.day', days),\n }\n }\n\n const formatDeltaToString = (delta?: number) => {\n const { value, unit } = formatDelta(delta)\n return `${value} ${unit}`\n }\n\n return {\n formatDelta,\n formatDeltaToString,\n }\n}\n","<script setup lang=\"ts\">\n import { computed, onMounted, onUnmounted, ref } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useTime } from 'composables/src/useTime'\n\n const props = withDefaults(\n defineProps<{\n date: Date | string | number\n endDate?: Date | string | number\n autoUpdate?: boolean\n updateInterval?: number\n }>(),\n {\n endDate: undefined,\n autoUpdate: true,\n updateInterval: 1000,\n },\n )\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const now = ref(Date.now())\n let intervalId: ReturnType<typeof setTimeout> | null = null\n\n const targetDate = computed(() => {\n if (props.date instanceof Date) {\n return props.date.getTime()\n }\n if (typeof props.date === 'string') {\n return new Date(props.date).getTime()\n }\n return props.date\n })\n\n const targetEndDate = computed(() => {\n if (props.endDate === undefined) {\n return null\n }\n if (props.endDate instanceof Date) {\n return props.endDate.getTime()\n }\n if (typeof props.endDate === 'string') {\n return new Date(props.endDate).getTime()\n }\n return props.endDate\n })\n\n const deltaMs = computed(() => {\n const reference = targetEndDate.value ?? now.value\n return targetDate.value - reference\n })\n\n const isInFuture = computed(() => {\n return deltaMs.value > 0\n })\n\n const absoluteDelta = computed(() => {\n return Math.abs(deltaMs.value)\n })\n\n const { formatDelta } = useTime()\n const formattedTime = computed(() => {\n const delta = absoluteDelta.value\n return formatDelta(delta)\n })\n\n const displayText = computed(() => {\n const { value, unit } = formattedTime.value\n\n if (props.endDate) {\n return `${value} ${unit}`\n }\n\n if (isInFuture.value) {\n return `${$t('time.future')} ${value} ${unit}`\n }\n\n return `${value} ${unit} ${$t('time.past')}`\n })\n\n const dateTimeAttribute = computed(() => {\n return new Date(targetDate.value).toISOString()\n })\n\n const getAdaptiveInterval = () => {\n const delta = Math.abs(Date.now() - targetDate.value)\n if (delta < 60_000) {\n return props.updateInterval\n }\n if (delta < 3_600_000) {\n return 60_000\n }\n return 3_600_000\n }\n\n const updateNow = () => {\n now.value = Date.now()\n if (props.autoUpdate && !props.endDate) {\n intervalId = setTimeout(updateNow, getAdaptiveInterval())\n }\n }\n\n onMounted(() => {\n if (props.autoUpdate && !props.endDate) {\n intervalId = setTimeout(updateNow, getAdaptiveInterval())\n }\n })\n\n onUnmounted(() => {\n if (intervalId) {\n clearTimeout(intervalId)\n }\n })\n</script>\n\n<template>\n <time :datetime=\"dateTimeAttribute\">\n {{ displayText }}\n </time>\n</template>\n","<script setup lang=\"ts\">\n import { computed, onMounted, onUnmounted, ref } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useTime } from 'composables/src/useTime'\n\n const props = withDefaults(\n defineProps<{\n date: Date | string | number\n endDate?: Date | string | number\n autoUpdate?: boolean\n updateInterval?: number\n }>(),\n {\n endDate: undefined,\n autoUpdate: true,\n updateInterval: 1000,\n },\n )\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const now = ref(Date.now())\n let intervalId: ReturnType<typeof setTimeout> | null = null\n\n const targetDate = computed(() => {\n if (props.date instanceof Date) {\n return props.date.getTime()\n }\n if (typeof props.date === 'string') {\n return new Date(props.date).getTime()\n }\n return props.date\n })\n\n const targetEndDate = computed(() => {\n if (props.endDate === undefined) {\n return null\n }\n if (props.endDate instanceof Date) {\n return props.endDate.getTime()\n }\n if (typeof props.endDate === 'string') {\n return new Date(props.endDate).getTime()\n }\n return props.endDate\n })\n\n const deltaMs = computed(() => {\n const reference = targetEndDate.value ?? now.value\n return targetDate.value - reference\n })\n\n const isInFuture = computed(() => {\n return deltaMs.value > 0\n })\n\n const absoluteDelta = computed(() => {\n return Math.abs(deltaMs.value)\n })\n\n const { formatDelta } = useTime()\n const formattedTime = computed(() => {\n const delta = absoluteDelta.value\n return formatDelta(delta)\n })\n\n const displayText = computed(() => {\n const { value, unit } = formattedTime.value\n\n if (props.endDate) {\n return `${value} ${unit}`\n }\n\n if (isInFuture.value) {\n return `${$t('time.future')} ${value} ${unit}`\n }\n\n return `${value} ${unit} ${$t('time.past')}`\n })\n\n const dateTimeAttribute = computed(() => {\n return new Date(targetDate.value).toISOString()\n })\n\n const getAdaptiveInterval = () => {\n const delta = Math.abs(Date.now() - targetDate.value)\n if (delta < 60_000) {\n return props.updateInterval\n }\n if (delta < 3_600_000) {\n return 60_000\n }\n return 3_600_000\n }\n\n const updateNow = () => {\n now.value = Date.now()\n if (props.autoUpdate && !props.endDate) {\n intervalId = setTimeout(updateNow, getAdaptiveInterval())\n }\n }\n\n onMounted(() => {\n if (props.autoUpdate && !props.endDate) {\n intervalId = setTimeout(updateNow, getAdaptiveInterval())\n }\n })\n\n onUnmounted(() => {\n if (intervalId) {\n clearTimeout(intervalId)\n }\n })\n</script>\n\n<template>\n <time :datetime=\"dateTimeAttribute\">\n {{ displayText }}\n </time>\n</template>\n"],"mappings":";;;AAEA,IAAa,UAAgB;CACzB,IAAM,EAAE,GAAG,MAAO,EAAQ,EACtB,UAAU,UACb,CAAC,EAEI,KAAe,MAAmB;AACpC,MAAI,CAAC,EACD,QAAO;GACH,OAAO;GACP,MAAM,EAAG,oBAAoB,EAAE;GAClC;EACL,IAAM,IAAU,KAAK,MAAM,IAAQ,IAAK,EAClC,IAAU,KAAK,MAAM,KAAS,MAAO,IAAI,EACzC,IAAQ,KAAK,MAAM,KAAS,MAAO,KAAK,IAAI,EAC5C,IAAO,KAAK,MAAM,KAAS,MAAO,KAAK,KAAK,IAAI;AAuBtD,SArBI,IAAU,KACH;GACH,OAAO;GACP,MAAM,EAAG,oBAAoB,EAAQ;GACxC,GAGD,IAAU,KACH;GACH,OAAO;GACP,MAAM,EAAG,oBAAoB,EAAQ;GACxC,GAGD,IAAQ,KACD;GACH,OAAO;GACP,MAAM,EAAG,kBAAkB,EAAM;GACpC,GAGE;GACH,OAAO;GACP,MAAM,EAAG,iBAAiB,EAAK;GAClC;;AAQL,QAAO;EACH;EACA,sBAPyB,MAAmB;GAC5C,IAAM,EAAE,UAAO,YAAS,EAAY,EAAM;AAC1C,UAAO,GAAG,EAAM,GAAG;;EAMtB;;;;;;;;;;;;;EChDD,IAAM,IAAQ,GAcR,EAAE,GAAG,MAAO,EAAQ,EACtB,UAAU,UACb,CAAA,EAEK,IAAM,EAAI,KAAK,KAAK,CAAA,EACtB,IAAmD,MAEjD,IAAa,QACX,EAAM,gBAAgB,OACf,EAAM,KAAK,SAAQ,GAE1B,OAAO,EAAM,QAAS,WACf,IAAI,KAAK,EAAM,KAAK,CAAC,SAAQ,GAEjC,EAAM,KAChB,EAEK,IAAgB,QACd,EAAM,YAAY,KAAA,IACX,OAEP,EAAM,mBAAmB,OAClB,EAAM,QAAQ,SAAQ,GAE7B,OAAO,EAAM,WAAY,WAClB,IAAI,KAAK,EAAM,QAAQ,CAAC,SAAQ,GAEpC,EAAM,QAChB,EAEK,IAAU,QAAe;GAC3B,IAAM,IAAY,EAAc,SAAS,EAAI;AAC7C,UAAO,EAAW,QAAQ;IAC7B,EAEK,IAAa,QACR,EAAQ,QAAQ,EAC1B,EAEK,IAAgB,QACX,KAAK,IAAI,EAAQ,MAAK,CAChC,EAEK,EAAE,mBAAgB,GAAQ,EAC1B,IAAgB,QAAe;GACjC,IAAM,IAAQ,EAAc;AAC5B,UAAO,EAAY,EAAK;IAC3B,EAEK,IAAc,QAAe;GAC/B,IAAM,EAAE,UAAO,YAAS,EAAc;AAUtC,UARI,EAAM,UACC,GAAG,EAAM,GAAG,MAGnB,EAAW,QACJ,GAAG,EAAG,cAAc,CAAC,GAAG,EAAM,GAAG,MAGrC,GAAG,EAAM,GAAG,EAAK,GAAG,EAAG,YAAY;IAC7C,EAEK,IAAoB,QACf,IAAI,KAAK,EAAW,MAAM,CAAC,aAAY,CACjD,EAEK,UAA4B;GAC9B,IAAM,IAAQ,KAAK,IAAI,KAAK,KAAK,GAAG,EAAW,MAAK;AAOpD,UANI,IAAQ,MACD,EAAM,iBAEb,IAAQ,OACD,MAEJ;KAGL,UAAkB;AAEpB,GADA,EAAI,QAAQ,KAAK,KAAI,EACjB,EAAM,cAAc,CAAC,EAAM,YAC3B,IAAa,WAAW,GAAW,GAAqB,CAAA;;SAIhE,QAAgB;AACZ,GAAI,EAAM,cAAc,CAAC,EAAM,YAC3B,IAAa,WAAW,GAAW,GAAqB,CAAA;IAE/D,EAED,QAAkB;AACd,GAAI,KACA,aAAa,EAAU;IAE9B,kBAID,EAEO,QAAA,EAFA,UAAU,EAAA,OAAiB,EAAA,EAC3B,EAAA,MAAW,EAAA,GAAA,EAAA"}
|