Description
Implement two runonce startup tasks that wire up Angular portlets into the admin menu as part of the migration away from legacy JSP portlets.
Task 1 — Tags portlet menu migration
Ensure the Angular Tags portlet (id tags, route /tags) is present in the admin menu and the legacy Tags portlet (tags-legacy) is removed from all layouts. This was previously implemented in `Task260211AddTagsNewPortletToMenu` and removed from its original PR so it can be delivered in a dedicated PR.
The task should:
- Run when: Any layout still has `tags-legacy`, or no layout has `tags`, or any layout has the old id `tags-new`.
- On run:
- Migrate layout entries from portlet id `tags-new` to `tags` (portlet was renamed).
- Remove `tags-legacy` from all layouts (so it does not appear in the sidebar).
- If `tags` is still not in any layout after migration, add it to the "Content Types" layout (or fallback to a layout that contained `tags-legacy`).
- Clear layout cache (
CacheLocator.getLayoutCache().clearCache()).
Task 2 — Plugins portlet menu addition
Ensure the Angular Plugins portlet (id plugins, route /plugins) appears in the admin menu right after the existing legacy dynamic-plugins JSP portlet (OSGI Manager). Both portlets live in the same menu group.
The task should:
- Run when: The
plugins portlet is not present in any layout.
- On run:
- Find the layout containing
dynamic-plugins.
- Shift all portlets in that layout with
portlet_order ≥ dynamic-plugins.portlet_order + 1 up by 1 to make room.
- Insert
plugins with portlet_order = dynamic-plugins.portlet_order + 1.
- Clear layout cache (
CacheLocator.getLayoutCache().clearCache()).
Acceptance Criteria
Tags task
Plugins task
Both tasks
Priority
Medium
Additional Context
Already done in the companion PR (issue-34732):
portlet.xml — plugins portlet entry added with PortletController class (Angular).
PortletID.java — PLUGINS enum entry added.
app.routes.ts — /plugins route now has canActivate: [MenuGuardService].
portlet.xml already has tags and tags-legacy entries.
Startup task reference: Task260206AddUsagePortletToMenu.java — same pattern for layout lookup, cms_layouts_portlets insert, and cache clear.
Tables: cms_layout, cms_layouts_portlets. Columns: layout_id, portlet_id, portlet_order, id (UUID for new rows).
Insert pattern:
INSERT INTO cms_layouts_portlets(id, layout_id, portlet_id, portlet_order) VALUES (?, ?, ?, ?)
Use UUIDUtil.uuid() for id.
Shift pattern (for Plugins task):
UPDATE cms_layouts_portlets SET portlet_order = portlet_order + 1
WHERE layout_id = ? AND portlet_order >= ?
This work was split out from the PR that adds the Angular portlets (issue-34732) so startup tasks can be reviewed and merged in a dedicated PR.
Description
Implement two runonce startup tasks that wire up Angular portlets into the admin menu as part of the migration away from legacy JSP portlets.
Task 1 — Tags portlet menu migration
Ensure the Angular Tags portlet (id
tags, route/tags) is present in the admin menu and the legacy Tags portlet (tags-legacy) is removed from all layouts. This was previously implemented in `Task260211AddTagsNewPortletToMenu` and removed from its original PR so it can be delivered in a dedicated PR.The task should:
CacheLocator.getLayoutCache().clearCache()).Task 2 — Plugins portlet menu addition
Ensure the Angular Plugins portlet (id
plugins, route/plugins) appears in the admin menu right after the existing legacydynamic-pluginsJSP portlet (OSGI Manager). Both portlets live in the same menu group.The task should:
pluginsportlet is not present in any layout.dynamic-plugins.portlet_order≥dynamic-plugins.portlet_order + 1up by 1 to make room.pluginswithportlet_order = dynamic-plugins.portlet_order + 1.CacheLocator.getLayoutCache().clearCache()).Acceptance Criteria
Tags task
dotCMS/src/main/java/com/dotmarketing/startup/runonce/(e.g.Task260211AddTagsNewPortletToMenu, following current date-based naming).forceRun()returnstruewhen:tags-legacyis in any layout, ortagsis in zero layouts, ortags-newis in any layout.executeUpgrade()migratestags-new→tags, removestags-legacyfrom all layouts, addstagsto "Content Types" layout (or fallback) if missing, then clears layout cache.PortletID.TAGSandPortletID.TAGS_LEGACYfromcom.dotmarketing.util.PortletID.forceRun()catchesException(not justDotDataException) becauseDotConnect.getInt()can throwDotRuntimeException.TaskLocatorUtil.getStartupRunOnceTaskClasses().Plugins task
Task260318AddPluginsPortletToMenu, following current date-based naming).forceRun()returnstruewhenpluginsportlet is absent from all layouts (COUNT = 0); catchesException.executeUpgrade()finds the layout containingdynamic-plugins, shifts subsequent portlets'portlet_orderup by 1, insertspluginsimmediately afterdynamic-plugins, then clears layout cache.dynamic-pluginsis not found in any layout, logs an error and exits gracefully without inserting.PortletID.DYNAMIC_PLUGINSandPortletID.PLUGINSfromcom.dotmarketing.util.PortletID.PLUGINSenum entry must be added toPortletID.java(resolves to"plugins"by default naming convention).TaskLocatorUtil.getStartupRunOnceTaskClasses().Both tasks
Logger; noSystem.out.Task260206AddUsagePortletToMenu.javaas reference).Priority
Medium
Additional Context
Already done in the companion PR (issue-34732):
portlet.xml—pluginsportlet entry added withPortletControllerclass (Angular).PortletID.java—PLUGINSenum entry added.app.routes.ts—/pluginsroute now hascanActivate: [MenuGuardService].portlet.xmlalready hastagsandtags-legacyentries.Startup task reference:
Task260206AddUsagePortletToMenu.java— same pattern for layout lookup,cms_layouts_portletsinsert, and cache clear.Tables:
cms_layout,cms_layouts_portlets. Columns:layout_id,portlet_id,portlet_order,id(UUID for new rows).Insert pattern:
Use
UUIDUtil.uuid()forid.Shift pattern (for Plugins task):
This work was split out from the PR that adds the Angular portlets (issue-34732) so startup tasks can be reviewed and merged in a dedicated PR.