11<script setup lang="ts">
2+ import type { DevframeMessageAction } from ' @devframes/hub'
23import type { DocksContext } from ' @devframes/hub/client'
34import { MESSAGES_DOCK_ID } from ' ../../constants'
45import { selectMessage , useMessages } from ' ../../state/messages'
@@ -23,6 +24,20 @@ function openMessages(toastId: string) {
2324 // (its dock id is the plugin's devframe id).
2425 props .context ?.docks .switchEntry (MESSAGES_DOCK_ID )
2526}
27+
28+ /**
29+ * Mirrors `@devframes/plugin-messages`'s own `onActivate` dispatch (its
30+ * `App.vue`) — the toast's own `entry.actions` buttons behave identically to
31+ * the ones in the messages panel's detail view, without waiting for that
32+ * panel to be open. `context.docks`/`context.commands` reach the hub
33+ * directly here, whereas the plugin (an iframe) goes through RPC.
34+ */
35+ function dispatchAction(action : DevframeMessageAction ) {
36+ if (action .kind === ' activate' )
37+ props .context ?.docks .switchEntry (action .activate .dockId )
38+ else if (action .kind === ' command' )
39+ props .context ?.commands .execute (action .command .id , ... (action .command .params ?? []))
40+ }
2641 </script >
2742
2843<template >
@@ -44,6 +59,14 @@ function openMessages(toastId: string) {
4459 >
4560 <MessageItem :entry =" toast .entry " compact class="px-3 py-2.5 ">
4661 <template #actions >
62+ <button
63+ v-for =" action of toast.entry.actions"
64+ :key =" action.id"
65+ class =" flex-none text-xs px-1.5 py-0.5 rounded border border-base op70 hover:op100 hover:bg-active transition"
66+ @click.stop =" dispatchAction(action)"
67+ >
68+ {{ action.label }}
69+ </button >
4770 <button
4871 class =" flex-none op30 hover:op100 p-0.5 rounded hover:bg-active transition"
4972 @click.stop =" dismissToast(toast.id)"
0 commit comments