fix(ui): round-3 polish — container list, bundle upload, toast severity#35380
fix(ui): round-3 polish — container list, bundle upload, toast severity#35380
Conversation
…rity Groups four related UI fixes surfaced during issue 35274 review. Container list (dot-container-list): - Add right-click context menu that reuses the existing row actions. The row now listens to (contextmenu) and shows a <p-contextMenu> attached via viewChild, matching the standard used by the template list portlet. - Hide the per-row 3-dot action button by default and reveal it on row hover via Tailwind group/group-hover utilities. Replaces <dot-action-menu-button> with a <p-button pi-ellipsis-v> that opens the same context menu, giving one source of truth for row actions. - Migrate the @ViewChild('actionsMenu') decorator to the signal-based viewChild<Menu>('actionsMenu') API. Mixing the legacy decorator with the new signal viewChild for the context menu caused @ViewChild to resolve to the wrong component at runtime (ContextMenu instead of Menu), breaking handleActionMenuOpen. - Spec: add a window.matchMedia jsdom polyfill (required once PrimeNG ContextMenu is present) and update action-menu tests to assert against setContainerActions() directly instead of querying the removed <dot-action-menu-button>. Bundle upload dialog (view_publish_tool.jsp): - Replace the raw <input type=\"file\"> with a dojox.form.Uploader widget so the dialog matches the dijit look-and-feel of the rest of the portlet. Adds a localized file-name label that updates on selection. - Work around two dojox.form.Uploader limitations observed in the custom Dojo build: 1. The widget does not forward the 'accept' attribute to its internal <input type=\"file\">, so any file could be picked. applyBundleAcceptFilter() walks the widget's domNode and sets accept=\".tar.gz,.gz,.tgz\" on the actual file input. Rerun on every dialog open because uploader.reset() recreates the input. 2. The widget only fires an onChange event — it does not update any visible element. updateBundleFileNameDisplay() is wired to onChange in dojo.ready() so the label reflects the picked file (or falls back to the localized 'No file chosen' string). - Add spacing and an action-bar margin so the new controls sit cleanly in the dialog. Toast severity (dot-message-display): - PrimeNG Toast expects severity 'warn', but the DotMessageSeverity enum emits 'WARNING'. Map 'warning' → 'warn' before handing it to MessageService.add() so warning toasts pick up the warn style. SCSS class rename (.warning → .warn) keeps the component stylesheet in sync. Container service (dot-containers.service): - Switch copy() from PUT to POST. The backend _copy endpoint is a POST, and the previous PUT returned 405 on the first copy attempt. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Claude finished @hmoreras's task in 2m 34s —— View job PR Review
The core fixes (PUT→POST for 1. display.innerHTML = names.join(", ");
display.textContent = names.join(", ");2. Dead form <form action="/DotAjaxDirector/com.dotcms.publisher.ajax.RemotePublishAjaxAction/cmd/uploadBundle" ...>Upload now goes through 3. Redundant <td style="width: 5%" (contextmenu)="setContextMenu($event, rowData)">The 4. Duplicate setContextMenu(event: Event, container: DotContainer): void {
if (container.disableInteraction) {
event.preventDefault(); // ← duplicated
event.stopPropagation(); // ← duplicated
return;
}
event.preventDefault();
event.stopPropagation();
...
}These two calls are unconditional — move them before the guard to eliminate the duplication. 5. Reviewer raised this in the previous round; it was noted as non-breaking (no 6. The new test at line 132 asserts No issues with:
|
…n keys - Route right-click on actions column through setContextMenu() instead of swallowing the event, so right-clicking anywhere on a row opens the menu - Add event.stopPropagation() to setContextMenu() disabled guard for parity with the active path - Expand doBundleUpload() suffix check to accept .gz and .tgz (matching the accept filter already set on the Uploader widget) - Add missing i18n keys: Choose-File and No-file-chosen in Language.properties Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace p-tag (theme SCSS / p-tag-success) with p-chip using the same Tailwind utility classes (bg-green-100 / text-green-700) already used by dot-contentlet-status-chip. Swap TagModule for ChipModule, drop the tag-padding workaround, and update the spec selector accordingly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…play - migrate @ViewChildren tableRows to viewChildren() signal - split static/conditional [class] binding in container-list template - update spec to use signal array access (tableRows()[0]) instead of QueryList.get() - add template-level test for warn severity icon in dot-message-display - trim JSDoc boilerplate on setContextMenu, keep only the non-obvious why
Summary
Round 3 of UI consistency fixes for the post-Lara-theme portlet polish (part of #35274). Four related areas:
Container list (
dot-container-list)pContextMenuRowwas set on each<tr>but no<p-contextMenu>was attached, so the directive was a no-op. Fixed by wiring a<p-contextMenu>viaviewChildand a(contextmenu)handler that reuses the existingsetContainerActions()entries, matching the pattern already used by the template list.group/group-hover:opacity-100), matching other list portlets.<dot-action-menu-button>replaced with a<p-button pi-ellipsis-v>that opens the same context menu, so right-click and the button share one source of truth.@ViewChild('actionsMenu')regression: once a signal-basedviewChildwas declared for the context menu, the legacy decorator started resolving to the wrong component at runtime (ContextMenuinstead ofMenu), breakinghandleActionMenuOpen. MigratingactionsMenuto the signal API restores correct resolution.window.matchMediajsdom polyfill required by PrimeNGContextMenu, and converted the action-menu DOM assertions to callsetContainerActions()directly.Bundle upload dialog (
view_publish_tool.jsp)<input type="file">with adojox.form.Uploaderwidget so the dialog matches the dijit styling of the surrounding portlet, and added a localized filename label.Uploader:Uploader._createInput()does not forward theacceptattribute to its internal<input type="file">, so any file could be picked.applyBundleAcceptFilter()walks the widget'sdomNodeand setsaccept=".tar.gz,.gz,.tgz"on the real file input. Re-applied on every dialog open becauseuploader.reset()recreates the input.onChangeevent — no visible element is updated — so the label kept reading "No file chosen" even after a pick.updateBundleFileNameDisplay()is wired toonChangeindojo.ready()and reflects the selection.Before

After

Toast severity (
dot-message-display)'warn', butDotMessageSeverityemits'WARNING'. Map'warning' → 'warn'before callingMessageService.add()so warning toasts pick up the warn style. SCSS class renamed (.warning→.warn) to stay in sync.Before
After
Container service (
dot-containers.service)copy()switched fromPUTtoPOST— the backend_copyendpoint is a POST, and the PUT was returning 405.Related
Part of #35274
Test plan
yarn nx test dotcms-ui --testPathPattern=container-list.component.specpasses.tar.gz,.gz,.tgzfilesDotMessageDisplayService.push({ severity: DotMessageSeverity.WARNING, ... })) displays with the warn style rather than the default🤖 Generated with Claude Code