UI: improve machine details
This commit is contained in:
@@ -6,14 +6,17 @@ export type OperationNames = keyof API;
|
|||||||
export type OperationArgs<T extends OperationNames> = API[T]["arguments"];
|
export type OperationArgs<T extends OperationNames> = API[T]["arguments"];
|
||||||
export type OperationResponse<T extends OperationNames> = API[T]["return"];
|
export type OperationResponse<T extends OperationNames> = API[T]["return"];
|
||||||
|
|
||||||
export type SuccessData<T extends OperationNames> = Extract<
|
export type SuccessQuery<T extends OperationNames> = Extract<
|
||||||
OperationResponse<T>,
|
OperationResponse<T>,
|
||||||
{ status: "success" }
|
{ status: "success" }
|
||||||
>;
|
>;
|
||||||
export type ErrorData<T extends OperationNames> = Extract<
|
export type SuccessData<T extends OperationNames> = SuccessQuery<T>["data"];
|
||||||
|
|
||||||
|
export type ErrorQuery<T extends OperationNames> = Extract<
|
||||||
OperationResponse<T>,
|
OperationResponse<T>,
|
||||||
{ status: "error" }
|
{ status: "error" }
|
||||||
>;
|
>;
|
||||||
|
export type ErrorData<T extends OperationNames> = ErrorQuery<T>["errors"];
|
||||||
|
|
||||||
export type ClanOperations = {
|
export type ClanOperations = {
|
||||||
[K in OperationNames]: (str: string) => void;
|
[K in OperationNames]: (str: string) => void;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { createSignal, Show } from "solid-js";
|
import { createSignal, Show } from "solid-js";
|
||||||
import { callApi, SuccessData } from "../api";
|
import { callApi, SuccessQuery } from "../api";
|
||||||
import { Menu } from "./Menu";
|
import { Menu } from "./Menu";
|
||||||
import { activeURI } from "../App";
|
import { activeURI } from "../App";
|
||||||
import toast from "solid-toast";
|
import toast from "solid-toast";
|
||||||
import { A, useNavigate } from "@solidjs/router";
|
import { A, useNavigate } from "@solidjs/router";
|
||||||
|
|
||||||
type MachineDetails = SuccessData<"list_inventory_machines">["data"][string];
|
type MachineDetails = SuccessQuery<"list_inventory_machines">["data"][string];
|
||||||
|
|
||||||
interface MachineListItemProps {
|
interface MachineListItemProps {
|
||||||
name: string;
|
name: string;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { callApi, SuccessData } from "@/src/api";
|
import { callApi, SuccessQuery } from "@/src/api";
|
||||||
import { BackButton } from "@/src/components/BackButton";
|
import { BackButton } from "@/src/components/BackButton";
|
||||||
import { useParams } from "@solidjs/router";
|
import { useParams } from "@solidjs/router";
|
||||||
import { createQuery } from "@tanstack/solid-query";
|
import { createQuery } from "@tanstack/solid-query";
|
||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
} from "@modular-forms/solid";
|
} from "@modular-forms/solid";
|
||||||
import { TextInput } from "@/src/components/TextInput";
|
import { TextInput } from "@/src/components/TextInput";
|
||||||
|
|
||||||
type AdminData = SuccessData<"get_admin_service">["data"];
|
type AdminData = SuccessQuery<"get_admin_service">["data"];
|
||||||
|
|
||||||
interface ClanDetailsProps {
|
interface ClanDetailsProps {
|
||||||
admin: AdminData;
|
admin: AdminData;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { callApi, SuccessData } from "@/src/api";
|
import { callApi, SuccessData, SuccessQuery } from "@/src/api";
|
||||||
import { activeURI } from "@/src/App";
|
import { activeURI } from "@/src/App";
|
||||||
import { BackButton } from "@/src/components/BackButton";
|
import { BackButton } from "@/src/components/BackButton";
|
||||||
import { FileInput } from "@/src/components/FileInput";
|
import { FileInput } from "@/src/components/FileInput";
|
||||||
@@ -11,15 +11,14 @@ import { createSignal, For, Show, Switch, Match } from "solid-js";
|
|||||||
import toast from "solid-toast";
|
import toast from "solid-toast";
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
||||||
type MachineFormInterface = {
|
type MachineFormInterface = MachineType & {
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
targetHost?: string;
|
|
||||||
sshKey?: File;
|
sshKey?: File;
|
||||||
disk?: string;
|
disk?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Disks = SuccessData<"show_block_devices">["data"]["blockdevices"];
|
type MachineType = SuccessData<"get_inventory_machine_details">;
|
||||||
|
|
||||||
|
type Disks = SuccessQuery<"show_block_devices">["data"]["blockdevices"];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the custom file dialog
|
* Opens the custom file dialog
|
||||||
@@ -50,7 +49,7 @@ type InstallForm = { disk?: string };
|
|||||||
|
|
||||||
interface InstallMachineProps {
|
interface InstallMachineProps {
|
||||||
name?: string;
|
name?: string;
|
||||||
targetHost?: string;
|
targetHost?: string | null;
|
||||||
sshKey?: File;
|
sshKey?: File;
|
||||||
disks: Disks;
|
disks: Disks;
|
||||||
}
|
}
|
||||||
@@ -296,17 +295,19 @@ const InstallMachine = (props: InstallMachineProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
interface MachineDetailsProps {
|
interface MachineDetailsProps {
|
||||||
initialData: MachineFormInterface;
|
initialData: MachineType;
|
||||||
}
|
}
|
||||||
const MachineForm = (props: MachineDetailsProps) => {
|
const MachineForm = (props: MachineDetailsProps) => {
|
||||||
const [formStore, { Form, Field }] = createForm<MachineFormInterface>({
|
const [formStore, { Form, Field }] =
|
||||||
initialValues: props.initialData,
|
// TODO: retrieve the correct initial values from API
|
||||||
});
|
createForm<MachineFormInterface>({
|
||||||
|
initialValues: props.initialData,
|
||||||
|
});
|
||||||
|
|
||||||
const sshKey = () => getValue(formStore, "sshKey");
|
const sshKey = () => getValue(formStore, "sshKey");
|
||||||
const targetHost = () => getValue(formStore, "targetHost");
|
const targetHost = () => getValue(formStore, "machine.deploy.targetHost");
|
||||||
const machineName = () =>
|
const machineName = () =>
|
||||||
getValue(formStore, "name") || props.initialData.name;
|
getValue(formStore, "machine.name") || props.initialData.machine.name;
|
||||||
|
|
||||||
const onlineStatusQuery = createQuery(() => ({
|
const onlineStatusQuery = createQuery(() => ({
|
||||||
queryKey: [activeURI(), "machine", targetHost(), "check_machine_online"],
|
queryKey: [activeURI(), "machine", targetHost(), "check_machine_online"],
|
||||||
@@ -361,14 +362,8 @@ const MachineForm = (props: MachineDetailsProps) => {
|
|||||||
|
|
||||||
const machine_response = await callApi("set_machine", {
|
const machine_response = await callApi("set_machine", {
|
||||||
flake_url: curr_uri,
|
flake_url: curr_uri,
|
||||||
machine_name: props.initialData.name,
|
machine_name: props.initialData.machine.name,
|
||||||
machine: {
|
machine: values.machine,
|
||||||
name: values.name,
|
|
||||||
description: values.description,
|
|
||||||
deploy: {
|
|
||||||
targetHost: values.targetHost,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
if (machine_response.status === "error") {
|
if (machine_response.status === "error") {
|
||||||
toast.error(
|
toast.error(
|
||||||
@@ -445,7 +440,7 @@ const MachineForm = (props: MachineDetailsProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="my-2 w-full text-2xl">Details</div>
|
<div class="my-2 w-full text-2xl">Details</div>
|
||||||
<Field name="name">
|
<Field name="machine.name">
|
||||||
{(field, props) => (
|
{(field, props) => (
|
||||||
<TextInput
|
<TextInput
|
||||||
formStore={formStore}
|
formStore={formStore}
|
||||||
@@ -458,7 +453,7 @@ const MachineForm = (props: MachineDetailsProps) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
<Field name="description">
|
<Field name="machine.description">
|
||||||
{(field, props) => (
|
{(field, props) => (
|
||||||
<TextInput
|
<TextInput
|
||||||
formStore={formStore}
|
formStore={formStore}
|
||||||
@@ -478,7 +473,7 @@ const MachineForm = (props: MachineDetailsProps) => {
|
|||||||
Connection Settings
|
Connection Settings
|
||||||
</div>
|
</div>
|
||||||
<div class="collapse-content">
|
<div class="collapse-content">
|
||||||
<Field name="targetHost">
|
<Field name="machine.deploy.targetHost">
|
||||||
{(field, props) => (
|
{(field, props) => (
|
||||||
<TextInput
|
<TextInput
|
||||||
formStore={formStore}
|
formStore={formStore}
|
||||||
@@ -558,7 +553,7 @@ const MachineForm = (props: MachineDetailsProps) => {
|
|||||||
<InstallMachine
|
<InstallMachine
|
||||||
name={machineName()}
|
name={machineName()}
|
||||||
sshKey={sshKey()}
|
sshKey={sshKey()}
|
||||||
targetHost={getValue(formStore, "targetHost")}
|
targetHost={getValue(formStore, "machine.deploy.targetHost")}
|
||||||
disks={remoteDiskQuery.data?.blockdevices || []}
|
disks={remoteDiskQuery.data?.blockdevices || []}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -613,13 +608,7 @@ export const MachineDetails = () => {
|
|||||||
when={query.data}
|
when={query.data}
|
||||||
fallback={<span class="loading loading-lg"></span>}
|
fallback={<span class="loading loading-lg"></span>}
|
||||||
>
|
>
|
||||||
<MachineForm
|
{(data) => <MachineForm initialData={data()} />}
|
||||||
initialData={{
|
|
||||||
name: query.data?.machine.name ?? "",
|
|
||||||
description: query.data?.machine.description ?? "",
|
|
||||||
targetHost: query.data?.machine.deploy.targetHost ?? "",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user