Skip to content

Experiments Portlet — Screen 2: Create/Update (/experiments/new + /:id/configuration) #37003

Description

@oidacra

Description

Creation is a routed screen, not a dialog: /experiments/new is the Configure screen with an empty draft. This retires the current drawer (name + description only, page implied by the UVE route context) and lets a user create, configure and start an experiment end-to-end without opening the page editor.

Design: approved prototype, edit screen + Select A Page modal + Add Variant modal.

Routing and creation flow

  • /experiments/new and /experiments/:experimentId/configuration render the same component in new vs edit mode.
  • Autosave is the creation mechanism (design footer: "Changes are saved as you edit." — no Save button): in new mode, debounced autosave issues the POST as soon as name + page exist, then replaceUrl to /experiments/:id/configuration; every subsequent change is a debounced PATCH per field group. Hard dependency on Experiments API gaps for the standalone portlet: archive/restore, PATCH side effects, goal operators, variant cap #36988's PATCH fix — without it every autosave call creates an empty Rule.
  • Page preselection via query param: /experiments/new?pageId=<uuid> or /experiments/new?url=/index (path resolved by HTMLPAGE search on the current site) prefills the Page card and skips the picker. Invalid param → inline message, never a blank screen. (?page= avoided — collides with pagination; ?url= matches UVE.)
  • Locked state when status ∈ {RUNNING, ENDED, ARCHIVED}: banner per the design, every field disabled, add/delete variant hidden; RUNNING copy differs from generic read-only copy.

Layout

Fixed header (back · title falling back to "New Experiment" · status tag · subline {pageTitle} · {pagePath} or "No Page selected" · View Results / Stop when applicable) + scrolling card body (max-width 1040 centered) + pinned footer (hint · Back To Experiments · primary Start/Schedule). Header kebab with end / abort / cancelSchedule / pushPublish / addToBundle gated by AllowedActionsByExperimentStatus (parity with the current screen's menu).

The five cards

  1. Details — name (required) + description textarea.
  2. Goal — SET/REQUIRED chip; goal name; 4 types as radio cards (BOUNCE_RATE, EXIT_RATE, REACH_PAGE, URL_PARAMETER); condition sub-panels for REACH_PAGE (Parameter/Operator/Value) and URL_PARAMETER (Parameter Name/Operator incl. EXISTS/Value). Operator lists come from what the backend validates after Experiments API gaps for the standalone portlet: archive/restore, PATCH side effects, goal operators, variant cap #36988 — never offer an operator the backend silently ignores.
  3. Page — read-only summary + Select → Select A Page dialog (900×560: folder tree + page table Page | Template | Modified | State + search, radio selection). A page may host any number of experiments, so the picker restricts nothing: ExperimentsAPIImpl.save puts no page-based condition on creating one. What cannot happen is two running on the same page at once, which start rejects — outright for an immediate start, and for a scheduled one unless the running experiment's window closes before the new one opens. Traffic allocation: slider 1–100 synced with number input.
  4. Variants — color dot, name + CONTROL chip, meta line, weight input, delete (non-control, unlocked). Ported parity behaviors: inplace variant rename, copy-variant-URL (dot-copy-button with &variantName=), n/max counter. Total + Split Evenly (even = floor(100/n), first absorbs remainder) + + Add Variant dialog (440px, Variant {n} fallback, re-splits evenly) + warning bar when weights ≠ 100. Edit Content/Preview out of scope here (UVE-integration issue) — render disabled with tooltip or omit until it lands. Cap: whatever Experiments API gaps for the standalone portlet: archive/restore, PATCH side effects, goal operators, variant cap #36988 enforces.
  5. Scheduling — start/end with time-of-day (p-datepicker [showTime]="true") and the min/max duration bounds from DotExperimentsConfigResolver (the design draws bare date inputs; dropping time + duration validation would be a parity regression). Note box + Clear Schedule.

Validation and transitions

The 8 rules (name, page, goal type, goal name, condition value, parameter name, ≥2 variants, weights = 100), revealed only after pressing Start — scroll to the first [data-error], count in the footer; Start never disabled. Start with date → SCHEDULED; without → RUNNING; Stop → ENDED. Toast per transition.

Store

Signal Store Events, same shape as #36989: experiments-form.events.ts, reducers per card, autosave in withEventHandlers (debounce + switchMap; failed PATCH → DotHttpErrorManagerService, state back to loaded).

Unhide from Screen 1

The New Experiment button and the Configure primary row action in #36989 route here.

Acceptance Criteria

  • /experiments/new renders the empty-draft Configure screen; typing a name and picking a page creates the experiment (one POST, no dialog) and the URL becomes /experiments/:id/configuration via replaceUrl.
  • Every field change persists via debounced PATCH; no PATCH creates a Rule/ConditionGroup (spec asserts untouched targetingConditions is omitted from the payload).
  • ?url=/index and ?pageId=<id> prefill the Page card; invalid values show a message.
  • All five cards match the design, including the ported behaviors: variant inplace rename, copy-variant-URL, n/max counter, scheduling time + duration bounds.
  • Select A Page: current-site browse, search, radio selection; selection updates the summary + traffic helper copy. No page is excluded or greyed — concurrency on a page is enforced at Start, not at the pick.
  • The 8 validation rules reveal on Start, scroll to the first error, count in the footer.
  • Start/Schedule/Stop transitions with toasts; locked states disable everything with the right banner copy.
  • Header kebab per AllowedActionsByExperimentStatus.
  • The old UVE configuration screen is untouched.
  • Jest specs per card + the autosave store (fake timers for debounce).

Priority

High.

Additional Context

Activity

  1. added theissue type on Aug 11, 2026
  2. moved this from New to Current Sprint Backlog in dotCMS - Product Planningon Aug 11, 2026
  3. moved this from Current Sprint Backlog to In Progress in dotCMS - Product Planningon Aug 13, 2026
  4. moved this from In Progress to In Review in dotCMS - Product Planningon Aug 19, 2026
  5. moved this from In Review to In Progress in dotCMS - Product Planningon Aug 26, 2026
  6. 10 remaining items

  7. moved this from QA to Current Sprint Backlog in dotCMS - Product Planningon Sep 7, 2026
  8. moved this from Current Sprint Backlog to In Progress in dotCMS - Product Planningon Sep 9, 2026
  9. moved this from In Progress to QA in dotCMS - Product Planningon Sep 16, 2026
  10. removed their assignment
    on Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions