Skip to content

#759 supported#882

Merged
revolist merged 6 commits into
mainfrom
#759
Jun 5, 2026
Merged

#759 supported#882
revolist merged 6 commits into
mainfrom
#759

Conversation

@revolist

@revolist revolist commented Jun 5, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Clipboard can be configured with a rangeFill option to paste a single cell across a selected range; utilities added to support this.
  • Behavior Change

    • Range-fill clipboard behavior enabled by default on page load.
  • Refactor

    • Paste transformation logic rewritten to respect target ranges and readonly cells and accept new clipboard config.
  • Tests

    • New unit and end-to-end tests covering paste behaviors with and without range-fill.
  • Chores

    • Public types and component props updated to accept the clipboard configuration.

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a configurable ClipboardConfig with rangeFill to control single-cell paste behavior; widens useClipboard props/types, refactors ColumnService to accept { start, data, targetRange }, updates overlay paste handling and clipboard helpers, adds unit and e2e tests, enables rangeFill in the demo serve, and updates docs pointer.

Changes

Clipboard Range-Fill Feature

Layer / File(s) Summary
ClipboardConfig type definition & generated typings
src/types/interfaces.ts, src/components.d.ts, src/components/revoGrid/revo-grid.tsx
New exported ClipboardConfig with optional rangeFill; generated Stencil types and RevoGrid prop widened to `boolean
Clipboard utils and overlay paste flow
src/components/overlay/clipboard.utils.ts, src/components/overlay/revogr-overlay-selection.tsx
Adds getRangeFillClipboardData, isClipboardRangeFillEnabled, trimming helpers; OverlaySelection derives rangeFillData and optional targetRange, then calls columnService.getTransformedDataToApply({ start, data, targetRange }).
Data service range-aware transformation
src/components/data/column.service.ts
Introduces DataToApplyOptions; refactors getTransformedDataToApply to accept { start, data, targetRange }, compute apply bounds, apply rows/cols skipping readonly, track applied area, and return conditional range or null.
ColumnService unit tests
test/column-service.spec.ts
Adds tests for default paste focused-cell behavior, expansion into targetRange for single-cell clipboard, skipping readonly cells, and empty-clipboard no-op.
E2E helpers and tests
e2e/helpers/types.ts, e2e/helpers/grid.ts, e2e/range.spec.ts
E2E types import ClipboardConfig; GridSetupOptions adds useClipboard; grid mount applies useClipboard; Playwright tests validate rangeFill-enabled paste fills selection and default paste updates only focused cell (including trailing-delimiter cases).
Clipboard utils unit tests
test/overlay-selection.spec.ts
Adds Jest tests validating trimming/normalization behavior and disabled range-fill behavior.
Serve demo enable range-fill
src/serve/controller.js
Demo onLoad() sets grid.useClipboard = { rangeFill: true }.
Documentation submodule update
docs
Docs subproject pointer updated to a newer commit.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant OverlaySelection
  participant ColumnService
  participant DataStoreRow
  participant DataStoreCol
  participant RevoGrid
  User->>OverlaySelection: paste event (clipboard data)
  OverlaySelection->>OverlaySelection: normalize via getRangeFillClipboardData
  OverlaySelection->>ColumnService: paste({ start, data, targetRange? })
  ColumnService->>DataStoreRow: compute per-row changes (skip readonly)
  ColumnService->>DataStoreCol: compute per-column mappings
  ColumnService-->>OverlaySelection: return { changed, range|null }
  OverlaySelection->>RevoGrid: apply changed cells / rerender
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

feature

Suggested reviewers

  • m2a2x

Poem

🐰 I nibble keys and hop with glee,

A single paste can fill a sea,
Or stay a dot where it began,
With rangeFill I follow plan,
Hooray — now paste like magic, whee!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title '#759 supported' is vague and does not clearly convey the main purpose of the changeset. It references an issue number but provides no meaningful context about what feature or fix is being implemented. Replace the title with a descriptive summary of the main change, such as 'Add range-fill clipboard configuration support' or 'Support configurable clipboard range-fill behavior'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch #759

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c6bf2b0f91

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/overlay/revogr-overlay-selection.tsx Outdated

@coderabbitai coderabbitai Bot 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/components/data/column.service.ts (1)

285-316: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Return null when every target cell is skipped.

Lines 304-305 advance maxCol and lastRow even when the inner loop never writes a cell, so a fully read-only paste target still returns a concrete range. That breaks the new RangeArea | null contract and makes src/components/overlay/revogr-overlay-selection.tsx Line 864 treat a no-op paste as applied.

Suggested fix
       const endCol = Math.min(
         colLength - 1,
         targetRange?.x1 ?? start.x + copyColLength - 1,
       );
       // columns
+      let rowWritten = false;
       let colIndex = startCol;
       for (let j = 0; colIndex <= endCol; colIndex++, j++) {
         const p = this.columns[colIndex].prop;
         const currentCol = j % copyColLength;
 
         /** if can write */
         if (!this.isReadOnly(rowIndex, colIndex)) {
           /** to show before save */
           if (!changed[rowIndex]) {
             changed[rowIndex] = {};
           }
           changed[rowIndex][p] = copyRow[currentCol];
+          rowWritten = true;
+          maxCol = Math.max(maxCol, colIndex);
         }
       }
-      maxCol = Math.max(maxCol, colIndex - 1);
-      lastRow = rowIndex;
+      if (rowWritten) {
+        lastRow = rowIndex;
+      }
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/data/column.service.ts` around lines 285 - 316, The loop
currently advances maxCol and lastRow even when no cells were written (e.g., all
targets are read-only), causing a false non-null range; fix by tracking whether
any write occurred for each row (e.g., a local boolean like wroteInRow and an
overall wroteAny) inside the inner loop that checks isReadOnly and only update
maxCol and lastRow when wroteInRow is true (and compute/getRange only when
wroteAny is true), ensuring the function returns null when every target cell was
skipped; reference variables/methods: isReadOnly, changed, maxCol, lastRow,
getRange, startCol, startRow.
src/components/overlay/revogr-overlay-selection.tsx (1)

848-865: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Stop before applying a null paste range.

getTransformedDataToApply now explicitly returns range: null when there is no applicable target, but Line 864 still forwards that result into onRangeApply. Short-circuit on !range here so the overlay honors the new service contract instead of pushing a no-op/invalid target downstream.

Suggested fix
     const { defaultPrevented: canPaste } = this.rangeClipboardPaste.emit({
       data: changed,
       models: collectModelsOfRange(changed, this.dataStore),
       range,
       ...this.types,
     });
 
-    if (canPaste) {
+    if (canPaste || !range) {
       return;
     }
     this.autoFillService?.onRangeApply(changed, range, range);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/overlay/revogr-overlay-selection.tsx` around lines 848 - 865,
After calling getClipboardPasteTargetRange and
columnService.getTransformedDataToApply (producing changed and range),
short-circuit if range is falsy (range === null) and return early rather than
continuing; do this before emitting rangeClipboardPaste.emit and before calling
autoFillService.onRangeApply so we do not forward a null/invalid range
downstream (refer to getClipboardPasteTargetRange,
columnService.getTransformedDataToApply, rangeClipboardPaste.emit,
autoFillService.onRangeApply and the changed/range variables).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/components/data/column.service.ts`:
- Around line 285-316: The loop currently advances maxCol and lastRow even when
no cells were written (e.g., all targets are read-only), causing a false
non-null range; fix by tracking whether any write occurred for each row (e.g., a
local boolean like wroteInRow and an overall wroteAny) inside the inner loop
that checks isReadOnly and only update maxCol and lastRow when wroteInRow is
true (and compute/getRange only when wroteAny is true), ensuring the function
returns null when every target cell was skipped; reference variables/methods:
isReadOnly, changed, maxCol, lastRow, getRange, startCol, startRow.

In `@src/components/overlay/revogr-overlay-selection.tsx`:
- Around line 848-865: After calling getClipboardPasteTargetRange and
columnService.getTransformedDataToApply (producing changed and range),
short-circuit if range is falsy (range === null) and return early rather than
continuing; do this before emitting rangeClipboardPaste.emit and before calling
autoFillService.onRangeApply so we do not forward a null/invalid range
downstream (refer to getClipboardPasteTargetRange,
columnService.getTransformedDataToApply, rangeClipboardPaste.emit,
autoFillService.onRangeApply and the changed/range variables).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3d7c3ddb-d63f-45e6-8f31-e2f7f5d5326e

📥 Commits

Reviewing files that changed from the base of the PR and between 8b253f4 and c6bf2b0.

📒 Files selected for processing (9)
  • docs
  • e2e/helpers/grid.ts
  • e2e/helpers/types.ts
  • e2e/range.spec.ts
  • src/components.d.ts
  • src/components/data/column.service.ts
  • src/components/overlay/revogr-overlay-selection.tsx
  • src/components/revoGrid/revo-grid.tsx
  • src/types/interfaces.ts

@revolist

revolist commented Jun 5, 2026

Copy link
Copy Markdown
Owner Author

@codex review

Repository owner deleted a comment from chatgpt-codex-connector Bot Jun 5, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7490850826

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/overlay/clipboard.utils.ts Outdated
@revolist

revolist commented Jun 5, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@sonarqubecloud

sonarqubecloud Bot commented Jun 5, 2026

Copy link
Copy Markdown

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@revolist revolist merged commit fa3bc93 into main Jun 5, 2026
8 checks passed
@revolist revolist deleted the #759 branch June 5, 2026 15:58
@revolist revolist added the feature New feature or request label Jun 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants