feat: Script Generator Phase 1 — backend models, engine, API, and AD templates #105

Merged
chihlasm merged 78 commits from feat/script-generator into main 2026-03-15 00:19:00 +00:00
2 changed files with 24 additions and 13 deletions
Showing only changes of commit 5768e04804 - Show all commits

View File

@@ -9,6 +9,14 @@ interface Props {
export function ScriptBodyEditor({ value, onChange, disabled }: Props) {
const textareaRef = useRef<HTMLTextAreaElement>(null)
const overlayRef = useRef<HTMLDivElement>(null)
const handleScroll = useCallback(() => {
if (textareaRef.current && overlayRef.current) {
overlayRef.current.scrollTop = textareaRef.current.scrollTop
overlayRef.current.scrollLeft = textareaRef.current.scrollLeft
}
}, [])
const handleTab = useCallback((e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (e.key === 'Tab') {
@@ -26,9 +34,9 @@ export function ScriptBodyEditor({ value, onChange, disabled }: Props) {
}, [value, onChange])
return (
<div className="relative rounded-xl border border-border">
{/* Highlighted overlay (read-only visual layer) */}
<div className="absolute inset-0 pointer-events-none overflow-auto p-4">
<div className="relative rounded-xl border border-border overflow-hidden">
{/* Highlighted overlay (read-only visual layer) — scroll synced to textarea */}
<div ref={overlayRef} className="absolute inset-0 pointer-events-none overflow-hidden p-4">
<PowerShellHighlighter script={value || ' '} />
</div>
@@ -37,6 +45,7 @@ export function ScriptBodyEditor({ value, onChange, disabled }: Props) {
ref={textareaRef}
value={value}
onChange={e => onChange(e.target.value)}
onScroll={handleScroll}
onKeyDown={handleTab}
disabled={disabled}
spellCheck={false}

View File

@@ -27,16 +27,18 @@ export default function ScriptManagePage() {
}
return (
<div className="p-6 max-w-5xl mx-auto h-full overflow-y-auto">
{mode === 'list' ? (
<ScriptTemplateListView onEdit={handleEdit} onCreate={handleCreate} />
) : (
<ScriptTemplateEditor
templateId={editingId}
onBack={handleBack}
onSaved={handleSaved}
/>
)}
<div className="h-full overflow-y-auto">
<div className="p-6 max-w-5xl mx-auto">
{mode === 'list' ? (
<ScriptTemplateListView onEdit={handleEdit} onCreate={handleCreate} />
) : (
<ScriptTemplateEditor
templateId={editingId}
onBack={handleBack}
onSaved={handleSaved}
/>
)}
</div>
</div>
)
}