feat(retry): FailedBanner + App.tsx mount (#2 v0.2.3)
This commit is contained in:
@@ -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={{
|
||||
|
||||
32
src/renderer/inbox/components/FailedBanner.tsx
Normal file
32
src/renderer/inbox/components/FailedBanner.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user