adding stuff
This commit is contained in:
@@ -125,6 +125,8 @@
|
||||
padding: 16px 0 32px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.btn-rerank {
|
||||
|
||||
@@ -84,3 +84,7 @@
|
||||
.pipeline-step-label {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.pipeline-retry {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ const STAGES: { key: keyof StageMap; label: string }[] = [
|
||||
|
||||
interface PipelineProgressProps {
|
||||
stages: StageMap;
|
||||
onRetry?: () => void;
|
||||
}
|
||||
|
||||
function StageIcon({ status }: { status: StageStatus }) {
|
||||
@@ -25,10 +26,12 @@ function StageIcon({ status }: { status: StageStatus }) {
|
||||
}
|
||||
}
|
||||
|
||||
export function PipelineProgress({ stages }: PipelineProgressProps) {
|
||||
export function PipelineProgress({ stages, onRetry }: PipelineProgressProps) {
|
||||
const hasError = Object.values(stages).some((s) => s === 'error');
|
||||
|
||||
return (
|
||||
<div class="pipeline-progress">
|
||||
<h3 class="pipeline-title">Generating Recommendations…</h3>
|
||||
<h3 class="pipeline-title">{hasError ? 'Pipeline Failed' : 'Generating Recommendations…'}</h3>
|
||||
<ul class="pipeline-steps">
|
||||
{STAGES.map(({ key, label }) => (
|
||||
<li key={key} class={`pipeline-step pipeline-step--${stages[key]}`}>
|
||||
@@ -37,6 +40,11 @@ export function PipelineProgress({ stages }: PipelineProgressProps) {
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{hasError && onRetry && (
|
||||
<div class="pipeline-retry">
|
||||
<button class="btn-primary" onClick={onRetry}>Re-run Pipeline</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -142,4 +142,25 @@
|
||||
.sidebar-type-movie {
|
||||
background: rgba(245, 158, 11, 0.15);
|
||||
color: #fbbf24;
|
||||
}
|
||||
|
||||
.sidebar-item-delete {
|
||||
flex-shrink: 0;
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-dim);
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
padding: 0 2px;
|
||||
line-height: 1;
|
||||
opacity: 0;
|
||||
transition: opacity 0.15s, color 0.15s;
|
||||
}
|
||||
|
||||
.sidebar-item:hover .sidebar-item-delete {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.sidebar-item-delete:hover {
|
||||
color: var(--red);
|
||||
}
|
||||
@@ -6,6 +6,7 @@ interface SidebarProps {
|
||||
selectedId: string | null;
|
||||
onSelect: (id: string) => void;
|
||||
onNewClick: () => void;
|
||||
onDelete?: (id: string) => void;
|
||||
}
|
||||
|
||||
function statusIcon(status: RecommendationSummary['status']): string {
|
||||
@@ -26,7 +27,7 @@ function statusClass(status: RecommendationSummary['status']): string {
|
||||
}
|
||||
}
|
||||
|
||||
export function Sidebar({ list, selectedId, onSelect, onNewClick }: SidebarProps) {
|
||||
export function Sidebar({ list, selectedId, onSelect, onNewClick, onDelete }: SidebarProps) {
|
||||
return (
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
@@ -56,6 +57,13 @@ export function Sidebar({ list, selectedId, onSelect, onNewClick }: SidebarProps
|
||||
<span class={`sidebar-type-badge sidebar-type-${item.media_type}`}>
|
||||
{item.media_type === 'movie' ? 'Film' : 'TV'}
|
||||
</span>
|
||||
{onDelete && (
|
||||
<button
|
||||
class="sidebar-item-delete"
|
||||
onClick={(e) => { e.stopPropagation(); onDelete(item.id); }}
|
||||
title="Delete"
|
||||
>×</button>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user