Skip to content

Unify folder p-tree into a shared @dotcms/ui component #36733

Description

@nicobytes

Description

Today the admin UI has three separate PrimeNG p-tree implementations for site/folder browsing. They look and behave differently (selection mode, load-more convention, toggler icons, label pipes) and do not reuse each other:

Location Component Role
core-web/libs/portlets/dot-content-drive/ui/src/lib/dot-tree-folder/ DotTreeFolderComponent Presentational tree + drag-and-drop (Content Drive)
core-web/libs/edit-content/src/lib/fields/dot-edit-content-host-folder-field/components/host-folder-field/ DotHostFolderFieldComponent Inline p-tree inside Host Folder Field overlay
core-web/libs/ui/src/lib/components/dot-browser-selector/components/dot-sidebar/ DotSideBarComponent Presentational tree inside Browser Selector (not exported on its own)

Already shared: DotBrowsingService, path-label pipes (FolderNamePipe / DotTruncatePathPipe — near-duplicates), and TreeNodeItem models in @dotcms/dotcms-models.

Not shared: the p-tree shell (default / load-more / toggler templates, selection modes, styling). Content Drive has the richest presentational API; Host Folder Field embeds its own tree; Browser Selector sidebar is the thinnest variant.

Proposal

Extract a presentational folder tree component (e.g. DotFolderTreeComponent) into @dotcms/ui (core-web/libs/ui), export it from libs/ui/src/index.ts, and reuse it in:

  1. Content Drive (dot-tree-folder consumer)
  2. Edit Content Host Folder Field
  3. Browser Selector sidebar (dot-sidebar)

Prefer evolving from DotTreeFolderComponent’s public API (folders, loading, selection, expand/collapse, load-more, toggler modes), with content projection or inputs for node label formatting.

Keep consumer-owned (out of the shared leaf):

  • Host Folder Field: overlay chrome, sites scroller, search, pending/commit CVA, copy path
  • Content Drive: drag/drop upload/move, “All folders” synthetic root, site header chrome, pulse empty state
  • Data fetching / stores (prefer DotBrowsingService where already used; Content Drive may keep its store wiring)

Also consolidate where practical:

  • Unify load-more node convention (one of: PrimeNG type + typed template, or data.type)
  • Align path-label pipes (FolderNamePipe / DotTruncatePathPipe)
  • Extend shared tree node models for load-more instead of portlet-only types

Acceptance Criteria

  • A presentational folder tree component lives under core-web/libs/ui and is exported from @dotcms/ui
  • The shared component owns the p-tree shell: value, selection (single and multi where needed), loading, expand/collapse outputs, load-more handling, and toggler modes (chevron vs folder icons)
  • Content Drive sidebar uses the shared @dotcms/ui tree; Content Drive–specific drag/drop and “All folders” behavior remain in the Content Drive consumer
  • Host Folder Field uses the shared @dotcms/ui tree for its folder panel; overlay, sites list, search, and form CVA remain in edit-content
  • Browser Selector sidebar uses the same shared tree (replacing or wrapping the current DotSideBarComponent tree)
  • Observable folder-tree behavior is preserved in all three consumers: lazy expand, node selection, and load-more still work as before
  • Existing unit tests for the three consumers are updated/passing; the shared component has Spectator/Jest coverage for selection, expand, load-more, and toggler modes
  • No duplicate inline p-tree folder shell remains in the three adoption sites after migration

Priority

Medium

Additional Context

Suggested adoption order: promote Content Drive’s presentational tree into @dotcms/ui → replace Browser Selector sidebar → wrap Host Folder Field’s right-hand tree while leaving its overlay/store in edit-content.

Related services/pipes already in @dotcms/ui: DotBrowsingService, FolderNamePipe, DotTruncatePathPipe.

Metadata

Metadata

Assignees

Type

Projects

Status
Current Sprint Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions