UI: improve open clan from directory & list machines
This commit is contained in:
@@ -16,7 +16,6 @@ let
|
|||||||
> $out/config.json < ${pkgs.element-web}/config.json
|
> $out/config.json < ${pkgs.element-web}/config.json
|
||||||
ln -s $out/config.json $out/config.${nginx-vhost}.json
|
ln -s $out/config.json $out/config.${nginx-vhost}.json
|
||||||
'';
|
'';
|
||||||
|
|
||||||
in
|
in
|
||||||
# FIXME: This was taken from upstream. Drop this when our patch is upstream
|
# FIXME: This was taken from upstream. Drop this when our patch is upstream
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const getFakeResponse = (method: OperationNames, data: any) => {
|
|||||||
if (method === "open_file") {
|
if (method === "open_file") {
|
||||||
return {
|
return {
|
||||||
status: "success",
|
status: "success",
|
||||||
data: "/path/to/clan",
|
data: "/home/johannes/git/clan-core",
|
||||||
op_key,
|
op_key,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,17 +4,13 @@ import { Layout } from "./layout/layout";
|
|||||||
import { Route, Router } from "./Routes";
|
import { Route, Router } from "./Routes";
|
||||||
import { Toaster } from "solid-toast";
|
import { Toaster } from "solid-toast";
|
||||||
|
|
||||||
// Global state
|
// Some global state
|
||||||
const [route, setRoute] = createSignal<Route>("machines");
|
const [route, setRoute] = createSignal<Route>("machines");
|
||||||
|
|
||||||
const [currClanURI, setCurrClanURI] = createSignal<string>(
|
|
||||||
"/home/johannes/git/testing/xd"
|
|
||||||
);
|
|
||||||
|
|
||||||
export { currClanURI, setCurrClanURI };
|
|
||||||
|
|
||||||
export { route, setRoute };
|
export { route, setRoute };
|
||||||
|
|
||||||
|
const [currClanURI, setCurrClanURI] = createSignal<string | null>(null);
|
||||||
|
export { currClanURI, setCurrClanURI };
|
||||||
|
|
||||||
const App: Component = () => {
|
const App: Component = () => {
|
||||||
return [
|
return [
|
||||||
<Toaster position="top-right" />,
|
<Toaster position="top-right" />,
|
||||||
|
|||||||
@@ -26,12 +26,16 @@ export const makeMachineContext = () => {
|
|||||||
{ loading, machines },
|
{ loading, machines },
|
||||||
{
|
{
|
||||||
getMachines: () => {
|
getMachines: () => {
|
||||||
|
const clan_dir = currClanURI();
|
||||||
|
|
||||||
|
if (clan_dir) {
|
||||||
|
setLoading(true);
|
||||||
|
pyApi.list_machines.dispatch({
|
||||||
|
debug: true,
|
||||||
|
flake_url: clan_dir,
|
||||||
|
});
|
||||||
|
}
|
||||||
// When the gtk function sends its data the loading state will be set to false
|
// When the gtk function sends its data the loading state will be set to false
|
||||||
setLoading(true);
|
|
||||||
pyApi.list_machines.dispatch({
|
|
||||||
debug: true,
|
|
||||||
flake_url: currClanURI(),
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
] as const;
|
] as const;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export const Sidebar = (props: SidebarProps) => {
|
|||||||
const { route, setRoute } = props;
|
const { route, setRoute } = props;
|
||||||
return (
|
return (
|
||||||
<aside class="min-h-screen w-80 bg-base-100">
|
<aside class="min-h-screen w-80 bg-base-100">
|
||||||
<div class="sticky top-0 z-20 hidden items-center gap-2 bg-base-100/90 px-4 py-2 shadow-sm backdrop-blur lg:flex">
|
<div class="sticky top-0 z-20 items-center gap-2 bg-base-100/90 px-4 py-2 shadow-sm backdrop-blur lg:flex">
|
||||||
Icon
|
Icon
|
||||||
</div>
|
</div>
|
||||||
<ul class="menu px-4 py-0">
|
<ul class="menu px-4 py-0">
|
||||||
|
|||||||
@@ -54,17 +54,20 @@ pyApi.show_machine_deployment_target.receive((r) => {
|
|||||||
export const MachineListItem = (props: MachineListItemProps) => {
|
export const MachineListItem = (props: MachineListItemProps) => {
|
||||||
const { name, info } = props;
|
const { name, info } = props;
|
||||||
|
|
||||||
pyApi.show_machine_hardware_info.dispatch({
|
const clan_dir = currClanURI();
|
||||||
op_key: name,
|
if (clan_dir) {
|
||||||
clan_dir: currClanURI(),
|
pyApi.show_machine_hardware_info.dispatch({
|
||||||
machine_name: name,
|
op_key: name,
|
||||||
});
|
clan_dir,
|
||||||
|
machine_name: name,
|
||||||
|
});
|
||||||
|
|
||||||
pyApi.show_machine_deployment_target.dispatch({
|
pyApi.show_machine_deployment_target.dispatch({
|
||||||
op_key: name,
|
op_key: name,
|
||||||
clan_dir: currClanURI(),
|
clan_dir,
|
||||||
machine_name: name,
|
machine_name: name,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li>
|
<li>
|
||||||
@@ -91,25 +94,22 @@ export const MachineListItem = (props: MachineListItemProps) => {
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row flex-wrap gap-4 py-2">
|
<div class="flex flex-row flex-wrap gap-4 py-2">
|
||||||
<div class="badge badge-primary flex flex-row gap-1 py-4 align-middle">
|
<div class="badge badge-primary flex flex-row gap-1 py-4 align-middle">
|
||||||
<span class="material-icons">
|
<span>System:</span>
|
||||||
{hwInfo()[name]?.system ? "check" : "pending"}
|
{hwInfo()[name]?.system ? (
|
||||||
</span>
|
<span class="text-primary">{hwInfo()[name]?.system}</span>
|
||||||
|
) : (
|
||||||
<Switch fallback={<div class="skeleton h-8 w-full"></div>}>
|
<span class="text-warning">Not set</span>
|
||||||
<Match when={hwInfo()[name]?.system}>
|
)}
|
||||||
{(system) => "System: " + system()}
|
|
||||||
</Match>
|
|
||||||
<Match when={hwInfo()[name]?.system === null}>
|
|
||||||
{"No hardware info"}
|
|
||||||
</Match>
|
|
||||||
</Switch>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="badge badge-primary flex flex-row gap-1 py-4 align-middle">
|
<div class="badge badge-ghost flex flex-row gap-1 py-4 align-middle">
|
||||||
<span class="material-icons">
|
<span>Target Host:</span>
|
||||||
{deploymentInfo()[name] ? "check" : "pending"}
|
{deploymentInfo()[name] ? (
|
||||||
</span>
|
<span class="text-primary">{deploymentInfo()[name]}</span>
|
||||||
<Show
|
) : (
|
||||||
|
<span class="text-warning">Not set</span>
|
||||||
|
)}
|
||||||
|
{/* <Show
|
||||||
when={deploymentInfo()[name]}
|
when={deploymentInfo()[name]}
|
||||||
fallback={
|
fallback={
|
||||||
<Switch fallback={<div class="skeleton h-8 w-full"></div>}>
|
<Switch fallback={<div class="skeleton h-8 w-full"></div>}>
|
||||||
@@ -119,8 +119,8 @@ export const MachineListItem = (props: MachineListItemProps) => {
|
|||||||
</Switch>
|
</Switch>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{(i) => "Deploys to: " + i()}
|
{(i) => + i()}
|
||||||
</Show>
|
</Show> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* Show only the first error at the bottom */}
|
{/* Show only the first error at the bottom */}
|
||||||
|
|||||||
@@ -18,22 +18,24 @@ if (import.meta.env.DEV) {
|
|||||||
console.log("Development mode");
|
console.log("Development mode");
|
||||||
// Load the debugger in development mode
|
// Load the debugger in development mode
|
||||||
await import("solid-devtools");
|
await import("solid-devtools");
|
||||||
window.webkit = window.webkit || {
|
|
||||||
messageHandlers: {
|
|
||||||
gtk: {
|
|
||||||
postMessage: (postMessage) => {
|
|
||||||
const { method, data } = postMessage;
|
|
||||||
console.debug("Python API call", { method, data });
|
|
||||||
setTimeout(() => {
|
|
||||||
const mock = getFakeResponse(method, data);
|
|
||||||
console.log("Returning mock-data: ", { mock });
|
|
||||||
|
|
||||||
window.clan[method](JSON.stringify(mock));
|
// Uncomment this block to use the Mock API
|
||||||
}, 200);
|
// window.webkit = window.webkit || {
|
||||||
},
|
// messageHandlers: {
|
||||||
},
|
// gtk: {
|
||||||
},
|
// postMessage: (postMessage) => {
|
||||||
};
|
// const { method, data } = postMessage;
|
||||||
|
// console.debug("Python API call", { method, data });
|
||||||
|
// setTimeout(() => {
|
||||||
|
// const mock = getFakeResponse(method, data);
|
||||||
|
// console.log("Returning mock-data: ", { mock });
|
||||||
|
|
||||||
|
// window.clan[method](JSON.stringify(mock));
|
||||||
|
// }, 200);
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// };
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
render(() => <App />, root!);
|
render(() => <App />, root!);
|
||||||
|
|||||||
@@ -1,18 +1,27 @@
|
|||||||
|
import { currClanURI } from "../App";
|
||||||
|
|
||||||
export const Header = () => {
|
export const Header = () => {
|
||||||
return (
|
return (
|
||||||
<div class="navbar bg-base-100">
|
<div class="navbar bg-base-100">
|
||||||
<div class="flex-none">
|
<div class="flex-none">
|
||||||
<button class="btn btn-square btn-ghost">
|
<span class="tooltip tooltip-bottom" data-tip="Menu">
|
||||||
<span class="material-icons">home</span>
|
<label
|
||||||
</button>
|
class="btn btn-square btn-ghost drawer-button"
|
||||||
|
for="toplevel-drawer"
|
||||||
|
>
|
||||||
|
<span class="material-icons">menu</span>
|
||||||
|
</label>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<a class="btn btn-ghost text-xl">Clan</a>
|
<a class="text-xl">{currClanURI() || "Clan"}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-none">
|
<div class="flex-none">
|
||||||
<button class="btn btn-square btn-ghost">
|
<span class="tooltip tooltip-bottom" data-tip="Account">
|
||||||
<span class="material-icons">menu</span>
|
<button class="btn btn-square btn-ghost">
|
||||||
</button>
|
<span class="material-icons">account_circle</span>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export const BlockDevicesView: Component = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div class="tooltip" data-tip="Refresh">
|
<div class="tooltip tooltip-bottom" data-tip="Refresh">
|
||||||
<button
|
<button
|
||||||
class="btn btn-ghost"
|
class="btn btn-ghost"
|
||||||
onClick={() => pyApi.show_block_devices.dispatch({})}
|
onClick={() => pyApi.show_block_devices.dispatch({})}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export const HostList: Component = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div class="tooltip" data-tip="Refresh install targets">
|
<div class="tooltip tooltip-bottom" data-tip="Refresh install targets">
|
||||||
<button
|
<button
|
||||||
class="btn btn-ghost"
|
class="btn btn-ghost"
|
||||||
onClick={() => pyApi.show_mdns.dispatch({})}
|
onClick={() => pyApi.show_mdns.dispatch({})}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
type Component,
|
type Component,
|
||||||
} from "solid-js";
|
} from "solid-js";
|
||||||
import { useMachineContext } from "../../Config";
|
import { useMachineContext } from "../../Config";
|
||||||
import { route } from "@/src/App";
|
import { route, setCurrClanURI } from "@/src/App";
|
||||||
import { OperationResponse, pyApi } from "@/src/api";
|
import { OperationResponse, pyApi } 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";
|
||||||
@@ -28,6 +28,17 @@ type MachinesModel = Extract<
|
|||||||
{ status: "success" }
|
{ status: "success" }
|
||||||
>["data"];
|
>["data"];
|
||||||
|
|
||||||
|
pyApi.open_file.receive((r) => {
|
||||||
|
if (r.op_key === "open_clan") {
|
||||||
|
console.log(r);
|
||||||
|
if (r.status === "error") return console.error(r.errors);
|
||||||
|
|
||||||
|
if (r.data) {
|
||||||
|
setCurrClanURI(r.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export const MachineListView: Component = () => {
|
export const MachineListView: Component = () => {
|
||||||
const [{ machines, loading }, { getMachines }] = useMachineContext();
|
const [{ machines, loading }, { getMachines }] = useMachineContext();
|
||||||
|
|
||||||
@@ -77,7 +88,7 @@ export const MachineListView: Component = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="max-w-screen-lg">
|
<div class="max-w-screen-lg">
|
||||||
<div class="tooltip" data-tip="Open Clan">
|
<div class="tooltip tooltip-bottom" data-tip="Open Clan">
|
||||||
<button
|
<button
|
||||||
class="btn btn-ghost"
|
class="btn btn-ghost"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
@@ -86,13 +97,14 @@ export const MachineListView: Component = () => {
|
|||||||
title: "Open Clan",
|
title: "Open Clan",
|
||||||
mode: "select_folder",
|
mode: "select_folder",
|
||||||
},
|
},
|
||||||
|
op_key: "open_clan",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<span class="material-icons ">folder_open</span>
|
<span class="material-icons ">folder_open</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="tooltip" data-tip="Search install targets">
|
<div class="tooltip tooltip-bottom" data-tip="Search install targets">
|
||||||
<button
|
<button
|
||||||
class="btn btn-ghost"
|
class="btn btn-ghost"
|
||||||
onClick={() => pyApi.show_mdns.dispatch({})}
|
onClick={() => pyApi.show_mdns.dispatch({})}
|
||||||
@@ -100,7 +112,7 @@ export const MachineListView: Component = () => {
|
|||||||
<span class="material-icons ">search</span>
|
<span class="material-icons ">search</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="tooltip" data-tip="Refresh">
|
<div class="tooltip tooltip-bottom" data-tip="Refresh">
|
||||||
<button class="btn btn-ghost" onClick={() => getMachines()}>
|
<button class="btn btn-ghost" onClick={() => getMachines()}>
|
||||||
<span class="material-icons ">refresh</span>
|
<span class="material-icons ">refresh</span>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user