Skip to content

Commit 30f7930

Browse files
authored
fix(workflow-preview): fixed the workflow preview to pull directly from the state in DB
2 parents dcf6e10 + 79d8dcb commit 30f7930

File tree

48 files changed

+2475
-1718
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+2475
-1718
lines changed
Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
import { eq } from 'drizzle-orm'
2-
import type { NextRequest } from 'next/server'
2+
import type { NextRequest, NextResponse } from 'next/server'
33
import { createLogger } from '@/lib/logs/console-logger'
44
import { db } from '@/db'
55
import { workflow } from '@/db/schema'
66
import { validateWorkflowAccess } from '../../middleware'
77
import { createErrorResponse, createSuccessResponse } from '../../utils'
88

9-
const logger = createLogger('WorkflowDeployedAPI')
9+
const logger = createLogger('WorkflowDeployedStateAPI')
1010

1111
export const dynamic = 'force-dynamic'
1212
export const runtime = 'nodejs'
1313

14+
// Helper function to add Cache-Control headers to NextResponse
15+
function addNoCacheHeaders(response: NextResponse): NextResponse {
16+
response.headers.set('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
17+
return response
18+
}
19+
1420
export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
1521
const requestId = crypto.randomUUID().slice(0, 8)
1622
const { id } = await params
@@ -21,10 +27,11 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{
2127

2228
if (validation.error) {
2329
logger.warn(`[${requestId}] Failed to fetch deployed state: ${validation.error.message}`)
24-
return createErrorResponse(validation.error.message, validation.error.status)
30+
const response = createErrorResponse(validation.error.message, validation.error.status)
31+
return addNoCacheHeaders(response)
2532
}
2633

27-
// Fetch just the deployed state
34+
// Fetch the workflow's deployed state
2835
const result = await db
2936
.select({
3037
deployedState: workflow.deployedState,
@@ -36,27 +43,28 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{
3643

3744
if (result.length === 0) {
3845
logger.warn(`[${requestId}] Workflow not found: ${id}`)
39-
return createErrorResponse('Workflow not found', 404)
46+
const response = createErrorResponse('Workflow not found', 404)
47+
return addNoCacheHeaders(response)
4048
}
4149

4250
const workflowData = result[0]
4351

4452
// If the workflow is not deployed, return appropriate response
4553
if (!workflowData.isDeployed || !workflowData.deployedState) {
46-
logger.info(`[${requestId}] No deployed state available for workflow: ${id}`)
47-
return createSuccessResponse({
54+
const response = createSuccessResponse({
4855
deployedState: null,
49-
isDeployed: false,
56+
message: 'Workflow is not deployed or has no deployed state',
5057
})
58+
return addNoCacheHeaders(response)
5159
}
5260

53-
logger.info(`[${requestId}] Successfully retrieved DEPLOYED state: ${id}`)
54-
return createSuccessResponse({
61+
const response = createSuccessResponse({
5562
deployedState: workflowData.deployedState,
56-
isDeployed: true,
5763
})
64+
return addNoCacheHeaders(response)
5865
} catch (error: any) {
5966
logger.error(`[${requestId}] Error fetching deployed state: ${id}`, error)
60-
return createErrorResponse(error.message || 'Failed to fetch deployed state', 500)
67+
const response = createErrorResponse(error.message || 'Failed to fetch deployed state', 500)
68+
return addNoCacheHeaders(response)
6169
}
6270
}

apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/deployment-info.tsx

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ import { ApiKey } from '@/app/w/[id]/components/control-bar/components/deploy-mo
2020
import { DeployStatus } from '@/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/components/deploy-status/deploy-status'
2121
import { ExampleCommand } from '@/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/components/example-command/example-command'
2222
import { useNotificationStore } from '@/stores/notifications/store'
23+
import type { WorkflowState } from '@/stores/workflows/workflow/types'
2324
import { DeployedWorkflowModal } from '../../../deployment-controls/components/deployed-workflow-modal'
2425

2526
interface DeploymentInfoProps {
26-
isLoading: boolean
27+
isLoading?: boolean
2728
deploymentInfo: {
28-
isDeployed: boolean
2929
deployedAt?: string
3030
apiKey: string
3131
endpoint: string
@@ -36,7 +36,9 @@ interface DeploymentInfoProps {
3636
onUndeploy: () => void
3737
isSubmitting: boolean
3838
isUndeploying: boolean
39-
workflowId?: string
39+
workflowId: string | null
40+
deployedState: WorkflowState
41+
isLoadingDeployedState: boolean
4042
}
4143

4244
export function DeploymentInfo({
@@ -47,9 +49,10 @@ export function DeploymentInfo({
4749
isSubmitting,
4850
isUndeploying,
4951
workflowId,
52+
deployedState,
53+
isLoadingDeployedState,
5054
}: DeploymentInfoProps) {
5155
const [isViewingDeployed, setIsViewingDeployed] = useState(false)
52-
const [deployedWorkflowState, setDeployedWorkflowState] = useState<any>(null)
5356
const { addNotification } = useNotificationStore()
5457

5558
const handleViewDeployed = async () => {
@@ -58,28 +61,13 @@ export function DeploymentInfo({
5861
return
5962
}
6063

61-
try {
62-
const response = await fetch(`/api/workflows/${workflowId}/deployed`)
63-
64-
if (!response.ok) {
65-
throw new Error('Failed to fetch deployed workflow')
66-
}
67-
68-
const data = await response.json()
69-
70-
if (data?.deployedState) {
71-
setDeployedWorkflowState(data.deployedState)
72-
setIsViewingDeployed(true)
73-
} else {
74-
addNotification('error', 'Failed to view deployment: No deployment state found', workflowId)
75-
}
76-
} catch (error) {
77-
console.error('Error fetching deployed workflow:', error)
78-
addNotification(
79-
'error',
80-
`Failed to fetch deployed workflow: ${(error as Error).message}`,
81-
workflowId
82-
)
64+
// If deployedState is already loaded, use it directly
65+
if (deployedState) {
66+
setIsViewingDeployed(true)
67+
return
68+
}
69+
if (!isLoadingDeployedState) {
70+
addNotification('error', 'Cannot view deployment: No deployed state available', workflowId)
8371
}
8472
}
8573

@@ -168,11 +156,12 @@ export function DeploymentInfo({
168156
</div>
169157
</div>
170158

171-
{deployedWorkflowState && (
159+
{deployedState && (
172160
<DeployedWorkflowModal
173161
isOpen={isViewingDeployed}
174162
onClose={() => setIsViewingDeployed(false)}
175-
deployedWorkflowState={deployedWorkflowState}
163+
needsRedeployment={deploymentInfo.needsRedeployment}
164+
deployedWorkflowState={deployedState}
176165
/>
177166
)}
178167
</>

apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/deploy-modal.tsx

Lines changed: 49 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { useNotificationStore } from '@/stores/notifications/store'
2727
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
2828
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
2929
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
30+
import type { WorkflowState } from '@/stores/workflows/workflow/types'
3031

3132
const logger = createLogger('DeployModal')
3233

@@ -36,6 +37,9 @@ interface DeployModalProps {
3637
workflowId: string | null
3738
needsRedeployment: boolean
3839
setNeedsRedeployment: (value: boolean) => void
40+
deployedState: WorkflowState
41+
isLoadingDeployedState: boolean
42+
refetchDeployedState: () => Promise<void>
3943
}
4044

4145
interface ApiKey {
@@ -69,6 +73,9 @@ export function DeployModal({
6973
workflowId,
7074
needsRedeployment,
7175
setNeedsRedeployment,
76+
deployedState,
77+
isLoadingDeployedState,
78+
refetchDeployedState,
7279
}: DeployModalProps) {
7380
// Store hooks
7481
const { addNotification } = useNotificationStore()
@@ -306,6 +313,9 @@ export function DeployModal({
306313

307314
setDeploymentInfo(newDeploymentInfo)
308315

316+
// Fetch the updated deployed state after deployment
317+
await refetchDeployedState()
318+
309319
// No notification on successful deploy
310320
} catch (error: any) {
311321
logger.error('Error deploying workflow:', { error })
@@ -395,7 +405,9 @@ export function DeployModal({
395405
useWorkflowRegistry.getState().setWorkflowNeedsRedeployment(workflowId, false)
396406
}
397407

398-
// Add a success notification
408+
// Fetch the updated deployed state after redeployment
409+
await refetchDeployedState()
410+
399411
addNotification('info', 'Workflow successfully redeployed', workflowId)
400412
} catch (error: any) {
401413
logger.error('Error redeploying workflow:', { error })
@@ -407,7 +419,6 @@ export function DeployModal({
407419

408420
// Custom close handler to ensure we clean up loading states
409421
const handleCloseModal = () => {
410-
// Reset all loading states
411422
setIsSubmitting(false)
412423
setIsChatDeploying(false)
413424
setChatSubmitting(false)
@@ -505,8 +516,6 @@ export function DeployModal({
505516
deployedAt ? new Date(deployedAt) : undefined,
506517
apiKey
507518
)
508-
509-
logger.info('Workflow automatically deployed for chat deployment')
510519
} catch (error: any) {
511520
logger.error('Error auto-deploying workflow for chat:', { error })
512521
addNotification('error', `Failed to deploy workflow: ${error.message}`, workflowId)
@@ -606,38 +615,43 @@ export function DeployModal({
606615

607616
<div className='flex-1 overflow-y-auto'>
608617
<div className='p-6'>
609-
{activeTab === 'api' &&
610-
(isDeployed ? (
611-
<DeploymentInfo
612-
isLoading={isLoading}
613-
deploymentInfo={deploymentInfo}
614-
onRedeploy={handleRedeploy}
615-
onUndeploy={handleUndeploy}
616-
isSubmitting={isSubmitting}
617-
isUndeploying={isUndeploying}
618-
workflowId={workflowId || undefined}
619-
/>
620-
) : (
621-
<>
622-
{apiDeployError && (
623-
<div className='mb-4 rounded-md border border-destructive/30 bg-destructive/10 p-3 text-destructive text-sm'>
624-
<div className='font-semibold'>API Deployment Error</div>
625-
<div>{apiDeployError}</div>
618+
{activeTab === 'api' && (
619+
<>
620+
{isDeployed ? (
621+
<DeploymentInfo
622+
isLoading={isLoading}
623+
deploymentInfo={deploymentInfo}
624+
onRedeploy={handleRedeploy}
625+
onUndeploy={handleUndeploy}
626+
isSubmitting={isSubmitting}
627+
isUndeploying={isUndeploying}
628+
workflowId={workflowId}
629+
deployedState={deployedState}
630+
isLoadingDeployedState={isLoadingDeployedState}
631+
/>
632+
) : (
633+
<>
634+
{apiDeployError && (
635+
<div className='mb-4 rounded-md border border-destructive/30 bg-destructive/10 p-3 text-destructive text-sm'>
636+
<div className='font-semibold'>API Deployment Error</div>
637+
<div>{apiDeployError}</div>
638+
</div>
639+
)}
640+
<div className='-mx-1 px-1'>
641+
<DeployForm
642+
apiKeys={apiKeys}
643+
keysLoaded={keysLoaded}
644+
endpointUrl={`${env.NEXT_PUBLIC_APP_URL}/api/workflows/${workflowId}/execute`}
645+
workflowId={workflowId || ''}
646+
onSubmit={onDeploy}
647+
getInputFormatExample={getInputFormatExample}
648+
onApiKeyCreated={fetchApiKeys}
649+
/>
626650
</div>
627-
)}
628-
<div className='-mx-1 px-1'>
629-
<DeployForm
630-
apiKeys={apiKeys}
631-
keysLoaded={keysLoaded}
632-
endpointUrl={`${env.NEXT_PUBLIC_APP_URL}/api/workflows/${workflowId}/execute`}
633-
workflowId={workflowId || ''}
634-
onSubmit={onDeploy}
635-
getInputFormatExample={getInputFormatExample}
636-
onApiKeyCreated={fetchApiKeys}
637-
/>
638-
</div>
639-
</>
640-
))}
651+
</>
652+
)}
653+
</>
654+
)}
641655

642656
{activeTab === 'chat' && (
643657
<ChatDeploy

0 commit comments

Comments
 (0)