Show live repair progress on requests
This commit is contained in:
@@ -36,6 +36,24 @@ type PipelineStage = {
|
||||
link?: string | null
|
||||
}
|
||||
|
||||
type RepairActivityStep = {
|
||||
id: string
|
||||
label: string
|
||||
state: 'complete' | 'active' | 'attention' | 'waiting' | string
|
||||
detail: string
|
||||
}
|
||||
|
||||
type RepairActivity = {
|
||||
visible?: boolean
|
||||
actionId?: string
|
||||
state?: 'searching' | 'downloading' | 'importing' | 'indexing' | 'complete' | 'attention' | string
|
||||
headline?: string
|
||||
message?: string
|
||||
service?: string
|
||||
updatedAt?: string | null
|
||||
steps?: RepairActivityStep[]
|
||||
}
|
||||
|
||||
type Snapshot = {
|
||||
request_id: string
|
||||
title: string
|
||||
@@ -57,6 +75,7 @@ type Snapshot = {
|
||||
}
|
||||
nextStep?: { title?: string; description?: string; actionIds?: string[] }
|
||||
pipeline?: PipelineStage[]
|
||||
repairActivity?: RepairActivity
|
||||
}
|
||||
raw?: Record<string, any>
|
||||
}
|
||||
@@ -288,6 +307,10 @@ export default function RequestTimelinePage() {
|
||||
(stage) => stage.id === 'available' && stage.state === 'active'
|
||||
)
|
||||
)
|
||||
const repairIsActive = Boolean(
|
||||
snapshot?.presentation?.repairActivity?.visible &&
|
||||
!['complete', 'attention'].includes(snapshot.presentation.repairActivity.state ?? '')
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (!requestId) return
|
||||
@@ -367,12 +390,15 @@ export default function RequestTimelinePage() {
|
||||
if (!stopped) console.error(error)
|
||||
}
|
||||
}
|
||||
const timer = window.setInterval(() => void refresh(), awaitingMediaIndex ? 5_000 : 15_000)
|
||||
const timer = window.setInterval(
|
||||
() => void refresh(),
|
||||
awaitingMediaIndex || repairIsActive ? 5_000 : 15_000,
|
||||
)
|
||||
return () => {
|
||||
stopped = true
|
||||
window.clearInterval(timer)
|
||||
}
|
||||
}, [awaitingMediaIndex, requestId, router])
|
||||
}, [awaitingMediaIndex, repairIsActive, requestId, router])
|
||||
|
||||
const liveDownloadKey = useMemo(() => {
|
||||
const downloadStage = snapshot?.presentation?.pipeline?.find((stage) => stage.id === 'download')
|
||||
@@ -470,6 +496,7 @@ export default function RequestTimelinePage() {
|
||||
const statusLabel = presentation.status?.label ?? fallbackStatusLabel(snapshot.state)
|
||||
const statusMeaning = presentation.status?.meaning ?? snapshot.state_reason ?? 'Magent is checking this request.'
|
||||
const download = presentation.download
|
||||
const repairActivity = presentation.repairActivity
|
||||
const downloadVisible = Boolean(download?.visible)
|
||||
const nextStep = presentation.nextStep ?? {
|
||||
title: snapshot.actions[0]?.label ?? 'No action needed right now',
|
||||
@@ -753,6 +780,35 @@ export default function RequestTimelinePage() {
|
||||
)}
|
||||
</section>
|
||||
|
||||
{repairActivity?.visible && (
|
||||
<section className={`request-repair-activity is-${repairActivity.state ?? 'searching'}`} aria-live="polite">
|
||||
<div className="request-repair-heading">
|
||||
<div>
|
||||
<span className="section-kicker">Repair activity</span>
|
||||
<h2>{repairActivity.headline ?? 'Repair in progress'}</h2>
|
||||
<p>{repairActivity.message ?? 'Magent is checking the repair with the connected services.'}</p>
|
||||
</div>
|
||||
<div className="request-repair-meta">
|
||||
<span className={`request-operation-status is-${repairActivity.state === 'attention' ? 'error' : repairActivity.state === 'complete' ? 'complete' : 'running'}`}>
|
||||
{repairActivity.state === 'complete' ? 'Complete' : repairActivity.state === 'attention' ? 'Attention' : 'Live'}
|
||||
</span>
|
||||
{repairActivity.updatedAt && <small>Updated {formatWhen(repairActivity.updatedAt)}</small>}
|
||||
</div>
|
||||
</div>
|
||||
<div className="request-repair-steps">
|
||||
{(repairActivity.steps ?? []).map((step) => (
|
||||
<div className={`request-repair-step is-${step.state}`} key={step.id}>
|
||||
<i aria-hidden="true" />
|
||||
<div>
|
||||
<strong>{step.label}</strong>
|
||||
<span>{step.detail}</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
<section className="request-journey" aria-labelledby="request-journey-heading">
|
||||
<div className="request-journey-heading">
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user