feat: delete ScriptGeneratorPanel — superseded by ScriptConfigurePane
The right pane is now ScriptPreview-only. Generate/Download/Copy controls moved to ScriptConfigurePane in the left pane (configure mode). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,115 +0,0 @@
|
|||||||
import { Terminal, Download, Loader2, AlertTriangle } from 'lucide-react'
|
|
||||||
import { useScriptGeneratorStore } from '@/store/scriptGeneratorStore'
|
|
||||||
import { usePermissions } from '@/hooks/usePermissions'
|
|
||||||
import { ScriptParameterForm } from './ScriptParameterForm'
|
|
||||||
import { ScriptPreview } from './ScriptPreview'
|
|
||||||
|
|
||||||
export function ScriptGeneratorPanel() {
|
|
||||||
const selectedTemplate = useScriptGeneratorStore(s => s.selectedTemplate)
|
|
||||||
const isLoadingDetail = useScriptGeneratorStore(s => s.isLoadingDetail)
|
|
||||||
const generatedScript = useScriptGeneratorStore(s => s.generatedScript)
|
|
||||||
const generationWarnings = useScriptGeneratorStore(s => s.generationWarnings)
|
|
||||||
const isGenerating = useScriptGeneratorStore(s => s.isGenerating)
|
|
||||||
const generateError = useScriptGeneratorStore(s => s.generateError)
|
|
||||||
const generate = useScriptGeneratorStore(s => s.generate)
|
|
||||||
|
|
||||||
const { isEngineer } = usePermissions()
|
|
||||||
const canGenerate = isEngineer
|
|
||||||
|
|
||||||
// No template selected
|
|
||||||
if (!selectedTemplate && !isLoadingDetail) {
|
|
||||||
return (
|
|
||||||
<div className="glass-card-static h-full flex flex-col items-center justify-center gap-3 text-center p-8">
|
|
||||||
<Terminal size={40} className="text-muted-foreground/40" />
|
|
||||||
<p className="text-sm text-muted-foreground">Select a template to get started</p>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loading template detail
|
|
||||||
if (isLoadingDetail) {
|
|
||||||
return (
|
|
||||||
<div className="glass-card-static h-full flex items-center justify-center">
|
|
||||||
<Loader2 size={28} className="text-primary animate-spin" />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!selectedTemplate) return null
|
|
||||||
|
|
||||||
const handleDownload = () => {
|
|
||||||
if (!generatedScript) return
|
|
||||||
const blob = new Blob([generatedScript], { type: 'text/plain' })
|
|
||||||
const url = URL.createObjectURL(blob)
|
|
||||||
const a = document.createElement('a')
|
|
||||||
a.href = url
|
|
||||||
a.download = `${selectedTemplate.slug}.ps1`
|
|
||||||
document.body.appendChild(a)
|
|
||||||
a.click()
|
|
||||||
document.body.removeChild(a)
|
|
||||||
URL.revokeObjectURL(url)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="glass-card-static h-full flex flex-col gap-4 p-4 overflow-y-auto">
|
|
||||||
{/* Header */}
|
|
||||||
<div>
|
|
||||||
<h2 className="text-base font-semibold text-foreground">{selectedTemplate.name}</h2>
|
|
||||||
{selectedTemplate.description && (
|
|
||||||
<p className="text-sm text-muted-foreground mt-0.5">{selectedTemplate.description}</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Parameter form */}
|
|
||||||
<ScriptParameterForm canGenerate={canGenerate} />
|
|
||||||
|
|
||||||
{/* Warnings */}
|
|
||||||
{generationWarnings.length > 0 && (
|
|
||||||
<div className="flex flex-col gap-1 rounded-lg border border-amber-400/20 bg-amber-400/5 p-3">
|
|
||||||
<div className="flex items-center gap-1.5 text-amber-400 text-xs font-medium mb-1">
|
|
||||||
<AlertTriangle size={13} />
|
|
||||||
Warnings
|
|
||||||
</div>
|
|
||||||
{generationWarnings.map((w, i) => (
|
|
||||||
<p key={i} className="text-xs text-amber-400/80">{w}</p>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Preview */}
|
|
||||||
<ScriptPreview />
|
|
||||||
|
|
||||||
{/* Action bar */}
|
|
||||||
<div className="flex items-center gap-2 pt-1">
|
|
||||||
<span title={!canGenerate ? 'Engineer access required' : undefined}>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => generate()}
|
|
||||||
disabled={isGenerating || !canGenerate}
|
|
||||||
className="flex items-center gap-1.5 bg-gradient-brand text-[#101114] font-semibold text-sm px-4 py-2 rounded-[10px] hover:opacity-90 active:scale-[0.97] transition-all shadow-lg shadow-primary/20 disabled:opacity-50 disabled:cursor-not-allowed disabled:active:scale-100"
|
|
||||||
>
|
|
||||||
{isGenerating && <Loader2 size={14} className="animate-spin" />}
|
|
||||||
Generate
|
|
||||||
</button>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span title={!canGenerate ? 'Engineer access required' : undefined}>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={handleDownload}
|
|
||||||
disabled={!generatedScript || !canGenerate}
|
|
||||||
className="flex items-center gap-1.5 bg-white/5 border border-border text-foreground text-sm px-4 py-2 rounded-[10px] hover:border-[rgba(255,255,255,0.12)] transition-all disabled:opacity-50 disabled:cursor-not-allowed"
|
|
||||||
>
|
|
||||||
<Download size={14} />
|
|
||||||
Download .ps1
|
|
||||||
</button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Generate error */}
|
|
||||||
{generateError && (
|
|
||||||
<p className="text-xs text-rose-500">{generateError}</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user