feat(edit-content): restructure command bar & side panel around Actions tab (#35892)#36021
feat(edit-content): restructure command bar & side panel around Actions tab (#35892)#36021oidacra wants to merge 28 commits into
Conversation
…ns tab (#35892) Command bar (dot-edit-content-form): - Slim to [status tag] | Preview ... (overflow menu) [sidebar toggle], sticky on scroll. - Status rendered as a local p-tag; lock toggle and inline workflow actions removed. - New dot-edit-content-command-bar-actions overflow menu (Permissions, Rules for pages, View references) that owns the relocated dialog logic. - Preview now supports HTML pages via generatePageEditUrl and URL-mapped content. Side panel (dot-edit-content-sidebar): - Info tab becomes Actions (bolt icon); Settings tab removed. - Lock control relocated as a distinct outlined button with a lock icon, separated from the workflow actions by a divider. - Workflow actions render stacked full-width (new `stacked` mode on dot-workflow-actions), one above another, first action primary; firing stays in the form via layout wiring (workflowActionFired output -> DotEditContentLayoutComponent.onWorkflowActionFired). - Sections (Locales, Workflow, Details) are independently collapsible and persist their state via DotLocalstorageService; headers restyled to the design's uppercase treatment. - Information card drops the status chip and References card (moved to the command bar). Removed the now-orphaned sidebar permissions/rules wrapper components.
|
Claude finished @oidacra's task in 3m 43s —— View job Code Review
Findings1.
2. Stale In 3.
params.set('url', `${contentlet.url}?host_id=${contentlet.host}`);If 4.
lockedBy ? ` (${escapeHtml(lockedBy)})` : ''
5. Hardcoded
<p-tab [value]="0" [pTooltip]="'Actions' | dm" tooltipPosition="bottom">The string 6. Lock button inline styles are a workaround for a PrimeNG directive limitation
[class.p-button-outlined]="$store.isContentLocked()"
[style.border-color]="$store.isContentLocked() ? null : 'var(--p-surface-200)'"This is correctly called out in the comment above it — the 7.
8.
9.
10. Missing i18n key for the new "View References" command-bar action label (minor)
Overall: The restructuring is well-reasoned and the code is clean. Issues #3 (double |
Override the Tag `success` color scheme in CustomLaraPreset so it uses a tinted
background with dark text ({green.100}/{green.700}) instead of Lara's default solid
fill + white text. Applies globally to every p-tag success, including the Edit
Content command-bar status; the primitives map 1:1 to the Claude Design green tones.
… fluid buttons (#35892) - Make the status p-tag a fully-rounded pill globally via CustomLaraPreset (tag.root: 9999px radius, 4px 12px padding, 600 weight) instead of a per-instance class, so a forgotten class can never make a tag look different. - Replace the statusSeverity template method with memoized computeds ($contentStatus via DotContentletStatusPipe + $statusSeverity), backed by a pure exported contentStatusSeverity() so the mapping stays unit-testable. Avoids the per-CD method call. - Use the native PrimeNG [fluid] input for full-width stacked workflow actions and the lock button instead of styleClass (class does not reach p-button's inner element).
…35892) Move the tag's hardcoded shape/typography values into a css block driven by Tailwind variables — same mechanism as the chip preset — instead of magic numbers: padding uses var(--spacing), font-weight uses var(--font-weight-semibold), and the full pill radius uses calc(infinity * 1px) (what Tailwind's rounded-full emits; there is no --radius-full).
…with the design (#35892) - Invert sidebar backgrounds to match the design: the panel is now white and the Workflow/Details sections sit in surface-50 cards (was a gray panel with white cards). - Sidebar width 360px (was 21.875rem ≈ 306px at the 14px root) and the left drop shadow is removed — only the thin border remains, per the design. - Accordion headers: chevron moved to the right, points up when expanded, and gains a surface-50 hover background. - Rename the "General" section to "Details" (new edit.content.sidebar.details.title key). - Details card redesigned to the design spec: a single surface-50 card with a key/value grid (Content type link, Modified by + initials avatar, Modified) and a footer holding the Copy Identifier button and a "View as JSON" link. The copy button moved out of the section header; Created/Published columns were dropped to match the design. - Tabs use an underline indicator (active border on the bottom, not the top) with no static tab background, via the global Tabs preset.
…er accordion titles (#35892) - Lock button, Actions tab tooltip and the Details section title now reuse existing, already-translated message keys (Unlock / Make-Editable, Actions, details) via the dm pipe instead of brand-new keys. New keys only resolve after a backend rebuild, so they rendered as raw uppercase keys in a running instance; the existing keys translate immediately. Removed the now-unused new keys. - The lock wording is action-based: "Lock for Editing" when unlocked, "Unlock" when locked. - Vertically center the collapsible section titles: the section had asymmetric padding (pt-0 pb-3) which pushed the header toward the top divider; it is now symmetric (py-3), and the title uses leading-none so the uppercase text sits on the true vertical center.
…o the hover no longer merges with the card (#35892)
Drop the font-size override on the top-bar messages. It was converted assuming a 16px root (0.84375rem) but the app root is 14px, so it rendered at 11.8px — too small. The fixed 54px height already handles alignment, so the text keeps its default 14px scale.
Set the top-bar message font to 13.5px (in px, since the app root is 14px and a rem value would not land on 13.5) and align the icon-to-text gap across all top-bar messages to gap-3 (12px) so the info and lock banners match. Previously the info banner used gap-1 (4px) while the lock banner used gap-3.
…35892) Mirror the sidebar tabs: give the form tablist a defined height and make the tabs and tab-list fill it (min-h-[53px], [&_.p-tab]:h-full, [&_.p-tablist-tab-list]:h-full). The active-tab underline now sits flush on the bottom border instead of floating ~3px above it, matching the sidebar tabs.
Resolve the actionable findings from the automated PR review: - Dialogs: set closeOnEscape: true on the permissions and rules dialogs (CLAUDE.md requires all dialogs to be ESC-closable); update the matching spec expectation. - Permissions dialog: drop the invalid transitionOptions: null option. - form: convert the $appendContext getter to a computed so its object reference is memoized instead of recreated on every change-detection cycle. - Move isPage into the store as a single computed; the form now reads $store.isPage and the sidebar's duplicate (unused) computed is removed. - references dialog: drop the dead error handler on the onClose subscription (the Subject never errors) — match the other two dialogs. - Document the intentional reset-workflow validation bypass in the sidebar with a TODO.
…user (#35892) When content is locked by a different user and the current user can release it, the sidebar lock button now reads "Release Lock" and asks for confirmation before stealing the lock — instead of releasing it silently. - store/lock: add isLockedByAnotherUser and lockedByName computeds. - sidebar lock button: label is "Release Lock" (locked by another), "Unlock" (own lock) or "Lock for Editing" (unlocked); the click is routed through onLockAction(). - onLockAction opens a confirmation dialog (existing p-confirmDialog/ConfirmationService) before releasing another user's lock; own-lock unlock and locking act directly. - i18n: add edit.content.release.lock.confirmation.header/message.
…log (#35892) - Constrain the shared confirm dialog to 32rem so the long release-lock message wraps instead of stretching across the viewport. - Make "Release Lock" the primary action and "Cancel" an outlined/secondary button.
…35892) Map the "New" status to the `secondary` severity instead of `warn`, so a brand-new unsaved contentlet shows a soft gray pill (Lara secondary = surface.100/surface.600) rather than a warning-orange one. Reads as informational and matches the soft-pill style of the other statuses without colliding with Revision (info/blue).
- showPreview(): early-return when the contentlet is null so a concurrent state change between render and click can't trigger a null dereference in the URL generators. - lock button: pass `undefined` (not `null`) to the PrimeNG `severity` input. - sidebar: rename fireWorkflowAction → fireResetWorkflowAction and tighten its doc so the validation-bypassing direct-fire path is clearly reset-only (other actions go through the workflowActionFired output). - test: add a coupling test asserting every DotContentletStatusPipe output maps to its intended status-chip severity, so a future pipe label change fails loudly.
…review (#35892) - Escape the API-provided locker name before it is interpolated into the [innerHTML] banner and the release-lock confirm message (new escapeHtml util). Also drop the redundant <b> wrap — the i18n keys already bold {0}, so the name was double-bolded. - Extract the duplicated lockedBy-resolution into a single resolveLocker() util (shared by lockWarningMessage, lockedByName and isLockedByAnotherUser). - command-bar: guard openReferencesDialog() with !hasReferences() so a direct call can't open an empty dialog. - layout: guard onWorkflowActionFired() against an undefined inode before firing. - dot-workflow-actions: getVariant() returns undefined (not null) for cleaner typing. - Document the section linkedSignal's non-reactive localStorage dependency and the stacked-mode SEPARATOR drop. - Tests for escapeHtml and resolveLocker; specs updated for the above.
Proposed Changes
Restructures the new Edit Contentlet command bar and side panel around a single Actions tab (#35892).
Command bar (
dot-edit-content-form)[status tag] | Preview … (overflow menu) ▢ (sidebar toggle)and made sticky on scroll.p-tag; the lock toggle and inline workflow actions were removed from the bar.dot-edit-content-command-bar-actionsoverflow (…) menu — Permissions, Rules (pages only), View references — which owns the dialog-open logic relocated from the deleted sidebar wrappers.generatePageEditUrlhelper in addition to URL-mapped content.Side panel (
dot-edit-content-sidebar)stackedmode on the shareddot-workflow-actions), first action primary. Firing stays in the form — the sidebar emitsworkflowActionFiredand the layout delegates toDotEditContentFormComponent.fireWorkflowActionvia itsviewChild, so all validation/wizard/push-publish logic is untouched.DotLocalstorageService; headers use the design's uppercase treatment.Removed the now-orphaned
dot-edit-content-sidebar-permissions/dot-edit-content-sidebar-ruleswrapper components (their dialogs are reused by the new overflow menu).Out of scope (by design): Locales content is untouched (tracked in #35889) — only its section becomes collapsible. The lock control is relocated only; the richer "Release Lock"/steal-lock flow is deferred. Workflow/Details card visual restyle was intentionally left for a later pass.
Checklist
yarn nx lint edit-content/yarn nx lint ui— pass (pre-existing warnings only)yarn nx test edit-content/yarn nx test ui— passyarn nx build dotcms-ui(AOT template type-check) — passyarn nx format:writeHow to test
[status tag] | Preview … ▢, sticks on scroll; no lock toggle / inline workflow actions.…menu opens Permissions, Rules (pages only) and View references; Settings tab is gone.…menu hidden.