Skip to content

EPMRPP-104644 add outside drop for sortable component#248

Merged
evshipilo merged 4 commits intodevelopfrom
EPMRPP-106692-add-outside-drop-for-Sortable-component
Feb 26, 2026
Merged

EPMRPP-104644 add outside drop for sortable component#248
evshipilo merged 4 commits intodevelopfrom
EPMRPP-106692-add-outside-drop-for-Sortable-component

Conversation

@evshipilo
Copy link
Contributor

@evshipilo evshipilo commented Feb 25, 2026

Screen.Recording.2026-02-25.at.14.18.20.mov

Summary by CodeRabbit

  • New Features

    • Tree sortable components can now accept items from external drag-and-drop sources.
    • New props to enable external drops and specify external drop types; drag items expose an external flag.
    • Separate handlers for external move and duplicate actions to support distinct workflows.
  • Documentation

    • Added external drag-and-drop usage guide and examples.

@coderabbitai
Copy link

coderabbitai bot commented Feb 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e338f14 and 18b7a41.

📒 Files selected for processing (1)
  • src/components/sortable/README.md

Walkthrough

Adds external drag-and-drop support to the tree sortable system: new external drop constant, types, hook options and helper, component props and external handlers, plus README documentation; behavior routes external drops to dedicated handlers and conditions hover/drop logic on acceptExternalDrop.

Changes

Cohort / File(s) Summary
Constants
src/common/constants/sortable.ts
Added EXTERNAL_TREE_DROP_TYPE constant ('EXTERNAL_TREE_DROP').
Types
src/common/types/sortableTypes.ts
Extended types: TreeDragItem.isExternal?: boolean; added acceptExternalDrop? and externalDropType? to options/props; added onMoveExternal? and onDuplicateExternal? to container props.
Hook
src/common/hooks/useTreeSortable.ts
Added acceptExternalDrop / externalDropType options, isExternalDragItem helper, updated accepted drag types, hover/drop-position and collect/drop logic to handle external drops, and updated dependencies.
Components
src/components/sortable/treeSortableItem/treeSortableItem.tsx, src/components/sortable/treeSortableContainer/treeSortableContainer.tsx
TreeSortableItem forwards acceptExternalDrop and externalDropType to the hook; TreeSortableContainer adds onMoveExternal and onDuplicateExternal props and routes external drops to those handlers.
Docs
src/components/sortable/README.md
Documented new item/container props and external-drop usage with examples and the external drop workflow.

Sequence Diagram

sequenceDiagram
    participant External as External Drag Source
    participant Item as TreeSortableItem
    participant Hook as useTreeSortable
    participant Container as TreeSortableContainer
    participant Handler as onMoveExternal/onDuplicateExternal

    External->>Item: Drag external item over
    Item->>Hook: Provide dragged item (isExternal=true)
    Hook->>Hook: Check acceptExternalDrop & externalDropType
    alt acceptExternalDrop == true
        Hook->>Hook: Calculate allowed drop positions (inside-only for external)
        Hook->>Item: Update hover state / dropPosition
        External->>Item: Drop
        Item->>Hook: Trigger drop with external item
        Hook->>Container: Emit drop event with item.isExternal
        Container->>Container: Detect external flag
        Container->>Handler: Route to onMoveExternal/onDuplicateExternal
        Handler->>Container: Handle external move/duplicate
    else acceptExternalDrop == false
        Hook->>Item: Reject drop, clear hover
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

Check: RP team

Suggested reviewers

  • AmsterGet
  • allaprischepa
  • maria-hambardzumian
  • siarheirazuvalau

Poem

🐰 From outside the tree I hop and sing,
New items flutter on a gentle wing.
Accept me in folders, let handlers decide,
I’ll nestle inside where tree-branches hide.
Hooray — external drops now join the ride!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'add outside drop for sortable component' accurately reflects the main changes: introducing external drop support for tree sortable components across types, hooks, and UI components.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch EPMRPP-106692-add-outside-drop-for-Sortable-component

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.

