Skip to content

Conversation

@zJaaal
Copy link
Contributor

@zJaaal zJaaal commented Jan 15, 2026

🎯 Issue 34251: Migrate Rules Portlet UI to PrimeNG 21 / Angular 21

Base Branch: issue-33882-primeng-update
Target: Angular 21 + PrimeNG 21 + Tailwind CSS + Jest


📊 Migration Summary

Total Scope:

  • 98 files changed across dot-rules library and infrastructure
  • 4,753 insertions / 14,534 deletions (net -9,781 lines removed!)
  • 12 commits spanning cleanup, modernization, and architectural improvements
  • 100% backward compatible with existing rules

🧹 Phase 1: Codebase Cleanup (Commits 1-2)

Removed Deprecated Components & Legacy Code

  • Custom form controls: dot-autocomplete-tags, custom dropdown, input-date, RestDropdown
  • Legacy dialogs: modal-dialog, push-publish dialogs (add-to-bundle)
  • Deprecated directives: dot-autofocus
  • Old component implementations: dot-unlicense, legacy rule-engine components
  • Build tools: Karma config → Jest, tslint → ESLint
  • Aligned code standards to use PrimeNG equivalents throughout

🏗️ Phase 2: Rules Portlet Modernization (Commits 3-12)

Complete Architectural Restructure

libs/dot-rules/
├── features/                    # ✨ NEW: Feature-based organization
│   ├── actions/                 # Rule actions
│   ├── conditions/              # Condition components
│   │   ├── geolocation/         # Visitors location (Google Maps)
│   │   │   ├── dialog/          # Map picker dialog
│   │   │   └── visitors-location/
│   │   │       ├── container/   # State management
│   │   │       └── dot-visitors-location.component.ts
│   │   ├── serverside-condition/# Server-side conditions
│   │   ├── rule-condition/      # Individual conditions
│   │   └── condition-group/     # Condition groups
│   ├── rule/                    # Rule component
│   └── rule-engine/             # Main rule engine
│       ├── container/           # State management
│       └── dot-rule-engine.component.ts
├── services/                    # Reorganized services
│   ├── api/                     # API clients with proper types
│   ├── models/                  # Domain models
│   ├── validators/              # Form validators
│   └── utils/                   # Utilities
└── entry/                       # Public API entry point

Before: Scattered files in condition-types/, custom-types/, google-map/, root
After: Clear feature hierarchy with domain-driven organization + container pattern

Key Technical Improvements

1. Testing Infrastructure Migration

- karma.conf.js (Karma + Jasmine)
+ jest.config.ts (Jest)
+ DOT-RULES-ARCHITECTURE.md (comprehensive developer guide)

2. TypeScript Type Safety Overhaul

// Before: Loose typing with 'any'
_inputs: Array<any>
onDropdownChange(input: any, value: any)

// After: Strict domain types
_inputs: CwComponent[]
onDropdownChange(input: CwComponent, value: string | string[])

// New domain types added:
- UnitKey ('mi' | 'km')
- ComparisonOption (comparison dropdown options)
- VisitorsLocationParams (geolocation parameters)
- CwComponent (component model)
- EventModel (event definitions)

3. Modern RxJS Patterns

// Before: Deprecated multi-param subscribe
this.observable.subscribe(
  data => handleData(data),
  error => handleError(error)
)

// After: Object notation (Angular 19 standard)
this.observable.subscribe({
  next: (data) => handleData(data),
  error: (error) => handleError(error)
})

4. Tailwind CSS Migration (11,095 lines removed!)

- <div class="layout-row layout-align-space-between layout-fill">
+ <div class="flex justify-between h-full">

- <div flex="50" layout="column">
+ <div class="w-1/2 flex flex-col">

- Removed: angular-material.layouts.scss (11,095 lines)
- Updated: All 7 HTML templates to use Tailwind utilities
- Cleaned up: Renamed cw-* CSS classes to dot-rules-* prefix

5. Enhanced Google Maps Integration

// NEW: Circle dragging with center_changed event
google.maps.event.addListener(circle, 'center_changed', () => {
  const newCenter = circle.getCenter();
  updateCircleParams(newCenter);
});

6. UI Bug Fixes

  • Fixed: Rule actions not updating after deletion (added refreshRules() call)
  • Fixed: Change detection issues with Angular signals

7. Component Organization & Separation of Concerns

- features/rule-engine/dot-rule-engine-container.component.ts (mixed concerns)
+ features/rule-engine/container/dot-rule-engine-container.component.ts (state)
+ features/rule-engine/dot-rule-engine.component.ts (presentation)

- features/conditions/geolocation/*.component.ts (flat structure)
+ features/conditions/geolocation/dialog/ (map picker)
+ features/conditions/geolocation/visitors-location/ (input fields)
+ features/conditions/geolocation/visitors-location/container/ (state management)

📚 Phase 3: Comprehensive Documentation (Commit 13)

Frontend Developer's Survival Guide

Updated: README.md - A complete guide for navigating the Rules Engine

What's Included:

  • 🗺️ Component Hierarchy Diagram - Visual map of what talks to what
  • 🎯 Component Glossary - Every component explained with purpose, inputs, outputs, gotchas
  • 🔄 Data Flow Diagrams - Complete user action → API flows
  • 🏗️ Data Models Reference - RuleModel, ConditionModel, ActionModel explained
  • 🔧 Common Development Tasks - Copy-paste examples for extending the portlet
  • 🐛 Debugging Guides - Solutions for "UI not updating", date picker issues, etc.
  • 📖 Learning Path - Day 1-3 progression for new developers
  • 🚑 Emergency Debugging - Browser DevTools tricks, network debugging
  • ⚠️ Common Pitfalls - The traps everyone falls into (with solutions!)

Key Sections:

## 🗺️ What Is This Thing?
## 📊 The 30,000 Foot View
## 🎯 Component Glossary (What Each One Actually Does)
## 🔄 Data Flow (The Complete Picture)
## 🏗️ The Data Models (What You're Actually Working With)
## 🔧 Common Development Tasks
## 🎓 Learning the Codebase
## 🚑 Emergency Debugging
## 📚 File Index (Quick Reference)

Why This Matters:
The Rules Engine was previously the "god-forbidden portlet" that nobody wanted to touch. This documentation provides:

  • Clear explanations of complex patterns (signals + OnPush + refreshRules())
  • Visual diagrams showing component relationships
  • Practical debugging steps for common issues
  • A roadmap for new developers to get productive quickly

📦 Deliverables

New Files Created

  • jest.config.ts - Modern Jest configuration
  • features/*/container/ - Separated state management components
  • features/conditions/geolocation/dialog/ - Map picker dialog
  • features/conditions/geolocation/visitors-location/ - Location input components
  • services/models/input.model.ts - Centralized input models (257 lines)
  • entry/dot-rules.component.ts - New entry point component

Files Removed (Legacy Code)

  • angular-material.layouts.scss - 11,095 lines of unused styles
  • 8 deprecated component directories
  • Karma/Jasmine config files
  • Legacy rule engine components (rule-component.ts, rule-engine.ts, etc.)
  • Component-specific .scss files (consolidated into shared styles)

Component Reorganization

Old Structure (Flat):
- features/rule-engine/dot-rule-engine-container.component.ts
- features/conditions/geolocation/dot-visitors-location-container.component.ts

New Structure (Container Pattern):
+ features/rule-engine/container/dot-rule-engine-container.component.ts
+ features/rule-engine/dot-rule-engine.component.ts (presentation)
+ features/conditions/geolocation/dialog/dot-area-picker-dialog.component.ts
+ features/conditions/geolocation/visitors-location/container/...
+ features/conditions/geolocation/visitors-location/dot-visitors-location.component.ts

🧪 Testing Checklist

Core Functionality

  • Create/edit rules with multiple condition groups
  • Add/remove/reorder rule actions
  • Location picker dialog with Google Maps integration
  • NEW: Drag circle to reposition on map (center_changed event)
  • Server-side conditions with dropdowns, dates, text inputs
  • Rule validation and error messages
  • Save/publish/archive rules
  • Verify backward compatibility with existing rules in database

Code Quality

nx lint dot-rules    # Should pass with documented eslint-disable comments

🎨 Visual & UX Changes

Layout Migration

- Angular Material Flex Layout (@angular/flex-layout deprecated)
+ Tailwind CSS Utilities (modern, tree-shakeable)

Component Organization

