Skip to content

style/feat(ui-fixes): portlet UI standardization and push publish for plugins#35311

Merged
hmoreras merged 12 commits intomainfrom
issue-35274-ui-fixes
Apr 14, 2026
Merged

style/feat(ui-fixes): portlet UI standardization and push publish for plugins#35311
hmoreras merged 12 commits intomainfrom
issue-35274-ui-fixes

Conversation

@hmoreras
Copy link
Copy Markdown
Member

@hmoreras hmoreras commented Apr 14, 2026

Summary

  • feat(dot-plugins): Add push publish action to the plugins portlet context menu. Wires up DotPushPublishEnvironmentsResolver and DotEnterpriseLicenseResolver on the route so the option appears when the instance has an enterprise license and at least one push publish environment configured — matching the pattern used in the locales portlet.
  • style(dot-locales): Standardize the locales portlet UI to match current portlet conventions.
  • style(dot-tags): Remove icons from the Add and Import toolbar buttons in the tags portlet.
  • style(portlets): Standardize dialog widths, toolbar borders, and branding bar background across portlets.
  • feat(plugins,tags): Apply the categories upload dialog error-handling pattern to plugins and tags portlets.
  • fix(ui): Rename .checkbox/.radio wrapper classes to .form-checkbox/.form-radio to avoid DaisyUI collision.

Test plan

  • Verify push publish option appears in the plugins portlet context menu when enterprise license is active and push publish environments are configured.
  • Verify push publish option is hidden when no enterprise license or no environments are present.
  • Verify the push publish dialog opens correctly and allows selecting an environment to publish to.
  • Verify locales portlet UI matches portlet conventions.
  • Verify tags portlet toolbar buttons no longer show icons for Add and Import.
  • Run unit tests: yarn nx test portlets-dot-plugins-portlet

🤖 Generated with Claude Code

This PR fixes: #35274

This PR fixes: #35274

hmoreras and others added 7 commits April 9, 2026 12:02
…o to avoid DaisyUI collision

DaisyUI defines .checkbox for native <input type="checkbox"> elements, applying fixed
width/height and ::before pseudo-elements that collapsed the div wrapper to ~21x21px
and broke label layout. Renaming the wrapper class to .form-checkbox/.form-radio
eliminates the conflict. Also updates items-center alignment as the correct default.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tern

- Show inline p-message notification bar (no margin, rounded-none) at top of dialog on error
- Dialog stays open on error so user can retry without re-opening
- Fixed dialog height via contentStyle so layout is stable
- Tags: replace DotHttpErrorManagerService with inline #extractErrorMessage + $errorMessage signal
- Plugins: move HTTP upload call from store into dialog; store gets setUploadingStatus() for
  the dialog-success path; drag-and-drop path keeps uploadBundles() with global error handler

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ding bar background

- Normalize all form/import dialog widths to 700px across dot-tags, dot-plugins,
  and dot-categories (were 400–600px depending on portlet)
- Add [style]="{ width: '500px' }" to all <p-confirmDialog> elements so delete/
  warning confirmations have a consistent width (PrimeNG Confirmation type does not
  support 'style' via the service call)
- Fix tags import: backend always returns HTTP 200; check response.entity.success
  to show inline error and keep dialog open instead of closing on partial failure
- Replace border-none! with border-x-0! border-t-0! on listing toolbars so only
  the bottom border is visible, matching the design directive
- Set branding bar toolbar background to var(--surface-0) via PrimeNG pt API to
  override the component's own background token
- Remove disabled binding from search inputs in categories and plugins listings so
  the field stays active when the table is empty
- Document dialog sizing standards in libs/portlets/CLAUDE.md
- Update affected specs to assert new 700px widths and the improved import error behavior

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace plain <div> toolbar with <p-toolbar> using border-x-0! border-t-0!
  for bottom-border-only appearance consistent with other portlets
- Fix search input: iconPosition left, standard w-80 width, placeholder and
  aria-label via new locales.search.placeholder i18n key
- Remove icon from Add button
- Replace DotActionMenuButtonComponent with a hover-only p-button
  (opacity-0 group-hover:opacity-100) that opens a p-contextMenu; right-click
  on any row also opens the same context menu
- Add separator before Delete in the context menu
- Remove shell padding so toolbar spans full width like other portlets
- Switch table to [scrollable]="true" scrollHeight="flex", drop dotTable styleClass
- Remove Menu column header text
- Add draggable:false and closeOnEscape:true to the add/edit dialog config
- Standardize dialog widths: form 31rem → 700px, confirmation 38rem → 500px
- Fix p-confirmDialog: add [draggable]="false" and [style]="{ width: '500px' }"
- Change submit button labels: Add mode → save, Edit mode → update
- Add [draggable]="false" to the shared dot-push-publish-dialog component
- Add plugins.search placeholder copy: "Search plugins..."
- Update store and component specs to reflect separator in action list and
  renamed search input test id

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… menu

Wires up DotPushPublishEnvironmentsResolver and DotEnterpriseLicenseResolver
on the route so the push publish option appears in the row context menu when
the instance has an enterprise license and at least one push publish environment
configured, matching the pattern used in the locales portlet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@claude
Copy link
Copy Markdown
Contributor

claude bot commented Apr 14, 2026

Claude finished @hmoreras's task in 4m 12s —— View job


PR Review

  • Gather context
  • Read changed files
  • Analyze for bugs, risks, and design issues
  • Post review findings

Issues

1. #extractErrorMessage duplication is still unaddressed

Reviewer oidacra flagged this at dot-plugins-upload.component.ts:58; there's no author response and the implementation is unchanged. The method body is identical byte-for-byte in both files:

  • core-web/libs/portlets/dot-plugins/src/lib/dot-plugins-upload/dot-plugins-upload.component.ts:78
  • core-web/libs/portlets/dot-tags/src/lib/dot-tags-import/dot-tags-import.component.ts:101

