11import { useState , useEffect } from 'react' ;
22import { useOutletContext , useNavigate } from 'react-router-dom' ;
33import { actionApi } from '../utils/api' ;
4+ import FormFieldDefinition from '../components/common/FormFieldDefinition' ;
45
56function ActionsPlayground ( ) {
67 const { showToast } = useOutletContext ( ) ;
7- const navigate = useNavigate ( ) ;
88 const [ actions , setActions ] = useState ( [ ] ) ;
99 const [ selectedAction , setSelectedAction ] = useState ( '' ) ;
10- const [ configJson , setConfigJson ] = useState ( '{}' ) ;
11- const [ paramsJson , setParamsJson ] = useState ( '{}' ) ;
10+ const [ actionMeta , setActionMeta ] = useState ( null ) ;
11+ const [ configValues , setConfigValues ] = useState ( { } ) ;
12+ const [ paramsValues , setParamsValues ] = useState ( { } ) ;
1213 const [ result , setResult ] = useState ( null ) ;
1314 const [ loading , setLoading ] = useState ( false ) ;
1415 const [ loadingActions , setLoadingActions ] = useState ( true ) ;
@@ -24,33 +25,50 @@ function ActionsPlayground() {
2425 // Fetch available actions
2526 useEffect ( ( ) => {
2627 const fetchActions = async ( ) => {
27- try {
28- const response = await actionApi . listActions ( ) ;
29- setActions ( response ) ;
30- } catch ( err ) {
31- console . error ( 'Error fetching actions:' , err ) ;
32- showToast ( 'Failed to load actions' , 'error' ) ;
33- } finally {
34- setLoadingActions ( false ) ;
35- }
28+ const response = await actionApi . listActions ( ) ;
29+ setActions ( response ) ;
30+ setLoadingActions ( false ) ;
3631 } ;
3732
3833 fetchActions ( ) ;
39- } , [ showToast ] ) ;
34+ } , [ ] ) ;
35+
36+ // Fetch action metadata when an action is selected
37+ useEffect ( ( ) => {
38+ if ( selectedAction ) {
39+ const fetchActionMeta = async ( ) => {
40+ const response = await actionApi . getAgentConfigMeta ( ) ;
41+ const meta = response . actions . find ( a => a . name === selectedAction ) ;
42+ setActionMeta ( meta ) ;
43+ // Reset values when action changes
44+ setConfigValues ( { } ) ;
45+ setParamsValues ( { } ) ;
46+ } ;
47+
48+ fetchActionMeta ( ) ;
49+ }
50+ } , [ selectedAction ] ) ;
4051
4152 // Handle action selection
4253 const handleActionChange = ( e ) => {
4354 setSelectedAction ( e . target . value ) ;
4455 setResult ( null ) ;
4556 } ;
4657
47- // Handle JSON input changes
48- const handleConfigChange = ( e ) => {
49- setConfigJson ( e . target . value ) ;
58+ // Handle config field changes
59+ const handleConfigChange = ( fieldName , value ) => {
60+ setConfigValues ( prev => ( {
61+ ...prev ,
62+ [ fieldName ] : value
63+ } ) ) ;
5064 } ;
5165
52- const handleParamsChange = ( e ) => {
53- setParamsJson ( e . target . value ) ;
66+ // Handle params field changes
67+ const handleParamsChange = ( fieldName , value ) => {
68+ setParamsValues ( prev => ( {
69+ ...prev ,
70+ [ fieldName ] : value
71+ } ) ) ;
5472 } ;
5573
5674 // Execute the selected action
@@ -66,146 +84,77 @@ function ActionsPlayground() {
6684 setResult ( null ) ;
6785
6886 try {
69- // Parse JSON inputs
70- let config = { } ;
71- let params = { } ;
72-
73- try {
74- config = JSON . parse ( configJson ) ;
75- } catch ( err ) {
76- showToast ( 'Invalid configuration JSON' , 'error' ) ;
77- setLoading ( false ) ;
78- return ;
79- }
80-
81- try {
82- params = JSON . parse ( paramsJson ) ;
83- } catch ( err ) {
84- showToast ( 'Invalid parameters JSON' , 'error' ) ;
85- setLoading ( false ) ;
86- return ;
87- }
88-
8987 // Prepare action data
9088 const actionData = {
9189 action : selectedAction ,
92- config : config ,
93- params : params
90+ config : configValues ,
91+ params : paramsValues
9492 } ;
9593
9694 // Execute action
9795 const response = await actionApi . executeAction ( selectedAction , actionData ) ;
9896 setResult ( response ) ;
9997 showToast ( 'Action executed successfully' , 'success' ) ;
10098 } catch ( err ) {
101- console . error ( 'Error executing action:' , err ) ;
102- showToast ( `Failed to execute action: ${ err . message } ` , 'error' ) ;
99+ showToast ( 'Failed to execute action' , 'error' ) ;
103100 } finally {
104101 setLoading ( false ) ;
105102 }
106103 } ;
107104
108105 return (
109- < div className = "actions-playground-container" >
110- < header className = "page-header" >
111- < h1 > Actions Playground</ h1 >
112- < p > Test and execute actions directly from the UI</ p >
113- </ header >
106+ < div className = "actions-playground" >
107+ < h1 > Actions Playground</ h1 >
114108
115- < div className = "actions-playground-content" >
116- < div className = "section-box" >
117- < h2 > Select an Action</ h2 >
118-
119- < div className = "form-group mb-4" >
120- < label htmlFor = "action-select" > Available Actions:</ label >
121- < select
122- id = "action-select"
123- value = { selectedAction }
124- onChange = { handleActionChange }
125- className = "form-control"
126- disabled = { loadingActions }
127- >
128- < option value = "" > -- Select an action --</ option >
129- { actions . map ( ( action ) => (
130- < option key = { action } value = { action } > { action } </ option >
131- ) ) }
132- </ select >
133- </ div >
109+ < form onSubmit = { handleExecuteAction } >
110+ < div className = "form-group" >
111+ < label htmlFor = "actionSelect" > Select Action</ label >
112+ < select
113+ id = "actionSelect"
114+ value = { selectedAction }
115+ onChange = { handleActionChange }
116+ disabled = { loadingActions }
117+ >
118+ < option value = "" > Select an action...</ option >
119+ { actions . map ( action => (
120+ < option key = { action } value = { action } > { action } </ option >
121+ ) ) }
122+ </ select >
134123 </ div >
135-
136- { selectedAction && (
137- < div className = "section-box" >
138- < h2 > Action Configuration</ h2 >
139-
140- < form onSubmit = { handleExecuteAction } >
141- < div className = "form-group mb-6" >
142- < label htmlFor = "config-json" > Configuration (JSON):</ label >
143- < textarea
144- id = "config-json"
145- value = { configJson }
146- onChange = { handleConfigChange }
147- className = "form-control"
148- rows = "5"
149- placeholder = '{"key": "value"}'
150- />
151- < p className = "text-xs text-gray-400 mt-1" > Enter JSON configuration for the action</ p >
152- </ div >
153-
154- < div className = "form-group mb-6" >
155- < label htmlFor = "params-json" > Parameters (JSON):</ label >
156- < textarea
157- id = "params-json"
158- value = { paramsJson }
159- onChange = { handleParamsChange }
160- className = "form-control"
161- rows = "5"
162- placeholder = '{"key": "value"}'
163- />
164- < p className = "text-xs text-gray-400 mt-1" > Enter JSON parameters for the action</ p >
165- </ div >
166-
167- < div className = "flex justify-end" >
168- < button
169- type = "submit"
170- className = "action-btn"
171- disabled = { loading }
172- >
173- { loading ? (
174- < > < i className = "fas fa-spinner fa-spin" > </ i > Executing...</ >
175- ) : (
176- < > < i className = "fas fa-play" > </ i > Execute Action</ >
177- ) }
178- </ button >
179- </ div >
180- </ form >
181- </ div >
182- ) }
183-
184- { result && (
185- < div className = "section-box" >
186- < h2 > Action Results</ h2 >
187-
188- < div className = "result-container" style = { {
189- maxHeight : '400px' ,
190- overflow : 'auto' ,
191- border : '1px solid rgba(94, 0, 255, 0.2)' ,
192- borderRadius : '4px' ,
193- padding : '10px' ,
194- backgroundColor : 'rgba(30, 30, 30, 0.7)'
195- } } >
196- { typeof result === 'object' ? (
197- < pre style = { { margin : 0 , whiteSpace : 'pre-wrap' , wordBreak : 'break-word' } } >
198- { JSON . stringify ( result , null , 2 ) }
199- </ pre >
200- ) : (
201- < pre style = { { margin : 0 , whiteSpace : 'pre-wrap' , wordBreak : 'break-word' } } >
202- { result }
203- </ pre >
204- ) }
205- </ div >
206- </ div >
124+
125+ { actionMeta && (
126+ < >
127+ < h2 > Configuration</ h2 >
128+ < FormFieldDefinition
129+ fields = { actionMeta . configFields || [ ] }
130+ values = { configValues }
131+ onChange = { handleConfigChange }
132+ idPrefix = "config_"
133+ />
134+
135+ < h2 > Parameters</ h2 >
136+ < FormFieldDefinition
137+ fields = { actionMeta . paramFields || [ ] }
138+ values = { paramsValues }
139+ onChange = { handleParamsChange }
140+ idPrefix = "param_"
141+ />
142+ </ >
207143 ) }
208- </ div >
144+
145+ < div className = "form-group" >
146+ < button type = "submit" disabled = { loading || ! selectedAction } >
147+ { loading ? 'Executing...' : 'Execute Action' }
148+ </ button >
149+ </ div >
150+ </ form >
151+
152+ { result && (
153+ < div className = "result-section" >
154+ < h2 > Result</ h2 >
155+ < pre > { JSON . stringify ( result , null , 2 ) } </ pre >
156+ </ div >
157+ ) }
209158 </ div >
210159 ) ;
211160}
0 commit comments