Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export interface UseChildDeploymentReturn {
activeVersion: number | null
/** Whether the child workflow has an active deployment */
isDeployed: boolean | null
/** Whether the child workflow needs redeployment due to changes */
needsRedeploy: boolean
/** Whether the deployment information is currently being fetched */
isLoading: boolean
/** Function to manually refetch deployment status */
Expand All @@ -23,6 +25,7 @@ export interface UseChildDeploymentReturn {
export function useChildDeployment(childWorkflowId: string | undefined): UseChildDeploymentReturn {
const [activeVersion, setActiveVersion] = useState<number | null>(null)
const [isDeployed, setIsDeployed] = useState<boolean | null>(null)
const [needsRedeploy, setNeedsRedeploy] = useState(false)
const [isLoading, setIsLoading] = useState(false)
const [refetchTrigger, setRefetchTrigger] = useState(0)

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

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

if (!res.ok) {
// Fetch both deployment versions and workflow metadata in parallel
const [deploymentsRes, workflowRes] = await Promise.all([
fetch(`/api/workflows/${wfId}/deployments`, {
cache: 'no-store',
headers: { 'Cache-Control': 'no-cache' },
}),
fetch(`/api/workflows/${wfId}`, {
cache: 'no-store',
headers: { 'Cache-Control': 'no-cache' },
}),
])

if (!deploymentsRes.ok || !workflowRes.ok) {
if (!cancelled) {
setActiveVersion(null)
setIsDeployed(null)
setNeedsRedeploy(false)
}
return
}

const json = await res.json()
const versions = Array.isArray(json?.data?.versions)
? json.data.versions
: Array.isArray(json?.versions)
? json.versions
const deploymentsJson = await deploymentsRes.json()
const workflowJson = await workflowRes.json()

const versions = Array.isArray(deploymentsJson?.data?.versions)
? deploymentsJson.data.versions
: Array.isArray(deploymentsJson?.versions)
? deploymentsJson.versions
: []

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

if (!cancelled) {
const v = active ? Number(active.version) : null
const deployed = v != null
setActiveVersion(v)
setIsDeployed(v != null) // true if deployed, false if undeployed
setIsDeployed(deployed)

// Check if workflow has been updated since deployment
if (deployed && active?.createdAt && workflowUpdatedAt) {
const deploymentTime = new Date(active.createdAt).getTime()
const updateTime = new Date(workflowUpdatedAt).getTime()
setNeedsRedeploy(updateTime > deploymentTime)
} else {
setNeedsRedeploy(false)
}
}
} catch {
if (!cancelled) {
setActiveVersion(null)
setIsDeployed(null)
setNeedsRedeploy(false)
}
} finally {
if (!cancelled) setIsLoading(false)
Expand All @@ -78,6 +104,7 @@ export function useChildDeployment(childWorkflowId: string | undefined): UseChil
} else {
setActiveVersion(null)
setIsDeployed(null)
setNeedsRedeploy(false)
}
}, [childWorkflowId, refetchTrigger, fetchActiveVersion])

Expand All @@ -88,6 +115,7 @@ export function useChildDeployment(childWorkflowId: string | undefined): UseChil
return {
activeVersion,
isDeployed,
needsRedeploy,
isLoading,
refetch,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ export interface UseChildWorkflowReturn {
childActiveVersion: number | null
/** Whether the child workflow is deployed */
childIsDeployed: boolean | null
/** Whether the child workflow needs redeployment due to changes */
childNeedsRedeploy: boolean
/** Whether the child version information is loading */
isLoadingChildVersion: boolean
/** Function to manually refetch deployment status */
Expand Down Expand Up @@ -54,6 +56,7 @@ export function useChildWorkflow(
const {
activeVersion: childActiveVersion,
isDeployed: childIsDeployed,
needsRedeploy: childNeedsRedeploy,
isLoading: isLoadingChildVersion,
refetch: refetchDeployment,
} = useChildDeployment(isWorkflowSelector ? childWorkflowId : undefined)
Expand All @@ -62,6 +65,7 @@ export function useChildWorkflow(
childWorkflowId,
childActiveVersion,
childIsDeployed,
childNeedsRedeploy,
isLoadingChildVersion,
refetchDeployment,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,8 @@ export const WorkflowBlock = memo(function WorkflowBlock({
disableSchedule,
} = useScheduleInfo(id, type, currentWorkflowId)

const { childWorkflowId, childIsDeployed, refetchDeployment } = useChildWorkflow(
id,
type,
data.isPreview ?? false,
data.subBlockValues
)
const { childWorkflowId, childIsDeployed, childNeedsRedeploy, refetchDeployment } =
useChildWorkflow(id, type, data.isPreview ?? false, data.subBlockValues)

const [isDeploying, setIsDeploying] = useState(false)
const setDeploymentStatus = useWorkflowRegistry((state) => state.setDeploymentStatus)
Expand Down Expand Up @@ -656,24 +652,44 @@ export const WorkflowBlock = memo(function WorkflowBlock({
<Tooltip.Trigger asChild>
<Badge
variant='outline'
className={!childIsDeployed ? 'cursor-pointer' : ''}
className={!childIsDeployed || childNeedsRedeploy ? 'cursor-pointer' : ''}
style={{
borderColor: childIsDeployed ? '#22C55E' : '#EF4444',
color: childIsDeployed ? '#22C55E' : '#EF4444',
borderColor: !childIsDeployed
? '#EF4444'
: childNeedsRedeploy
? '#FF6600'
: '#22C55E',
color: !childIsDeployed
? '#EF4444'
: childNeedsRedeploy
? '#FF6600'
: '#22C55E',
}}
onClick={(e) => {
e.stopPropagation()
if (!childIsDeployed && childWorkflowId && !isDeploying) {
if (
(!childIsDeployed || childNeedsRedeploy) &&
childWorkflowId &&
!isDeploying
) {
deployWorkflow(childWorkflowId)
}
}}
>
{isDeploying ? 'Deploying...' : childIsDeployed ? 'deployed' : 'undeployed'}
{isDeploying
? 'Deploying...'
: !childIsDeployed
? 'undeployed'
: childNeedsRedeploy
? 'redeploy'
: 'deployed'}
</Badge>
</Tooltip.Trigger>
{!childIsDeployed && (
{(!childIsDeployed || childNeedsRedeploy) && (
<Tooltip.Content>
<span className='text-sm'>Click to deploy</span>
<span className='text-sm'>
{!childIsDeployed ? 'Click to deploy' : 'Click to redeploy'}
</span>
</Tooltip.Content>
)}
</Tooltip.Root>
Expand Down