feat(workflow-block): added redeploy action to workflow header for workflow block (#1875)

This commit is contained in:
Waleed
2025-11-10 15:59:33 -08:00
committed by GitHub
parent 0d4d953169
commit 0ed0a26b3b
3 changed files with 72 additions and 24 deletions

View File

@@ -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 */
@@ -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)
@@ -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)
@@ -78,6 +104,7 @@ export function useChildDeployment(childWorkflowId: string | undefined): UseChil
} else {
setActiveVersion(null)
setIsDeployed(null)
setNeedsRedeploy(false)
}
}, [childWorkflowId, refetchTrigger, fetchActiveVersion])
@@ -88,6 +115,7 @@ export function useChildDeployment(childWorkflowId: string | undefined): UseChil
return {
activeVersion,
isDeployed,
needsRedeploy,
isLoading,
refetch,
}

View File

@@ -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 */
@@ -54,6 +56,7 @@ export function useChildWorkflow(
const {
activeVersion: childActiveVersion,
isDeployed: childIsDeployed,
needsRedeploy: childNeedsRedeploy,
isLoading: isLoadingChildVersion,
refetch: refetchDeployment,
} = useChildDeployment(isWorkflowSelector ? childWorkflowId : undefined)
@@ -62,6 +65,7 @@ export function useChildWorkflow(
childWorkflowId,
childActiveVersion,
childIsDeployed,
childNeedsRedeploy,
isLoadingChildVersion,
refetchDeployment,
}

View File

@@ -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)
@@ -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>