Skip to content

[WIKI-554] feat: delete multiple rows/columns from a table#7426

Merged
pushya22 merged 2 commits intopreviewfrom
chore/table-delete
Jul 17, 2025
Merged

[WIKI-554] feat: delete multiple rows/columns from a table#7426
pushya22 merged 2 commits intopreviewfrom
chore/table-delete

Conversation

@aaryan610
Copy link
Member

@aaryan610 aaryan610 commented Jul 16, 2025

Description

This PR introduces the ability to delete multiple rows/columns from a table by selection them and hitting Backspace/Delete. The first backspace clears the content inside the selected cells, and the second deletes the cells.

Other improvements-

  1. Created a helper function to check whether a selection is a CellSelection or not.
  2. Deleted unused plugins.

Type of Change

  • Improvement (change that would cause existing functionality to not work as expected)

Media

Screen.Recording.2025-07-16.at.18.47.42.mov

Summary by CodeRabbit

  • Refactor

    • Streamlined table cell selection and deletion logic by consolidating utility functions and removing duplicate code.
    • Updated keyboard shortcut handling for table deletion, enabling deletion of entire rows or columns when all selected cells are empty.
    • Improved consistency in cell selection checks across the editor.
  • New Features

    • Enhanced table editing: Now supports deleting full rows or columns with keyboard shortcuts when all selected cells are empty.
  • Chores

    • Removed unused plugins and utility files related to table cell selection outlines.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 16, 2025

Walkthrough

This update refactors table-related utilities by centralizing helper functions for cell emptiness and selection checks, removes the table selection outline plugin and its utilities, and introduces a new handler for delete key operations on tables. Several redundant or duplicate implementations are deleted, with logic consolidated into shared modules.

Changes

Files/Groups Change Summary
.../table/plugins/insert-handlers/utils.ts, .../table/table-view.tsx, .../table/plugins/selection-outline/plugin.ts Refactored to use shared helper functions (isCellEmpty, isCellSelection) instead of local or direct instance checks.
.../table/plugins/table-selection-outline/plugin.ts, .../table/plugins/table-selection-outline/utils.ts Deleted the table selection outline plugin and its related utility functions.
.../table/table/utilities/delete-table-when-all-cells-selected.ts Deleted the command for deleting a table when all cells are selected.
.../table/table/utilities/delete-key-shortcut.ts Added a new handler for delete key operations on tables, supporting row/column deletion when all selected cells are empty.
.../table/table/utilities/helpers.ts Added isCellEmpty utility function; now provides both cell selection and emptiness checks.
.../table/table.ts Switched keyboard shortcut handlers to use the new delete key handler instead of the old "delete table" logic.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Editor
    participant TableUtil as Table Utilities

    User->>Editor: Presses Delete/Backspace with table cell selection
    Editor->>TableUtil: handleDeleteKeyOnTable(selection, state, dispatch)
    TableUtil->>TableUtil: Check if selection is cell selection
    TableUtil->>TableUtil: Check if selected cells are empty
    alt All selected cells are empty and full rows/columns selected
        TableUtil->>Editor: Delete rows/columns, reposition cursor
    else
        TableUtil->>Editor: No action
    end
Loading

Possibly related PRs

  • makeplane/plane#7274: Adds the table selection outline plugin and related utilities, which are removed in this PR, indicating a direct but inverse relationship regarding the table selection outline feature.

Suggested labels

ready to merge

Suggested reviewers

  • Palanikannan1437
  • VipinDevelops
  • sriramveeraghanta

Poem

In the warren of code, some helpers did roam,
Now gathered together, they’ve found a new home.
Outlines erased, old shortcuts replaced,
With tidy new logic, confusion’s effaced.
A hop and a skip, the table’s now neat—
This rabbit’s quite proud of this codebase’s feat!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

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 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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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.

@makeplane
Copy link

makeplane bot commented Jul 16, 2025

Pull Request Linked with Plane Work Items

Comment Automatically Generated by Plane

Copy link
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: 1

🧹 Nitpick comments (1)
packages/editor/src/core/extensions/table/table/utilities/delete-key-shortcut.ts (1)

91-113: Remove redundant fallback search

The manual search loop (lines 103-110) is redundant as it performs the exact same operation as indexOf. If indexOf returns -1, the manual loop will also fail to find the value.

 const findCellCoordinate = (cellStart: number, tableInfo: TableInfo): CellCoord | null => {
-  // Primary method: use indexOf
   const cellIndex = tableInfo.map.map.indexOf(cellStart);
 
   if (cellIndex !== -1) {
     return {
       row: Math.floor(cellIndex / tableInfo.totalColumns),
       col: cellIndex % tableInfo.totalColumns,
     };
   }
 
-  // Fallback: manual search
-  for (let i = 0; i < tableInfo.map.map.length; i++) {
-    if (tableInfo.map.map[i] === cellStart) {
-      return {
-        row: Math.floor(i / tableInfo.totalColumns),
-        col: i % tableInfo.totalColumns,
-      };
-    }
-  }
-
   return null;
 };
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 89983b0 and da2e991.

📒 Files selected for processing (9)
  • packages/editor/src/core/extensions/table/plugins/insert-handlers/utils.ts (1 hunks)
  • packages/editor/src/core/extensions/table/plugins/selection-outline/plugin.ts (2 hunks)
  • packages/editor/src/core/extensions/table/plugins/table-selection-outline/plugin.ts (0 hunks)
  • packages/editor/src/core/extensions/table/plugins/table-selection-outline/utils.ts (0 hunks)
  • packages/editor/src/core/extensions/table/table/table-view.tsx (2 hunks)
  • packages/editor/src/core/extensions/table/table/table.ts (2 hunks)
  • packages/editor/src/core/extensions/table/table/utilities/delete-key-shortcut.ts (1 hunks)
  • packages/editor/src/core/extensions/table/table/utilities/delete-table-when-all-cells-selected.ts (0 hunks)
  • packages/editor/src/core/extensions/table/table/utilities/helpers.ts (2 hunks)
