diff --git a/crates/app/src/App.tsx b/crates/app/src/App.tsx index 44c6d4efa..85e7e3002 100644 --- a/crates/app/src/App.tsx +++ b/crates/app/src/App.tsx @@ -1,23 +1,23 @@ -import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; +import {BrowserRouter as Router, Route, Routes} from "react-router-dom"; import Components from "@/pages/components"; import CreateComponent from "@/pages/components/create"; -import { APIs } from "@/pages/api"; +import {APIs} from "@/pages/api"; import CreateAPI from "@/pages/api/create"; import APIDetails from "@/pages/api/details"; import APISettings from "@/pages/api/details/settings"; import CreateRoute from "@/pages/api/details/createRoute.tsx"; import Deployments from "@/pages/deployment"; -import { ComponentDetails } from "@/pages/components/details"; -import { PluginList } from "@/pages/plugin"; +import {ComponentDetails} from "@/pages/components/details"; +import {PluginList} from "@/pages/plugin"; import ComponentSettings from "@/pages/components/details/settings"; import ComponentInfo from "@/pages/components/details/info"; import Exports from "@/pages/components/details/export"; import ComponentUpdate from "@/pages/components/details/update"; import WorkerList from "@/pages/workers"; -import { ThemeProvider } from "@/components/theme-provider.tsx"; +import {ThemeProvider} from "@/components/theme-provider.tsx"; import Navbar from "@/components/navbar.tsx"; import APINewVersion from "./pages/api/details/newVersion"; -import { Dashboard } from "@/pages/dashboard"; +import {Dashboard} from "@/pages/dashboard"; import CreateWorker from "@/pages/workers/create"; import WorkerDetails from "@/pages/workers/details"; import ErrorBoundary from "@/components/errorBoundary"; @@ -26,106 +26,112 @@ import WorkerManage from "@/pages/workers/details/manage"; import WorkerInvoke from "@/pages/workers/details/invoke"; import WorkerLive from "@/pages/workers/details/live"; import CreatePlugin from "@/pages/plugin/create.tsx"; -import { PluginView } from "@/pages/plugin/view.tsx"; -import { ApiRoute } from "@/pages/api/details/viewRoute"; +import {PluginView} from "@/pages/plugin/view.tsx"; +import {ApiRoute} from "@/pages/api/details/viewRoute"; import CreateDeployment from "@/pages/deployment/create"; -import { ApiLayout } from "./pages/api/details/api-layout"; +import {ApiLayout} from "./pages/api/details/api-layout"; import ComponentInvoke from "@/pages/components/details/invoke"; +import Plugins from "@/pages/components/details/plugin.tsx"; function App() { - return ( - - -
- - - - - } /> - } /> - } /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } /> - } /> - } - > - } /> - } /> - } /> - } /> - } /> - } /> - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } - /> - -
-
-
- ); + return ( + + +
+ + + + + }/> + }/> + }/> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + }/> + }/> + } + > + }/> + }/> + }/> + }/> + }/> + }/> + + }/> + }/> + }/> + }/> + }/> + }/> + }/> + }/> + } + /> + +
+
+
+ ); } export default App; diff --git a/crates/app/src/pages/components/details/componentsLeftNav.tsx b/crates/app/src/pages/components/details/componentsLeftNav.tsx index 7f9f64262..034f98940 100644 --- a/crates/app/src/pages/components/details/componentsLeftNav.tsx +++ b/crates/app/src/pages/components/details/componentsLeftNav.tsx @@ -1,162 +1,169 @@ -import { useNavigate, useParams, useLocation } from "react-router-dom"; -import { - ArrowRightFromLine, - Home, - Pencil, - Settings, - ArrowLeft, - Pickaxe, - Info, - Workflow, -} from "lucide-react"; +import {useLocation, useNavigate, useParams} from "react-router-dom"; +import {ArrowLeft, ArrowRightFromLine, Home, Info, Pencil, Pickaxe, Settings, ToyBrick, Workflow,} from "lucide-react"; -import { Button } from "@/components/ui/button"; -import { cn } from "@/lib/utils"; +import {Button} from "@/components/ui/button"; +import {cn} from "@/lib/utils"; import ErrorBoundary from "@/components/errorBoundary"; -import { Component } from "@/types/component"; +import {Component} from "@/types/component"; interface ComponentLeftNavProps { - componentDetails: Component; + componentDetails: Component; } const ComponentLeftNav: React.FC = ({ - componentDetails, -}) => { - const navigate = useNavigate(); - const { componentId } = useParams(); - const location = useLocation(); + componentDetails, + }) => { + const navigate = useNavigate(); + const {componentId} = useParams(); + const location = useLocation(); - const isActive = (path: string) => location.pathname.endsWith(path); + const isActive = (path: string) => location.pathname.endsWith(path); - return ( - - + + ); }; export default ComponentLeftNav; diff --git a/crates/app/src/pages/components/details/plugin.tsx b/crates/app/src/pages/components/details/plugin.tsx new file mode 100644 index 000000000..ece8f377c --- /dev/null +++ b/crates/app/src/pages/components/details/plugin.tsx @@ -0,0 +1,216 @@ +import {Search} from "lucide-react"; +import {Input} from "@/components/ui/input"; +import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow,} from "@/components/ui/table"; +import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue,} from "@/components/ui/select"; +import ComponentLeftNav from "./componentsLeftNav"; +import {useEffect, useState} from "react"; +import {API} from "@/service"; +import {useParams} from "react-router-dom"; +import {Component, ComponentExportFunction, Export, Field, Parameter, Result, Typ,} from "@/types/component.ts"; +import ErrorBoundary from "@/components/errorBoundary"; +import {calculateExportFunctions} from "@/lib/utils"; + +function parseType(typ: Typ): string { + if (typ.type) { + if (typ.type === "Record" && typ.fields) { + return `{ + ${typ.fields + .map((field: Field) => `${field.name}: ${parseType(field.typ)}`) + .join(", \n ")} + }`; + } else if (typ.type === "Array" && typ.fields) { + return `Array<{ + ${typ.fields + .map((field: Field) => `${field.name}: ${parseType(field.typ)}`) + .join(", \n ")} + }>`; + } else if (typ.type === "Variant" && typ.cases) { + return typ.cases + .map((caseItem) => { + if (caseItem.typ.fields) { + return `${caseItem.name}: { + ${caseItem.typ.fields + .map((field) => `${field.name}: ${parseType(field.typ)}`) + .join(", \n ")} + }`; + } + return `${caseItem.name}: ${parseType(caseItem.typ)}`; + }) + .join(" | "); + } + return typ.type; + } + return "Unknown"; +} + +// Main function to convert JSON to function structure +function convertJsonToFunctionStructure(json: Parameter[] | Result[]) { + return json.map((entry) => { + const name = entry.name; + const fieldsStructure = parseType(entry.typ); + return `(${name}: ${fieldsStructure})`; + }); +} + +export default function Plugins() { + const {componentId = ""} = useParams(); + const [componentList, setComponentList] = useState([] as Component[]); + const [component, setComponent] = useState({}); + const [versionList, setVersionList] = useState([] as number[]); + const [versionChange, setVersionChange] = useState(0 as number); + const [functions, setFunctions] = useState([] as ComponentExportFunction[]); + + useEffect(() => { + if (componentId) { + API.getComponents().then((response) => { + setComponentList(response); + }); + + API.getComponentByIdAsKey().then((response) => { + setVersionList(response[componentId].versionId || []); + setComponent(response[componentId]); + }); + } + }, [componentId]); + + useEffect(() => { + if (component && component.exports) { + const functions = component.exports.reduce( + (acc: ComponentExportFunction[], curr: Export) => { + const updatedFunctions = curr.functions.map( + (func: ComponentExportFunction) => ({ + ...func, + exportName: curr.name, + }) + ); + + return acc.concat(updatedFunctions); + }, + [] + ); + setFunctions(functions); + } + }, [component]); + + const handleVersionChange = (version: number) => { + setVersionChange(version); + const componentDetails = componentList.find((component: Component) => { + if (component.versionedComponentId) { + return ( + component.versionedComponentId.componentId === componentId && + component.versionedComponentId.version === version + ); + } + }); + if (componentDetails) { + setComponent({ + ...componentDetails, + exports: componentDetails.metadata?.exports, + }); + } else { + setComponent({}); + } + }; + + const handleSearch = (e: React.ChangeEvent) => { + const value = e.target.value; + + const searchResult = calculateExportFunctions( + component.exports || [] + ).filter((fn: ComponentExportFunction) => { + return fn.name.includes(value); + }); + setFunctions(searchResult || ([] as ComponentExportFunction[])); + }; + + return ( + +
+ +
+
+
+
+

