11"use client" ;
22
3- import { useState } from "react" ;
3+ import { useState , useCallback } from "react" ;
44import { useAgent } from "@copilotkit/react-core/v2" ;
55import { TemplateCard } from "./template-card" ;
66
7+ /** Submit a message through the CopilotChat textarea so it goes through the full rendering pipeline */
8+ function submitChatPrompt ( text : string ) {
9+ const textarea = document . querySelector < HTMLTextAreaElement > (
10+ '[data-testid="copilot-chat-textarea"]'
11+ ) ;
12+ if ( ! textarea ) return ;
13+
14+ const setter = Object . getOwnPropertyDescriptor (
15+ window . HTMLTextAreaElement . prototype , "value"
16+ ) ?. set ;
17+ setter ?. call ( textarea , text ) ;
18+ textarea . dispatchEvent ( new Event ( "input" , { bubbles : true } ) ) ;
19+
20+ setTimeout ( ( ) => {
21+ const form = textarea . closest ( "form" ) ;
22+ if ( form ) form . requestSubmit ( ) ;
23+ } , 150 ) ;
24+ }
25+
726interface TemplateLibraryProps {
827 open : boolean ;
928 onClose : ( ) => void ;
10- onSendPrompt : ( text : string ) => void ;
1129}
1230
1331interface Template {
@@ -16,10 +34,11 @@ interface Template {
1634 description : string ;
1735 html : string ;
1836 data_description : string ;
37+ component_type ?: string ;
1938 version : number ;
2039}
2140
22- export function TemplateLibrary ( { open, onClose, onSendPrompt } : TemplateLibraryProps ) {
41+ export function TemplateLibrary ( { open, onClose } : TemplateLibraryProps ) {
2342 const { agent } = useAgent ( ) ;
2443 const templates : Template [ ] = agent . state ?. templates || [ ] ;
2544
@@ -35,21 +54,26 @@ export function TemplateLibrary({ open, onClose, onSendPrompt }: TemplateLibrary
3554 }
3655 } ;
3756
38- const handleApplyConfirm = ( ) => {
57+ const handleApplyConfirm = useCallback ( ( ) => {
3958 if ( ! applyingTemplate ) return ;
4059 const dataDesc = applyData . trim ( ) ;
4160 if ( ! dataDesc ) return ;
4261
43- // Send the template HTML directly in the prompt so the agent doesn't
44- // need to look it up from state (frontend setState may not sync to backend)
45- onSendPrompt (
46- `Use this saved template called "${ applyingTemplate . name } " as a base layout and adapt it for the following new data: ${ dataDesc } \n\n` +
47- `Here is the template HTML to adapt:\n\n${ applyingTemplate . html } `
48- ) ;
62+ const isChart =
63+ applyingTemplate . component_type === "barChart" ||
64+ applyingTemplate . component_type === "pieChart" ;
65+
66+ const chartType = applyingTemplate . component_type === "pieChart" ? "pie chart" : "bar chart" ;
67+ const message = isChart
68+ ? `Apply ${ chartType } template "${ applyingTemplate . name } " (${ applyingTemplate . id } ) with: ${ dataDesc } `
69+ : `Apply template "${ applyingTemplate . name } " (${ applyingTemplate . id } ) with: ${ dataDesc } ` ;
70+
71+ submitChatPrompt ( message ) ;
72+
4973 setApplyingTemplate ( null ) ;
5074 setApplyData ( "" ) ;
5175 onClose ( ) ;
52- } ;
76+ } , [ applyingTemplate , applyData , onClose ] ) ;
5377
5478 const handleApplyCancel = ( ) => {
5579 setApplyingTemplate ( null ) ;
@@ -153,6 +177,8 @@ export function TemplateLibrary({ open, onClose, onSendPrompt }: TemplateLibrary
153177 name = { t . name }
154178 description = { t . description }
155179 html = { t . html }
180+ componentType = { ( t as unknown as Record < string , unknown > ) . component_type as string | undefined }
181+ componentData = { ( t as unknown as Record < string , unknown > ) . component_data as Record < string , unknown > | undefined }
156182 dataDescription = { t . data_description }
157183 version = { t . version }
158184 onApply = { handleApplyClick }
0 commit comments