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 { useState, useEffect } from 'react'
import { Link } from 'react-router-dom' 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 { useScriptGeneratorStore } from '@/store/scriptGeneratorStore'
import { usePermissions } from '@/hooks/usePermissions' import { usePermissions } from '@/hooks/usePermissions'
import { ScriptFilterBar } from '@/components/scripts/ScriptFilterBar' import { ScriptFilterBar } from '@/components/scripts/ScriptFilterBar'
import { ScriptTemplateList } from '@/components/scripts/ScriptTemplateList' import { ScriptTemplateList } from '@/components/scripts/ScriptTemplateList'
import { ScriptConfigurePane } from '@/components/scripts/ScriptConfigurePane' import { ScriptConfigurePane } from '@/components/scripts/ScriptConfigurePane'
import { ScriptPreview } from '@/components/scripts/ScriptPreview' 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' type LibraryTab = 'mine' | 'team'
@@ -23,8 +26,35 @@ export default function ScriptLibraryPage() {
const clearOutput = useScriptGeneratorStore(s => s.clearOutput) const clearOutput = useScriptGeneratorStore(s => s.clearOutput)
const selectedTemplate = useScriptGeneratorStore(s => s.selectedTemplate) const selectedTemplate = useScriptGeneratorStore(s => s.selectedTemplate)
const categories = useScriptGeneratorStore(s => s.categories)
const { isEngineer } = usePermissions() const { isEngineer } = usePermissions()
const canGenerate = isEngineer 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(() => { useEffect(() => {
loadCategories().then(() => { loadCategories().then(() => {
@@ -70,13 +100,23 @@ export default function ScriptLibraryPage() {
Browse PowerShell templates, fill in parameters, and generate ready-to-run scripts. Browse PowerShell templates, fill in parameters, and generate ready-to-run scripts.
</p> </p>
{isEngineer && ( {isEngineer && (
<Link <div className="flex items-center gap-2 mt-2">
to="/scripts/manage" <Link
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" 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 <Settings size={12} className="group-hover:rotate-90 transition-transform duration-300" />
</Link> 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> </div>
<Link <Link
@@ -138,6 +178,14 @@ export default function ScriptLibraryPage() {
</div> </div>
)} )}
</div> </div>
{/* Import script panel */}
{showImportPanel && (
<ParameterizeAndSavePanel
onSave={handleImportSave}
onClose={() => setShowImportPanel(false)}
/>
)}
</div> </div>
) )
} }