初始化模版工程
This commit is contained in:
110
components/nova-sdk/task-panel/Preview/ShellExecutePreview.tsx
Normal file
110
components/nova-sdk/task-panel/Preview/ShellExecutePreview.tsx
Normal file
@@ -0,0 +1,110 @@
|
||||
import { Loader2 } from 'lucide-react'
|
||||
import ScriptPreview from './ScriptPreview'
|
||||
|
||||
export interface ShellExecutePreviewProps {
|
||||
/** shell_execute 的输出文本(已做 ANSI 处理) */
|
||||
output: string
|
||||
/** 顶部和终端中展示的工具名称,默认 shell_execute */
|
||||
toolLabel?: string
|
||||
/** 是否处于加载中(统一在终端里展示 loading) */
|
||||
loading?: boolean
|
||||
}
|
||||
|
||||
export function ShellExecutePreview({
|
||||
output,
|
||||
toolLabel = 'shell_execute',
|
||||
loading = false,
|
||||
}: ShellExecutePreviewProps) {
|
||||
const safeOutput = output || 'No output'
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center py-10 h-full">
|
||||
<Loader2 className="h-6 w-6 animate-spin text-primary" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`flex w-full bg-background text-foreground ${
|
||||
!loading ? 'animate-in fade-in-0 slide-in-from-bottom-2 duration-300' : ''
|
||||
}`}
|
||||
style={{ height: 'calc(100% + 20px)' }}
|
||||
>
|
||||
{/* 右侧主体区域 */}
|
||||
<div className="flex-1 flex flex-col h-full">
|
||||
{/* 内容区域:一张终端卡片 */}
|
||||
<main className="flex-1 overflow-y-auto custom-scrollbar px-3 md:px-6 py-4 md:py-6 flex items-center justify-center">
|
||||
<div className="max-w-4xl mx-auto space-y-4 md:space-y-6 min-w-[60%]">
|
||||
{/* 终端卡片,主进场:从下浮现 + 略微缩放 */}
|
||||
<div
|
||||
className={`min-h-[200px] overflow-hidden rounded-xl border ${
|
||||
!loading
|
||||
? 'animate-in fade-in-0 zoom-in-95 slide-in-from-bottom-4 duration-500'
|
||||
: ''
|
||||
}`}
|
||||
style={{
|
||||
backgroundColor: 'var(--terminal-background)',
|
||||
borderColor: 'var(--terminal-border)',
|
||||
...( !loading ? { animationTimingFunction: 'cubic-bezier(0.16, 1, 0.3, 1)' } : {}),
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="flex items-center justify-between border-b px-3 py-2 md:px-4"
|
||||
style={{
|
||||
backgroundColor: 'var(--terminal-surface)',
|
||||
borderColor: 'var(--terminal-border)',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={`flex gap-1.5 ${
|
||||
!loading ? 'animate-in fade-in zoom-in-75 duration-700 fill-mode-both' : ''
|
||||
}`}
|
||||
>
|
||||
<div className="h-2.5 w-2.5 rounded-full transition-colors" style={{ backgroundColor: 'color-mix(in srgb, var(--destructive) 72%, transparent)' }} />
|
||||
<div className="h-2.5 w-2.5 rounded-full transition-colors" style={{ backgroundColor: 'color-mix(in srgb, var(--warning) 72%, transparent)' }} />
|
||||
<div className="h-2.5 w-2.5 rounded-full transition-colors" style={{ backgroundColor: 'color-mix(in srgb, var(--success) 72%, transparent)' }} />
|
||||
</div>
|
||||
<span
|
||||
className={`text-[10px] font-mono ${
|
||||
!loading ? 'animate-in fade-in slide-in-from-top-1 duration-700 fill-mode-both' : ''
|
||||
}`}
|
||||
style={{ color: 'var(--terminal-text-muted)' }}
|
||||
>
|
||||
bash — {toolLabel}
|
||||
</span>
|
||||
</div>
|
||||
<div className="relative space-y-2 py-3 font-mono text-[11px] md:py-4 md:text-xs" style={{ color: 'var(--terminal-text)' }}>
|
||||
<div
|
||||
className={`flex gap-2 mb-1 px-3 md:px-4 ${
|
||||
!loading ? 'animate-in fade-in-0 slide-in-from-left-2 duration-500' : ''
|
||||
}`}
|
||||
>
|
||||
<span style={{ color: 'var(--terminal-prompt)' }}>$</span>
|
||||
<span className="truncate" style={{ color: 'var(--terminal-text)' }}>{toolLabel}</span>
|
||||
</div>
|
||||
<div
|
||||
className={`mt-2 max-h-[420px] overflow-auto whitespace-pre-wrap border-t px-3 pt-2 custom-scrollbar md:px-4 ${
|
||||
!loading ? 'animate-in fade-in-0 slide-in-from-bottom-2 duration-500' : ''
|
||||
}`}
|
||||
style={{
|
||||
borderColor: 'var(--terminal-border)',
|
||||
color: 'var(--terminal-text)',
|
||||
}}
|
||||
>
|
||||
<ScriptPreview
|
||||
code={safeOutput}
|
||||
language="bash"
|
||||
title={toolLabel}
|
||||
theme="github-dark-default"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user