Skip to content

Commit 974cc66

Browse files
TheodoreSpeaksTheodore Li
andauthored
fix(ui) add embedded workflow notifications, switch tab on workflow run (#3618)
* Include notification view in embedded workflow view * fix(ui) fix workflow not showing up when mothership calls run * Wire up fix in mothership * Refresh events after workflow run * Fix so run workflow switches tabs as well --------- Co-authored-by: Theodore Li <theo@sim.ai>
1 parent c867801 commit 974cc66

File tree

6 files changed

+56
-6
lines changed

6 files changed

+56
-6
lines changed

apps/sim/app/workspace/[workspaceId]/home/home.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,15 @@ export function Home({ chatId }: HomeProps = {}) {
250250
[sendMessage]
251251
)
252252

253+
useEffect(() => {
254+
const handler = (e: Event) => {
255+
const message = (e as CustomEvent<{ message: string }>).detail?.message
256+
if (message) sendMessage(message)
257+
}
258+
window.addEventListener('mothership-send-message', handler)
259+
return () => window.removeEventListener('mothership-send-message', handler)
260+
}, [sendMessage])
261+
253262
const handleContextAdd = useCallback(
254263
(context: ChatContext) => {
255264
let resourceType: MothershipResourceType | null = null

apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,22 @@ export function useChat(
651651
) {
652652
clientExecutionStarted.add(id)
653653
const args = data?.arguments ?? data?.input ?? {}
654+
const targetWorkflowId =
655+
typeof (args as Record<string, unknown>).workflowId === 'string'
656+
? ((args as Record<string, unknown>).workflowId as string)
657+
: useWorkflowRegistry.getState().activeWorkflowId
658+
if (targetWorkflowId) {
659+
const meta = useWorkflowRegistry.getState().workflows[targetWorkflowId]
660+
const wasAdded = addResource({
661+
type: 'workflow',
662+
id: targetWorkflowId,
663+
title: meta?.name ?? 'Workflow',
664+
})
665+
if (!wasAdded && activeResourceIdRef.current !== targetWorkflowId) {
666+
setActiveResourceId(targetWorkflowId)
667+
}
668+
onResourceEventRef.current?.()
669+
}
654670
executeRunToolOnClient(id, name, args as Record<string, unknown>)
655671
}
656672
break

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/notifications/notifications.tsx

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
type Notification,
1010
type NotificationAction,
1111
openCopilotWithMessage,
12+
sendMothershipMessage,
1213
useNotificationStore,
1314
} from '@/stores/notifications'
1415
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
@@ -81,7 +82,11 @@ function CountdownRing({ onPause }: { onPause: () => void }) {
8182
* Workflow error notifications auto-dismiss after {@link AUTO_DISMISS_MS}ms with a countdown
8283
* ring. Clicking the ring pauses all timers until the notification stack clears.
8384
*/
84-
export const Notifications = memo(function Notifications() {
85+
interface NotificationsProps {
86+
embedded?: boolean
87+
}
88+
89+
export const Notifications = memo(function Notifications({ embedded }: NotificationsProps) {
8590
const activeWorkflowId = useWorkflowRegistry((state) => state.activeWorkflowId)
8691

8792
const allNotifications = useNotificationStore((state) => state.notifications)
@@ -112,7 +117,11 @@ export const Notifications = memo(function Notifications() {
112117

113118
switch (action.type) {
114119
case 'copilot':
115-
openCopilotWithMessage(action.message)
120+
if (embedded) {
121+
sendMothershipMessage(action.message)
122+
} else {
123+
openCopilotWithMessage(action.message)
124+
}
116125
break
117126
case 'refresh':
118127
window.location.reload()
@@ -133,7 +142,7 @@ export const Notifications = memo(function Notifications() {
133142
})
134143
}
135144
},
136-
[removeNotification]
145+
[embedded, removeNotification]
137146
)
138147

139148
useRegisterGlobalCommands(() =>
@@ -281,7 +290,9 @@ export const Notifications = memo(function Notifications() {
281290
onClick={() => executeAction(notification.id, notification.action!)}
282291
className='w-full rounded-[5px] px-[8px] py-[4px] font-medium text-[12px]'
283292
>
284-
{ACTION_LABELS[notification.action!.type] ?? 'Take action'}
293+
{embedded && notification.action!.type === 'copilot'
294+
? 'Fix in Mothership'
295+
: (ACTION_LABELS[notification.action!.type] ?? 'Take action')}
285296
</Button>
286297
)}
287298
</div>

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3922,7 +3922,7 @@ const WorkflowContent = React.memo(
39223922
</>
39233923
)}
39243924

3925-
{!embedded && <Notifications />}
3925+
<Notifications embedded={embedded} />
39263926

39273927
{!embedded && isWorkflowReady && isWorkflowEmpty && effectivePermissions.canEdit && (
39283928
<CommandList />

apps/sim/stores/notifications/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ export type {
44
Notification,
55
NotificationAction,
66
} from './types'
7-
export { openCopilotWithMessage } from './utils'
7+
export { openCopilotWithMessage, sendMothershipMessage } from './utils'

apps/sim/stores/notifications/utils.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,20 @@ import { useCopilotStore, usePanelStore } from '@/stores/panel'
33

44
const logger = createLogger('NotificationUtils')
55

6+
/**
7+
* Dispatches a message to the mothership chat via a custom window event.
8+
* The mothership `Home` component listens for this event and calls `sendMessage`.
9+
*/
10+
export function sendMothershipMessage(message: string): void {
11+
const trimmed = message.trim()
12+
if (!trimmed) {
13+
logger.warn('sendMothershipMessage called with empty message')
14+
return
15+
}
16+
window.dispatchEvent(new CustomEvent('mothership-send-message', { detail: { message: trimmed } }))
17+
logger.info('Dispatched mothership message event', { messageLength: trimmed.length })
18+
}
19+
620
/**
721
* Opens the copilot panel and directly sends the message.
822
*

0 commit comments

Comments
 (0)