Reconcile verified account IDs and make language repairs observable
Magent CI/CD / verify (push) Successful in 1m50s
Magent CI/CD / deploy-prod (push) Skipped
Magent CI/CD / deploy-beta (push) Skipped

This commit is contained in:
2026-09-11 19:56:32 +12:00
parent 38169b881e
commit de25255ea8
25 changed files with 593 additions and 160 deletions
+10 -8
View File
@@ -2,6 +2,7 @@
import { useEffect, useRef, useState } from 'react'
import './latest-activity.css'
import { lockBodyScroll } from '../../lib/scrollLock'
type Event = { id: string; service: string; state: string; message: string; started_at?: string; finished_at?: string }
type Operation = { id: string; label: string; status: string; events: Event[] }
@@ -11,21 +12,21 @@ export default function LatestActivity({ operation, besideDownload, onDismiss }:
}) {
const dialog = useRef<HTMLDialogElement>(null)
const trigger = useRef<HTMLButtonElement>(null)
const [open, setOpen] = useState(false)
const [open, setOpen] = useState(true)
useEffect(() => { setOpen(true) }, [operation.id])
const latest = [...operation.events].sort((a, b) =>
(a.finished_at ?? a.started_at ?? '').localeCompare(b.finished_at ?? b.started_at ?? '')
).at(-1)
const status = operation.status === 'running' ? 'Working' : operation.status === 'complete' ? 'Finished' : 'Needs attention'
const status = operation.status === 'running' ? 'Working' : operation.status === 'complete' ? 'Finished' : operation.status === 'searching' ? 'Search still running' : 'Needs attention'
useEffect(() => {
if (!open) return
const element = dialog.current
element?.showModal()
const previous = document.body.style.overflow
document.body.style.overflow = 'hidden'
const unlock = lockBodyScroll()
return () => {
element?.close()
document.body.style.overflow = previous
unlock()
trigger.current?.focus()
}
}, [open])
@@ -37,13 +38,14 @@ export default function LatestActivity({ operation, besideDownload, onDismiss }:
<span className="latest-activity-message" role="status">{latest?.message || 'Getting ready to check your request…'}</span>
<span className="latest-activity-more">View all activity ({operation.events.length}) <span aria-hidden="true"></span></span>
</button>
<dialog ref={dialog} className="activity-dialog" aria-labelledby="activity-dialog-title" onCancel={() => setOpen(false)} onClose={() => setOpen(false)} onClick={(event) => { if (event.target === event.currentTarget) setOpen(false) }}>
<dialog ref={dialog} className="activity-dialog" aria-labelledby="activity-dialog-title" onCancel={() => setOpen(false)} onClose={() => setOpen(false)}>
<div className="activity-dialog-content">
<header>
<div><span className="request-overview-label">Activity details</span><h2 id="activity-dialog-title">{operation.label}</h2><small>{status} · {operation.events.length} updates</small></div>
<button type="button" onClick={() => setOpen(false)} autoFocus>Close</button>
<button type="button" onClick={() => setOpen(false)}>Close</button>
</header>
<ol className="activity-dialog-events" aria-label="All activity, oldest first">
{operation.status === 'running' && <p role="status" className="activity-working">Working on your request. This can take a minute while the media services search.</p>}
<ol aria-live="polite" className="activity-dialog-events" aria-label="All activity, oldest first">
{operation.events.map((event) => <li key={event.id} className={`is-${event.state}`}>
<span className="activity-event-state">{event.state === 'active' ? 'Working' : event.state === 'error' ? 'Needs attention' : 'Done'}</span>
<div><strong>{event.service}</strong><p>{event.message}</p></div>