diff --git a/webui/react-ui/src/App.jsx b/webui/react-ui/src/App.jsx
index 2aeb250..decbba7 100644
--- a/webui/react-ui/src/App.jsx
+++ b/webui/react-ui/src/App.jsx
@@ -1,5 +1,5 @@
import { useState } from 'react'
-import { Outlet, Link } from 'react-router-dom'
+import { Outlet, Link, useOutletContext } from 'react-router-dom'
import './App.css'
function App() {
@@ -19,6 +19,9 @@ function App() {
setMobileMenuOpen(!mobileMenuOpen);
};
+ // Provide showToast to children
+ const context = { showToast };
+
return (
{/* Navigation Menu */}
@@ -110,7 +113,7 @@ function App() {
{/* Main Content Area */}
-
+
diff --git a/webui/react-ui/src/pages/ActionsPlayground.jsx b/webui/react-ui/src/pages/ActionsPlayground.jsx
index 355338e..c3ed28c 100644
--- a/webui/react-ui/src/pages/ActionsPlayground.jsx
+++ b/webui/react-ui/src/pages/ActionsPlayground.jsx
@@ -1,14 +1,15 @@
import { useState, useEffect } from 'react';
import { useOutletContext, useNavigate } from 'react-router-dom';
import { actionApi } from '../utils/api';
+import FormFieldDefinition from '../components/common/FormFieldDefinition';
function ActionsPlayground() {
const { showToast } = useOutletContext();
- const navigate = useNavigate();
const [actions, setActions] = useState([]);
const [selectedAction, setSelectedAction] = useState('');
- const [configJson, setConfigJson] = useState('{}');
- const [paramsJson, setParamsJson] = useState('{}');
+ const [actionMeta, setActionMeta] = useState(null);
+ const [configValues, setConfigValues] = useState({});
+ const [paramsValues, setParamsValues] = useState({});
const [result, setResult] = useState(null);
const [loading, setLoading] = useState(false);
const [loadingActions, setLoadingActions] = useState(true);
@@ -24,19 +25,29 @@ function ActionsPlayground() {
// Fetch available actions
useEffect(() => {
const fetchActions = async () => {
- try {
- const response = await actionApi.listActions();
- setActions(response);
- } catch (err) {
- console.error('Error fetching actions:', err);
- showToast('Failed to load actions', 'error');
- } finally {
- setLoadingActions(false);
- }
+ const response = await actionApi.listActions();
+ setActions(response);
+ setLoadingActions(false);
};
fetchActions();
- }, [showToast]);
+ }, []);
+
+ // Fetch action metadata when an action is selected
+ useEffect(() => {
+ if (selectedAction) {
+ const fetchActionMeta = async () => {
+ const response = await actionApi.getAgentConfigMeta();
+ const meta = response.actions.find(a => a.name === selectedAction);
+ setActionMeta(meta);
+ // Reset values when action changes
+ setConfigValues({});
+ setParamsValues({});
+ };
+
+ fetchActionMeta();
+ }
+ }, [selectedAction]);
// Handle action selection
const handleActionChange = (e) => {
@@ -44,13 +55,20 @@ function ActionsPlayground() {
setResult(null);
};
- // Handle JSON input changes
- const handleConfigChange = (e) => {
- setConfigJson(e.target.value);
+ // Handle config field changes
+ const handleConfigChange = (fieldName, value) => {
+ setConfigValues(prev => ({
+ ...prev,
+ [fieldName]: value
+ }));
};
- const handleParamsChange = (e) => {
- setParamsJson(e.target.value);
+ // Handle params field changes
+ const handleParamsChange = (fieldName, value) => {
+ setParamsValues(prev => ({
+ ...prev,
+ [fieldName]: value
+ }));
};
// Execute the selected action
@@ -66,31 +84,11 @@ function ActionsPlayground() {
setResult(null);
try {
- // Parse JSON inputs
- let config = {};
- let params = {};
-
- try {
- config = JSON.parse(configJson);
- } catch (err) {
- showToast('Invalid configuration JSON', 'error');
- setLoading(false);
- return;
- }
-
- try {
- params = JSON.parse(paramsJson);
- } catch (err) {
- showToast('Invalid parameters JSON', 'error');
- setLoading(false);
- return;
- }
-
// Prepare action data
const actionData = {
action: selectedAction,
- config: config,
- params: params
+ config: configValues,
+ params: paramsValues
};
// Execute action
@@ -98,114 +96,65 @@ function ActionsPlayground() {
setResult(response);
showToast('Action executed successfully', 'success');
} catch (err) {
- console.error('Error executing action:', err);
- showToast(`Failed to execute action: ${err.message}`, 'error');
+ showToast('Failed to execute action', 'error');
} finally {
setLoading(false);
}
};
return (
-
-
+
+
Actions Playground
-
-
-
Select an Action
-
-
-
-
-
+
+
+
+
+
+
+
+ {result && (
+
+
Result
+
{JSON.stringify(result, null, 2)}
+
+ )}
);
}
diff --git a/webui/react-ui/src/utils/api.js b/webui/react-ui/src/utils/api.js
index 9f7eb80..9f1db4a 100644
--- a/webui/react-ui/src/utils/api.js
+++ b/webui/react-ui/src/utils/api.js
@@ -216,6 +216,14 @@ export const actionApi = {
return handleResponse(response);
},
+ // Get agent configuration metadata
+ getAgentConfigMeta: async () => {
+ const response = await fetch(buildUrl(API_CONFIG.endpoints.agentConfigMetadata), {
+ headers: API_CONFIG.headers
+ });
+ return handleResponse(response);
+ },
+
// Execute an action for an agent
executeAction: async (name, actionData) => {
const response = await fetch(buildUrl(API_CONFIG.endpoints.executeAction(name)), {