Skip to content

fix: table cell editor now closes on any other press on the unified canvas - #566

Open
bvnaik05 wants to merge 1 commit into
frappe:mainfrom
bvnaik05:563-table-cell-editor-deselect
Open

bvnaik05 wants to merge 1 commit into
frappe:mainfrom
bvnaik05:563-table-cell-editor-deselect

Conversation

@bvnaik05

Copy link
Copy Markdown
Contributor

Summary

  • Fixes Clicking empty canvas doesn't deselect an open table cell editor #563: with a table cell editor open (editingCell set), clicking empty canvas — away from the table — did not commit/close the editor on a unified document (the type "Create" makes, i.e. most new diagrams). The toolbar and caret both stayed on screen.
  • Root cause: on the unified canvas, delegatesSurface() in DiagramCanvas.vue only routes a select-tool press to the whiteboard layer for tools in WHITEBOARD_TOOLS — select isn't one of them. So a plain empty-canvas click never reached the whiteboard's own selectAt/beginMarquee, which is what actually nulls editingCell and empties the selection on a miss-click. (A legacy whiteboard-only document was unaffected — there the sole-registrant rule routes every tool to the whiteboard layer regardless.)
  • This is also the exact gap fix: table toolbar, header columns, click-to-select, wrap and auto-fit (#556) #557 documents as a deliberately-deferred "known gap" ("click-outside-deselect... unified documents"), so this closes that out too.
  • Fix: onSurfacePointerDown now clears the whiteboard selection itself (whiteboardUi.clearSelection()) for a plain, non-additive press on a unified doc with the select tool, before routing the press onward — mirroring the same miss-click clear the legacy path already does. This closes the editor (committing the in-progress text) and drops the table's own selection, so clicking away returns the canvas to its normal, nothing-selected state.

Test plan

  • yarn vitest run — all 151 files / 1741 tests pass, including a new tableCellEditorClose.test.js pinning the wiring (source-inspection house pattern — DiagramCanvas.vue can't mount in the node test env, same as structuralConnector.test.js)
  • yarn build — succeeds
  • Manually verified in the running app on a unified document: opened a table cell (double-click), typed text, clicked empty canvas — the text committed, the cell-editing toolbar disappeared, and the table's own selection cleared too (toolbar reverted to the plain Select state)

🤖 Generated with Claude Code

…anvas (frappe#563)

blockEmpty and delegatesSurface aside, the select tool never delegated
surface pointerdowns to the whiteboard layer on a unified document, so
the legacy whiteboard's own selectAt/clearSelection — which is what
actually nulls editingCell and drops the selection on an empty-canvas
click — never ran there. An open cell editor (and its toolbar) stayed
on screen after clicking away, and the table itself stayed selected
too. onSurfacePointerDown now clears the whiteboard selection itself
for a plain press on a unified doc, mirroring that same miss-click
clear, before routing the press onward.
Copilot AI lite review requested due to automatic review settings August 28, 2026 09:31

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@greptile-apps

greptile-apps Bot commented Aug 28, 2026

Copy link
Copy Markdown

Confidence Score: 4/5

The mixed-selection drag regression should be fixed before merging because dragging a selected shared shape leaves co-selected whiteboard objects behind.

The unconditional pre-routing clear removes whiteboard objects before the shared transform captures the complete mixed selection.

Files Needing Attention: frontend/src/components/canvas/DiagramCanvas.vue

Prompt To Fix All With AI
### Issue 1
frontend/src/components/canvas/DiagramCanvas.vue:509
**Mixed selection drag breaks**

When a unified canvas has a shared shape and whiteboard object selected together, this clears the whiteboard selection before the shared move snapshots it, causing the shape to move while the co-selected whiteboard object stays behind.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "fix: table cell editor now closes on any..." | Re-trigger Greptile

!isAdditiveEvent(event) &&
(whiteboardUi.state.editingCell || whiteboardUi.state.selection.length)
) {
whiteboardUi.clearSelection()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Mixed selection drag breaks

When a unified canvas has a shared shape and whiteboard object selected together, this clears the whiteboard selection before the shared move snapshots it, causing the shape to move while the co-selected whiteboard object stays behind.

Knowledge Base Used:

Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/components/canvas/DiagramCanvas.vue
Line: 509

Comment:
**Mixed selection drag breaks**

When a unified canvas has a shared shape and whiteboard object selected together, this clears the whiteboard selection before the shared move snapshots it, causing the shape to move while the co-selected whiteboard object stays behind.

**Knowledge Base Used:**
- [Canvas interaction and rendering](https://app.greptile.com/frappe/-/custom-context/knowledge-base/frappe/draw/-/docs/canvas-interaction-and-rendering.md)
- [Whiteboard and freeform content](https://app.greptile.com/frappe/-/custom-context/knowledge-base/frappe/draw/-/docs/whiteboard-and-freeform-content.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

@vibhavkatre vibhavkatre left a comment

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.

The diagnosis is right and the placement in onSurfacePointerDown is right, but one claim in the new comment is not true, and because of it the fix leaves a table on the unified canvas with no way back.

The comment says the press can never be on the table:

A press that reaches this handler is always off the table (its own pointerdown intercepts and stops propagation for any in-bounds press)

WhiteboardTable.vue:185 only stops propagation once the table is already selected:

if (isAdditiveEvent(event) || !ui.isSelected('table', props.table.id)) return
event.stopPropagation()

and the comment above it says so explicitly — "fall through to the surface selectAt". On a legacy whiteboard that fall-through lands in selectAt, which selects the table. On a unified document it lands here, and delegatesSurface() returns false for the select tool, so nothing selects it.

What that costs. Today the only route into a table on a unified canvas is editTableCellAt on double-click (DiagramCanvas.vue:632), which selects the table and opens a cell editor. Before this PR the selection then stuck around — the bug #563 reports — so the table stayed usable. After this PR, clicking empty canvas correctly deselects it, and a single click on the table no longer brings it back: the user has to double-click into a cell every time they want to move or restyle the table.

The fix is small and belongs in the same block. Export a selectWhiteboardAt(store, point) from useWhiteboardInteraction.js — whiteboardHitAt + SELECT_FN are already there, just not exported — and in onSurfacePointerDown select the object under the point if there is one, clear otherwise:

if (isUnified.value && editorUi.state.tool === 'select' && !isAdditiveEvent(event)) {
  const point = selection.toLogicalFor(event, surface.value, viewport)
  if (!selectWhiteboardAt(store, point)) whiteboardUi.clearSelection()
}

That keeps everything #563 asks for, makes a table selectable by a plain click on the unified canvas the way it is on a legacy whiteboard, and — worth checking while you are there — probably closes the same gap for drawn lines and strokes, which have no per-object pointerdown at all.

On the test. The source-inspection pattern is the house one and fine here, but the first regex pins the exact whitespace and line breaks of the if, so reformatting the condition breaks a passing test for no reason. The three ordering assertions below it are the ones carrying real meaning; I would keep those and loosen the first to the parts that matter (isUnified, tool === 'select', !isAdditiveEvent, clearSelection).

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.

Clicking empty canvas doesn't deselect an open table cell editor

3 participants