- Flat structure with mixed concerns
+ Feature-based hierarchy with container/presentation separation

Styling Standards

- cw-* prefixed classes (legacy)
+ dot-rules-* prefixed classes (dotCMS standard)
- Component-specific .scss files
+ Consolidated shared styles

🚨 Breaking Changes

None! 🎉

  • ✅ Same rule execution logic and business rules
  • ✅ Same REST API contracts
  • ✅ Same user workflows and interactions
  • ✅ Same database schema
  • ✅ Same public exports from library
  • ✅ Existing rules in database work unchanged

🎯 Success Criteria

Functional Requirements

  • ✅ All existing Rules functionality preserved
  • ✅ Google Maps geolocation conditions work
  • ✅ Server-side conditions (dropdowns, dates, text) work
  • ✅ Rule actions can be added/removed/reordered
  • ✅ Rule validation enforces business rules

Technical Requirements

  • ✅ No TypeScript compilation errors
  • ✅ Lint passes (ESLint strict mode)
  • ✅ Jest tests pass (migrated from Karma)
  • ✅ Improved type safety (eliminated most 'any' types)
  • ✅ Better code organization (feature-based + container pattern)
  • ✅ Removed 11,095 lines of unused CSS
  • ✅ Modern Angular 19 patterns (signals, control flow)
  • ✅ Modern RxJS patterns (object notation)
  • ✅ Component separation (container/presentation)

Documentation Requirements

  • ✅ Comprehensive architecture guide (904 lines)
  • ✅ Component glossary with visual diagrams
  • ✅ Data flow documentation
  • ✅ Debugging guides for common issues
  • ✅ Learning path for new developers
  • ✅ Code examples for extending the portlet
  • ✅ File index and quick reference

📚 Related

Parent Epic: #33882 - PrimeNG 21 Migration
Base Branch: issue-33882-primeng-update (contains infrastructure: Esbuild, Tailwind, PrimeNG 21)
Tracking Issue: #34251


🎨 Angular 21 • PrimeNG 21 • Tailwind CSS • Jest

Rules Engine: Fully Modernized & Documented

-9,781 lines of legacy code removed • Feature-based architecture • Type-safe domain models • Comprehensive developer guide

This PR fixes: #34251

zJaaal and others added 2 commits January 15, 2026 17:57
Remove legacy components replaced by PrimeNG equivalents:
- dot-autocomplete-tags, dot-unlicense
- Custom dropdown, input-date, and restdropdown
- Legacy modal-dialog and push-publish dialogs
- Old rule-engine components
- Deprecated directives (dot-autofocus)
- Karma config and tslint files

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
… use primeng

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@zJaaal zJaaal linked an issue Jan 15, 2026 that may be closed by this pull request
@zJaaal zJaaal changed the base branch from main to issue-33882-primeng-update January 15, 2026 21:00
@semgrep-code-dotcms-test
Copy link

Semgrep found 1 ssc-74b4cbd5-76e9-40fe-adb6-38be9f569d24 finding:

Risk: Affected versions of next are vulnerable to Dependency on Vulnerable Third-Party Component / Deserialization of Untrusted Data / Uncontrolled Resource Consumption. A flaw in Next.js's App Router deserialization allows an attacker to send a specially crafted HTTP request body that, when parsed by the server, triggers excessive CPU work or an infinite loop. By targeting any App Router endpoint with this malicious payload, the server process can hang and become unresponsive, resulting in a denial-of-service.

Fix: Upgrade this library to at least version 14.2.34 at core/core-web/package-lock.json:47304.

Reference(s): GHSA-mwv6-3258-q52c

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Semgrep found 1 ssc-b94a740c-3b13-43fd-9f2d-4d8bb0fe0b69 finding:

