feat: add 'New from Script' button to ScriptLibraryPage

Opens the ParameterizeAndSavePanel in paste mode, letting users import
raw scripts with parameter detection and review before saving to library.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-03-29 05:54:48 +00:00
parent da71cd6ca4
commit 00e4a16ab5

View File

@@ -1,12 +1,15 @@
import { useState, useEffect } from 'react'
import { Link } from 'react-router-dom'
import { Terminal, Settings, Wand2 } from 'lucide-react'
import { Terminal, Settings, Wand2, FileUp } from 'lucide-react'
import { useScriptGeneratorStore } from '@/store/scriptGeneratorStore'
import { usePermissions } from '@/hooks/usePermissions'
import { ScriptFilterBar } from '@/components/scripts/ScriptFilterBar'
import { ScriptTemplateList } from '@/components/scripts/ScriptTemplateList'
import { ScriptConfigurePane } from '@/components/scripts/ScriptConfigurePane'
import { ScriptPreview } from '@/components/scripts/ScriptPreview'
import { ParameterizeAndSavePanel } from '@/components/scripts/ParameterizeAndSavePanel'
import { scriptsApi } from '@/api'
import type { ScriptParameter } from '@/types'
type LibraryTab = 'mine' | 'team'
@@ -23,8 +26,35 @@ export default function ScriptLibraryPage() {
const clearOutput = useScriptGeneratorStore(s => s.clearOutput)
const selectedTemplate = useScriptGeneratorStore(s => s.selectedTemplate)
const categories = useScriptGeneratorStore(s => s.categories)
const { isEngineer } = usePermissions()
const canGenerate = isEngineer
const [showImportPanel, setShowImportPanel] = useState(false)
const handleImportSave = async (payload: {
name: string
description: string | undefined
category_id: string | undefined
share_with_team: boolean
script_body: string
parameters_schema: { parameters: ScriptParameter[] }
}) => {
const categoryId = payload.category_id || categories[0]?.id
if (!categoryId) {
throw new Error('No categories available. Please create a category first.')
}
await scriptsApi.createTemplate({
category_id: categoryId,
name: payload.name,
description: payload.description,
script_body: payload.script_body,
parameters_schema: payload.parameters_schema,
})
setShowImportPanel(false)
const filters = activeTab === 'mine' ? { mine: true } : { shared: true }
loadTemplates(filters)
}
useEffect(() => {
loadCategories().then(() => {
@@ -70,13 +100,23 @@ export default function ScriptLibraryPage() {
Browse PowerShell templates, fill in parameters, and generate ready-to-run scripts.
</p>
{isEngineer && (
<Link
to="/scripts/manage"
className="inline-flex items-center gap-1.5 text-xs text-primary bg-accent-dim hover:bg-primary/15 px-2.5 py-1 rounded-full transition-colors mt-2 group"
>
<Settings size={12} className="group-hover:rotate-90 transition-transform duration-300" />
Manage Templates
</Link>
<div className="flex items-center gap-2 mt-2">
<Link
to="/scripts/manage"
className="inline-flex items-center gap-1.5 text-xs text-primary bg-accent-dim hover:bg-primary/15 px-2.5 py-1 rounded-full transition-colors group"
>
<Settings size={12} className="group-hover:rotate-90 transition-transform duration-300" />
Manage Templates
</Link>
<button
type="button"
onClick={() => setShowImportPanel(true)}
className="inline-flex items-center gap-1.5 text-xs text-primary bg-accent-dim hover:bg-primary/15 px-2.5 py-1 rounded-full transition-colors"
>
<FileUp size={12} />
New from Script
</button>
</div>
)}
</div>
<Link
@@ -138,6 +178,14 @@ export default function ScriptLibraryPage() {
</div>
)}
</div>
{/* Import script panel */}
{showImportPanel && (
<ParameterizeAndSavePanel
onSave={handleImportSave}
onClose={() => setShowImportPanel(false)}
/>
)}
</div>
)
}