feat(retry): FailedBanner + App.tsx mount (#2 v0.2.3)

This commit is contained in:
altair823
2026-05-02 03:34:09 +09:00
parent 3ebd3bc9a5
commit 406a5e61f0
2 changed files with 34 additions and 0 deletions

View File

@@ -10,6 +10,7 @@ import { OllamaBanner } from './components/OllamaBanner.js';
import { RecoveryToast } from './components/RecoveryToast.js';
import { TagUndoToast } from './components/TagUndoToast.js';
import { ExpiryBanner } from './components/ExpiryBanner.js';
import { FailedBanner } from './components/FailedBanner.js';
export function App(): React.ReactElement {
const {
@@ -83,6 +84,7 @@ export function App(): React.ReactElement {
onDismiss={() => { markRecoveryDismissed(); setRecoveryDismissed(true); }}
/>
<PendingBanner />
<FailedBanner />
<ExpiryBanner />
{tagFilter !== null && (
<div style={{

View File

@@ -0,0 +1,32 @@
import React from 'react';
import { useInbox } from '../store.js';
export function FailedBanner(): React.ReactElement | null {
const count = useInbox((s) => s.failedCount);
const retryAllFailed = useInbox((s) => s.retryAllFailed);
if (count === 0) return null;
return (
<div style={{
background: '#fce4e4', border: '1px solid #a33', borderRadius: 6,
padding: '8px 12px', margin: '8px 0', fontSize: 13,
display: 'flex', alignItems: 'center', gap: 8
}}>
<span style={{ flex: 1 }}> AI <b>{count}</b></span>
<button
onClick={() => {
retryAllFailed().catch((e) => {
// eslint-disable-next-line no-console
console.warn('retryAllFailed failed', e);
});
}}
style={{
background: '#a33', color: '#fff',
border: 'none', borderRadius: 4,
padding: '4px 12px', fontSize: 12, cursor: 'pointer'
}}
>
</button>
</div>
);
}