A third portlet needing inline file-error handling will copy it again. Extract it to @dotcms/utils as extractHttpErrorMessage(error: HttpErrorResponse): stringgetDownloadLink is already there as a model. Fix this →


2. viewChild claim about TypeScript access modifiers is incorrect

dot-locales-list.component.ts:64:

private readonly contextMenu = viewChild.required<ContextMenu>('rowMenu');

The author's response that "Angular's compiler requires TypeScript access modifiers (not ES private) for view queries" applied to the old @ViewChild() decorator. Signal-based viewChild() / viewChild.required() in Angular 19 has no such restriction — # works fine. This was also left un-fixed on dot-plugins-list.component.ts:91:

private readonly table = viewChild<Table>('dt');

Both should be readonly #contextMenu and readonly #table to be consistent with the rest of the refactor in this PR.


3. Missing test coverage for openRowMenu in locales

dot-locales-list.component.spec.ts has 4 tests, none of which exercise openRowMenu. The new behaviour being added — push publish menu item visibility, set-as-default guard, delete guard — is all in that method. A right-click that opens the menu with push publish enabled will silently do nothing wrong, but there's nothing catching regressions here.

Minimum coverage needed:

  • Context menu items when isEnterprise: true and environments present (push publish visible)
  • Context menu items when isEnterprise: false (push publish hidden)
  • Set-as-default and delete hidden for the default locale itself

4. DotLocalesListStore services still use private readonly (not #)

dot-locales-list.store.ts:45-48:

private readonly languageService = inject(DotLanguagesService);
private readonly dotMessageService = inject(DotMessageService);
private readonly messageService = inject(MessageService);
private readonly dotHttpErrorManagerService = inject(DotHttpErrorManagerService);

The same # refactor applied to the component was not carried into the store. These are @Injectable() class fields with no decorator constraints — # applies cleanly here too.


5. Route data reads from shell's route, not the list's own route (subtle coupling)

In plugins, resolvers are on the shell route:

// lib.routes.ts
{ path: '', component: DotPluginsShellComponent, resolve: { ... } }  // resolvers here

DotPluginsListComponent is embedded in the shell template (not a routed component), so it inherits the shell's ActivatedRoute. This works today, but it's an implicit coupling that differs from the locales pattern (where resolvers are on the list's own child route). If DotPluginsListComponent is ever lifted into a standalone route without the shell, this.#route.snapshot.data would silently be empty, and pushPublishEnvironments.length > 0 would throw. The inconsistency between the two portlets is worth documenting in the route file, or aligning on the locales pattern.


Verified clean

  • jarFile as push-publish assetIdentifier is correct — OSGIBundler.java:83 reads element.getAsset() as the jar filename
  • viewChild.required for contextMenu is correct — the <p-contextMenu #rowMenu> is outside the @if (vm$ | async) block and is always in the DOM
  • defaultLocale guard fix (!locale.defaultLanguage && defaultLocale) is correct

@github-actions github-actions bot added Area : Backend PR changes Java/Maven backend code Area : Frontend PR changes Angular/TypeScript frontend code labels Apr 14, 2026
hmoreras and others added 3 commits April 14, 2026 09:46
- Fix aria-label on locales row menu button: replace incorrect
  'categories.actions' key with the scoped 'locales.menu' key
  which already exists in Language.properties (= "Menu")
- Fix 'as never' type assertions in plugins spec: replace with
  'as DotEnvironment[]' for proper type safety

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rename $uploading/$errorMessage signals to drop the $ prefix in
  dot-plugins-upload and dot-tags-import (signals, not observables)
- Fix static accept attribute binding in dot-plugins-upload template
- Replace hardcoded items[5] index with .find() in plugins list spec
- Refactor DotLocalesListStore to remove DialogService and
  DotPushPublishDialogService injections; move all dialog-opening
  logic to DotLocalesListComponent per CLAUDE.md separation of concerns
- Drop stale icon assertion from dot-tags-list spec after toolbar icon
  removal in a prior commit
- dot-login.component.spec: fix checkbox selector from '.checkbox'
  to '.form-checkbox' to match the renamed template class
- dot-add-to-menu.component.spec: fix radio container selector from
  '.radio label[for=...]' to '.form-radio label[for=...]'
- dot-edit-contentlet.component.spec: mock DotcmsConfigService to
  prevent its constructor HTTP call to /api/v1/appconfiguration from
  bleeding into test assertions
- Use # prefix for private inject/signal fields (viewChild stays private readonly per Angular constraint)
- Guard defaultLocale before pushing set-default/delete menu items
- Add explicit type annotations for route.snapshot.data in dot-plugins-list
- Update spec to inject DotMessageDisplayService via debugElement.injector
@hmoreras hmoreras enabled auto-merge April 14, 2026 20:52
@hmoreras hmoreras removed request for nicobytes and zJaaal April 14, 2026 20:57
@hmoreras hmoreras requested review from adrianjm-dotCMS, dario-daza, nicobytes, rjvelazco and zJaaal and removed request for rjvelazco April 14, 2026 20:57
@hmoreras hmoreras added this pull request to the merge queue Apr 14, 2026
Merged via the queue into main with commit 910fb3e Apr 14, 2026
62 checks passed
@hmoreras hmoreras deleted the issue-35274-ui-fixes branch April 14, 2026 22:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI: Safe To Rollback Area : Backend PR changes Java/Maven backend code Area : Frontend PR changes Angular/TypeScript frontend code

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

fix(portlets): UI consistency polish — Categories, Plugins, Tags & Lara theme post-migration

4 participants