Skip to content

Variable assign#2346

Merged
liuruibin merged 6 commits intomainfrom
variable-assign
Feb 21, 2025
Merged

Variable assign#2346
liuruibin merged 6 commits intomainfrom
variable-assign

Conversation

@liuruibin
Copy link
Member

What this PR does / why we need it?

Summary of your change

Please indicate you've done the following:

  • Made sure tests are passing and test coverage is added if needed.
  • Made sure commit message follow the rule of Conventional Commits specification.
  • Considered the docs impact and opened a new docs issue or PR with docs changes if needed.

set(props.nodeModel, 'validate', validate)
})
</script>
<style lang="scss" scoped></style>
Copy link
Contributor

Choose a reason for hiding this comment

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

The code appears to be a Vue component template and script setup block for an application workflow interface in an open-source project using Vue.js and Element Plus. Here's some feedback that highlights key aspects of the code:

Key Points:

  1. Template Structure:

    • The template uses various components including NodeContainer, el-form, el-card, el-form-item, el-button, el-select, and NodeCascader.
    • It dynamically generates cards based on form_data.variable_list using a v-for directive.
  2. Data Management:

    • A reactive data object called form is initialized with default variables.
    • A computed prop (form_data) syncs input form with workflow properties.
  3. Handling Form Events:

    • An event listener (@submit.prevent) is attached to the entire form element, preventing submission.
    • Individual field validation is handled via replyNodeFormRef.value?.validate() when needed.
  4. Functionality:

    • submitDialog modifies node content based on user selections.
    • addVariable adds new variables to the list and updates node_model.properties.node_data.
    • deleteVariable removes variables from the list and updates node_model.properties.node_data.
    • variableChange updates node labels using global fields if applicable.
  5. UI Enhancements:

    • Labels are structured using Flexbox for better alignment and accessibility.
    • Icons (like Delete and Plus) are used to enhance interactivity.
  6. Lifecycle Hook:

    • onMounted ensures initialization tasks like setting up the is_result property after checking its undefined state.
  7. Code Quality:

    • Code follows TypeScript conventions, with appropriate imports and use of hooks like defineProps, computed, etc.
    • Comments explain the purpose of each function and section of the template/script.

Potential Improvements:

  1. TypeScript Type Checking:

    • Ensure all types (especially custom ones) for properties like fields, reference, type, source are defined to avoid runtime errors.
  2. Conditional Rendering:

    • Use conditional rendering properly to handle scenarios where certain elements might not appear due to specific conditions (e.g., last node).
  3. Global Fields Handling:

    • Validate that accessing node_graphModel.nodes.map only exists when necessary to prevent potential runtime errors caused by undeclared variables.
  4. Performance Considerations:

    • Optimize performance-sensitive parts if any; especially those involving looping over large lists like node_graphModel.nodes.
  5. Documentation and Comments:

    • Add more comments explaining complex logic or sections in the component to make it easier for future developers to understand.
  6. Validation:

    • Double-check validations ensure they cover all expected scenarios and do no unnecessary computations during render cycles.

Overall, this component looks well-structured both syntactically and semantically. Minor adjustments can improve maintainability and robustness while keeping the core functionality intact.

'result_list': self.context.get('result_list'),
'status': self.status,
'err_message': self.err_message
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This code looks mostly correct but contains some minor issues and room for optimization:

  1. Code Style: Ensure consistent indentation and spacing to improve readability.

  2. Type Hints: While typing.List is good, make sure you have imported it from the right module (from typing import *) to avoid circular imports or undefined variables if this file has dependencies unrelated to List.

  3. Comments: The comments help understand what parts of the code do, which is great! However, consider adding more detailed comments explaining why certain steps are taken, especially where logic might require explanation (like handling JSON parsing).

  4. Function Naming Conventions: It's generally recommended to use underscores instead of spaces in function names, e.g., get_details(index: int, **kwargs) becomes get_details(index:int ,**kwargs). Similarly, keep other functions consistent with Python naming conventions.

  5. Exception Handling: You don't currently handle exceptions explicitly within any of these methods. Consider adding try-except blocks around potentially error-prone operations like loading a JSON string from a variable value or trying to set context fields.

  6. Optimization Suggestions:

    • Early Termination: If checking for an empty fields list before iterating over it doesn’t affect the intended flow, you could add it earlier to reduce unnecessary processing.
    • Use of Constants: Consider defining constants for known values used throughout the class that might otherwise be repeated multiple times. For example, "global" and default field indices/lengths might fit into this category.

