191 lines
6.1 KiB
JavaScript
191 lines
6.1 KiB
JavaScript
import { useState, useMemo } from "react";
|
|
import { krowSDK } from "@/api/krowSDK";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from "@/components/ui/select";
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import ApiResponse from "@/components/ApiResponse";
|
|
import { Textarea } from "@/components/ui/textarea";
|
|
import { Label } from "@/components/ui/label";
|
|
|
|
const entityNames = Object.keys(krowSDK.entities).sort();
|
|
|
|
const getPrettifiedJSON = (entity, method) => {
|
|
// Basic placeholder payloads. A more advanced SDK could provide detailed examples.
|
|
const payloads = {
|
|
get: { id: "some-id" },
|
|
create: { data: { property: "value" } },
|
|
update: { id: "some-id", data: { property: "new-value" } },
|
|
delete: { id: "some-id" },
|
|
filter: { where: { property: { _eq: "value" } } },
|
|
list: {}
|
|
};
|
|
return JSON.stringify(payloads[method] || {}, null, 2);
|
|
};
|
|
|
|
const EntityTester = () => {
|
|
const [selectedEntity, setSelectedEntity] = useState(null);
|
|
const [selectedMethod, setSelectedMethod] = useState(null);
|
|
const [response, setResponse] = useState(null);
|
|
const [error, setError] = useState(null);
|
|
const [loading, setLoading] = useState(false);
|
|
const [jsonInput, setJsonInput] = useState("");
|
|
const [jsonError, setJsonError] = useState(null);
|
|
|
|
const availableMethods = useMemo(() => {
|
|
if (!selectedEntity) return [];
|
|
return Object.keys(krowSDK.entities[selectedEntity]);
|
|
}, [selectedEntity]);
|
|
|
|
const handleEntityChange = (entity) => {
|
|
setSelectedEntity(entity);
|
|
setSelectedMethod(null);
|
|
setJsonInput("");
|
|
setJsonError(null);
|
|
setResponse(null);
|
|
setError(null);
|
|
};
|
|
|
|
const handleMethodSelect = (method) => {
|
|
setSelectedMethod(method);
|
|
setJsonInput(getPrettifiedJSON(selectedEntity, method));
|
|
setJsonError(null);
|
|
setResponse(null);
|
|
setError(null);
|
|
};
|
|
|
|
const handleJsonInputChange = (e) => {
|
|
setJsonInput(e.target.value);
|
|
try {
|
|
JSON.parse(e.target.value);
|
|
setJsonError(null);
|
|
} catch (err) {
|
|
setJsonError("Invalid JSON format");
|
|
}
|
|
};
|
|
|
|
const executeApi = async () => {
|
|
if (!selectedEntity || !selectedMethod || jsonError) return;
|
|
|
|
setLoading(true);
|
|
setResponse(null);
|
|
setError(null);
|
|
|
|
try {
|
|
const params = JSON.parse(jsonInput);
|
|
const sdkMethod = krowSDK.entities[selectedEntity][selectedMethod];
|
|
const res = await sdkMethod(params);
|
|
setResponse(res);
|
|
} catch (err) {
|
|
setError(err.response?.data || err.message);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const renderMethodForm = () => {
|
|
if (!selectedMethod) {
|
|
return (
|
|
<div className="mt-4 p-4 text-center text-slate-500 bg-slate-50 rounded-lg">
|
|
<p>Select a method to begin.</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="space-y-4 mt-6">
|
|
<h3 className="text-lg font-semibold text-slate-800">
|
|
Parameters for <code className="bg-slate-100 p-1 rounded text-sm">/{selectedEntity}/{selectedMethod}</code>
|
|
</h3>
|
|
|
|
{/*
|
|
This is a textarea for JSON input. A more advanced implementation could
|
|
dynamically generate a form based on the expected parameters of each
|
|
SDK method, but that requires metadata about each method's signature
|
|
which is not currently available in the mock client.
|
|
*/}
|
|
<div className="space-y-2">
|
|
<Label htmlFor="params">JSON Payload</Label>
|
|
<Textarea
|
|
id="params"
|
|
name="params"
|
|
value={jsonInput}
|
|
onChange={handleJsonInputChange}
|
|
rows={8}
|
|
className={`font-mono text-sm ${jsonError ? 'border-red-500 focus-visible:ring-red-500' : ''}`}
|
|
/>
|
|
{jsonError && <p className="text-xs text-red-600">{jsonError}</p>}
|
|
</div>
|
|
|
|
<Button onClick={executeApi} disabled={loading || !!jsonError}>
|
|
{loading ? "Executing..." : "Execute"}
|
|
</Button>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<header className="mb-8">
|
|
<h1 className="text-3xl font-bold text-slate-900">Entity API Tester</h1>
|
|
<p className="text-slate-600 mt-1">
|
|
Select an entity and method, provide the required parameters in JSON format, and execute the API call.
|
|
</p>
|
|
</header>
|
|
|
|
<Card className="shadow-sm">
|
|
<CardHeader>
|
|
<CardTitle>API Configuration</CardTitle>
|
|
<CardDescription>Choose a Base44 entity and method to interact with.</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
|
|
<div className="col-span-1">
|
|
<Label>Entity</Label>
|
|
<Select onValueChange={handleEntityChange} value={selectedEntity || ""}>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Select an entity" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{entityNames.map(entity => (
|
|
<SelectItem key={entity} value={entity}>{entity}</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
|
|
{selectedEntity && (
|
|
<div className="col-span-2">
|
|
<Label>Method</Label>
|
|
<div className="flex flex-wrap items-center gap-2 pt-2">
|
|
{availableMethods.map(method => (
|
|
<Button
|
|
key={method}
|
|
variant={selectedMethod === method ? "default" : "outline"}
|
|
size="sm"
|
|
onClick={() => handleMethodSelect(method)}
|
|
>
|
|
{method}
|
|
</Button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{renderMethodForm()}
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<ApiResponse response={response} error={error} loading={loading} />
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default EntityTester;
|