feat(presentation): add Smart Presentation Layer for Pipeline output
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
- Add PresentationAnalyzer in Rust backend (13 tests passing) - Add PresentationContainer with auto type detection - Add TypeSwitcher for manual type switching - Add ChartRenderer, QuizRenderer, SlideshowRenderer, DocumentRenderer - Integrate ResultModal into PipelinesPanel for result display - Update docs: pipeline-overview.md, README.md, roadmap.md Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,7 @@ import {
|
||||
formatInputType,
|
||||
} from '../lib/pipeline-client';
|
||||
import { useToast } from './ui/Toast';
|
||||
import { PresentationContainer } from './presentation';
|
||||
|
||||
// === Category Badge Component ===
|
||||
|
||||
@@ -116,6 +117,64 @@ function PipelineCard({ pipeline, onRun }: PipelineCardProps) {
|
||||
);
|
||||
}
|
||||
|
||||
// === Pipeline Result Modal ===
|
||||
|
||||
interface ResultModalProps {
|
||||
result: PipelineRunResponse;
|
||||
pipeline: PipelineInfo;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
function ResultModal({ result, pipeline, onClose }: ResultModalProps) {
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
|
||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-[90vw] max-w-4xl h-[85vh] flex flex-col mx-4">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-2xl">{pipeline.icon}</span>
|
||||
<div>
|
||||
<h2 className="text-lg font-semibold text-gray-900 dark:text-white">
|
||||
{pipeline.displayName} - 执行结果
|
||||
</h2>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||||
状态: {result.status === 'completed' ? '已完成' : '失败'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded"
|
||||
>
|
||||
<X className="w-5 h-5 text-gray-500" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="flex-1 overflow-hidden">
|
||||
{result.outputs ? (
|
||||
<PresentationContainer
|
||||
data={result.outputs}
|
||||
pipelineId={pipeline.id}
|
||||
supportedTypes={['document', 'chart', 'quiz', 'slideshow']}
|
||||
/>
|
||||
) : result.error ? (
|
||||
<div className="p-6 text-center text-red-500">
|
||||
<XCircle className="w-8 h-8 mx-auto mb-2" />
|
||||
<p>{result.error}</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="p-6 text-center text-gray-500">
|
||||
<Package className="w-8 h-8 mx-auto mb-2" />
|
||||
<p>无输出结果</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// === Pipeline Run Modal ===
|
||||
|
||||
interface RunModalProps {
|
||||
@@ -375,6 +434,7 @@ export function PipelinesPanel() {
|
||||
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [selectedPipeline, setSelectedPipeline] = useState<PipelineInfo | null>(null);
|
||||
const [runResult, setRunResult] = useState<{ result: PipelineRunResponse; pipeline: PipelineInfo } | null>(null);
|
||||
const { toast } = useToast();
|
||||
|
||||
// Fetch all pipelines without filtering
|
||||
@@ -412,6 +472,7 @@ export function PipelinesPanel() {
|
||||
setSelectedPipeline(null);
|
||||
if (result.status === 'completed') {
|
||||
toast('Pipeline 执行完成', 'success');
|
||||
setRunResult({ result, pipeline: selectedPipeline! });
|
||||
} else {
|
||||
toast(`Pipeline 执行失败: ${result.error}`, 'error');
|
||||
}
|
||||
@@ -524,6 +585,15 @@ export function PipelinesPanel() {
|
||||
onComplete={handleRunComplete}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Result Modal */}
|
||||
{runResult && (
|
||||
<ResultModal
|
||||
result={runResult.result}
|
||||
pipeline={runResult.pipeline}
|
||||
onClose={() => setRunResult(null)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user