@burdenoff/fluidgrids-fe-sdk 2026.925.2 → 2026.930.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ExecutionDetailPage-RK3KJ46E.js +12 -0
- package/dist/{ExecutionDetailPage-3ZJMNWBY.js.map → ExecutionDetailPage-RK3KJ46E.js.map} +1 -1
- package/dist/ExecutionsListPage-NXINADRN.js +11 -0
- package/dist/{ExecutionsListPage-FPNETFQX.js.map → ExecutionsListPage-NXINADRN.js.map} +1 -1
- package/dist/{WorkflowBuilder-IS2ZZ6JY.js → WorkflowBuilder-MAFYHWGY.js} +7 -7
- package/dist/{WorkflowBuilder-IS2ZZ6JY.js.map → WorkflowBuilder-MAFYHWGY.js.map} +1 -1
- package/dist/WorkflowsList-AFTTUUHX.js +13 -0
- package/dist/{WorkflowsList-GEPG3OZ6.js.map → WorkflowsList-AFTTUUHX.js.map} +1 -1
- package/dist/{chunk-UBKJDGYS.js → chunk-3P4YQ7DO.js} +57 -3
- package/dist/chunk-3P4YQ7DO.js.map +1 -0
- package/dist/chunk-5OZB7AQ4.js +9878 -0
- package/dist/chunk-5OZB7AQ4.js.map +1 -0
- package/dist/{chunk-A6PDDUMN.js → chunk-7SX5OWZR.js} +4 -4
- package/dist/{chunk-A6PDDUMN.js.map → chunk-7SX5OWZR.js.map} +1 -1
- package/dist/{chunk-QV6T4R4T.js → chunk-G3RPRMP5.js} +3 -3
- package/dist/{chunk-QV6T4R4T.js.map → chunk-G3RPRMP5.js.map} +1 -1
- package/dist/{chunk-H5LGKSBM.js → chunk-GKSXZFDY.js} +3 -3
- package/dist/{chunk-H5LGKSBM.js.map → chunk-GKSXZFDY.js.map} +1 -1
- package/dist/{chunk-ZZ3SFJXV.js → chunk-IJSJOTIZ.js} +4 -4
- package/dist/{chunk-ZZ3SFJXV.js.map → chunk-IJSJOTIZ.js.map} +1 -1
- package/dist/{chunk-T7FJ2TBD.js → chunk-NHZQE7ZB.js} +4 -4
- package/dist/{chunk-T7FJ2TBD.js.map → chunk-NHZQE7ZB.js.map} +1 -1
- package/dist/{chunk-YMD3T6J2.js → chunk-NTJTPYCD.js} +37 -4
- package/dist/chunk-NTJTPYCD.js.map +1 -0
- package/dist/{chunk-6DQDX6LD.js → chunk-ODOEVG2G.js} +5 -5
- package/dist/{chunk-6DQDX6LD.js.map → chunk-ODOEVG2G.js.map} +1 -1
- package/dist/{chunk-IOP2IBDV.js → chunk-R5ZYOIZG.js} +4 -4
- package/dist/{chunk-IOP2IBDV.js.map → chunk-R5ZYOIZG.js.map} +1 -1
- package/dist/{chunk-CGQG3QUR.js → chunk-T4BFEI3I.js} +5 -5
- package/dist/{chunk-CGQG3QUR.js.map → chunk-T4BFEI3I.js.map} +1 -1
- package/dist/{chunk-O4UTOCZJ.js → chunk-USFSPC6S.js} +3 -3
- package/dist/{chunk-O4UTOCZJ.js.map → chunk-USFSPC6S.js.map} +1 -1
- package/dist/{chunk-6SXISR7B.js → chunk-VG2BTLUN.js} +600 -93
- package/dist/chunk-VG2BTLUN.js.map +1 -0
- package/dist/{chunk-YQ4GDK4I.js → chunk-ZLYJKIKG.js} +3 -3
- package/dist/{chunk-YQ4GDK4I.js.map → chunk-ZLYJKIKG.js.map} +1 -1
- package/dist/executions.js +5 -5
- package/dist/history.js +3 -3
- package/dist/index.d.ts +82113 -35336
- package/dist/index.js +20 -20
- package/dist/index.js.map +1 -1
- package/dist/nodes.js +2 -2
- package/dist/settings.js +3 -3
- package/dist/templates.js +5 -5
- package/dist/{workflow-builder-Y7PcoT2O.d.ts → workflow-builder-DqInt43T.d.ts} +31 -2
- package/dist/workflow-builder.d.ts +1 -1
- package/dist/workflow-builder.js +6 -6
- package/dist/workflows-list.js +4 -4
- package/package.json +1 -1
- package/dist/ExecutionDetailPage-3ZJMNWBY.js +0 -12
- package/dist/ExecutionsListPage-FPNETFQX.js +0 -11
- package/dist/WorkflowsList-GEPG3OZ6.js +0 -13
- package/dist/chunk-6SXISR7B.js.map +0 -1
- package/dist/chunk-HCL5CCLH.js +0 -4940
- package/dist/chunk-HCL5CCLH.js.map +0 -1
- package/dist/chunk-UBKJDGYS.js.map +0 -1
- package/dist/chunk-YMD3T6J2.js.map +0 -1
|
@@ -7,10 +7,10 @@ import { GetMyNodeInstallationsDocument, BrowseWorkflowTemplatesDocument, Instal
|
|
|
7
7
|
import { QuotaExhaustedDialog } from './chunk-AANIWER2.js';
|
|
8
8
|
import { SdkPermissionGate, FLUIDGRIDS_PERMISSIONS, SdkPermissionButton } from './chunk-W23ZXNKU.js';
|
|
9
9
|
import { cn as cn$1 } from './chunk-3ZYUGTIT.js';
|
|
10
|
-
import { useWorkflowVersions, useRestoreWorkflowVersion, useActivateWorkflow, useDeleteWorkflow, useLazyWorkflowDefinition, useDeactivateWorkflow } from './chunk-
|
|
10
|
+
import { useWorkflowVersions, useRestoreWorkflowVersion, useActivateWorkflow, useDeleteWorkflow, useLazyWorkflowDefinition, useDeactivateWorkflow } from './chunk-GKSXZFDY.js';
|
|
11
11
|
import { config, getFluidGridsConfig, validateTrustedOrigin, setFluidGridsConfig, resetFluidGridsConfig } from './chunk-U4AJLVHA.js';
|
|
12
|
-
import { useFlowStore } from './chunk-
|
|
13
|
-
import { NodeEndpointConfigsDocument, NodeManifestDocument, UpdateWorkflowDefinitionDocument, CreateWorkflowDefinitionDocument, CreateWorkflowVersionDocument, TriggerWorkflowDocument, RunFromNodeDocument, ExecutionDetailDocument, WorkflowRunDocument, FluidgridsEntityTagsDocument, AvailableFluidgridsTagsDocument, SearchFluidgridsTagsDocument, TagFluidgridsEntityDocument, UntagFluidgridsEntityDocument, ReplaceFluidgridsEntityTagsDocument, CreateFluidgridsTagDocument, NodeSchemaIntrospectionDocument, useWorkflowPinnedDataQuery, usePinNodeDataMutation, useUnpinNodeDataMutation, EventRegistrationsDocument, NodeUsageStatusDocument, RemoveNodeFromWorkflowsDocument } from './chunk-
|
|
12
|
+
import { useFlowStore } from './chunk-NTJTPYCD.js';
|
|
13
|
+
import { NodeEndpointConfigsDocument, NodeManifestDocument, UpdateWorkflowDefinitionDocument, CreateWorkflowDefinitionDocument, CreateWorkflowVersionDocument, ExecuteStepDocument, TriggerWorkflowDocument, RunFromNodeDocument, ExecutionDetailDocument, WorkflowRunDocument, FluidgridsEntityTagsDocument, AvailableFluidgridsTagsDocument, SearchFluidgridsTagsDocument, TagFluidgridsEntityDocument, UntagFluidgridsEntityDocument, ReplaceFluidgridsEntityTagsDocument, CreateFluidgridsTagDocument, NodeSchemaIntrospectionDocument, useWorkflowPinnedDataQuery, usePinNodeDataMutation, useUnpinNodeDataMutation, useRunFromNodeEligibilityQuery, EventRegistrationsDocument, NodeUsageStatusDocument, RemoveNodeFromWorkflowsDocument } from './chunk-3P4YQ7DO.js';
|
|
14
14
|
import { throwIfResultError, describeOperationError } from './chunk-LMO5ASOE.js';
|
|
15
15
|
import { useTr, FluidGridsTranslationProvider, ENGLISH_FALLBACK_TRANSLATOR } from './chunk-7YWBH2A5.js';
|
|
16
16
|
import { waitForFluidGridsClient, getFluidGridsClient, getFluidGridsClientSafe, createFluidGridsClient, setFluidGridsClient, resetFluidGridsClient } from './chunk-5BDQNSP3.js';
|
|
@@ -3601,6 +3601,7 @@ function ConnectionSelector({
|
|
|
3601
3601
|
] });
|
|
3602
3602
|
}
|
|
3603
3603
|
var TRIGGER_WORKFLOW = TriggerWorkflowDocument;
|
|
3604
|
+
var EXECUTE_STEP = ExecuteStepDocument;
|
|
3604
3605
|
var WORKFLOW_RUN = WorkflowRunDocument;
|
|
3605
3606
|
var RUN_FROM_NODE = RunFromNodeDocument;
|
|
3606
3607
|
var EXECUTION_DETAIL = ExecutionDetailDocument;
|
|
@@ -3640,6 +3641,10 @@ function useNodeExecution() {
|
|
|
3640
3641
|
const startExecution = useFlowStore(
|
|
3641
3642
|
(s) => s.actions.execution.startExecution
|
|
3642
3643
|
);
|
|
3644
|
+
const setRunMetadata = useFlowStore(
|
|
3645
|
+
(s) => s.actions.execution.setRunMetadata
|
|
3646
|
+
);
|
|
3647
|
+
const setStepPlan = useFlowStore((s) => s.actions.execution.setStepPlan);
|
|
3643
3648
|
const addLog = useFlowStore((s) => s.actions.execution.addLog);
|
|
3644
3649
|
const updateLog = useFlowStore((s) => s.actions.execution.updateLog);
|
|
3645
3650
|
const setNodeStatus = useFlowStore((s) => s.actions.execution.setNodeStatus);
|
|
@@ -3803,6 +3808,11 @@ function useNodeExecution() {
|
|
|
3803
3808
|
}
|
|
3804
3809
|
return;
|
|
3805
3810
|
}
|
|
3811
|
+
setRunMetadata({
|
|
3812
|
+
runId,
|
|
3813
|
+
workflowKey: run.workflowKey,
|
|
3814
|
+
version: run.version
|
|
3815
|
+
});
|
|
3806
3816
|
if (run.nodeStates?.length) {
|
|
3807
3817
|
processNodeStates(runId, run.nodeStates);
|
|
3808
3818
|
}
|
|
@@ -3822,60 +3832,56 @@ function useNodeExecution() {
|
|
|
3822
3832
|
};
|
|
3823
3833
|
pollTimerRef.current = setTimeout(doPoll, 800);
|
|
3824
3834
|
},
|
|
3825
|
-
[processNodeStates, completeExecution, cleanup]
|
|
3835
|
+
[processNodeStates, completeExecution, cleanup, setRunMetadata]
|
|
3826
3836
|
);
|
|
3827
|
-
const
|
|
3828
|
-
async (
|
|
3829
|
-
const triggerNode = findTriggerNode();
|
|
3830
|
-
if (!triggerNode) {
|
|
3831
|
-
console.error("[useNodeExecution] No trigger node found in workflow");
|
|
3832
|
-
return { success: false, error: "No trigger node found" };
|
|
3833
|
-
}
|
|
3837
|
+
const executeStep = useCallback(
|
|
3838
|
+
async (nodeId) => {
|
|
3834
3839
|
cleanup();
|
|
3835
3840
|
clearLogs();
|
|
3836
3841
|
const workflowKey = workflow.workflowKey || workflow.id;
|
|
3837
3842
|
const version = workflow.version || "1.0.0";
|
|
3838
3843
|
if (!workflowKey) {
|
|
3839
3844
|
console.error(
|
|
3840
|
-
"[useNodeExecution] Workflow must be saved before execution. No workflowKey found."
|
|
3845
|
+
"[useNodeExecution] Workflow must be saved before step execution. No workflowKey found."
|
|
3841
3846
|
);
|
|
3842
3847
|
return {
|
|
3843
3848
|
success: false,
|
|
3844
3849
|
error: "Workflow must be saved before execution"
|
|
3845
3850
|
};
|
|
3846
3851
|
}
|
|
3847
|
-
setNodeStatus(
|
|
3852
|
+
setNodeStatus(nodeId, "running");
|
|
3848
3853
|
try {
|
|
3849
3854
|
const client = getFluidGridsClient();
|
|
3850
3855
|
const result = throwIfResultError(
|
|
3851
3856
|
await client.mutate({
|
|
3852
|
-
mutation:
|
|
3857
|
+
mutation: EXECUTE_STEP,
|
|
3853
3858
|
variables: {
|
|
3854
3859
|
input: {
|
|
3855
3860
|
workflowKey,
|
|
3856
3861
|
version,
|
|
3857
|
-
|
|
3858
|
-
triggerData: {},
|
|
3859
|
-
context: {},
|
|
3860
|
-
stopAtNodeId,
|
|
3861
|
-
// Step execution from the builder is always a manual/debug
|
|
3862
|
-
// run (BOFF-7511) — pinned node data only ever applies here,
|
|
3863
|
-
// never on a PRODUCTION trigger (webhook, schedule, API).
|
|
3864
|
-
mode: "TEST"
|
|
3862
|
+
nodeId
|
|
3865
3863
|
}
|
|
3866
3864
|
}
|
|
3867
3865
|
})
|
|
3868
3866
|
);
|
|
3869
|
-
const
|
|
3870
|
-
if (
|
|
3871
|
-
const backendRunId =
|
|
3872
|
-
startExecution(
|
|
3867
|
+
const stepResult = result.data?.executeStep;
|
|
3868
|
+
if (stepResult) {
|
|
3869
|
+
const backendRunId = stepResult.runId;
|
|
3870
|
+
startExecution(nodeId, backendRunId, {
|
|
3871
|
+
workflowKey: stepResult.workflowKey,
|
|
3872
|
+
version: stepResult.version
|
|
3873
|
+
});
|
|
3874
|
+
setStepPlan({
|
|
3875
|
+
runId: backendRunId,
|
|
3876
|
+
...stepResult.plan,
|
|
3877
|
+
sourceRunId: stepResult.plan.sourceRunId ?? null
|
|
3878
|
+
});
|
|
3873
3879
|
const initialLog = {
|
|
3874
|
-
id: `${backendRunId}-${
|
|
3880
|
+
id: `${backendRunId}-${nodeId}`,
|
|
3875
3881
|
runId: backendRunId,
|
|
3876
|
-
nodeId
|
|
3877
|
-
nodeType: workflow.nodes.find((
|
|
3878
|
-
nodeName: getNodeName(
|
|
3882
|
+
nodeId,
|
|
3883
|
+
nodeType: workflow.nodes.find((node) => node.id === nodeId)?.type || "unknown",
|
|
3884
|
+
nodeName: getNodeName(nodeId),
|
|
3879
3885
|
status: "running",
|
|
3880
3886
|
inputArgs: null,
|
|
3881
3887
|
output: null,
|
|
@@ -3886,21 +3892,21 @@ function useNodeExecution() {
|
|
|
3886
3892
|
};
|
|
3887
3893
|
addLog(initialLog);
|
|
3888
3894
|
pollRunUpdates(backendRunId);
|
|
3889
|
-
return { success: true, runId: backendRunId };
|
|
3895
|
+
return { success: true, runId: backendRunId, plan: stepResult.plan };
|
|
3890
3896
|
}
|
|
3891
|
-
console.error("[useNodeExecution] No result from
|
|
3892
|
-
setNodeStatus(
|
|
3893
|
-
return { success: false, error: "No result from
|
|
3897
|
+
console.error("[useNodeExecution] No result from executeStep");
|
|
3898
|
+
setNodeStatus(nodeId, "error");
|
|
3899
|
+
return { success: false, error: "No result from executeStep" };
|
|
3894
3900
|
} catch (error) {
|
|
3895
|
-
console.error("[useNodeExecution] Error
|
|
3901
|
+
console.error("[useNodeExecution] Error executing step:", error);
|
|
3896
3902
|
const errorMessage = describeOperationError(error);
|
|
3897
3903
|
const errorRunId = nanoid$1();
|
|
3898
3904
|
const errorLog = {
|
|
3899
|
-
id: `${errorRunId}-${
|
|
3905
|
+
id: `${errorRunId}-${nodeId}`,
|
|
3900
3906
|
runId: errorRunId,
|
|
3901
|
-
nodeId
|
|
3902
|
-
nodeType: workflow.nodes.find((
|
|
3903
|
-
nodeName: getNodeName(
|
|
3907
|
+
nodeId,
|
|
3908
|
+
nodeType: workflow.nodes.find((node) => node.id === nodeId)?.type || "unknown",
|
|
3909
|
+
nodeName: getNodeName(nodeId),
|
|
3904
3910
|
status: "failed",
|
|
3905
3911
|
inputArgs: null,
|
|
3906
3912
|
output: null,
|
|
@@ -3910,16 +3916,16 @@ function useNodeExecution() {
|
|
|
3910
3916
|
endTime: (/* @__PURE__ */ new Date()).toISOString()
|
|
3911
3917
|
};
|
|
3912
3918
|
addLog(errorLog);
|
|
3913
|
-
setNodeStatus(
|
|
3919
|
+
setNodeStatus(nodeId, "error");
|
|
3914
3920
|
completeExecution();
|
|
3915
3921
|
return { success: false, error: errorMessage };
|
|
3916
3922
|
}
|
|
3917
3923
|
},
|
|
3918
3924
|
[
|
|
3919
|
-
findTriggerNode,
|
|
3920
3925
|
cleanup,
|
|
3921
3926
|
clearLogs,
|
|
3922
3927
|
startExecution,
|
|
3928
|
+
setStepPlan,
|
|
3923
3929
|
workflow,
|
|
3924
3930
|
getNodeName,
|
|
3925
3931
|
addLog,
|
|
@@ -3961,8 +3967,9 @@ function useNodeExecution() {
|
|
|
3961
3967
|
triggerNodeId: triggerNode.id,
|
|
3962
3968
|
triggerData: customTriggerData || {},
|
|
3963
3969
|
context: {},
|
|
3964
|
-
// Builder "Test workflow" is always a manual/debug run
|
|
3965
|
-
//
|
|
3970
|
+
// Builder "Test workflow" is always a manual/debug run.
|
|
3971
|
+
// Pinned node data only applies to TEST executions, never a
|
|
3972
|
+
// production trigger (webhook, schedule, API).
|
|
3966
3973
|
mode: "TEST"
|
|
3967
3974
|
}
|
|
3968
3975
|
}
|
|
@@ -3971,7 +3978,10 @@ function useNodeExecution() {
|
|
|
3971
3978
|
const triggerResult = result.data?.triggerWorkflow;
|
|
3972
3979
|
if (triggerResult) {
|
|
3973
3980
|
const backendRunId = triggerResult.runId;
|
|
3974
|
-
startExecution(triggerNode.id, backendRunId
|
|
3981
|
+
startExecution(triggerNode.id, backendRunId, {
|
|
3982
|
+
workflowKey: triggerResult.workflowKey,
|
|
3983
|
+
version: triggerResult.version
|
|
3984
|
+
});
|
|
3975
3985
|
pollRunUpdates(backendRunId);
|
|
3976
3986
|
return { success: true, runId: backendRunId };
|
|
3977
3987
|
}
|
|
@@ -4030,7 +4040,7 @@ function useNodeExecution() {
|
|
|
4030
4040
|
sourceRunId,
|
|
4031
4041
|
nodeId,
|
|
4032
4042
|
// Run-from-node is a debug affordance — always TEST, same
|
|
4033
|
-
// rule as
|
|
4043
|
+
// rule as the other builder debug execution paths.
|
|
4034
4044
|
mode: "TEST"
|
|
4035
4045
|
}
|
|
4036
4046
|
}
|
|
@@ -4039,7 +4049,10 @@ function useNodeExecution() {
|
|
|
4039
4049
|
const runFromNodeResult = result.data?.runFromNode;
|
|
4040
4050
|
if (runFromNodeResult) {
|
|
4041
4051
|
const backendRunId = runFromNodeResult.runId;
|
|
4042
|
-
startExecution(nodeId, backendRunId
|
|
4052
|
+
startExecution(nodeId, backendRunId, {
|
|
4053
|
+
workflowKey: runFromNodeResult.workflowKey,
|
|
4054
|
+
version: runFromNodeResult.version
|
|
4055
|
+
});
|
|
4043
4056
|
pollRunUpdates(backendRunId);
|
|
4044
4057
|
return { success: true, runId: backendRunId };
|
|
4045
4058
|
}
|
|
@@ -4099,7 +4112,10 @@ function useNodeExecution() {
|
|
|
4099
4112
|
reusedFromRunId: nodeState.reusedFromRunId ?? null
|
|
4100
4113
|
};
|
|
4101
4114
|
});
|
|
4102
|
-
loadDebugRun(runId, logs
|
|
4115
|
+
loadDebugRun(runId, logs, {
|
|
4116
|
+
workflowKey: run.workflowKey,
|
|
4117
|
+
version: run.version
|
|
4118
|
+
});
|
|
4103
4119
|
return { success: true, runId };
|
|
4104
4120
|
} catch (error) {
|
|
4105
4121
|
console.error("[useNodeExecution] Error loading execution:", error);
|
|
@@ -4117,7 +4133,7 @@ function useNodeExecution() {
|
|
|
4117
4133
|
};
|
|
4118
4134
|
}, [cleanup, completeExecution]);
|
|
4119
4135
|
return {
|
|
4120
|
-
|
|
4136
|
+
executeStep,
|
|
4121
4137
|
executeFullWorkflow,
|
|
4122
4138
|
executeFromNode,
|
|
4123
4139
|
loadExecution,
|
|
@@ -6665,7 +6681,7 @@ var getNodeMetadata = (value) => {
|
|
|
6665
6681
|
return updated;
|
|
6666
6682
|
});
|
|
6667
6683
|
}, [nodeType, id, edges, data, setNodes, zustandSetNodes]);
|
|
6668
|
-
const {
|
|
6684
|
+
const { executeStep } = useNodeExecution();
|
|
6669
6685
|
const deleteNode = useDeleteNode();
|
|
6670
6686
|
const handleDeleteNode = () => {
|
|
6671
6687
|
deleteNode(id);
|
|
@@ -6723,11 +6739,11 @@ var getNodeMetadata = (value) => {
|
|
|
6723
6739
|
openNdv({ nodeId: id, type: value?.type });
|
|
6724
6740
|
}, [id, openNdv]);
|
|
6725
6741
|
const handleExecuteStep = useCallback(() => {
|
|
6726
|
-
|
|
6742
|
+
executeStep(id).then((_result) => {
|
|
6727
6743
|
}).catch((error) => {
|
|
6728
|
-
console.error("[NodeComponent] Execute error:", error);
|
|
6744
|
+
console.error("[NodeComponent] Execute step error:", error);
|
|
6729
6745
|
});
|
|
6730
|
-
}, [
|
|
6746
|
+
}, [executeStep, id]);
|
|
6731
6747
|
const missingCredentials = useMemo(() => {
|
|
6732
6748
|
const visibleAdapters = getVisibleConnectionAdapters(
|
|
6733
6749
|
String(value?.type ?? ""),
|
|
@@ -23831,6 +23847,335 @@ function useMediaQuery(query) {
|
|
|
23831
23847
|
}, [query]);
|
|
23832
23848
|
return matches;
|
|
23833
23849
|
}
|
|
23850
|
+
|
|
23851
|
+
// src/builder/lib/continuation.ts
|
|
23852
|
+
var BLOCKED = {
|
|
23853
|
+
eligible: false,
|
|
23854
|
+
action: null,
|
|
23855
|
+
blockers: [],
|
|
23856
|
+
blockerReason: null,
|
|
23857
|
+
reason: null
|
|
23858
|
+
};
|
|
23859
|
+
function blocked(blockerReason, reason, blockers = [], targetStatus = null) {
|
|
23860
|
+
return {
|
|
23861
|
+
...BLOCKED,
|
|
23862
|
+
targetStatus,
|
|
23863
|
+
blockerReason,
|
|
23864
|
+
blockers,
|
|
23865
|
+
reason
|
|
23866
|
+
};
|
|
23867
|
+
}
|
|
23868
|
+
function sourceMetadata(input) {
|
|
23869
|
+
const source = input.sourceRun;
|
|
23870
|
+
return {
|
|
23871
|
+
runId: source?.runId ?? input.sourceRunId ?? null,
|
|
23872
|
+
workflowKey: source?.workflowKey ?? input.sourceRunWorkflowKey ?? null,
|
|
23873
|
+
version: source?.version ?? source?.workflowVersion ?? input.sourceRunVersion ?? null
|
|
23874
|
+
};
|
|
23875
|
+
}
|
|
23876
|
+
function getContinuationEligibility(input) {
|
|
23877
|
+
const source = sourceMetadata(input);
|
|
23878
|
+
if (!source.runId) {
|
|
23879
|
+
return blocked(
|
|
23880
|
+
"missing-source-run",
|
|
23881
|
+
"Load a completed or failed run before continuing from this node."
|
|
23882
|
+
);
|
|
23883
|
+
}
|
|
23884
|
+
if (!source.workflowKey || !source.version || source.workflowKey !== input.workflowKey || source.version !== input.workflowVersion) {
|
|
23885
|
+
return blocked(
|
|
23886
|
+
"incompatible-source-run",
|
|
23887
|
+
"The selected run belongs to a different workflow version."
|
|
23888
|
+
);
|
|
23889
|
+
}
|
|
23890
|
+
const nodeIds = new Set(input.nodes.map((node) => node.id));
|
|
23891
|
+
if (!nodeIds.has(input.targetNodeId)) {
|
|
23892
|
+
return blocked(
|
|
23893
|
+
"missing-target",
|
|
23894
|
+
"The selected node is not present in this workflow.",
|
|
23895
|
+
[input.targetNodeId]
|
|
23896
|
+
);
|
|
23897
|
+
}
|
|
23898
|
+
const logsByNode = /* @__PURE__ */ new Map();
|
|
23899
|
+
for (const log of input.logs) {
|
|
23900
|
+
if (log.runId === source.runId) logsByNode.set(log.nodeId, log);
|
|
23901
|
+
}
|
|
23902
|
+
const targetLog = logsByNode.get(input.targetNodeId);
|
|
23903
|
+
const targetStatus = targetLog?.status?.toLowerCase() ?? null;
|
|
23904
|
+
const action = targetStatus === "failed" ? "retry" : targetStatus === null || targetStatus === "completed" ? "continue" : null;
|
|
23905
|
+
if (!action) {
|
|
23906
|
+
return blocked(
|
|
23907
|
+
"target-not-terminal",
|
|
23908
|
+
"Continue is available only for completed or failed nodes.",
|
|
23909
|
+
[input.targetNodeId],
|
|
23910
|
+
targetStatus
|
|
23911
|
+
);
|
|
23912
|
+
}
|
|
23913
|
+
const predecessors = /* @__PURE__ */ new Map();
|
|
23914
|
+
for (const edge of input.edges) {
|
|
23915
|
+
const parents = predecessors.get(edge.target) ?? [];
|
|
23916
|
+
if (!parents.includes(edge.source)) parents.push(edge.source);
|
|
23917
|
+
predecessors.set(edge.target, parents);
|
|
23918
|
+
}
|
|
23919
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
23920
|
+
const cycleNodes = /* @__PURE__ */ new Set();
|
|
23921
|
+
const visiting = /* @__PURE__ */ new Set([input.targetNodeId]);
|
|
23922
|
+
const visited = /* @__PURE__ */ new Set();
|
|
23923
|
+
const visitAncestor = (nodeId) => {
|
|
23924
|
+
if (visiting.has(nodeId)) {
|
|
23925
|
+
cycleNodes.add(nodeId);
|
|
23926
|
+
return;
|
|
23927
|
+
}
|
|
23928
|
+
if (visited.has(nodeId)) return;
|
|
23929
|
+
ancestors.add(nodeId);
|
|
23930
|
+
visiting.add(nodeId);
|
|
23931
|
+
for (const parentId of predecessors.get(nodeId) ?? []) {
|
|
23932
|
+
visitAncestor(parentId);
|
|
23933
|
+
}
|
|
23934
|
+
visiting.delete(nodeId);
|
|
23935
|
+
visited.add(nodeId);
|
|
23936
|
+
};
|
|
23937
|
+
for (const parentId of predecessors.get(input.targetNodeId) ?? []) {
|
|
23938
|
+
visitAncestor(parentId);
|
|
23939
|
+
}
|
|
23940
|
+
if (cycleNodes.size > 0) {
|
|
23941
|
+
return blocked(
|
|
23942
|
+
"cycle",
|
|
23943
|
+
"This workflow has a cycle upstream of the selected node, so continuation is disabled.",
|
|
23944
|
+
[...cycleNodes].sort(),
|
|
23945
|
+
targetStatus
|
|
23946
|
+
);
|
|
23947
|
+
}
|
|
23948
|
+
for (const ancestorId of ancestors) {
|
|
23949
|
+
if (!nodeIds.has(ancestorId) || !logsByNode.has(ancestorId)) {
|
|
23950
|
+
return blocked(
|
|
23951
|
+
"missing-ancestor-log",
|
|
23952
|
+
"Every upstream node must have a result in the selected run.",
|
|
23953
|
+
[ancestorId],
|
|
23954
|
+
targetStatus
|
|
23955
|
+
);
|
|
23956
|
+
}
|
|
23957
|
+
const ancestor = logsByNode.get(ancestorId);
|
|
23958
|
+
if (ancestor?.status.toLowerCase() !== "completed") {
|
|
23959
|
+
return blocked(
|
|
23960
|
+
"ancestor-not-completed",
|
|
23961
|
+
"Every upstream node must be completed before continuing.",
|
|
23962
|
+
[ancestorId],
|
|
23963
|
+
targetStatus
|
|
23964
|
+
);
|
|
23965
|
+
}
|
|
23966
|
+
if (ancestor.output == null) {
|
|
23967
|
+
return blocked(
|
|
23968
|
+
"ancestor-missing-output",
|
|
23969
|
+
"Every completed upstream node must have output data before continuing.",
|
|
23970
|
+
[ancestorId],
|
|
23971
|
+
targetStatus
|
|
23972
|
+
);
|
|
23973
|
+
}
|
|
23974
|
+
}
|
|
23975
|
+
return {
|
|
23976
|
+
eligible: true,
|
|
23977
|
+
action,
|
|
23978
|
+
targetStatus,
|
|
23979
|
+
blockers: [],
|
|
23980
|
+
blockerReason: null,
|
|
23981
|
+
reason: null
|
|
23982
|
+
};
|
|
23983
|
+
}
|
|
23984
|
+
function NodeExecutionActions({
|
|
23985
|
+
targetNodeId,
|
|
23986
|
+
nodes,
|
|
23987
|
+
edges,
|
|
23988
|
+
logs,
|
|
23989
|
+
workflowKey,
|
|
23990
|
+
workflowVersion,
|
|
23991
|
+
sourceRun,
|
|
23992
|
+
onExecuteStep,
|
|
23993
|
+
onContinueFromNode,
|
|
23994
|
+
isExecuting = false,
|
|
23995
|
+
className,
|
|
23996
|
+
testIdPrefix = "node-execution"
|
|
23997
|
+
}) {
|
|
23998
|
+
const tr = useTr();
|
|
23999
|
+
const [pendingAction, setPendingAction] = useState(null);
|
|
24000
|
+
const localEligibility = useMemo(
|
|
24001
|
+
() => getContinuationEligibility({
|
|
24002
|
+
nodes,
|
|
24003
|
+
edges,
|
|
24004
|
+
logs,
|
|
24005
|
+
targetNodeId,
|
|
24006
|
+
workflowKey,
|
|
24007
|
+
workflowVersion,
|
|
24008
|
+
sourceRun
|
|
24009
|
+
}),
|
|
24010
|
+
[nodes, edges, logs, targetNodeId, workflowKey, workflowVersion, sourceRun]
|
|
24011
|
+
);
|
|
24012
|
+
const queryIdentity = `${sourceRun?.runId ?? ""}:${targetNodeId}`;
|
|
24013
|
+
const sourceStateVersion = useMemo(
|
|
24014
|
+
() => logs.filter((log) => !sourceRun || log.runId === sourceRun.runId).map(
|
|
24015
|
+
(log) => `${log.nodeId}:${log.status}:${log.output == null ? "empty" : "ready"}`
|
|
24016
|
+
).sort().join("|"),
|
|
24017
|
+
[logs, sourceRun]
|
|
24018
|
+
);
|
|
24019
|
+
const queryIdentityRef = useRef(queryIdentity);
|
|
24020
|
+
const {
|
|
24021
|
+
data: eligibilityData,
|
|
24022
|
+
loading: eligibilityLoading,
|
|
24023
|
+
error: eligibilityError,
|
|
24024
|
+
refetch: refetchEligibility
|
|
24025
|
+
} = useRunFromNodeEligibilityQuery({
|
|
24026
|
+
variables: {
|
|
24027
|
+
input: {
|
|
24028
|
+
sourceRunId: sourceRun?.runId ?? "",
|
|
24029
|
+
nodeId: targetNodeId
|
|
24030
|
+
}
|
|
24031
|
+
},
|
|
24032
|
+
skip: !sourceRun,
|
|
24033
|
+
fetchPolicy: "network-only",
|
|
24034
|
+
nextFetchPolicy: "network-only"
|
|
24035
|
+
});
|
|
24036
|
+
useEffect(() => {
|
|
24037
|
+
if (!sourceRun) {
|
|
24038
|
+
queryIdentityRef.current = queryIdentity;
|
|
24039
|
+
return;
|
|
24040
|
+
}
|
|
24041
|
+
if (queryIdentityRef.current !== queryIdentity) {
|
|
24042
|
+
queryIdentityRef.current = queryIdentity;
|
|
24043
|
+
return;
|
|
24044
|
+
}
|
|
24045
|
+
void refetchEligibility();
|
|
24046
|
+
}, [queryIdentity, refetchEligibility, sourceRun?.runId, sourceStateVersion]);
|
|
24047
|
+
const serverEligibility = sourceRun && !eligibilityLoading && !eligibilityError && eligibilityData?.runFromNodeEligibility ? (() => {
|
|
24048
|
+
const result = eligibilityData.runFromNodeEligibility;
|
|
24049
|
+
const targetStatus = result.targetStatus?.toLowerCase() ?? null;
|
|
24050
|
+
return {
|
|
24051
|
+
eligible: result.eligible,
|
|
24052
|
+
action: targetStatus === "failed" ? "retry" : result.eligible ? "continue" : null,
|
|
24053
|
+
targetStatus,
|
|
24054
|
+
blockers: result.blockedNodeIds.length ? result.blockedNodeIds : result.blockers,
|
|
24055
|
+
blockerReason: null,
|
|
24056
|
+
reason: result.reason ?? null
|
|
24057
|
+
};
|
|
24058
|
+
})() : null;
|
|
24059
|
+
const eligibility = sourceRun ? serverEligibility ?? {
|
|
24060
|
+
eligible: false,
|
|
24061
|
+
action: null,
|
|
24062
|
+
reason: eligibilityError ? tr(
|
|
24063
|
+
"fluidgrids.builder.nodeExecutionActions.queryError",
|
|
24064
|
+
"Unable to verify continuation readiness. Try loading the run again."
|
|
24065
|
+
) : tr(
|
|
24066
|
+
"fluidgrids.builder.nodeExecutionActions.checking",
|
|
24067
|
+
"Checking continuation readiness\u2026"
|
|
24068
|
+
)
|
|
24069
|
+
} : localEligibility;
|
|
24070
|
+
const runAction = async (action, callback) => {
|
|
24071
|
+
setPendingAction(action);
|
|
24072
|
+
try {
|
|
24073
|
+
await callback();
|
|
24074
|
+
} finally {
|
|
24075
|
+
setPendingAction(null);
|
|
24076
|
+
}
|
|
24077
|
+
};
|
|
24078
|
+
const executePending = pendingAction === "execute" || isExecuting;
|
|
24079
|
+
const continuePending = pendingAction === "continue";
|
|
24080
|
+
const continuationLabel = eligibility.action === "retry" ? tr(
|
|
24081
|
+
"fluidgrids.builder.nodeExecutionActions.retryFromHere",
|
|
24082
|
+
"Retry from here"
|
|
24083
|
+
) : tr(
|
|
24084
|
+
"fluidgrids.builder.nodeExecutionActions.continueFromHere",
|
|
24085
|
+
"Continue from here"
|
|
24086
|
+
);
|
|
24087
|
+
const blockerLabel = eligibility.reason ? tr(
|
|
24088
|
+
"fluidgrids.builder.nodeExecutionActions.blocked",
|
|
24089
|
+
"Unavailable: {{reason}}",
|
|
24090
|
+
{ reason: eligibility.reason }
|
|
24091
|
+
) : tr(
|
|
24092
|
+
"fluidgrids.builder.nodeExecutionActions.noSourceRun",
|
|
24093
|
+
"Load a run to enable continuation."
|
|
24094
|
+
);
|
|
24095
|
+
return /* @__PURE__ */ jsxs(
|
|
24096
|
+
"section",
|
|
24097
|
+
{
|
|
24098
|
+
className: cn(
|
|
24099
|
+
"shrink-0 border-t border-border bg-muted/20 px-3 py-2",
|
|
24100
|
+
className
|
|
24101
|
+
),
|
|
24102
|
+
"aria-label": tr(
|
|
24103
|
+
"fluidgrids.builder.nodeExecutionActions.ariaLabel",
|
|
24104
|
+
"Node execution actions"
|
|
24105
|
+
),
|
|
24106
|
+
"data-testid": `${testIdPrefix}-execution-actions`,
|
|
24107
|
+
children: [
|
|
24108
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
24109
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-semibold uppercase tracking-[0.12em] text-muted-foreground", children: tr("fluidgrids.builder.nodeExecutionActions.heading", "Execution") }),
|
|
24110
|
+
/* @__PURE__ */ jsxs(
|
|
24111
|
+
"button",
|
|
24112
|
+
{
|
|
24113
|
+
type: "button",
|
|
24114
|
+
onClick: () => {
|
|
24115
|
+
void runAction("execute", () => onExecuteStep(targetNodeId));
|
|
24116
|
+
},
|
|
24117
|
+
disabled: executePending || continuePending,
|
|
24118
|
+
title: tr(
|
|
24119
|
+
"fluidgrids.builder.nodeExecutionActions.executeStepHint",
|
|
24120
|
+
"Run only this node as a fresh TEST execution."
|
|
24121
|
+
),
|
|
24122
|
+
className: "inline-flex items-center gap-1 rounded-md border border-border bg-background px-2 py-1 text-xs font-medium text-foreground transition-colors hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
24123
|
+
"data-testid": `${testIdPrefix}-execute-step`,
|
|
24124
|
+
children: [
|
|
24125
|
+
/* @__PURE__ */ jsx(
|
|
24126
|
+
Icon,
|
|
24127
|
+
{
|
|
24128
|
+
icon: executePending ? "svg-spinners:ring-resize" : "mdi:play",
|
|
24129
|
+
className: "size-3.5"
|
|
24130
|
+
}
|
|
24131
|
+
),
|
|
24132
|
+
tr(
|
|
24133
|
+
"fluidgrids.builder.nodeExecutionActions.executeStep",
|
|
24134
|
+
"Execute step"
|
|
24135
|
+
)
|
|
24136
|
+
]
|
|
24137
|
+
}
|
|
24138
|
+
),
|
|
24139
|
+
/* @__PURE__ */ jsxs(
|
|
24140
|
+
"button",
|
|
24141
|
+
{
|
|
24142
|
+
type: "button",
|
|
24143
|
+
onClick: () => {
|
|
24144
|
+
if (!eligibility.eligible || !sourceRun) return;
|
|
24145
|
+
void runAction(
|
|
24146
|
+
"continue",
|
|
24147
|
+
() => onContinueFromNode(sourceRun.runId, targetNodeId)
|
|
24148
|
+
);
|
|
24149
|
+
},
|
|
24150
|
+
disabled: !eligibility.eligible || !sourceRun || executePending || continuePending,
|
|
24151
|
+
title: eligibility.eligible ? continuationLabel : blockerLabel,
|
|
24152
|
+
className: "inline-flex items-center gap-1 rounded-md border border-primary/30 bg-primary/5 px-2 py-1 text-xs font-medium text-primary transition-colors hover:bg-primary/10 disabled:cursor-not-allowed disabled:opacity-50",
|
|
24153
|
+
"data-testid": `${testIdPrefix}-continue-from-here`,
|
|
24154
|
+
children: [
|
|
24155
|
+
/* @__PURE__ */ jsx(
|
|
24156
|
+
Icon,
|
|
24157
|
+
{
|
|
24158
|
+
icon: continuePending ? "svg-spinners:ring-resize" : "mdi:skip-forward",
|
|
24159
|
+
className: "size-3.5"
|
|
24160
|
+
}
|
|
24161
|
+
),
|
|
24162
|
+
continuePending ? tr("fluidgrids.builder.nodeExecutionActions.running", "Running\u2026") : continuationLabel
|
|
24163
|
+
]
|
|
24164
|
+
}
|
|
24165
|
+
)
|
|
24166
|
+
] }),
|
|
24167
|
+
!eligibility.eligible && /* @__PURE__ */ jsx(
|
|
24168
|
+
"p",
|
|
24169
|
+
{
|
|
24170
|
+
className: "mt-1 text-[10px] leading-snug text-muted-foreground",
|
|
24171
|
+
"data-testid": `${testIdPrefix}-continuation-blocker`,
|
|
24172
|
+
children: blockerLabel
|
|
24173
|
+
}
|
|
24174
|
+
)
|
|
24175
|
+
]
|
|
24176
|
+
}
|
|
24177
|
+
);
|
|
24178
|
+
}
|
|
23834
24179
|
var SECTION_LABEL5 = "text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground";
|
|
23835
24180
|
function NodeDetailView() {
|
|
23836
24181
|
const tr = useTr();
|
|
@@ -23856,11 +24201,20 @@ function NodeDetailView() {
|
|
|
23856
24201
|
const [inputView, setInputView] = useState("schema");
|
|
23857
24202
|
const executionLogs = useFlowStore((s) => s.execution.logs);
|
|
23858
24203
|
const currentRunId = useFlowStore((s) => s.execution.currentRunId);
|
|
24204
|
+
const sourceRun = useFlowStore((s) => s.execution.sourceRun);
|
|
24205
|
+
const isExecuting = useFlowStore((s) => s.execution.isExecuting);
|
|
24206
|
+
const workflowNodes = useFlowStore((s) => s.workflow.nodes);
|
|
24207
|
+
const workflowEdges = useFlowStore((s) => s.workflow.edges);
|
|
24208
|
+
const workflowKey = useFlowStore((s) => s.workflow.workflowKey);
|
|
24209
|
+
const workflowId = useFlowStore((s) => s.workflow.id);
|
|
24210
|
+
const workflowVersion = useFlowStore((s) => s.workflow.version);
|
|
24211
|
+
const stepPlan = useFlowStore((s) => s.execution.stepPlan);
|
|
23859
24212
|
const nodeLog = useMemo(() => {
|
|
23860
24213
|
if (!ndv?.nodeId) return null;
|
|
23861
24214
|
const matches = executionLogs.filter((l) => l.nodeId === ndv.nodeId);
|
|
23862
24215
|
return matches.length > 0 ? matches[matches.length - 1] : null;
|
|
23863
24216
|
}, [executionLogs, ndv?.nodeId]);
|
|
24217
|
+
const stepPlanForNode = stepPlan?.runId === currentRunId && stepPlan.targetNodeId === ndv?.nodeId ? stepPlan : null;
|
|
23864
24218
|
const hasRealOutput = !!nodeLog?.output && Object.keys(nodeLog.output).length > 0;
|
|
23865
24219
|
const hasRealInput = !!nodeLog?.inputArgs && Object.keys(nodeLog.inputArgs).length > 0;
|
|
23866
24220
|
const realOutputFields = useMemo(
|
|
@@ -23899,18 +24253,7 @@ function NodeDetailView() {
|
|
|
23899
24253
|
console.error("[NodeDetailView] Failed to toggle pinned data", err);
|
|
23900
24254
|
}
|
|
23901
24255
|
};
|
|
23902
|
-
const { executeFromNode } = useNodeExecution();
|
|
23903
|
-
const [runningFromHere, setRunningFromHere] = useState(false);
|
|
23904
|
-
const canRunFromHere = !!currentRunId && nodeLog?.status === "completed";
|
|
23905
|
-
const runFromHere = async () => {
|
|
23906
|
-
if (!currentRunId || !ndv?.nodeId) return;
|
|
23907
|
-
setRunningFromHere(true);
|
|
23908
|
-
try {
|
|
23909
|
-
await executeFromNode(currentRunId, ndv.nodeId);
|
|
23910
|
-
} finally {
|
|
23911
|
-
setRunningFromHere(false);
|
|
23912
|
-
}
|
|
23913
|
-
};
|
|
24256
|
+
const { executeStep, executeFromNode } = useNodeExecution();
|
|
23914
24257
|
const threePaneLayout = useMediaQuery("(min-width: 1024px)");
|
|
23915
24258
|
const [pane, setPane] = useState("parameters");
|
|
23916
24259
|
const panesRef = useRef(null);
|
|
@@ -23972,33 +24315,6 @@ function NodeDetailView() {
|
|
|
23972
24315
|
/* @__PURE__ */ jsx(DialogTitle, { className: "truncate text-sm font-semibold leading-tight", children: nodeTitle(node) }),
|
|
23973
24316
|
nodeSubtitle(node) && /* @__PURE__ */ jsx(DialogDescription, { className: "truncate text-xs leading-tight", children: nodeSubtitle(node) })
|
|
23974
24317
|
] }),
|
|
23975
|
-
canRunFromHere && /* @__PURE__ */ jsxs(
|
|
23976
|
-
"button",
|
|
23977
|
-
{
|
|
23978
|
-
type: "button",
|
|
23979
|
-
onClick: runFromHere,
|
|
23980
|
-
disabled: runningFromHere,
|
|
23981
|
-
"data-testid": "ndv-run-from-here",
|
|
23982
|
-
className: "flex items-center gap-1 rounded-md border border-primary/30 px-2 py-1 text-xs text-primary hover:bg-primary/10 disabled:opacity-50",
|
|
23983
|
-
title: tr(
|
|
23984
|
-
"fluidgrids.builder.nodeDetailView.runFromHereHint",
|
|
23985
|
-
"Re-run from this node, reusing upstream outputs instead of re-executing them."
|
|
23986
|
-
),
|
|
23987
|
-
children: [
|
|
23988
|
-
/* @__PURE__ */ jsx(
|
|
23989
|
-
Icon,
|
|
23990
|
-
{
|
|
23991
|
-
icon: runningFromHere ? "svg-spinners:ring-resize" : "mdi:play",
|
|
23992
|
-
className: "size-3.5"
|
|
23993
|
-
}
|
|
23994
|
-
),
|
|
23995
|
-
tr(
|
|
23996
|
-
"fluidgrids.builder.nodeDetailView.runFromHereButton",
|
|
23997
|
-
"Run from here"
|
|
23998
|
-
)
|
|
23999
|
-
]
|
|
24000
|
-
}
|
|
24001
|
-
),
|
|
24002
24318
|
/* @__PURE__ */ jsx(
|
|
24003
24319
|
"button",
|
|
24004
24320
|
{
|
|
@@ -24025,6 +24341,28 @@ function NodeDetailView() {
|
|
|
24025
24341
|
}
|
|
24026
24342
|
)
|
|
24027
24343
|
] }),
|
|
24344
|
+
ndv && /* @__PURE__ */ jsx(
|
|
24345
|
+
NodeExecutionActions,
|
|
24346
|
+
{
|
|
24347
|
+
targetNodeId: ndv.nodeId,
|
|
24348
|
+
nodes: workflowNodes,
|
|
24349
|
+
edges: workflowEdges,
|
|
24350
|
+
logs: executionLogs,
|
|
24351
|
+
workflowKey: workflowKey || workflowId,
|
|
24352
|
+
workflowVersion: workflowVersion || "1.0.0",
|
|
24353
|
+
sourceRun,
|
|
24354
|
+
isExecuting,
|
|
24355
|
+
onExecuteStep: async (targetId) => {
|
|
24356
|
+
await executeStep(targetId);
|
|
24357
|
+
},
|
|
24358
|
+
onContinueFromNode: async (sourceRunId, targetId) => {
|
|
24359
|
+
await executeFromNode(sourceRunId, targetId);
|
|
24360
|
+
},
|
|
24361
|
+
testIdPrefix: "ndv",
|
|
24362
|
+
className: "border-t-0 border-b"
|
|
24363
|
+
}
|
|
24364
|
+
),
|
|
24365
|
+
stepPlanForNode && /* @__PURE__ */ jsx(StepExecutionPlanSummary, { plan: stepPlanForNode }),
|
|
24028
24366
|
!threePaneLayout && /* @__PURE__ */ jsxs(
|
|
24029
24367
|
"div",
|
|
24030
24368
|
{
|
|
@@ -24349,6 +24687,152 @@ function NodeDetailView() {
|
|
|
24349
24687
|
}
|
|
24350
24688
|
) });
|
|
24351
24689
|
}
|
|
24690
|
+
function StepExecutionPlanSummary({ plan }) {
|
|
24691
|
+
const tr = useTr();
|
|
24692
|
+
return /* @__PURE__ */ jsxs(
|
|
24693
|
+
"section",
|
|
24694
|
+
{
|
|
24695
|
+
className: "shrink-0 border-b border-border bg-muted/30 px-4 py-2.5",
|
|
24696
|
+
"data-testid": "ndv-step-execution-plan",
|
|
24697
|
+
"aria-live": "polite",
|
|
24698
|
+
children: [
|
|
24699
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1", children: [
|
|
24700
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-foreground", children: tr(
|
|
24701
|
+
"fluidgrids.builder.nodeDetailView.stepPlanTitle",
|
|
24702
|
+
"TEST execution plan"
|
|
24703
|
+
) }),
|
|
24704
|
+
/* @__PURE__ */ jsx(
|
|
24705
|
+
PlanMetric,
|
|
24706
|
+
{
|
|
24707
|
+
label: tr(
|
|
24708
|
+
"fluidgrids.builder.nodeDetailView.stepPlanExecute",
|
|
24709
|
+
"Execute"
|
|
24710
|
+
),
|
|
24711
|
+
count: plan.executeNodeIds.length
|
|
24712
|
+
}
|
|
24713
|
+
),
|
|
24714
|
+
/* @__PURE__ */ jsx(
|
|
24715
|
+
PlanMetric,
|
|
24716
|
+
{
|
|
24717
|
+
label: tr("fluidgrids.builder.nodeDetailView.stepPlanReuse", "Reuse"),
|
|
24718
|
+
count: plan.reusedNodeIds.length
|
|
24719
|
+
}
|
|
24720
|
+
),
|
|
24721
|
+
/* @__PURE__ */ jsx(
|
|
24722
|
+
PlanMetric,
|
|
24723
|
+
{
|
|
24724
|
+
label: tr(
|
|
24725
|
+
"fluidgrids.builder.nodeDetailView.stepPlanPinned",
|
|
24726
|
+
"Pinned"
|
|
24727
|
+
),
|
|
24728
|
+
count: plan.pinnedNodeIds.length
|
|
24729
|
+
}
|
|
24730
|
+
),
|
|
24731
|
+
/* @__PURE__ */ jsx(
|
|
24732
|
+
PlanMetric,
|
|
24733
|
+
{
|
|
24734
|
+
label: tr(
|
|
24735
|
+
"fluidgrids.builder.nodeDetailView.stepPlanBlockers",
|
|
24736
|
+
"Blockers"
|
|
24737
|
+
),
|
|
24738
|
+
count: plan.blockers.length
|
|
24739
|
+
}
|
|
24740
|
+
)
|
|
24741
|
+
] }),
|
|
24742
|
+
plan.sourceRunId && /* @__PURE__ */ jsxs("p", { className: "mt-1 text-[11px] text-muted-foreground", children: [
|
|
24743
|
+
tr(
|
|
24744
|
+
"fluidgrids.builder.nodeDetailView.stepPlanSource",
|
|
24745
|
+
"Using compatible TEST data from run"
|
|
24746
|
+
),
|
|
24747
|
+
" ",
|
|
24748
|
+
/* @__PURE__ */ jsx("code", { className: "font-mono text-foreground", children: plan.sourceRunId })
|
|
24749
|
+
] }),
|
|
24750
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-2 grid gap-2 sm:grid-cols-2", children: [
|
|
24751
|
+
/* @__PURE__ */ jsx(
|
|
24752
|
+
PlanNodeList,
|
|
24753
|
+
{
|
|
24754
|
+
label: tr(
|
|
24755
|
+
"fluidgrids.builder.nodeDetailView.stepPlanExecuteNodes",
|
|
24756
|
+
"Nodes to execute"
|
|
24757
|
+
),
|
|
24758
|
+
nodeIds: plan.executeNodeIds,
|
|
24759
|
+
emptyLabel: tr(
|
|
24760
|
+
"fluidgrids.builder.nodeDetailView.stepPlanExecuteNodesEmpty",
|
|
24761
|
+
"No nodes need execution."
|
|
24762
|
+
)
|
|
24763
|
+
}
|
|
24764
|
+
),
|
|
24765
|
+
/* @__PURE__ */ jsx(
|
|
24766
|
+
PlanNodeList,
|
|
24767
|
+
{
|
|
24768
|
+
label: tr(
|
|
24769
|
+
"fluidgrids.builder.nodeDetailView.stepPlanReusedNodes",
|
|
24770
|
+
"Reused nodes"
|
|
24771
|
+
),
|
|
24772
|
+
nodeIds: plan.reusedNodeIds,
|
|
24773
|
+
emptyLabel: tr(
|
|
24774
|
+
"fluidgrids.builder.nodeDetailView.stepPlanReusedNodesEmpty",
|
|
24775
|
+
"No prior node data reused."
|
|
24776
|
+
)
|
|
24777
|
+
}
|
|
24778
|
+
),
|
|
24779
|
+
/* @__PURE__ */ jsx(
|
|
24780
|
+
PlanNodeList,
|
|
24781
|
+
{
|
|
24782
|
+
label: tr(
|
|
24783
|
+
"fluidgrids.builder.nodeDetailView.stepPlanPinnedNodes",
|
|
24784
|
+
"Pinned nodes"
|
|
24785
|
+
),
|
|
24786
|
+
nodeIds: plan.pinnedNodeIds,
|
|
24787
|
+
emptyLabel: tr(
|
|
24788
|
+
"fluidgrids.builder.nodeDetailView.stepPlanPinnedNodesEmpty",
|
|
24789
|
+
"No pinned data used."
|
|
24790
|
+
)
|
|
24791
|
+
}
|
|
24792
|
+
),
|
|
24793
|
+
/* @__PURE__ */ jsx(
|
|
24794
|
+
PlanNodeList,
|
|
24795
|
+
{
|
|
24796
|
+
label: tr(
|
|
24797
|
+
"fluidgrids.builder.nodeDetailView.stepPlanBlockerNodes",
|
|
24798
|
+
"Blockers"
|
|
24799
|
+
),
|
|
24800
|
+
nodeIds: plan.blockers,
|
|
24801
|
+
emptyLabel: tr(
|
|
24802
|
+
"fluidgrids.builder.nodeDetailView.stepPlanBlockerNodesEmpty",
|
|
24803
|
+
"No blockers."
|
|
24804
|
+
)
|
|
24805
|
+
}
|
|
24806
|
+
)
|
|
24807
|
+
] })
|
|
24808
|
+
]
|
|
24809
|
+
}
|
|
24810
|
+
);
|
|
24811
|
+
}
|
|
24812
|
+
function PlanMetric({ label, count: count2 }) {
|
|
24813
|
+
return /* @__PURE__ */ jsxs("span", { className: "text-[11px] text-muted-foreground", children: [
|
|
24814
|
+
label,
|
|
24815
|
+
": ",
|
|
24816
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: count2 })
|
|
24817
|
+
] });
|
|
24818
|
+
}
|
|
24819
|
+
function PlanNodeList({
|
|
24820
|
+
label,
|
|
24821
|
+
nodeIds,
|
|
24822
|
+
emptyLabel
|
|
24823
|
+
}) {
|
|
24824
|
+
return /* @__PURE__ */ jsxs("div", { className: "min-w-0 rounded-md border border-border bg-background/60 px-2 py-1.5", children: [
|
|
24825
|
+
/* @__PURE__ */ jsx("p", { className: "text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: label }),
|
|
24826
|
+
nodeIds.length > 0 ? /* @__PURE__ */ jsx("div", { className: "mt-1 flex flex-wrap gap-1", children: nodeIds.map((nodeId) => /* @__PURE__ */ jsx(
|
|
24827
|
+
"code",
|
|
24828
|
+
{
|
|
24829
|
+
className: "max-w-full truncate rounded bg-muted px-1 py-0.5 font-mono text-[10px] text-foreground",
|
|
24830
|
+
children: nodeId
|
|
24831
|
+
},
|
|
24832
|
+
`${label}-${nodeId}`
|
|
24833
|
+
)) }) : /* @__PURE__ */ jsx("p", { className: "mt-1 text-[10px] text-muted-foreground", children: emptyLabel })
|
|
24834
|
+
] });
|
|
24835
|
+
}
|
|
24352
24836
|
function ResizeHandle({ onStart }) {
|
|
24353
24837
|
return /* @__PURE__ */ jsx(
|
|
24354
24838
|
"div",
|
|
@@ -24465,6 +24949,9 @@ function QuickConfigPanelInner({
|
|
|
24465
24949
|
const close = useFlowStore((s) => s.actions.quickConfig.close);
|
|
24466
24950
|
const openNdv = useFlowStore((s) => s.actions.ndv.open);
|
|
24467
24951
|
const tr = useTr();
|
|
24952
|
+
const { executeStep, executeFromNode } = useNodeExecution();
|
|
24953
|
+
const workflow = useFlowStore((s) => s.workflow);
|
|
24954
|
+
const execution = useFlowStore((s) => s.execution);
|
|
24468
24955
|
const config2 = useNodeConfig({ nodeId});
|
|
24469
24956
|
const {
|
|
24470
24957
|
node,
|
|
@@ -24750,6 +25237,26 @@ function QuickConfigPanelInner({
|
|
|
24750
25237
|
)
|
|
24751
25238
|
}
|
|
24752
25239
|
),
|
|
25240
|
+
/* @__PURE__ */ jsx(
|
|
25241
|
+
NodeExecutionActions,
|
|
25242
|
+
{
|
|
25243
|
+
targetNodeId: nodeId,
|
|
25244
|
+
nodes: workflow.nodes,
|
|
25245
|
+
edges: workflow.edges,
|
|
25246
|
+
logs: execution.logs,
|
|
25247
|
+
workflowKey: workflow.workflowKey || workflow.id,
|
|
25248
|
+
workflowVersion: workflow.version || "1.0.0",
|
|
25249
|
+
sourceRun: execution.sourceRun,
|
|
25250
|
+
isExecuting: execution.isExecuting,
|
|
25251
|
+
onExecuteStep: async (targetId) => {
|
|
25252
|
+
await executeStep(targetId);
|
|
25253
|
+
},
|
|
25254
|
+
onContinueFromNode: async (sourceRunId, targetId) => {
|
|
25255
|
+
await executeFromNode(sourceRunId, targetId);
|
|
25256
|
+
},
|
|
25257
|
+
testIdPrefix: "qc"
|
|
25258
|
+
}
|
|
25259
|
+
),
|
|
24753
25260
|
/* @__PURE__ */ jsx("p", { className: "shrink-0 border-t border-border px-3 py-1.5 text-[10px] leading-snug text-muted-foreground", children: tr(
|
|
24754
25261
|
"fluidgrids.builder.quickConfigPanel.footerHint",
|
|
24755
25262
|
"Changes apply instantly \xB7 double-click the node for the full editor"
|
|
@@ -26040,5 +26547,5 @@ var FlowBuilderPage = ({
|
|
|
26040
26547
|
};
|
|
26041
26548
|
|
|
26042
26549
|
export { Card2 as Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ConnectionFormDialog, ConnectionSelector, EntityTagPicker, FLUIDGRIDS_ENTITY_TYPES, FlowBuilderPage, FluidGridsMark, FluidGridsProvider, ProviderPicker, SchemaConnectionForm, ScopePicker, TemplateCard, buildNodeCheck, buildRequiredNodeTypes, listCustomBlocks, mergeStickyNotes, refetchStoreNodes, registerCustomBlock, resolveUiSpec, stripSubmitActions, tagLabel, useAvailableTags, useConnection, useConnectionDialog, useConnections, useConnectionsByProvider, useCreateConnection, useCreateTag, useDraftEntityTags, useEntityTags, useFluidGridsContext, useImportWorkflowTemplate, useInitiateOAuth, useInstalledNodes, useNodeExecution, useProviderByKey, useProviderCatalog, useProviders, useReplaceEntityTags, useSearchTags, useTagEntity, useUntagEntity, useWorkflowTemplates };
|
|
26043
|
-
//# sourceMappingURL=chunk-
|
|
26044
|
-
//# sourceMappingURL=chunk-
|
|
26550
|
+
//# sourceMappingURL=chunk-VG2BTLUN.js.map
|
|
26551
|
+
//# sourceMappingURL=chunk-VG2BTLUN.js.map
|