Skip to content

feat(content-drive): #33753 implement virtual scroll with lazy loading for content type filter - #34823

Merged
zJaaal merged 283 commits into
mainfrom
33753-task-content-drive-implement-virtual-scroll-for-content-type-filter
Mar 2, 2026
Merged

zJaaal merged 283 commits into
mainfrom
33753-task-content-drive-implement-virtual-scroll-for-content-type-filter

Conversation

@zJaaal

@zJaaal zJaaal commented Mar 2, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Implement virtual scroll on the p-multiselect content type filter in Content Drive, enabling users to browse all content types without requiring search
  • Add lazy loading / pagination (onLazyLoad) to the DotContentDriveContentTypeFieldComponent so content types are fetched page-by-page as the user scrolls rather than all at once
  • Replace the static scrollHeight binding with PrimeNG's built-in [virtualScroll]="true" and [virtualScrollItemSize]="38.5" for performant rendering of large datasets
  • Add defineCustomElements() call in main.ts to ensure dotCMS web components are registered on bootstrap

Files changed:

  • core-web/libs/portlets/dot-content-drive/portlet/src/lib/components/dot-content-drive-toolbar/components/dot-content-drive-content-type-field/dot-content-drive-content-type-field.component.html — enable lazy, virtualScroll, virtualScrollItemSize, wire onLazyLoad event
  • core-web/libs/portlets/dot-content-drive/portlet/src/lib/components/dot-content-drive-toolbar/components/dot-content-drive-content-type-field/dot-content-drive-content-type-field.component.ts — add onLazyLoad() handler with page-based pagination logic using signalState
  • core-web/libs/portlets/dot-content-drive/portlet/src/lib/components/dot-content-drive-toolbar/components/dot-content-drive-content-type-field/dot-content-drive-content-type-field.component.spec.ts — updated tests covering lazy load behavior
  • core-web/apps/dotcms-ui/src/main.ts — add defineCustomElements() from @dotcms/dotcms-webcomponents/loader

Test plan

  • Open Content Drive and click the Content Type filter dropdown — content types should load without requiring a search term
  • Scroll to the bottom of the content type list — additional pages should load incrementally (infinite scroll behavior)
  • Type in the filter input — results reset and filter correctly with debounce
  • Select content types, hide the panel, and reopen — selections persist, filter resets
  • Change the Base Type filter — selected content types not matching the new base type are cleared
  • Verify no duplicate content type entries appear when scrolling
  • Run unit tests: yarn nx test portlets-dot-content-drive-portlet

🤖 Generated with Claude Code

This PR fixes: #33753

This PR fixes: #33753

