mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-06 03:00:16 -04:00
feat(workflow-block): added redeploy action to workflow header for workflow block (#1875)
This commit is contained in:
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user