Skip to content

feat: add node alignment helper lines with toggle control in flow editor#8279

Merged
Cristhianzl merged 7 commits into
mainfrom
cz/add-helper-lines
Jul 14, 2025
Merged

feat: add node alignment helper lines with toggle control in flow editor#8279
Cristhianzl merged 7 commits into
mainfrom
cz/add-helper-lines

Conversation

@Cristhianzl
Copy link
Copy Markdown
Member

@Cristhianzl Cristhianzl commented May 29, 2025

This pull request introduces a new feature to display helper lines for node alignment in the flow editor, along with associated UI updates and state management. The changes include adding helper line rendering, snapping functionality, and a toggle control to enable or disable the feature.

Helper Line Rendering and Snapping

  • Added the HelperLines component to render horizontal and vertical alignment lines based on node positions (src/frontend/src/pages/FlowPage/components/PageComponent/components/helper-lines.tsx).
  • Implemented logic in getHelperLines and getSnapPosition to calculate alignment lines and snap nodes to aligned positions (src/frontend/src/pages/FlowPage/components/PageComponent/helpers/helper-lines.ts).

UI and Interaction Updates

  • Added a new button to the CanvasControls component for toggling helper lines, with visual feedback based on the toggle state (src/frontend/src/components/core/canvasControlsComponent/index.tsx). [1] [2] [3]
  • Updated the Page component to handle node dragging events, calculate helper lines, and snap positions dynamically (src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx). [1] [2] [3] [4] [5]

State Management

  • Extended the useFlowStore state management to include helperLineEnabled and its corresponding setter (src/frontend/src/stores/flowStore.ts).
  • Updated the FlowStoreType definition to include the new state properties (src/frontend/src/types/zustand/flow/index.ts).

Styling

  • Added CSS styles for the helper lines, including dashed lines and shadow effects for better visibility (src/frontend/src/style/applies.css).

This pull request adds a new button to the React Flow custom controls that enables alignment lines between components during use.
When enabled, alignment lines will appear as shown in the screenshot below:

image - image - image

Summary by CodeRabbit

  • New Features

    • Introduced toggleable helper lines in the flow editor for easier node alignment.
    • Added snapping behavior to nodes during dragging, visually guided by helper lines.
    • Helper lines can be enabled or disabled via a new control in the canvas controls panel.
  • Style

    • Added visual styling for helper lines, including dashed lines and drop shadow effects for improved visibility.

…r nodes during drag and drop operations. This feature includes the ability to toggle helper lines on and off, snap nodes to alignment positions, and visually display horizontal and vertical lines for alignment.
…adability by removing redundant comments explaining basic logic in helper-lines.ts
@Cristhianzl Cristhianzl self-assigned this May 29, 2025
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label May 29, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 29, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

A helper lines feature was introduced for the flow editor. This includes state management for enabling helper lines, logic for calculating and snapping node positions, rendering helper lines during node dragging, new React components, and corresponding CSS for visual styling. The control panel now includes a toggle for this feature.

Changes

File(s) Change Summary
src/frontend/src/components/core/canvasControlsComponent/index.tsx Added "Helper Lines" toggle button; integrated state selectors and toggle logic for helper line display.
src/frontend/src/pages/FlowPage/components/PageComponent/components/helper-lines.tsx Added new HelperLines React component to render SVG helper lines.
src/frontend/src/pages/FlowPage/components/PageComponent/helpers/helper-lines.ts Introduced helper functions and types for computing and snapping to helper lines.
src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx Integrated helper lines and snapping into node dragging logic; renders HelperLines when enabled.
src/frontend/src/stores/flowStore.ts
src/frontend/src/types/zustand/flow/index.ts
Added helperLineEnabled state and setter to flow store and its type definition.
src/frontend/src/style/applies.css Added CSS classes for helper line visualization and container.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CanvasControls
    participant FlowStore
    participant PageComponent
    participant HelperLines

    User->>CanvasControls: Clicks "Helper Lines" toggle
    CanvasControls->>FlowStore: setHelperLineEnabled(newState)
    FlowStore-->>PageComponent: helperLineEnabled state updated

    User->>PageComponent: Drags node
    PageComponent->>PageComponent: Compute helper lines & snap position
    PageComponent->>HelperLines: Render helper lines (if enabled)
    PageComponent->>PageComponent: Update node position (if snapping)
    User->>PageComponent: Releases node
    PageComponent->>HelperLines: Remove helper lines