+ {component.componentName} +

+
+
+
+
+
+
+

Exports

+
+
+
+ + handleSearch(e)} + /> +
+ {versionList.length > 0 && ( + + )} +
+ +
+ + + + Package + Function + Parameters + Return Value + + + + {functions?.length > 0 ? ( + functions.map((fn: ComponentExportFunction) => ( + + + {fn.exportName} + + + {fn.name} + + + {convertJsonToFunctionStructure(fn.parameters)} + + + {convertJsonToFunctionStructure(fn.results)} + + + )) + ) : ( +
+ No exports found. +
+ )} +
+
+
+
+
+
+
+
+ ); +} diff --git a/test-components/file-server/Cargo.lock b/test-components/file-server/Cargo.lock index 084a2b79b..729ab796b 100644 --- a/test-components/file-server/Cargo.lock +++ b/test-components/file-server/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "bitflags" @@ -92,9 +92,9 @@ dependencies = [ [[package]] name = "wit-bindgen-rt" -version = "0.26.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c7526379ace8709ee9ab9f2bb50f112d95581063a59ef3097d9c10153886c9" +checksum = "fc801b991c56492f87ab3086e786468f75c285a4d73017ab0ebc2fa1aed5d82c" dependencies = [ "bitflags", ] diff --git a/test-components/initial-file-read-write/Cargo.lock b/test-components/initial-file-read-write/Cargo.lock index 084a2b79b..729ab796b 100644 --- a/test-components/initial-file-read-write/Cargo.lock +++ b/test-components/initial-file-read-write/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "bitflags" @@ -92,9 +92,9 @@ dependencies = [ [[package]] name = "wit-bindgen-rt" -version = "0.26.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c7526379ace8709ee9ab9f2bb50f112d95581063a59ef3097d9c10153886c9" +checksum = "fc801b991c56492f87ab3086e786468f75c285a4d73017ab0ebc2fa1aed5d82c" dependencies = [ "bitflags", ] diff --git a/test-components/rust-service/Cargo.lock b/test-components/rust-service/Cargo.lock index e04214e02..fb595f628 100644 --- a/test-components/rust-service/Cargo.lock +++ b/test-components/rust-service/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -1235,9 +1235,9 @@ dependencies = [ [[package]] name = "wit-bindgen-rt" -version = "0.26.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c7526379ace8709ee9ab9f2bb50f112d95581063a59ef3097d9c10153886c9" +checksum = "fc801b991c56492f87ab3086e786468f75c285a4d73017ab0ebc2fa1aed5d82c" dependencies = [ "bitflags", ] diff --git a/test-components/wasi-http-incoming-request-handler/Cargo.lock b/test-components/wasi-http-incoming-request-handler/Cargo.lock index 1ef2185fc..777d4075e 100644 --- a/test-components/wasi-http-incoming-request-handler/Cargo.lock +++ b/test-components/wasi-http-incoming-request-handler/Cargo.lock @@ -9,7 +9,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] -name = "handler" +name = "wasi-http-incoming-request-handler" version = "0.1.0" dependencies = [ "wit-bindgen-rt",