fix(FN-4764): add dismissible structured PR error blocks and styles

Fusion-Task-Id: FN-4764
Fusion-Task-Lineage: 14809ad5-8463-4e16-a934-1414225f17ae
This commit is contained in:
Fusion (runfusion.ai)
2026-05-17 14:31:24 -07:00
committed by gsxdsm
parent 26c3d330d3
commit ae740bdb24
5 changed files with 68 additions and 9 deletions

View File

@@ -171,6 +171,28 @@
background: color-mix(in srgb, var(--color-error) 10%, transparent);
}
.pr-error {
background: color-mix(in srgb, var(--color-error) 10%, transparent);
border: var(--btn-border-width) solid color-mix(in srgb, var(--color-error) 35%, transparent);
border-radius: var(--radius-md);
}
.pr-error__hint {
margin: 0;
}
.pr-error__actions {
align-items: center;
display: flex;
flex-wrap: wrap;
gap: var(--space-sm);
}
.pr-error__retry:focus-visible,
.pr-error__dismiss:focus-visible {
box-shadow: var(--focus-ring-strong);
}
@media (max-width: 768px) {
.pr-create-modal {
gap: var(--space-md);

View File

@@ -437,12 +437,15 @@ export function PrCreateModal({
</details>
{error && (
<div className="form-error" role="alert">
<div className="form-error pr-error" role="alert">
<p>{error}</p>
{lastGhError?.hint ? <p>{lastGhError.hint}</p> : null}
{lastGhError?.action?.kind === "shell" ? <p>Action: run <code>{lastGhError.action.command}</code></p> : null}
{lastGhError?.action?.kind === "open" ? <p>Action: open <a href={lastGhError.action.url} target="_blank" rel="noreferrer">docs</a></p> : null}
{lastGhError?.retryable ? <button type="button" className="btn btn-sm" onClick={() => void submit()}>Retry</button> : null}
{lastGhError?.hint ? <p className="pr-error__hint">{lastGhError.hint}</p> : null}
<div className="pr-error__actions">
{lastGhError?.action?.kind === "shell" ? <p>Action: run <code>{lastGhError.action.command}</code></p> : null}
{lastGhError?.action?.kind === "open" ? <p>Action: open <a href={lastGhError.action.url} target="_blank" rel="noreferrer">docs</a></p> : null}
{lastGhError?.retryable ? <button type="button" className="btn btn-sm pr-error__retry" onClick={() => void submit()}>Retry</button> : null}
<button type="button" className="btn btn-sm pr-error__dismiss" onClick={() => { setLastGhError(null); setError(null); }} aria-label="Dismiss PR error">×</button>
</div>
</div>
)}
</>

View File

@@ -198,6 +198,32 @@
padding: var(--space-sm);
}
.pr-error {
background: color-mix(in srgb, var(--color-error) 10%, transparent);
border: var(--btn-border-width) solid color-mix(in srgb, var(--color-error) 35%, transparent);
border-radius: var(--radius-md);
color: var(--color-error);
display: grid;
gap: var(--space-sm);
padding: var(--space-sm);
}
.pr-error__hint {
color: var(--text);
}
.pr-error__actions {
align-items: center;
display: flex;
flex-wrap: wrap;
gap: var(--space-sm);
}
.pr-error__retry:focus-visible,
.pr-error__dismiss:focus-visible {
box-shadow: var(--focus-ring-strong);
}
@media (max-width: 768px) {
.pr-panel-checks-rollup {
align-items: flex-start;

View File

@@ -235,11 +235,14 @@ export function PrPanel({
</div>
<div className="pr-title">{prInfo.title}</div>
{lastGhError ? (
<div className="pr-hint pr-hint--warning" role="alert">
<div className="pr-error" role="alert">
<div>{lastGhError.message}</div>
{lastGhError.hint ? <div>{lastGhError.hint}</div> : null}
{lastGhError.action?.kind === "shell" ? <div>Action: run <code>{lastGhError.action.command}</code></div> : null}
{lastGhError.retryable ? <button className="btn btn-sm" onClick={() => void handleRefresh()}>Retry</button> : null}
{lastGhError.hint ? <div className="pr-error__hint">{lastGhError.hint}</div> : null}
<div className="pr-error__actions">
{lastGhError.action?.kind === "shell" ? <div>Action: run <code>{lastGhError.action.command}</code></div> : null}
{lastGhError.retryable ? <button className="btn btn-sm pr-error__retry" onClick={() => void handleRefresh()}>Retry</button> : null}
<button className="btn btn-sm pr-error__dismiss" onClick={() => setLastGhError(null)} aria-label="Dismiss PR error">×</button>
</div>
</div>
) : null}
<div className="pr-meta">