Issue 32639 ai dotai portlet#33744
Issue 32639 ai dotai portlet#33744jdotcms wants to merge 521 commits intoissue-32639-ai-vertex-vendorfrom
Conversation
### Proposed Changes This pull request refactors the "Render Mode" property field in the content type fields properties form to improve its UI/UX and code maintainability. The main changes include switching from basic radio buttons to a card-based selection interface, updating the render mode enum, and introducing better styling and structure for the selection options. **UI/UX Improvements:** - The render mode selection is now displayed as selectable cards, each with a label and tooltip, providing a clearer and more interactive way for users to choose between modes. - The new card-based UI is styled for improved accessibility and responsiveness, including visual feedback for selection and hover states. **Codebase and Structure Updates:** - Updated the `DotRenderModes` enum: renamed `COMPONENTS` to `COMPONENT` for consistency and correctness. - Refactored the component logic to use Angular signals for managing render modes, encapsulated render mode metadata, and added utility getters for cleaner code. - Added the required PrimeNG `CardModule` to the module imports to support the new card UI. [[1]](diffhunk://#diff-0f3ec14af7770b7e5376a79d0ebe9857b53fd3a61a4afb3725d1f5f515e95753R9) [[2]](diffhunk://#diff-0f3ec14af7770b7e5376a79d0ebe9857b53fd3a61a4afb3725d1f5f515e95753R125) ### Checklist - [x] Tests - [x] Translations - [x] Security Implications Contemplated (add notes if applicable) | Before | After | |--------|--------| | <img width="629" height="770" alt="Screenshot 2025-12-05 at 8 02 49 AM" src="https://github.com/user-attachments/assets/a78c67bb-0b88-4cc7-9fab-2510f5892700" /> | <img width="628" height="772" alt="Screenshot 2025-12-05 at 8 03 20 AM" src="https://github.com/user-attachments/assets/394b7827-1b7c-465c-83e1-db09f649fd24" /> |
### Proposed Changes * Trying to isolate a race condition in a smaller PR * This PR contains changes that modernize the folder info returned by the new content-drive endpoint * Previously, the returned folder info was getting mapped using the old BrowerAPI Transformer * ContentDrive is the new default view in DotFolderTransformer This PR fixes: #34016
…#34053) ## Summary Fixes the release workflow by removing the redundant `deployment_succeeded` parameter that caused syntax validation errors and skipped the entire release phase during workflow run [#20043196360](https://github.com/dotCMS/core/actions/runs/20043196360). ## Root Cause The `deployment_succeeded` parameter had two critical problems: 1. **GitHub Actions Syntax Error**: GitHub Actions does **NOT** support using `needs.<job>.result` in the `with:` block of reusable workflow calls. The `needs.*.result` context is **only available in `if:` conditions**. 2. **Redundant Logic**: The parameter was unnecessary because: - The release job already has `needs: [deployment]` with `if: !failure()`, ensuring deployment succeeded - The release-labeling job uses `if: success()`, which already checks that release-artifacts succeeded - GitHub Actions' native dependency chain already enforces the safety requirement When GitHub Actions validated the workflow and found: ```yaml deployment_succeeded: ${{ needs.deployment.result == 'success' }} ``` It rejected this with "Unexpected value" errors and skipped the entire release phase, marking it as "failure" without ever executing it. ## Impact This caused **critical partial release failures**: - ✅ Docker images deployed successfully - ❌ Maven artifacts NOT deployed to Artifactory - ❌ Javadocs NOT uploaded to S3 - ❌ SBOM NOT generated - ❌ GitHub labels NOT updated - ❌ Plugins NOT notified ## The Fix Removed the `deployment_succeeded` parameter entirely from: 1. **cicd_6-release.yml** (line 132) - Removed the problematic input 2. **cicd_comp_release-phase.yml** (lines 53-56) - Removed the input definition 3. **cicd_comp_release-phase.yml** (line 211) - Removed from release-labeling condition The workflow now relies on GitHub Actions' native job dependency checking: - The `release` job only runs if `deployment` succeeds (via `needs` + `if: !failure()`) - The `release-labeling` job only runs if `release-artifacts` succeeds (via `if: success()`) - This properly ensures both deployment and release-artifacts succeed before updating labels **Changes**: 2 files, -6 lines (removed redundancy) ## Test Plan - [ ] Trigger a test release workflow run - [ ] Verify the release phase actually executes (no annotations) - [ ] Verify all release steps complete successfully (Artifactory, Javadocs, SBOM, labels) - [ ] Confirm release-labeling only runs when both deployment and release-artifacts succeed ## Related Issues Fixes #34051 References: https://github.com/dotCMS/core/actions/runs/20043196360 ## Documentation See complete root cause analysis: `.claude/diagnostics/run-20043196360/DIAGNOSIS-FINAL.md`
### Description This PR fixes the breadcrumb / menu navigation active menu mapping and navigation handling for the analytics dashboard by reintroducing the `REPLACE_SECTIONS_MAP` in the menu management system. ### Changes - **Added `REPLACE_SECTIONS_MAP`** again (as we used to do in DotNavigationService) in `menu.slice.ts` to maintain backward compatibility with legacy section IDs - Maps `'edit-page'` → `'site-browser'` - Maps `'analytics'` → `'analytics-dashboard'` - **Updated `with-menu.feature.ts`** to use `REPLACE_SECTIONS_MAP` for correct menu activation, especially for the analytics section - **Added tests** to validate the menu activation behavior with section ID replacement ### Purpose Ensures that the analytics dashboard breadcrumbs are correctly displayed and the menu item correctly highlighted and that old bookmarks/URLs using legacy section IDs continue to work properly. --------- Co-authored-by: Nicolas Molina Monroy <hi@nicobytes.com>
core-web/yarn.lock
Outdated
| version "19.2.9" | ||
| resolved "https://registry.npmjs.org/@angular/compiler/-/compiler-19.2.9.tgz#0af6a48fc0db9f981e1d662a1c9cf299d3ac92d9" | ||
| integrity sha512-K6wtAsJhQeD2OjoupV03gWHBqnqhEP9llzFzlnQoXAAZzM1eIT/KAtQEdNY75NO+BESKxaXvQBAU16Tg/1I6uw== | ||
| "@angular/compiler@20.3.9": |
There was a problem hiding this comment.
High severity vulnerability may affect your project—review required:
Line 557 lists a dependency (@angular/compiler) with a known High severity vulnerability.
ℹ️ Why this matters
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.
To resolve this comment:
Check if you allow SVG/MathML attributes (e.g., xlink:href, href) or to the attributeName field of SVG animation tags (, , etc.) in HTML templates.
- If you're affected, upgrade this dependency to at least version 20.3.15 at core-web/yarn.lock.
- If you're not affected, comment
/fp we don't use this [condition]
💬 Ignore this finding
To ignore this, reply with:
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.
You can view more details on this finding in the Semgrep AppSec Platform here.
|
Semgrep found 322
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 Manual Review Advice: A vulnerability from this advisory is reachable if you allow Fix: Upgrade this library to at least version 20.3.15 at core/core-web/yarn.lock:557. 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 56
Risk: Affected versions of @angular/common are vulnerable to Exposure of Private Personal Information to an Unauthorized Actor / Insertion of Sensitive Information Into Sent Data. HttpClient incorrectly treats protocol-relative URLs as same-origin and attaches the X-XSRF-TOKEN header, allowing an attacker-triggered request to leak the victim’s XSRF token to an attacker-controlled domain. Fix: Upgrade this library to at least version 20.3.14 at core/core-web/yarn.lock:536. Reference(s): GHSA-58c5-g7wp-6w37, CVE-2025-66035 If this is a critical or high severity finding, please also link this issue in the #security channel in Slack. |
We need to support bath in dotCMs to send the event to jitsu, for this we need to use a different key and a different endpoint, the endpoint is going to be set in the App, for now this batch is really simple it just take the batch of events send by the FE and send it as a batch to jitsu. ### Proposed Changes * Use the m2 key instead of the jskey https://github.com/dotCMS/core/pull/34059/files#diff-29cacbde2fe6ea160809f524ffd80ffc8526f8d2f60cff0339996965c0e36b90R90 * Not send a request for each event in the payload, now we are going to send just one Request for all the events https://github.com/dotCMS/core/pull/34059/files#diff-c6b552720dcdd032d58c9b299fd4c5aba7a5f3b233c6ae1d7a1528e94bfe51c7R102-R131
…sions` metric (#34069) ### Proposed Changes * This metric provides a visual representation of the metric exposed here: * #33870 * The CubeJS query that exposes the data for a specified time range is: ```json { "measures": [ "EventSummary.uniqueVisitors", "EventSummary.uniqueConvertingVisitors" ], "timeDimensions": [ { "dimension": "EventSummary.day", "dateRange": [ "2025-12-01", "2025-12-08" ], "granularity": "day" } ] } ```
) ## Summary This PR implements comprehensive folder support in the Content Drive table view, enabling users to browse, navigate, and manage folders alongside content items with full drag-and-drop functionality. ### Key Features - **Folder Display**: Show folders in table view with proper icons, metadata, and visual indicators - **Navigation**: Click folder rows to navigate into them with breadcrumb path tracking - **Drag & Drop**: Move both files and folders between locations using drag-and-drop - **Folder Management**: Create and edit folders with full metadata (title, sort order, show on menu, file masks) - **Context Menus**: Folder-specific workflow actions and operations - **Search Integration**: Text search that intelligently filters folders when searching content - **System Host Protection**: Prevents folder loading on system host ### Technical Implementation **New Services:** - `DotContentDriveService` - Unified search API using `/api/v1/drive/search` endpoint - Enhanced `DotFolderService` with `createFolder()` and `saveFolder()` methods **Type System:** - Extended `DotContentDriveItem` to support both `DotCMSContentlet` and `DotContentDriveFolder` - New `DotContentDriveSearchRequest` interface with comprehensive filtering options - New `DotContentDriveSearchResponse` with folder/content counts **State Management:** - Folder-aware store with navigation state - Enhanced drag-and-drop with folder destination support - Sidebar integration for folder operations **UI Components:** - Updated `dot-contentlet-icon` web component with consistent gray-700 styling - Enhanced folder list view with navigation indicators - Improved dialog for folder creation/editing ### Changes Summary - **43 files changed** with 3,639 additions, 514 deletions - Comprehensive unit test coverage for all new services - Integration tests for drag-and-drop functionality - Component tests using Spectator with modern Angular testing patterns Related to #33991 🤖 Generated with [Claude Code](https://claude.com/claude-code)
#34004) ### Proposed Changes * Exposes a new method in the existing `structures` ViewTool that allow developers to check whether the Content Type that the ViewTool is called in has the new Edit mode enabled or not. * This mechanism is going to be used by the Angular layer to determine how existing Custom Fields are going to be rendered in the new Content Edit Mode. That is, the mode that uses Angular instead of the legacy JSP/Dojo UI. This PR fixes: #33988
### Proposed Changes This pull request introduces improvements to how the default value for the `newRenderMode` field property is determined and managed, making it more dynamic and responsive to feature flag configuration. It also refactors related code for clarity and maintainability, and adds a new feature flag for the default render mode. The main changes are grouped below by theme. **Dynamic Default Value for `newRenderMode`:** * The `FieldPropertyService` now retrieves the default value for `newRenderMode` from a feature flag (`FEATURE_FLAG_CONTENT_EDITOR2_RENDER_MODE_DEFAULT`) using the `DotPropertiesService`, falling back to `DotRenderModes.IFRAME` if the flag is not found. This makes the default configurable without code changes. [[1]](diffhunk://#diff-bde383871412422b64c2a096eeda7acad8858088182afe147943fae6d6113629R30-R39) [[2]](diffhunk://#diff-bde383871412422b64c2a096eeda7acad8858088182afe147943fae6d6113629L86-R106) [[3]](diffhunk://#diff-3f0ed89ee1cbcb925153f86b2a576abd34e5a4e0639c55669b3a1f5d205ac5afR29) * The `DotPropertiesService.getKey()` method is refactored to return `FEATURE_FLAG_NOT_FOUND` when the requested key does not exist, improving error handling and clarity. **Component Lifecycle and Efficiency Improvements:** * The `DynamicFieldPropertyDirective` now implements `OnDestroy` and manages component creation, updating, and destruction more efficiently, only recreating components when necessary and cleaning up properly. It also uses deep equality checks for field changes. **Minor Adjustments and Refactoring:** * The default value for `newRenderMode` in `PROPERTY_INFO` is changed from `'false'` to an empty string, reflecting that the value should be dynamically determined. * Various imports and type usages are updated to support the above changes and improve code clarity. [[1]](diffhunk://#diff-bde383871412422b64c2a096eeda7acad8858088182afe147943fae6d6113629R2-R15) [[2]](diffhunk://#diff-b404d83cba1d88245c1bd41631e510a204262f092431af1339ff90d5f87ffa7cL8-R8) These changes collectively make the handling of the `newRenderMode` property more robust and configurable, and improve the lifecycle management of dynamic field property components. ### Checklist - [ ] Tests - [ ] Translations - [ ] Security Implications Contemplated (add notes if applicable)
…e on dotcms/uve (#34038) https://github.com/user-attachments/assets/67c0f657-49e9-4e5f-9071-2bc830cbea2a ### Usage ``` // First define the form with the API. const blogForm = defineStyleEditorSchema({ contentType: 'Content', sections: [ { title: 'Typography', fields: [ styleEditorField.checkboxGroup({ label: 'New CheckboxGroup', options: [ { label: 'Option 1', value: 'option1' }, { label: 'Option 2', value: 'option2' } ], defaultValue: { option1: false, option2: false }, }), styleEditorField.radio({ label: 'Layout', columns: 2, options: [ { label: 'Option 1', value: 'option1', imageURL: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSphn5CRr3MrQUjWWH7ByHWW-lROnVQl4XxYQ&s', width: 119 }, { label: 'Option 2', value: 'option2', imageURL: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSphn5CRr3MrQUjWWH7ByHWW-lROnVQl4XxYQ&s' }, { label: 'New Option', value: '' }, { label: 'New Option', value: 'new-option' } ], }) ] } ] }) // Then use the helper hook. useStyleEditorSchemas([blogForm]) // This hook internally use a exposed function called registerStyleEditorSchemas() // In Angular, we can use this function directly. We can create a service for this too, but maybe is a lot of code only for that, but we can recheck this later ``` --------- Co-authored-by: Kevin <kfariid@gmail.com>
… the palette (#34073) ### Video https://github.com/user-attachments/assets/eaa94159-eec9-42e7-8918-df4751f51fba This PR fixes: #34065
Before <img width="1712" height="923" alt="Screenshot 2025-12-08 at 3 38 33 PM" src="https://github.com/user-attachments/assets/0338e164-b05d-4a60-abe7-47ad6e43a913" /> After <img width="1706" height="883" alt="Screenshot 2025-12-08 at 3 38 09 PM" src="https://github.com/user-attachments/assets/590faa0a-0f38-4a3e-a7cb-08cbfea9fb51" /> This PR fixes: #33978
Before <img width="1722" height="748" alt="Screenshot 2025-12-08 at 2 53 58 PM" src="https://github.com/user-attachments/assets/ef26b32b-37cb-4f21-9b3c-835d58f3375b" /> After <img width="1422" height="606" alt="Screenshot 2025-12-08 at 2 53 38 PM" src="https://github.com/user-attachments/assets/ed2e03c4-4f49-40d5-8874-9e16a9e7ebd6" /> This PR fixes: #34033
…ments (#34081) ## Summary ### Major Changes - **Field Reorganization**: Reorganized folder dialog to prioritize key fields in the basic tab: - **Name (URL)** - Primary field, URL-friendly slug (first field, autofocused) - **Navigation Title** - Display name for menus (auto-generated from name) - **Path** - Read-only path preview - Advanced fields moved to Advanced tab (sort order, file extensions, default file type) - **Auto-generation Logic Reversal**: Changed from title→name to name→title - Previously: User enters title, name (URL) auto-generated as slug - Now: User enters name (URL), navigation title auto-capitalizes with proper formatting - Navigation title only auto-generates when not manually edited (respects dirty state) - Conversion: `my-folder-name` → `My Folder Name` ### Bug Fixes - **Dialog Context Fix**: Fixed folder dialog not opening in correct folder by adding null safety to slug generation - **Path Preview**: Added null/empty/whitespace handling for path generation, shows hostname when name is empty ### Accessibility - **Context Menu Focus**: Changed from `:focus` to `:focus-visible` for better keyboard navigation - Prevents unwanted focus ring on mouse clicks - Shows focus ring only during keyboard navigation ### Performance & Caching - **Memoization Fix**: Fixed context menu caching to use correct keys - Folders: Use `identifier` as cache key - Contentlets: Use `inode` as cache key - Prevents incorrect menu display when switching between folders and files ### UI/UX Improvements - **Dialog Height**: Reduced max-height from 30rem to 24rem to better fit reorganized content - **Field Labels**: Updated "Title" to "Navigation Title" for better clarity - **Table Header**: Changed column header from "title" to "name" for consistency 🤖 Generated with [Claude Code](https://claude.com/claude-code)
…eb components (#34078) ### Proposed Changes This pull request introduces a new, unified API for interacting with form fields across both Angular and Dojo form bridges, and adds support for a rendered value in content type fields. It also enhances the custom field UI with modal and inline iframe display options, and updates the models and services to support these features. ### Form Bridge API Enhancements * Added the `FormFieldAPI` interface to provide a consistent set of methods (`getValue`, `setValue`, `onChange`, `enable`, `disable`, `show`, `hide`) for interacting with individual form fields. Both `AngularFormBridge` and `DojoFormBridge` now implement the new `getField(fieldId)` method, making field manipulation easier and more standardized. [[1]](diffhunk://#diff-ce753b47e2efc0c67e1d72f1710d3e4bba7014ff5c9f758c3bf588857dc3256bR3-R45) [[2]](diffhunk://#diff-ce753b47e2efc0c67e1d72f1710d3e4bba7014ff5c9f758c3bf588857dc3256bR74-R81) [[3]](diffhunk://#diff-08b7f2dbb6ec1f4033d7a5801c7f63b080a8f9565b11c3f9b7c40ea512578e6fR178-R237) [[4]](diffhunk://#diff-fe3a388c08be205717a8a85cc52f63bf2b3aacac655960871dc86e0276987e09R197-R273) * Updated imports and usage to include the new `FormFieldAPI` type in the bridge implementations. [[1]](diffhunk://#diff-08b7f2dbb6ec1f4033d7a5801c7f63b080a8f9565b11c3f9b7c40ea512578e6fR8) [[2]](diffhunk://#diff-fe3a388c08be205717a8a85cc52f63bf2b3aacac655960871dc86e0276987e09L1-R1) ### Content Type Field Model and Service Updates * Added a new `rendered` property to both `ContentTypeCustomField` and `DotCMSContentTypeField` interfaces to support storing rendered field values. [[1]](diffhunk://#diff-f992fe94678442e33dc4933224e4efd6fcd0dfb04e02a18bc57eebe90da91ff0R318) [[2]](diffhunk://#diff-f992fe94678442e33dc4933224e4efd6fcd0dfb04e02a18bc57eebe90da91ff0R568) * Added a new service method `getContentTypeWithRender(idOrVar)` in `DotContentTypeService` to fetch content types with rendered values via a new API endpoint. ### UI Improvements for Custom Fields * Implemented a new UI for legacy custom fields, supporting both inline iframe and modal dialog display modes based on field configuration. This improves usability for fields requiring external or embedded content. * Added corresponding SCSS styles for the new custom field UI, including modal, fullscreen, and disabled input states. ### Miscellaneous Fixes * Updated field merging logic in the drop zone component to use spread syntax, ensuring a safer and more predictable merge of field properties. * Improved handling of field variables in the properties form component to preserve existing variable data when updating the new render mode. ### Checklist - [x] Tests - [x] Translations - [x] Security Implications Contemplated (add notes if applicable) ### Additional Info ** any additional useful context or info **
### Proposed Changes
Below are the classes modified that allow the PageAPI to **save
Content** with styleProperties within a container in a page.
* `PageContainerForm.java`
- [ ] Added `stylePropertiesMap` field to `ContainerEntry`
- [ ] Updated constructors to support `stylePropertiesMap`
- [ ] Added getter/setter methods
- [ ] Enhanced JSON deserializer to parse `styleProperties` with
multi-type support (string, number, boolean)
* `PageResourceHelper.java`
- [ ] Modified `saveContent()` method to extract `stylePropertiesMap`
from containerEntry.
* `PageResource.java`
- [ ] Fixed `reduce()` method to preserve `stylePropertiesMap` during
container entry consolidation, if the key is repeated the styles are
overwrite with the last entry evaluated.
- [ ] Created `ContainerData` helper class to hold both `contentIds` and
`stylePropertiesMap`.
* `PageResourceTest.java`
- [ ] Added comprehensive integration test
`test_addContent_with_styleProperties()`
- [ ] Added deserialized test when passing a string.
* `PageResourceTest.json`
- [ ] Include test when style properties are send.
* `resources/PageResourceTest.json`
- [ ] Delete repeated postman tests already present in
`PageResourceTest.json`
This PR fixes: #33695
### Proposed Changes
This pull request introduces several improvements and refactors across
multiple Angular applications in the monorepo, focusing on standardizing
configuration, improving error handling patterns, and minor
dependency/configuration cleanups. The most notable changes are grouped
as follows:
**1. Standardization of RxJS Error Handling:**
- Refactored all usages of the `tapResponse` operator to use the
object-based signature (`{ next, error }`) instead of positional
arguments, improving code readability and aligning with best practices.
This was done in files such as `dotcdn.component.store.ts`,
`dot-pages.store.ts`, and `dot-template.store.ts`.
[[1]](diffhunk://#diff-b202dfd3e850f6f8d29a81e0f698f305309a1d524fcb089138c0eed4f0b0e2d0L95-R117)
[[2]](diffhunk://#diff-1145b6e61f8f24833b827ae5f3fe939586964551b15aab913ba530cd44808f0eL364-R365)
[[3]](diffhunk://#diff-1145b6e61f8f24833b827ae5f3fe939586964551b15aab913ba530cd44808f0eL377-R380)
[[4]](diffhunk://#diff-1145b6e61f8f24833b827ae5f3fe939586964551b15aab913ba530cd44808f0eL789-R804)
[[5]](diffhunk://#diff-1145b6e61f8f24833b827ae5f3fe939586964551b15aab913ba530cd44808f0eL838-R843)
[[6]](diffhunk://#diff-1145b6e61f8f24833b827ae5f3fe939586964551b15aab913ba530cd44808f0eL861-R867)
[[7]](diffhunk://#diff-1145b6e61f8f24833b827ae5f3fe939586964551b15aab913ba530cd44808f0eL892-R893)
[[8]](diffhunk://#diff-1145b6e61f8f24833b827ae5f3fe939586964551b15aab913ba530cd44808f0eL905-R907)
[[9]](diffhunk://#diff-7cdbc60fb309458c9c97919670ee9f2700e6f97077360d7b2c60be5d8915f1eaL164-R178)
**2. Project Configuration Updates:**
- Added or updated `"tags"` fields (often to empty arrays or with
specific tags like `["skip:test", "skip:lint"]`) in multiple
`project.json` files for better project categorization and tooling
compatibility.
[[1]](diffhunk://#diff-b9f5cc7169c5770b5a2f040c8662568055bb427d78d3de5863f18368983602b3R7)
[[2]](diffhunk://#diff-7bb84e18c1e3ac80aed41afaa0693a7c4224324e222c2ed95f1cec1525903f35R7)
[[3]](diffhunk://#diff-5ee971cb1c993c2ebd054104878f6077f83bdc3191e9297c79086deda2f909e0R7)
[[4]](diffhunk://#diff-a5a7709ae811f21c30177ca89ea61196bd970f2695ce9a24aee461b0e792dfa8R7-R8)
- Added `"continuous": true` to several `serve` targets, likely to
enable continuous build/watch mode for development servers.
[[1]](diffhunk://#diff-b9f5cc7169c5770b5a2f040c8662568055bb427d78d3de5863f18368983602b3L76-R78)
[[2]](diffhunk://#diff-7bb84e18c1e3ac80aed41afaa0693a7c4224324e222c2ed95f1cec1525903f35L87-R89)
[[3]](diffhunk://#diff-5ee971cb1c993c2ebd054104878f6077f83bdc3191e9297c79086deda2f909e0L101-R103)
[[4]](diffhunk://#diff-a5a7709ae811f21c30177ca89ea61196bd970f2695ce9a24aee461b0e792dfa8L129-R132)
- Set `"tsConfig"` options for test targets to explicitly point to the
correct TypeScript configuration files, improving test setup
reliability.
[[1]](diffhunk://#diff-b9f5cc7169c5770b5a2f040c8662568055bb427d78d3de5863f18368983602b3L104-L108)
[[2]](diffhunk://#diff-7bb84e18c1e3ac80aed41afaa0693a7c4224324e222c2ed95f1cec1525903f35L103-L107)
[[3]](diffhunk://#diff-a5a7709ae811f21c30177ca89ea61196bd970f2695ce9a24aee461b0e792dfa8L146-R150)
**3. TypeScript Compiler Configuration Improvements:**
- Added `"moduleResolution": "bundler"` to various `tsconfig.app.json`
and `tsconfig.spec.json` files, aligning module resolution with modern
build tools and improving compatibility.
[[1]](diffhunk://#diff-f471e0ae31ecc282b2a482daebb1c09198820853e891ab8f914631c22d498b71L7-R8)
[[2]](diffhunk://#diff-d90cd0ce74ab8203ec196742db3429152e143bec6bd4db856a092509e2e72d83L5-R6)
[[3]](diffhunk://#diff-28e86d8c2042724ba496375177c06ec7b815d0e70cdebdd469312e2f959d4d3cL7-R8)
[[4]](diffhunk://#diff-92c379b3c88f28b0ae55d4b1ad62ee3936e66e2bd02867ec58d1087989de4410L7-R8)
**4. Dependency and Import Cleanups:**
- Removed unused imports (e.g., `DynamicDialogRef` in
`dot-template-create-edit.component.ts`) and simplified type usage for
dialog references.
[[1]](diffhunk://#diff-65fc5701762b720a1b4fd8afbbf0b8a0ee54827d1b9fe386f5ffc314058ce099L14)
[[2]](diffhunk://#diff-65fc5701762b720a1b4fd8afbbf0b8a0ee54827d1b9fe386f5ffc314058ce099L184-R183)
**5. Minor Project Metadata Adjustments:**
- Updated or added `implicitDependencies` fields and cleaned up
redundant or misplaced `tags` arrays in project configuration files.
[[1]](diffhunk://#diff-a5a7709ae811f21c30177ca89ea61196bd970f2695ce9a24aee461b0e792dfa8R7-R8)
[[2]](diffhunk://#diff-a5a7709ae811f21c30177ca89ea61196bd970f2695ce9a24aee461b0e792dfa8L178-R182)
[[3]](diffhunk://#diff-5ee971cb1c993c2ebd054104878f6077f83bdc3191e9297c79086deda2f909e0L125-R127)
These changes collectively improve code maintainability, developer
experience, and build/test reliability across the workspace.
### Checklist
- [x] Tests
- [x] Translations
- [x] Security Implications Contemplated (add notes if applicable)
This PR fixes: #34087
---------
Co-authored-by: Freddy Montes <751424+fmontes@users.noreply.github.com>
### Proposed Changes * Add `rel="noreferrer noopener"` when we open a blank page via the frontend editor, for now it only affects the **copy URL** functionality of the "Page Edit Mode". This PR fixes: #33898
…rectly (#34086) ### Proposed Changes Update SDK examples (Next.js, Angular, Astro) adding styles and retrieve the contentlet information by using. ```ts props.node.attrs?.data ``` ### Changes made - [ ] Added styles to the custom render Activities, Products. - [ ] Create a custom render for Destinations - [ ] update `props.attrs?.data` data to `props.node.attrs?.data` where need it. This PR fixes: #34061
…es (#34095) ## Summary - Fixed pagination offset synchronization issues when navigating folders and applying filters - Resolved UI layout jumps caused by inconsistent table column widths and loading states - Improved search input state management to properly sync with global filters - Fixed PrimeNG Table pagination state management to prevent offset loss during sorting ## Changes ### Pagination & State Management - **DotContentDriveStore**: Enhanced `setPath()`, `removeFilter()`, and `setGlobalSearch()` methods to properly reset pagination offset to 0 when navigating or filtering - **Shell Component**: Added computed `$offset` signal and improved query params handling with merge strategy to maintain URL state correctly - **Folder List View**: Removed local `currentPageFirstRowIndex` state in favor of store-managed offset for single source of truth ### UI Layout Fixes - **Table Layout**: Applied `table-layout: fixed` to prevent column width recalculation causing UI jumps - **Column Widths**: Adjusted header column widths (32% for title, 18% for modified date) for better layout stability - **Loading Skeletons**: Fixed skeleton placeholder widths to match actual column dimensions and prevent layout shifts during loading states - **Title Column**: Implemented CSS grid layout (4.5rem thumbnail + flexible text + min-content actions) for consistent alignment ### Search & Filter Synchronization - **Search Input Component**: Added `cleanTextEffect` to sync form control value with store filter changes without triggering unnecessary events - **Query Params**: Implemented proper `queryParamsHandling: 'merge'` strategy to preserve URL state during navigation ### PrimeNG Table Workaround - **FirstChange Handler**: Added `onFirstChange()` method to manually sync table's `first` property with offset from store, addressing PrimeNG issue #11898 where table loses pagination reference during sorting operations ## Test Coverage - ✅ Added tests for `setGlobalSearch()` pagination reset behavior - ✅ Added tests for `removeFilter()` pagination reset behavior - ✅ Added tests for `setPath()` pagination reset behavior - ✅ Updated shell component tests for new query params merge strategy - ✅ Added tests for offset input and firstChange synchronization ## Test Plan - [ ] Navigate through multiple folders and verify pagination stays at page 1 - [ ] Apply filters and verify pagination resets to first page - [ ] Use global search and verify pagination and path reset correctly - [ ] Remove filters and verify pagination resets - [ ] Sort columns and verify pagination offset is maintained correctly - [ ] Verify no UI layout jumps during loading states or data updates - [ ] Test with various amounts of content (empty, partial page, multiple pages) 🤖 Generated with [Claude Code](https://claude.com/claude-code) This PR fixes: #33991
…34675) ## Description Fixes the auto-labeling bug where the `area_cicd` filter incorrectly applied "Area : CI/CD" label to PRs with **no `.github/` changes**. This was caused by a known bug in `dorny/paths-filter` where negation patterns use OR logic instead of AND logic. ### Root Cause The original filter used separate negation patterns: ```yaml area_cicd: - '.github/**' - '!.github/ISSUE_TEMPLATE/**' - '!.github/**/*.md' ``` Due to OR logic in dorny/paths-filter, the negation `'!.github/**/*.md'` matched **any file NOT a markdown file in .github/**, which includes ALL files in `core-web/`, `dotCMS/`, etc. Example from workflow run 22088029961: - Changed files: `core-web/apps/dotcms-ui/src/.../onboarding-author.component.html` - Filter result: `area_cicd = true` ❌ (WRONG - no .github/ changes!) ### Solution Replace negation patterns with explicit positive patterns only: ```yaml area_cicd: - '.github/workflows/**' # All workflow files - '.github/actions/**' # All custom actions - '.github/filters.yaml' # CI/CD config - '.github/area-labels.yml' # PR labeling config - '.github/test-matrix.yml' # Test matrix config ``` **Hybrid Approach:** - ✅ Wildcards for directories with many files (workflows/, actions/) - ✅ Explicit paths for individual config files - ✅ No negation patterns (avoids dorny/paths-filter bug) - ✅ Self-documenting (what's NOT listed is intentionally excluded) ## Changes - [x] Updated `area_cicd` filter to use explicit positive patterns only - [x] Added comprehensive documentation explaining the negation bug - [x] Documented what files are intentionally excluded (ISSUE_TEMPLATE/, data/, *.md, etc.) - [x] Referenced upstream bug reports (dorny/paths-filter #97, #184) ## Testing - [x] Verified filter syntax is valid YAML - [x] Confirmed patterns match intended files (workflows, actions, config) - [x] Verified excluded patterns (templates, docs, data files) - [ ] **Requires validation**: Create test PR with frontend-only changes to verify label is NOT applied - [ ] **Requires validation**: Create test PR with workflow changes to verify label IS applied ## Additional Context **Upstream Bug Reports:** - dorny/paths-filter#97 - dorny/paths-filter#184 **Follow-up Work:** - Issue #34673 created for larger filter refactoring with consistent naming convention Closes #34669 --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
…iage label (#34678) ## Summary - Removed `[TASK]`, `[DEFECT]`, `[FEATURE]`, `[SPIKE]`, `[EPIC]`, and `[PILLAR]` bracket prefixes from issue template title fields - Removed `Triage` label from `task.yaml` and `defect.yaml` templates ## Test plan - [ ] Verify each issue template no longer pre-fills the title with bracket prefixes - [ ] Verify `Triage` label is no longer automatically applied to new Task or Defect issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Will Ezell <will@dotcms.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
#34688) ## Summary - Remove `title: ""` from all 6 issue form templates — GitHub's form parser silently drops templates with an empty string `title`, causing none to appear in the issue chooser UI - Fix `spike.yaml`'s `labels: [""]` (invalid empty-string label) to `labels: []` ## Root Cause PR #34678 changed `title: "[LABEL] "` to `title: ""` across all templates. While the intent was to remove the bracket prefixes, setting the field to an empty string causes GitHub to silently reject those templates instead of just leaving the title blank. The fix is to omit the `title` key entirely. ## Test plan - [ ] Go to https://github.com/dotCMS/core/issues/new/choose and verify all templates (Task, Defect, Feature, Spike, EPIC, Pillar) appear in the chooser - [ ] Open each template and confirm the title field starts empty 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…#34664) ## Description Add support for parallel Java version builds during releases with automatic workflow triggering and new manual deployment workflow with safety checks. ## Changes - [x] New cicd_7-release-java-variant.yml workflow for automatic parallel Java builds - [x] Runtime -Dchangelist override in release phase for Maven versioning - [x] Conditional operations skip one-time tasks (javadocs, plugins, labels, SBOM) for variants - [x] New cicd_8-manual-deploy.yml workflow for on-demand Docker deployments - [x] Safety checks prevent artifact collision with release versions - [x] Separate environment (GitHub UI grouping) and version (artifact naming) inputs - [x] Deprecation notices added to legacy workflows with migration guide - [x] LEGACY_WORKFLOW_MIGRATION.md documents transition plan ## Architecture Both primary and variant workflows run in parallel from the same release branch and commit, ensuring identical source code. The variant workflow uses runtime Maven property precedence to override -Dchangelist without creating separate branches. ## Testing - [x] Actionlint validation passes for all workflows - [x] Shellcheck validation passes with documented safety exclusions - [x] Safety checks validate artifact namespace separation - [x] Documented test cases for manual deploy workflow scenarios ## Changes - [ ] [List the main changes made] ## Testing - [ ] [Describe testing approach] Closes #34637 **Issue:** [TASK] Add release workflow support for parallel J --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: Steve Freudenthaler <31257998+sfreudenthaler@users.noreply.github.com>
## Summary Disable all analytics initialization and tracking when running inside the DotCMS Universal Visual Editor (UVE) to eliminate unnecessary overhead (observers, listeners, DOM scanning, network requests) and prevent interference with the editor. ## Changes Made ### Frontend (SDK Analytics) **Core - Single entry point guard:** - Added early `getUVEState()` check in `initializeContentAnalytics()` that returns `null` before any plugin is created (`dot-analytics.content.ts:58-66`) - This prevents initialization of **all** plugins (Identity, Click, Impression, Enricher, Main), event queues, observers, listeners, and network requests - Sets `__dotAnalyticsActive__` window flag to `false` when inside UVE **Impression Tracker - Removed redundant check:** - Removed `getUVEState()` check and `@dotcms/uve` import from `DotCMSImpressionTracker.initialize()` (`dot-analytics.impression-tracker.ts`) — no longer needed since the entire system is disabled upstream **React Hook (`useContentAnalytics`) - Graceful degradation:** - Replaced `throw new Error()` with no-op analytics functions (`NOOP_ANALYTICS`) when instance is `null`, preventing app crashes inside UVE - Moved warning/error logging inside `useMemo` so it fires once (not on every re-render) - Distinguishes between UVE context (warns) and config errors (errors) in console messages - Removed redundant per-method `isInUVE` checks from `track()`, `pageView()`, and `conversion()` callbacks **Router Tracker (`useRouterTracker`) - Cleanup:** - Removed redundant `getUVEState()` check and `@dotcms/uve` import — the `if (!analytics) return` guard already handles the null instance from UVE ### Tests - Added test: `initializeContentAnalytics` returns `null` and skips all plugins when inside UVE editor - Added test: `useContentAnalytics` returns no-op functions and warns when inside UVE - Added test: `useContentAnalytics` logs error when initialization fails outside UVE (config error) - Removed test: `DotCMSImpressionTracker` UVE editor mode check (moved upstream) - Removed tests: per-method UVE skip checks in `useContentAnalytics` (no longer needed) ## Technical Details Previously, only the Impression Tracker checked for UVE state — all other plugins (Activity Tracker, Click Tracker, Identity, Queue, Enricher) still initialized fully inside the editor, attaching MutationObservers, IntersectionObservers, click listeners, DOM scanning, and session management. The fix centralizes the UVE check at the single entry point (`initializeContentAnalytics`), ensuring zero analytics code runs inside UVE regardless of mode (edit, preview, or live). ## Breaking Changes - `useContentAnalytics` no longer throws when analytics fails to initialize — it returns no-op functions instead. This is intentionally less strict to support the UVE use case without crashing React apps. Config errors are now logged via `console.error` rather than thrown. ## Testing - [x] Unit tests added/updated - [ ] Integration tests added/updated - [x] Manual testing performed - [ ] E2E tests added/updated (if applicable) ## Related Issues Closes #34618
…34680) ## Summary - Enable `change-detection: 'enabled'` in merge queue workflow to match PR workflow behavior - Frontend-only changes will now skip integration, postman, and karate tests in merge queue - Reduces merge queue time for frontend PRs from ~45 minutes to ~10-15 minutes ## Test plan - [ ] Verify merge queue workflow runs path-based filtering for frontend-only PRs - [ ] Verify backend/mixed changes still run full test suite - [ ] Confirm workflow summary shows correct "Build & Test Matrix" filtering ## References - ADR-0013: dotCMS/platform-adrs#53 - Related discussion: PR #34622 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
… (#34676) ## Description Add core-web/.yarnrc to configure BunnyCDN as the npm registry, update yarn.lock to replace all 3,279 registry.yarnpkg.com resolved URLs with dotcms-npm.b-cdn.net so --frozen-lockfile uses CDN URLs from the lockfile, and remove the now-redundant pom.xml registry execution block that was ineffective due to --frozen-lockfile bypassing runtime registry config. ## Changes - [ ] [List the main changes made] ## Testing - [ ] [Describe testing approach] Closes #34619 **Issue:** Registry configuration mismatch yarn.lock uses pub Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
…r messages (#34646) (#34653) ## Summary Fixes the UVE Personalization error handling which was only showing one generic error message ("Personalization requires page content. Add some first"), making it extremely difficult to debug when different errors occurred. ### Changes - **Enhanced error extraction**: Added `#getPersonalizeErrorDetail()` method to extract meaningful error messages from `HttpErrorResponse` - **Multi-source error detection**: - First checks `error-message` header for backend messages - Falls back to parsing error body (extracts message after colon prefix) - Returns `null` to use generic i18n message only when no specific error available - **Comprehensive test coverage**: Added 3 test cases covering: - Error from `error-message` header - Error from response body with colon prefix - Error from response body without prefix ### Why this matters Previously, any Personalization creation error would only display "Personalization requires page content. Add some first", regardless of the actual problem. This made debugging: - Backend validation errors - Missing persona errors - Network failures - API parameter issues Nearly impossible to troubleshoot without checking browser console or backend logs. ### Example errors now properly shown: - ✅ "Does not exists a Persona with the tag: nonexistent-persona" - ✅ "Page parameter is missing" - ✅ "Something went wrong" (generic backend errors) - ✅ Falls back to i18n message only when no backend error available ## Test plan - [x] Added test for error-message header extraction - [x] Added test for body error with colon prefix parsing - [x] Added test for body error without prefix - [x] All unit tests passing - [x] Pre-commit hooks (lint, format, SDK build) passed - [ ] Manual testing: Trigger various Personalization errors and verify correct messages displayed ## Related Issue Fixes #34646 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
## Why Triage meetings: 30 minutes, Will, Marc and I, mostly mechanical work. Reading issues, searching duplicates, figuring out code ownership, deciding priority. This PR replaces that with an AI agent pipeline. Under a minute, human approves or rejects. Triage output is a technical briefing (entry point, call chain, files, test commands) so a coding agent can pick up the issue directly. Triage becomes the handoff between "problem reported" and "agent working on it." ## Demo https://github.com/user-attachments/assets/843b0c8d-ae91-4bfb-b6da-cdff7c642e55 ## What this adds - `/triage` skill for Claude Code: four AI agents validate, deduplicate, research, and route issues - GitHub Action: auto-adds unowned issues to the AI Triage Pipeline project board - Team routing config (`.claude/triage-config.json`): maps file ownership via git blame Nothing is written to GitHub without human approval. ## How it works 1. `/triage --issue 1234` or `/triage` for next in queue 2. Three agents run in parallel: validation, duplicate detection, codebase research 3. Team-router runs after researcher finishes (`blockedBy` dependency) 4. Agents report back, shut down, team is deleted 5. Proposal shown: team, priority, complexity, AI confidence, full comment preview 6. Approve: labels, comment, project card set. Reject: nothing happens ## Queue filters No assignee, no `Team :` label, no parent issue, no linked PR, type is `Bug` or `Task`. ## Test plan - [ ] `/triage --issue <number>` on a real open issue - [ ] 3 agents parallel, team-router waits for code-researcher - [ ] Proposal shown before anything posts - [ ] Approve: comment, labels, project card all set - [ ] `/triage` (no args) skips issues with linked PR - [ ] GitHub Action triggers on new issue, adds to project board ## Setup - `TRIAGE_PROJECT_TOKEN` secret: fine-grained PAT with `issues` write + `project` write - `TRIAGE_PROJECT_NUMBER` variable: already set to `41` --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
### Context The `FileMetadataAPIImpl.internalGetGenerateMetadata()` method was failing to retrieve metadata for binary fields when **indexed: false**. The original implementation only checked getFullMetadataMap(), which is only populated for indexed binary fields. This caused: - NullPointerException when calling Map.of() with null values - 500 error on file upload API endpoints ### Proposed Changes This fix ensures that binary field metadata is consistently available regardless of the indexed field setting, maintaining backward compatibility while preventing breaking changes from content type configuration updates. ### Files Modified - [ ] `FileMetadataAPIImpl.java` Tries to load fullMetadataMap first (indexed fields), then falls back to basicMetadataMap (non-indexed fields). Do a log error if metadata generation fails. - [ ] `WebAssets.postman_collection.json` Test file upload without indexing binary field, add parent authentication for all request and format code. - [ ] `FileAsset.java` Change in the map the possible null values for "unknown" This PR fixes: #34533
…34686) ## Description Remove unused list-files: 'escape' option from dorny/paths-filter in Initialize Phase workflow. This option generates file list outputs that are never used, but cause 'Argument list too long' failures on PRs with 1800+ changed files. ## Changes - [ ] [List the main changes made] ## Testing - [ ] [Describe testing approach] Closes #34683 **Issue:** [TASK] Remove unused listfiles option from pathsfi Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
…4322 (#34415) Add bulk delete publishing jobs by status endpoint Changes: - Add IN_PROGRESS_STATUSES and SAFE_PURGE_STATUSES constants to helper - Add isInProgressStatus() and getInProgressStatuses() validation methods - Add ResponseEntityPurgeView for Swagger documentation - Add 7 integration tests for purge endpoint validation ### Checklist - [ ] Tests - [ ] Translations - [ ] Security Implications Contemplated (add notes if applicable) ### Additional Info ** any additional useful context or info ** ### Screenshots Original | Updated :-------------------------:|:-------------------------: ** original screenshot ** | ** updated screenshot ** This PR fixes: #34322 --------- Co-authored-by: Freddy Montes <freddymontes@gmail.com>
…34667) <img width="2770" height="1368" alt="CleanShot 2026-02-19 at 09 27 33@2x" src="https://github.com/user-attachments/assets/5c397338-d773-48e3-bd18-3a28b00ea312" /> ### Proposed Changes Implements `$googleAnalytics` ViewTool for explicit GA4 tracking code placement in Velocity templates. Replaces auto-injection approach after feedback that it produced "bad results." * Created `GoogleAnalyticsTool` ViewTool with function-style API * `trackingCode()` - uses site's `googleAnalytics` field * `trackingCode(String customId)` - overrides with custom tracking ID * `getTrackingId()` - returns configured tracking ID * Registered in `toolbox.xml` as request-scoped tool * Removed unused `GoogleAnalyticsWebInterceptor` and auto-inject registration from `InterceptorFilter` **Usage:** ```velocity ## Basic - site configuration $googleAnalytics.trackingCode() ## Custom tracking ID (multi-environment/multi-tenant) #if($config.get("ENVIRONMENT") == "production") $googleAnalytics.trackingCode("G-PROD12345") #else $googleAnalytics.trackingCode("G-DEV890") #end ``` **Generated output:** ```html <!-- Google tag (gtag.js) --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-ABC123XYZ"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-ABC123XYZ'); </script> ``` ### Checklist - [x] Tests (21 unit tests: site config, custom IDs, null/empty fallback, backward compatibility) - [ ] Translations (N/A - no user-facing strings) - [x] Security Implications Contemplated * Tracking ID from database, not user input (no XSS risk) * Enables consent-based conditional rendering for GDPR compliance ### Additional Info **Implementation notes:** * Method overloading: `trackingCode()` and `trackingCode(String)` for optional parameter * Falls back to site config if custom ID is null/empty * Deprecated `getTrackingCode()` for backward compatibility * All documentation in source JavaDoc (temporary markdown docs removed) **Benefits over auto-injection:** * Developer control over placement * Conditional inclusion for consent management * No HTML parsing overhead * Multi-environment and multi-tenant support via custom IDs ### Screenshots N/A - Backend feature, no UI changes <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> ---- *This section details on the original issue you should resolve* <issue_title>Implement Google Analytics tracking code injection for sites</issue_title> <issue_description>## Description The `googleAnalytics` field exists in dotCMS sites (Host content type) but is currently only used for storage. The field is exposed via the REST API (`SiteResource`, `SiteForm`, `SiteView`) but has no functional implementation to automatically inject Google Analytics tracking codes into pages. **Current State:** - Field defined in `SiteResource.GOOGLE_ANALYTICS` constant - Stored and retrieved via REST API endpoints - No automatic injection into page templates or HTML output - No Velocity/VTL template usage found - Users must manually implement GA tracking if they want to use this field **Proposed Implementation:** Automatically inject Google Analytics (GA4) tracking code into pages when the `googleAnalytics` field is populated on a site. ## Acceptance Criteria - [ ] Read `googleAnalytics` field value from current site/host context - [ ] Automatically inject GA4 tracking code into page `<head>` when field is populated - [ ] Support both Universal Analytics (UA) and GA4 tracking ID formats - [ ] Provide configuration option to disable auto-injection if needed - [ ] Make tracking code available in Velocity context (e.g., \$site.googleAnalytics) - [ ] Update documentation on how to use the Google Analytics field - [ ] Add integration tests for GA code injection - [ ] Verify tracking code injection works across different page types (templates, pages, content) ## Additional Context **Related Files:** - `dotCMS/src/main/java/com/dotcms/rest/api/v1/site/SiteResource.java:100` - Field constant - `dotCMS/src/main/java/com/dotcms/rest/api/v1/site/SiteHelper.java:328` - Field mapping - `dotCMS/src/main/java/com/dotcms/rest/api/v1/site/SiteForm.java:33` - Form binding - `dotCMS/src/main/java/com/dotcms/rest/api/v1/site/SiteView.java:28` - API response **Implementation Options:** 1. **Server-side injection**: Intercept HTML output and inject GA script before `</body>` 2. **Template-level**: Provide Velocity macro/variable for manual placement 3. **Hybrid**: Auto-inject by default with option to use manual placement **GA4 Tracking Code Example:** ```html <!-- Google tag (gtag.js) --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-XXXXXXXXXX'); </script> ``` **Considerations:** - Privacy/GDPR compliance (consider consent management integration) - Performance impact of auto-injection - Support for Google Tag Manager as alternative - Backwards compatibility with existing custom implementations</issue_description> <agent_instructions>Make sure you use the environment variable, because some customers might not want this enable by default.</agent_instructions> ## Comments on the Issue (you are @copilot in this section) <comments> <comment_new><author>@fmontes</author><body> ## 🔧 Technical Implementation Details ### Server-Side HTML Generation & Injection Points Based on analysis of the dotCMS codebase, here are the key classes and patterns for implementing Google Analytics tracking code injection: --- ## Key Architecture Components ### 1. **WebInterceptor Pattern** (Recommended Approach) The cleanest implementation would use dotCMS's `WebInterceptor` system, which provides a pluggable way to intercept and modify HTTP responses. **Key Interface:** - `com.dotcms.filters.interceptor.WebInterceptor` - Core interface for request/response interception **Existing Interceptor Examples:** - `com.dotcms.filters.interceptor.meta.ResponseMetaDataWebInterceptor` - Adds headers to responses - `com.dotcms.analytics.track.AnalyticsTrackWebInterceptor` - Injects analytics tracking (perfect reference!) **Registration:** - `com.dotmarketing.filters.InterceptorFilter` - Main filter that manages all web interceptors - Interceptors are registered in the filter chain and execute on every request ### 2. **HTML Page Rendering Pipeline** Where HTML pages are actually rendered and assembled: **Core Rendering Classes:** - `com.dotmarketing.portlets.htmlpageasset.business.render.HTMLPageAssetRenderedAPIImpl` - Main page rendering API - `com.dotmarketing.portlets.htmlpageasset.business.render.page.HTMLPageAssetRenderedBuilder` - Builds page metadata and HTML - `com.dotmarketing.portlets.htmlpageasset.business.render.page.PageView` - Page view object containing rendered HTML ### 3. **Request/Response Flow** Main filter chain entry point: - `com.dotmarketing.filters.CMSFilter` - Primary CMS filter (line 59: `doFilter`) - Gets current site/host context (line 85) - Executes rules engine - Delegates to page rendering --- ## 📋 Recommended Implementation Approach ### Option A: WebInterceptor (Cleanest & Most Maintainable) Create a new class: `com.dotcms... </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes #34665 <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: fmontes <751424+fmontes@users.noreply.github.com> Co-authored-by: Freddy Montes <freddymontes@gmail.com> Co-authored-by: Nollymar Longa <nollymar.longa@dotcms.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This PR fixes: #34585 ### Video https://github.com/user-attachments/assets/3483a7d7-6e2e-4a28-9cd5-92d60461628b --------- Co-authored-by: Kevin <kevin.davila@dotcms.com>
## Summary - Fixed undefined variant parameter issue in UVE page properties by using the correct `$variantId` signal instead of accessing `variantName` from `pageParams` - Updated all variant references in `DotEmaDialogStore` to use the dedicated `$variantId()` signal from UVEStore - Updated test mocks to include the `$variantId` signal for consistency ## Changes - **dot-ema-dialog.store.ts**: Replaced 4 instances of `this.uveStore.pageParams().variantName` with `this.uveStore.$variantId()` - **dot-ema-dialog.component.spec.ts**: Added `$variantId` signal to test mock setup - **dot-ema-dialog.store.spec.ts**: Created proper mock UVEStore with both `pageParams` and `$variantId` signals ## Test plan - [x] Verify unit tests pass for dot-ema-dialog component and store - [x] Verify force unlock workflow action properly uses variant ID - [ ] Manual testing: Open UVE page properties and trigger force unlock action - [ ] Manual testing: Verify variant parameter is correctly passed in all EMA dialog actions (create contentlet, edit layout, content selector, reorder menu) ## Related Issue Fixes #34333 🤖 Generated with [Claude Code](https://claude.com/claude-code)
…#34690) ## Summary Refactors the analytics dashboard by reorganizing components into a domain-driven folder structure (`reports/engagement`, `reports/conversions`, `reports/pageview`, `shared`) and fixes several visual inconsistencies in card styling, typography, and engagement dialog copy. ## Changes Made ### Frontend - **Folder restructure**: Moved all analytics dashboard components from a flat `components/` directory into domain-specific subfolders: - `reports/engagement/` — engagement report and related components - `reports/conversions/` — conversions report, content conversions table, and overview table - `reports/pageview/` — pageview report and top pages table - `shared/` — shared utilities, plugins, directives, chart, metric, filters, and state message components - **Component renames** for consistency (removed `dashboard-` prefix): - `dot-analytics-dashboard-chart` → `dot-analytics-chart` - `dot-analytics-dashboard-metrics` → `dot-analytics-metric` - `dot-analytics-dashboard-*-report` → `dot-analytics-*-report` - **Card styling encapsulation**: Moved `border` and `border-radius` overrides on `.p-card` from parent report SCSS into `dot-analytics-chart` and `dot-analytics-platforms-table` directly, so each component owns its visual appearance - **Platforms table**: `dot-analytics-platforms-table` now renders its own title internally instead of relying on the parent template - **Engagement dialog copy**: Updated the "How it's calculated" dialog to reflect the actual session classification rules (duration > 10s, 2+ pageview events, 1+ conversion event), replacing the previous incorrect criteria (scrolling/clicking) - **Import path updates**: Updated
) # Migrate Custom Fields to New Edit Mode and Consolidate Shared Styles ## Summary This PR migrates multiple custom field implementations to the new edit mode architecture, replacing legacy Dojo-based code with modern DOM manipulation and the DotCustomFieldApi framework. Additionally, shared dropdown styles have been extracted and consolidated for reusability across field types. Comprehensive accessibility improvements and code quality fixes have been applied throughout. ## Changes ### Custom Field Migrations #### 1. **Personas KeyTag Field** (`keytag_custom_field`) - **New Implementation**: `keytag_custom_field_new.vtl` - Replaces Dojo framework with native DOM and DotCustomFieldApi - Implements camelCase transformation with proper casing (first letter uppercase, remaining lowercase) - Real-time field validation and synchronization with persona name input - **Legacy Preservation**: `keytag_custom_field_old.vtl` retained for backward compatibility - **Switcher Logic**: `keytag_custom_field.vtl` conditionally routes based on `isNewEditModeEnabled()` #### 2. **File Browser Field** (`file_browser_field_render`) - **New Implementation**: `file_browser_field_render_new.vtl` - Replaces legacy dijit FilteringSelect with native input and DotCustomFieldApi browser modal - Native file/page/folder browser integration - Accessibility improvements: Added `placeholder` for URI input field - **Legacy Preservation**: `file_browser_field_render_old.vtl` retained for backward compatibility - **Switcher Logic**: `file_browser_field_render.vtl` conditionally routes based on `isNewEditModeEnabled()` #### 3. **Tag Storage Field** (`tag_storage_field_creation`) - **New Implementation**: `tag_storage_field_creation_new.vtl` - Replaces legacy dijit dropdown with custom native select component - Null-safe Velocity templating (guards against missing attributes) - **Legacy Preservation**: `tag_storage_field_creation_old.vtl` retained for backward compatibility - **Switcher Logic**: `tag_storage_field_creation.vtl` (FIXED) - Corrected inconsistent #parse directive paths to use leading slash (`/static/...`) for consistency DEMO https://github.com/user-attachments/assets/45a43678-f0a6-4a1e-a849-9ed82ca12180 --------- Co-authored-by: Adrian Molina <adrian.molina@dotcms.com>
…ll + added DEFAULT variantId logic in PageResourceHelper (#34696) ## Summary Moved Multitree validation before copyContentlet call + added DEFAULT variantId logic in PageResourceHelper in case of null/empty values. ## Changes - Changed the validation order in PageResourceHelper.copyContentlet() method. Now we validate the existence of the Multitree before actually copying the Contentlet. - Added a default value for variantId in case the value from the request is null or empty. - Added integration tests. ## Motivation The issue related to this PR shows that we return a 404 when attempting to copy a contentlet and the variantId in the request is empty. To address this, we added logic to set a default value when the variantId is null or empty. Additionally, while investigating this issue, we uncovered another problem. The contentlet was being copied before doing the required validations for the Multitree. So when the Multitree call returned null, the response was still a 404, but the contentlet had already been copied, and the rollback was not being done. This means the bug was not limited to the empty variantId scenario. Any case where the Multitree was null could trigger the same unintended behavior. ## Related Issue Fixes: [BUG: PUT /api/v1/page/copyContent returns 404 but successfully copies content when variantId is empty string #34473](#34473)
- Introduced function to the object in to enhance style editor capabilities. - Updated to include new functionality for handling style editor schemas, improving the overall editing experience. This change supports the integration of style editing features within the UVE framework, aligning with recent enhancements in the editing architecture. https://github.com/user-attachments/assets/7103695e-52d8-422d-ba26-9d452b8ebbaa This PR fixes: #34708
…34699) ## Description Fix the `cicd_8-manual-deploy.yml` workflow that was failing with invalid input parameters, and improve CI/CD infrastructure consistency across all workflows: run-name visibility, Docker image tag architecture, nightly build repeatability and tag ordering, and CLI artifact deployment control. ## Changes ### Bug Fixes (cicd_8 manual deploy) - **Fix invalid inputs**: use `change-detection='disabled'` instead of the invalid `validation-level='none'` - **Make `ref` input optional**: defaults to the dispatch branch, preserving legacy behavior and fixing the concurrency group fallback when `ref` is empty ### Run-Name Improvements (all workflows) - **Add `run-name` to all CI/CD workflows** (`cicd_1` through `cicd_8`) so every run is identifiable in the GitHub Actions UI without opening it - **Fix expression syntax**: switch run-name YAML strings from single-quoted to double-quoted so that GitHub Actions expression parser receives properly single-quoted string literals inside `${{ }}` — fixes `Unexpected symbol: '"' in expression` validation error (cicd_3, cicd_4, cicd_6, cicd_7, cicd_8) - **Always show ref in manual deploy run-name**: fall back to `github.ref_name` when the `ref` input is empty, so the run name is always `Manual [branch-name]` rather than just `Manual` ### Nightly Build Repeatability (cicd_4) - **New `setup` job** that determines the commit to build from before any other jobs run - **Default behavior (scheduled and manual dispatch)**: finds the last commit on `main` at or before midnight UTC. This ensures repeatability — re-running a nightly later in the day to investigate a failure produces the exact same build as the scheduled run. The date tag (`nightly_YYYYMMDD`) labels the day covered (yesterday), not the day the workflow runs. - **New `use-latest-commit` dispatch input**: set to `true` to build from the current `HEAD` of `main` instead, useful when you need to pick up commits made after midnight - **All downstream jobs** (`build`, `deployment`, `finalize`) now depend on `setup` and pass through its `build-ref` and `tag-date` outputs ### Docker Image Tag Architecture (nightly + all builds) - **Redesign tag inputs on `deploy-docker` action**: replace raw `type=raw,value=...,enable=` format strings with semantic `identifier-tag` / `custom-tag` inputs — callers express intent, not bake-meta syntax - **Centralize tag computation**: `Compute Docker Tags` step consolidates all tag logic in clear bash `if/else`, replacing the previous `Compute Docker Base Tag` + scattered `enable=` expressions - **Fix tag ordering**: identifier appears before suffix (`nightly_20250218_java25`, not `nightly_java25_20250218`), consistent with the release pattern - **Retain `extra-tags`** as an escape hatch for advanced cases ### CLI Artifact Deployment Control - **Add `deploy-cli` boolean input** to the deployment phase composite workflow (default: `false`); replaces the previous hardcoded `environment != 'manual'` name check - **Explicit opt-in pattern**: trunk, nightly, and release callers set `deploy-cli: true`; manual deploys omit it and default to `false`, preventing accidental JFrog publishes from feature-branch builds — mirrors the same pattern used by `publish-npm-cli` and `publish-npm-sdk-libs` - **Restore `publish-npm-sdk-libs`** condition to input-only guard (environment hardcoding removed) ### Miscellaneous - **Remove dead code**: `reuse-previous-build` removed from all deployment-phase calls (only meaningful in the initialize phase) - **Remove stale `java_version` default** from `cicd_7-release-java-variant` dispatch input (`'25.0.1-open'` was outdated); update description to reference the `RELEASE_JAVA_VARIANT_VERSION` repository variable used by push-triggered builds ## Files Changed | File | What changed | |------|-------------| | `.github/actions/core-cicd/deployment/deploy-docker/action.yml` | New `identifier-tag`/`custom-tag` inputs; centralized tag computation | | `.github/workflows/cicd_1-pr.yml` | Add `run-name` | | `.github/workflows/cicd_2-merge-queue.yml` | Add `run-name` | | `.github/workflows/cicd_3-trunk.yml` | Add `run-name` (fixed quotes); add `deploy-cli: true` | | `.github/workflows/cicd_4-nightly.yml` | Add `setup` job for commit pinning; add `use-latest-commit` input; add `run-name` (fixed quotes); fix tag ordering; add `deploy-cli: true` | | `.github/workflows/cicd_6-release.yml` | Fix `run-name` quotes; add `deploy-cli: true` | | `.github/workflows/cicd_7-release-java-variant.yml` | Fix `run-name` quotes; remove stale `java_version` default | | `.github/workflows/cicd_8-manual-deploy.yml` | Fix invalid inputs; make `ref` optional; fix `run-name` always shows ref | | `.github/workflows/cicd_comp_deployment-phase.yml` | Add `deploy-cli` input; replace env-name guard with input guard | | `.github/workflows/cicd_comp_initialize-phase.yml` | Minor cleanup | ## Testing - Workflow YAML validates on push (GitHub Actions schema validation) - Manual deploy workflow (`cicd_8`) can be triggered successfully end-to-end - Docker tags produced with correct naming pattern and ordering - `run-name` displays correctly in GitHub Actions UI for all workflow types - CLI artifacts are not published when running manual/feature-branch builds - Nightly default behavior pins to the midnight UTC commit, not current HEAD Closes #34689 **Issue:** [DEFECT] Manual deploy workflow cicd_8manualdeploy --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…4719) Closes #33587 ### Proposed Changes * This PR introduces a new REST endpoint (/api/v1/content/_refresh) that allows manual refresh of a contentlet in the cache and the search index. This is particularly useful for troubleshooting cache-related issues and forcing content reindexing. * A postman test has been included to verify the new endpoint. ### Checklist - [x] Tests --------- Co-authored-by: fabrizzio-dotCMS <fabrizzio@dotCMS.com>
…Release CLI workflow (#34726) (#34727) ## Description `cicd_release-cli.yml` is the dedicated workflow responsible for building the CLI tool and publishing `@dotcms/dotcli` to NPM. It is triggered by GitHub Release creation events and is **separate from** `cicd_6-release.yml` (the main dotCMS product release), which explicitly skips NPM CLI publishing (`publish-npm-cli: false`). A recent change made the `change-detection` input **required** in `cicd_comp_initialize-phase.yml`, but `cicd_release-cli.yml` was not updated to pass it. This caused every GitHub Release event to immediately fail with `startup_failure` before any jobs could execute. > **Note:** Future work may consider integrating the CLI release directly into the main release pipeline (`cicd_6-release.yml`), but this PR is a targeted fix to restore current functionality. ## Changes - Added `with: change-detection: 'disabled'` to the `initialize` job in `cicd_release-cli.yml` - `disabled` is the correct value here — the CLI release should always run all build/test components unconditionally, with no selective change detection - This is consistent with how the same parameter was applied in the related fix for `cicd_7` and `cicd_8` (#34689) ## Testing To manually trigger the workflow against this branch via the `gh` CLI: ```bash gh workflow run cicd_release-cli.yml \ --repo dotCMS/core \ --ref issue-34726-defect-release-cli-workflow-fails-with \ --field version=v26.02.23-01 \ --field dry-run=false ``` **QA run:** https://github.com/dotCMS/core/actions/runs/22315061235 - This `workflow_dispatch` run against this branch serves as the end-to-end validation for this fix - Merge once this run completes successfully Closes #34726 **Issue:** [DEFECT] Release CLI workflow fails with startup_failure due to missing change-detection parameter Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This pull request introduces several improvements to the behavior of custom fields **Custom field event handling improvements:** * In `keytag_custom_field_new.vtl`, the logic for updating the key tag when the name field changes was replaced with an event listener for the `blur` (focus loss) event on the name input, ensuring the key tag is only derived when the user finishes editing the name. This also aligns with the behavior in related custom fields. **Dropdown and field value initialization:** * In `tag_storage_field_creation_new.vtl`, the dropdown initialization logic was enhanced to better handle cases where a value is already set: if the current value matches an option, that option is marked as selected and the button text is updated accordingly. This ensures that the dropdown correctly reflects the stored value even if the user hasn't interacted with it yet. **Bug fix in field lookup:** * In `file_browser_field_render_new.vtl`, the field lookup was changed from using a template variable to a hardcoded `"forwardTo"` field name, likely fixing a bug where the wrong field was being targeted in the file browser custom field. DEMO https://github.com/user-attachments/assets/1f04a921-704f-4183-a927-ab6c27a679b3
### Proposed Changes
- Add `POST /v1/publishing/push/{bundleId}` endpoint to queue bundles
for publishing
- Support publish, expire, and publishexpire operations with ISO 8601
dates
- Validate environment permissions and return actual processed
environments
- Integration tests
### Checklist
- [ ] Tests
- [ ] Translations
- [ ] Security Implications Contemplated (add notes if applicable)
### Additional Info
** any additional useful context or info **
### Screenshots
Original | Updated
:-------------------------:|:-------------------------:
** original screenshot ** | ** updated screenshot **
This PR fixes: #34323
---------
Co-authored-by: Freddy Montes <freddymontes@gmail.com>
…l in @dotcms/angular (#34297) (#34756) Fixes #34297 ## Summary * Fixed `DotHeadingBlock` to accept `level` as a number or string — the Block Editor serializes heading levels as numbers, causing the `@switch` to always fall through to `@default` and render `<h1>`. * Added a `normalizedLevel` getter that coerces `level` to a string before the switch comparison. * Replaced multiple `<ng-content />` usages inside `@switch` branches with a single `<ng-template #content>` + `*ngTemplateOutlet` to fix Angular's "duplicated ng-content" content projection error. * Added `style` input to `DotHeadingBlock` to accept style attributes from block editor node attrs. * Added unit tests covering numeric `level` handling and heading content rendering. ## Test plan - [ ] Verify headings `h1`–`h6` render with the correct tag when `level` is a number - [ ] Verify heading content (text, marks) is projected correctly inside each heading level - [ ] Run `nx test sdk-angular` — all new and existing tests should pass 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| export async function fetchWithRetry(url: string, retries = 5, delay = 5000) { | ||
| for (let i = 0; i < retries; i++) { | ||
| try { | ||
| return await axios.get(url); |
There was a problem hiding this comment.
High severity and reachable issue identified in your code:
Line 11 has a vulnerable usage of axios, introducing a high severity vulnerability.
ℹ️ Why this is reachable
A reachable issue is a real security risk because your project actually executes the vulnerable code. This issue is reachable because your code uses a certain version of axios.
Affected versions of axios are vulnerable to Improper Check for Unusual or Exceptional Conditions. It fails to correctly validate configuration keys during merging. This allows a crafted proto property to trigger an internal TypeError, causing the application to crash.
To resolve this comment:
Upgrade this dependency to at least version 1.13.5 at core-web/yarn.lock.
💬 Ignore this finding
To ignore this, reply with:
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.
You can view more details on this finding in the Semgrep AppSec Platform here.
…-3-small support #34808 - Bump jtokkit version in bom/application/pom.xml to 1.1.0, which adds encoding registry support for the text-embedding-3-* model family - Update EmbeddingsAPIImpl to call .boxed() on the IntArrayList returned by the new encode() API to obtain a List<Integer> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adding the rag embedding implementation
This PR fixes: #32639