💤 Files with no reviewable changes (3)
  • packages/editor/src/core/extensions/table/table/utilities/delete-table-when-all-cells-selected.ts
  • packages/editor/src/core/extensions/table/plugins/table-selection-outline/plugin.ts
  • packages/editor/src/core/extensions/table/plugins/table-selection-outline/utils.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/editor/src/core/extensions/table/table/utilities/delete-key-shortcut.ts (2)
packages/editor/src/core/extensions/table/table/utilities/helpers.ts (2)
  • isCellSelection (10-10)
  • isCellEmpty (17-35)
packages/editor/src/index.ts (1)
  • CORE_EXTENSIONS (37-37)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (7)
packages/editor/src/core/extensions/table/table/utilities/helpers.ts (1)

12-35: Well-structured cell emptiness check with proper node type handling.

The isCellEmpty function correctly handles different scenarios:

  • Null cells and empty content
  • Paragraph nodes (checking content size)
  • Other node types (checking content size or text nodes)

The centralization of this logic from the previous duplicate implementation is a good improvement.

packages/editor/src/core/extensions/table/table/table-view.tsx (1)

100-100: Good refactoring to use centralized helper function.

Replacing the direct CellSelection instance check with isCellSelection(selection) improves consistency across the codebase and centralizes the selection type checking logic.

packages/editor/src/core/extensions/table/plugins/selection-outline/plugin.ts (1)

29-29: Consistent refactoring to use centralized selection helper.

The change from selection instanceof CellSelection to isCellSelection(selection) aligns with the broader refactoring effort to standardize selection type checking across the table extension.

packages/editor/src/core/extensions/table/table/table.ts (1)

239-242: Significant behavioral enhancement for table delete operations.

The replacement of deleteTableWhenAllCellsSelected with handleDeleteKeyOnTable implements the new multi-row/column deletion feature described in the PR objectives. This provides more nuanced delete behavior where:

  • First delete clears cell content
  • Second delete removes the cells themselves
  • Supports deleting multiple rows/columns when selection spans them

This change aligns well with the PR's goal to improve table editing UX.

packages/editor/src/core/extensions/table/plugins/insert-handlers/utils.ts (1)

5-5: Good refactoring to eliminate code duplication.

Importing isCellEmpty from the shared helpers module instead of maintaining a local implementation centralizes the logic and reduces code duplication. This aligns with the broader refactoring effort to consolidate table utilities.

packages/editor/src/core/extensions/table/table/utilities/delete-key-shortcut.ts (2)

143-166: Fix row deletion logic to account for shifting indices

After deleting a row, all subsequent rows shift up by one position. The current implementation continues to position the cursor at the original minRow, which could lead to deleting incorrect rows.

 const deleteMultipleRows = (
   editor: Editor,
   totalRowsInSelection: number,
   minRow: number,
   initialTableInfo: TableInfo
 ): boolean => {
-  // Position cursor at the first selected row
-  setCursorAtPosition(editor, initialTableInfo, minRow, 0);
-
-  // Delete rows one by one
+  // Always delete at the same row index as rows shift up after deletion
   for (let i = 0; i < totalRowsInSelection; i++) {
+    const updatedTableInfo = getTableInfo(editor);
+    if (!updatedTableInfo) return false;
+    
+    setCursorAtPosition(editor, updatedTableInfo, minRow, 0);
     editor.commands.deleteRow();
-
-    // Reposition cursor if there are more rows to delete
-    if (i < totalRowsInSelection - 1) {
-      const updatedTableInfo = getTableInfo(editor);
-      if (updatedTableInfo) {
-        setCursorAtPosition(editor, updatedTableInfo, minRow, 0);
-      }
-    }
   }
 
   return true;
 };

Likely an incorrect or invalid review comment.


168-191: Fix column deletion logic to account for shifting indices

Similar to the row deletion issue, columns shift left after deletion. The current implementation could delete incorrect columns.

 const deleteMultipleColumns = (
   editor: Editor,
   totalColumnsInSelection: number,
   minCol: number,
   initialTableInfo: TableInfo
 ): boolean => {
-  // Position cursor at the first selected column
-  setCursorAtPosition(editor, initialTableInfo, 0, minCol);
-
-  // Delete columns one by one
+  // Always delete at the same column index as columns shift left after deletion
   for (let i = 0; i < totalColumnsInSelection; i++) {
+    const updatedTableInfo = getTableInfo(editor);
+    if (!updatedTableInfo) return false;
+    
+    setCursorAtPosition(editor, updatedTableInfo, 0, minCol);
     editor.commands.deleteColumn();
-
-    // Reposition cursor if there are more columns to delete
-    if (i < totalColumnsInSelection - 1) {
-      const updatedTableInfo = getTableInfo(editor);
-      if (updatedTableInfo) {
-        setCursorAtPosition(editor, updatedTableInfo, 0, minCol);
-      }
-    }
   }
 
   return true;
 };

Likely an incorrect or invalid review comment.

Copy link
Member

@iam-vipin iam-vipin left a comment

Choose a reason for hiding this comment

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

LGTM

@pushya22 pushya22 merged commit d8f2c97 into preview Jul 17, 2025
5 of 6 checks passed
@pushya22 pushya22 deleted the chore/table-delete branch July 17, 2025 07:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants