Skip to content

fix: Workflow node search for several errors#4862

Merged
shaohuzhang1 merged 1 commit intov2from
pr@v2@fix_workflow_search
Mar 11, 2026
Merged

fix: Workflow node search for several errors#4862
shaohuzhang1 merged 1 commit intov2from
pr@v2@fix_workflow_search

Conversation

@shaohuzhang1
Copy link
Contributor

fix: Workflow node search for several errors

@shaohuzhang1 shaohuzhang1 merged commit ac43b46 into v2 Mar 11, 2026
3 checks passed
@shaohuzhang1 shaohuzhang1 deleted the pr@v2@fix_workflow_search branch March 11, 2026 02:38
defineExpose({ reSearch })
</script>

<style scoped>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The provided code is mostly correct, but there are several areas that could be improved or optimized:

  1. Null Checks: The use of props.lf and method calls like graphModel.getNodeModelById(...) can potentially throw null errors if lf is not defined or the node model does not exist.

  2. Type Checking and Defaults: Ensure that all properties used in filter, find, etc., have defaults in case they might return undefined unexpectedly.

  3. Error Handling : Add try-catch blocks around complex operations to catch and handle runtime errors more gracefully.

  4. Use Safe Navigation Operator (?.): Always use safe navigation (??) instead of optional chaining (?) when accessing deep nested objects to avoid potential type errors.

Here's an updated version with these improvements:

<script lang="ts" setup>
import { ref } from "vue";
// other imports

const selectedNodes = ref<LFNode[]>([]);
const currentIndex = ref<number | null>(null);
const searchText = ref("");

const getSelectNodes = (kw: string) => {
  const graph_data = props.lf?.getGraphData();
  if (!graph_data || !Array.isArray(graph_data.nodes)) {
    // handle error or default behavior
    return;
  }

  graph_data.nodes.filter((node: any) => {
    if (node.properties && typeof node.properties.stepName === 'string' &&
      node.properties.stepName.includes(kw)) {
      
      const safeNodeModel = props.lf?.graphModel?.getNodeModelById(node.id);
      if (safeNodeModel != null) {
        result.push({
          ...node,
          order: 1,
          focusOn: () => {
            if (currentNodeModel) {
              currentNodeModel.focusOn(searchText.value);
            }
          },
          selectOn: () => {
            if (currentNodeModel) {
              currentNodeModel.selectOn(searchText.value);
            }
          },
          clearSelectOn: () => {
            if (currentNodeModel) {
              currentNodeModel.clearSelectOn(searchText.value);
            }
          },
        });
      }
    }
    if (node.type === 'loop-body-node') {
      const nodeModel = props.lf?.graphModel;
      if (nodeModel != null){
        currentNodesValue.push(/* loop body logic*/ );
      }
}
  });
}

const next = () => {
  if (!selectedNodes.value || selectedNodes.value.length === 0) {
    return; // do nothing if no selected nodes are available
  }

  const currentNode = selectedNodes.value[currentIndex.value];
  if(currentIndex.value >= 0){ currentIndex.value--; }
};

const up = () => {
  if (selectedNodes.value && selectedNodes.value.length > 0) {
   selectedNodes.value[currentIndex.value]?.selectOn();
   currentIndex.value ? currentIndex.value-- : currentIndex.value = selectedNodes.value.length - 1;
 }
};

const handleSearch = (kw: string) => {
    searchText.value = kw.trim(); // ensure search text is trimmed before processing
    onSearch?.(searchText.value); // call existing function
}

const reSearch = () => {
  handleSearch('');
}

onMounted(() => {
  window.addEventListener('keydown', handleKeyDown);
});

onUnmounted(() => {
  window.removeEventListener('keydown', handleKeyDown);
})

defineExpose({ reSearch });

</script>

<style scoped>
/*
css styles
*/
</style>

These changes add safety checks and improve best practices for dealing with data flow between components and state management in Vue.js. Additionally, I added a parameter check in next() for selectedNodes, which avoids calling methods on an empty array causing errors and handles edge cases where selectedIndex may go below zero by setting it to zero initially rather than relying solely on conditional expressions.

})
initDefaultShortcut(lf.value, lf.value.graphModel)
lf.value.batchRegister([
...Object.keys(nodes).map((key) => nodes[key].default),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is a brief report on the code and some suggestions:

Issues/Failures:

  • No Import Statement for @vue/runtime-dom: There needs to be an import statement at the beginning of the file to use <Teleport>. For example: import { Teleport } from '@vue/runtime-dom';

Suggestions:

  1. Add Required Imports: Make sure all necessary imports are present, especially for any third-party libraries or Vue components used.
import { Teleport } from '@vue/runtime-dom';
  1. Ensure Component Names Are Correct: Double-check that the component names (Control, NodeSearch) exist in their respective files and are spelled correctly. If not, these could cause runtime errors.

  2. Update Flow ID Reference: Consider adding logic to update the flowId reference whenever it changes during graph re-rendering, rather than relying solely on lf.value.graphModel.flowId.

  3. Optimization for node:delete: The current approach of calling reSearch() immediately after deleting a node might trigger unnecessary searches if there's no change required. It's better to implement more precise conditions to decide when to perform a search.

  4. Consistent Use of Refs: Ensure consistency in using refs across different parts of your template and script setups. This can help avoid runtime errors and improve readability.

  5. Component Initialization: Initialize other state variables (like lf and others) early in the lifecycle to ensure they are available when needed without causing undefined errors.

These changes should help enhance the robustness and performance of your workflow application.

@f2c-ci-robot
Copy link

f2c-ci-robot bot commented Mar 11, 2026

Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@f2c-ci-robot
Copy link

f2c-ci-robot bot commented Mar 11, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant