Skip to content

Template Builder: removing a row reorders columns / duplicates rows in the templates portlet #35697

@zJaaal

Description

@zJaaal

Problem Statement

In the templates portlet (/templates/edit/...), removing a row from a multi-row layout causes columns within other rows to reorder (boxes "pushed up" to the left) and, in some scenarios, rows to appear duplicated. The bug does not affect the EMA layout editor — only the standalone templates portlet.

This regressed when @for row tracking in template-builder.component.html switched from identify(row) (id+index) to row.id directly (commit ab89c85, PR #35277). Previously the index-shift on deletion forced Angular to destroy/recreate every subsequent row, which incidentally reset GridStack state and masked a latent state-corruption bug in updateOldRows.

Root cause (technical)

The templates portlet wrapper (dot-template-builder.component.ts) called updateTemplate.emit(item) synchronously on every templateChange. That propagates through the parent store's working signal and echoes back into the designer's [layout] input → ngOnChangesupdateOldRows. After removeRow, state has gaps in y (e.g. [0, 2]) while the parsed newRows from the echoed body has sequential y ([0, 1]). updateOldRows matched by y and silently produced rows with children: undefined and missing x/y/w/h, manifesting as the visual corruption.

EMA does not have this problem because its layout signal only updates after a successful save (pageReload), so there is no synchronous echo.

Steps to Reproduce

Video screencast:

Screen.Recording.2026-05-13.at.5.15.00.PM.mov
  1. Open a template via /templates/edit/<identifier> (design type).
  2. Add ≥ 3 rows with multiple columns each, including columns at non-zero x positions (e.g. a box at x=6).
  3. Delete a row from the middle of the layout.
  4. Observe: columns within other rows visually shift / reorder, or a row appears duplicated.

Acceptance Criteria

  • Deleting a row in the templates portlet removes only that row.
  • Columns in other rows retain their positions.
  • No duplicated rows in the DOM after deletion.
  • Auto-save still fires after the 5s debounce window.
  • Page-leave guard still prompts when there are unsaved changes.
  • EMA layout editor behavior unchanged.
  • Regression test in place to prevent re-introduction.

dotCMS Version

main (current).

Severity

Medium - Some functionality impacted

Links

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Status

    QA

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions