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:
committed by
gsxdsm
parent
26c3d330d3
commit
ae740bdb24
5
.changeset/FN-4764-structured-gh-errors.md
Normal file
5
.changeset/FN-4764-structured-gh-errors.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@runfusion/fusion": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Structured surfacing of GitHub CLI / API errors with retry affordances in the dashboard PR UI and `fn pr create` CLI flow.
|
||||||
@@ -171,6 +171,28 @@
|
|||||||
background: color-mix(in srgb, var(--color-error) 10%, transparent);
|
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) {
|
@media (max-width: 768px) {
|
||||||
.pr-create-modal {
|
.pr-create-modal {
|
||||||
gap: var(--space-md);
|
gap: var(--space-md);
|
||||||
|
|||||||
@@ -437,12 +437,15 @@ export function PrCreateModal({
|
|||||||
</details>
|
</details>
|
||||||
|
|
||||||
{error && (
|
{error && (
|
||||||
<div className="form-error" role="alert">
|
<div className="form-error pr-error" role="alert">
|
||||||
<p>{error}</p>
|
<p>{error}</p>
|
||||||
{lastGhError?.hint ? <p>{lastGhError.hint}</p> : null}
|
{lastGhError?.hint ? <p className="pr-error__hint">{lastGhError.hint}</p> : null}
|
||||||
{lastGhError?.action?.kind === "shell" ? <p>Action: run <code>{lastGhError.action.command}</code></p> : null}
|
<div className="pr-error__actions">
|
||||||
{lastGhError?.action?.kind === "open" ? <p>Action: open <a href={lastGhError.action.url} target="_blank" rel="noreferrer">docs</a></p> : null}
|
{lastGhError?.action?.kind === "shell" ? <p>Action: run <code>{lastGhError.action.command}</code></p> : null}
|
||||||
{lastGhError?.retryable ? <button type="button" className="btn btn-sm" onClick={() => void submit()}>Retry</button> : 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>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -198,6 +198,32 @@
|
|||||||
padding: var(--space-sm);
|
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) {
|
@media (max-width: 768px) {
|
||||||
.pr-panel-checks-rollup {
|
.pr-panel-checks-rollup {
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|||||||
@@ -235,11 +235,14 @@ export function PrPanel({
|
|||||||
</div>
|
</div>
|
||||||
<div className="pr-title">{prInfo.title}</div>
|
<div className="pr-title">{prInfo.title}</div>
|
||||||
{lastGhError ? (
|
{lastGhError ? (
|
||||||
<div className="pr-hint pr-hint--warning" role="alert">
|
<div className="pr-error" role="alert">
|
||||||
<div>{lastGhError.message}</div>
|
<div>{lastGhError.message}</div>
|
||||||
{lastGhError.hint ? <div>{lastGhError.hint}</div> : null}
|
{lastGhError.hint ? <div className="pr-error__hint">{lastGhError.hint}</div> : null}
|
||||||
{lastGhError.action?.kind === "shell" ? <div>Action: run <code>{lastGhError.action.command}</code></div> : null}
|
<div className="pr-error__actions">
|
||||||
{lastGhError.retryable ? <button className="btn btn-sm" onClick={() => void handleRefresh()}>Retry</button> : null}
|
{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>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
<div className="pr-meta">
|
<div className="pr-meta">
|
||||||
|
|||||||
Reference in New Issue
Block a user