|
@@ -421,6 +421,7 @@ function WorkflowEditorInner() {
|
|
|
pinExecution,
|
|
pinExecution,
|
|
|
unpinExecution,
|
|
unpinExecution,
|
|
|
setViewingExecution,
|
|
setViewingExecution,
|
|
|
|
|
+ recomputeChangeStatus,
|
|
|
} = useExecutionPinStore()
|
|
} = useExecutionPinStore()
|
|
|
|
|
|
|
|
// Effective execution state: uses pinned execution when available (viewing or pinned), otherwise live state
|
|
// Effective execution state: uses pinned execution when available (viewing or pinned), otherwise live state
|
|
@@ -571,6 +572,18 @@ function WorkflowEditorInner() {
|
|
|
setViewingExecution(false)
|
|
setViewingExecution(false)
|
|
|
}, [setViewingExecution])
|
|
}, [setViewingExecution])
|
|
|
|
|
|
|
|
|
|
+ // The pinned/unchanged-vs-changed diff is computed once at pin time. If the
|
|
|
|
|
+ // user keeps editing after pinning (a node is live-editable in Pinned-not-
|
|
|
|
|
+ // viewing mode), that diff goes stale - a node the user just changed would
|
|
|
|
|
+ // keep reading as "unchanged, pinned data available" until unpin/re-pin.
|
|
|
|
|
+ // Recompute it whenever the live graph changes while something is pinned.
|
|
|
|
|
+ useEffect(() => {
|
|
|
|
|
+ if (!pinnedExecution || isViewingExecution) return
|
|
|
|
|
+ const { currentNodes, currentConnections } = getCurrentWorkflowData()
|
|
|
|
|
+ recomputeChangeStatus(currentNodes, currentConnections)
|
|
|
|
|
+ // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
|
|
+ }, [nodes, edges, pinnedExecution, isViewingExecution])
|
|
|
|
|
+
|
|
|
const { data: workflow, isLoading: workflowLoading } = useQuery({
|
|
const { data: workflow, isLoading: workflowLoading } = useQuery({
|
|
|
queryKey: ['workflow', id],
|
|
queryKey: ['workflow', id],
|
|
|
queryFn: () => workflowsApi.get(id!),
|
|
queryFn: () => workflowsApi.get(id!),
|
|
@@ -3022,14 +3035,17 @@ function WorkflowEditorInner() {
|
|
|
edges={isViewingExecution && viewedEdges ? viewedEdges : edges}
|
|
edges={isViewingExecution && viewedEdges ? viewedEdges : edges}
|
|
|
expandedNodes={expandedNodes}
|
|
expandedNodes={expandedNodes}
|
|
|
selectedIterations={selectedIterations}
|
|
selectedIterations={selectedIterations}
|
|
|
|
|
+ isViewingExecution={isViewingExecution}
|
|
|
onClose={() => {
|
|
onClose={() => {
|
|
|
|
|
+ // Closing here means the same thing as the banner's "Return to
|
|
|
|
|
+ // Editor": stop looking at the read-only snapshot, but leave the
|
|
|
|
|
+ // pin alone. Clearing pinned data is a separate, deliberate
|
|
|
|
|
+ // action (the "Clear" control), reachable in every mode where
|
|
|
|
|
+ // something is pinned - not a side effect of closing this panel.
|
|
|
setShowExecutionPanel(false)
|
|
setShowExecutionPanel(false)
|
|
|
if (isViewingExecution) {
|
|
if (isViewingExecution) {
|
|
|
setViewingExecution(false)
|
|
setViewingExecution(false)
|
|
|
}
|
|
}
|
|
|
- if (pinnedExecution) {
|
|
|
|
|
- unpinExecution()
|
|
|
|
|
- }
|
|
|
|
|
}}
|
|
}}
|
|
|
onToggleNodeExpansion={toggleNodeExpansion}
|
|
onToggleNodeExpansion={toggleNodeExpansion}
|
|
|
onSelectIteration={(nodeId, index) => {
|
|
onSelectIteration={(nodeId, index) => {
|