fmontes and others added 30 commits December 12, 2025 13:25
…d-elements (#34076)

# Migrate Stencil from v2 to v4 and Fix Build Errors

## Overview

This PR migrates Stencil from version 2.22.2 to 4.39.0 to resolve
critical build errors and fixes TypeScript compilation issues that were
introduced after the Angular 21 migration.

## Problem Statement

After the Angular 21 migration, the Stencil build was failing with:
1. **Runtime Error**: `TypeError: Cannot read properties of null
(reading 'newLine')` at `getNewLineCharacter` - This was a bug in
Stencil 2.x that prevented builds from completing
2. **TypeScript Compilation Errors**: 
   - `Cannot find module 'primeng/api'`
   - `Cannot find module '@angular/common/http'`
- These errors occurred because Stencil builds couldn't resolve types
from Angular/PrimeNG dependencies

## Solution

### 1. Stencil Migration (v2 → v4)

**Upgraded Dependencies:**
- `@stencil/core`: `^2.22.2` → `^4.39.0`
- `@stencil/sass`: `^2.0.3` → `^3.2.3`
- `@nxext/stencil`: `20.1.0` → `21.0.0`

**Configuration Updates:**
- Removed deprecated configuration options
- Fixed duplicate `outputTargets` in
`dotcms-field-elements/stencil.config.ts`
- Verified no deprecated `@Prop` context/connect usage (none found)

**Migration References:**
- [Stencil 4 Migration
Guide](https://stenciljs.com/docs/introduction/upgrading-to-stencil-four)
- [Stencil 2 Breaking
Changes](https://github.com/stenciljs/core/blob/main/BREAKING_CHANGES.md#stencil-two)
- [Stencil 3 Breaking
Changes](https://github.com/stenciljs/core/blob/main/BREAKING_CHANGES.md#stencil-v300)

### 2. Type Declaration Stubs

Created type declaration stubs (`stencil-types.d.ts`) for both Stencil
projects to provide TypeScript type information for external
dependencies that aren't available during the Stencil build:

- **`@angular/common/http`**: Stub declarations for `HttpClient`,
`HttpRequest`, `HttpResponse`, `HttpErrorResponse`, `HttpEvent`,
`HttpEventType`, `HttpParams`, `HttpHeaders`
- **`primeng/api`**: Stub declarations for `MenuItem`,
`MenuItemCommandEvent`, `SelectItem`

**Why This Approach?**
- Web components should be framework-agnostic and not bundle
Angular/PrimeNG code
- These dependencies are only needed for type checking, not runtime
- Stencil builds web components independently, and these external
dependencies shouldn't be included in the final bundle
- This is a standard TypeScript pattern using `declare module`

**Files Created:**
- `libs/dotcms-webcomponents/stencil-types.d.ts`
- `libs/dotcms-field-elements/stencil-types.d.ts`

### 3. TypeScript Configuration Updates

**Updated `tsconfig.json` files:**
- Added `skipLibCheck: true` to ignore type errors in declaration files
- Excluded e2e test files (`**/*.e2e.ts`, `**/*.e2e.tsx`) from builds
- Updated `include` paths to reference type declaration files
- Added `types: ["node"]` for proper type resolution

**Files Modified:**
- `libs/dotcms-webcomponents/tsconfig.json`
- `libs/dotcms-field-elements/tsconfig.json`

### 4. Type-Only Imports

Converted regular imports to `import type` for type-only usage to
prevent runtime dependencies:

**Files Modified:**
- `libs/dotcms-models/src/lib/dot-action-menu-item.model.ts`
- `libs/dotcms-models/src/lib/dot-apps.model.ts`
- `libs/dotcms-models/src/lib/dot-experiments.model.ts`
- `libs/dotcms-js/src/lib/core/util/http-response-util.ts`
- `libs/dotcms-js/src/lib/core/login.service.ts`

### 5. Babel Runtime Module Resolution

**Problem**: Build was failing with `Module not found: Error: Can't
resolve '@babel/runtime/helpers/esm/asyncToGenerator.js'` because the
build system was looking for `@babel/runtime` in a nested location.

**Solution**:
- Added `@babel/runtime@^7.28.4` as a direct dependency
- Added npm `overrides` to ensure proper module hoisting:
  ```json
  "overrides": {
      "@babel/runtime": "^7.28.4"
  }
  ```

### 6. Additional Fixes

**MCP Server Module Resolution:**
- Fixed ESM subpath imports by adding `.js` extensions:
- `@modelcontextprotocol/sdk/server/mcp` →
`@modelcontextprotocol/sdk/server/mcp.js`
- `@modelcontextprotocol/sdk/shared/protocol` →
`@modelcontextprotocol/sdk/shared/protocol.js`
- `@modelcontextprotocol/sdk/types` →
`@modelcontextprotocol/sdk/types.js`

**SCSS @extend Issues:**
- Added `!optional` flag to `@extend #form-field-disabled` in
`_autocomplete.scss`
- Added `@use "common";` at the top of `form/index.scss` to ensure
proper import order

**Type Definitions:**
- Added `@types/minimatch@^5.1.2` for Stencil build compatibility

## Testing

✅ **All builds now succeed:**
- `nx run dotcms-webcomponents:build` - ✅ Success
- `nx run dotcms-field-elements:build` - ✅ Success (with type stubs)
- `nx run dotcdn:build` - ✅ Success
- `nx run mcp-server:build:production` - ✅ Success
- `nx run sdk-angular:build:production` - ✅ Success

## Breaking Changes

None. This is a bug fix and migration that maintains backward
compatibility.

## Migration Notes

- The type declaration stubs are minimal and only include the types
actually used
- If new Angular/PrimeNG types are needed in the future, they should be
added to the stubs
- The Stencil 4 migration follows official migration guides and
maintains all existing functionality

## Related Issues

- Resolves Stencil runtime error: `TypeError: Cannot read properties of
null (reading 'newLine')`
- Resolves TypeScript compilation errors for `primeng/api` and
`@angular/common/http`
- Resolves Babel runtime module resolution issues
- Resolves MCP server module resolution issues

This PR fixes: #33882
…nent with improved prop binding and lazy loading validation
…ontrol for enhanced form handling in unit tests
…izing indentation and formatting for better readability
…omponent properties and methods to improve code clarity and maintainability
…d virtual scroller initialization for improved user experience
…ze and minHeight properties for better layout control
…d user experience and enhance dropdown options management
…nsive scenarios including lazy loading, filtering, and pinned option functionality
… for improved consistency and functionality across the application
…nput bindings and adding output emission tests for improved coverage
…unnecessary disabled input binding and focusing on FormControl state
…g unused provideNoopAnimations and maintaining essential testing utilities
…t by refining input handling, enhancing output emissions, and ensuring proper state management during filtering and lazy loading
hmoreras and others added 6 commits February 27, 2026 00:37
…es (#34784)

## Summary
- Replace Angular `@slideAnimation` trigger with CSS-based
`animate.enter`/`animate.leave` attributes to remove the deprecated
`@angular/animations` dependency from the toolbar component
- Change toolbar tree-toggler visibility from conditional rendering
(`@if`) to CSS-based show/hide (opacity/visibility/width) so the toggle
button animates smoothly instead of popping in/out
- Fix folder list view loading skeleton: extract `loadingRow` into a
reusable `<ng-template>` and show it inside `emptymessage` during
loading so rows appear correctly on initial load and page changes
- Update `$loadingRows` signal to track the current page size and emit
correctly sized skeleton row arrays on pagination
- Fix optional chaining on `$dialog` signal calls in the shell component
to prevent null-access errors
- Fix `$folder` input type from `null` default to `undefined` (aligns
with Angular signal input best practices)
- Fix typing errors and update tests to match new DOM structure (toggler
now always rendered, assertions check styles rather than element
presence)


https://github.com/user-attachments/assets/411e025f-b070-47b4-a931-4de53f257141




## Test plan
- [ ] Navigate to Content Drive portlet and verify the folder list
renders skeleton loading rows on initial load
- [ ] Verify that changing pages shows the correct number of skeleton
rows matching the page size
- [ ] Expand/collapse the folder tree panel and verify the tree-toggler
button animates smoothly (fades rather than snapping in/out)
- [ ] Click "Add New" and verify the toolbar button animates in/out when
switching between normal and multi-selection mode
- [ ] Open a dialog (e.g., create folder), verify it opens and closes
correctly without null-reference errors
- [ ] Run unit tests: `yarn nx test dot-content-drive-portlet` and
confirm all pass
- [ ] Run unit tests for the UI lib: `yarn nx test dot-content-drive-ui`
and confirm all pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@zJaaal zJaaal linked an issue Mar 2, 2026 that may be closed by this pull request
28 tasks
@zJaaal
zJaaal marked this pull request as ready for review March 2, 2026 16:23
@github-actions github-actions Bot added the Area : Frontend PR changes Angular/TypeScript frontend code label Mar 2, 2026
@nicobytes
nicobytes requested a review from Copilot March 2, 2026 16:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Content Drive’s Content Type filter to support PrimeNG virtual scrolling with incremental (lazy) loading, so users can browse large content-type lists without forcing search-based discovery.

Changes:

  • Enable p-multiselect virtual scroll + lazy loading and wire the onLazyLoad event.
  • Add page-based pagination logic to DotContentDriveContentTypeFieldComponent using getContentTypesWithPagination.
  • Update unit tests for the new lazy-load behavior; register dotCMS web components at app bootstrap.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
core-web/libs/portlets/dot-content-drive/portlet/src/lib/components/dot-content-drive-toolbar/components/dot-content-drive-content-type-field/dot-content-drive-content-type-field.component.html Enables lazy + virtualScroll, sets item size, wires (onLazyLoad) for infinite-scroll behavior.
core-web/libs/portlets/dot-content-drive/portlet/src/lib/components/dot-content-drive-toolbar/components/dot-content-drive-content-type-field/dot-content-drive-content-type-field.component.ts Implements pagination state (ITEMS_PER_PAGE, currentPage, canLoadMore) and lazy-load fetching via getContentTypesWithPagination.
core-web/libs/portlets/dot-content-drive/portlet/src/lib/components/dot-content-drive-toolbar/components/dot-content-drive-content-type-field/dot-content-drive-content-type-field.component.spec.ts Updates tests to assert paginated fetching and lazy-load behavior; adjusts store/signal interactions accordingly.
core-web/apps/dotcms-ui/src/main.ts Registers dotCMS web components by calling defineCustomElements().

@zJaaal
zJaaal disabled auto-merge March 2, 2026 16:48
@zJaaal
zJaaal enabled auto-merge March 2, 2026 16:55
@zJaaal
zJaaal added this pull request to the merge queue Mar 2, 2026
Merged via the queue into main with commit e269263 Mar 2, 2026
25 checks passed
@zJaaal
zJaaal deleted the 33753-task-content-drive-implement-virtual-scroll-for-content-type-filter branch March 2, 2026 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area : Frontend PR changes Angular/TypeScript frontend code

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

[TASK] Content Drive: Implement virtual scroll for Content Type Filter

10 participants