From 22d6d57e3afd49a0d03386e664bedea374d8a979 Mon Sep 17 00:00:00 2001
From: Johannes Kirschbauer
Date: Wed, 14 Aug 2024 13:16:14 +0200
Subject: [PATCH] Clan-app: dynamic router concept
---
pkgs/webview-ui/app/package-lock.json | 9 ++
pkgs/webview-ui/app/package.json | 1 +
pkgs/webview-ui/app/src/App.tsx | 29 +-----
pkgs/webview-ui/app/src/Routes.tsx | 91 ------------------
pkgs/webview-ui/app/src/Sidebar.tsx | 73 ++++++++++-----
.../app/src/components/MachineListItem.tsx | 10 +-
pkgs/webview-ui/app/src/index.tsx | 92 ++++++++++++++++++-
pkgs/webview-ui/app/src/layout/header.tsx | 4 +-
pkgs/webview-ui/app/src/layout/layout.tsx | 22 ++---
.../app/src/routes/clan/clanDetails.tsx | 6 +-
pkgs/webview-ui/app/src/routes/disk/view.tsx | 1 -
pkgs/webview-ui/app/src/routes/hosts/view.tsx | 19 +---
.../app/src/routes/machines/[name]/view.tsx | 6 ++
.../app/src/routes/machines/create.tsx | 6 +-
.../app/src/routes/machines/view.tsx | 9 +-
.../app/src/routes/settings/index.tsx | 17 +---
.../app/src/routes/welcome/index.tsx | 6 +-
17 files changed, 194 insertions(+), 207 deletions(-)
delete mode 100644 pkgs/webview-ui/app/src/Routes.tsx
create mode 100644 pkgs/webview-ui/app/src/routes/machines/[name]/view.tsx
diff --git a/pkgs/webview-ui/app/package-lock.json b/pkgs/webview-ui/app/package-lock.json
index 5f435d99c..317efb017 100644
--- a/pkgs/webview-ui/app/package-lock.json
+++ b/pkgs/webview-ui/app/package-lock.json
@@ -12,6 +12,7 @@
"@floating-ui/dom": "^1.6.8",
"@modular-forms/solid": "^0.21.0",
"@solid-primitives/storage": "^3.7.1",
+ "@solidjs/router": "^0.14.2",
"@tanstack/eslint-plugin-query": "^5.51.12",
"@tanstack/solid-query": "^5.51.2",
"material-icons": "^1.13.12",
@@ -1551,6 +1552,14 @@
"solid-js": "^1.6.12"
}
},
+ "node_modules/@solidjs/router": {
+ "version": "0.14.2",
+ "resolved": "https://registry.npmjs.org/@solidjs/router/-/router-0.14.2.tgz",
+ "integrity": "sha512-JaJe7XJcZTyOfMOIVHmLO+3wP3akm5QQesrDU4XLn/JRMxozBzCaNXBsK7F8pBuDgxzRRxTV8RvXeS09HGXv6Q==",
+ "peerDependencies": {
+ "solid-js": "^1.8.6"
+ }
+ },
"node_modules/@tailwindcss/typography": {
"version": "0.5.13",
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.13.tgz",
diff --git a/pkgs/webview-ui/app/package.json b/pkgs/webview-ui/app/package.json
index 356215a3e..8681e2830 100644
--- a/pkgs/webview-ui/app/package.json
+++ b/pkgs/webview-ui/app/package.json
@@ -41,6 +41,7 @@
"@floating-ui/dom": "^1.6.8",
"@modular-forms/solid": "^0.21.0",
"@solid-primitives/storage": "^3.7.1",
+ "@solidjs/router": "^0.14.2",
"@tanstack/eslint-plugin-query": "^5.51.12",
"@tanstack/solid-query": "^5.51.2",
"material-icons": "^1.13.12",
diff --git a/pkgs/webview-ui/app/src/App.tsx b/pkgs/webview-ui/app/src/App.tsx
index a30f315eb..d5ad8b40e 100644
--- a/pkgs/webview-ui/app/src/App.tsx
+++ b/pkgs/webview-ui/app/src/App.tsx
@@ -1,15 +1,6 @@
-import { type Component, createEffect, createSignal } from "solid-js";
-import { Layout } from "./layout/layout";
-import { Route, Router } from "./Routes";
-import { Toaster } from "solid-toast";
-import { effect } from "solid-js/web";
+import { createSignal } from "solid-js";
import { makePersisted } from "@solid-primitives/storage";
-// Some global state
-const [route, setRoute] = createSignal("machines");
-
-export { route, setRoute };
-
const [activeURI, setActiveURI] = makePersisted(
createSignal(null),
{
@@ -26,21 +17,3 @@ const [clanList, setClanList] = makePersisted(createSignal([]), {
});
export { clanList, setClanList };
-
-const App: Component = () => {
- effect(() => {
- if (clanList().length === 0) {
- setRoute("welcome");
- }
- });
- return (
-
-
-
-
-
-
- );
-};
-
-export default App;
diff --git a/pkgs/webview-ui/app/src/Routes.tsx b/pkgs/webview-ui/app/src/Routes.tsx
deleted file mode 100644
index 420502948..000000000
--- a/pkgs/webview-ui/app/src/Routes.tsx
+++ /dev/null
@@ -1,91 +0,0 @@
-import { Accessor, For, Match, Switch } from "solid-js";
-import { MachineListView } from "./routes/machines/view";
-import { colors } from "./routes/colors/view";
-import { CreateClan } from "./routes/clan/view";
-import { HostList } from "./routes/hosts/view";
-import { BlockDevicesView } from "./routes/blockdevices/view";
-import { Flash } from "./routes/flash/view";
-import { Settings } from "./routes/settings";
-import { Welcome } from "./routes/welcome";
-import { Deploy } from "./routes/deploy";
-import { CreateMachine } from "./routes/machines/create";
-import { DiskView } from "./routes/disk/view";
-
-export type Route = keyof typeof routes;
-
-export const routes = {
- createClan: {
- child: CreateClan,
- label: "Create Clan",
- icon: "groups",
- },
- machines: {
- child: MachineListView,
- label: "Machines",
- icon: "devices_other",
- },
- "machines/add": {
- child: CreateMachine,
- label: "create Machine",
- icon: "add",
- },
- hosts: {
- child: HostList,
- label: "hosts",
- icon: "devices_other",
- },
- flash: {
- child: Flash,
- label: "create_flash_installer",
- icon: "devices_other",
- },
- blockdevices: {
- child: BlockDevicesView,
- label: "blockdevices",
- icon: "devices_other",
- },
- colors: {
- child: colors,
- label: "Colors",
- icon: "color_lens",
- },
- settings: {
- child: Settings,
- label: "Settings",
- icon: "settings",
- },
- welcome: {
- child: Welcome,
- label: "welcome",
- icon: "settings",
- },
- deploy: {
- child: Deploy,
- label: "deploy",
- icon: "content_copy",
- },
- diskConfig: {
- child: DiskView,
- label: "diskConfig",
- icon: "disk",
- },
- "machines/edit": {
- child: CreateMachine,
- label: "Edit Machine",
- icon: "edit",
- },
-};
-
-interface RouterProps {
- route: Accessor;
-}
-export const Router = (props: RouterProps) => {
- const { route } = props;
- return (
- route {route()} not found
}>
-
- {([key, { child }]) => {child}}
-
-
- );
-};
diff --git a/pkgs/webview-ui/app/src/Sidebar.tsx b/pkgs/webview-ui/app/src/Sidebar.tsx
index f548ed5cc..cb9bc3f55 100644
--- a/pkgs/webview-ui/app/src/Sidebar.tsx
+++ b/pkgs/webview-ui/app/src/Sidebar.tsx
@@ -1,14 +1,11 @@
-import { Accessor, For, Setter } from "solid-js";
-import { Route, routes } from "./Routes";
+import { For, Show } from "solid-js";
import { activeURI } from "./App";
import { createQuery } from "@tanstack/solid-query";
import { callApi } from "./api";
+import { A, RouteSectionProps } from "@solidjs/router";
+import { AppRoute, routes } from "./index";
-interface SidebarProps {
- route: Accessor;
- setRoute: Setter;
-}
-export const Sidebar = (props: SidebarProps) => {
+export const Sidebar = (props: RouteSectionProps) => {
const query = createQuery(() => ({
queryKey: [activeURI(), "meta"],
queryFn: async () => {
@@ -20,29 +17,57 @@ export const Sidebar = (props: SidebarProps) => {
}
},
}));
- const { route, setRoute } = props;
+
return (
);
};
+
+const RouteMenu = (props: {
+ class?: string;
+ routes: AppRoute[];
+ prefix?: string;
+}) => (
+
+ !r.hidden)}>
+ {(route) => (
+ -
+
+
+
+ }
+ >
+ {(children) => (
+
+
+ {route.icon && (
+ {route.icon}
+ )}
+ {route.label}
+
+
+
+ )}
+
+
+ )}
+
+
+);
diff --git a/pkgs/webview-ui/app/src/components/MachineListItem.tsx b/pkgs/webview-ui/app/src/components/MachineListItem.tsx
index 5eca6d334..92a245918 100644
--- a/pkgs/webview-ui/app/src/components/MachineListItem.tsx
+++ b/pkgs/webview-ui/app/src/components/MachineListItem.tsx
@@ -1,7 +1,7 @@
-import { Accessor, createSignal, Show } from "solid-js";
+import { createSignal, Show } from "solid-js";
import { callApi, SuccessData } from "../api";
import { Menu } from "./Menu";
-import { activeURI, setRoute } from "../App";
+import { activeURI } from "../App";
import toast from "solid-toast";
type MachineDetails = SuccessData<"list_inventory_machines">["data"][string];
@@ -63,9 +63,9 @@ export const MachineListItem = (props: MachineListItemProps) => {
-
{
- setRoute("machines/edit");
- }}
+ // onClick={() => {
+ // setRoute("machines/edit");
+ // }}
>
Edit
diff --git a/pkgs/webview-ui/app/src/index.tsx b/pkgs/webview-ui/app/src/index.tsx
index 6dff3cd3a..6a2ebe1a2 100644
--- a/pkgs/webview-ui/app/src/index.tsx
+++ b/pkgs/webview-ui/app/src/index.tsx
@@ -1,9 +1,19 @@
/* @refresh reload */
import { render } from "solid-js/web";
+import { RouteDefinition, Router } from "@solidjs/router";
import "./index.css";
-import App from "./App";
import { QueryClient, QueryClientProvider } from "@tanstack/solid-query";
+import { MachineDetails } from "./routes/machines/[name]/view";
+import { Layout } from "./layout/layout";
+import { MachineListView } from "./routes/machines/view";
+import { CreateClan } from "./routes/clan/view";
+import { Settings } from "./routes/settings";
+import { EditClanForm } from "./routes/clan/editClan";
+import { Flash } from "./routes/flash/view";
+import { CreateMachine } from "./routes/machines/create";
+import { HostList } from "./routes/hosts/view";
+import { Welcome } from "./routes/welcome";
const client = new QueryClient();
@@ -23,10 +33,88 @@ if (import.meta.env.DEV) {
await import("solid-devtools");
}
+export type AppRoute = Omit & {
+ label: string;
+ icon?: string;
+ children?: AppRoute[];
+ hidden?: boolean;
+};
+
+export const routes: AppRoute[] = [
+ {
+ path: "/machines",
+ label: "Machines",
+ icon: "devices_other",
+ children: [
+ {
+ path: "/",
+ label: "Overview",
+ component: () => ,
+ },
+ {
+ path: "/create",
+ label: "Create",
+ component: () => ,
+ },
+ {
+ path: "/:id",
+ label: "Details",
+ hidden: true,
+ component: () => ,
+ },
+ ],
+ },
+ {
+ path: "/clan",
+ label: "Clans",
+ icon: "groups",
+ children: [
+ {
+ path: "/",
+ label: "Overview",
+ component: () => ,
+ },
+ {
+ path: "/create",
+ label: "Create",
+ component: () => ,
+ },
+ {
+ path: "/:id",
+ label: "Details",
+ hidden: true,
+ },
+ ],
+ },
+ {
+ path: "/tools",
+ label: "Tools",
+ icon: "bolt",
+ children: [
+ {
+ path: "/flash",
+ label: "Clan Installer",
+ component: () => ,
+ },
+ {
+ path: "/hosts",
+ label: "Local Hosts",
+ component: () => ,
+ },
+ ],
+ },
+ {
+ path: "/welcome",
+ label: "",
+ hidden: true,
+ component: () => ,
+ },
+];
+
render(
() => (
-
+ {routes}
),
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
diff --git a/pkgs/webview-ui/app/src/layout/header.tsx b/pkgs/webview-ui/app/src/layout/header.tsx
index 7ce8e7d3d..8d98113e4 100644
--- a/pkgs/webview-ui/app/src/layout/header.tsx
+++ b/pkgs/webview-ui/app/src/layout/header.tsx
@@ -1,5 +1,5 @@
import { createQuery } from "@tanstack/solid-query";
-import { activeURI, setRoute } from "../App";
+import { activeURI } from "../App";
import { callApi } from "../api";
import { Accessor, Show } from "solid-js";
@@ -63,7 +63,7 @@ export const Header = (props: HeaderProps) => {
-
diff --git a/pkgs/webview-ui/app/src/layout/layout.tsx b/pkgs/webview-ui/app/src/layout/layout.tsx
index 031564f69..2c77254b5 100644
--- a/pkgs/webview-ui/app/src/layout/layout.tsx
+++ b/pkgs/webview-ui/app/src/layout/layout.tsx
@@ -1,15 +1,12 @@
-import { Component, JSXElement, Show } from "solid-js";
+import { Component, createEffect, Show } from "solid-js";
import { Header } from "./header";
import { Sidebar } from "../Sidebar";
-import { activeURI, clanList, route, setRoute } from "../App";
+import { activeURI, clanList } from "../App";
+import { RouteSectionProps } from "@solidjs/router";
-interface LayoutProps {
- children: JSXElement;
-}
-
-export const Layout: Component
= (props) => {
+export const Layout: Component = (props) => {
return (
- <>
+
= (props) => {
class="drawer-toggle hidden"
/>
-
+
{props.children}
@@ -25,7 +22,8 @@ export const Layout: Component = (props) => {
-
+
- >
+
);
};
diff --git a/pkgs/webview-ui/app/src/routes/clan/clanDetails.tsx b/pkgs/webview-ui/app/src/routes/clan/clanDetails.tsx
index fec7a8891..7daad7ccf 100644
--- a/pkgs/webview-ui/app/src/routes/clan/clanDetails.tsx
+++ b/pkgs/webview-ui/app/src/routes/clan/clanDetails.tsx
@@ -1,4 +1,4 @@
-import { callApi, OperationResponse, pyApi } from "@/src/api";
+import { callApi, OperationResponse } from "@/src/api";
import { Show } from "solid-js";
import {
createForm,
@@ -7,7 +7,7 @@ import {
SubmitHandler,
} from "@modular-forms/solid";
import toast from "solid-toast";
-import { setActiveURI, setRoute } from "@/src/App";
+import { setActiveURI } from "@/src/App";
type CreateForm = Meta & {
template_url: string;
@@ -53,7 +53,7 @@ export const ClanForm = () => {
},
});
setActiveURI(target_dir[0]);
- setRoute("machines");
+ // setRoute("machines");
})(),
{
loading: "Creating clan...",
diff --git a/pkgs/webview-ui/app/src/routes/disk/view.tsx b/pkgs/webview-ui/app/src/routes/disk/view.tsx
index 43e2f4aff..5fcfe6bda 100644
--- a/pkgs/webview-ui/app/src/routes/disk/view.tsx
+++ b/pkgs/webview-ui/app/src/routes/disk/view.tsx
@@ -2,7 +2,6 @@ import { callApi } from "@/src/api";
import { activeURI } from "@/src/App";
import { createQuery } from "@tanstack/solid-query";
import { createEffect } from "solid-js";
-import toast from "solid-toast";
export function DiskView() {
const query = createQuery(() => ({
diff --git a/pkgs/webview-ui/app/src/routes/hosts/view.tsx b/pkgs/webview-ui/app/src/routes/hosts/view.tsx
index bb75162fa..155507ef4 100644
--- a/pkgs/webview-ui/app/src/routes/hosts/view.tsx
+++ b/pkgs/webview-ui/app/src/routes/hosts/view.tsx
@@ -1,11 +1,4 @@
-import {
- type Component,
- createEffect,
- createSignal,
- For,
- Show,
-} from "solid-js";
-import { route } from "@/src/App";
+import { type Component, createSignal, For, Show } from "solid-js";
import { OperationResponse, pyApi } from "@/src/api";
type ServiceModel = Extract<
@@ -16,16 +9,6 @@ type ServiceModel = Extract<
export const HostList: Component = () => {
const [services, setServices] = createSignal
();
- // pyApi.show_mdns.receive((r) => {
- // const { status } = r;
- // if (status === "error") return console.error(r.errors);
- // setServices(r.data.services);
- // });
-
- // createEffect(() => {
- // if (route() === "hosts") pyApi.show_mdns.dispatch({});
- // });
-
return (
- setRoute("machines/add")}>
+ setRoute("machines/add")}
+ >
add
diff --git a/pkgs/webview-ui/app/src/routes/settings/index.tsx b/pkgs/webview-ui/app/src/routes/settings/index.tsx
index fba7b3b57..c2618c805 100644
--- a/pkgs/webview-ui/app/src/routes/settings/index.tsx
+++ b/pkgs/webview-ui/app/src/routes/settings/index.tsx
@@ -1,11 +1,5 @@
import { callApi } from "@/src/api";
-import {
- activeURI,
- clanList,
- setActiveURI,
- setClanList,
- setRoute,
-} from "@/src/App";
+import { activeURI, clanList, setActiveURI, setClanList } from "@/src/App";
import { createSignal, For, Match, Setter, Show, Switch } from "solid-js";
import { createQuery } from "@tanstack/solid-query";
import { useFloating } from "@/src/floating";
@@ -17,7 +11,6 @@ export const registerClan = async () => {
const loc = await callApi("open_file", {
file_request: { mode: "select_folder" },
});
- console.log({ loc }, loc.status);
if (loc.status === "success" && loc.data) {
const data = loc.data[0];
setClanList((s) => {
@@ -25,10 +18,10 @@ export const registerClan = async () => {
return Array.from(res);
});
setActiveURI(data);
- setRoute((r) => {
- if (r === "welcome") return "machines";
- return r;
- });
+ // setRoute((r) => {
+ // if (r === "welcome") return "machines";
+ // return r;
+ // });
return data;
}
} catch (e) {
diff --git a/pkgs/webview-ui/app/src/routes/welcome/index.tsx b/pkgs/webview-ui/app/src/routes/welcome/index.tsx
index 0e828b397..3df2f3940 100644
--- a/pkgs/webview-ui/app/src/routes/welcome/index.tsx
+++ b/pkgs/webview-ui/app/src/routes/welcome/index.tsx
@@ -1,4 +1,4 @@
-import { setActiveURI, setRoute } from "@/src/App";
+import { setActiveURI } from "@/src/App";
import { registerClan } from "../settings";
export const Welcome = () => {
@@ -11,7 +11,7 @@ export const Welcome = () => {
setRoute("createClan")}
+ // onClick={() => setRoute("createClan")}
>
Build your own
@@ -27,7 +27,7 @@ export const Welcome = () => {
{
- setRoute("machines");
+ // setRoute("machines");
}}
>
Skip (Debug)