Skip to content

Conversation

@waleedlatif1
Copy link
Collaborator

Summary

  • added action bar for picker/hand/undo/redo/zoom workflow controls, added general setting to disabl
  • added util to fitViewToBounds that is panel/sidebar/terminal aware & updated callers
  • added new emcn hand and picker icon, updated strokewidth for some existing ones that were only used in this contetx

Type of Change

  • New feature

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link

vercel bot commented Jan 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
docs Ready Ready Preview, Comment Jan 15, 2026 9:23pm

Review with Vercel Agent

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 10, 2026

Greptile Summary

This PR adds a new workflow controls action bar for canvas interaction modes (hand/cursor), fit-to-view functionality, and undo/redo controls. It introduces a general setting to toggle the visibility of these controls and properly refactors the canvas mode system to use persistent hand/cursor mode switching instead of temporary Shift-key behavior.

Key changes:

  • Added WorkflowControls component (renamed from action-bar) with mode selector, fit-to-view, undo/redo, and context menu
  • Added showActionBar boolean setting to user preferences (database, schema, stores, API)
  • Implemented useCanvasViewport hook that accounts for sidebar, panel, and terminal overlays when calculating fit-to-view bounds
  • Created useCanvasModeStore for persistent hand/cursor mode selection stored in localStorage
  • Updated canvas behavior: selectionOnDrag={!isHandMode} and panOnDrag={isHandMode ? [0, 1] : false}
  • Removed dead isShiftPressed state and its event listeners (previously used for temporary selection mode)
  • Added new hand and cursor SVG icons with proper stroke widths
  • Added canvas-mode-specific CSS classes for cursor styling (grab/grabbing in hand mode, default in cursor mode)
  • Updated fitViewToBounds calls throughout the codebase to use the new overlay-aware utility

All previous review comments have been properly addressed: error handling now awaits mutations, dead state has been removed, and the system supports both persistent canvas modes and multi-selection key combinations.

Confidence Score: 5/5

  • This PR is safe to merge with no critical issues. All previous review comments have been properly addressed, and the feature implementation is solid.
  • Score reflects thorough implementation with no bugs found. The PR successfully: (1) Properly manages the new showActionBar setting throughout the data flow (database → API → React Query → Zustand → components); (2) Correctly removes dead isShiftPressed state and event listeners that were cluttering the component; (3) Implements error handling that properly awaits mutation results before closing UI; (4) Creates overlay-aware fitViewToBounds utility that accounts for all sidebar, panel, and terminal dimensions; (5) Establishes persistent hand/cursor mode system with localStorage persistence; (6) Properly applies CSS classes for cursor styling based on canvas mode; (7) Maintains backward compatibility with multi-selection key codes. All previous review feedback has been implemented.
  • No files require special attention. All changes are straightforward and well-integrated.

Important Files Changed

Filename Overview
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-controls/workflow-controls.tsx Renamed from action-bar and now properly handles canvas mode switching, fit-to-view, undo/redo controls, and hide functionality. Error handling correctly awaits mutations. No issues found.
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx Removed dead isShiftPressed state and its event listeners. Replaced with persistent canvas-mode store for hand/cursor toggling. Canvas behavior now controlled via isHandMode variable. Selection-on-drag and pan-on-drag properly conditional.
apps/sim/stores/settings/general/store.ts General settings store properly initialized with showActionBar: true default. Store interface correctly includes the new setting.
apps/sim/hooks/use-canvas-viewport.ts Utility properly accounts for sidebar, panel, and terminal overlays when calculating visible bounds and fitting view. Math is correct for viewport positioning.
packages/db/schema.ts Database schema includes showActionBar column with correct boolean type and true default. Column properly indexed and typed.

Sequence Diagram

sequenceDiagram
    participant User
    participant UI as WorkflowControls UI
    participant Store as Canvas Mode Store
    participant Settings as Settings Store
    participant API as API Endpoint
    participant DB as Database

    User->>UI: Click hand/cursor mode button
    UI->>Store: setMode('hand' or 'cursor')
    Store->>Store: Save to localStorage
    Store->>UI: Update tooltip & icon
    
    User->>UI: Click "Fit to View"
    UI->>UI: fitViewToBounds() with overlay offsets
    UI->>UI: Calculate visible canvas bounds
    UI->>UI: Animate viewport to fit all nodes
    
    User->>UI: Right-click to hide controls
    UI->>UI: handleHide() - show context menu
    User->>UI: Click "Hide canvas controls"
    UI->>API: PATCH /api/users/me/settings
    API->>DB: UPDATE settings.show_action_bar = false
    DB-->>API: Success
    API-->>Settings: Optimistic update
    Settings-->>UI: showActionBar = false
    UI->>UI: Component returns null

    User->>UI: Open Settings Modal
    UI->>Settings: Check showActionBar setting
    UI->>UI: Toggle switch
    UI->>API: PATCH /api/users/me/settings
    API->>DB: UPDATE settings.show_action_bar
    DB-->>API: Success
    API-->>Settings: Update store
    Settings-->>UI: Conditional render

Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

3 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

@waleedlatif1
Copy link
Collaborator Author

@greptile

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

4 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

onSelectionStart={onSelectionStart}
onSelectionEnd={onSelectionEnd}
panOnDrag={isHandMode ? [0, 1] : false}
multiSelectionKeyCode={['Meta', 'Control', 'Shift']}
Copy link
Contributor

Choose a reason for hiding this comment

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

With the new hand/cursor mode system, having Shift in multiSelectionKeyCode may cause confusion. Previously, Shift was used to toggle selection mode temporarily, but now it's just one of the multi-selection modifiers.

Since the new system uses a persistent mode toggle (hand vs cursor), consider whether Shift should still be in this array. If users press Shift in hand mode, it might create unexpected behavior where they can multi-select even though they're in hand mode.

