@burdenoff/fluidgrids-fe-sdk 2026.1031.4 → 2026.1031.6
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-GKX4OUUR.js +23 -0
- package/dist/{WorkflowsList-BZXBTGNL.js → ExecutionsListPage-ZZOUZQBS.js} +9 -8
- package/dist/{TemplateDetailPanel-MTKW3SPM.js → TemplateDetailPanel-WH74G7PF.js} +18 -7
- package/dist/{WorkflowBuilder-N3ZUYFRK.js → WorkflowBuilder-4QEJNKVE.js} +12 -11
- package/dist/{ExecutionsListPage-AYDGFU6W.js → WorkflowsList-4CTHUYM7.js} +9 -8
- package/dist/{chunk-VJWJGSRS.js → chunk-34HHBNZE.js} +1 -1
- package/dist/{chunk-P3TGCUXP.js → chunk-34XK5BC7.js} +5 -37
- package/dist/{chunk-JFQGODKK.js → chunk-35N3PEO6.js} +1 -1
- package/dist/{chunk-DHR2YURL.js → chunk-3KKGE7CE.js} +164 -9
- package/dist/{chunk-XX6D7IND.js → chunk-5XQMYHJ7.js} +2 -2
- package/dist/{chunk-OGYAC7QW.js → chunk-AHDYETEE.js} +1 -1
- package/dist/{chunk-WHPQRYZD.js → chunk-CAZHE2MQ.js} +6 -5
- package/dist/{chunk-GV5RJ6BU.js → chunk-E7AQAPZN.js} +33 -22
- package/dist/{chunk-6PGLJWIC.js → chunk-EPYTVCYH.js} +30 -188
- package/dist/{chunk-DJAGZUHW.js → chunk-FUYHCONW.js} +1257 -34
- package/dist/{chunk-ADTEMSJI.js → chunk-GMVXPC5N.js} +849 -4
- package/dist/{chunk-IGROOI7E.js → chunk-GREPXIXS.js} +2 -2
- package/dist/{chunk-PTROESUB.js → chunk-HCKYGGUU.js} +4 -4
- package/dist/{chunk-Z3FYBDE3.js → chunk-HQX7JZLY.js} +33 -1
- package/dist/{chunk-QKQOTEAB.js → chunk-I5BPMBIV.js} +1 -1
- package/dist/{chunk-R4Q37Q4X.js → chunk-IJBT25CS.js} +3 -3
- package/dist/{chunk-44KAAKFK.js → chunk-JUHSLK7C.js} +5 -5
- package/dist/{chunk-AW3UXMNI.js → chunk-KEYKB4E7.js} +12 -1
- package/dist/{chunk-P2VAHDGO.js → chunk-NLRQSHRS.js} +2 -2
- package/dist/{chunk-BHD4CDLL.js → chunk-P4R4ACCC.js} +1 -1
- package/dist/{chunk-CIR7WF4W.js → chunk-PP62ABIG.js} +1 -1
- package/dist/{chunk-Q3HKE627.js → chunk-RYUSWVIR.js} +3 -3
- package/dist/{chunk-INMYNHJL.js → chunk-TVOXRODW.js} +34 -2
- package/dist/{chunk-PKG6BCHB.js → chunk-VWFA3RQR.js} +2 -2
- package/dist/{chunk-475XP5J7.js → chunk-ZEHMJURX.js} +6 -5
- package/dist/chunk-ZUVFD5KV.js +186 -0
- package/dist/executions.js +13 -12
- package/dist/history.js +5 -4
- package/dist/index.d.ts +741 -4
- package/dist/index.js +45 -40
- package/dist/nodes.js +2 -2
- package/dist/observability.js +7 -6
- package/dist/settings.js +7 -6
- package/dist/templates.js +11 -10
- package/dist/workflow-builder.js +13 -12
- package/dist/workflows-list.js +9 -8
- package/package.json +1 -1
- package/dist/ExecutionDetailPage-WOOORXXU.js +0 -22
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import { deepClone, applyTemplateInputs } from './chunk-GEMNVFPK.js';
|
|
2
2
|
import { templatePreview } from './chunk-B6CCE2RW.js';
|
|
3
3
|
import { Input } from './chunk-IEVSFCFS.js';
|
|
4
|
-
import { Dialog as Dialog$1, DialogContent as DialogContent$1, DialogHeader as DialogHeader$1, DialogTitle as DialogTitle$1, DialogDescription as DialogDescription$1, DialogFooter } from './chunk-YXMFRQYV.js';
|
|
4
|
+
import { Dialog as Dialog$1, DialogContent as DialogContent$1, DialogHeader as DialogHeader$1, DialogTitle as DialogTitle$1, DialogDescription as DialogDescription$1, DialogFooter as DialogFooter$1 } from './chunk-YXMFRQYV.js';
|
|
5
5
|
import { Badge as Badge$1, Button } from './chunk-BQXVT32O.js';
|
|
6
|
-
import { QuotaExhaustedDialog, useWorkflowCodeExport, orderedExportFiles, fileBaseName, downloadWorkflowCodeExport, isLosslessReport, sortFidelityItems, isLossyFidelityItem, lineOfNode } from './chunk-
|
|
7
|
-
import { EntityTagPicker, useWorkflowProposal, WorkflowProposalCard, useRunHistory, RunHistoryView, SignalRunDialog } from './chunk-
|
|
6
|
+
import { QuotaExhaustedDialog, useWorkflowCodeExport, orderedExportFiles, fileBaseName, downloadWorkflowCodeExport, isLosslessReport, sortFidelityItems, isLossyFidelityItem, lineOfNode } from './chunk-GREPXIXS.js';
|
|
7
|
+
import { emptyTestCaseDraft, EntityTagPicker, useWorkflowProposal, WorkflowProposalCard, useRunHistory, RunHistoryView, SignalRunDialog, readAssertRulesSetting, rowsFromRules, normaliseAssertRules, ruleFromRow, describeAssertRuleProblem, operatorSpec, ASSERT_OPERATORS, emptyAssertRuleRow, useWorkflowTests, pinnedOutputsFromCanvas, enabledCaseIds, isTestRunOpen, MAX_TEST_CASES, draftFromTestCase, testRunSummaryText, testStatusLabel, TEST_STATUS_TONE_CLASS, testStatusTone, MAX_CASE_NAME, nextSortOrder, draftToInput } from './chunk-GMVXPC5N.js';
|
|
8
|
+
import { buildNodeDisplayMap } from './chunk-TVOXRODW.js';
|
|
8
9
|
import { AiCreditBalanceSlot } from './chunk-Y53CVZVV.js';
|
|
9
|
-
import { useRestoreWorkflowVersion, useWorkflowVersions, useActivateWorkflow, useDeleteWorkflow, useLazyWorkflowDefinition, useDeactivateWorkflow } from './chunk-
|
|
10
|
-
import { isAgentNodeType, AgentDefinitionSelectField } from './chunk-
|
|
10
|
+
import { useRestoreWorkflowVersion, useWorkflowVersions, useActivateWorkflow, useDeleteWorkflow, useLazyWorkflowDefinition, useDeactivateWorkflow } from './chunk-VWFA3RQR.js';
|
|
11
|
+
import { isAgentNodeType, AgentDefinitionSelectField } from './chunk-35N3PEO6.js';
|
|
11
12
|
import { FluidGridsDocsLink } from './chunk-4VJ3MDOV.js';
|
|
12
|
-
import { leaseCallQueue, NODE_CONFIGS, createConfiguredNode, resolveOutputHandles, resolveInputHandles, isNodeConfigsInitialized, useFlowStore, getNodeDetail, useSaveStatusStore, isNodeTypeHiddenFromPalette, liveInternalOperations, resolveNodeOperation, readDisplayOptions, parseParameterValue, canAutosave, STICKY_NOTE_TYPE, isNodeTrigger, resolveUiSpec, RUNS_QUOTA_NAME, throwIfResultError, BILLING_PLANS_PATH, emitUpgradeClicked, FluidGridsContext, emitWorkflowCreated, emitTemplateUsed, describeOperationError, ensureNodeConfigsLoaded, useEditLeaseStore, useEditLeaseLocked, registerWorkflowNodeTypes, emitNodeInstalled, useNodeExecution, usePaletteGates, onNodeTypesUpdate, NODE_TYPES, getNodeMetadata, useIsValidConnection, BuilderReadOnlyProvider, refetchStoreNodes, AVAILABLE_NODES, EDIT_SESSION_ID,
|
|
13
|
+
import { leaseCallQueue, NODE_CONFIGS, createConfiguredNode, resolveOutputHandles, resolveInputHandles, isNodeConfigsInitialized, useFlowStore, getNodeDetail, useSaveStatusStore, isNodeTypeHiddenFromPalette, liveInternalOperations, resolveNodeOperation, readDisplayOptions, parseParameterValue, canAutosave, STICKY_NOTE_TYPE, isNodeTrigger, resolveUiSpec, RUNS_QUOTA_NAME, throwIfResultError, BILLING_PLANS_PATH, emitUpgradeClicked, FluidGridsContext, emitWorkflowCreated, emitTemplateUsed, describeOperationError, ensureNodeConfigsLoaded, useEditLeaseStore, useEditLeaseLocked, registerWorkflowNodeTypes, emitNodeInstalled, useNodeExecution, usePaletteGates, onNodeTypesUpdate, NODE_TYPES, getNodeMetadata, useIsValidConnection, BuilderReadOnlyProvider, refetchStoreNodes, AVAILABLE_NODES, EDIT_SESSION_ID, useInsertNode, NODE_TYPE_DRAG_DATA_FORMAT, NODE_OPERATION_DRAG_DATA_FORMAT, useDurableFunctionNodesEnabled, CODE_WORKFLOW_NODE_TYPE, bannerOf, useSaveWorkflow, useBuilderReadOnly, fieldsFromValue, filterPaletteNodes, useFluidGridsAnalytics, sessionBeforeReload, forgetSessionForReload, releasesOnClose, editStateOf, workflowFingerprint, isLocked, buildStickyNode, useNodeRegistryRevision, fieldsFromIO, readCodeWorkflowState, useCodeWorkflowInterface, clearCodeWorkflowDefinitionCache, isParamVisible, ConnectionSelector, structuredParameterType, nodeAccent, NodeTypeIcon, NODES_METADATA, shouldReleaseForIdle, tickAction, rememberSessionForReload, buildOperationSeed, useDurableParityEnabled, useConnections, ConnectionFormDialog, useWorkflowTestsEnabled, useFluidGridsFlag, FLUIDGRIDS_FLAGS, saveIndicatorOf, inAppLeaveTarget, declaredOutputFields, subscribeWorkflowSaved, pathToExpression, diagnosticsByPath, interfaceHandlers, declaredSignals, ExpressionEditor, toCodeMirrorDiagnostics, formatParameterValue, leaveNeedsConfirmation, phaseAfterAcquire, rememberOwnStatusChange, snapshotForSave, childRunIdOf, defaultSourcePath, projectLanguage, changedSourceFiles, isEditableSourcePath, sourceLanguageOf, interfaceFields, isImageIcon, NODES, synchronizeOperationUpdate, NodePropertyPanel, loadDefinitionJson, openRunQuotaUpgradePrompt, isTriggerOperation, canRenderOperationPanel, runPreparationOf, resolveOperationName, savesInPlace, AUTOSAVE_RETRY_DELAYS_MS, AUTOSAVE_DEBOUNCE_MS, rememberRevision, phaseAfterTakeOver } from './chunk-EPYTVCYH.js';
|
|
14
|
+
import { SdkPermissionButton, FLUIDGRIDS_PERMISSIONS, useFluidGridsPermission } from './chunk-ZUVFD5KV.js';
|
|
13
15
|
import { cn } from './chunk-JL7CASN5.js';
|
|
14
16
|
import { getGlobalStoreClient } from './chunk-PXIFUMLA.js';
|
|
15
17
|
import { getFluidGridsConfig } from './chunk-6AMNEX2Y.js';
|
|
16
18
|
import { GetMyNodeInstallationsDocument, BrowseWorkflowTemplatesDocument, InstallWorkflowNodeDocument, SubmitWorkflowTemplateDocument, MyWorkflowTemplateSubmissionsDocument, WithdrawWorkflowTemplateSubmissionDocument, InstallPurchasedNodeDocument, BrowseWorkflowNodesDocument, UninstallWorkflowNodeDocument, CreateStoreOrderDocument, GetNodeInstallableVersionsDocument, OrganizationPrivateNodesDocument, InstallOrganizationPrivateNodeDocument, UninstallOrganizationPrivateNodeDocument } from './chunk-G77IGC3Y.js';
|
|
17
|
-
import { WorkspaceRunsQuotaDocument, WorkflowGenerationTemplatesDocument, ReleaseWorkflowEditLeaseDocument, NodeSchemaIntrospectionDocument, useWorkflowPinnedDataQuery, usePinNodeDataMutation, useUnpinNodeDataMutation, useRunFromNodeEligibilityQuery, EventRegistrationsDocument, AcquireWorkflowEditLeaseDocument, WorkflowEnvironmentsDocument, WorkflowPromotionRequestsDocument, DeployWorkflowVersionToDevDocument, RequestWorkflowPromotionDocument, ApproveWorkflowPromotionDocument, RejectWorkflowPromotionDocument, CancelWorkflowPromotionDocument, UpdateWorkflowEnvironmentPolicyDocument, WorkflowGitRepositoryDocument, WorkflowGitPushesDocument, WorkflowGitCommitsDocument, LinkWorkflowGitRepositoryDocument, UnlinkWorkflowGitRepositoryDocument, PushWorkflowToGitDocument, WorkflowGitDiffDocument, RestoreWorkflowFromGitDocument, WorkflowAuthoringDocument, NodeStatesDocument, PreviewScheduleDocument, WorkflowEditLeaseDocument, WorkflowVersioningDocument, WorkflowVersionDrainageDocument, ActivateWorkflowVersionCheckedDocument, WorkflowDefinitionDocument, WorkflowCodeSourceDocument, WorkflowEditLeaseStatusDocument, BuildWorkflowCodeDocument, WebhookTestListenerDocument, StopWebhookTestListenerDocument, ListenForWebhookTestEventDocument, NodeUsageStatusDocument, RemoveNodeFromWorkflowsDocument, SetWorkflowRolloutDocument, DeleteWorkflowRolloutDocument, TakeOverWorkflowEditLeaseDocument } from './chunk-
|
|
19
|
+
import { WorkspaceRunsQuotaDocument, WorkflowGenerationTemplatesDocument, ReleaseWorkflowEditLeaseDocument, NodeSchemaIntrospectionDocument, useWorkflowPinnedDataQuery, usePinNodeDataMutation, useUnpinNodeDataMutation, useRunFromNodeEligibilityQuery, EventRegistrationsDocument, AcquireWorkflowEditLeaseDocument, WorkflowEnvironmentsDocument, WorkflowPromotionRequestsDocument, DeployWorkflowVersionToDevDocument, RequestWorkflowPromotionDocument, ApproveWorkflowPromotionDocument, RejectWorkflowPromotionDocument, CancelWorkflowPromotionDocument, UpdateWorkflowEnvironmentPolicyDocument, WorkflowGitRepositoryDocument, WorkflowGitPushesDocument, WorkflowGitCommitsDocument, LinkWorkflowGitRepositoryDocument, UnlinkWorkflowGitRepositoryDocument, PushWorkflowToGitDocument, WorkflowGitDiffDocument, RestoreWorkflowFromGitDocument, WorkflowAuthoringDocument, NodeStatesDocument, PreviewScheduleDocument, WorkflowEditLeaseDocument, WorkflowVersioningDocument, WorkflowVersionDrainageDocument, ActivateWorkflowVersionCheckedDocument, WorkflowDefinitionDocument, WorkflowCodeSourceDocument, WorkflowEditLeaseStatusDocument, BuildWorkflowCodeDocument, WebhookTestListenerDocument, StopWebhookTestListenerDocument, ListenForWebhookTestEventDocument, NodeUsageStatusDocument, RemoveNodeFromWorkflowsDocument, SetWorkflowRolloutDocument, DeleteWorkflowRolloutDocument, TakeOverWorkflowEditLeaseDocument } from './chunk-KEYKB4E7.js';
|
|
18
20
|
import { useTr } from './chunk-UULVIT25.js';
|
|
19
21
|
import { getFluidGridsClient, waitForFluidGridsClient, getFluidGridsClientSafe } from './chunk-NTWG3CJX.js';
|
|
20
22
|
import { __export } from './chunk-62GWEYJ5.js';
|
|
@@ -24,13 +26,13 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
24
26
|
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
25
27
|
import { gql } from '@apollo/client';
|
|
26
28
|
import { cn as cn$1 } from '@burdenoff/fe-libs/utils';
|
|
27
|
-
import { Card as Card$1, Badge, CardContent as CardContent$1, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Button as Button$1, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Popover as Popover$1, PopoverTrigger as PopoverTrigger$1, PopoverContent as PopoverContent$1, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, Toaster, Tabs, TabsList, TabsTrigger, TabsContent, CardHeader as CardHeader$1, CardTitle as CardTitle$1, CardDescription as CardDescription$1, ScrollArea, Sheet, SheetTrigger, SheetContent, SheetHeader, SheetTitle, SheetDescription, Label, Textarea, AlertDialogAction, TooltipProvider, Switch, Input as Input$1, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, Skeleton, Tooltip, TooltipTrigger, TooltipContent, DropdownMenuLabel, DropdownMenuSeparator } from '@burdenoff/fe-libs/ui';
|
|
29
|
+
import { Card as Card$1, Badge, CardContent as CardContent$1, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Button as Button$1, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Popover as Popover$1, PopoverTrigger as PopoverTrigger$1, PopoverContent as PopoverContent$1, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, Toaster, Tabs, TabsList, TabsTrigger, TabsContent, CardHeader as CardHeader$1, CardTitle as CardTitle$1, CardDescription as CardDescription$1, ScrollArea, Sheet, SheetTrigger, SheetContent, SheetHeader, SheetTitle, SheetDescription, Label, Textarea, AlertDialogAction, TooltipProvider, Switch, Input as Input$1, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, Skeleton, Tooltip, TooltipTrigger, TooltipContent, DialogFooter, DropdownMenuLabel, DropdownMenuSeparator } from '@burdenoff/fe-libs/ui';
|
|
28
30
|
import { Link, useParams, useNavigate } from 'react-router';
|
|
29
31
|
import { useEventBus } from '@burdenoff/fe-libs/shared/events';
|
|
30
32
|
import { useQuery, useMutation } from '@apollo/client/react';
|
|
31
33
|
import { gql as gql$1 } from '@apollo/client/core';
|
|
32
34
|
import 'jszip';
|
|
33
|
-
import { Sparkles, Star, Download, Eye, Maximize2, Undo2, Redo2, LayoutGrid, Keyboard, Plus, Trash2, GitBranch, Loader2, AlertCircle, Search, RefreshCw, History, GitCompareArrows, Play, RotateCcw, Layers, Upload, Rocket, ArrowRight, Check, X, Link2, Unlink, GitCompare, ExternalLink, GitCommitHorizontal, CircleHelp, CheckCircle2, Package, SlidersHorizontal, Info, Copy, BadgeCheck, DollarSign, Type, Code, Hash, List, Braces, Workflow, PlusCircle, ChevronDown, ChevronRight, AlertTriangle } from 'lucide-react';
|
|
35
|
+
import { Sparkles, Star, Download, Eye, Maximize2, Undo2, Redo2, LayoutGrid, Keyboard, Plus, Trash2, GitBranch, Loader2, AlertCircle, Search, RefreshCw, History, GitCompareArrows, Play, RotateCcw, Layers, Upload, Rocket, ArrowRight, Check, X, Link2, Unlink, GitCompare, ExternalLink, GitCommitHorizontal, CircleHelp, CheckCircle2, Package, SlidersHorizontal, FlaskConical, Pencil, Info, Copy, BadgeCheck, DollarSign, Type, Code, Hash, List, Braces, Workflow, PlusCircle, ChevronDown, ChevronRight, AlertTriangle } from 'lucide-react';
|
|
34
36
|
import { Icon } from '@iconify/react';
|
|
35
37
|
import { create } from 'zustand';
|
|
36
38
|
import { toast } from 'sonner';
|
|
@@ -1942,13 +1944,23 @@ function TemplateCard({
|
|
|
1942
1944
|
template.tags.length - 2
|
|
1943
1945
|
] })
|
|
1944
1946
|
] }),
|
|
1945
|
-
/* @__PURE__ */
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1947
|
+
/* @__PURE__ */ jsx(
|
|
1948
|
+
SdkPermissionButton,
|
|
1949
|
+
{
|
|
1950
|
+
permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_CREATE,
|
|
1951
|
+
deniedTooltip: tr(
|
|
1952
|
+
"fluidgrids.templates.useDeniedTooltip",
|
|
1953
|
+
"You don't have permission to create workflows from templates"
|
|
1954
|
+
),
|
|
1955
|
+
children: /* @__PURE__ */ jsxs(Button, { size: "sm", className: "w-full mt-2", onClick: handleUseTemplate, children: [
|
|
1956
|
+
/* @__PURE__ */ jsx(Sparkles, { className: "size-3 mr-1" }),
|
|
1957
|
+
tr(
|
|
1958
|
+
"fluidgrids.builder.templateCard.useTemplateButton",
|
|
1959
|
+
"Use Template"
|
|
1960
|
+
)
|
|
1961
|
+
] })
|
|
1962
|
+
}
|
|
1963
|
+
)
|
|
1952
1964
|
] })
|
|
1953
1965
|
]
|
|
1954
1966
|
}
|
|
@@ -25503,7 +25515,7 @@ function TemplatesGrid({
|
|
|
25503
25515
|
] });
|
|
25504
25516
|
}
|
|
25505
25517
|
var LazyTemplateDetailPanel = lazy$1(
|
|
25506
|
-
() => import('./TemplateDetailPanel-
|
|
25518
|
+
() => import('./TemplateDetailPanel-WH74G7PF.js').then((m) => ({
|
|
25507
25519
|
default: m.TemplateDetailPanel
|
|
25508
25520
|
}))
|
|
25509
25521
|
);
|
|
@@ -27241,8 +27253,8 @@ var reducer = (state, action) => {
|
|
|
27241
27253
|
if (toastId) {
|
|
27242
27254
|
addToRemoveQueue(toastId);
|
|
27243
27255
|
} else {
|
|
27244
|
-
state.toasts.forEach((
|
|
27245
|
-
addToRemoveQueue(
|
|
27256
|
+
state.toasts.forEach((toast19) => {
|
|
27257
|
+
addToRemoveQueue(toast19.id);
|
|
27246
27258
|
});
|
|
27247
27259
|
}
|
|
27248
27260
|
return {
|
|
@@ -28618,7 +28630,7 @@ function VisualMapperContent({
|
|
|
28618
28630
|
mapping,
|
|
28619
28631
|
onMappingChange
|
|
28620
28632
|
}) {
|
|
28621
|
-
const { toast:
|
|
28633
|
+
const { toast: toast19 } = useToast();
|
|
28622
28634
|
const tr = useTr();
|
|
28623
28635
|
const reactFlowWrapper = useRef(null);
|
|
28624
28636
|
const [selectedSourceNode, setSelectedSourceNode] = useState(null);
|
|
@@ -28638,7 +28650,7 @@ function VisualMapperContent({
|
|
|
28638
28650
|
targetOperation
|
|
28639
28651
|
);
|
|
28640
28652
|
if (generatedNodes.length === 0) {
|
|
28641
|
-
|
|
28653
|
+
toast19({
|
|
28642
28654
|
title: tr(
|
|
28643
28655
|
"fluidgrids.builder.visualMapper.noFieldsFoundTitle",
|
|
28644
28656
|
"No fields found"
|
|
@@ -28664,7 +28676,7 @@ function VisualMapperContent({
|
|
|
28664
28676
|
targetNode,
|
|
28665
28677
|
targetOperation,
|
|
28666
28678
|
setNodes,
|
|
28667
|
-
|
|
28679
|
+
toast19,
|
|
28668
28680
|
tr
|
|
28669
28681
|
]);
|
|
28670
28682
|
useEffect(() => {
|
|
@@ -28771,7 +28783,7 @@ function VisualMapperContent({
|
|
|
28771
28783
|
}
|
|
28772
28784
|
onMappingChange(updatedMapping);
|
|
28773
28785
|
if (isCompatible) {
|
|
28774
|
-
|
|
28786
|
+
toast19({
|
|
28775
28787
|
title: tr(
|
|
28776
28788
|
"fluidgrids.builder.visualMapper.mappingCreatedTitle",
|
|
28777
28789
|
"Mapping created"
|
|
@@ -28779,7 +28791,7 @@ function VisualMapperContent({
|
|
|
28779
28791
|
description: `Mapped ${sourcePath} (${sourceType}) to ${targetPath} (${targetType})`
|
|
28780
28792
|
});
|
|
28781
28793
|
} else {
|
|
28782
|
-
|
|
28794
|
+
toast19({
|
|
28783
28795
|
title: tr(
|
|
28784
28796
|
"fluidgrids.builder.visualMapper.typeMismatchTitle",
|
|
28785
28797
|
"Type mismatch warning"
|
|
@@ -28789,7 +28801,7 @@ function VisualMapperContent({
|
|
|
28789
28801
|
});
|
|
28790
28802
|
}
|
|
28791
28803
|
} else {
|
|
28792
|
-
|
|
28804
|
+
toast19({
|
|
28793
28805
|
title: tr(
|
|
28794
28806
|
"fluidgrids.builder.visualMapper.invalidMappingTitle",
|
|
28795
28807
|
"Invalid mapping"
|
|
@@ -28802,7 +28814,7 @@ function VisualMapperContent({
|
|
|
28802
28814
|
});
|
|
28803
28815
|
}
|
|
28804
28816
|
},
|
|
28805
|
-
[nodes, mapping, onMappingChange,
|
|
28817
|
+
[nodes, mapping, onMappingChange, toast19, tr, setEdges]
|
|
28806
28818
|
);
|
|
28807
28819
|
const onEdgeDelete = useCallback(
|
|
28808
28820
|
(edge) => {
|
|
@@ -28859,7 +28871,7 @@ function VisualMapperContent({
|
|
|
28859
28871
|
const handleSaveMappingDialog = (expression, targetFieldName) => {
|
|
28860
28872
|
const targetPath = targetFieldName || selectedTargetNode?.data?.path;
|
|
28861
28873
|
if (!targetPath) {
|
|
28862
|
-
|
|
28874
|
+
toast19({
|
|
28863
28875
|
title: tr(
|
|
28864
28876
|
"fluidgrids.builder.visualMapper.noTargetFieldTitle",
|
|
28865
28877
|
"No target field specified"
|
|
@@ -28891,7 +28903,7 @@ function VisualMapperContent({
|
|
|
28891
28903
|
}
|
|
28892
28904
|
onMappingChange(updatedMapping);
|
|
28893
28905
|
const mappingType = detectMappingType(expression);
|
|
28894
|
-
|
|
28906
|
+
toast19({
|
|
28895
28907
|
title: `${mappingType.charAt(0).toUpperCase() + mappingType.slice(1)} mapping created`,
|
|
28896
28908
|
description: `${tr("fluidgrids.builder.visualMapper.appliedMappingTo", "Applied mapping to")} ${targetPath}`
|
|
28897
28909
|
});
|
|
@@ -29190,7 +29202,7 @@ function MappingEditor({
|
|
|
29190
29202
|
setEdges,
|
|
29191
29203
|
edgeId
|
|
29192
29204
|
}) {
|
|
29193
|
-
const { toast:
|
|
29205
|
+
const { toast: toast19 } = useToast();
|
|
29194
29206
|
const tr = useTr();
|
|
29195
29207
|
const [mappingJson, setMappingJson] = useState({});
|
|
29196
29208
|
const [jsonDataString, setJsonDataString] = useState(
|
|
@@ -29314,7 +29326,7 @@ function MappingEditor({
|
|
|
29314
29326
|
const handleSaveMapping = () => {
|
|
29315
29327
|
try {
|
|
29316
29328
|
checkJsonValidity();
|
|
29317
|
-
|
|
29329
|
+
toast19({
|
|
29318
29330
|
title: tr(
|
|
29319
29331
|
"fluidgrids.builder.mappingEditor.mappingSavedTitle",
|
|
29320
29332
|
"Mapping saved"
|
|
@@ -29325,7 +29337,7 @@ function MappingEditor({
|
|
|
29325
29337
|
)
|
|
29326
29338
|
});
|
|
29327
29339
|
} catch (error62) {
|
|
29328
|
-
|
|
29340
|
+
toast19({
|
|
29329
29341
|
title: tr(
|
|
29330
29342
|
"fluidgrids.builder.mappingEditor.errorSavingTitle",
|
|
29331
29343
|
"Error saving mapping"
|
|
@@ -29344,7 +29356,7 @@ function MappingEditor({
|
|
|
29344
29356
|
const parsedData = checkJsonValidity();
|
|
29345
29357
|
const result = await applyMapping(parsedData, sampleInput);
|
|
29346
29358
|
setPreviewOutput(result);
|
|
29347
|
-
|
|
29359
|
+
toast19({
|
|
29348
29360
|
title: tr(
|
|
29349
29361
|
"fluidgrids.builder.mappingEditor.mappingTestedTitle",
|
|
29350
29362
|
"Mapping tested"
|
|
@@ -29356,7 +29368,7 @@ function MappingEditor({
|
|
|
29356
29368
|
});
|
|
29357
29369
|
} catch (error62) {
|
|
29358
29370
|
console.error("Test mapping error:", error62);
|
|
29359
|
-
|
|
29371
|
+
toast19({
|
|
29360
29372
|
title: tr(
|
|
29361
29373
|
"fluidgrids.builder.mappingEditor.mappingTestFailedTitle",
|
|
29362
29374
|
"Mapping test failed"
|
|
@@ -38540,6 +38552,284 @@ function ScheduleRulesEditor({
|
|
|
38540
38552
|
}
|
|
38541
38553
|
);
|
|
38542
38554
|
}
|
|
38555
|
+
var rowInput3 = "rounded-md border border-input bg-background px-2 py-1 text-xs text-foreground outline-none focus:border-primary";
|
|
38556
|
+
function serialiseRows(rows, previous) {
|
|
38557
|
+
const rules = rows.map(ruleFromRow);
|
|
38558
|
+
return Array.isArray(previous) ? rules : JSON.stringify(rules, null, 2);
|
|
38559
|
+
}
|
|
38560
|
+
function textOf(value) {
|
|
38561
|
+
if (typeof value === "string") return value;
|
|
38562
|
+
if (value === void 0 || value === null) return "";
|
|
38563
|
+
return JSON.stringify(value, null, 2);
|
|
38564
|
+
}
|
|
38565
|
+
function AssertRulesEditor({
|
|
38566
|
+
value,
|
|
38567
|
+
onChange,
|
|
38568
|
+
testIdPrefix = "ndv"
|
|
38569
|
+
}) {
|
|
38570
|
+
const tr = useTr();
|
|
38571
|
+
const initial = readAssertRulesSetting(value);
|
|
38572
|
+
const [rows, setRows] = useState(
|
|
38573
|
+
() => rowsFromRules(initial ?? [])
|
|
38574
|
+
);
|
|
38575
|
+
const [jsonView, setJsonView] = useState(initial === null);
|
|
38576
|
+
const [jsonText, setJsonText] = useState(() => textOf(value));
|
|
38577
|
+
const written = useRef(value);
|
|
38578
|
+
useEffect(() => {
|
|
38579
|
+
if (value === written.current) return;
|
|
38580
|
+
written.current = value;
|
|
38581
|
+
const parsed = readAssertRulesSetting(value);
|
|
38582
|
+
setJsonText(textOf(value));
|
|
38583
|
+
if (parsed === null) {
|
|
38584
|
+
setJsonView(true);
|
|
38585
|
+
} else {
|
|
38586
|
+
setRows(rowsFromRules(parsed));
|
|
38587
|
+
}
|
|
38588
|
+
}, [value]);
|
|
38589
|
+
const write = (next) => {
|
|
38590
|
+
written.current = next;
|
|
38591
|
+
onChange(next);
|
|
38592
|
+
};
|
|
38593
|
+
const setRowList = (next) => {
|
|
38594
|
+
setRows(next);
|
|
38595
|
+
const serialised = serialiseRows(next, value);
|
|
38596
|
+
setJsonText(textOf(serialised));
|
|
38597
|
+
write(serialised);
|
|
38598
|
+
};
|
|
38599
|
+
const setRow = (index, patch) => {
|
|
38600
|
+
const next = rows.slice();
|
|
38601
|
+
const current = next[index];
|
|
38602
|
+
if (!current) return;
|
|
38603
|
+
next[index] = { ...current, ...patch };
|
|
38604
|
+
setRowList(next);
|
|
38605
|
+
};
|
|
38606
|
+
const parsedJson = jsonView ? readAssertRulesSetting(jsonText) : null;
|
|
38607
|
+
const check2 = normaliseAssertRules(
|
|
38608
|
+
jsonView ? parsedJson ?? [] : rows.map(ruleFromRow)
|
|
38609
|
+
);
|
|
38610
|
+
const problem = jsonView && parsedJson === null ? {
|
|
38611
|
+
key: "fluidgrids.builder.assertRules.invalidJson",
|
|
38612
|
+
fallback: "The rules must be a JSON array."
|
|
38613
|
+
} : "problem" in check2 ? describeAssertRuleProblem(check2.problem) : null;
|
|
38614
|
+
const toggleView = () => {
|
|
38615
|
+
if (jsonView) {
|
|
38616
|
+
const parsed = readAssertRulesSetting(jsonText);
|
|
38617
|
+
if (parsed === null) return;
|
|
38618
|
+
setRows(rowsFromRules(parsed));
|
|
38619
|
+
setJsonView(false);
|
|
38620
|
+
} else {
|
|
38621
|
+
setJsonText(textOf(serialiseRows(rows, value)));
|
|
38622
|
+
setJsonView(true);
|
|
38623
|
+
}
|
|
38624
|
+
};
|
|
38625
|
+
return /* @__PURE__ */ jsxs(
|
|
38626
|
+
"div",
|
|
38627
|
+
{
|
|
38628
|
+
className: "flex flex-col gap-2",
|
|
38629
|
+
"data-testid": `${testIdPrefix}-assert-rules`,
|
|
38630
|
+
children: [
|
|
38631
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-end", children: /* @__PURE__ */ jsx(
|
|
38632
|
+
"button",
|
|
38633
|
+
{
|
|
38634
|
+
type: "button",
|
|
38635
|
+
onClick: toggleView,
|
|
38636
|
+
disabled: jsonView && parsedJson === null,
|
|
38637
|
+
className: "text-[11px] text-primary hover:underline disabled:opacity-50",
|
|
38638
|
+
"data-testid": `${testIdPrefix}-assert-rules-view`,
|
|
38639
|
+
children: jsonView ? tr("fluidgrids.builder.assertRules.showRows", "Edit as rows") : tr("fluidgrids.builder.assertRules.showJson", "Edit as JSON")
|
|
38640
|
+
}
|
|
38641
|
+
) }),
|
|
38642
|
+
jsonView ? /* @__PURE__ */ jsx(
|
|
38643
|
+
"textarea",
|
|
38644
|
+
{
|
|
38645
|
+
value: jsonText,
|
|
38646
|
+
rows: 8,
|
|
38647
|
+
spellCheck: false,
|
|
38648
|
+
"aria-label": tr(
|
|
38649
|
+
"fluidgrids.builder.assertRules.jsonLabel",
|
|
38650
|
+
"Rules (JSON array)"
|
|
38651
|
+
),
|
|
38652
|
+
onChange: (event) => {
|
|
38653
|
+
setJsonText(event.target.value);
|
|
38654
|
+
write(
|
|
38655
|
+
Array.isArray(value) ? readAssertRulesSetting(event.target.value) ?? value : event.target.value
|
|
38656
|
+
);
|
|
38657
|
+
},
|
|
38658
|
+
className: cn$1(rowInput3, "w-full font-mono"),
|
|
38659
|
+
"data-testid": `${testIdPrefix}-assert-rules-json`
|
|
38660
|
+
}
|
|
38661
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
38662
|
+
rows.length === 0 && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: tr(
|
|
38663
|
+
"fluidgrids.builder.assertRules.empty",
|
|
38664
|
+
"Add at least one rule."
|
|
38665
|
+
) }),
|
|
38666
|
+
rows.map((row, index) => {
|
|
38667
|
+
const operand = operatorSpec(row.operator)?.operand ?? "expected";
|
|
38668
|
+
return /* @__PURE__ */ jsxs(
|
|
38669
|
+
"div",
|
|
38670
|
+
{
|
|
38671
|
+
className: "rounded-md border border-border p-2",
|
|
38672
|
+
"data-testid": `${testIdPrefix}-assert-rule-${index}`,
|
|
38673
|
+
children: [
|
|
38674
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
38675
|
+
/* @__PURE__ */ jsxs("span", { className: "text-[10px] font-semibold text-muted-foreground", children: [
|
|
38676
|
+
index + 1,
|
|
38677
|
+
"."
|
|
38678
|
+
] }),
|
|
38679
|
+
/* @__PURE__ */ jsx(
|
|
38680
|
+
"input",
|
|
38681
|
+
{
|
|
38682
|
+
type: "text",
|
|
38683
|
+
value: row.path,
|
|
38684
|
+
placeholder: tr(
|
|
38685
|
+
"fluidgrids.builder.assertRules.pathPlaceholder",
|
|
38686
|
+
"path, e.g. body.items.0.id (empty = whole input)"
|
|
38687
|
+
),
|
|
38688
|
+
"aria-label": tr(
|
|
38689
|
+
"fluidgrids.builder.assertRules.path",
|
|
38690
|
+
"Path"
|
|
38691
|
+
),
|
|
38692
|
+
onChange: (event) => setRow(index, { path: event.target.value }),
|
|
38693
|
+
className: cn$1(rowInput3, "min-w-0 flex-1 font-mono")
|
|
38694
|
+
}
|
|
38695
|
+
),
|
|
38696
|
+
/* @__PURE__ */ jsx(
|
|
38697
|
+
"select",
|
|
38698
|
+
{
|
|
38699
|
+
value: row.operator,
|
|
38700
|
+
"aria-label": tr(
|
|
38701
|
+
"fluidgrids.builder.assertRules.operator",
|
|
38702
|
+
"Operator"
|
|
38703
|
+
),
|
|
38704
|
+
onChange: (event) => setRow(index, { operator: event.target.value }),
|
|
38705
|
+
className: rowInput3,
|
|
38706
|
+
children: ASSERT_OPERATORS.map((spec) => /* @__PURE__ */ jsx("option", { value: spec.wire, children: tr(
|
|
38707
|
+
`fluidgrids.builder.assertRules.op.${spec.wire}`,
|
|
38708
|
+
spec.label
|
|
38709
|
+
) }, spec.wire))
|
|
38710
|
+
}
|
|
38711
|
+
),
|
|
38712
|
+
/* @__PURE__ */ jsx(
|
|
38713
|
+
"button",
|
|
38714
|
+
{
|
|
38715
|
+
type: "button",
|
|
38716
|
+
onClick: () => setRowList(rows.filter((_, i) => i !== index)),
|
|
38717
|
+
title: tr(
|
|
38718
|
+
"fluidgrids.builder.assertRules.remove",
|
|
38719
|
+
"Remove rule"
|
|
38720
|
+
),
|
|
38721
|
+
className: "rounded p-0.5 text-muted-foreground hover:text-[var(--color-status-error-text)]",
|
|
38722
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-4" })
|
|
38723
|
+
}
|
|
38724
|
+
)
|
|
38725
|
+
] }),
|
|
38726
|
+
operand === "expected" && /* @__PURE__ */ jsx(
|
|
38727
|
+
"input",
|
|
38728
|
+
{
|
|
38729
|
+
type: "text",
|
|
38730
|
+
value: row.expected,
|
|
38731
|
+
placeholder: row.operator === "matches" ? tr(
|
|
38732
|
+
"fluidgrids.builder.assertRules.regexPlaceholder",
|
|
38733
|
+
"regular expression, e.g. ^ord_"
|
|
38734
|
+
) : tr(
|
|
38735
|
+
"fluidgrids.builder.assertRules.expectedPlaceholder",
|
|
38736
|
+
'expected value as JSON, e.g. 42, "ok" or {"a": 1}'
|
|
38737
|
+
),
|
|
38738
|
+
"aria-label": tr(
|
|
38739
|
+
"fluidgrids.builder.assertRules.expected",
|
|
38740
|
+
"Expected"
|
|
38741
|
+
),
|
|
38742
|
+
onChange: (event) => setRow(index, { expected: event.target.value }),
|
|
38743
|
+
className: cn$1(rowInput3, "mt-1.5 w-full font-mono")
|
|
38744
|
+
}
|
|
38745
|
+
),
|
|
38746
|
+
operand === "range" && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 flex gap-1.5", children: [
|
|
38747
|
+
/* @__PURE__ */ jsx(
|
|
38748
|
+
"input",
|
|
38749
|
+
{
|
|
38750
|
+
type: "text",
|
|
38751
|
+
inputMode: "decimal",
|
|
38752
|
+
value: row.min,
|
|
38753
|
+
placeholder: tr(
|
|
38754
|
+
"fluidgrids.builder.assertRules.min",
|
|
38755
|
+
"min"
|
|
38756
|
+
),
|
|
38757
|
+
"aria-label": tr(
|
|
38758
|
+
"fluidgrids.builder.assertRules.min",
|
|
38759
|
+
"min"
|
|
38760
|
+
),
|
|
38761
|
+
onChange: (event) => setRow(index, { min: event.target.value }),
|
|
38762
|
+
className: cn$1(rowInput3, "w-full")
|
|
38763
|
+
}
|
|
38764
|
+
),
|
|
38765
|
+
/* @__PURE__ */ jsx(
|
|
38766
|
+
"input",
|
|
38767
|
+
{
|
|
38768
|
+
type: "text",
|
|
38769
|
+
inputMode: "decimal",
|
|
38770
|
+
value: row.max,
|
|
38771
|
+
placeholder: tr(
|
|
38772
|
+
"fluidgrids.builder.assertRules.max",
|
|
38773
|
+
"max"
|
|
38774
|
+
),
|
|
38775
|
+
"aria-label": tr(
|
|
38776
|
+
"fluidgrids.builder.assertRules.max",
|
|
38777
|
+
"max"
|
|
38778
|
+
),
|
|
38779
|
+
onChange: (event) => setRow(index, { max: event.target.value }),
|
|
38780
|
+
className: cn$1(rowInput3, "w-full")
|
|
38781
|
+
}
|
|
38782
|
+
)
|
|
38783
|
+
] }),
|
|
38784
|
+
/* @__PURE__ */ jsx(
|
|
38785
|
+
"input",
|
|
38786
|
+
{
|
|
38787
|
+
type: "text",
|
|
38788
|
+
value: row.message,
|
|
38789
|
+
placeholder: tr(
|
|
38790
|
+
"fluidgrids.builder.assertRules.messagePlaceholder",
|
|
38791
|
+
"message when it does not hold (optional)"
|
|
38792
|
+
),
|
|
38793
|
+
"aria-label": tr(
|
|
38794
|
+
"fluidgrids.builder.assertRules.message",
|
|
38795
|
+
"Message"
|
|
38796
|
+
),
|
|
38797
|
+
onChange: (event) => setRow(index, { message: event.target.value }),
|
|
38798
|
+
className: cn$1(rowInput3, "mt-1.5 w-full")
|
|
38799
|
+
}
|
|
38800
|
+
)
|
|
38801
|
+
]
|
|
38802
|
+
},
|
|
38803
|
+
index
|
|
38804
|
+
);
|
|
38805
|
+
}),
|
|
38806
|
+
/* @__PURE__ */ jsxs(
|
|
38807
|
+
"button",
|
|
38808
|
+
{
|
|
38809
|
+
type: "button",
|
|
38810
|
+
onClick: () => setRowList([...rows, emptyAssertRuleRow()]),
|
|
38811
|
+
className: "flex items-center gap-1 self-start text-xs text-primary hover:underline",
|
|
38812
|
+
"data-testid": `${testIdPrefix}-assert-rule-add`,
|
|
38813
|
+
children: [
|
|
38814
|
+
/* @__PURE__ */ jsx(Plus, { className: "size-3.5" }),
|
|
38815
|
+
tr("fluidgrids.builder.assertRules.add", "Add rule")
|
|
38816
|
+
]
|
|
38817
|
+
}
|
|
38818
|
+
)
|
|
38819
|
+
] }),
|
|
38820
|
+
problem && /* @__PURE__ */ jsx(
|
|
38821
|
+
"p",
|
|
38822
|
+
{
|
|
38823
|
+
className: "text-[11px] text-[var(--color-status-error-text)]",
|
|
38824
|
+
role: "alert",
|
|
38825
|
+
"data-testid": `${testIdPrefix}-assert-rules-problem`,
|
|
38826
|
+
children: tr(problem.key, problem.fallback)
|
|
38827
|
+
}
|
|
38828
|
+
)
|
|
38829
|
+
]
|
|
38830
|
+
}
|
|
38831
|
+
);
|
|
38832
|
+
}
|
|
38543
38833
|
function formatRunInZone(date5, timezone) {
|
|
38544
38834
|
try {
|
|
38545
38835
|
return new Intl.DateTimeFormat(void 0, {
|
|
@@ -39446,6 +39736,25 @@ function NodeParamsForm({
|
|
|
39446
39736
|
)
|
|
39447
39737
|
] }, p.name);
|
|
39448
39738
|
}
|
|
39739
|
+
if (nodeType === "internal:assert" && p.name === "rules") {
|
|
39740
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
39741
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
39742
|
+
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-foreground", children: tr(
|
|
39743
|
+
"fluidgrids.builder.nodeParamsForm.assertRulesLabel",
|
|
39744
|
+
"Rules"
|
|
39745
|
+
) }),
|
|
39746
|
+
p.required && /* @__PURE__ */ jsx("span", { className: "text-destructive", children: "*" })
|
|
39747
|
+
] }),
|
|
39748
|
+
/* @__PURE__ */ jsx(
|
|
39749
|
+
AssertRulesEditor,
|
|
39750
|
+
{
|
|
39751
|
+
value: argsState[p.name],
|
|
39752
|
+
onChange: (next) => writeFixed(p.name, next),
|
|
39753
|
+
testIdPrefix
|
|
39754
|
+
}
|
|
39755
|
+
)
|
|
39756
|
+
] }, p.name);
|
|
39757
|
+
}
|
|
39449
39758
|
if (p.type === "workflow" || nodeType === "internal:subworkflow" && p.name === "workflowKey") {
|
|
39450
39759
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
39451
39760
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
@@ -43437,7 +43746,7 @@ function TriggerDataDialog({
|
|
|
43437
43746
|
"."
|
|
43438
43747
|
] })
|
|
43439
43748
|
] }),
|
|
43440
|
-
/* @__PURE__ */ jsxs(DialogFooter, { className: "gap-2 sm:gap-0", children: [
|
|
43749
|
+
/* @__PURE__ */ jsxs(DialogFooter$1, { className: "gap-2 sm:gap-0", children: [
|
|
43441
43750
|
/* @__PURE__ */ jsx(
|
|
43442
43751
|
Button$1,
|
|
43443
43752
|
{
|
|
@@ -47282,6 +47591,918 @@ function GitSyncPanel({
|
|
|
47282
47591
|
}
|
|
47283
47592
|
);
|
|
47284
47593
|
}
|
|
47594
|
+
var JSON_FIELDS = [
|
|
47595
|
+
{
|
|
47596
|
+
field: "triggerData",
|
|
47597
|
+
key: "triggerData",
|
|
47598
|
+
label: "Trigger input",
|
|
47599
|
+
hint: "The JSON object the run starts with.",
|
|
47600
|
+
rows: 4
|
|
47601
|
+
},
|
|
47602
|
+
{
|
|
47603
|
+
field: "connectionMocks",
|
|
47604
|
+
key: "connectionMocks",
|
|
47605
|
+
label: "Connection mocks",
|
|
47606
|
+
hint: '[{ "nodeId": "...", "operation"?: "...", "response": { ... } }] or an "error": { "message": "..." } instead of "response". A mocked node never calls its connection.',
|
|
47607
|
+
rows: 6
|
|
47608
|
+
},
|
|
47609
|
+
{
|
|
47610
|
+
field: "pinnedOutputs",
|
|
47611
|
+
key: "pinnedOutputs",
|
|
47612
|
+
label: "Pinned outputs",
|
|
47613
|
+
hint: '{ "nodeId": { "data": { ... } } }: the node is skipped and returns this output.',
|
|
47614
|
+
rows: 5
|
|
47615
|
+
},
|
|
47616
|
+
{
|
|
47617
|
+
field: "expectations",
|
|
47618
|
+
key: "expectations",
|
|
47619
|
+
label: "Expectations",
|
|
47620
|
+
hint: '{ "nodeId": [{ "path": "total", "operator": "equals", "expected": 42 }] }. Operators: equals, notEquals, contains, notContains, matches, jsonSchema, between, itemCount, exists, notExists.',
|
|
47621
|
+
rows: 6
|
|
47622
|
+
}
|
|
47623
|
+
];
|
|
47624
|
+
var fieldClass = (invalid) => cn$1(
|
|
47625
|
+
"font-mono text-xs",
|
|
47626
|
+
invalid && "border-[var(--color-status-error-border)]"
|
|
47627
|
+
);
|
|
47628
|
+
function WorkflowTestCaseDialog({
|
|
47629
|
+
open: open2,
|
|
47630
|
+
mode,
|
|
47631
|
+
initialDraft,
|
|
47632
|
+
nodes,
|
|
47633
|
+
canvasPinnedOutputs,
|
|
47634
|
+
onSave,
|
|
47635
|
+
onOpenChange
|
|
47636
|
+
}) {
|
|
47637
|
+
const tr = useTr();
|
|
47638
|
+
const [draft, setDraft] = useState(initialDraft);
|
|
47639
|
+
const [problem, setProblem] = useState(null);
|
|
47640
|
+
const [saving, setSaving] = useState(false);
|
|
47641
|
+
useEffect(() => {
|
|
47642
|
+
if (open2) {
|
|
47643
|
+
setDraft(initialDraft);
|
|
47644
|
+
setProblem(null);
|
|
47645
|
+
}
|
|
47646
|
+
}, [open2, initialDraft]);
|
|
47647
|
+
const update = (key, value) => {
|
|
47648
|
+
setDraft((current) => ({ ...current, [key]: value }));
|
|
47649
|
+
setProblem(
|
|
47650
|
+
(current) => current && current.field === key ? null : current
|
|
47651
|
+
);
|
|
47652
|
+
};
|
|
47653
|
+
const hasCanvasPins = Object.keys(canvasPinnedOutputs).length > 0;
|
|
47654
|
+
const handleSave = async () => {
|
|
47655
|
+
setSaving(true);
|
|
47656
|
+
try {
|
|
47657
|
+
const result = await onSave(draft);
|
|
47658
|
+
setProblem(result);
|
|
47659
|
+
} finally {
|
|
47660
|
+
setSaving(false);
|
|
47661
|
+
}
|
|
47662
|
+
};
|
|
47663
|
+
const problemFor = (field) => problem && problem.field === field ? /* @__PURE__ */ jsx(
|
|
47664
|
+
"p",
|
|
47665
|
+
{
|
|
47666
|
+
className: "text-xs text-[var(--color-status-error-text)]",
|
|
47667
|
+
role: "alert",
|
|
47668
|
+
"data-testid": `fluidgrids-test-case-error-${field}`,
|
|
47669
|
+
children: problem.raw ? problem.fallback : tr(problem.key, problem.fallback)
|
|
47670
|
+
}
|
|
47671
|
+
) : null;
|
|
47672
|
+
return /* @__PURE__ */ jsx(Dialog, { open: open2, onOpenChange: (next) => !saving && onOpenChange(next), children: /* @__PURE__ */ jsxs(
|
|
47673
|
+
DialogContent,
|
|
47674
|
+
{
|
|
47675
|
+
className: "z-[120] max-h-[90vh] overflow-y-auto sm:max-w-2xl",
|
|
47676
|
+
"data-testid": "fluidgrids-test-case-dialog",
|
|
47677
|
+
children: [
|
|
47678
|
+
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
47679
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: mode === "create" ? tr("fluidgrids.builder.workflowTests.newTitle", "New test case") : tr(
|
|
47680
|
+
"fluidgrids.builder.workflowTests.editTitle",
|
|
47681
|
+
"Edit test case"
|
|
47682
|
+
) }),
|
|
47683
|
+
/* @__PURE__ */ jsx(DialogDescription, { children: tr(
|
|
47684
|
+
"fluidgrids.builder.workflowTests.editorDescription",
|
|
47685
|
+
"A test case runs the workflow in test mode with this input. Mocked and pinned nodes never reach a real connection, and the expectations are checked as each node completes."
|
|
47686
|
+
) })
|
|
47687
|
+
] }),
|
|
47688
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
47689
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
47690
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "fg-test-case-name", className: "text-xs", children: tr("fluidgrids.builder.workflowTests.nameLabel", "Name") }),
|
|
47691
|
+
/* @__PURE__ */ jsx(
|
|
47692
|
+
Input$1,
|
|
47693
|
+
{
|
|
47694
|
+
id: "fg-test-case-name",
|
|
47695
|
+
value: draft.name,
|
|
47696
|
+
maxLength: MAX_CASE_NAME,
|
|
47697
|
+
onChange: (event) => update("name", event.target.value),
|
|
47698
|
+
"data-testid": "fluidgrids-test-case-name"
|
|
47699
|
+
}
|
|
47700
|
+
),
|
|
47701
|
+
problemFor("name")
|
|
47702
|
+
] }),
|
|
47703
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
47704
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "fg-test-case-description", className: "text-xs", children: tr(
|
|
47705
|
+
"fluidgrids.builder.workflowTests.descriptionLabel",
|
|
47706
|
+
"Description (optional)"
|
|
47707
|
+
) }),
|
|
47708
|
+
/* @__PURE__ */ jsx(
|
|
47709
|
+
Textarea,
|
|
47710
|
+
{
|
|
47711
|
+
id: "fg-test-case-description",
|
|
47712
|
+
value: draft.description,
|
|
47713
|
+
rows: 2,
|
|
47714
|
+
onChange: (event) => update("description", event.target.value)
|
|
47715
|
+
}
|
|
47716
|
+
)
|
|
47717
|
+
] }),
|
|
47718
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [
|
|
47719
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
47720
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "fg-test-case-start", className: "text-xs", children: tr(
|
|
47721
|
+
"fluidgrids.builder.workflowTests.startNodeLabel",
|
|
47722
|
+
"Start on"
|
|
47723
|
+
) }),
|
|
47724
|
+
/* @__PURE__ */ jsxs(
|
|
47725
|
+
"select",
|
|
47726
|
+
{
|
|
47727
|
+
id: "fg-test-case-start",
|
|
47728
|
+
value: draft.triggerNodeId,
|
|
47729
|
+
onChange: (event) => update("triggerNodeId", event.target.value),
|
|
47730
|
+
className: "w-full rounded-md border border-input bg-background px-2 py-1.5 text-sm text-foreground",
|
|
47731
|
+
children: [
|
|
47732
|
+
/* @__PURE__ */ jsx("option", { value: "", children: tr(
|
|
47733
|
+
"fluidgrids.builder.workflowTests.startNodeDefault",
|
|
47734
|
+
"The workflow's entry node"
|
|
47735
|
+
) }),
|
|
47736
|
+
nodes.map((node2) => /* @__PURE__ */ jsx("option", { value: node2.id, children: node2.label }, node2.id))
|
|
47737
|
+
]
|
|
47738
|
+
}
|
|
47739
|
+
)
|
|
47740
|
+
] }),
|
|
47741
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
47742
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "fg-test-case-expected", className: "text-xs", children: tr(
|
|
47743
|
+
"fluidgrids.builder.workflowTests.expectedStatusLabel",
|
|
47744
|
+
"The run should"
|
|
47745
|
+
) }),
|
|
47746
|
+
/* @__PURE__ */ jsxs(
|
|
47747
|
+
"select",
|
|
47748
|
+
{
|
|
47749
|
+
id: "fg-test-case-expected",
|
|
47750
|
+
value: draft.expectedStatus,
|
|
47751
|
+
onChange: (event) => update(
|
|
47752
|
+
"expectedStatus",
|
|
47753
|
+
event.target.value === "FAILED" /* Failed */ ? "FAILED" /* Failed */ : "COMPLETED" /* Completed */
|
|
47754
|
+
),
|
|
47755
|
+
className: "w-full rounded-md border border-input bg-background px-2 py-1.5 text-sm text-foreground",
|
|
47756
|
+
children: [
|
|
47757
|
+
/* @__PURE__ */ jsx("option", { value: "COMPLETED" /* Completed */, children: tr(
|
|
47758
|
+
"fluidgrids.builder.workflowTests.expectCompleted",
|
|
47759
|
+
"Complete"
|
|
47760
|
+
) }),
|
|
47761
|
+
/* @__PURE__ */ jsx("option", { value: "FAILED" /* Failed */, children: tr("fluidgrids.builder.workflowTests.expectFailed", "Fail") })
|
|
47762
|
+
]
|
|
47763
|
+
}
|
|
47764
|
+
)
|
|
47765
|
+
] })
|
|
47766
|
+
] }),
|
|
47767
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 rounded-md border border-border p-2.5", children: [
|
|
47768
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "fg-test-case-enabled", className: "text-xs", children: tr(
|
|
47769
|
+
"fluidgrids.builder.workflowTests.enabledLabel",
|
|
47770
|
+
"Run this case with Run all"
|
|
47771
|
+
) }),
|
|
47772
|
+
/* @__PURE__ */ jsx(
|
|
47773
|
+
Switch,
|
|
47774
|
+
{
|
|
47775
|
+
id: "fg-test-case-enabled",
|
|
47776
|
+
checked: draft.enabled,
|
|
47777
|
+
onCheckedChange: (checked) => update("enabled", checked)
|
|
47778
|
+
}
|
|
47779
|
+
)
|
|
47780
|
+
] }),
|
|
47781
|
+
JSON_FIELDS.map((item) => /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
47782
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
47783
|
+
/* @__PURE__ */ jsx(
|
|
47784
|
+
Label,
|
|
47785
|
+
{
|
|
47786
|
+
htmlFor: `fg-test-case-${item.field}`,
|
|
47787
|
+
className: "text-xs",
|
|
47788
|
+
children: tr(
|
|
47789
|
+
`fluidgrids.builder.workflowTests.${item.key}Label`,
|
|
47790
|
+
item.label
|
|
47791
|
+
)
|
|
47792
|
+
}
|
|
47793
|
+
),
|
|
47794
|
+
item.field === "pinnedOutputs" && hasCanvasPins && /* @__PURE__ */ jsx(
|
|
47795
|
+
Button$1,
|
|
47796
|
+
{
|
|
47797
|
+
type: "button",
|
|
47798
|
+
variant: "ghost",
|
|
47799
|
+
size: "sm",
|
|
47800
|
+
className: "h-6 px-2 text-xs",
|
|
47801
|
+
onClick: () => update(
|
|
47802
|
+
"pinnedOutputs",
|
|
47803
|
+
JSON.stringify(canvasPinnedOutputs, null, 2)
|
|
47804
|
+
),
|
|
47805
|
+
"data-testid": "fluidgrids-test-case-use-pins",
|
|
47806
|
+
children: tr(
|
|
47807
|
+
"fluidgrids.builder.workflowTests.useCanvasPins",
|
|
47808
|
+
"Use the canvas's pinned data"
|
|
47809
|
+
)
|
|
47810
|
+
}
|
|
47811
|
+
)
|
|
47812
|
+
] }),
|
|
47813
|
+
/* @__PURE__ */ jsx(
|
|
47814
|
+
Textarea,
|
|
47815
|
+
{
|
|
47816
|
+
id: `fg-test-case-${item.field}`,
|
|
47817
|
+
value: draft[item.field],
|
|
47818
|
+
rows: item.rows,
|
|
47819
|
+
spellCheck: false,
|
|
47820
|
+
className: fieldClass(problem?.field === item.field),
|
|
47821
|
+
onChange: (event) => update(item.field, event.target.value),
|
|
47822
|
+
"data-testid": `fluidgrids-test-case-${item.field}`
|
|
47823
|
+
}
|
|
47824
|
+
),
|
|
47825
|
+
/* @__PURE__ */ jsx("p", { className: "text-[11px] leading-snug text-muted-foreground", children: tr(
|
|
47826
|
+
`fluidgrids.builder.workflowTests.${item.key}Hint`,
|
|
47827
|
+
item.hint
|
|
47828
|
+
) }),
|
|
47829
|
+
problemFor(item.field)
|
|
47830
|
+
] }, item.field)),
|
|
47831
|
+
problemFor("size")
|
|
47832
|
+
] }),
|
|
47833
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
47834
|
+
/* @__PURE__ */ jsx(
|
|
47835
|
+
Button$1,
|
|
47836
|
+
{
|
|
47837
|
+
variant: "outline",
|
|
47838
|
+
disabled: saving,
|
|
47839
|
+
onClick: () => onOpenChange(false),
|
|
47840
|
+
children: tr("fluidgrids.builder.workflowTests.cancel", "Cancel")
|
|
47841
|
+
}
|
|
47842
|
+
),
|
|
47843
|
+
/* @__PURE__ */ jsxs(
|
|
47844
|
+
Button$1,
|
|
47845
|
+
{
|
|
47846
|
+
disabled: saving,
|
|
47847
|
+
onClick: () => void handleSave(),
|
|
47848
|
+
"data-testid": "fluidgrids-test-case-save",
|
|
47849
|
+
children: [
|
|
47850
|
+
saving && /* @__PURE__ */ jsx(Loader2, { className: "mr-1 size-4 animate-spin" }),
|
|
47851
|
+
mode === "create" ? tr("fluidgrids.builder.workflowTests.create", "Save test case") : tr("fluidgrids.builder.workflowTests.save", "Save changes")
|
|
47852
|
+
]
|
|
47853
|
+
}
|
|
47854
|
+
)
|
|
47855
|
+
] })
|
|
47856
|
+
]
|
|
47857
|
+
}
|
|
47858
|
+
) });
|
|
47859
|
+
}
|
|
47860
|
+
function WorkflowTestStatusBadge({
|
|
47861
|
+
status,
|
|
47862
|
+
className
|
|
47863
|
+
}) {
|
|
47864
|
+
const tr = useTr();
|
|
47865
|
+
const label = testStatusLabel(status);
|
|
47866
|
+
return /* @__PURE__ */ jsx(
|
|
47867
|
+
Badge,
|
|
47868
|
+
{
|
|
47869
|
+
variant: "outline",
|
|
47870
|
+
className: cn$1(
|
|
47871
|
+
"h-5 shrink-0 px-1.5 py-0 text-[10px]",
|
|
47872
|
+
TEST_STATUS_TONE_CLASS[testStatusTone(status)],
|
|
47873
|
+
className
|
|
47874
|
+
),
|
|
47875
|
+
"data-status": status,
|
|
47876
|
+
"data-testid": "fluidgrids-test-status",
|
|
47877
|
+
children: tr(label.key, label.fallback)
|
|
47878
|
+
}
|
|
47879
|
+
);
|
|
47880
|
+
}
|
|
47881
|
+
function WorkflowTestCaseResultItem({
|
|
47882
|
+
result,
|
|
47883
|
+
onOpenRun
|
|
47884
|
+
}) {
|
|
47885
|
+
const tr = useTr();
|
|
47886
|
+
return /* @__PURE__ */ jsxs(
|
|
47887
|
+
"li",
|
|
47888
|
+
{
|
|
47889
|
+
className: "rounded-md border border-border p-2",
|
|
47890
|
+
"data-testid": "fluidgrids-test-result",
|
|
47891
|
+
children: [
|
|
47892
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
47893
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate text-sm text-foreground", children: result.caseName }),
|
|
47894
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [
|
|
47895
|
+
/* @__PURE__ */ jsx(WorkflowTestStatusBadge, { status: result.status }),
|
|
47896
|
+
result.runId && /* @__PURE__ */ jsxs(
|
|
47897
|
+
"button",
|
|
47898
|
+
{
|
|
47899
|
+
type: "button",
|
|
47900
|
+
className: "inline-flex items-center gap-0.5 text-xs text-primary hover:underline",
|
|
47901
|
+
onClick: () => result.runId && onOpenRun(result.runId),
|
|
47902
|
+
"data-testid": "fluidgrids-test-result-run",
|
|
47903
|
+
children: [
|
|
47904
|
+
tr("fluidgrids.builder.workflowTests.openRun", "Run"),
|
|
47905
|
+
/* @__PURE__ */ jsx(ExternalLink, { className: "size-3" })
|
|
47906
|
+
]
|
|
47907
|
+
}
|
|
47908
|
+
)
|
|
47909
|
+
] })
|
|
47910
|
+
] }),
|
|
47911
|
+
result.failures.length > 0 && /* @__PURE__ */ jsx("ul", { className: "mt-1.5 space-y-1", children: result.failures.map((failure2, index) => /* @__PURE__ */ jsxs(
|
|
47912
|
+
"li",
|
|
47913
|
+
{
|
|
47914
|
+
className: "text-xs text-muted-foreground",
|
|
47915
|
+
"data-testid": "fluidgrids-test-failure",
|
|
47916
|
+
children: [
|
|
47917
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-[var(--color-status-error-text)]", children: failure2.code }),
|
|
47918
|
+
failure2.nodeId && /* @__PURE__ */ jsxs("span", { className: "font-mono", children: [
|
|
47919
|
+
" \xB7 ",
|
|
47920
|
+
failure2.nodeId
|
|
47921
|
+
] }),
|
|
47922
|
+
/* @__PURE__ */ jsx("span", { className: "block whitespace-pre-wrap break-words text-foreground", children: failure2.message })
|
|
47923
|
+
]
|
|
47924
|
+
},
|
|
47925
|
+
`${failure2.code}-${failure2.nodeId ?? ""}-${index}`
|
|
47926
|
+
)) })
|
|
47927
|
+
]
|
|
47928
|
+
}
|
|
47929
|
+
);
|
|
47930
|
+
}
|
|
47931
|
+
function WorkflowTestRunCard({
|
|
47932
|
+
run,
|
|
47933
|
+
onOpenRun
|
|
47934
|
+
}) {
|
|
47935
|
+
const tr = useTr();
|
|
47936
|
+
return /* @__PURE__ */ jsxs(
|
|
47937
|
+
"div",
|
|
47938
|
+
{
|
|
47939
|
+
className: "rounded-lg border border-border p-3",
|
|
47940
|
+
"data-testid": "fluidgrids-test-run",
|
|
47941
|
+
"data-status": run.status,
|
|
47942
|
+
children: [
|
|
47943
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
47944
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
47945
|
+
/* @__PURE__ */ jsxs("p", { className: "text-sm font-medium text-foreground", children: [
|
|
47946
|
+
tr("fluidgrids.builder.workflowTests.suiteRun", "Test run"),
|
|
47947
|
+
" ",
|
|
47948
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-xs text-muted-foreground", children: run.version })
|
|
47949
|
+
] }),
|
|
47950
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
47951
|
+
testRunSummaryText(run.summary),
|
|
47952
|
+
" \xB7 ",
|
|
47953
|
+
relativeTime(run.startedAt)
|
|
47954
|
+
] })
|
|
47955
|
+
] }),
|
|
47956
|
+
/* @__PURE__ */ jsx(WorkflowTestStatusBadge, { status: run.status })
|
|
47957
|
+
] }),
|
|
47958
|
+
run.results.length > 0 && /* @__PURE__ */ jsx("ul", { className: "mt-2 space-y-1.5", children: run.results.map((result) => /* @__PURE__ */ jsx(
|
|
47959
|
+
WorkflowTestCaseResultItem,
|
|
47960
|
+
{
|
|
47961
|
+
result,
|
|
47962
|
+
onOpenRun
|
|
47963
|
+
},
|
|
47964
|
+
result.caseId
|
|
47965
|
+
)) })
|
|
47966
|
+
]
|
|
47967
|
+
}
|
|
47968
|
+
);
|
|
47969
|
+
}
|
|
47970
|
+
function WorkflowTestCaseRow({
|
|
47971
|
+
testCase,
|
|
47972
|
+
actions
|
|
47973
|
+
}) {
|
|
47974
|
+
const tr = useTr();
|
|
47975
|
+
return /* @__PURE__ */ jsxs(
|
|
47976
|
+
"li",
|
|
47977
|
+
{
|
|
47978
|
+
className: "rounded-lg border border-border p-3",
|
|
47979
|
+
"data-testid": "fluidgrids-test-case",
|
|
47980
|
+
children: [
|
|
47981
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
47982
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
47983
|
+
/* @__PURE__ */ jsx("p", { className: "truncate text-sm font-medium text-foreground", children: testCase.name }),
|
|
47984
|
+
testCase.description && /* @__PURE__ */ jsx("p", { className: "mt-0.5 line-clamp-2 text-xs text-muted-foreground", children: testCase.description }),
|
|
47985
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-[11px] text-muted-foreground", children: [
|
|
47986
|
+
testCase.connectionMocks.length > 0 ? `${testCase.connectionMocks.length} ${tr("fluidgrids.builder.workflowTests.mocks", "mocked")}` : null,
|
|
47987
|
+
testCase.expectations.length > 0 ? `${testCase.expectations.length} ${tr("fluidgrids.builder.workflowTests.checked", "checked")}` : null,
|
|
47988
|
+
testCase.lastResult?.completedAt ? `${tr("fluidgrids.builder.workflowTests.lastRun", "last run")} ${relativeTime(testCase.lastResult.completedAt)}` : null
|
|
47989
|
+
].filter(Boolean).join(" \xB7 ") })
|
|
47990
|
+
] }),
|
|
47991
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [
|
|
47992
|
+
!testCase.enabled && /* @__PURE__ */ jsx(
|
|
47993
|
+
Badge,
|
|
47994
|
+
{
|
|
47995
|
+
variant: "outline",
|
|
47996
|
+
className: "h-5 px-1.5 py-0 text-[10px] text-muted-foreground",
|
|
47997
|
+
children: tr("fluidgrids.builder.workflowTests.disabled", "Off")
|
|
47998
|
+
}
|
|
47999
|
+
),
|
|
48000
|
+
testCase.lastResult ? /* @__PURE__ */ jsx(WorkflowTestStatusBadge, { status: testCase.lastResult.status }) : /* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground", children: tr("fluidgrids.builder.workflowTests.neverRun", "Not run yet") })
|
|
48001
|
+
] })
|
|
48002
|
+
] }),
|
|
48003
|
+
/* @__PURE__ */ jsx("div", { className: "mt-2 flex flex-wrap gap-1.5", children: actions })
|
|
48004
|
+
]
|
|
48005
|
+
}
|
|
48006
|
+
);
|
|
48007
|
+
}
|
|
48008
|
+
var SHEET_TOOLTIP = "z-[130]";
|
|
48009
|
+
function WorkflowTestsPanel({
|
|
48010
|
+
className,
|
|
48011
|
+
compact = false
|
|
48012
|
+
}) {
|
|
48013
|
+
const enabled = useWorkflowTestsEnabled();
|
|
48014
|
+
if (!enabled) return null;
|
|
48015
|
+
return /* @__PURE__ */ jsx(WorkflowTestsSheet, { className, compact });
|
|
48016
|
+
}
|
|
48017
|
+
function WorkflowTestsSheet({
|
|
48018
|
+
className,
|
|
48019
|
+
compact = false
|
|
48020
|
+
}) {
|
|
48021
|
+
const tr = useTr();
|
|
48022
|
+
const params = useParams();
|
|
48023
|
+
const workflowKey = params?.id ?? "";
|
|
48024
|
+
const loadedVersion = useFlowStore((s) => s.workflow.version);
|
|
48025
|
+
const currentVersion = params?.version || loadedVersion || "";
|
|
48026
|
+
const guardedNavigate = useGuardedNavigate();
|
|
48027
|
+
const canvasNodes = useFlowStore((s) => s.workflow.nodes);
|
|
48028
|
+
const canvasPins = useFlowStore((s) => s.workflow.pinnedNodeData);
|
|
48029
|
+
const [open2, setOpen] = useState(false);
|
|
48030
|
+
const {
|
|
48031
|
+
cases,
|
|
48032
|
+
runs,
|
|
48033
|
+
activeRun,
|
|
48034
|
+
loading,
|
|
48035
|
+
error: error62,
|
|
48036
|
+
forbidden,
|
|
48037
|
+
refetch,
|
|
48038
|
+
createCase,
|
|
48039
|
+
updateCase,
|
|
48040
|
+
deleteCase,
|
|
48041
|
+
runTests
|
|
48042
|
+
} = useWorkflowTests(workflowKey, open2);
|
|
48043
|
+
useEffect(() => {
|
|
48044
|
+
if (open2) void refetch();
|
|
48045
|
+
}, [open2, refetch]);
|
|
48046
|
+
const { allowed: canEdit } = useFluidGridsPermission(
|
|
48047
|
+
FLUIDGRIDS_PERMISSIONS.WORKFLOW_UPDATE
|
|
48048
|
+
);
|
|
48049
|
+
const { allowed: canRun } = useFluidGridsPermission(
|
|
48050
|
+
FLUIDGRIDS_PERMISSIONS.WORKFLOW_RUN_EXECUTE
|
|
48051
|
+
);
|
|
48052
|
+
const [editor, setEditor] = useState(null);
|
|
48053
|
+
const [deleting, setDeleting] = useState(null);
|
|
48054
|
+
const [busy, setBusy] = useState(null);
|
|
48055
|
+
const nodeOptions = useMemo(() => {
|
|
48056
|
+
const labels = buildNodeDisplayMap({ data: { nodes: canvasNodes } });
|
|
48057
|
+
return canvasNodes.filter((node2) => typeof node2.id === "string" && node2.id !== "").map((node2) => ({
|
|
48058
|
+
id: node2.id,
|
|
48059
|
+
label: labels[node2.id]?.label ? `${labels[node2.id]?.label} (${node2.id})` : node2.id
|
|
48060
|
+
}));
|
|
48061
|
+
}, [canvasNodes]);
|
|
48062
|
+
const canvasPinnedOutputs = useMemo(
|
|
48063
|
+
() => pinnedOutputsFromCanvas(canvasPins),
|
|
48064
|
+
[canvasPins]
|
|
48065
|
+
);
|
|
48066
|
+
const runIds = enabledCaseIds(cases);
|
|
48067
|
+
const suiteOpen = !!activeRun && isTestRunOpen(activeRun.status);
|
|
48068
|
+
const atCap = cases.length >= MAX_TEST_CASES;
|
|
48069
|
+
const deniedEdit = tr(
|
|
48070
|
+
"fluidgrids.builder.workflowTests.deniedEdit",
|
|
48071
|
+
"You need edit access to this workflow to change its test cases"
|
|
48072
|
+
);
|
|
48073
|
+
const deniedRun = tr(
|
|
48074
|
+
"fluidgrids.builder.workflowTests.deniedRun",
|
|
48075
|
+
"You need permission to run this workflow to run its tests"
|
|
48076
|
+
);
|
|
48077
|
+
const openRun = (runId) => guardedNavigate(`../runs/${encodeURIComponent(runId)}`);
|
|
48078
|
+
const start = async (key, caseIds) => {
|
|
48079
|
+
setBusy(key);
|
|
48080
|
+
try {
|
|
48081
|
+
await runTests({
|
|
48082
|
+
version: currentVersion || void 0,
|
|
48083
|
+
...caseIds ? { caseIds } : {}
|
|
48084
|
+
});
|
|
48085
|
+
} catch (err) {
|
|
48086
|
+
toast.error(
|
|
48087
|
+
tr(
|
|
48088
|
+
"fluidgrids.builder.workflowTests.runError",
|
|
48089
|
+
"The tests did not start"
|
|
48090
|
+
),
|
|
48091
|
+
{ description: err instanceof Error ? err.message : String(err) }
|
|
48092
|
+
);
|
|
48093
|
+
} finally {
|
|
48094
|
+
setBusy(null);
|
|
48095
|
+
}
|
|
48096
|
+
};
|
|
48097
|
+
const save = async (draft) => {
|
|
48098
|
+
if (!editor) return null;
|
|
48099
|
+
const sortOrder = editor.mode === "edit" ? editor.sortOrder : nextSortOrder(cases);
|
|
48100
|
+
const parsed = draftToInput(draft, sortOrder);
|
|
48101
|
+
if ("error" in parsed) return parsed.error;
|
|
48102
|
+
try {
|
|
48103
|
+
if (editor.mode === "edit") await updateCase(editor.id, parsed.input);
|
|
48104
|
+
else await createCase(parsed.input);
|
|
48105
|
+
toast.success(
|
|
48106
|
+
tr("fluidgrids.builder.workflowTests.saved", "Test case saved"),
|
|
48107
|
+
{ dismissible: true }
|
|
48108
|
+
);
|
|
48109
|
+
setEditor(null);
|
|
48110
|
+
return null;
|
|
48111
|
+
} catch (err) {
|
|
48112
|
+
return {
|
|
48113
|
+
field: "size",
|
|
48114
|
+
key: "fluidgrids.builder.workflowTests.saveError",
|
|
48115
|
+
fallback: err instanceof Error ? err.message : String(err),
|
|
48116
|
+
raw: true
|
|
48117
|
+
};
|
|
48118
|
+
}
|
|
48119
|
+
};
|
|
48120
|
+
const confirmDelete = async () => {
|
|
48121
|
+
const target = deleting;
|
|
48122
|
+
setDeleting(null);
|
|
48123
|
+
if (!target) return;
|
|
48124
|
+
setBusy(`delete:${target.id}`);
|
|
48125
|
+
try {
|
|
48126
|
+
await deleteCase(target.id);
|
|
48127
|
+
toast.success(
|
|
48128
|
+
tr("fluidgrids.builder.workflowTests.deleted", "Test case deleted"),
|
|
48129
|
+
{ dismissible: true }
|
|
48130
|
+
);
|
|
48131
|
+
} catch (err) {
|
|
48132
|
+
toast.error(
|
|
48133
|
+
tr(
|
|
48134
|
+
"fluidgrids.builder.workflowTests.deleteError",
|
|
48135
|
+
"Could not delete the test case"
|
|
48136
|
+
),
|
|
48137
|
+
{ description: err instanceof Error ? err.message : String(err) }
|
|
48138
|
+
);
|
|
48139
|
+
} finally {
|
|
48140
|
+
setBusy(null);
|
|
48141
|
+
}
|
|
48142
|
+
};
|
|
48143
|
+
const triggerLabel = tr("fluidgrids.builder.workflowTests.trigger", "Tests");
|
|
48144
|
+
return /* @__PURE__ */ jsxs(Sheet, { open: open2, onOpenChange: setOpen, children: [
|
|
48145
|
+
/* @__PURE__ */ jsx(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
48146
|
+
Button$1,
|
|
48147
|
+
{
|
|
48148
|
+
"data-tour": "fluidgrids-builder-tests",
|
|
48149
|
+
variant: "outline",
|
|
48150
|
+
size: compact ? "icon" : "sm",
|
|
48151
|
+
className: cn$1(!compact && "flex gap-1", className),
|
|
48152
|
+
"aria-label": triggerLabel,
|
|
48153
|
+
title: compact ? triggerLabel : void 0,
|
|
48154
|
+
disabled: !workflowKey,
|
|
48155
|
+
"data-testid": "fluidgrids-tests-trigger",
|
|
48156
|
+
children: [
|
|
48157
|
+
/* @__PURE__ */ jsx(FlaskConical, { className: "size-4" }),
|
|
48158
|
+
!compact && triggerLabel
|
|
48159
|
+
]
|
|
48160
|
+
}
|
|
48161
|
+
) }),
|
|
48162
|
+
/* @__PURE__ */ jsxs(
|
|
48163
|
+
SheetContent,
|
|
48164
|
+
{
|
|
48165
|
+
side: "right",
|
|
48166
|
+
className: "w-[380px] overflow-y-auto sm:w-[480px]",
|
|
48167
|
+
"data-testid": "fluidgrids-tests-panel",
|
|
48168
|
+
children: [
|
|
48169
|
+
/* @__PURE__ */ jsxs(SheetHeader, { children: [
|
|
48170
|
+
/* @__PURE__ */ jsxs(SheetTitle, { className: "flex items-center gap-2", children: [
|
|
48171
|
+
/* @__PURE__ */ jsx(FlaskConical, { className: "size-5" }),
|
|
48172
|
+
tr("fluidgrids.builder.workflowTests.title", "Test cases")
|
|
48173
|
+
] }),
|
|
48174
|
+
/* @__PURE__ */ jsx(SheetDescription, { children: tr(
|
|
48175
|
+
"fluidgrids.builder.workflowTests.description",
|
|
48176
|
+
"Saved inputs, mocked connections and expected outputs for this workflow. Each case runs in test mode, so no real connection is called for a mocked node."
|
|
48177
|
+
) })
|
|
48178
|
+
] }),
|
|
48179
|
+
forbidden ? /* @__PURE__ */ jsx(
|
|
48180
|
+
"p",
|
|
48181
|
+
{
|
|
48182
|
+
className: "py-6 text-sm text-muted-foreground",
|
|
48183
|
+
"data-testid": "fluidgrids-tests-no-access",
|
|
48184
|
+
children: tr(
|
|
48185
|
+
"fluidgrids.builder.workflowTests.noAccess",
|
|
48186
|
+
"You don't have access to this workflow's test cases."
|
|
48187
|
+
)
|
|
48188
|
+
}
|
|
48189
|
+
) : loading && cases.length === 0 && runs.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center py-8 text-sm text-muted-foreground", children: [
|
|
48190
|
+
/* @__PURE__ */ jsx(Loader2, { className: "mr-2 size-4 animate-spin" }),
|
|
48191
|
+
tr("fluidgrids.builder.workflowTests.loading", "Loading...")
|
|
48192
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "mt-4 space-y-5 pb-6", children: [
|
|
48193
|
+
error62 && /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-[var(--color-status-error-border)] p-2 text-xs text-[var(--color-status-error-text)]", children: [
|
|
48194
|
+
error62,
|
|
48195
|
+
" ",
|
|
48196
|
+
/* @__PURE__ */ jsx(
|
|
48197
|
+
"button",
|
|
48198
|
+
{
|
|
48199
|
+
type: "button",
|
|
48200
|
+
className: "underline",
|
|
48201
|
+
onClick: () => void refetch(),
|
|
48202
|
+
children: tr("fluidgrids.builder.workflowTests.retry", "Retry")
|
|
48203
|
+
}
|
|
48204
|
+
)
|
|
48205
|
+
] }),
|
|
48206
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
48207
|
+
/* @__PURE__ */ jsx(
|
|
48208
|
+
SdkPermissionButton,
|
|
48209
|
+
{
|
|
48210
|
+
permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_RUN_EXECUTE,
|
|
48211
|
+
deniedTooltip: deniedRun,
|
|
48212
|
+
deniedTooltipClassName: SHEET_TOOLTIP,
|
|
48213
|
+
children: /* @__PURE__ */ jsxs(
|
|
48214
|
+
Button$1,
|
|
48215
|
+
{
|
|
48216
|
+
size: "sm",
|
|
48217
|
+
className: "gap-1",
|
|
48218
|
+
disabled: busy !== null || suiteOpen || runIds.length === 0,
|
|
48219
|
+
onClick: () => void start("all"),
|
|
48220
|
+
"data-testid": "fluidgrids-tests-run-all",
|
|
48221
|
+
children: [
|
|
48222
|
+
busy === "all" || suiteOpen ? /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin" }) : /* @__PURE__ */ jsx(Play, { className: "size-4" }),
|
|
48223
|
+
tr("fluidgrids.builder.workflowTests.runAll", "Run all")
|
|
48224
|
+
]
|
|
48225
|
+
}
|
|
48226
|
+
)
|
|
48227
|
+
}
|
|
48228
|
+
),
|
|
48229
|
+
/* @__PURE__ */ jsx(
|
|
48230
|
+
SdkPermissionButton,
|
|
48231
|
+
{
|
|
48232
|
+
permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_UPDATE,
|
|
48233
|
+
deniedTooltip: deniedEdit,
|
|
48234
|
+
deniedTooltipClassName: SHEET_TOOLTIP,
|
|
48235
|
+
children: /* @__PURE__ */ jsxs(
|
|
48236
|
+
Button$1,
|
|
48237
|
+
{
|
|
48238
|
+
size: "sm",
|
|
48239
|
+
variant: "outline",
|
|
48240
|
+
className: "gap-1",
|
|
48241
|
+
disabled: busy !== null || atCap,
|
|
48242
|
+
title: atCap ? tr(
|
|
48243
|
+
"fluidgrids.builder.workflowTests.atCap",
|
|
48244
|
+
"A workflow can have at most 50 test cases"
|
|
48245
|
+
) : void 0,
|
|
48246
|
+
onClick: () => setEditor({ mode: "create", draft: emptyTestCaseDraft() }),
|
|
48247
|
+
"data-testid": "fluidgrids-tests-new",
|
|
48248
|
+
children: [
|
|
48249
|
+
/* @__PURE__ */ jsx(Plus, { className: "size-4" }),
|
|
48250
|
+
tr(
|
|
48251
|
+
"fluidgrids.builder.workflowTests.newCase",
|
|
48252
|
+
"New test case"
|
|
48253
|
+
)
|
|
48254
|
+
]
|
|
48255
|
+
}
|
|
48256
|
+
)
|
|
48257
|
+
}
|
|
48258
|
+
),
|
|
48259
|
+
/* @__PURE__ */ jsx(
|
|
48260
|
+
Button$1,
|
|
48261
|
+
{
|
|
48262
|
+
size: "icon",
|
|
48263
|
+
variant: "ghost",
|
|
48264
|
+
className: "ml-auto size-8",
|
|
48265
|
+
disabled: loading,
|
|
48266
|
+
"aria-label": tr(
|
|
48267
|
+
"fluidgrids.builder.workflowTests.refresh",
|
|
48268
|
+
"Refresh"
|
|
48269
|
+
),
|
|
48270
|
+
onClick: () => void refetch(),
|
|
48271
|
+
children: /* @__PURE__ */ jsx(
|
|
48272
|
+
RefreshCw,
|
|
48273
|
+
{
|
|
48274
|
+
className: cn$1("size-4", loading && "animate-spin")
|
|
48275
|
+
}
|
|
48276
|
+
)
|
|
48277
|
+
}
|
|
48278
|
+
)
|
|
48279
|
+
] }),
|
|
48280
|
+
(!canEdit || !canRun) && /* @__PURE__ */ jsx(
|
|
48281
|
+
"p",
|
|
48282
|
+
{
|
|
48283
|
+
className: "text-[11px] text-muted-foreground",
|
|
48284
|
+
"data-testid": "fluidgrids-tests-read-only",
|
|
48285
|
+
children: !canEdit && !canRun ? tr(
|
|
48286
|
+
"fluidgrids.builder.workflowTests.readOnly",
|
|
48287
|
+
"You can view the test cases and their results, but not change or run them."
|
|
48288
|
+
) : !canEdit ? tr(
|
|
48289
|
+
"fluidgrids.builder.workflowTests.runOnly",
|
|
48290
|
+
"You can run the test cases, but not change them."
|
|
48291
|
+
) : tr(
|
|
48292
|
+
"fluidgrids.builder.workflowTests.editOnly",
|
|
48293
|
+
"You can change the test cases, but not run them."
|
|
48294
|
+
)
|
|
48295
|
+
}
|
|
48296
|
+
),
|
|
48297
|
+
activeRun && /* @__PURE__ */ jsxs("section", { "aria-labelledby": "fg-tests-active", children: [
|
|
48298
|
+
/* @__PURE__ */ jsx(
|
|
48299
|
+
"h3",
|
|
48300
|
+
{
|
|
48301
|
+
id: "fg-tests-active",
|
|
48302
|
+
className: "mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground",
|
|
48303
|
+
children: suiteOpen ? tr(
|
|
48304
|
+
"fluidgrids.builder.workflowTests.runningTitle",
|
|
48305
|
+
"Running"
|
|
48306
|
+
) : tr(
|
|
48307
|
+
"fluidgrids.builder.workflowTests.latestTitle",
|
|
48308
|
+
"Latest run"
|
|
48309
|
+
)
|
|
48310
|
+
}
|
|
48311
|
+
),
|
|
48312
|
+
/* @__PURE__ */ jsx(WorkflowTestRunCard, { run: activeRun, onOpenRun: openRun })
|
|
48313
|
+
] }),
|
|
48314
|
+
/* @__PURE__ */ jsxs("section", { "aria-labelledby": "fg-tests-cases", children: [
|
|
48315
|
+
/* @__PURE__ */ jsxs(
|
|
48316
|
+
"h3",
|
|
48317
|
+
{
|
|
48318
|
+
id: "fg-tests-cases",
|
|
48319
|
+
className: "mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground",
|
|
48320
|
+
children: [
|
|
48321
|
+
tr("fluidgrids.builder.workflowTests.casesTitle", "Cases"),
|
|
48322
|
+
" (",
|
|
48323
|
+
cases.length,
|
|
48324
|
+
")"
|
|
48325
|
+
]
|
|
48326
|
+
}
|
|
48327
|
+
),
|
|
48328
|
+
cases.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: tr(
|
|
48329
|
+
"fluidgrids.builder.workflowTests.empty",
|
|
48330
|
+
"No test cases yet. Create one here, or open a finished run and choose Save as test case."
|
|
48331
|
+
) }) : /* @__PURE__ */ jsx("ul", { className: "space-y-2", children: cases.map((testCase) => /* @__PURE__ */ jsx(
|
|
48332
|
+
WorkflowTestCaseRow,
|
|
48333
|
+
{
|
|
48334
|
+
testCase,
|
|
48335
|
+
actions: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
48336
|
+
/* @__PURE__ */ jsx(
|
|
48337
|
+
SdkPermissionButton,
|
|
48338
|
+
{
|
|
48339
|
+
permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_RUN_EXECUTE,
|
|
48340
|
+
deniedTooltip: deniedRun,
|
|
48341
|
+
deniedTooltipClassName: SHEET_TOOLTIP,
|
|
48342
|
+
children: /* @__PURE__ */ jsxs(
|
|
48343
|
+
Button$1,
|
|
48344
|
+
{
|
|
48345
|
+
size: "sm",
|
|
48346
|
+
variant: "secondary",
|
|
48347
|
+
className: "h-7 gap-1 text-xs",
|
|
48348
|
+
disabled: busy !== null || suiteOpen,
|
|
48349
|
+
onClick: () => void start(`run:${testCase.id}`, [testCase.id]),
|
|
48350
|
+
"data-testid": "fluidgrids-test-case-run",
|
|
48351
|
+
children: [
|
|
48352
|
+
busy === `run:${testCase.id}` ? /* @__PURE__ */ jsx(Loader2, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ jsx(Play, { className: "size-3.5" }),
|
|
48353
|
+
tr(
|
|
48354
|
+
"fluidgrids.builder.workflowTests.runOne",
|
|
48355
|
+
"Run"
|
|
48356
|
+
)
|
|
48357
|
+
]
|
|
48358
|
+
}
|
|
48359
|
+
)
|
|
48360
|
+
}
|
|
48361
|
+
),
|
|
48362
|
+
/* @__PURE__ */ jsx(
|
|
48363
|
+
SdkPermissionButton,
|
|
48364
|
+
{
|
|
48365
|
+
permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_UPDATE,
|
|
48366
|
+
deniedTooltip: deniedEdit,
|
|
48367
|
+
deniedTooltipClassName: SHEET_TOOLTIP,
|
|
48368
|
+
children: /* @__PURE__ */ jsxs(
|
|
48369
|
+
Button$1,
|
|
48370
|
+
{
|
|
48371
|
+
size: "sm",
|
|
48372
|
+
variant: "outline",
|
|
48373
|
+
className: "h-7 gap-1 text-xs",
|
|
48374
|
+
disabled: busy !== null,
|
|
48375
|
+
onClick: () => setEditor({
|
|
48376
|
+
mode: "edit",
|
|
48377
|
+
id: testCase.id,
|
|
48378
|
+
sortOrder: testCase.sortOrder,
|
|
48379
|
+
draft: draftFromTestCase(testCase)
|
|
48380
|
+
}),
|
|
48381
|
+
"data-testid": "fluidgrids-test-case-edit",
|
|
48382
|
+
children: [
|
|
48383
|
+
/* @__PURE__ */ jsx(Pencil, { className: "size-3.5" }),
|
|
48384
|
+
tr(
|
|
48385
|
+
"fluidgrids.builder.workflowTests.edit",
|
|
48386
|
+
"Edit"
|
|
48387
|
+
)
|
|
48388
|
+
]
|
|
48389
|
+
}
|
|
48390
|
+
)
|
|
48391
|
+
}
|
|
48392
|
+
),
|
|
48393
|
+
/* @__PURE__ */ jsx(
|
|
48394
|
+
SdkPermissionButton,
|
|
48395
|
+
{
|
|
48396
|
+
permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_UPDATE,
|
|
48397
|
+
deniedTooltip: deniedEdit,
|
|
48398
|
+
deniedTooltipClassName: SHEET_TOOLTIP,
|
|
48399
|
+
children: /* @__PURE__ */ jsxs(
|
|
48400
|
+
Button$1,
|
|
48401
|
+
{
|
|
48402
|
+
size: "sm",
|
|
48403
|
+
variant: "ghost",
|
|
48404
|
+
className: "h-7 gap-1 text-xs",
|
|
48405
|
+
disabled: busy !== null,
|
|
48406
|
+
onClick: () => setDeleting(testCase),
|
|
48407
|
+
"data-testid": "fluidgrids-test-case-delete",
|
|
48408
|
+
children: [
|
|
48409
|
+
busy === `delete:${testCase.id}` ? /* @__PURE__ */ jsx(Loader2, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ jsx(Trash2, { className: "size-3.5" }),
|
|
48410
|
+
tr(
|
|
48411
|
+
"fluidgrids.builder.workflowTests.delete",
|
|
48412
|
+
"Delete"
|
|
48413
|
+
)
|
|
48414
|
+
]
|
|
48415
|
+
}
|
|
48416
|
+
)
|
|
48417
|
+
}
|
|
48418
|
+
)
|
|
48419
|
+
] })
|
|
48420
|
+
},
|
|
48421
|
+
testCase.id
|
|
48422
|
+
)) })
|
|
48423
|
+
] }),
|
|
48424
|
+
runs.length > 1 && /* @__PURE__ */ jsxs("section", { "aria-labelledby": "fg-tests-history", children: [
|
|
48425
|
+
/* @__PURE__ */ jsx(
|
|
48426
|
+
"h3",
|
|
48427
|
+
{
|
|
48428
|
+
id: "fg-tests-history",
|
|
48429
|
+
className: "mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground",
|
|
48430
|
+
children: tr(
|
|
48431
|
+
"fluidgrids.builder.workflowTests.historyTitle",
|
|
48432
|
+
"Earlier runs"
|
|
48433
|
+
)
|
|
48434
|
+
}
|
|
48435
|
+
),
|
|
48436
|
+
/* @__PURE__ */ jsx("ul", { className: "space-y-1.5", children: runs.filter((run) => run.id !== activeRun?.id).map((run) => /* @__PURE__ */ jsxs(
|
|
48437
|
+
"li",
|
|
48438
|
+
{
|
|
48439
|
+
className: "flex items-center justify-between gap-2 text-xs",
|
|
48440
|
+
"data-testid": "fluidgrids-test-run-history",
|
|
48441
|
+
children: [
|
|
48442
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0 truncate text-muted-foreground", children: [
|
|
48443
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono", children: run.version }),
|
|
48444
|
+
" \xB7",
|
|
48445
|
+
" ",
|
|
48446
|
+
run.summary.passed,
|
|
48447
|
+
"/",
|
|
48448
|
+
run.summary.total,
|
|
48449
|
+
" \xB7",
|
|
48450
|
+
" ",
|
|
48451
|
+
relativeTime(run.startedAt)
|
|
48452
|
+
] }),
|
|
48453
|
+
/* @__PURE__ */ jsx(WorkflowTestStatusBadge, { status: run.status })
|
|
48454
|
+
]
|
|
48455
|
+
},
|
|
48456
|
+
run.id
|
|
48457
|
+
)) })
|
|
48458
|
+
] })
|
|
48459
|
+
] })
|
|
48460
|
+
]
|
|
48461
|
+
}
|
|
48462
|
+
),
|
|
48463
|
+
/* @__PURE__ */ jsx(
|
|
48464
|
+
WorkflowTestCaseDialog,
|
|
48465
|
+
{
|
|
48466
|
+
open: editor !== null,
|
|
48467
|
+
mode: editor?.mode ?? "create",
|
|
48468
|
+
initialDraft: editor?.draft ?? EMPTY_DRAFT,
|
|
48469
|
+
nodes: nodeOptions,
|
|
48470
|
+
canvasPinnedOutputs,
|
|
48471
|
+
onSave: save,
|
|
48472
|
+
onOpenChange: (next) => !next && setEditor(null)
|
|
48473
|
+
}
|
|
48474
|
+
),
|
|
48475
|
+
/* @__PURE__ */ jsx(
|
|
48476
|
+
AlertDialog,
|
|
48477
|
+
{
|
|
48478
|
+
open: deleting !== null,
|
|
48479
|
+
onOpenChange: (next) => !next && setDeleting(null),
|
|
48480
|
+
children: /* @__PURE__ */ jsxs(AlertDialogContent, { className: "z-[120]", children: [
|
|
48481
|
+
/* @__PURE__ */ jsxs(AlertDialogHeader, { children: [
|
|
48482
|
+
/* @__PURE__ */ jsx(AlertDialogTitle, { children: tr(
|
|
48483
|
+
"fluidgrids.builder.workflowTests.deleteTitle",
|
|
48484
|
+
"Delete this test case?"
|
|
48485
|
+
) }),
|
|
48486
|
+
/* @__PURE__ */ jsxs(AlertDialogDescription, { children: [
|
|
48487
|
+
deleting?.name,
|
|
48488
|
+
".",
|
|
48489
|
+
" ",
|
|
48490
|
+
tr(
|
|
48491
|
+
"fluidgrids.builder.workflowTests.deleteBody",
|
|
48492
|
+
"Earlier test runs keep their results."
|
|
48493
|
+
)
|
|
48494
|
+
] })
|
|
48495
|
+
] }),
|
|
48496
|
+
/* @__PURE__ */ jsxs(AlertDialogFooter, { children: [
|
|
48497
|
+
/* @__PURE__ */ jsx(AlertDialogCancel, { children: tr("fluidgrids.builder.workflowTests.cancel", "Cancel") }),
|
|
48498
|
+
/* @__PURE__ */ jsx(AlertDialogAction, { onClick: () => void confirmDelete(), children: tr("fluidgrids.builder.workflowTests.delete", "Delete") })
|
|
48499
|
+
] })
|
|
48500
|
+
] })
|
|
48501
|
+
}
|
|
48502
|
+
)
|
|
48503
|
+
] });
|
|
48504
|
+
}
|
|
48505
|
+
var EMPTY_DRAFT = emptyTestCaseDraft();
|
|
47285
48506
|
var NO_TEMPLATE = "__none__";
|
|
47286
48507
|
function AiDraftPanel({
|
|
47287
48508
|
className,
|
|
@@ -48320,6 +49541,7 @@ function PanelIcons() {
|
|
|
48320
49541
|
/* @__PURE__ */ jsx(AiDraftPanel, { compact: true }),
|
|
48321
49542
|
/* @__PURE__ */ jsx(EnvironmentsPanel, { compact: true }),
|
|
48322
49543
|
/* @__PURE__ */ jsx(GitSyncPanel, { compact: true }),
|
|
49544
|
+
/* @__PURE__ */ jsx(WorkflowTestsPanel, { compact: true }),
|
|
48323
49545
|
/* @__PURE__ */ jsx(CodeViewPanel, { compact: true })
|
|
48324
49546
|
] });
|
|
48325
49547
|
}
|
|
@@ -48338,6 +49560,7 @@ function HeaderActions({ tier }) {
|
|
|
48338
49560
|
/* @__PURE__ */ jsx(VersionHistoryPanel, { compact: true }),
|
|
48339
49561
|
/* @__PURE__ */ jsx(EnvironmentsPanel, { compact: true }),
|
|
48340
49562
|
/* @__PURE__ */ jsx(GitSyncPanel, { compact: true }),
|
|
49563
|
+
/* @__PURE__ */ jsx(WorkflowTestsPanel, { compact: true }),
|
|
48341
49564
|
/* @__PURE__ */ jsx(CodeViewPanel, { compact: true }),
|
|
48342
49565
|
/* @__PURE__ */ jsx(GuideIcon, {}),
|
|
48343
49566
|
/* @__PURE__ */ jsx(Divider, {}),
|