Skip to content

Refactor(UVE): Real-Time Canvas#34173

Merged
zJaaal merged 379 commits intomainfrom
uve-experiment
Apr 14, 2026
Merged

Refactor(UVE): Real-Time Canvas#34173
zJaaal merged 379 commits intomainfrom
uve-experiment

Conversation

@fmontes
Copy link
Copy Markdown
Member

@fmontes fmontes commented Dec 26, 2025

Scope

This summary is based on the branch artifacts available locally in this workspace (not live GitHub PR metadata, which is not accessible from this environment). The changes are centered on UVE store state refactoring in edit-ema.

What Changed

The branch refactors the UVE store architecture from a duplicated state model to a single-source-of-truth model.

1. New computed-signal access layer (withPageAsset)

A new store feature was introduced to expose page asset data through computed signals:

  • $page(), $site(), $containers(), $template(), $layout()
  • $viewAs(), $vanityUrl(), $urlContentMap(), $numberContents()
  • $clientResponse()

This centralizes derived state access and reduces direct dependence on internal response structure.

2. State/API renaming for cleaner semantics

Several store properties and methods were renamed to remove GraphQL-specific wording and better describe intent:

  • graphqlRequest -> requestMetadata
  • graphqlResponse -> pageAssetResponse
  • legacyGraphqlResponse -> legacyResponseFormat
  • setGraphqlResponse() -> setPageAssetResponse()
  • setGraphqlResponseOptimistic() -> setPageAssetResponseOptimistic()
  • rollbackGraphqlResponse() -> rollbackPageAssetResponse()
  • $graphqlWithParams -> $requestWithParams
  • $customGraphqlResponse -> $clientResponse

3. Duplication removed from load/save flows

withLoad and withSave were simplified by removing repeated manual extraction/sync of pageAsset sub-properties.

Instead of repeatedly patching multiple top-level fields, flows now rely on updating pageAssetResponse once and reading via computed signals.

4. Consumer updates

Related consumers were updated to use the new API naming and signals, including:

  • Store features (withLayout, etc.)
  • Services (for example, action handling)
  • Components (for example, editor/style-editor integrations)
  • Tests across affected store/features/components

Why This Matters

Architectural improvements

  • Moves from multiple duplicated state fields to one authoritative source.
  • Removes manual synchronization points that could drift out of sync.
  • Makes API naming implementation-agnostic and easier to maintain.
  • Improves type-safety and readability via explicit computed accessors.

Engineering impact

  • Lower maintenance overhead when pageAsset shape changes.
  • Fewer fragile updates across load/save/consumer code paths.
  • Simpler mocking in tests (less setup of duplicated top-level state).

Reported Quantified Outcomes

From branch docs/changelog:

  • Manual sync points eliminated.
  • Duplicate extraction code removed from load/save paths.
  • 10 computed signals added for page-asset-derived data.
  • Store-related test suite reported as passing (with unrelated failures noted in other areas).

Backward Compatibility and Migration

Current compatibility

The branch indicates no immediate breaking changes for consumers because existing patterns are still tolerated during transition.

Recommended direction

Adopt computed-signal usage in new/updated code:

  • Prefer store.$page() over store.page()
  • Prefer store.$site() over store.site()
  • Continue migrating remaining direct property reads progressively

Future cleanup (planned)

Branch docs mention a later cleanup phase to fully remove deprecated direct-property access patterns once migration is complete.

Risk / Attention Points

  • Broad usage of legacy access patterns means migration should remain incremental.
  • Any consumer still directly tied to old names/patterns is a potential regression point if cleanup phase lands.
  • End-to-end validation of editor workflows should continue through migration phases (loading, saving, style editing, rollback flows).

Quick Takeaway

PR #34173 is primarily an internal architecture refactor that modernizes UVE store state handling: one source of truth, cleaner API names, computed signal access, and reduced duplication in critical load/save paths. It is aimed at maintainability, consistency, and safer future evolution rather than introducing large user-facing behavior changes.

Videos

video-general-walkthrough.mov
content-editing.mov
uve-bookmark.mov
new-animation.mov

@semgrep-code-dotcms-test
Copy link
Copy Markdown

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

  • core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/edit-ema-editor.component.ts
  • core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-zoom-controls/dot-uve-zoom-controls.component.ts
  • core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.ts
  • core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-palette/dot-uve-palette.component.ts
  • core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-palette/components/dot-uve-palette-list/dot-uve-palette-list.component.ts
  • core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-palette/components/dot-row-reorder/dot-row-reorder.component.ts
  • core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-iframe/dot-uve-iframe.component.ts
  • core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-contentlet-quick-edit/dot-uve-contentlet-quick-edit.component.ts
  • core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.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 20.3.16 at core/core-web/yarn.lock:512.

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.

This was linked to issues Feb 9, 2026
@fmontes fmontes changed the title UVE experiment UVE Real-Time Canvas Feb 9, 2026
@fmontes fmontes removed a link to an issue Feb 9, 2026
fmontes and others added 19 commits February 13, 2026 07:27
- Moved workflowIsPageLocked computed from withPageContext and withEditor to withWorkflow (single source of truth)
- Moved systemIsLockFeatureEnabled computed from withPageContext to withWorkflow
- Moved lock UI props ($unlockButton, $workflowLockOptions) from withView to withWorkflow
- Merged withLock.ts methods (lockPage, unlockPage, workflowToggleLock) into withWorkflow
- Deleted withLock.ts file (fully consolidated)
- Updated store composition: withWorkflow now comes before withPageContext
- Fixed circular dependency with optional pageReload parameter
- Removed duplicate lock computeds from withPageContext and withEditor
- Updated withEditor to use WorkflowComputed interface from withWorkflow
- Removed workflowIsPageLocked from withView dependencies
- Fixed import ordering in withWorkflow.ts, withWorkflow.spec.ts, wihtLayout.spec.ts
- Removed unused UVE_STATUS, ToggleLockOptions, UnlockOptions imports from withView.ts

This eliminates duplicate lock logic across 4 features (withPageContext, withEditor, withView, withLock) and consolidates all lock concerns in a single place.
- Fixed circular dependency between withWorkflow and withLoad by accessing pageReload directly from store at runtime using (store as any).pageReload?.()
- Removed WithWorkflowDeps.pageReload parameter to avoid compile-time type errors
- Added canLock property to ToggleLockOptions interface (was missing after consolidation)
- Updated $workflowLockOptions computed to include canLock: page.canLock ?? false
- Build now succeeds with no TypeScript errors

This fixes the TypeScript compilation errors introduced in Phase 6.2.
- Moved all page-related computeds from withPageContext to withClient
  - pageLanguageId, pageLanguage, pageURI, pageVariantId
  - pageTranslateProps, pageFriendlyParams
- Moved viewMode to withView (proper domain ownership)
- Removed duplicate viewMode from withEditor
- Updated PageAssetComputed interface with merged properties
- Deleted withPageContext.ts (87 lines eliminated)
- Removed withPageContext from store composition
- Updated withView to use PageAssetComputed props (removed deps parameter)
- Updated withEditor to use ViewComputed interface for viewMode
- Fixed circular references by using local computed values

This consolidates all page-related computeds in one place (withClient) and eliminates duplication between withPageContext and withEditor (viewMode was computed in both).
Renamed withClient feature to withPage to better reflect its purpose:
- 90% page data access, 10% page loading configuration
- Directory: features/client → features/page
- File: withClient.ts → withPage.ts
- Function: withClient() → withPage()

Renamed interfaces for clarity:
- ClientConfigState → PageLoadingConfigState (with detailed JSDoc)
- WithClientMethods → WithPageMethods

Updated all imports across codebase:
- dot-uve.store.ts
- withEditor.ts, withView.ts, withWorkflow.ts
- withStoreComputed.ts
- All spec files (withLayout, withLoad, withWorkflow)

Documentation improvements:
- Added comprehensive JSDoc to PageLoadingConfigState
- Clarified that client config is "page loading configuration"
- Updated store composition comments

Build verified successful - all TypeScript compilation passes.
…-prefixed state

- Add withUve feature managing uveStatus, uveIsEnterprise, uveCurrentUser
- Update UVEState interface with flat state structure and domain prefixes
- Migrate property names: status→uveStatus, isEnterprise→uveIsEnterprise,
  currentUser→uveCurrentUser, errorCode→pageErrorCode, languages→pageLanguages,
  experiment→pageExperiment, viewOrientation→viewDeviceOrientation
- Update 15+ component and feature files with new property references
- Add comprehensive unit tests for withUve (13 tests passing)
- Fix TypeScript types: remove any types, properly type dependencies

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Fix empty interface linting errors in withView and withWorkflow
- Remove unused imports (patchState, Signal, byTestId, DotDevice)
- Fix parsing error in edit-ema-editor.component.spec.ts (double quotes)
- Replace any types with proper TypeScript types in store features
- Add DotLanguage import for proper pageLanguage typing

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Create withHistory feature as reusable composition utility
  - Generic history tracking with configurable max entries (default: 50)
  - Deep cloning support with structuredClone (fallback to JSON)
  - Computed signals: canUndo, canRedo, historyLength, isAtStart, isAtEnd
  - Methods: addToHistory, undo, redo, goTo, clearHistory, getHistory
  - Mock structuredClone in tests for Node.js compatibility

- Update withPage to compose with withHistory
  - Replace withTimeMachine with withHistory (same interface)
  - Track pageAssetResponse changes for optimistic updates
  - Support undo/redo for style editor, layout changes

- Update store dependencies to use addToHistory method
  - Fix withLoad and withSave dependencies
  - Update dot-uve-style-editor-form component
  - Build successful, all tests passing

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Document why 'any' is appropriate for the store parameter in selector
- Keep the any localized to the generic config interface
- Avoids forcing callers to cast or complicating the API with extra generics
- Add eslint-disable with detailed justification

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Consolidate all view concerns (device preview, SEO preview, zoom controls, view mode) into single withView feature
- Remove redundant boolean flags (viewIsEditState, viewIsPreviewModeActive) in favor of viewMode enum
- Add zoom functionality directly to withView with flat state structure
- Add comprehensive JSDoc documenting feature responsibilities
- Delete withViewZoom feature and zoom/ directory
- Update components to use viewMode() === UVE_MODE.EDIT pattern
- Maintain flat state structure following NgRx Signal Store best practices
- Fix lint issues in withHistory.spec.ts (remove unused imports, fix non-null assertions)

Modified:
- models.ts: Remove redundant flags, add flat zoom properties
- dot-uve.store.ts: Remove withViewZoom from composition
- withView.ts: Add zoom computeds and methods with documentation
- withEditor.ts: Update to use viewMode instead of viewIsEditState
- edit-ema-editor.component.ts: Update computed signals to use viewMode
- withHistory.spec.ts: Fix lint warnings (remove patchState import, fix non-null assertions)

Deleted:
- store/features/zoom/withZoom.ts
- store/features/zoom/models.ts
- store/features/zoom/ directory

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Consolidate all backend API interactions into single withPageApi feature
- Merge withLoad and withSave features for better organization
- All page loading and saving operations now in one place
- Clearer ownership of backend communication concerns
- Consistent error handling and uveStatus orchestration across all API calls

New Feature - withPageApi:
- pageLoad() - Load page with all related data (languages, experiments, license, user)
- pageReload() - Refresh current page with optional param updates
- pageUpdateParams() - Update page parameters (language, variant, etc.)
- editorSave() - Save page content (containers)
- updateRows() - Save page layout (update rows)
- saveStyleEditor() - Save style properties with optimistic updates and rollback

Modified:
- dot-uve.store.ts: Replace withLoad and withSave with withPageApi
- Added comprehensive JSDoc documenting feature responsibilities
- Organized dependencies into logical groups (client config, workflow, request metadata, page management, history)

Deleted:
- store/features/load/withLoad.ts
- store/features/load/ directory
- store/features/editor/save/withSave.ts
- store/features/editor/save/ directory

Benefits:
- Single responsibility for all backend interactions
- Reduced feature count (11 → 10 features)
- Clear orchestration of uveStatus during async operations
- Centralized error handling with rollback support
- Type safety via explicit WithPageApiDeps interface

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add TODO comment explaining why page accessors are passed as dependencies
- Document potential solutions to revisit: reorder composition, props type assertion, type assertion
- Current approach is necessary due to TypeScript type inference limitations with feature composition order
- No functional changes, build still successful

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

- Add comprehensive JSDoc to withEditor explaining all responsibilities
- Add comprehensive JSDoc to withWorkflow explaining lock management
- Document why pageReload() uses type assertion in withWorkflow
- Clarify feature composition order dependency (withWorkflow before withPageApi)
- Improve inline comments for better code clarity
- No functional changes - documentation and comment improvements only

withEditor improvements:
- Document responsibilities: UI state, panel preferences, edit capabilities, inline editing
- Document dependencies: UVEState, PageAssetComputed, WorkflowComputed, ViewComputed
- Already uses correct naming from previous phases (viewMode, uveIsEnterprise)

withWorkflow improvements:
- Document responsibilities: workflow actions, lock/unlock, lock state computeds
- Explain type assertion necessity for pageReload() access
- Note runtime safety despite compile-time limitation
- Already uses correct naming (uveCurrentUser, pageErrorCode, uveStatus)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add comprehensive JSDoc documenting feature composition order in main store
- Document dependencies for each feature in composition chain
- Explain circular dependency between withWorkflow and withPageApi
- Add inline comments numbering each feature in composition order
- Verify current order is optimal given dependency constraints

Feature Composition Order (11 features):
1. withState - Base state
2. withUve - Global system state
3. withFlags - Feature flags
4. withPage - Page data + history
5. withTrack - Analytics
6. withWorkflow - Workflow + lock
7. withMethods - Helper methods
8. withLayout - Layout operations
9. withView - View modes + zoom
10. withEditor - Editor UI
11. withPageApi - Backend API (must be last)

Circular Dependency Analysis:
- withWorkflow needs pageReload() from withPageApi (type assertion)
- withPageApi needs workflowFetch() from withWorkflow (dependency injection)
- Current order is optimal - cannot be reordered without breaking dependencies
- Type assertion in withWorkflow is necessary and acceptable solution

No functional changes - documentation only

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Update test files to use new property names from Phase 1:
- Replace store.currentUser() with store.uveCurrentUser()
- Replace store.status() with store.uveStatus()
- Replace store.languages() with store.pageLanguages()

Files updated:
- withView.spec.ts: Update uveCurrentUser reference
- dot-uve.store.integration.spec.ts: Update uveStatus and pageLanguages references

Note: Service method calls like dotLicenseService.isEnterprise() remain unchanged
as they are not store properties.

Verified: No remaining old naming conventions in component/test files.
All occurrences of store.status() in palette store are for local store,
not UVE store, so they remain unchanged.

Phase 7 complete - Component updates done.
Create comprehensive README.md explaining UVE Store architecture:

Core Principles:
- Flat state structure (NgRx Signal Store best practice)
- Domain prefixes for clear ownership (uve*, page*, editor*, view*, workflow*)
- Single responsibility per feature
- Composition patterns for reusability

Key Documentation:
- Feature composition order with dependencies explained
- Circular dependency between withWorkflow ↔ withPageApi documented
- Scaling rules for adding new state and creating features
- Common patterns for accessing state, updating, and checking permissions
- Property naming conventions

Focused on:
- WHY the architecture is designed this way
- RULES for scaling the store safely
- PATTERNS for common operations

Phase 8 complete - Documentation done (~150 lines, focused on architecture).
@fmontes fmontes requested a review from Copilot February 14, 2026 05:03
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a real-time canvas for the Universal Visual Editor (UVE) with zoom controls, a right sidebar for content editing, and comprehensive store refactoring. The changes establish a cleaner architecture with flat state structure, domain-prefixed properties, and improved separation of concerns.

Changes:

  • Implements zoom functionality with controls and gesture support for the UVE canvas
  • Adds a right sidebar with tabbed interface for content editing and style editor
  • Refactors UVE store to use flat state structure with domain prefixes (uve*, page*, editor*, view*, workflow*)
  • Introduces new presentational components following container/presentational pattern
  • Removes deprecated store features and consolidates state management

Reviewed changes

Copilot reviewed 101 out of 130 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
withUVEToolbar.ts File deleted - toolbar state moved to withView feature
withSave.ts File deleted - save functionality consolidated into withPageApi
withClient.ts File deleted - client configuration moved to withPage feature
dot-uve.store.ts Complete refactoring with flat state structure and domain-prefixed properties
README.md Added comprehensive architecture documentation with 200+ lines
models.ts Removed deprecated interfaces (UVEToolbarProps, EditorProps, UnlockOptions) and updated palette tabs enum
shared/models.ts Removed UnlockOptions interface and showBanner/showOverlay from ToggleLockOptions
mocks.ts Updated page mock properties from isLocked/lockedByUser to locked/lockedBy/lockedByName
edit-ema-editor.component.scss Added zoom canvas layout with grid system and right sidebar wrapper
edit-ema-editor.component.html Complete template refactor with zoom controls, browser toolbar, and right sidebar tabs
dot-uve-zoom-controls component New component for zoom in/out/reset controls
dot-uve-iframe component New component extracted from editor with height reporting and traditional page support
dot-uve-contentlet-quick-edit component New presentational component for inline contentlet editing with dynamic form generation
dot-uve-palette.component.ts Refactored to use local signalState for tab management instead of global store
lib.routes.ts Removed DotEditPageResolver and DotPageStateService, added UVEStore and dependencies as providers
Comments suppressed due to low confidence (1)

core-web/libs/portlets/edit-ema/portlet/src/lib/store/dot-uve.store.ts:1

  • The comment mentions a circular dependency between withWorkflow and withPageApi but doesn't provide a clear reference to where this is documented or how to resolve it safely. Consider adding a reference to related documentation or tracking issue for future resolution.
import { signalStore, withFeature, withMethods, withState } from '@ngrx/signals';

Comment thread core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/models.ts Outdated
Comment thread core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/models.ts Outdated
Comment thread core-web/libs/portlets/edit-ema/portlet/src/lib/shared/models.ts Outdated
fmontes and others added 2 commits February 15, 2026 18:03
Security:
- Force regenerate yarn.lock to match package.json Angular 20.3.16
- Addresses Semgrep CVE-2026-22610 (XSS via SVG script href attributes)

Code Quality (10 Copilot findings):
- Update comment clarity for currentTab state management
- Reorder enum values for sequential ordering (LAYERS=3, STYLE_EDITOR=4)
- Add JSDoc documentation for ToggleLockOptions properties
- Extract magic numbers/strings to named constants (DROP_INDICATOR_HEIGHT_PX, DEFAULT_DEVICE_INODE)
- Add null safety checks in language selector lifecycle methods
- Optimize effect to avoid unnecessary form rebuilds
- Add i18n translations for Cancel/Save button labels
- Rename ambiguous method tryHandleIframeHeightMessage
- Fix type guard in isQuickEditSupportedField to properly narrow types

No functional changes - addresses security and maintainability improvements

Resolves all review findings in PR #34173

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Remove 'Phase X.Y:' prefixes from describe() blocks in specs
- Remove 'Phase X.Y:' from inline comments in component and store files
- Keep semantic meaning of comments while removing development phase markers
- Documentation files (*.md) intentionally not modified

No functional changes - code cleanup only
Comment thread core-web/libs/portlets/edit-ema/portlet/README.md
Comment thread core-web/libs/portlets/edit-ema/portlet/REFACTORING_SUMMARY.md Outdated
Comment thread core-web/UVE_REFACTOR_HANDOFF.md Outdated
Comment thread examples/nextjs/src/utils/getDotCMSPage.js
Comment thread examples/nextjs/src/views/Page.js Outdated
zJaaal and others added 2 commits April 9, 2026 17:01
…trip and fix drag regression

- Add metadata field to DotLayoutRow, DotLayoutColumn, DotGridStackWidget, DotGridStackNode
- Pass metadata through parseFromDotObjectToGridStack and parseFromGridStackToDotObject
- Guard against undefined oldChild in updateOldRows when column moves to new X position
- Remove identify() method, use row.id/box.id directly in @for track expressions
- Bump gridstack 8.1.1 -> 8.4.0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 9, 2026

Rollback Safety Analysis

  • Gather context
  • Read rollback-unsafe categories reference
  • Get full PR diff (commits 1e5c35e...98333455)
  • Analyze diff against all unsafe categories
  • Apply appropriate label

Result: Safe To Rollback

I reviewed the diff between 1e5c35eda7fd94861cd0af0dc5e32e51236250bb...98333455aa28163d4374d11dbc3d0c38467fc930 against all rollback-unsafe categories.

Scope of changes: ~100 files — overwhelmingly frontend-only Angular/TypeScript/SCSS. Only 9 backend Java files changed, plus openapi.yaml. No SQL migrations, no runonce tasks.

New commits since last analysis (f9e089298333455):

  • e5b54dc6 — example app fix (frontend-only)
  • 98333455 — template-builder metadata round-trip fix and drag regression fix (frontend-only: optional metadata? fields added to TypeScript interfaces DotLayoutRow, DotLayoutColumn, DotGridStackWidget, DotGridStackNode; SDK GraphQL query updated to request metadata { name }; @for tracking bug fixed)

Backend changes (all additive, unchanged from prior analysis):

  • Nullable metadata: Map<String, Object> added to TemplateLayoutRow, TemplateLayoutColumn and their REST DTO counterparts
  • New DotPageMetadata GraphQL type added; metadata field added to LayoutRow/LayoutColumn in PageAPIGraphQLTypesProvider
  • New PageScannerResource with two additive REST endpoints
  • New FEATURE_FLAG_PAGE_SCANNER constant in FeatureFlagName.java

All rollback-unsafe categories — clear:

  • C-1: No runonce task, no structural storage change
  • C-2: No ESMappingAPIImpl/ESMappingConstants changes, no reindex
  • C-3: No CURRENT_MODEL_VERSION bump, no ImmutableContentlet change
  • C-4: No DROP TABLE or DROP COLUMN
  • H-1 thru H-7: No data migration, rename, PK change, new field type, storage change, procedure drop, or NOT NULL column added
  • M-1 thru M-4: No column type change, bundle format change, breaking API contract, or OSGi interface breakage

Rollback scenario: If N writes templates with metadata fields, N-1 rollback is safe — Jackson's @JsonCreator deserialization silently ignores the unknown metadata property. N-1 GraphQL clients querying without metadata are unaffected by the additive type additions.

Applied label: AI: Safe To Rollback

View job run

Comment thread core-web/yarn.lock
Comment thread core-web/yarn.lock
Comment thread core-web/yarn.lock
zJaaal and others added 5 commits April 10, 2026 12:07
Replace row and column drag handle icons in the Row Reorder component:
- Row drag handle: pi-table → split_screen (Material Icon)
- Column drag handle: pi-objects-column → view_column_2 (Material Icon)
# Conflicts:
#	core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/components/dot-file-field/dot-file-field.component.html
#	core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/edit-ema-editor.component.ts
#	core-web/libs/sdk/types/src/lib/editor/public.ts
#	dotCMS/src/main/webapp/ext/uve/dot-uve.js
…erService

Move CREATE_CONTENTLET postMessage action handling from edit-ema-editor
component (main branch) into DotUveActionsHandlerService where it belongs
in this branch's architecture. Add test coverage for the new action.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread core-web/yarn.lock
Comment thread core-web/yarn.lock
Comment thread core-web/yarn.lock
Comment thread core-web/yarn.lock
@zJaaal zJaaal marked this pull request as ready for review April 13, 2026 19:27
zJaaal and others added 4 commits April 14, 2026 10:15
…ith skipWhile logic

Set $shouldHideControls initial value to false (was true) so palette
controls are visible by default. The skipWhile(status !== LOADING)
gate added to #updateControlsVisibility() prevents stale store state
from a previous palette tab from hiding controls on tab switch; with
that guard in place the signal must start as false. Update three tests
in the "control visibility behavior" block to drive status through
LOADING → EMPTY instead of jumping straight to EMPTY, matching the
production code path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@zJaaal zJaaal enabled auto-merge April 14, 2026 15:04
@zJaaal zJaaal added this pull request to the merge queue Apr 14, 2026
Merged via the queue into main with commit 5431c63 Apr 14, 2026
50 checks passed
@zJaaal zJaaal deleted the uve-experiment branch April 14, 2026 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI: Safe To Rollback Area : Backend PR changes Java/Maven backend code Area : Documentation PR changes documentation files Area : Frontend PR changes Angular/TypeScript frontend code Area : SDK PR changes SDK libraries Changelog: Breaking Change

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

UVE: Real-Time Canvas

6 participants