11import Button from '@/components/Button/Button' ;
2+ import Switch from '@/components/Switch/Switch' ;
23import {
34 Dialog ,
45 DialogClose ,
@@ -12,6 +13,7 @@ import {
1213import { Form , FormControl , FormField , FormItem , FormLabel , FormMessage } from '@/components/ui/form' ;
1314import { Label } from '@/components/ui/label' ;
1415import { Select , SelectContent , SelectItem , SelectTrigger , SelectValue } from '@/components/ui/select' ;
16+ import { Tooltip , TooltipContent , TooltipTrigger } from '@/components/ui/tooltip' ;
1517import Properties from '@/pages/platform/workflow-editor/components/properties/Properties' ;
1618import { ConnectionI , useWorkflowEditor } from '@/pages/platform/workflow-editor/providers/workflowEditorProvider' ;
1719import useWorkflowNodeDetailsPanelStore from '@/pages/platform/workflow-editor/stores/useWorkflowNodeDetailsPanelStore' ;
@@ -30,7 +32,7 @@ import {WorkflowTestConfigurationKeys} from '@/shared/queries/platform/workflowT
3032import { PropertyAllType } from '@/shared/types' ;
3133import * as Portal from '@radix-ui/react-portal' ;
3234import { useQueryClient } from '@tanstack/react-query' ;
33- import { PlusIcon } from 'lucide-react' ;
35+ import { InfoIcon , PlusIcon } from 'lucide-react' ;
3436import { Dispatch , SetStateAction , useState } from 'react' ;
3537import { UseFormReturn , useForm } from 'react-hook-form' ;
3638import InlineSVG from 'react-inlinesvg' ;
@@ -41,23 +43,27 @@ interface WorkflowTestConfigurationDialogProps {
4143 workflowTestConfiguration ?: WorkflowTestConfiguration ;
4244}
4345
46+ interface WorkflowTestConfigurationFormFieldProps {
47+ componentConnection : ComponentConnection ;
48+ connectionDialogAllowed : boolean ;
49+ connections : ConnectionI [ ] ;
50+ form : UseFormReturn < WorkflowTestConfiguration > ;
51+ groupedIndices ?: number [ ] ;
52+ index : number ;
53+ setComponentConnection : Dispatch < SetStateAction < ComponentConnection | undefined > > ;
54+ setShowNewConnectionDialog : Dispatch < SetStateAction < boolean > > ;
55+ }
56+
4457const WorkflowTestConfigurationFormField = ( {
4558 componentConnection,
4659 connectionDialogAllowed,
4760 connections,
4861 form,
62+ groupedIndices,
4963 index,
5064 setComponentConnection,
5165 setShowNewConnectionDialog,
52- } : {
53- componentConnection : ComponentConnection ;
54- connectionDialogAllowed : boolean ;
55- connections : ConnectionI [ ] ;
56- form : UseFormReturn < WorkflowTestConfiguration > ;
57- index : number ;
58- setShowNewConnectionDialog : Dispatch < SetStateAction < boolean > > ;
59- setComponentConnection : Dispatch < SetStateAction < ComponentConnection | undefined > > ;
60- } ) => {
66+ } : WorkflowTestConfigurationFormFieldProps ) => {
6167 const { data : componentDefinition } = useGetComponentDefinitionQuery ( {
6268 componentName : componentConnection . componentName ,
6369 componentVersion : componentConnection . componentVersion ,
@@ -78,13 +84,32 @@ const WorkflowTestConfigurationFormField = ({
7884
7985 < span className = "ml-1" > { componentDefinition ?. title } Connection</ span >
8086
81- < span className = "ml-0.5 text-xs text-gray-500" >
82- { `(${ componentConnection . workflowNodeName } - ${ componentConnection . key } )` }
83- </ span >
87+ { groupedIndices ? (
88+ < span className = "ml-0.5 text-xs text-content-neutral-secondary" >
89+ (applies to { groupedIndices . length } nodes)
90+ </ span >
91+ ) : (
92+ < span className = "ml-0.5 text-xs text-content-neutral-secondary" >
93+ { `(${ componentConnection . workflowNodeName } - ${ componentConnection . key } )` }
94+ </ span >
95+ ) }
8496 </ FormLabel >
8597
8698 < Select
87- onValueChange = { field . onChange }
99+ onValueChange = { ( value ) => {
100+ field . onChange ( value ) ;
101+
102+ if ( groupedIndices ) {
103+ for ( const groupedIndex of groupedIndices ) {
104+ if ( groupedIndex !== index ) {
105+ form . setValue (
106+ `connections.${ groupedIndex } .connectionId` ,
107+ Number ( value )
108+ ) ;
109+ }
110+ }
111+ }
112+ } }
88113 value = { field . value ? field . value . toString ( ) : undefined }
89114 >
90115 < FormControl >
@@ -151,6 +176,7 @@ const WorkflowTestConfigurationDialog = ({
151176} : WorkflowTestConfigurationDialogProps ) => {
152177 const [ showNewConnectionDialog , setShowNewConnectionDialog ] = useState ( false ) ;
153178 const [ componentConnection , setComponentConnection ] = useState < ComponentConnection | undefined > ( ) ;
179+ const [ groupConnections , setGroupConnections ] = useState ( false ) ;
154180
155181 const connectionDialogAllowed = useWorkflowNodeDetailsPanelStore ( ( state ) => state . connectionDialogAllowed ) ;
156182
@@ -229,6 +255,36 @@ const WorkflowTestConfigurationDialog = ({
229255 } ) ;
230256 }
231257
258+ const getConnectionsToRender = ( ) : Array < {
259+ connection : ComponentConnection ;
260+ groupedIndices ?: number [ ] ;
261+ index : number ;
262+ } > => {
263+ if ( ! groupConnections ) {
264+ return componentConnections . map ( ( connection , index ) => ( { connection, index} ) ) ;
265+ }
266+
267+ const connectionGroupMap = new Map < string , number [ ] > ( ) ;
268+
269+ for ( const [ index , connection ] of componentConnections . entries ( ) ) {
270+ const componentName = connection . componentName ;
271+
272+ if ( ! connectionGroupMap . has ( componentName ) ) {
273+ connectionGroupMap . set ( componentName , [ ] ) ;
274+ }
275+
276+ connectionGroupMap . get ( componentName ) ! . push ( index ) ;
277+ }
278+
279+ return Array . from ( connectionGroupMap . values ( ) ) . map ( ( indices ) => ( {
280+ connection : componentConnections [ indices [ 0 ] ] ,
281+ groupedIndices : indices . length > 1 ? indices : undefined ,
282+ index : indices [ 0 ] ,
283+ } ) ) ;
284+ } ;
285+
286+ const connectionsToRender = getConnectionsToRender ( ) ;
287+
232288 return (
233289 < Dialog onOpenChange = { onClose } open = { true } >
234290 < DialogContent
@@ -253,7 +309,7 @@ const WorkflowTestConfigurationDialog = ({
253309 < div className = "space-y-4 py-4" >
254310 { inputs && inputs . length > 0 && (
255311 < div className = "space-y-2" >
256- < Label className = "text-gray-500 " > Inputs</ Label >
312+ < Label className = "text-content-neutral-secondary " > Inputs</ Label >
257313
258314 < Properties
259315 control = { control }
@@ -285,21 +341,20 @@ const WorkflowTestConfigurationDialog = ({
285341
286342 { componentConnections && componentConnections . length > 0 && (
287343 < div className = "space-y-2" >
288- < Label className = "text-gray-500 " > Connections</ Label >
344+ < Label className = "text-content-neutral-secondary " > Connections</ Label >
289345
290346 < div className = "space-y-4" >
291- { componentConnections . map (
292- ( workflowConnection , index ) =>
347+ { connectionsToRender . map (
348+ ( { connection , groupedIndices , index} ) =>
293349 connections && (
294350 < WorkflowTestConfigurationFormField
295- componentConnection = { workflowConnection }
351+ componentConnection = { connection }
296352 connectionDialogAllowed = { connectionDialogAllowed }
297353 connections = { connections }
298354 form = { form }
355+ groupedIndices = { groupedIndices }
299356 index = { index }
300- key = { `${ workflowConnection . workflowNodeName } _${
301- workflowConnection . key
302- } `}
357+ key = { `${ connection . workflowNodeName } _${ connection . key } ` }
303358 setComponentConnection = { setComponentConnection }
304359 setShowNewConnectionDialog = { setShowNewConnectionDialog }
305360 />
@@ -311,7 +366,25 @@ const WorkflowTestConfigurationDialog = ({
311366 </ div >
312367 </ div >
313368
314- < DialogFooter >
369+ < DialogFooter className = "flex items-center" >
370+ < div className = "mr-auto flex items-center gap-2" >
371+ { componentConnections . length > 1 && (
372+ < >
373+ < Switch checked = { groupConnections } onCheckedChange = { setGroupConnections } />
374+
375+ < span className = "text-sm font-semibold" > Group Connections</ span >
376+
377+ < Tooltip >
378+ < TooltipTrigger asChild >
379+ < InfoIcon className = "size-4 cursor-default text-content-onsurface-primary" />
380+ </ TooltipTrigger >
381+
382+ < TooltipContent > Connections grouped by their app.</ TooltipContent >
383+ </ Tooltip >
384+ </ >
385+ ) }
386+ </ div >
387+
315388 < DialogClose asChild >
316389 < Button label = "Cancel" type = "button" variant = "outline" />
317390 </ DialogClose >
0 commit comments