These improvements should make your code cleaner and less error-prone while maintaining its functionality.

tooltip: 'Describe elements you want to exclude from the generated image',
placeholder:
'Please describe content you do not want to generate, such as color, bloody content'
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The code appears to be generally clear and well-written, with only minor punctuation and formatting adjustments needed. Here's a concise checklist for review:

Irregularities/Potential Issues:

  1. Duplicate Punctuation: There are two unnecessary periods at the end of lines.
    tooltip: 'Define the output content of this node. { form } is a placeholder for the form',
  2. Typographical Errors:
    • "Referencing" should likely be "Referred".
    • In the variable object, the phrase inside quotes might need revision (e.g., replacing spaces).
  3. Code Consistency:
    • Although the changes appear small, consistency would help readability.

Optimization Suggestions:

  1. Punctuation Consistency: Regularly check each line for consistent use of punctuation marks like dots (.) and commas (,).
  2. Consistent Naming Conventions: Consider standardizing naming conventions, especially where variables start with uppercase letters (camelCase).

Revised Code with Minor Corrections:

export default {
  autoSave: 'Auto Save',
  latestRelease: 'Latest Release',
  copyParam: 'Copy Parameters',
  debug: 'Run',

  tip: {
    publicSuccess: 'Published successfully',
  },
  
  variable: {
    label: 'Variable',
    global: 'Global Variable',
    referencing: 'Referenced Variable',
    referencingRequired: 'Referenced variable is required',
    referencingError: 'Invalid referenced variable',
    noReferencing: 'Referenced variable does not exist',
    placeholder: 'Please select a variable'
  },

  condition: {
    title: 'Execution Condition',
  },

  searchDatasetNode: {
    // Revisions applied here as well if necessary
  }

};

By applying these suggestions, the code becomes more readable and free of redundant punctuation.

set(props.nodeModel, 'validate', validate)
})
</script>
<style lang="scss" scoped></style>
Copy link
Contributor

Choose a reason for hiding this comment

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

This template appears to be for configuring variables in an application workflow. Here are some potential suggestions and findings:

  1. Duplicated IDs: The "id" attribute of NodeCascader within each loop has the same value (randomId()), which might create duplicate entries in your data.

  2. Potential Dangling References: Not all elements have clear references or connections with global fields, leading to unclear behavior when modifying variable references.

  3. Validation Logic: While validation is present, it can be more robust by ensuring that forms submitted are complete before committing changes.

  4. Optimization:

    • Use Vue Composition API hooks appropriately instead of relying solely on lifecycle hooks like onMounted.
    • Consider lazy loading or deferring the creation of components until they are needed.
  5. Scalability: Since this setup supports adding multiple variables using cloning and direct modification, scalability should not pose major issues unless managing very many at once becomes common.

  6. Accessibility: Ensure labels for inputs are clearly visible and accessible via keyboard navigation.

  7. Documentation/Comments: Add comments wherever necessary to explain complex logic and functionality.

Overall, the code seems well-documented and functional, but these improvements could enhance its maintainability and performance.

'result_list': self.context.get('result_list'),
'status': self.status,
'err_message': self.err_message
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The provided Python code appears to be an implementation of base functionality for handling variable assignments within flow steps. Some potential improvements and suggestions are:

  1. Code Formatting: The spacing between lines can enhance readability.

  2. Error Handling: Missing error handling for critical operations like field lookups and context updates could be added to prevent unexpected behavior under certain conditions.

  3. Efficiency Considerations:

    • The use of isinstance() checks in the type-specific logic might not be necessary with proper initialization.
    • Directly updating dictionaries using update() methods or unpacking could simplify some of this logic.
  4. Documentation: Adding comments around key parts of the code would help understand its purpose and operation more easily.

  5. Security Considerations: Be cautious about parsing potentially unsafe JSON values without validation.

  6. Type Annotations: While current annotation is sufficient, ensuring consistency across similar functions can improve clarity.

  7. Modularity: Extract reusable components into other classes/functions if they become too complex.

Here’s a revised version addressing these points:

# coding=utf-8
import json

from typing import List

