11<script setup lang="ts">
22import type { DocksContext } from ' @vitejs/devtools-kit/client'
3+ import { useLogs } from ' ../state/logs'
34import { dismissToast , useToasts } from ' ../state/toasts'
45import DockIcon from ' ./DockIcon.vue'
56
67const props = defineProps <{
78 context? : DocksContext
89}>()
910
11+ // Initialize logs state early so the RPC handler is registered
12+ // and toasts are triggered even before the logs panel is opened
13+ if (props .context )
14+ useLogs (props .context )
15+
1016const toasts = useToasts ()
1117
1218const levelColors: Record <string , string > = {
@@ -32,49 +38,47 @@ function openLogs(toastId: string) {
3238 </script >
3339
3440<template >
35- <Teleport to =" body" >
36- <div
37- v-if =" toasts.length > 0"
38- class =" fixed bottom-4 right-4 z-2147483647 flex flex-col gap-2 pointer-events-auto max-w-80"
41+ <div
42+ v-if =" toasts.length > 0"
43+ class =" fixed bottom-4 right-4 z-2147483647 flex flex-col gap-2 pointer-events-auto max-w-80"
44+ >
45+ <TransitionGroup
46+ enter-active-class =" transition-all duration-300 ease-out"
47+ leave-active-class =" transition-all duration-200 ease-in"
48+ enter-from-class =" opacity-0 translate-x-4"
49+ leave-to-class =" opacity-0 translate-x-4"
3950 >
40- <TransitionGroup
41- enter-active-class =" transition-all duration-300 ease-out"
42- leave-active-class =" transition-all duration-200 ease-in"
43- enter-from-class =" opacity-0 translate-x-4"
44- leave-to-class =" opacity-0 translate-x-4"
51+ <div
52+ v-for =" toast of toasts"
53+ :key =" toast.id"
54+ class =" bg-base border border-base rounded-lg shadow-lg flex items-start gap-2 px-3 py-2 border-l-3 cursor-pointer"
55+ :class =" levelColors[toast.entry.level] || 'border-gray'"
56+ @click =" openLogs(toast.id)"
4557 >
58+ <DockIcon
59+ v-if =" toast.entry.status !== 'loading'"
60+ :icon =" levelIcons[toast.entry.level] || 'ph:info-duotone'"
61+ class =" w-4 h-4 flex-none mt-0.5"
62+ />
4663 <div
47- v-for =" toast of toasts"
48- :key =" toast.id"
49- class =" bg-base border border-base rounded-lg shadow-lg flex items-start gap-2 px-3 py-2 border-l-3 cursor-pointer"
50- :class =" levelColors[toast.entry.level] || 'border-gray'"
51- @click =" openLogs(toast.id)"
52- >
53- <DockIcon
54- v-if =" toast.entry.status !== 'loading'"
55- :icon =" levelIcons[toast.entry.level] || 'ph:info-duotone'"
56- class =" w-4 h-4 flex-none mt-0.5"
57- />
58- <div
59- v-else
60- class =" w-4 h-4 flex-none mt-0.5 border-2 border-current border-t-transparent rounded-full animate-spin op50"
61- />
62- <div class =" flex-1 min-w-0" >
63- <div class =" text-sm font-medium truncate" >
64- {{ toast.entry.message }}
65- </div >
66- <div v-if =" toast.entry.source" class =" text-xs op50 truncate" >
67- {{ toast.entry.source }}
68- </div >
64+ v-else
65+ class =" w-4 h-4 flex-none mt-0.5 border-2 border-current border-t-transparent rounded-full animate-spin op50"
66+ />
67+ <div class =" flex-1 min-w-0" >
68+ <div class =" text-sm font-medium truncate" >
69+ {{ toast.entry.message }}
70+ </div >
71+ <div v-if =" toast.entry.source" class =" text-xs op50 truncate" >
72+ {{ toast.entry.source }}
6973 </div >
70- <button
71- class =" flex-none op50 hover:op100 p-0.5"
72- @click.stop =" dismissToast(toast.id)"
73- >
74- <DockIcon icon =" ph:x" class =" w-3 h-3" />
75- </button >
7674 </div >
77- </TransitionGroup >
78- </div >
79- </Teleport >
75+ <button
76+ class =" flex-none op50 hover:op100 p-0.5"
77+ @click.stop =" dismissToast(toast.id)"
78+ >
79+ <DockIcon icon =" ph:x" class =" w-3 h-3" />
80+ </button >
81+ </div >
82+ </TransitionGroup >
83+ </div >
8084</template >
0 commit comments