Loading

Poem

A toggle appears with a gentle shine,
Now helper lines guide where nodes align.
As you drag and drop with glee,
Snapping helps with symmetry!
Dashed and bright, they softly show—
A rabbit’s way to help you flow.
🐇✨

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cz/add-helper-lines

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@dosubot dosubot Bot added the enhancement New feature or request label May 29, 2025
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels May 29, 2025
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (5)
src/frontend/src/style/applies.css (1)

1266-1284: Good styling implementation with minor redundancy.

The helper lines styling is well-implemented:

  • Proper overlay positioning with pointer-events-none
  • Good visual design with dashed lines, opacity, and drop shadow
  • Correct use of CSS custom properties for theming

However, there's redundancy in the .horizontal and .vertical subclasses - they both set the same stroke: hsl(var(--primary)) which is already defined in the parent .helper-line class.

Consider removing the redundant stroke declarations:

-.helper-line.horizontal {
-  stroke: hsl(var(--primary));
-}
-
-.helper-line.vertical {
-  stroke: hsl(var(--primary));
-}
+.helper-line.horizontal,
+.helper-line.vertical {
+  /* Additional specific styling if needed */
+}
src/frontend/src/pages/FlowPage/components/PageComponent/components/helper-lines.tsx (1)

15-36: Add explicit width / height and use consistent units inside the <svg> element

<svg> without an explicit width / height inherits the intrinsic size of its parent – in many layouts this ends up being 0×0, so the lines never render.
In addition, x1={0} / y1={0} are numeric pixels, whereas x2="100%" / y2="100%" are percent strings. Mixing the two is valid, but makes the coordinate-system harder to reason about and trips some strict TS/linters.

