fix(edit-content): keep lock toggle out of FormGroup so locked content opens pristine#35772
fix(edit-content): keep lock toggle out of FormGroup so locked content opens pristine#35772oidacra wants to merge 1 commit into
Conversation
…t opens pristine The lock <p-toggleSwitch [ngModel]="isContentLocked"> is defined in the #appendContent ng-template, which dotTabViewInsert injects inside the <form [formGroup]="form"> in the new Edit Content experience. Without ngModelOptions.standalone, Angular registers the ngModel as an implicit control on the reactive FormGroup. When the async lock-status check resolves after #scheduleMarkPristineAfterInit has already called markAsPristine(), the signal update writes through the toggle CVA and dirties the form — triggering the "You have unsaved changes" dialog on navigation even though the user never edited anything. Mark the toggle as standalone so it lives outside the reactive form, preserving the existing one-way [ngModel] binding and (onChange) handler. Add four fakeAsync unit tests in dot-edit-content-form.component.spec.ts: - locked content opens pristine (and stays pristine after tick(500)) - lock toggle onChange does not dirty the form (regression guard) - editing a real field still dirties the form - locked -> unlocked -> edited path still dirties the form Closes #35754
|
Claude finished @oidacra's task in 1m 55s —— View job Review —
|
Summary
Fixes a UX bug where opening a locked content item in the new Edit Content experience marked the form as
dirtywithout any user interaction, triggering a spurious "You have unsaved changes" dialog when navigating away.Root cause. The lock
<p-toggleSwitch [ngModel]="isContentLocked">lives in<ng-template #appendContent>, whichdotTabViewInsertinjects into the DOM inside<form [formGroup]="form">. Without[ngModelOptions]="{ standalone: true }", Angular registers the template-drivenngModelas an implicit control on the reactiveFormGroup.isContentLockedis a store signal that resolves asynchronously — when it writes through[ngModel]after#scheduleMarkPristineAfterInitalready fired, the toggle's CVAonChangere-dirties the form. No subsequent pristine reset happens.Fix. One-line template change: add
[ngModelOptions]="{ standalone: true }"to the lock toggle so it is excluded from the reactive form. The one-way[ngModel]binding and the(onChange)="onContentLockChange($event)"handler are unchanged — the toggle's visual state and lock/unlock service calls still work exactly as before.Closes #35754
Acceptance Criteria
FormGroup.dirty === false,pristine === true).FormGroup.dirtyremainsfalse.form.dirty; AC1/AC2 proveform.dirty === false.)component.form.dirty === false.component.form.dirty === true.Test plan
yarn nx lint edit-content— 0 errors (9 pre-existing warnings unrelated to this change)yarn nx test edit-content --testPathPattern=dot-edit-content-form.component.spec— 1863 passed, 0 failuresyarn nx build dotcms-ui— succeeds (template compilation green)Changed files
core-web/libs/edit-content/src/lib/components/dot-edit-content-form/dot-edit-content-form.component.html— add[ngModelOptions]="{ standalone: true }"on the lockp-toggleSwitch(1 line).core-web/libs/edit-content/src/lib/components/dot-edit-content-form/dot-edit-content-form.component.spec.ts— add 4fakeAsynctests in a newdescribe('Form dirty state after lock toggle')block.Visual Changes
No visual changes — the lock toggle still renders and behaves identically. The fix changes how Angular registers the toggle internally, not what the user sees. Manual QA above is the relevant verification.