From 6fea35ac31deca34508cef0ec00f15025bc99f78 Mon Sep 17 00:00:00 2001 From: Saagar Patel Date: Tue, 21 Apr 2026 15:48:18 +0200 Subject: [PATCH 1/3] refactor(features): extract workspace performance mark helpers Lift the three perf marks, the PerfWindow typing, and the ticket-workspace-ready measurement out of TicketWorkspaceRail.tsx into a sibling workspacePerformanceMetrics.ts exposing a single markWorkspaceReady() side-effect function. Shell useEffect is now one line. Wave 5.5. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../workspace/TicketWorkspaceRail.tsx | 43 +----------------- .../workspace/workspacePerformanceMetrics.ts | 44 +++++++++++++++++++ 2 files changed, 46 insertions(+), 41 deletions(-) create mode 100644 src/features/workspace/workspacePerformanceMetrics.ts diff --git a/src/features/workspace/TicketWorkspaceRail.tsx b/src/features/workspace/TicketWorkspaceRail.tsx index dc50b54..3d4d9af 100644 --- a/src/features/workspace/TicketWorkspaceRail.tsx +++ b/src/features/workspace/TicketWorkspaceRail.tsx @@ -16,20 +16,9 @@ import type { WorkspaceFavorite, WorkspacePersonalization, } from "../../types/workspace"; +import { markWorkspaceReady } from "./workspacePerformanceMetrics"; import "./TicketWorkspaceRail.css"; -const APP_BOOTSTRAP_START_MARK = "assistsupport:perf:bootstrap-start"; -const TICKET_WORKSPACE_READY_MARK = "assistsupport:perf:ticket-workspace-ready"; -const TICKET_WORKSPACE_READY_MEASURE = - "assistsupport:perf:ticket-workspace-ready-ms"; - -type PerfWindow = Window & { - __assistsupportPerf?: { - bootstrapStartedAt: number; - ticketWorkspaceReadyMs?: number; - }; -}; - type IntakeField = | "issue" | "environment" @@ -209,35 +198,7 @@ export function TicketWorkspaceRail({ }, [guidedRunbookSession]); useEffect(() => { - if ( - typeof window === "undefined" || - typeof window.performance === "undefined" - ) { - return; - } - - const perfWindow = window as PerfWindow; - const bootstrapStartedAt = - perfWindow.__assistsupportPerf?.bootstrapStartedAt ?? 0; - perfWindow.__assistsupportPerf = { - ...(perfWindow.__assistsupportPerf ?? { bootstrapStartedAt }), - bootstrapStartedAt, - ticketWorkspaceReadyMs: Number( - (window.performance.now() - bootstrapStartedAt).toFixed(2), - ), - }; - window.performance.clearMarks(TICKET_WORKSPACE_READY_MARK); - window.performance.clearMeasures(TICKET_WORKSPACE_READY_MEASURE); - window.performance.mark(TICKET_WORKSPACE_READY_MARK); - try { - window.performance.measure( - TICKET_WORKSPACE_READY_MEASURE, - APP_BOOTSTRAP_START_MARK, - TICKET_WORKSPACE_READY_MARK, - ); - } catch { - // Keep the workspace usable even if performance marks are unavailable in the current runtime. - } + markWorkspaceReady(); }, []); return ( diff --git a/src/features/workspace/workspacePerformanceMetrics.ts b/src/features/workspace/workspacePerformanceMetrics.ts new file mode 100644 index 0000000..e8da221 --- /dev/null +++ b/src/features/workspace/workspacePerformanceMetrics.ts @@ -0,0 +1,44 @@ +export const APP_BOOTSTRAP_START_MARK = "assistsupport:perf:bootstrap-start"; +export const TICKET_WORKSPACE_READY_MARK = + "assistsupport:perf:ticket-workspace-ready"; +export const TICKET_WORKSPACE_READY_MEASURE = + "assistsupport:perf:ticket-workspace-ready-ms"; + +type PerfWindow = Window & { + __assistsupportPerf?: { + bootstrapStartedAt: number; + ticketWorkspaceReadyMs?: number; + }; +}; + +export function markWorkspaceReady(): void { + if ( + typeof window === "undefined" || + typeof window.performance === "undefined" + ) { + return; + } + + const perfWindow = window as PerfWindow; + const bootstrapStartedAt = + perfWindow.__assistsupportPerf?.bootstrapStartedAt ?? 0; + perfWindow.__assistsupportPerf = { + ...(perfWindow.__assistsupportPerf ?? { bootstrapStartedAt }), + bootstrapStartedAt, + ticketWorkspaceReadyMs: Number( + (window.performance.now() - bootstrapStartedAt).toFixed(2), + ), + }; + window.performance.clearMarks(TICKET_WORKSPACE_READY_MARK); + window.performance.clearMeasures(TICKET_WORKSPACE_READY_MEASURE); + window.performance.mark(TICKET_WORKSPACE_READY_MARK); + try { + window.performance.measure( + TICKET_WORKSPACE_READY_MEASURE, + APP_BOOTSTRAP_START_MARK, + TICKET_WORKSPACE_READY_MARK, + ); + } catch { + // Keep the workspace usable even if performance marks are unavailable in the current runtime. + } +} From 559ffd1c47a319cceff00c63070a0e63a71dae7c Mon Sep 17 00:00:00 2001 From: Saagar Patel Date: Tue, 21 Apr 2026 15:49:36 +0200 Subject: [PATCH 2/3] refactor(features): extract IntakeFieldControl sub-component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lift the IntakeFieldControl form-field wrapper plus the NOTE_AUDIENCES and INTAKE_FIELDS constants and the IntakeField key-type out of TicketWorkspaceRail.tsx into a sibling IntakeFieldControl.tsx. No external consumers; shell imports them back. Wave 5.5 (narrow scope — prop-API redesign explicitly deferred). Co-Authored-By: Claude Opus 4.7 (1M context) --- src/features/workspace/IntakeFieldControl.tsx | 74 +++++++++++++++++++ .../workspace/TicketWorkspaceRail.tsx | 74 ++----------------- 2 files changed, 80 insertions(+), 68 deletions(-) create mode 100644 src/features/workspace/IntakeFieldControl.tsx diff --git a/src/features/workspace/IntakeFieldControl.tsx b/src/features/workspace/IntakeFieldControl.tsx new file mode 100644 index 0000000..bbf1dc4 --- /dev/null +++ b/src/features/workspace/IntakeFieldControl.tsx @@ -0,0 +1,74 @@ +import type { NoteAudience } from "../../types/workspace"; + +export type IntakeField = + | "issue" + | "environment" + | "impact" + | "affected_user" + | "affected_system" + | "affected_site" + | "symptoms" + | "steps_tried" + | "blockers" + | "likely_category"; + +export const NOTE_AUDIENCES: Array<{ id: NoteAudience; label: string }> = [ + { id: "internal-note", label: "Internal note" }, + { id: "customer-safe", label: "Customer-safe" }, + { id: "escalation-note", label: "Escalation note" }, +]; + +export const INTAKE_FIELDS: Array<{ + key: IntakeField; + label: string; + rows?: number; +}> = [ + { key: "issue", label: "Issue summary" }, + { key: "environment", label: "Environment" }, + { key: "impact", label: "Impact", rows: 2 }, + { key: "affected_user", label: "Affected user" }, + { key: "affected_system", label: "Affected system" }, + { key: "affected_site", label: "Affected site" }, + { key: "symptoms", label: "Symptoms", rows: 3 }, + { key: "steps_tried", label: "Steps already tried", rows: 3 }, + { key: "blockers", label: "Current blocker", rows: 2 }, + { key: "likely_category", label: "Likely category" }, +]; + +interface IntakeFieldControlProps { + label: string; + value: string; + rows?: number; + onChange: (value: string) => void; +} + +export function IntakeFieldControl({ + label, + value, + rows, + onChange, +}: IntakeFieldControlProps) { + if (rows && rows > 1) { + return ( +