@evshipilo evshipilo requested a review from a team February 25, 2026 14:54
@evshipilo
Copy link
Contributor Author

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Feb 25, 2026

@evshipilo I'll perform a full review of all the changes in this PR.

✅ Actions performed

Full review triggered.

Copy link

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

Caution

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

⚠️ Outside diff range comments (1)
src/components/sortable/README.md (1)

129-153: ⚠️ Potential issue | 🟡 Minor

useTreeSortable hook docs are missing the new acceptExternalDrop and externalDropType options.

The "Options" section for useTreeSortable (lines 133–143) doesn't list these two new parameters, even though the hook accepts them and they're documented on TreeSortableItem. Consumers using the hook directly would miss these.

📝 Suggested addition after line 143
 - **hideDefaultPreview**: _boolean_, optional - Hide default preview
+- **acceptExternalDrop**: _boolean_, optional, default = false - Whether this item accepts external drops
+- **externalDropType**: _string_, optional - DnD type for external items (default: `EXTERNAL_TREE_DROP_TYPE`)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/sortable/README.md` around lines 129 - 153, The README's
useTreeSortable options are missing the new acceptExternalDrop and
externalDropType parameters; update the "Options" list in the useTreeSortable
docs to include entries for acceptExternalDrop: _boolean_, optional (whether the
hook accepts drops from external sources) and externalDropType: _string |
string[]_, optional (the DnD type(s) accepted from external drags), mirroring
how these are described on TreeSortableItem so consumers using the hook directly
see the new options.
🧹 Nitpick comments (2)
src/components/sortable/treeSortableContainer/treeSortableContainer.tsx (1)

105-146: Confirmation popover shows "Duplicate" for external items even if onDuplicateExternal is not provided.

When showDropConfirmation is true and an external item is dropped, both "Move" and "Duplicate" buttons are rendered. If only onMoveExternal is supplied, clicking "Duplicate" silently no-ops via optional chaining. This is the same pattern as the internal callbacks, but for external items the "Duplicate" action may be less common and could confuse users.

Consider conditionally hiding the "Duplicate" button when the corresponding handler is absent — but this applies equally to the internal case and is arguably outside the scope of this PR.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/sortable/treeSortableContainer/treeSortableContainer.tsx`
around lines 105 - 146, The confirmation popover currently renders a "Duplicate"
button even when the corresponding handler is not provided, causing a silent
no-op; update the popover rendering logic so the "Duplicate" button is only
shown when a duplicate handler exists for the current drop type (i.e., for
external drops show the button only if onDuplicateExternal is defined, and for
internal drops show it only if onDuplicate is defined), and ensure this matches
the branch logic used in handleAction (DROP_ACTIONS.DUPLICATE) so clicking the
button always invokes a valid handler.
src/common/hooks/useTreeSortable.ts (1)

61-62: Consider whether the OR condition in isExternalDragItem could lead to false positives.

The helper treats an item as external if either isExternal === true or item.type === externalDropType. If a consumer happens to set the internal tree's type prop to the same string as externalDropType, internal items would be misclassified as external and routed to onMoveExternal/onDuplicateExternal.