from application.flow.i_step_node import NodeResult
from application.flow.step_node.variable_assign_node.i_variable_assign_node import (
    IVariableAssignNode,
)

class BaseVariableAssignNode(IVariableAssignNode):
    def __init__(self):
        self.context = {'variable_list': [], 'result_list': []}

    def save_context(self, details, workflow_manage):
        self.context['variable_list'] = details.get('variable_list', [])
        self.context['result_list'] = details.get('result_list', [])

    def execute(self, variable_list: List[dict], stream, **kwargs) -> NodeResult:
        result_list = []
        for variable in variable_list:
            fields = variable.setdefault("fields", [])  # Ensure fields exist and default to empty list

            if len(fields) < 2:
                continue

            global_flag = fields[0]
            local_key = fields[1]

            if global_flag == "global":
                input_value = self._get_reference_content(variable.get('reference'))
                output_value = input_value

                if variable_type := variable.get('type'):
                    value_to_set = self._parse_value(variable['value'], variable_type)
                else:
                    raise ValueError(f"Missing variable type: {variable}")

                if isinstance(value_to_set, (list, dict)):
                    self.workflow_manage.context.update({local_key: value_to_set})
                else:
                    self.workflow_manage.context.update({local_key: {}})  # Initialize dictionary

                result = {
                    'name': variable['name'],
                    'input_value': input_value,
                    'output_value': output_value,
                }
                result_list.append(result)

        return NodeResult({
            'variable_list': variable_list,
            'result_list': result_list,
        }, {})

    @staticmethod
    def _get_reference_content(reference: str):
        try:
            return str(self.workflow_manage.get_reference_field reference))
        except Exception as e:
            raise RuntimeError(f"Failed to retrieve reference content from field '{reference}'): {e}")

    @staticmethod
    def _parse_value(raw_value, var_type: str):
        if raw_value.startswith("{") and raw_value.endswith("}") or \
           raw_value.startswith("[") and raw_value.endswith("]"):
            return json.loads(raw_value)
        
        if var_type == "int":
            return int(raw_value)
        elif var_type == "float":
            return float(raw_value)
        else:
            return raw_value

    def get_details(self, index: int, **kwargs) -> dict:
        return {
            'name': self.node.properties.get('stepName'),
            'index': index,
            'run_time': self.context.get('run_time'),
            'type': self.node.type,
            'variable_list': self.context.get('variable_list'),
            'result_list': self.context.get('result_list'),
            'status': self.status,
            'err_message': self.err_message,
        }

Key Changes:

  • Initialization: Initializations were moved to the constructor for better encapsulation.
  • Field Handling: Used setdefault to ensure fields is always populated.
  • Logic Simplification: Refactored _execute method to reduce complexity by breaking down specific tasks.
  • Helper Methods: Introduced helper methods for retrieving reference content and parsing types, which makes the main function cleaner and easier to debug.

tooltip: 'Describe elements you want to exclude from the generated image',
placeholder:
'Please describe content you do not want to generate, such as color, bloody content'
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The code appears to be well-formed and free of obvious errors. However, there are a few areas that could benefit from improvement:

  1. Consistency and Naming: Ensure consistency in naming conventions across the translations and descriptions. For example, use label consistently rather than text, and keep abbreviations consistent (e.g., "App" instead of "appName").

  2. Placeholder Text: The placeholder text for some nodes uses {form}, which should be more descriptive or removed if not meaningful.

  3. Translation Accuracy: Double-check that all text is accurately translated into another language, especially complex terms like 'execution condition' or 'referenced variables'.

  4. Documentation: Add comments to explain non-obvious parts of the configuration, particularly for fields with tooltips.

  5. Optimization: Minor optimization can involve ensuring clarity and readability but won't affect functionality significantly.

Overall, the code looks functional and ready for deployment.

@liuruibin liuruibin merged commit df94068 into main Feb 21, 2025
3 checks passed
@liuruibin liuruibin deleted the variable-assign branch February 21, 2025 03:00
wangdan-fit2cloud added a commit that referenced this pull request Feb 24, 2025
* feat: Support variable assign

* feat: Workfloat support variable assign(#2114)

* feat: Support variable assign save input output value

* feat: Execution detail support variable assign(#2114)

* feat: Support variable assign dict array value config

* chore: rename package

---------

Co-authored-by: wangdan-fit2cloud <dan.wang@fit2cloud.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants