Skip to content

[PRO-93] feat: apply select box to condition node enum parameters#79

Merged
fray-cloud merged 1 commit intodevfrom
fix/#93
Apr 2, 2026
Merged

[PRO-93] feat: apply select box to condition node enum parameters#79
fray-cloud merged 1 commit intodevfrom
fix/#93

Conversation

@fray-cloud
Copy link
Copy Markdown
Owner

@fray-cloud fray-cloud commented Apr 2, 2026

Summary

  • Adds options?: string[] to ParamDefinition type so node parameters can declare fixed enum values
  • Renders a <select> dropdown in ParamInput when options are present (localized via PARAM_VALUE_LABELS)
  • Applies options to: AND/OR operator, crossover direction, threshold operator, market-order side, RSI source

Changes

  • packages/types/src/flow.ts — add options field to ParamDefinition
  • apps/web/src/components/flows/node-inspector.tsx — conditional <select> render + Korean labels

Related

🤖 Generated with Claude Code

Summary by Sourcery

Introduce enum-style parameter options to flow nodes and render them as select dropdowns in the node inspector UI.

New Features:

  • Allow node parameter definitions to declare fixed option lists for their values.
  • Render select dropdown inputs in the node inspector when parameters specify predefined options.

Enhancements:

  • Define option lists for several existing node parameters, including RSI source, comparison operators, crossover direction, logical operators, and market-order side.

- Add `options?: string[]` to ParamDefinition type
- Add options arrays to and-or (AND/OR), crossover (above/below),
  threshold operator (</>/<=/>==/==), market-order side (buy/sell),
  and rsi source (close/open/high/low) params
- ParamInput renders <select> dropdown when options are present,
  showing localized labels from PARAM_VALUE_LABELS

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Apr 2, 2026

Reviewer's Guide

Adds enum-like parameter options to flow node definitions and updates the node inspector to render those parameters as localized select dropdowns instead of free-form inputs where applicable.

Sequence diagram for enum parameter selection in node inspector

sequenceDiagram
  actor User
  participant NodeInspector
  participant ParamInput
  participant BrowserDOM
  participant FlowStore

  User->>NodeInspector: Open_node_configuration
  NodeInspector->>NodeInspector: Read_NodeTypeInfo_and_ParamDefinition
  NodeInspector->>ParamInput: render(paramKey, value, onChange, options)
  ParamInput->>BrowserDOM: Render_select_when_options_present

  User->>BrowserDOM: Change_selected_option
  BrowserDOM->>ParamInput: change_event_with_selected_value
  ParamInput->>NodeInspector: onChange(selectedValue)
  NodeInspector->>FlowStore: updateNodeConfig(nodeId, partialConfig)
  FlowStore-->>NodeInspector: Updated_node_config_state
  NodeInspector-->>User: Display_updated_parameter_value
Loading

Class diagram for updated flow parameter definitions and node inspector

classDiagram
  class ParamDefinition {
    string key
    boolean required
    string[] options
  }

  class PortDefinition {
    string name
    string type
    string direction
  }

  class NodeTypeInfo {
    string subtype
    PortDefinition[] inputs
    PortDefinition[] outputs
    any defaultConfig
    ParamDefinition[] params
  }

  class NodeTypeRegistry {
    NodeTypeInfo rsi
    NodeTypeInfo threshold
    NodeTypeInfo crossover
    NodeTypeInfo and_or
    NodeTypeInfo market_order
  }

  class NodeInspector {
    +render()
    +updateNodeConfig(nodeId, partialConfig)
  }

  class ParamInput {
    +render(paramKey, value, onChange, options)
  }

  NodeTypeRegistry "1" --> "many" NodeTypeInfo : contains
  NodeTypeInfo "1" --> "many" ParamDefinition : has
  NodeTypeInfo "1" --> "many" PortDefinition : defines
  NodeInspector "1" --> "many" ParamInput : renders
  ParamInput --> ParamDefinition : uses_options
Loading

File-Level Changes

Change Details Files
Introduce optional enum-style options on parameter definitions and wire them through to the node inspector UI.
  • Extend ParamDefinition with an optional options string array for declaring fixed values.
  • Propagate options from required and optional params into the ParamInput component in the node inspector.
  • Update ParamInput to render a styled select dropdown when options are present, falling back to existing boolean/button and text input behavior otherwise.
  • Localize select option labels using PARAM_VALUE_LABELS when available.
packages/types/src/flow.ts
apps/web/src/components/flows/node-inspector.tsx
Apply fixed options to specific flow node parameters that should behave as enums.
  • Add options to RSI source parameter (close, open, high, low).
  • Constrain threshold operator to comparison operators (<, >, <=, >=, ==).
  • Constrain crossover direction to above/below.
  • Constrain AND/OR operator to AND/OR.
  • Constrain market-order side to buy/sell.
