Skip to content

Commit 0ed0a26

Browse files
authored
feat(workflow-block): added redeploy action to workflow header for workflow block (#1875)
1 parent 0d4d953 commit 0ed0a26

File tree

3 files changed

+72
-24
lines changed

3 files changed

+72
-24
lines changed

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/hooks/use-child-deployment.ts

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ export interface UseChildDeploymentReturn {
88
activeVersion: number | null
99
/** Whether the child workflow has an active deployment */
1010
isDeployed: boolean | null
11+
/** Whether the child workflow needs redeployment due to changes */
12+
needsRedeploy: boolean
1113
/** Whether the deployment information is currently being fetched */
1214
isLoading: boolean
1315
/** Function to manually refetch deployment status */
@@ -23,6 +25,7 @@ export interface UseChildDeploymentReturn {
2325
export function useChildDeployment(childWorkflowId: string | undefined): UseChildDeploymentReturn {
2426
const [activeVersion, setActiveVersion] = useState<number | null>(null)
2527
const [isDeployed, setIsDeployed] = useState<boolean | null>(null)
28+
const [needsRedeploy, setNeedsRedeploy] = useState(false)
2629
const [isLoading, setIsLoading] = useState(false)
2730
const [refetchTrigger, setRefetchTrigger] = useState(0)
2831

@@ -31,37 +34,60 @@ export function useChildDeployment(childWorkflowId: string | undefined): UseChil
3134

3235
try {
3336
setIsLoading(true)
34-
const res = await fetch(`/api/workflows/${wfId}/deployments`, {
35-
cache: 'no-store',
36-
headers: { 'Cache-Control': 'no-cache' },
37-
})
3837

39-
if (!res.ok) {
38+
// Fetch both deployment versions and workflow metadata in parallel
39+
const [deploymentsRes, workflowRes] = await Promise.all([
40+
fetch(`/api/workflows/${wfId}/deployments`, {
41+
cache: 'no-store',
42+
headers: { 'Cache-Control': 'no-cache' },
43+
}),
44+
fetch(`/api/workflows/${wfId}`, {
45+
cache: 'no-store',
46+
headers: { 'Cache-Control': 'no-cache' },
47+
}),
48+
])
49+
50+
if (!deploymentsRes.ok || !workflowRes.ok) {
4051
if (!cancelled) {
4152
setActiveVersion(null)
4253
setIsDeployed(null)
54+
setNeedsRedeploy(false)
4355
}
4456
return
4557
}
4658

47-
const json = await res.json()
48-
const versions = Array.isArray(json?.data?.versions)
49-
? json.data.versions
50-
: Array.isArray(json?.versions)
51-
? json.versions
59+
const deploymentsJson = await deploymentsRes.json()
60+
const workflowJson = await workflowRes.json()
61+
62+
const versions = Array.isArray(deploymentsJson?.data?.versions)
63+
? deploymentsJson.data.versions
64+
: Array.isArray(deploymentsJson?.versions)
65+
? deploymentsJson.versions
5266
: []
5367

5468
const active = versions.find((v: any) => v.isActive)
69+
const workflowUpdatedAt = workflowJson?.data?.updatedAt || workflowJson?.updatedAt
5570

5671
if (!cancelled) {
5772
const v = active ? Number(active.version) : null
73+
const deployed = v != null
5874
setActiveVersion(v)
59-
setIsDeployed(v != null) // true if deployed, false if undeployed
75+
setIsDeployed(deployed)
76+
77+
// Check if workflow has been updated since deployment
78+
if (deployed && active?.createdAt && workflowUpdatedAt) {
79+
const deploymentTime = new Date(active.createdAt).getTime()
80+
const updateTime = new Date(workflowUpdatedAt).getTime()
81+
setNeedsRedeploy(updateTime > deploymentTime)
82+
} else {
83+
setNeedsRedeploy(false)
84+
}
6085
}
6186
} catch {
6287
if (!cancelled) {
6388
setActiveVersion(null)
6489
setIsDeployed(null)
90+
setNeedsRedeploy(false)
6591
}
6692
} finally {
6793
if (!cancelled) setIsLoading(false)
@@ -78,6 +104,7 @@ export function useChildDeployment(childWorkflowId: string | undefined): UseChil
78104
} else {
79105
setActiveVersion(null)
80106
setIsDeployed(null)
107+
setNeedsRedeploy(false)
81108
}
82109
}, [childWorkflowId, refetchTrigger, fetchActiveVersion])
83110

@@ -88,6 +115,7 @@ export function useChildDeployment(childWorkflowId: string | undefined): UseChil
88115
return {
89116
activeVersion,
90117
isDeployed,
118+
needsRedeploy,
91119
isLoading,
92120
refetch,
93121
}

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/hooks/use-child-workflow.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ export interface UseChildWorkflowReturn {
1212
childActiveVersion: number | null
1313
/** Whether the child workflow is deployed */
1414
childIsDeployed: boolean | null
15+
/** Whether the child workflow needs redeployment due to changes */
16+
childNeedsRedeploy: boolean
1517
/** Whether the child version information is loading */
1618
isLoadingChildVersion: boolean
1719
/** Function to manually refetch deployment status */
@@ -54,6 +56,7 @@ export function useChildWorkflow(
5456
const {
5557
activeVersion: childActiveVersion,
5658
isDeployed: childIsDeployed,
59+
needsRedeploy: childNeedsRedeploy,
5760
isLoading: isLoadingChildVersion,
5861
refetch: refetchDeployment,
5962
} = useChildDeployment(isWorkflowSelector ? childWorkflowId : undefined)
@@ -62,6 +65,7 @@ export function useChildWorkflow(
6265
childWorkflowId,
6366
childActiveVersion,
6467
childIsDeployed,
68+
childNeedsRedeploy,
6569
isLoadingChildVersion,
6670
refetchDeployment,
6771
}

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

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -214,12 +214,8 @@ export const WorkflowBlock = memo(function WorkflowBlock({
214214
disableSchedule,
215215
} = useScheduleInfo(id, type, currentWorkflowId)
216216

217-
const { childWorkflowId, childIsDeployed, refetchDeployment } = useChildWorkflow(
218-
id,
219-
type,
220-
data.isPreview ?? false,
221-
data.subBlockValues
222-
)
217+
const { childWorkflowId, childIsDeployed, childNeedsRedeploy, refetchDeployment } =
218+
useChildWorkflow(id, type, data.isPreview ?? false, data.subBlockValues)
223219

224220
const [isDeploying, setIsDeploying] = useState(false)
225221
const setDeploymentStatus = useWorkflowRegistry((state) => state.setDeploymentStatus)
@@ -656,24 +652,44 @@ export const WorkflowBlock = memo(function WorkflowBlock({
656652
<Tooltip.Trigger asChild>
657653
<Badge
658654
variant='outline'
659-
className={!childIsDeployed ? 'cursor-pointer' : ''}
655+
className={!childIsDeployed || childNeedsRedeploy ? 'cursor-pointer' : ''}
660656
style={{
661-
borderColor: childIsDeployed ? '#22C55E' : '#EF4444',
662-
color: childIsDeployed ? '#22C55E' : '#EF4444',
657+
borderColor: !childIsDeployed
658+
? '#EF4444'
659+
: childNeedsRedeploy
660+
? '#FF6600'
661+
: '#22C55E',
662+
color: !childIsDeployed
663+
? '#EF4444'
664+
: childNeedsRedeploy
665+
? '#FF6600'
666+
: '#22C55E',
663667
}}
664668
onClick={(e) => {
665669
e.stopPropagation()
666-
if (!childIsDeployed && childWorkflowId && !isDeploying) {
670+
if (
671+
(!childIsDeployed || childNeedsRedeploy) &&
672+
childWorkflowId &&
673+
!isDeploying
674+
) {
667675
deployWorkflow(childWorkflowId)
668676
}
669677
}}
670678
>
671-
{isDeploying ? 'Deploying...' : childIsDeployed ? 'deployed' : 'undeployed'}
679+
{isDeploying
680+
? 'Deploying...'
681+
: !childIsDeployed
682+
? 'undeployed'
683+
: childNeedsRedeploy
684+
? 'redeploy'
685+
: 'deployed'}
672686
</Badge>
673687
</Tooltip.Trigger>
674-
{!childIsDeployed && (
688+
{(!childIsDeployed || childNeedsRedeploy) && (
675689
<Tooltip.Content>
676-
<span className='text-sm'>Click to deploy</span>
690+
<span className='text-sm'>
691+
{!childIsDeployed ? 'Click to deploy' : 'Click to redeploy'}
692+
</span>
677693
</Tooltip.Content>
678694
)}
679695
</Tooltip.Root>

0 commit comments

Comments
 (0)