Since both signals are under developer control and the README clearly instructs setting both type: EXTERNAL_TREE_DROP_TYPE and isExternal: true, this is a low-risk edge case, but the dual-check makes the contract slightly ambiguous. Consider documenting (or asserting at dev time) that the tree's own type must differ from externalDropType.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/common/hooks/useTreeSortable.ts` around lines 61 - 62, The current
isExternalDragItem helper can misclassify internal items because it returns true
when either item.isExternal is true OR item.type === externalDropType; change
isExternalDragItem to require both signals (i.e., treat an item as external only
if item.isExternal === true AND item.type === externalDropType) to avoid false
positives, and add a dev-time warning/assert inside isExternalDragItem when
item.type === externalDropType but item.isExternal !== true to help developers
detect a conflicting tree type configuration.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/components/sortable/README.md`:
- Around line 129-153: The README's useTreeSortable options are missing the new
acceptExternalDrop and externalDropType parameters; update the "Options" list in
the useTreeSortable docs to include entries for acceptExternalDrop: _boolean_,
optional (whether the hook accepts drops from external sources) and
externalDropType: _string | string[]_, optional (the DnD type(s) accepted from
external drags), mirroring how these are described on TreeSortableItem so
consumers using the hook directly see the new options.

---

Nitpick comments:
In `@src/common/hooks/useTreeSortable.ts`:
- Around line 61-62: The current isExternalDragItem helper can misclassify
internal items because it returns true when either item.isExternal is true OR
item.type === externalDropType; change isExternalDragItem to require both
signals (i.e., treat an item as external only if item.isExternal === true AND
item.type === externalDropType) to avoid false positives, and add a dev-time
warning/assert inside isExternalDragItem when item.type === externalDropType but
item.isExternal !== true to help developers detect a conflicting tree type
configuration.

In `@src/components/sortable/treeSortableContainer/treeSortableContainer.tsx`:
- Around line 105-146: The confirmation popover currently renders a "Duplicate"
button even when the corresponding handler is not provided, causing a silent
no-op; update the popover rendering logic so the "Duplicate" button is only
shown when a duplicate handler exists for the current drop type (i.e., for
external drops show the button only if onDuplicateExternal is defined, and for
internal drops show it only if onDuplicate is defined), and ensure this matches
the branch logic used in handleAction (DROP_ACTIONS.DUPLICATE) so clicking the
button always invokes a valid handler.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 722f299 and 17131cb.

📒 Files selected for processing (6)
  • src/common/constants/sortable.ts
  • src/common/hooks/useTreeSortable.ts
  • src/common/types/sortableTypes.ts
  • src/components/sortable/README.md
  • src/components/sortable/treeSortableContainer/treeSortableContainer.tsx
  • src/components/sortable/treeSortableItem/treeSortableItem.tsx

@evshipilo evshipilo changed the title Epmrpp 106692 add outside drop for sortable component EPMRPP-104644 add outside drop for sortable component Feb 25, 2026
Copy link

@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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/common/hooks/useTreeSortable.ts`:
- Around line 61-63: isExternalDragItem currently infers external drags by
checking item.type but the raw item passed into onDrop doesn't get its
isExternal flag set, causing downstream routing that checks
draggedItem.isExternal to misclassify drops; update the code paths that call
onDrop to normalize the item first by setting item.isExternal = true when
isExternalDragItem(item, externalDropType) is true (use the same logic in the
other occurrence around the second block that performs drops), and then call
onDrop with this normalized TreeDragItem so downstream handlers see a consistent
isExternal property.

In `@src/components/sortable/README.md`:
- Around line 60-61: Update the README prop docs to reference the actual
exported constant name used by consumers: change the mention of
EXTERNAL_TREE_DROP to EXTERNAL_TREE_DROP_TYPE in the description for
externalDropType (and keep acceptExternalDrop description unchanged), and note
that this constant is exported from `@common/constants/sortable` so consumers can
import EXTERNAL_TREE_DROP_TYPE when using externalDropType.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 722f299 and e338f14.

📒 Files selected for processing (6)
  • src/common/constants/sortable.ts
  • src/common/hooks/useTreeSortable.ts
  • src/common/types/sortableTypes.ts
  • src/components/sortable/README.md
  • src/components/sortable/treeSortableContainer/treeSortableContainer.tsx
  • src/components/sortable/treeSortableItem/treeSortableItem.tsx

@evshipilo evshipilo merged commit fb83f63 into develop Feb 26, 2026
2 checks passed
@evshipilo evshipilo deleted the EPMRPP-106692-add-outside-drop-for-Sortable-component branch February 26, 2026 13:56
github-actions bot pushed a commit that referenced this pull request Feb 26, 2026
…rop-for-Sortable-component

EPMRPP-104644 add outside drop for sortable component fb83f63
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

EPMRPP-104644 - US: Editor can drag&drop a selected Test Case to the Folder with action choice: Move or Duplicate

2 participants