diff --git a/pkgs/webview-ui/app/package-lock.json b/pkgs/webview-ui/app/package-lock.json index 45ef64ebb..dded1dd4e 100644 --- a/pkgs/webview-ui/app/package-lock.json +++ b/pkgs/webview-ui/app/package-lock.json @@ -15,6 +15,7 @@ "@solidjs/router": "^0.14.2", "@tanstack/eslint-plugin-query": "^5.51.12", "@tanstack/solid-query": "^5.51.2", + "@types/json-schema": "^7.0.15", "material-icons": "^1.13.12", "nanoid": "^5.0.7", "solid-js": "^1.8.11", @@ -1782,6 +1783,12 @@ "@types/unist": "^2" } }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT" + }, "node_modules/@types/mdast": { "version": "3.0.15", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", diff --git a/pkgs/webview-ui/app/package.json b/pkgs/webview-ui/app/package.json index 3434b50dd..feede18fd 100644 --- a/pkgs/webview-ui/app/package.json +++ b/pkgs/webview-ui/app/package.json @@ -42,6 +42,7 @@ "@solidjs/router": "^0.14.2", "@tanstack/eslint-plugin-query": "^5.51.12", "@tanstack/solid-query": "^5.51.2", + "@types/json-schema": "^7.0.15", "material-icons": "^1.13.12", "nanoid": "^5.0.7", "solid-js": "^1.8.11", diff --git a/pkgs/webview-ui/app/src/routes/modules/details.tsx b/pkgs/webview-ui/app/src/routes/modules/details.tsx index 7d3a18207..bda6f911b 100644 --- a/pkgs/webview-ui/app/src/routes/modules/details.tsx +++ b/pkgs/webview-ui/app/src/routes/modules/details.tsx @@ -3,10 +3,19 @@ import { activeURI } from "@/src/App"; import { BackButton } from "@/src/components/BackButton"; import { createModulesQuery } from "@/src/queries"; import { useParams } from "@solidjs/router"; -import { For, Match, Switch } from "solid-js"; +import { createEffect, For, Match, Show, Switch } from "solid-js"; import { SolidMarkdown } from "solid-markdown"; import toast from "solid-toast"; import { ModuleInfo } from "./list"; +import { createQuery } from "@tanstack/solid-query"; +import { JSONSchema4 } from "json-schema"; +import { TextInput } from "@/src/components/TextInput"; +import { + createForm, + getValue, + setValue, + SubmitHandler, +} from "@modular-forms/solid"; export const ModuleDetails = () => { const params = useParams(); @@ -104,6 +113,191 @@ const Details = (props: DetailsProps) => { Add to Clan + + + ); +}; + +type ModuleSchemasType = Record>; + +const Unsupported = (props: { schema: JSONSchema4; what: string }) => ( +
+ Cannot render {props.what} +
+      {JSON.stringify(props.schema, null, 2)}
+    
+
+); + +function removeTrailingS(str: string) { + // Check if the last character is "s" or "S" + if (str.endsWith("s") || str.endsWith("S")) { + return str.slice(0, -1); // Remove the last character + } + return str; // Return unchanged if no trailing "s" +} +interface SchemaFormProps { + title: string; + schema: JSONSchema4; + path: string[]; +} + +export const ModuleForm = (props: { id: string }) => { + // TODO: Fetch the synced schema for all the modules at runtime + // We use static schema file at build time for now. (Different versions might have different schema at runtime) + const schemaQuery = createQuery(() => ({ + queryKey: [activeURI(), "modules_schema"], + queryFn: async () => { + const moduleSchema = await import( + "../../../api/modules_schemas.json" + ).then((m) => m.default as ModuleSchemasType); + + return moduleSchema; + }, + })); + + createEffect(() => { + console.log("Schema Query", schemaQuery.data?.[props.id]); + }); + + const [formStore, { Form, Field }] = createForm(); + const handleSubmit: SubmitHandler> = async ( + values, + event, + ) => { + console.log("Submitted form values", values); + }; + const SchemaForm = (props: SchemaFormProps) => { + return ( +
+ } + > + + } + > + + {(properties) => ( + + {([key, value]) => ( + + )} + + )} + + + {(additionalProperties) => ( + <> +
{props.title}
+ {/* @ts-expect-error: We don't know the field names ahead of time */} + + {(f, p) => ( + <> + + , + )} + > + {(v) => ( +
+
+ {removeTrailingS(props.title)}: {v[0]} +
+
+ {" "} +
+
+ )} +
+
+ + + )} +
+ + )} +
+
+
+ + TODO: Array field "{props.title}" + + + {/* @ts-expect-error: We dont know the field names ahead of time */} + + {(field, fieldProps) => ( + + )} + + +
+
+ ); + }; + + return ( +
+ + Loading... + + {(rolesSchemas) => ( + <> + Configure this module + + {([role, schema]) => ( +
+

{role}

+
+ +
+ + +
+ )} +
+ + )} +
+
); };