Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

node-navigation.ts 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /**
  2. * Node navigation utilities for workflow
  3. * This module provides functions for node selection, focusing and scrolling in workflow
  4. */
  5. /**
  6. * Interface for node selection event detail
  7. */
  8. export type NodeSelectionDetail = {
  9. nodeId: string;
  10. focus?: boolean;
  11. }
  12. /**
  13. * Select a node in the workflow
  14. * @param nodeId - The ID of the node to select
  15. * @param focus - Whether to focus/scroll to the node
  16. */
  17. export function selectWorkflowNode(nodeId: string, focus = false): void {
  18. // Create and dispatch a custom event for node selection
  19. const event = new CustomEvent('workflow:select-node', {
  20. detail: {
  21. nodeId,
  22. focus,
  23. },
  24. })
  25. document.dispatchEvent(event)
  26. }
  27. /**
  28. * Scroll to a specific node in the workflow
  29. * @param nodeId - The ID of the node to scroll to
  30. */
  31. export function scrollToWorkflowNode(nodeId: string): void {
  32. // Create and dispatch a custom event for scrolling to node
  33. const event = new CustomEvent('workflow:scroll-to-node', {
  34. detail: { nodeId },
  35. })
  36. document.dispatchEvent(event)
  37. }
  38. /**
  39. * Setup node selection event listener
  40. * @param handleNodeSelect - Function to handle node selection
  41. * @returns Cleanup function
  42. */
  43. export function setupNodeSelectionListener(
  44. handleNodeSelect: (nodeId: string) => void,
  45. ): () => void {
  46. // Event handler for node selection
  47. const handleNodeSelection = (event: CustomEvent<NodeSelectionDetail>) => {
  48. const { nodeId, focus } = event.detail
  49. if (nodeId) {
  50. // Select the node
  51. handleNodeSelect(nodeId)
  52. // If focus is requested, scroll to the node
  53. if (focus) {
  54. // Use a small timeout to ensure node selection happens first
  55. setTimeout(() => {
  56. scrollToWorkflowNode(nodeId)
  57. }, 100)
  58. }
  59. }
  60. }
  61. // Add event listener
  62. document.addEventListener(
  63. 'workflow:select-node',
  64. handleNodeSelection as EventListener,
  65. )
  66. // Return cleanup function
  67. return () => {
  68. document.removeEventListener(
  69. 'workflow:select-node',
  70. handleNodeSelection as EventListener,
  71. )
  72. }
  73. }
  74. /**
  75. * Setup scroll to node event listener with ReactFlow
  76. * @param nodes - The workflow nodes
  77. * @param reactflow - The ReactFlow instance
  78. * @returns Cleanup function
  79. */
  80. export function setupScrollToNodeListener(
  81. nodes: any[],
  82. reactflow: any,
  83. ): () => void {
  84. // Event handler for scrolling to node
  85. const handleScrollToNode = (event: CustomEvent<NodeSelectionDetail>) => {
  86. const { nodeId } = event.detail
  87. if (nodeId) {
  88. // Find the target node
  89. const node = nodes.find(n => n.id === nodeId)
  90. if (node) {
  91. // Use ReactFlow's fitView API to scroll to the node
  92. reactflow.fitView({
  93. nodes: [node],
  94. padding: 0.2,
  95. duration: 800,
  96. minZoom: 0.5,
  97. maxZoom: 1,
  98. })
  99. }
  100. }
  101. }
  102. // Add event listener
  103. document.addEventListener(
  104. 'workflow:scroll-to-node',
  105. handleScrollToNode as EventListener,
  106. )
  107. // Return cleanup function
  108. return () => {
  109. document.removeEventListener(
  110. 'workflow:scroll-to-node',
  111. handleScrollToNode as EventListener,
  112. )
  113. }
  114. }