packages/types/src/flow.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • When rendering the <select>, consider handling cases where value is not in the options array (e.g., legacy or malformed configs) by providing a fallback option or default to avoid an empty/undefined visual state.
  • If you expect enum-like options to grow more complex over time (labels, descriptions, disabled states), it may be worth introducing a structured ParamOption type instead of a bare string[] for ParamDefinition.options to keep the API extensible.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- When rendering the `<select>`, consider handling cases where `value` is not in the `options` array (e.g., legacy or malformed configs) by providing a fallback option or default to avoid an empty/undefined visual state.
- If you expect enum-like options to grow more complex over time (labels, descriptions, disabled states), it may be worth introducing a structured `ParamOption` type instead of a bare `string[]` for `ParamDefinition.options` to keep the API extensible.

## Individual Comments

### Comment 1
<location path="apps/web/src/components/flows/node-inspector.tsx" line_range="50-64" />
<code_context>
+  if (options && options.length > 0) {
+    return (
+      <select
+        value={String(value)}
+        onChange={(e) => onChange(e.target.value)}
+        className="rounded border border-border bg-background px-2 py-1 text-xs text-foreground outline-none focus:border-primary"
</code_context>
<issue_to_address>
**suggestion:** Stringifying `undefined` can yield `"undefined"` in the select value.

For optional params, `value` may briefly be `undefined` (e.g., during config updates), so `String(value)` becomes `'undefined'`, which won't match any option and can put the select in an odd state. Consider normalizing nullish values, e.g. `value={value == null ? '' : String(value)}`, and providing a corresponding placeholder option if appropriate.

```suggestion
  if (options && options.length > 0) {
    const hasEmptyOption = options.includes('');
    const stringValue = value == null ? '' : String(value);

    return (
      <select
        value={stringValue}
        onChange={(e) => onChange(e.target.value)}
        className="rounded border border-border bg-background px-2 py-1 text-xs text-foreground outline-none focus:border-primary"
      >
        {!hasEmptyOption && stringValue === '' && (
          <option value="" disabled>
            Select…
          </option>
        )}
        {options.map((opt) => (
          <option key={opt} value={opt}>
            {PARAM_VALUE_LABELS[opt] ?? opt}
          </option>
        ))}
      </select>
    );
  }
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +50 to +64
if (options && options.length > 0) {
return (
<select
value={String(value)}
onChange={(e) => onChange(e.target.value)}
className="rounded border border-border bg-background px-2 py-1 text-xs text-foreground outline-none focus:border-primary"
>
{options.map((opt) => (
<option key={opt} value={opt}>
{PARAM_VALUE_LABELS[opt] ?? opt}
</option>
))}
</select>
);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion: Stringifying undefined can yield "undefined" in the select value.

For optional params, value may briefly be undefined (e.g., during config updates), so String(value) becomes 'undefined', which won't match any option and can put the select in an odd state. Consider normalizing nullish values, e.g. value={value == null ? '' : String(value)}, and providing a corresponding placeholder option if appropriate.

Suggested change
if (options && options.length > 0) {
return (
<select
value={String(value)}
onChange={(e) => onChange(e.target.value)}
className="rounded border border-border bg-background px-2 py-1 text-xs text-foreground outline-none focus:border-primary"
>
{options.map((opt) => (
<option key={opt} value={opt}>
{PARAM_VALUE_LABELS[opt] ?? opt}
</option>
))}
</select>
);
}
if (options && options.length > 0) {
const hasEmptyOption = options.includes('');
const stringValue = value == null ? '' : String(value);
return (
<select
value={stringValue}
onChange={(e) => onChange(e.target.value)}
className="rounded border border-border bg-background px-2 py-1 text-xs text-foreground outline-none focus:border-primary"
>
{!hasEmptyOption && stringValue === '' && (
<option value="" disabled>
Select…
</option>
)}
{options.map((opt) => (
<option key={opt} value={opt}>
{PARAM_VALUE_LABELS[opt] ?? opt}
</option>
))}
</select>
);
}

@fray-cloud
Copy link
Copy Markdown
Owner Author

코드 리뷰 완료. LGTM ✅

검토 결과:

  • ParamDefinitionoptions?: string[] 추가 — 기존 코드와 완전 호환되는 additive 변경
  • ParamInput에서 options 유무에 따른 분기 렌더링 로직 정확함
  • PARAM_VALUE_LABELS에 모든 enum 값(buy/sell, AND/OR, above/below, close/open/high/low) 한글 라벨 완비
  • 비교 연산자(<, >, <=, >=, ==)는 범용 기호라 raw fallback으로 처리 — 적절
  • required/optional 파라미터 모두 options prop 전달 경로 정상
  • Tailwind 스타일링 기존 컴포넌트와 일관성 유지

머지 진행합니다.

@fray-cloud fray-cloud merged commit a92bea4 into dev Apr 2, 2026
3 checks passed
@fray-cloud fray-cloud deleted the fix/#93 branch April 2, 2026 01:17
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.

1 participant