Clan-app: dynamic router concept
This commit is contained in:
9
pkgs/webview-ui/app/package-lock.json
generated
9
pkgs/webview-ui/app/package-lock.json
generated
@@ -12,6 +12,7 @@
|
|||||||
"@floating-ui/dom": "^1.6.8",
|
"@floating-ui/dom": "^1.6.8",
|
||||||
"@modular-forms/solid": "^0.21.0",
|
"@modular-forms/solid": "^0.21.0",
|
||||||
"@solid-primitives/storage": "^3.7.1",
|
"@solid-primitives/storage": "^3.7.1",
|
||||||
|
"@solidjs/router": "^0.14.2",
|
||||||
"@tanstack/eslint-plugin-query": "^5.51.12",
|
"@tanstack/eslint-plugin-query": "^5.51.12",
|
||||||
"@tanstack/solid-query": "^5.51.2",
|
"@tanstack/solid-query": "^5.51.2",
|
||||||
"material-icons": "^1.13.12",
|
"material-icons": "^1.13.12",
|
||||||
@@ -1551,6 +1552,14 @@
|
|||||||
"solid-js": "^1.6.12"
|
"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": {
|
"node_modules/@tailwindcss/typography": {
|
||||||
"version": "0.5.13",
|
"version": "0.5.13",
|
||||||
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.13.tgz",
|
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.13.tgz",
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
"@floating-ui/dom": "^1.6.8",
|
"@floating-ui/dom": "^1.6.8",
|
||||||
"@modular-forms/solid": "^0.21.0",
|
"@modular-forms/solid": "^0.21.0",
|
||||||
"@solid-primitives/storage": "^3.7.1",
|
"@solid-primitives/storage": "^3.7.1",
|
||||||
|
"@solidjs/router": "^0.14.2",
|
||||||
"@tanstack/eslint-plugin-query": "^5.51.12",
|
"@tanstack/eslint-plugin-query": "^5.51.12",
|
||||||
"@tanstack/solid-query": "^5.51.2",
|
"@tanstack/solid-query": "^5.51.2",
|
||||||
"material-icons": "^1.13.12",
|
"material-icons": "^1.13.12",
|
||||||
|
|||||||
@@ -1,15 +1,6 @@
|
|||||||
import { type Component, createEffect, createSignal } from "solid-js";
|
import { 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 { makePersisted } from "@solid-primitives/storage";
|
import { makePersisted } from "@solid-primitives/storage";
|
||||||
|
|
||||||
// Some global state
|
|
||||||
const [route, setRoute] = createSignal<Route>("machines");
|
|
||||||
|
|
||||||
export { route, setRoute };
|
|
||||||
|
|
||||||
const [activeURI, setActiveURI] = makePersisted(
|
const [activeURI, setActiveURI] = makePersisted(
|
||||||
createSignal<string | null>(null),
|
createSignal<string | null>(null),
|
||||||
{
|
{
|
||||||
@@ -26,21 +17,3 @@ const [clanList, setClanList] = makePersisted(createSignal<string[]>([]), {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export { clanList, setClanList };
|
export { clanList, setClanList };
|
||||||
|
|
||||||
const App: Component = () => {
|
|
||||||
effect(() => {
|
|
||||||
if (clanList().length === 0) {
|
|
||||||
setRoute("welcome");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return (
|
|
||||||
<div class="h-screen bg-gradient-to-b from-white to-base-100 p-4">
|
|
||||||
<Toaster position="top-right" />
|
|
||||||
<Layout>
|
|
||||||
<Router route={route} />
|
|
||||||
</Layout>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default App;
|
|
||||||
|
|||||||
@@ -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<Route>;
|
|
||||||
}
|
|
||||||
export const Router = (props: RouterProps) => {
|
|
||||||
const { route } = props;
|
|
||||||
return (
|
|
||||||
<Switch fallback={<p>route {route()} not found</p>}>
|
|
||||||
<For each={Object.entries(routes)}>
|
|
||||||
{([key, { child }]) => <Match when={route() === key}>{child}</Match>}
|
|
||||||
</For>
|
|
||||||
</Switch>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,14 +1,11 @@
|
|||||||
import { Accessor, For, Setter } from "solid-js";
|
import { For, Show } from "solid-js";
|
||||||
import { Route, routes } from "./Routes";
|
|
||||||
import { activeURI } from "./App";
|
import { activeURI } from "./App";
|
||||||
import { createQuery } from "@tanstack/solid-query";
|
import { createQuery } from "@tanstack/solid-query";
|
||||||
import { callApi } from "./api";
|
import { callApi } from "./api";
|
||||||
|
import { A, RouteSectionProps } from "@solidjs/router";
|
||||||
|
import { AppRoute, routes } from "./index";
|
||||||
|
|
||||||
interface SidebarProps {
|
export const Sidebar = (props: RouteSectionProps) => {
|
||||||
route: Accessor<Route>;
|
|
||||||
setRoute: Setter<Route>;
|
|
||||||
}
|
|
||||||
export const Sidebar = (props: SidebarProps) => {
|
|
||||||
const query = createQuery(() => ({
|
const query = createQuery(() => ({
|
||||||
queryKey: [activeURI(), "meta"],
|
queryKey: [activeURI(), "meta"],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
@@ -20,29 +17,57 @@ export const Sidebar = (props: SidebarProps) => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
const { route, setRoute } = props;
|
|
||||||
return (
|
return (
|
||||||
<aside class="w-80 rounded-xl border border-slate-900 bg-slate-800 pb-10">
|
<aside class="w-80 rounded-xl border border-slate-900 bg-slate-800 pb-10">
|
||||||
<div class="m-4 flex flex-col text-center capitalize text-white">
|
<div class="m-4 flex flex-col text-center capitalize text-white">
|
||||||
<span class="text-lg">{query.data?.name}</span>
|
<span class="text-lg">{query.data?.name}</span>
|
||||||
<span class="text-sm">{query.data?.description}</span>
|
<span class="text-sm">{query.data?.description}</span>
|
||||||
|
<RouteMenu class="menu px-4 py-2" routes={routes} />
|
||||||
</div>
|
</div>
|
||||||
<ul class="menu px-4 py-0">
|
</aside>
|
||||||
<For each={Object.entries(routes)}>
|
);
|
||||||
{([key, { label, icon }]) => (
|
};
|
||||||
|
|
||||||
|
const RouteMenu = (props: {
|
||||||
|
class?: string;
|
||||||
|
routes: AppRoute[];
|
||||||
|
prefix?: string;
|
||||||
|
}) => (
|
||||||
|
<ul class={props?.class}>
|
||||||
|
<For each={props.routes.filter((r) => !r.hidden)}>
|
||||||
|
{(route) => (
|
||||||
<li>
|
<li>
|
||||||
<button
|
<Show
|
||||||
onClick={() => setRoute(key as Route)}
|
when={route.children}
|
||||||
class="group text-white"
|
fallback={
|
||||||
classList={{ "!bg-primary !text-white": route() === key }}
|
<A href={[props.prefix, route.path].filter(Boolean).join("")}>
|
||||||
>
|
<button class="text-white">
|
||||||
<span class="material-icons">{icon}</span>
|
{route.icon && (
|
||||||
{label}
|
<span class="material-icons">{route.icon}</span>
|
||||||
|
)}
|
||||||
|
{route.label}
|
||||||
</button>
|
</button>
|
||||||
|
</A>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{(children) => (
|
||||||
|
<details id={`disclosure-${route.label}`} open={true}>
|
||||||
|
<summary class="group">
|
||||||
|
{route.icon && (
|
||||||
|
<span class="material-icons">{route.icon}</span>
|
||||||
|
)}
|
||||||
|
{route.label}
|
||||||
|
</summary>
|
||||||
|
<RouteMenu
|
||||||
|
routes={children()}
|
||||||
|
prefix={[props.prefix, route.path].filter(Boolean).join("")}
|
||||||
|
/>
|
||||||
|
</details>
|
||||||
|
)}
|
||||||
|
</Show>
|
||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
</ul>
|
</ul>
|
||||||
</aside>
|
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Accessor, createSignal, Show } from "solid-js";
|
import { createSignal, Show } from "solid-js";
|
||||||
import { callApi, SuccessData } from "../api";
|
import { callApi, SuccessData } from "../api";
|
||||||
import { Menu } from "./Menu";
|
import { Menu } from "./Menu";
|
||||||
import { activeURI, setRoute } from "../App";
|
import { activeURI } from "../App";
|
||||||
import toast from "solid-toast";
|
import toast from "solid-toast";
|
||||||
|
|
||||||
type MachineDetails = SuccessData<"list_inventory_machines">["data"][string];
|
type MachineDetails = SuccessData<"list_inventory_machines">["data"][string];
|
||||||
@@ -63,9 +63,9 @@ export const MachineListItem = (props: MachineListItemProps) => {
|
|||||||
<ul class="menu z-[1] w-52 rounded-box bg-base-100 p-2 shadow">
|
<ul class="menu z-[1] w-52 rounded-box bg-base-100 p-2 shadow">
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
onClick={() => {
|
// onClick={() => {
|
||||||
setRoute("machines/edit");
|
// setRoute("machines/edit");
|
||||||
}}
|
// }}
|
||||||
>
|
>
|
||||||
Edit
|
Edit
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -1,9 +1,19 @@
|
|||||||
/* @refresh reload */
|
/* @refresh reload */
|
||||||
import { render } from "solid-js/web";
|
import { render } from "solid-js/web";
|
||||||
|
import { RouteDefinition, Router } from "@solidjs/router";
|
||||||
|
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
import App from "./App";
|
|
||||||
import { QueryClient, QueryClientProvider } from "@tanstack/solid-query";
|
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();
|
const client = new QueryClient();
|
||||||
|
|
||||||
@@ -23,10 +33,88 @@ if (import.meta.env.DEV) {
|
|||||||
await import("solid-devtools");
|
await import("solid-devtools");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type AppRoute = Omit<RouteDefinition, "children"> & {
|
||||||
|
label: string;
|
||||||
|
icon?: string;
|
||||||
|
children?: AppRoute[];
|
||||||
|
hidden?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const routes: AppRoute[] = [
|
||||||
|
{
|
||||||
|
path: "/machines",
|
||||||
|
label: "Machines",
|
||||||
|
icon: "devices_other",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: "/",
|
||||||
|
label: "Overview",
|
||||||
|
component: () => <MachineListView />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/create",
|
||||||
|
label: "Create",
|
||||||
|
component: () => <CreateMachine />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/:id",
|
||||||
|
label: "Details",
|
||||||
|
hidden: true,
|
||||||
|
component: () => <MachineDetails />,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/clan",
|
||||||
|
label: "Clans",
|
||||||
|
icon: "groups",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: "/",
|
||||||
|
label: "Overview",
|
||||||
|
component: () => <Settings />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/create",
|
||||||
|
label: "Create",
|
||||||
|
component: () => <CreateClan />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/:id",
|
||||||
|
label: "Details",
|
||||||
|
hidden: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/tools",
|
||||||
|
label: "Tools",
|
||||||
|
icon: "bolt",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: "/flash",
|
||||||
|
label: "Clan Installer",
|
||||||
|
component: () => <Flash />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/hosts",
|
||||||
|
label: "Local Hosts",
|
||||||
|
component: () => <HostList />,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/welcome",
|
||||||
|
label: "",
|
||||||
|
hidden: true,
|
||||||
|
component: () => <Welcome />,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
render(
|
render(
|
||||||
() => (
|
() => (
|
||||||
<QueryClientProvider client={client}>
|
<QueryClientProvider client={client}>
|
||||||
<App />
|
<Router root={Layout}>{routes}</Router>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
),
|
),
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createQuery } from "@tanstack/solid-query";
|
import { createQuery } from "@tanstack/solid-query";
|
||||||
import { activeURI, setRoute } from "../App";
|
import { activeURI } from "../App";
|
||||||
import { callApi } from "../api";
|
import { callApi } from "../api";
|
||||||
import { Accessor, Show } from "solid-js";
|
import { Accessor, Show } from "solid-js";
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ export const Header = (props: HeaderProps) => {
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex-none">
|
<div class="flex-none">
|
||||||
<span class="tooltip tooltip-bottom" data-tip="Settings">
|
<span class="tooltip tooltip-bottom" data-tip="Settings">
|
||||||
<button class="link" onClick={() => setRoute("settings")}>
|
<button class="link">
|
||||||
<span class="material-icons">settings</span>
|
<span class="material-icons">settings</span>
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
import { Component, JSXElement, Show } from "solid-js";
|
import { Component, createEffect, Show } from "solid-js";
|
||||||
import { Header } from "./header";
|
import { Header } from "./header";
|
||||||
import { Sidebar } from "../Sidebar";
|
import { Sidebar } from "../Sidebar";
|
||||||
import { activeURI, clanList, route, setRoute } from "../App";
|
import { activeURI, clanList } from "../App";
|
||||||
|
import { RouteSectionProps } from "@solidjs/router";
|
||||||
|
|
||||||
interface LayoutProps {
|
export const Layout: Component<RouteSectionProps> = (props) => {
|
||||||
children: JSXElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Layout: Component<LayoutProps> = (props) => {
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div class="h-screen bg-gradient-to-b from-white to-base-100 p-4">
|
||||||
<div class="drawer lg:drawer-open ">
|
<div class="drawer lg:drawer-open ">
|
||||||
<input
|
<input
|
||||||
id="toplevel-drawer"
|
id="toplevel-drawer"
|
||||||
@@ -17,7 +14,7 @@ export const Layout: Component<LayoutProps> = (props) => {
|
|||||||
class="drawer-toggle hidden"
|
class="drawer-toggle hidden"
|
||||||
/>
|
/>
|
||||||
<div class="drawer-content">
|
<div class="drawer-content">
|
||||||
<Show when={route() !== "welcome"}>
|
<Show when={props.location.pathname !== "welcome"}>
|
||||||
<Header clan_dir={activeURI} />
|
<Header clan_dir={activeURI} />
|
||||||
</Show>
|
</Show>
|
||||||
{props.children}
|
{props.children}
|
||||||
@@ -25,7 +22,8 @@ export const Layout: Component<LayoutProps> = (props) => {
|
|||||||
<div
|
<div
|
||||||
class="drawer-side z-40 h-full"
|
class="drawer-side z-40 h-full"
|
||||||
classList={{
|
classList={{
|
||||||
"!hidden": route() === "welcome" || clanList().length === 0,
|
"!hidden":
|
||||||
|
props.location.pathname === "welcome" || clanList().length === 0,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
@@ -33,9 +31,9 @@ export const Layout: Component<LayoutProps> = (props) => {
|
|||||||
aria-label="close sidebar"
|
aria-label="close sidebar"
|
||||||
class="drawer-overlay"
|
class="drawer-overlay"
|
||||||
></label>
|
></label>
|
||||||
<Sidebar route={route} setRoute={setRoute} />
|
<Sidebar {...props} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { callApi, OperationResponse, pyApi } from "@/src/api";
|
import { callApi, OperationResponse } from "@/src/api";
|
||||||
import { Show } from "solid-js";
|
import { Show } from "solid-js";
|
||||||
import {
|
import {
|
||||||
createForm,
|
createForm,
|
||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
SubmitHandler,
|
SubmitHandler,
|
||||||
} from "@modular-forms/solid";
|
} from "@modular-forms/solid";
|
||||||
import toast from "solid-toast";
|
import toast from "solid-toast";
|
||||||
import { setActiveURI, setRoute } from "@/src/App";
|
import { setActiveURI } from "@/src/App";
|
||||||
|
|
||||||
type CreateForm = Meta & {
|
type CreateForm = Meta & {
|
||||||
template_url: string;
|
template_url: string;
|
||||||
@@ -53,7 +53,7 @@ export const ClanForm = () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
setActiveURI(target_dir[0]);
|
setActiveURI(target_dir[0]);
|
||||||
setRoute("machines");
|
// setRoute("machines");
|
||||||
})(),
|
})(),
|
||||||
{
|
{
|
||||||
loading: "Creating clan...",
|
loading: "Creating clan...",
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { callApi } from "@/src/api";
|
|||||||
import { activeURI } from "@/src/App";
|
import { activeURI } from "@/src/App";
|
||||||
import { createQuery } from "@tanstack/solid-query";
|
import { createQuery } from "@tanstack/solid-query";
|
||||||
import { createEffect } from "solid-js";
|
import { createEffect } from "solid-js";
|
||||||
import toast from "solid-toast";
|
|
||||||
|
|
||||||
export function DiskView() {
|
export function DiskView() {
|
||||||
const query = createQuery(() => ({
|
const query = createQuery(() => ({
|
||||||
|
|||||||
@@ -1,11 +1,4 @@
|
|||||||
import {
|
import { type Component, createSignal, For, Show } from "solid-js";
|
||||||
type Component,
|
|
||||||
createEffect,
|
|
||||||
createSignal,
|
|
||||||
For,
|
|
||||||
Show,
|
|
||||||
} from "solid-js";
|
|
||||||
import { route } from "@/src/App";
|
|
||||||
import { OperationResponse, pyApi } from "@/src/api";
|
import { OperationResponse, pyApi } from "@/src/api";
|
||||||
|
|
||||||
type ServiceModel = Extract<
|
type ServiceModel = Extract<
|
||||||
@@ -16,16 +9,6 @@ type ServiceModel = Extract<
|
|||||||
export const HostList: Component = () => {
|
export const HostList: Component = () => {
|
||||||
const [services, setServices] = createSignal<ServiceModel>();
|
const [services, setServices] = createSignal<ServiceModel>();
|
||||||
|
|
||||||
// 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 (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div class="tooltip tooltip-bottom" data-tip="Refresh install targets">
|
<div class="tooltip tooltip-bottom" data-tip="Refresh install targets">
|
||||||
|
|||||||
6
pkgs/webview-ui/app/src/routes/machines/[name]/view.tsx
Normal file
6
pkgs/webview-ui/app/src/routes/machines/[name]/view.tsx
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { useParams } from "@solidjs/router";
|
||||||
|
|
||||||
|
export const MachineDetails = () => {
|
||||||
|
const params = useParams();
|
||||||
|
return <div>Machine Details: {params.id}</div>;
|
||||||
|
};
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { callApi, OperationArgs, pyApi, OperationResponse } from "@/src/api";
|
import { callApi, OperationArgs } from "@/src/api";
|
||||||
import { activeURI, setRoute } from "@/src/App";
|
import { activeURI } from "@/src/App";
|
||||||
import { TextInput } from "@/src/components/TextInput";
|
import { TextInput } from "@/src/components/TextInput";
|
||||||
import { createForm, required, reset } from "@modular-forms/solid";
|
import { createForm, required, reset } from "@modular-forms/solid";
|
||||||
import { createQuery, useQueryClient } from "@tanstack/solid-query";
|
import { createQuery, useQueryClient } from "@tanstack/solid-query";
|
||||||
@@ -49,7 +49,7 @@ export function CreateMachine() {
|
|||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: [activeURI(), "list_machines"],
|
queryKey: [activeURI(), "list_machines"],
|
||||||
});
|
});
|
||||||
setRoute("machines");
|
// setRoute("machines");
|
||||||
} else {
|
} else {
|
||||||
toast.error(
|
toast.error(
|
||||||
`Error: ${response.errors[0].message}. Machine ${values.machine.name} could not be created`,
|
`Error: ${response.errors[0].message}. Machine ${values.machine.name} could not be created`,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { type Component, createEffect, For, Match, Switch } from "solid-js";
|
import { type Component, For, Match, Switch } from "solid-js";
|
||||||
import { activeURI, setRoute } from "@/src/App";
|
import { activeURI } from "@/src/App";
|
||||||
import { callApi, OperationResponse } from "@/src/api";
|
import { callApi, OperationResponse } from "@/src/api";
|
||||||
import toast from "solid-toast";
|
import toast from "solid-toast";
|
||||||
import { MachineListItem } from "@/src/components/MachineListItem";
|
import { MachineListItem } from "@/src/components/MachineListItem";
|
||||||
@@ -83,7 +83,10 @@ export const MachineListView: Component = () => {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="tooltip tooltip-bottom" data-tip="Create machine">
|
<div class="tooltip tooltip-bottom" data-tip="Create machine">
|
||||||
<button class="btn btn-ghost" onClick={() => setRoute("machines/add")}>
|
<button
|
||||||
|
class="btn btn-ghost"
|
||||||
|
// onClick={() => setRoute("machines/add")}
|
||||||
|
>
|
||||||
<span class="material-icons ">add</span>
|
<span class="material-icons ">add</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
import { callApi } from "@/src/api";
|
import { callApi } from "@/src/api";
|
||||||
import {
|
import { activeURI, clanList, setActiveURI, setClanList } from "@/src/App";
|
||||||
activeURI,
|
|
||||||
clanList,
|
|
||||||
setActiveURI,
|
|
||||||
setClanList,
|
|
||||||
setRoute,
|
|
||||||
} from "@/src/App";
|
|
||||||
import { createSignal, For, Match, Setter, Show, Switch } from "solid-js";
|
import { createSignal, For, Match, Setter, Show, Switch } from "solid-js";
|
||||||
import { createQuery } from "@tanstack/solid-query";
|
import { createQuery } from "@tanstack/solid-query";
|
||||||
import { useFloating } from "@/src/floating";
|
import { useFloating } from "@/src/floating";
|
||||||
@@ -17,7 +11,6 @@ export const registerClan = async () => {
|
|||||||
const loc = await callApi("open_file", {
|
const loc = await callApi("open_file", {
|
||||||
file_request: { mode: "select_folder" },
|
file_request: { mode: "select_folder" },
|
||||||
});
|
});
|
||||||
console.log({ loc }, loc.status);
|
|
||||||
if (loc.status === "success" && loc.data) {
|
if (loc.status === "success" && loc.data) {
|
||||||
const data = loc.data[0];
|
const data = loc.data[0];
|
||||||
setClanList((s) => {
|
setClanList((s) => {
|
||||||
@@ -25,10 +18,10 @@ export const registerClan = async () => {
|
|||||||
return Array.from(res);
|
return Array.from(res);
|
||||||
});
|
});
|
||||||
setActiveURI(data);
|
setActiveURI(data);
|
||||||
setRoute((r) => {
|
// setRoute((r) => {
|
||||||
if (r === "welcome") return "machines";
|
// if (r === "welcome") return "machines";
|
||||||
return r;
|
// return r;
|
||||||
});
|
// });
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { setActiveURI, setRoute } from "@/src/App";
|
import { setActiveURI } from "@/src/App";
|
||||||
import { registerClan } from "../settings";
|
import { registerClan } from "../settings";
|
||||||
|
|
||||||
export const Welcome = () => {
|
export const Welcome = () => {
|
||||||
@@ -11,7 +11,7 @@ export const Welcome = () => {
|
|||||||
<div class="flex flex-col items-start gap-2">
|
<div class="flex flex-col items-start gap-2">
|
||||||
<button
|
<button
|
||||||
class="btn btn-primary w-full"
|
class="btn btn-primary w-full"
|
||||||
onClick={() => setRoute("createClan")}
|
// onClick={() => setRoute("createClan")}
|
||||||
>
|
>
|
||||||
Build your own
|
Build your own
|
||||||
</button>
|
</button>
|
||||||
@@ -27,7 +27,7 @@ export const Welcome = () => {
|
|||||||
<button
|
<button
|
||||||
class="link w-full text-right text-secondary"
|
class="link w-full text-right text-secondary"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setRoute("machines");
|
// setRoute("machines");
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Skip (Debug)
|
Skip (Debug)
|
||||||
|
|||||||
Reference in New Issue
Block a user