-  return (
-    <svg className="helper-lines">
+  return (
+    <svg
+      className="helper-lines"
+      width="100%"
+      height="100%"
+      /* preserveAspectRatio keeps lines aligned when the canvas is resized */
+      preserveAspectRatio="none"
+    >

If you prefer to rely on CSS, at minimum add a comment clarifying that .helper-lines { width:100%; height:100%; } is required.

Make sure the helper lines are still visible after this change in all browsers.

src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx (2)

356-360: State explosion risk – throttle setHelperLines during drag

setHelperLines is called on every position change while dragging. When the cursor moves quickly this can trigger dozens of React state updates per animation frame, leading to dropped frames on large flows.

Add a small throttle (requestAnimationFrame or lodash.throttle(16ms)) around the updater:

- const [helperLines, setHelperLines] = useState<HelperLinesState>({});
+ const [helperLines, _setHelperLines] = useState<HelperLinesState>({});
+ const setHelperLines = useRef(
+   _.throttle((value: HelperLinesState) => _setHelperLines(value), 16)
+ ).current;

(or debounce with { leading:true, trailing:true }).


664-705: Don’t re-render <HelperLines> when the feature is disabled

{helperLineEnabled && <HelperLines … />} is fine, but the surrounding component still re-renders because helperLines changes in state even when helperLineEnabled is false. Consider moving helperLines into a useMemo that returns an empty object when the flag is off, or early-return in the state updater – this removes an unnecessary render path.

🧰 Tools
🪛 Biome (1.9.4)

[error] 688-689: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

src/frontend/src/pages/FlowPage/components/PageComponent/helpers/helper-lines.ts (1)

133-178: Redundant draggingNodeBounds calculation & unused variables

Inside both horizontal and vertical snap sections you recompute draggingNodeBounds but never use them afterwards. Remove these dead variables to reduce GC pressure:

- const draggingNodeBounds = {
-   top: …,
- };
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3d2f847 and 5fb69b1.

📒 Files selected for processing (7)
  • src/frontend/src/components/core/canvasControlsComponent/index.tsx (3 hunks)
  • src/frontend/src/pages/FlowPage/components/PageComponent/components/helper-lines.tsx (1 hunks)
  • src/frontend/src/pages/FlowPage/components/PageComponent/helpers/helper-lines.ts (1 hunks)
  • src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx (7 hunks)
  • src/frontend/src/stores/flowStore.ts (1 hunks)
  • src/frontend/src/style/applies.css (1 hunks)
  • src/frontend/src/types/zustand/flow/index.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/frontend/src/pages/FlowPage/components/PageComponent/components/helper-lines.tsx (1)
src/frontend/src/pages/FlowPage/components/PageComponent/helpers/helper-lines.ts (1)
  • HelperLinesState (9-12)
src/frontend/src/components/core/canvasControlsComponent/index.tsx (1)
src/frontend/src/utils/utils.ts (1)
  • cn (36-38)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: autofix
🔇 Additional comments (5)
src/frontend/src/stores/flowStore.ts (1)

1045-1048: LGTM! Helper lines state implementation follows store patterns.

The implementation correctly follows the established patterns in the flow store:

  • Proper initialization with false as a sensible default
  • Simple setter function with consistent naming convention
  • Correctly positioned within the store object
src/frontend/src/types/zustand/flow/index.ts (1)

288-289: LGTM! Type definitions correctly match the store implementation.

The type definitions are properly structured:

  • helperLineEnabled: boolean matches the store initialization
  • setHelperLineEnabled: (helperLineEnabled: boolean) => void matches the setter implementation
  • Consistent with other boolean state properties in the interface
src/frontend/src/components/core/canvasControlsComponent/index.tsx (3)

82-85: LGTM! State selectors follow established patterns.

The helper lines state selectors are properly implemented:

  • Consistent with other state selectors in the component
  • Proper use of the flow store
  • Good separation of setter and getter

116-118: LGTM! Toggle handler is correctly implemented.

The toggle handler follows good practices:

  • Simple and focused function
  • Proper useCallback with correct dependencies
  • Consistent naming convention with other handlers

161-169: LGTM! Toggle button integrates well with existing controls.

The helper lines toggle button is well-implemented:

  • Consistent with other CustomControlButton usage
  • Good icon choice (UnfoldHorizontal) for the feature
  • Proper conditional styling using the cn utility
  • Appropriate tooltip text and test ID

Comment on lines +383 to +450
const onNodesChangeWithHelperLines = useCallback(
(changes: NodeChange<AllNodeType>[]) => {
// Only process helper lines if the feature is enabled
if (helperLineEnabled) {
const dragChange = changes.find(
(change) =>
change.type === "position" &&
"dragging" in change &&
change.dragging &&
"id" in change,
);

if (
dragChange &&
dragChange.type === "position" &&
"position" in dragChange &&
isDragging
) {
const draggingNode = nodes.find((node) => node.id === dragChange.id);
if (draggingNode && dragChange.position) {
const updatedNode = {
...draggingNode,
position: dragChange.position,
};

const currentHelperLines = getHelperLines(updatedNode, nodes);
setHelperLines(currentHelperLines);

const snapPosition = getSnapPosition(updatedNode, nodes);

if (
snapPosition.x !== dragChange.position.x ||
snapPosition.y !== dragChange.position.y
) {
const updatedChanges = changes.map((change) => {
if (
"id" in change &&
change.id === dragChange.id &&
change.type === "position" &&
"position" in change
) {
return {
...change,
position: snapPosition,
};
}
return change;
});
onNodesChange(updatedChanges);
return;
}
}
}

if (!isDragging && (helperLines.horizontal || helperLines.vertical)) {
setHelperLines({});
}
} else {
// Clear helper lines if feature is disabled
if (helperLines.horizontal || helperLines.vertical) {
setHelperLines({});
}
}

onNodesChange(changes);
},
[onNodesChange, nodes, isDragging, helperLines, helperLineEnabled],
);
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.

⚠️ Potential issue

Potential TypeScript runtime error & unnecessary O(N²) loop

  1. getHelperLines / getSnapPosition are called twice per event with the same arguments. Cache the result or merge both calls to save ~50 % work per drag event.

  2. The helper util already iterates over all nodes; wrapping it again inside a nodes.find + map adds another O(N). With many nodes the drag can hitch. Consider computing snap & position once, then directly mutating dragChange.position before passing changes downstream ─ this avoids the expensive second map.

  3. When there is no dragChange, onNodesChangeWithHelperLines falls through to onNodesChange(changes) but keeps isDragging true. If the user releases the mouse outside of a node the onNodeDragStop callback might not fire and the flag is never cleared. Add a fallback:

  if (!dragChange) {
-
+     setIsDragging(false);
+     setHelperLines({});
+     onNodesChange(changes);
+     return;
  }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx around
lines 383 to 450, optimize onNodesChangeWithHelperLines by calling
getHelperLines and getSnapPosition only once per event and caching their results
to avoid duplicate computation. Replace the nodes.find and changes.map with
direct mutation of dragChange.position to snapPosition to eliminate the extra
O(N) iteration. Also, add a fallback condition to clear isDragging and
helperLines when no dragChange is found but isDragging remains true, ensuring
the drag state resets properly if the mouse is released outside a node.

Comment on lines +14 to +116
const SNAP_DISTANCE = 5;

export function getHelperLines(
draggingNode: Node,
nodes: Node[],
nodeWidth = 150,
nodeHeight = 50,
): HelperLinesState {
const helperLines: HelperLinesState = {};

const draggingNodeBounds = {
left: draggingNode.position.x,
right:
draggingNode.position.x + (draggingNode.measured?.width || nodeWidth),
top: draggingNode.position.y,
bottom:
draggingNode.position.y + (draggingNode.measured?.height || nodeHeight),
centerX:
draggingNode.position.x + (draggingNode.measured?.width || nodeWidth) / 2,
centerY:
draggingNode.position.y +
(draggingNode.measured?.height || nodeHeight) / 2,
};

const otherNodes = nodes.filter((node) => node.id !== draggingNode.id);

for (const node of otherNodes) {
const nodeBounds = {
left: node.position.x,
right: node.position.x + (node.measured?.width || nodeWidth),
top: node.position.y,
bottom: node.position.y + (node.measured?.height || nodeHeight),
centerX: node.position.x + (node.measured?.width || nodeWidth) / 2,
centerY: node.position.y + (node.measured?.height || nodeHeight) / 2,
};

if (Math.abs(draggingNodeBounds.top - nodeBounds.top) < SNAP_DISTANCE) {
helperLines.horizontal = {
id: `horizontal-top-${node.id}`,
position: nodeBounds.top,
orientation: "horizontal",
};
}

if (
Math.abs(draggingNodeBounds.bottom - nodeBounds.bottom) < SNAP_DISTANCE
) {
helperLines.horizontal = {
id: `horizontal-bottom-${node.id}`,
position: nodeBounds.bottom,
orientation: "horizontal",
};
}

if (
Math.abs(draggingNodeBounds.centerY - nodeBounds.centerY) < SNAP_DISTANCE
) {
helperLines.horizontal = {
id: `horizontal-center-${node.id}`,
position: nodeBounds.centerY,
orientation: "horizontal",
};
}
}

for (const node of otherNodes) {
const nodeBounds = {
left: node.position.x,
right: node.position.x + (node.measured?.width || nodeWidth),
top: node.position.y,
bottom: node.position.y + (node.measured?.height || nodeHeight),
centerX: node.position.x + (node.measured?.width || nodeWidth) / 2,
centerY: node.position.y + (node.measured?.height || nodeHeight) / 2,
};

if (Math.abs(draggingNodeBounds.left - nodeBounds.left) < SNAP_DISTANCE) {
helperLines.vertical = {
id: `vertical-left-${node.id}`,
position: nodeBounds.left,
orientation: "vertical",
};
}

if (Math.abs(draggingNodeBounds.right - nodeBounds.right) < SNAP_DISTANCE) {
helperLines.vertical = {
id: `vertical-right-${node.id}`,
position: nodeBounds.right,
orientation: "vertical",
};
}

if (
Math.abs(draggingNodeBounds.centerX - nodeBounds.centerX) < SNAP_DISTANCE
) {
helperLines.vertical = {
id: `vertical-center-${node.id}`,
position: nodeBounds.centerX,
orientation: "vertical",
};
}
}

return helperLines;
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.

🛠️ Refactor suggestion

Combine the two passes over otherNodes & store the closest snap

The file loops over otherNodes twice – first for horizontal, then for vertical checks – performing identical bounding-box calculations twice. This is an avoidable O(N²) cost on every mouse-move.

Suggested refactor (outline):

for (const node of otherNodes) {
  const bounds = ;
  const dxTop = Math.abs(draggingBounds.top - bounds.top);
  
  if (dxTop < SNAP_DISTANCE && dxTop < bestHorizontalDelta) {
      bestHorizontalDelta = dxTop;
      helperLines.horizontal = {};
  }
  // same loop, but collect vertical as well
}

Besides performance, storing the nearest helperLine prevents the later line overwriting the earlier one (current implementation replaces the line if two conditions are met).

🤖 Prompt for AI Agents
In
src/frontend/src/pages/FlowPage/components/PageComponent/helpers/helper-lines.ts
between lines 14 and 116, the code loops twice over otherNodes to calculate
horizontal and vertical helper lines separately, repeating bounding box
calculations and potentially overwriting helperLines. Refactor by combining
these loops into a single loop that calculates node bounds once per node, then
checks all horizontal and vertical snap distances within that loop. Track the
closest snap distance for horizontal and vertical separately, updating
helperLines only if the current node is closer than the previously stored one,
to improve performance and prevent overwriting helper lines.

Comment on lines +1 to +12
import { Node, XYPosition } from "@xyflow/react";

export interface HelperLine {
id: string;
position: number;
orientation: "horizontal" | "vertical";
}

export interface HelperLinesState {
horizontal?: HelperLine;
vertical?: HelperLine;
}
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.

⚠️ Potential issue

measured property does not exist on Node – breaks TS compile

@xyflow/react’s Node type exposes width and height, not measured.
All occurrences of node.measured?.width|height will raise:

Property 'measured' does not exist on type 'Node<...>'

Replace every usage with the canonical fields (with fallback):

- node.measured?.width || nodeWidth
+ (node.width ?? nodeWidth)

and likewise for height.

This change affects lines 27–36, 42–48, 82–88, 137–175.

- right: draggingNode.position.x + (draggingNode.measured?.width || nodeWidth),
+ right: draggingNode.position.x + (draggingNode.width ?? nodeWidth),

(continue for all occurrences)

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
src/frontend/src/pages/FlowPage/components/PageComponent/helpers/helper-lines.ts
at lines 27–36, 42–48, 82–88, and 137–175, the code incorrectly accesses a
non-existent 'measured' property on the 'Node' type from '@xyflow/react',
causing TypeScript compilation errors. Replace all instances of
'node.measured?.width' and 'node.measured?.height' with 'node.width ?? 0' and
'node.height ?? 0' respectively to use the correct properties with a fallback to
zero. Update all these occurrences accordingly to fix the type errors.

Comment on lines +116 to +119
const onToggleHelperLines = useCallback(() => {
setHelperLineEnabled(!helperLineEnabled);
}, [setHelperLineEnabled, helperLineEnabled]);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

On toggle can we change the icon? Right now there is no indication that the button was clicked while the user is still hovering over it.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

a smooth change

image
image

…he state of helperLineEnabled to provide better user experience
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels May 29, 2025
Copy link
Copy Markdown
Collaborator

@Empreiteiro Empreiteiro left a comment

Choose a reason for hiding this comment

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

Dashed lines appear to lend a hand,
Guiding you to build your plan.
Where once was guesswork, now there's flow
Components click and neatly glow.
For those who hate misaligned plight,
This feature brings pure work delight!

Gravando.2025-05-29.191126.mp4

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label May 29, 2025
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jun 26, 2025
…er lines and snapping to grid position during drag for better user experience.
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jun 26, 2025
@carlosrcoelho carlosrcoelho requested a review from mfortman11 July 2, 2025 18:26
@Empreiteiro Empreiteiro requested review from rodrigosnader and removed request for rodrigosnader July 11, 2025 16:25
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 14, 2025
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jul 14, 2025

Frontend Unit Test Coverage Report

Coverage Summary

Lines Statements Branches Functions
Coverage: 71%
73.58% (117/159) 57.46% (77/134) 59.52% (25/42)

Unit Test Results

Tests Skipped Failures Errors Time
45 0 💤 0 ❌ 0 🔥 2.607s ⏱️

@Cristhianzl Cristhianzl enabled auto-merge July 14, 2025 14:25
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 14, 2025
@Cristhianzl Cristhianzl added this pull request to the merge queue Jul 14, 2025
Merged via the queue into main with commit 76e6c98 Jul 14, 2025
55 checks passed
@Cristhianzl Cristhianzl deleted the cz/add-helper-lines branch July 14, 2025 14:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request lgtm This PR has been approved by a maintainer size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants