Redesign the alerts editor (CanvasWorkspace) into the "Studio" layout #100
Labels
No labels
auth
autorelease: pending
autorelease: tagged
bug
dependencies
devops
docker
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
javascript
maintenance
question
refactor
ui
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gitchegumi/GitchAlerts#100
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Type: enhancement / UX redesign
Area:
apps/web—/dashboard/[channelSlug]/alertsDesign reference: option 1b in the "Alerts Editor Redesign" design doc (Studio layout). Screenshots of the mock are the source of truth for visual details; this issue is the source of truth for behavior.
1. Motivation
The current alerts editor (
apps/web/src/components/CanvasWorkspace.tsx, rendered byapps/web/src/app/dashboard/[channelSlug]/alerts/page.tsx) has these problems:patchElementon everyonChange, so each keystroke re-renders and re-positions the element mid-edit.2. Target layout (Studio)
A single full-viewport editor in five fixed regions:
Keep the existing dark brand and all tokens from
apps/web/src/app/globals.css(
--bg #18191d,--panel #23252b,--line rgba(204,219,220,.24),--accent #afe0cetiffany,--primary #4166f5ultramarine,--attention #fca311golden orange, Inter). Panel chrome colorin the mock:
#1c1e23; canvas backdrop#131418with a checkerboard(
repeating-conic-gradient(rgba(204,219,220,.05) 0% 25%, transparent 0% 50%), 26px tiles).2.1 Top bar (52px,
#1c1e23, bottom hairline)Left → right:
support-files/GitchAlerts-image-logo.svg).▾; dropdown lists all overlay profiles, plus "New canvas" and "Duplicate". Replaces the current left "Canvases" panel as the primary switcher.isActive; hidden/inactive style otherwise.startTransitionPATCH lifecycle.copyUrl().#fca311with dark text) — existingtestAlert().2.2 Left panel (248px)
Three tabs at top: Layers | Alerts | Assets (segmented control; Alerts tab shows a bound-count badge in orange).
Layers tab (default):
addElement(type)(audio maps to the canvas audio settings, see 2.4).LAYERS · n.zIndexdescending (top layer first): 18px type glyph, name, right-aligned visibility dot. Selected row = ultramarine tint background + outline.⋯(context menu: duplicate, delete, rename). Double-click renames inline. Drag to reorder = rewriteszIndexvalues (replaces the numeric "Layer" input).+— secondary access to canvas switching.Alerts tab: the current "Alert bindings" section, grouped by platform (
platformLabel), each row a toggle + name + eventKey + inline Test link. Enabling a binding also enables the alert config globally if disabled (existingtoggleAlert+enableAlertConfigbehavior).Assets tab: browsable list of
WorkspaceAssets (image/video/audio) for drag-onto-canvas or click-to-assign to the selected image element.2.3 Canvas area
aspect-ratio: settings.width / settings.height, dark translucent fill, 1px outline, large shadow. Scale-to-fit with zoom override.W × Hdimension badge below the element (monospace).snapToCanvasCenter.backgroundsetting).2.4 Inspector (right, 264px) — replaces the "on-screen components" panel
Shows properties of the current selection only. Empty state (nothing selected): canvas-level settings (name, size, background, audio: stored sound + volume) plus a hint "Select an element to edit it".
Selected element, four hairline-separated sections:
centerElement.{{tokens}}as highlighted chips (orange tint, monospace); hint "Type/to insert event data" opening a token autocomplete popover fed byEVENT_VARIABLES(replaces the always-visible token button list). Image elements: asset picker (existing "Stored asset" select) + media preview.Numeric-input contract (fixes jitter) — applies to every numeric field in the editor:
canvasSizeDraftapproach):onChangeupdates a local string draft only; commit (validate → clamp →patchElement/patchCanvas) happens on blur or Enter; Escape reverts to the committed value.2.5 Status bar (30px,
#16171b)Left:
1920 × 1080 · 3 layers + audio · Bound to 4 alert types(bound count in accent). Right: contextual hints.3. Non-goals
overlay-profiles,alert-configs,assets,test-alert) andcanvas-schema.tsserialization stay as-is.OverlayLayoutEditor(the/overlay/[layoutId]/editpage) andAlertCatalogManagerare out of scope.4. Implementation plan (parallelizable workstreams)
Split
CanvasWorkspace.tsx(1320 lines) into components underapps/web/src/components/canvas-editor/, with shared state lifted into auseCanvasEditorhook (or context) exposing:canvases, selected, selectedElement, selectElement(id), patchCanvas, patchElement (commit-only), addElement, deleteElement, reorderElement(id, newIndex), toggleAlert, testAlert, copyUrl, zoom state, snap state.Keep styling in
globals.csswith acanvas-editor-*class prefix (or a co-located CSS module — match repo conventions).Workstream A — Editor shell + top bar + status bar.
CanvasEditor.tsx(grid: 52px / 1fr / 30px rows; 248px / 1fr / 264px columns),EditorTopBar.tsx(canvas switcher dropdown w/ create, duplicate, rename, width/height, delete),EditorStatusBar.tsx. Wires existingcreateCanvas,deleteCanvas,patchCanvas,copyUrl,testAlert.Workstream B — Left panel.
EditorLeftPanel.tsxwithLayersTab.tsx(rows, hover actions, inline rename, drag-reorder → zIndex rewrite),AlertsTab.tsx(port alert-bindings section),AssetsTab.tsx. Depends only on the shared hook's interface.Workstream C — Canvas stage.
EditorStage.tsx: portstartElementPointer,transformElement,snapToCanvasCenter, resize handles; add zoom/fit state, floating toolbar, selection badges (name + dimensions). Preserve pointer-capture drag behavior and themovedguard that avoids PATCHes on plain clicks.Workstream D — Inspector.
EditorInspector.tsx+NumericField.tsx(the commit-on-blur/Enter/arrow-nudge contract — single reusable component, unit-tested), sections per 2.4, token-chip textarea +/autocomplete fromEVENT_VARIABLES.Workstream E — Integration + cleanup.
Replace
CanvasWorkspaceusage inalerts/page.tsx, delete dead CSS (component-card-*,canvas-settings-grid, etc.), keepapplyAlertAssignmentexport + its tests passing, add tests forNumericFieldand zIndex reorder.Suggested order: A first (defines the shell + hook interface), then B/C/D in parallel, then E.
5. Acceptance criteria
/dashboard/[channelSlug]/alertsrenders the five-region Studio layout; no third "components" column.⋯menu work without changing selection.zIndexorder; the numeric Layer input is gone.serializeCanvasSettingspayloads are byte-compatible with current output.