Merge pull request 'Clan-app: show nixos machines and inventory machines' (#1849) from hsjobeki/clan-core:hsjobeki-main into main
This commit is contained in:
@@ -5,7 +5,7 @@ type MachineDetails = SuccessData<"list_inventory_machines">["data"][string];
|
||||
|
||||
interface MachineListItemProps {
|
||||
name: string;
|
||||
info: MachineDetails;
|
||||
info?: MachineDetails;
|
||||
}
|
||||
|
||||
type HWInfo = Record<string, SuccessData<"show_machine_hardware_info">["data"]>;
|
||||
@@ -53,21 +53,6 @@ const [errors, setErrors] = createSignal<MachineErrors>({});
|
||||
export const MachineListItem = (props: MachineListItemProps) => {
|
||||
const { name, info } = props;
|
||||
|
||||
// const clan_dir = currClanURI();
|
||||
// if (clan_dir) {
|
||||
// pyApi.show_machine_hardware_info.dispatch({
|
||||
// op_key: name,
|
||||
// clan_dir,
|
||||
// machine_name: name,
|
||||
// });
|
||||
|
||||
// pyApi.show_machine_deployment_target.dispatch({
|
||||
// op_key: name,
|
||||
// clan_dir,
|
||||
// machine_name: name,
|
||||
// });
|
||||
// }
|
||||
|
||||
return (
|
||||
<li>
|
||||
<div class="card card-side m-2 bg-base-100 shadow-lg">
|
||||
@@ -80,48 +65,9 @@ export const MachineListItem = (props: MachineListItemProps) => {
|
||||
<div class="flex flex-col">
|
||||
<h2 class="card-title">{name}</h2>
|
||||
<div class="text-slate-600">
|
||||
<Show
|
||||
when={info}
|
||||
fallback={
|
||||
<Switch fallback={<div class="skeleton h-8 w-full"></div>}>
|
||||
<Match when={!info.description}>No description</Match>
|
||||
</Switch>
|
||||
}
|
||||
>
|
||||
{(d) => d()?.description}
|
||||
</Show>
|
||||
</div>
|
||||
<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">
|
||||
<span>System:</span>
|
||||
{hwInfo()[name]?.system ? (
|
||||
<span class="text-primary">{hwInfo()[name]?.system}</span>
|
||||
) : (
|
||||
<span class="text-warning">Not set</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div class="badge badge-ghost flex flex-row gap-1 py-4 align-middle">
|
||||
<span>Target Host:</span>
|
||||
{deploymentInfo()[name] ? (
|
||||
<span class="text-primary">{deploymentInfo()[name]}</span>
|
||||
) : (
|
||||
<span class="text-warning">Not set</span>
|
||||
)}
|
||||
{/* <Show
|
||||
when={deploymentInfo()[name]}
|
||||
fallback={
|
||||
<Switch fallback={<div class="skeleton h-8 w-full"></div>}>
|
||||
<Match when={deploymentInfo()[name] !== undefined}>
|
||||
No deployment target detected
|
||||
</Match>
|
||||
</Switch>
|
||||
}
|
||||
>
|
||||
{(i) => + i()}
|
||||
</Show> */}
|
||||
</div>
|
||||
<Show when={info}>{(d) => d()?.description}</Show>
|
||||
</div>
|
||||
<div class="flex flex-row flex-wrap gap-4 py-2"></div>
|
||||
{/* Show only the first error at the bottom */}
|
||||
<Show when={errors()[name]?.[0]}>
|
||||
{(error) => (
|
||||
|
||||
@@ -11,6 +11,7 @@ import { activeURI, route, setActiveURI, setRoute } from "@/src/App";
|
||||
import { callApi, OperationResponse, pyApi } from "@/src/api";
|
||||
import toast from "solid-toast";
|
||||
import { MachineListItem } from "@/src/components/MachineListItem";
|
||||
import { createQuery } from "@tanstack/solid-query";
|
||||
|
||||
// type FilesModel = Extract<
|
||||
// OperationResponse<"get_directory">,
|
||||
@@ -39,20 +40,28 @@ type MachinesModel = Extract<
|
||||
// });
|
||||
|
||||
export const MachineListView: Component = () => {
|
||||
// const [files, setFiles] = createSignal<FilesModel>([]);
|
||||
|
||||
// pyApi.get_directory.receive((r) => {
|
||||
// const { status } = r;
|
||||
// if (status === "error") return console.error(r.errors);
|
||||
// setFiles(r.data.files);
|
||||
// });
|
||||
|
||||
// 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);
|
||||
// });
|
||||
const {
|
||||
data: nixosMachines,
|
||||
isFetching,
|
||||
isLoading,
|
||||
} = createQuery<string[]>(() => ({
|
||||
queryKey: [activeURI(), "list_nixos_machines"],
|
||||
queryFn: async () => {
|
||||
const uri = activeURI();
|
||||
if (uri) {
|
||||
const response = await callApi("list_nixos_machines", {
|
||||
flake_url: uri,
|
||||
});
|
||||
if (response.status === "error") {
|
||||
toast.error("Failed to fetch data");
|
||||
} else {
|
||||
return response.data;
|
||||
}
|
||||
}
|
||||
return [];
|
||||
},
|
||||
staleTime: 1000 * 60 * 5,
|
||||
}));
|
||||
|
||||
const [machines, setMachines] = createSignal<MachinesModel>({});
|
||||
const [loading, setLoading] = createSignal<boolean>(false);
|
||||
@@ -77,6 +86,14 @@ export const MachineListView: Component = () => {
|
||||
});
|
||||
|
||||
const unpackedMachines = () => Object.entries(machines());
|
||||
const nixOnlyMachines = () =>
|
||||
nixosMachines?.filter(
|
||||
(name) => !unpackedMachines().some(([key, machine]) => key === name),
|
||||
);
|
||||
|
||||
createEffect(() => {
|
||||
console.log(nixOnlyMachines(), unpackedMachines());
|
||||
});
|
||||
|
||||
return (
|
||||
<div class="max-w-screen-lg">
|
||||
@@ -155,7 +172,13 @@ export const MachineListView: Component = () => {
|
||||
</div>
|
||||
</div>
|
||||
</Match>
|
||||
<Match when={!loading() && unpackedMachines().length === 0}>
|
||||
<Match
|
||||
when={
|
||||
!loading() &&
|
||||
unpackedMachines().length === 0 &&
|
||||
nixOnlyMachines()?.length === 0
|
||||
}
|
||||
>
|
||||
No machines found
|
||||
</Match>
|
||||
<Match when={!loading()}>
|
||||
@@ -163,6 +186,9 @@ export const MachineListView: Component = () => {
|
||||
<For each={unpackedMachines()}>
|
||||
{([name, info]) => <MachineListItem name={name} info={info} />}
|
||||
</For>
|
||||
<For each={nixOnlyMachines()}>
|
||||
{(name) => <MachineListItem name={name} />}
|
||||
</For>
|
||||
</ul>
|
||||
</Match>
|
||||
</Switch>
|
||||
|
||||
Reference in New Issue
Block a user