Consider removing Shift from this array or documenting the intended behavior when Shift is pressed in hand mode.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx
Line: 3326:3326

Comment:
With the new hand/cursor mode system, having Shift in multiSelectionKeyCode may cause confusion. Previously, Shift was used to toggle selection mode temporarily, but now it's just one of the multi-selection modifiers.

Since the new system uses a persistent mode toggle (hand vs cursor), consider whether Shift should still be in this array. If users press Shift in hand mode, it might create unexpected behavior where they can multi-select even though they're in hand mode.

Consider removing Shift from this array or documenting the intended behavior when Shift is pressed in hand mode.

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines 55 to 82
const handleHide = async () => {
try {
await updateSetting.mutateAsync({ key: 'showActionBar', value: false })
} finally {
setContextMenu(null)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Error handling is incomplete - if updateSetting.mutateAsync fails, the error is silently swallowed. The context menu closes regardless of success or failure, leaving the user unaware that the setting wasn't actually updated.

Consider logging the error or showing a notification to inform the user when the operation fails.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx
Line: 55:61

Comment:
Error handling is incomplete - if updateSetting.mutateAsync fails, the error is silently swallowed. The context menu closes regardless of success or failure, leaving the user unaware that the setting wasn't actually updated.

Consider logging the error or showing a notification to inform the user when the operation fails.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Collaborator Author

@waleedlatif1 waleedlatif1 left a comment

Choose a reason for hiding this comment

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

🤖 AI Code Review

Pull Request Review: Workflow Controls Action Bar

🔍 Overview

This PR adds an action bar for workflow controls (picker/hand/undo/redo/zoom) with a general setting to disable it, plus viewport fitting utilities and icon updates.

⚠️ Critical Issues

1. Incomplete PR Title and Description

  • The title and description are truncated ("...to disabl")
  • Action Required: Complete the description to clearly state what can be disabled and why

2. Missing Test Coverage

  • The checklist shows "Tests added/updated and passing" is unchecked
  • For a feature touching 30 files, automated tests are essential
  • Recommendation: Add unit tests for the new utilities and integration tests for the action bar

📋 General Concerns

Code Quality

Positive:

  • Feature appears well-scoped (workflow controls consolidation)
  • Includes settings for user customization

Concerns:

  • 30 files changed is substantial for a single PR - consider if this could be split into smaller, reviewable chunks:
    1. Utility functions (fitViewToBounds)
    2. Icon updates
    3. Action bar implementation
    4. Settings integration

Documentation

  • No mention of documentation updates
  • Questions to address:
    • Are there user-facing docs that need updating?
    • Is the new setting documented?
    • Are the new utilities documented with JSDoc/TSDoc?

🐛 Potential Issues

Without seeing the actual code, here are common pitfalls to check:

1. Viewport/Bounds Calculations

// Ensure fitViewToBounds handles edge cases:
// - Empty/null bounds
// - Negative dimensions
// - Panel/sidebar in collapsed state
// - Multiple monitors with different DPIs
// - Zoom limits (min/max)

2. Settings Persistence

  • Verify the disable setting persists across sessions
  • Check default value is sensible (likely enabled)
  • Ensure setting changes apply immediately without requiring reload

3. Undo/Redo State Management

  • Confirm undo/redo doesn't conflict with existing keyboard shortcuts
  • Verify state consistency when action bar is disabled
  • Check for memory leaks in undo history

4. Icon Updates

  • Ensure SVG icons are optimized
  • Verify accessibility (proper ARIA labels)
  • Check icon sizing is consistent across different zoom levels

🔒 Security Considerations

  • If settings are stored, ensure they're validated on load
  • Verify no XSS vulnerabilities if icons are dynamically loaded
  • Check that zoom controls have reasonable min/max limits to prevent DoS

⚡ Performance Implications

Potential Concerns:

  1. fitViewToBounds calculations - ensure these are debounced/throttled if called frequently
  2. Panel/sidebar awareness - verify this doesn't cause layout thrashing
  3. Icon rendering - confirm SVGs are cached appropriately
  4. Undo/redo history - ensure there's a reasonable limit to prevent memory issues

Recommendations:

// Example: Debounce expensive calculations
const debouncedFitView = debounce(fitViewToBounds, 150);

// Example: Limit undo history
const MAX_UNDO_HISTORY = 50;

🎯 Specific Recommendations

1. Code Organization

  • Extract the fitViewToBounds utility into a separate, well-tested module
  • Consider using a factory pattern for the action bar to improve testability

2. Accessibility

  • Ensure all controls have keyboard shortcuts
  • Add proper ARIA labels and roles
  • Test with screen readers
  • Verify focus management

3. User Experience

  • Consider adding tooltips to action bar buttons
  • Provide visual feedback for disabled state
  • Ensure the action bar doesn't obstruct important content
  • Consider making the action bar position customizable

4. Testing Strategy

// Suggested test coverage:
// - Unit tests for fitViewToBounds with various panel states
// - Integration tests for action bar interactions
// - E2E tests for undo/redo functionality
// - Visual regression tests for icon updates
// - Accessibility tests (axe-core)


This review was automatically generated by an AI assistant.

@emir-karabeg emir-karabeg changed the title feat(workflow-controls): added action bar for picker/hand/undo/redo/zoom workflow controls, added general setting to disabl feat(workflow-controls): added action bar for workflow controls Jan 14, 2026
@emir-karabeg
Copy link
Collaborator

@greptile

@waleedlatif1 waleedlatif1 merged commit 1cc489e into staging Jan 15, 2026
6 checks passed
@waleedlatif1 waleedlatif1 deleted the fix/action-bar branch January 15, 2026 21:25
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