fix(edit-content): normalize string lockedBy shape for Pages in lock warning#35726
fix(edit-content): normalize string lockedBy shape for Pages in lock warning#35726oidacra wants to merge 3 commits into
Conversation
…warning
Pages return `lockedBy` as a userId string (with `lockedByName` for the full
name) while other content types return an object `{ userId, firstName,
lastName }`. The lock warning computed assumed the object shape, so for Pages
it could not detect "locked by current user" and rendered an empty name in the
banner ("Content locked by .").
Normalize both shapes when deriving the locker userId and display name, and
widen the model type to document the dual contract.
Closes #34541
|
Claude finished @oidacra's task in 2m 3s —— View job Review — PR #35726
Verdict: looks clean. Backend dual-shape claim is verified ( Things worth a second look1. Type widening is correct, but I verified no other call site in 2. The TODO at 3. Empty-object 4. Minor: the new logic could be a helper — the resolve-display-name dance (lines 68–74) is the load-bearing piece of Things checked and clean
Acceptance criteria reality checkThe "Manual: lock a Page as user A" rows in the PR test plan are still unchecked. Worth doing before merge — the unit tests prove the normalization logic but not that the banner actually renders the right copy end-to-end (e.g., that |
…d rephrase shape comment Address code-review feedback on PR #35726: - Add missing test for the no-permission branch when `lockedBy` is a string (Page content type) — the analogous object-shape case was already covered. - Rephrase the shape comment so it describes the two API shapes generically instead of attributing the string shape to "Pages", which couples the comment to a backend categorization that could be normalised later.
…navailable PageViewStrategy.getLockedByUserName returns null when loadUserById throws DotSecurityException, which makes an empty `lockedByName` reachable in production. The previous behavior interpolated the empty string into the i18n template, rendering "Content locked by ." — the same regression originally reported in #34541. Apply the fix consistently to both shapes: - Trim the computed display name. - If empty and the user lacks unlock permission, use the existing name-less `edit.content.locked.no.permission` key. - If empty and the user can unlock, suppress the banner (the lock switch UI still indicates the locked state) instead of rendering a misleading message. Update affected tests to assert the intended user-visible behavior rather than the previous edge-case output, and add coverage for the no-permission + no-name path.
Summary
lockedByin two shapes —DefaultTransformStrategyproduces an object{ userId, firstName, lastName }, butPageViewStrategyoverwrites it with the raw userId string plus a separatelockedByName. The frontend lock warning assumed only the object shape.lockWarningMessage(uselockedByNamefor display whenlockedByis a string, compare the string directly tocurrentUser.userId). Widen the model type to document the dual contract.Why frontend-only
Roughly 37 frontend files (UVE, edit-ema, sdk) already treat Page's
lockedByas a string. Normalizing the backend would have a much broader blast radius and is out of scope for this QA fix.Acceptance Criteria
lockedByName)lockedBy(non-Page content types) still worksTest Plan
yarn nx test edit-content --testPathPattern=lock.feature— all tests pass, 3 new tests addedyarn nx lint edit-content— cleanChanged Files
core-web/libs/edit-content/src/lib/store/features/lock/lock.feature.tslockedBycore-web/libs/dotcms-models/src/lib/dot-contentlet.model.tslockedBy?: DotContentletLockUser | string, addlockedByName?: stringcore-web/libs/edit-content/src/lib/store/features/lock/lock.feature.spec.tsCloses #34541