@@ -133,14 +133,7 @@ const CustomNode: FC<NodeProps> = ({
133133 return style ;
134134 } ;
135135
136- const nodeStyle = useMemo ( ( ) => {
137- return {
138- border : `${ isSelected ( highlightValues [ data ?. name ] ) } ${ getBorderColor (
139- data ?. type
140- ) } `,
141- ...commonStyle ,
142- } ;
143- } , [ highlightValues , data ] ) ;
136+
144137
145138 const genStyle = ( text : string ) => {
146139 return {
@@ -289,20 +282,72 @@ const CustomNode: FC<NodeProps> = ({
289282 setHighlightValues ( { } ) ;
290283 } , [ setHidden , setHighlightValues ] ) ;
291284
285+ const formatRate = ( rate ?: number ) : string => {
286+ return rate !== undefined && rate >= 0 ? `${ rate } /sec` : "Not Available" ;
287+ } ;
288+
289+ const hasBothSinks =
290+ data ?. nodeInfo ?. sink ?. onSuccess && data ?. nodeInfo ?. sink ?. fallback ;
291+ const wrapperClass = hasBothSinks
292+ ? "mono-vertex-img-wrapper-small"
293+ : "mono-vertex-img-wrapper" ;
294+ const imgClass = hasBothSinks ? "mono-vertex-img-small" : "mono-vertex-img" ;
295+ const nodeRateWrapperClass = hasBothSinks ? "node-rate-small" : "node-rate" ;
296+ const nodeRateStyle =
297+ data ?. type === "monoVertex" && hasBothSinks
298+ ? { bottom : "-1rem" }
299+ : { } ;
300+
301+
302+ const nodeStyle = useMemo ( ( ) => {
303+ return {
304+ border : `${ isSelected ( highlightValues [ data ?. name ] ) } ${ getBorderColor (
305+ data ?. type
306+ ) } `,
307+ ...( hasBothSinks
308+ ? {
309+ display : "flex" ,
310+ flexDirection : "column" ,
311+ }
312+ : { } ) ,
313+ ...commonStyle ,
314+ } ;
315+ } , [ highlightValues , data , hasBothSinks ] ) ;
316+
292317 // arrow for containers in monoVertex
293318 const arrowSvg = useMemo ( ( ) => {
294319 return (
295- < svg height = "1 " width = "18" >
320+ < svg height = "20 " width = "18" >
296321 < line x1 = "0" y1 = "10" x2 = "18" y2 = "10" stroke = "#d1dee9" />
297322 < line x1 = "14" y1 = "7" x2 = "18" y2 = "10" stroke = "#d1dee9" />
298323 < line x1 = "14" y1 = "13" x2 = "18" y2 = "10" stroke = "#d1dee9" />
299324 </ svg >
300325 ) ;
326+ } ) ;
327+
328+ // up arrow in case both onSuccess and fallback sinks are configured
329+ // will point to onSuccess
330+ const arrowUpSvg = useMemo ( ( ) => {
331+ return (
332+ < svg height = "16" width = "16" >
333+ < line x1 = "0" y1 = "16" x2 = "16" y2 = "8" stroke = "#d1dee9" />
334+ < line x1 = "11.1" y1 = "7.1" x2 = "16" y2 = "8" stroke = "#d1dee9" />
335+ < line x1 = "13.7" y1 = "12.5" x2 = "16" y2 = "8" stroke = "#d1dee9" />
336+ </ svg >
337+ ) ;
301338 } , [ ] ) ;
302339
303- const formatRate = ( rate ?: number ) : string => {
304- return rate !== undefined && rate >= 0 ? `${ rate } /sec` : "Not Available" ;
305- } ;
340+ // down arrow in case both onSuccess and fallback sinks are configured
341+ // will point to fallback
342+ const arrowDownSvg = useMemo ( ( ) => {
343+ return (
344+ < svg height = "16" width = "16" >
345+ < line x1 = "0" y1 = "0" x2 = "16" y2 = "8" stroke = "#d1dee9" />
346+ < line x1 = "11.1" y1 = "8.9" x2 = "16" y2 = "8" stroke = "#d1dee9" />
347+ < line x1 = "13.7" y1 = "3.5" x2 = "16" y2 = "8" stroke = "#d1dee9" />
348+ </ svg >
349+ ) ;
350+ } , [ ] ) ;
306351
307352 return (
308353 < Box data-testid = { data ?. name } >
@@ -317,15 +362,22 @@ const CustomNode: FC<NodeProps> = ({
317362 { data ?. type === "monoVertex" && (
318363 < >
319364 < Box className = "node-info-mono" > { data ?. name } </ Box >
320- < Box style = { { display : "flex" , justifyContent : "center" } } >
365+ < Box
366+ style = { {
367+ display : "flex" ,
368+ justifyContent : "center" ,
369+ alignItems : "center" ,
370+ flex : 1 ,
371+ } }
372+ >
321373 < Tooltip
322374 title = { < Box className = { "node-tooltip" } > Source Container</ Box > }
323375 arrow
324376 placement = { "left" }
325377 >
326- < Box className = { "mono-vertex-img-wrapper" } >
378+ < Box className = { wrapperClass } >
327379 < img
328- className = { "mono-vertex-img" }
380+ className = { imgClass }
329381 src = { source }
330382 alt = { "source-container" }
331383 />
@@ -340,9 +392,9 @@ const CustomNode: FC<NodeProps> = ({
340392 arrow
341393 placement = { "bottom" }
342394 >
343- < Box className = { "mono-vertex-img-wrapper" } >
395+ < Box className = { wrapperClass } >
344396 < img
345- className = { "mono-vertex-img" }
397+ className = { imgClass }
346398 src = { transformer }
347399 alt = { "transformer-container" }
348400 />
@@ -358,9 +410,9 @@ const CustomNode: FC<NodeProps> = ({
358410 arrow
359411 placement = { "bottom" }
360412 >
361- < Box className = { "mono-vertex-img-wrapper" } >
413+ < Box className = { wrapperClass } >
362414 < img
363- className = { "mono-vertex-img" }
415+ className = { imgClass }
364416 src = { udf }
365417 alt = { "udf-container" }
366418 />
@@ -371,33 +423,128 @@ const CustomNode: FC<NodeProps> = ({
371423 < Tooltip
372424 title = { < Box className = { "node-tooltip" } > Sink Container</ Box > }
373425 arrow
374- placement = { data ?. nodeInfo ?. sink ?. fallback ? "bottom" : "right" }
426+ placement = {
427+ data ?. nodeInfo ?. sink ?. fallback ||
428+ data ?. nodeInfo ?. sink ?. onSuccess
429+ ? "bottom"
430+ : "right"
431+ }
375432 >
376- < Box className = { "mono-vertex-img-wrapper" } >
433+ < Box className = { wrapperClass } >
377434 < img
378- className = { "mono-vertex-img" }
435+ className = { imgClass }
379436 src = { sink }
380437 alt = { "sink-container" }
381438 />
382439 </ Box >
383440 </ Tooltip >
384- { data ?. nodeInfo ?. sink ?. fallback && arrowSvg }
385- { data ?. nodeInfo ?. sink ?. fallback && (
386- < Tooltip
387- title = {
388- < Box className = { "node-tooltip" } > Fallback Sink Container </ Box >
389- }
390- arrow
391- placement = { "right" }
441+ { ( data ?. nodeInfo ?. sink ?. fallback ||
442+ data ?. nodeInfo ?. sink ?. onSuccess ) && (
443+ < Box
444+ style = { {
445+ display : "flex" ,
446+ flexDirection : "column" ,
447+ gap : "0.2rem" ,
448+ } }
392449 >
393- < Box className = { "mono-vertex-img-wrapper" } >
394- < img
395- className = { "mono-vertex-img" }
396- src = { fallback }
397- alt = { "fallback-sink-container" }
398- />
399- </ Box >
400- </ Tooltip >
450+ { data ?. nodeInfo ?. sink ?. onSuccess &&
451+ ! data ?. nodeInfo ?. sink ?. fallback && (
452+ < Box style = { { display : "flex" , alignItems : "center" } } >
453+ { arrowSvg }
454+ < Tooltip
455+ title = {
456+ < Box className = { "node-tooltip" } >
457+ OnSuccess Sink Container
458+ </ Box >
459+ }
460+ arrow
461+ placement = { "right" }
462+ >
463+ < Box className = { wrapperClass } >
464+ < img
465+ className = { imgClass }
466+ src = { sink }
467+ alt = { "on-success-sink-container" }
468+ />
469+ </ Box >
470+ </ Tooltip >
471+ </ Box >
472+ ) }
473+ { data ?. nodeInfo ?. sink ?. fallback &&
474+ ! data ?. nodeInfo ?. sink ?. onSuccess && (
475+ < Box style = { { display : "flex" , alignItems : "center" } } >
476+ { arrowSvg }
477+ < Tooltip
478+ title = {
479+ < Box className = { "node-tooltip" } >
480+ Fallback Sink Container
481+ </ Box >
482+ }
483+ arrow
484+ placement = { "right" }
485+ >
486+ < Box className = { wrapperClass } >
487+ < img
488+ className = { imgClass }
489+ src = { fallback }
490+ alt = { "fallback-sink-container" }
491+ />
492+ </ Box >
493+ </ Tooltip >
494+ </ Box >
495+ ) }
496+ { data ?. nodeInfo ?. sink ?. onSuccess &&
497+ data ?. nodeInfo ?. sink ?. fallback && (
498+ < Box
499+ style = { {
500+ display : "flex" ,
501+ flexDirection : "column" ,
502+ gap : 0 ,
503+ } }
504+ >
505+ < Box style = { { display : "flex" , alignItems : "center" } } >
506+ { arrowUpSvg }
507+ < Tooltip
508+ title = {
509+ < Box className = { "node-tooltip" } >
510+ OnSuccess Sink Container
511+ </ Box >
512+ }
513+ arrow
514+ placement = { "right" }
515+ >
516+ < Box className = { wrapperClass } >
517+ < img
518+ className = { imgClass }
519+ src = { sink }
520+ alt = { "on-success-sink-container" }
521+ />
522+ </ Box >
523+ </ Tooltip >
524+ </ Box >
525+ < Box style = { { display : "flex" , alignItems : "center" } } >
526+ { arrowDownSvg }
527+ < Tooltip
528+ title = {
529+ < Box className = { "node-tooltip" } >
530+ Fallback Sink Container
531+ </ Box >
532+ }
533+ arrow
534+ placement = { "right" }
535+ >
536+ < Box className = { wrapperClass } >
537+ < img
538+ className = { imgClass }
539+ src = { fallback }
540+ alt = { "fallback-sink-container" }
541+ />
542+ </ Box >
543+ </ Tooltip >
544+ </ Box >
545+ </ Box >
546+ ) }
547+ </ Box >
401548 ) }
402549 </ Box >
403550 </ >
@@ -449,7 +596,7 @@ const CustomNode: FC<NodeProps> = ({
449596 arrow
450597 placement = { "bottom-end" }
451598 >
452- < Box className = { "node-rate" } >
599+ < Box className = { nodeRateWrapperClass } style = { nodeRateStyle } >
453600 { formatRate ( data ?. vertexMetrics ?. ratePerMin ) }
454601 </ Box >
455602 </ Tooltip >
0 commit comments