Risk: Affected versions of next are vulnerable to Dependency on Vulnerable Third-Party Component / Deserialization of Untrusted Data / Uncontrolled Resource Consumption. An attacker can send a specially crafted HTTP request to any Server Function endpoint (as used by Next.js' App Router) that, when deserialized by the React Server Components runtime, enters an infinite loop—hanging the server process, exhausting CPU, and resulting in a denial-of-service.

Fix: Upgrade this library to at least version 14.2.35 at core/core-web/package-lock.json:47304.

Reference(s): GHSA-5j59-xgg2-r9c4, CVE-2025-67779

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Semgrep found 1 ssc-8b9dcf76-fc1d-cc03-9c41-131ebf43d4c2 finding:

Risk: Affected versions of storybook are vulnerable to Exposure of Sensitive Information to an Unauthorized Actor / Inclusion of Sensitive Information in an Include File / Insertion of Sensitive Information into Externally-Accessible File or Directory. A bug in Storybook's build process causes any environment variables defined in a .env file (e.g. .env.local) in the project directory to be unexpectedly bundled into the static output. When that build is published to the web, those variables —including any secrets—are exposed in the client‐side source.

Fix: Upgrade this library to at least version 8.6.15 at core/core-web/package-lock.json:60093.

Reference(s): GHSA-8452-54wp-rmv6, CVE-2025-68429

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Semgrep found 1 ssc-2427bad3-7619-448f-8f95-70806990606e finding:

Risk: Affected versions of @angular/compiler are vulnerable to Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'). A stored XSS vulnerability in the Angular Template Compiler arises because its internal security schema doesn't classify certain URL‐ holding attributes (e.g. xlink:href, math|href, annotation|href) or the attributeName binding on SVG animation elements (<animate>, <set>, etc.) as requiring strict URL sanitization. An attacker who can supply untrusted input to template bindings like [attr.xlink:href] or <animate [attributeName]="'href'" [values]="maliciousURL"> can inject a javascript: URL payload. When the element is activated (e.g. clicked) or the animation runs, the malicious script executes in the application's origin, enabling session hijacking, data exfiltration, or unauthorized actions.

Manual Review Advice: A vulnerability from this advisory is reachable if you allow SVG/MathML attributes (e.g., xlink:href, href) or to the attributeName field of SVG animation tags (, , etc.) in HTML templates

Fix: Upgrade this library to at least version 19.2.17 at core/core-web/package-lock.json:34712.

Reference(s): GHSA-v4hv-rgfq-gp49, CVE-2025-66412

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Semgrep found 1 ssc-4e59e976-8886-47a3-9b32-abcb3212a6c1 finding:

Risk: http-cache-semantics versions before 4.1.1 are vulnerable to Inefficient Regular Expression Complexity leading to Denial of Service. The issue can be exploited via malicious request header values sent to a server, when that server reads the cache policy from the request using this library.

Fix: Upgrade this library to at least version 4.1.1 at core/core-web/package-lock.json:50435.

Reference(s): GHSA-rc47-6667-2j5j, CVE-2022-25881

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

@semgrep-code-dotcms-test
Copy link

Legal Risk

The following dependencies were released under a license that
has been flagged by your organization for consideration.

Recommendation

While merging is not directly blocked, it's best to pause and consider what it means to use this license before continuing. If you are unsure, reach out to your security team or Semgrep admin to address this issue.

GPL-2.0

MPL-2.0

zJaaal and others added 10 commits January 19, 2026 10:12
- Moved dot-area-picker-dialog from google-map/ to components/ directory
- Moved dot-serverside-condition from condition-types/ to components/ directory
- Added proper TypeScript type annotations (UnitKey, ComparisonOption)
- Fixed RxJS subscribe calls to use object notation instead of deprecated multi-param syntax
- Added center_changed event listener for Google Maps circle
- Improved type safety throughout visitors-location and rule-engine components
- Added eslint-disable comments for pre-existing type issues in legacy code

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Replace all Angular Material layout attributes (flex, layout, layout-align,
  layout-fill) with Tailwind CSS utility classes across 7 HTML files
- Remove angular-material.layouts.scss (11,000+ lines of legacy styles)
- Rename remaining cw-* CSS classes to dot-rules-* in action component
- Fix UI not updating when deleting rule actions (add refreshRules() call)
@alwaysmeticulous
Copy link

Meticulous was unable to execute a test run for this PR because the most recent commit is associated with multiple PRs. To execute a test run, please try pushing up a new commit that is only associated with this PR.

Last updated for commit f502cbf. This comment will update as new commits are pushed.

@zJaaal zJaaal changed the title WIP: Migrate Rules Portlet UI to PrimeNG 21 and Angular 21 fix(Rules): Migrate Portlet UI to PrimeNG 21 and Angular 21 Jan 19, 2026
zJaaal and others added 7 commits January 20, 2026 10:32
…ze event types

- Remove ViewEncapsulation.None and monolithic rule-engine.scss
- Create component-specific SCSS files for each component
- Use shared SASS variables (spacing, colors, fonts) from dotcms-scss
- Convert px values to rem for consistency
- Use PrimeNG button props (severity, rounded, text) instead of custom classes
- Centralize event types in rule-event.model.ts
- Align condition/action layouts with consistent widths
- Fix AND/OR toggle alignment in condition groups
- Created detailed architecture documentation for Rules Engine portlet
- Added component glossary with purpose and usage for each component
- Documented complete data flow from user actions to API calls
- Included debugging guides for common issues (UI not updating, date pickers, etc.)
- Added practical examples for extending the portlet (new input types, rule properties)
- Provided learning path for new developers (Day 1-3 progression)
- Documented emergency debugging techniques and common pitfalls
- Added file index and quick reference sections

The guide is specifically tailored for frontend developers who are unfamiliar
with the Rules Engine, providing a "map through the wasteland" with focus on:
- Data flow and state management
- Component responsibilities and interactions
- Change detection patterns (signals + OnPush + refreshRules())
- Dynamic input generation system
- Event bubbling architecture

Also reorganized geolocation and rule-engine components into proper subdirectories:
- features/conditions/geolocation/ → dialog/, visitors-location/container/
- features/rule-engine/ → container/ for separation of concerns

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Move comprehensive developer's survival guide from DOT-RULES-ARCHITECTURE.md
to README.md for better discoverability. Developers typically check README.md
first, making this the more appropriate location for the architecture documentation.

The guide includes:
- Component hierarchy and glossary
- Complete data flow diagrams
- Data model references
- Common development tasks with examples
- Debugging guides and troubleshooting
- Learning path for new developers
- Emergency debugging techniques
- File index and quick reference

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@semgrep-code-dotcms-test
Copy link

Semgrep found 11 ssc-4fd3a3fc-acff-4277-9d88-60469f5a4fa5 findings:

  • core-web/libs/dot-rules/src/lib/features/rule/dot-rule.component.ts
  • core-web/libs/dot-rules/src/lib/features/rule-engine/dot-rule-engine.component.ts
  • core-web/libs/dot-rules/src/lib/features/rule-engine/container/dot-rule-engine-container.component.ts
  • core-web/libs/dot-rules/src/lib/features/conditions/serverside-condition/dot-serverside-condition.component.ts
  • core-web/libs/dot-rules/src/lib/features/conditions/rule-condition/dot-rule-condition.component.ts
  • core-web/libs/dot-rules/src/lib/features/conditions/geolocation/visitors-location/dot-visitors-location.component.ts
  • core-web/libs/dot-rules/src/lib/features/conditions/geolocation/visitors-location/container/dot-visitors-location-container.component.ts
  • core-web/libs/dot-rules/src/lib/features/conditions/geolocation/dialog/dot-area-picker-dialog.component.ts
  • core-web/libs/dot-rules/src/lib/features/conditions/condition-group/dot-condition-group.component.ts
  • core-web/libs/dot-rules/src/lib/features/actions/dot-rule-action.component.ts
  • core-web/libs/dot-rules/src/lib/entry/dot-rules.component.ts

Risk: Affected versions of @angular/compiler and @angular/core are vulnerable to Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'). Angular's template compiler fails to classify the href and xlink:href attributes on SVG <script> elements as Resource URL contexts. This allows an attacker to bind a malicious data: URI or external script via [attr.href] or [attr.xlink:href], resulting in arbitrary JavaScript execution (XSS) in the victim's browser.

Fix: Upgrade this library to at least version 21.0.7 at core/core-web/package-lock.json:5082.

Reference(s): GHSA-jrmj-c5cx-3cw6, CVE-2026-22610

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

@zJaaal zJaaal marked this pull request as ready for review January 21, 2026 14:55
@hmoreras hmoreras merged commit 14ac7f3 into issue-33882-primeng-update Jan 21, 2026
6 checks passed
@hmoreras hmoreras deleted the 34251-migrate-rules-portlet-ui-to-primeng-angular-21 branch January 21, 2026 16:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Migrate 'Rules' portlet UI to PrimeNG (Angular 21)

3 participants