Skip to content

Allow element to change its parent or model or both#9303

Open
khanaffan wants to merge 9 commits into
masterfrom
affank/move-el
Open

Allow element to change its parent or model or both#9303
khanaffan wants to merge 9 commits into
masterfrom
affank/move-el

Conversation

@khanaffan

@khanaffan khanaffan commented May 14, 2026

Copy link
Copy Markdown
Contributor

imodel-native: iTwin/imodel-native#1428

Add changeElementParent and changeElementModel methods to @itwin/core-backend

Adds new @beta APIs for moving elements between models and/or parents without deleting and re-inserting them. The native implementation automatically handles moving element subtrees (assemblies) — all descendants are moved along with the parent element.

Changes

  • EditTxn.changeElementParent — changes the parent of an element. If the new parent is in a different model, the element's model changes as well. When called on an element with children, all descendants are automatically moved as well (handled by the native implementation). Enforces model type matching, channel verification, and lock checks.
  • EditTxn.changeElementModel — changes the model of an element, making it a root element (no parent) in the new model. When called on an element with children, all descendants are automatically moved as well (handled by the native implementation). Enforces model type matching, channel verification, and lock checks.
  • IModelDb.Elements.changeElementParent — deprecated convenience wrapper that delegates to the implicit transaction. Use EditTxn.changeElementParent instead within an explicit EditTxn scope.
  • IModelDb.Elements.changeElementModel — deprecated convenience wrapper that delegates to the implicit transaction. Use EditTxn.changeElementModel instead within an explicit EditTxn scope.
  • ChangeElementParentProps / ChangeElementModelProps — interfaces specifying move parameters (element id, target parent/model).
  • ElementError — new error namespace in ITwinCoreErrors.ts (@itwin/core-common) for element operation errors (e.g. model type mismatch).

Code scope restrictions

Blocked scopes (will throw):

  • Model-scoped code — code uniqueness is tied to the source model; moving across models would break uniqueness guarantees.
  • ParentElement-scoped code — code scope is invalidated by reparenting; the scope reference becomes stale.

Allowed scopes (move proceeds):

  • Repository-scoped code — unique across the entire iModel, unaffected by model or parent changes.
  • RelatedElement-scoped code — scope element is independent of the parent/model hierarchy.
  • Empty codes — no scope to conflict.

For elements with blocked code scopes, use delete+insert instead of move.

Validation

  • Targeted verification: Added comprehensive unit tests (ChangeElementParentModel.test.ts) covering single-element moves, subtree moves (assemblies), model type mismatch, circular dependency rejection, self-parenting rejection, blocked code scopes (Model-scoped, ParentElement-scoped), allowed code scopes (Repository-scoped, RelatedElement-scoped, empty), and channel verification.
  • Known baseline issues: None.

@khanaffan khanaffan changed the title Affank/move el Add support for move element May 14, 2026
@khanaffan khanaffan marked this pull request as ready for review May 15, 2026 15:07
@khanaffan khanaffan requested review from a team as code owners May 15, 2026 15:07
@aruniverse aruniverse requested a review from Copilot May 15, 2026 15:09

This comment was marked as outdated.

@kabentley

Copy link
Copy Markdown
Collaborator

Didn't we already deal with this in a past PR? I distinctly remember telling whomever was working on it then to NOT call this "move" - that is the term we use for geometric location. It will confuse everyone!

At the time, i remember discussing why "move tree" is a bad idea. What brings this up again?

@aruniverse

Copy link
Copy Markdown
Member

Didn't we already deal with this in a past PR?

#8833

@khanaffan khanaffan requested a review from RohitPtnkr1996 as a code owner May 21, 2026 20:18
@khanaffan khanaffan changed the title Add support for move element Allow element to change its parent or model or both May 21, 2026
Comment thread core/backend/src/IModelDb.ts Outdated
Comment thread core/backend/src/IModelDb.ts Outdated
@mergify

mergify Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

This pull request is now in conflicts. Could you fix it @khanaffan? 🙏
To fixup this pull request, you can check out it locally. See documentation: https://help.github.com/articles/checking-out-pull-requests-locally/

@khanaffan

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts in this pull request

Copilot AI commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Merge conflicts resolved in commit eee59c2. The two conflicts were:

  1. core/backend/src/IModelDb.ts — combined the _verifyChannel import from our branch with the SchemaView import added in master.
  2. docs/changehistory/NextVersion.md — merged both branches' content, preserving our @itwin/core-backend section alongside master's new @itwin/map-layers-formats (Azure Maps) section.

Comment thread core/backend/src/IModelDb.ts Fixed
Comment thread core/backend/src/test/standalone/ElementUpdateHandler.test.ts Fixed
@mergify

mergify Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

This pull request is now in conflicts. Could you fix it @khanaffan? 🙏
To fixup this pull request, you can check out it locally. See documentation: https://help.github.com/articles/checking-out-pull-requests-locally/

Comment thread core/backend/src/EditTxn.ts Outdated
Comment thread core/backend/src/IModelDb.ts Outdated
@khanaffan

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts in this pull request

Copilot AI commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. The only conflict was in docs/changehistory/NextVersion.md — the table of contents now includes both our @itwin/core-backend section and master's new @itwin/core-frontend entries (high-coord precision, graceful query reader close, Bing Maps deprecation).

@khanaffan khanaffan requested a review from a team as a code owner June 12, 2026 17:27
Comment thread core/common/src/ITwinCoreErrors.ts
@mergify

mergify Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

This pull request is now in conflicts. Could you fix it @khanaffan? 🙏
To fixup this pull request, you can check out it locally. See documentation: https://help.github.com/articles/checking-out-pull-requests-locally/

Add @beta EditTxn.changeElementParent and EditTxn.changeElementModel to move
an element to a different parent or model without deleting and re-inserting it.
Only the target element is moved; its children are unaffected. Reparenting is
restricted to within the same model, and changeElementModel requires a root
element whose target model is of the same class. Add the @beta ElementError
namespace in core-common for reporting element-operation failures.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@rschili rschili left a comment

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.

Pr description is stale, plus I'm re-reviewing this, withdrawing my earlier approve until I'm finished, a lot has changed.

Comment thread core/backend/src/test/standalone/ChangeElementParentModel.test.ts
- Updated comments and documentation to clarify that moving an element's model relocates its entire subtree, preserving the parent-child hierarchy.
- Improved validation logic to ensure that any descendant with a Model-scoped code blocks the move, maintaining atomicity.
- Added tests to verify the behavior of subtree moves and cache invalidation for affected elements.
@mergify

mergify Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

This pull request is now in conflicts. Could you fix it @khanaffan? 🙏
To fixup this pull request, you can check out it locally. See documentation: https://help.github.com/articles/checking-out-pull-requests-locally/

Comment thread core/backend/src/EditTxn.ts Outdated
khanaffan and others added 2 commits June 29, 2026 11:38
changeElementModel moved an element's subtree between two models but only
invalidated the element caches, leaving stale source/target ModelProps in
models[_cache] (e.g. model geometry-derived state). Element insert/update/
delete invalidate models[_cache] via Element.onInserted/onUpdated/onDeleted,
but the native changeElementModel does not fire those element callbacks, so
the wrapper must evict both affected models itself.

Adds a regression test verifying both the source and target model cache
entries are invalidated after the move.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread core/backend/src/IModelDb.ts Outdated
Comment thread core/backend/src/IModelDb.ts Outdated
Comment thread core/backend/src/IModelDb.ts Outdated
Comment thread core/backend/src/IModelDb.ts Outdated
Comment thread core/common/src/ITwinCoreErrors.ts Outdated
- Remove redundant blocked/allowed-cases docs from ChangeElementParentProps
  and ChangeElementModelProps; point to the authoritative EditTxn method docs.
- Remove unused _verifyChannel import from IModelDb.ts.
- Fix deprecated IModelDb.Elements.changeElementParent/changeElementModel
  forwarders: @throws ITwinError (not IModelError) and @deprecated in 5.11.0
  (these methods are new in this release, not 5.9.0).
- Document ElementError.scope and ElementError.Key, and rename the scope from
  "itwin-element" to "itwin-Element" to match the title-case convention used by
  other recent ITwinError scopes (itwin-EditTxn, itwin-ServerBasedLocks, ...).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@aruniverse aruniverse added this to the iTwin.js 5.11 milestone Jun 29, 2026
khanaffan and others added 2 commits June 29, 2026 14:42
Update backend docs and changelog wording so changeElementModel is described
as a root-element/subtree move, not a replacement for cross-model reparenting
of parented elements. The changelog example now uses separate child/root ids
and narrows ElementError wording to the explicit validation cases.

Because the native model move updates the whole subtree in bulk, the EditTxn
wrapper now verifies exclusive locks for every element in the moved subtree
before invoking native.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add targeted tests for:
- rejecting self-parenting before it can write a corrupt parent id,
- requiring exclusive locks for every element in a subtree model move,
- updating source and target geometric model geometryGuids when moving a
  geometric element between models.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

8 participants