GUI: add credentials page (vars)
add it to machine details
This commit is contained in:
@@ -538,6 +538,17 @@ const MachineForm = (props: MachineDetailsProps) => {
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
<Button
|
||||
variant="light"
|
||||
class="w-full"
|
||||
size="s"
|
||||
onClick={() => {
|
||||
navigate(`/machines/${machineName()}/vars`);
|
||||
}}
|
||||
endIcon={<Icon size={12} icon="Folder" />}
|
||||
>
|
||||
Credentials
|
||||
</Button>
|
||||
</div>
|
||||
<div class=" w-fit" data-tip="Machine must be online"></div>
|
||||
{/* <Typography hierarchy="label" size="default">
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
getValue,
|
||||
submit,
|
||||
setValue,
|
||||
FormStore,
|
||||
} from "@modular-forms/solid";
|
||||
import { createEffect, createSignal, JSX, Match, Switch } from "solid-js";
|
||||
import { TextInput } from "@/src/Form/fields";
|
||||
|
||||
@@ -8,12 +8,14 @@ import {
|
||||
import { createQuery, useQueryClient } from "@tanstack/solid-query";
|
||||
import { Typography } from "@/src/components/Typography";
|
||||
import { Group } from "@/src/components/group";
|
||||
import { For, Match, Show, Switch } from "solid-js";
|
||||
import { For, JSX, Match, Show, Switch } from "solid-js";
|
||||
import { TextInput } from "@/src/Form/fields";
|
||||
import toast from "solid-toast";
|
||||
import { useNavigate, useParams, useSearchParams } from "@solidjs/router";
|
||||
import { activeURI } from "@/src/App";
|
||||
import { StepProps } from "./hardware-step";
|
||||
import { BackButton } from "@/src/components/BackButton";
|
||||
import { Button } from "@/src/components/button";
|
||||
|
||||
export type VarsValues = FieldValues & Record<string, Record<string, string>>;
|
||||
|
||||
@@ -22,6 +24,7 @@ export interface VarsFormProps {
|
||||
dir: string;
|
||||
handleSubmit: SubmitHandler<VarsValues>;
|
||||
generators: SuccessData<"get_generators_closure">;
|
||||
footer: JSX.Element;
|
||||
}
|
||||
|
||||
export const VarsForm = (props: VarsFormProps) => {
|
||||
@@ -58,6 +61,10 @@ export const VarsForm = (props: VarsFormProps) => {
|
||||
>
|
||||
<div class="max-h-[calc(100vh-20rem)] overflow-y-scroll">
|
||||
<div class="flex h-full flex-col gap-6 p-4">
|
||||
<Show
|
||||
when={props.generators.length > 0}
|
||||
fallback="No credentials needed"
|
||||
>
|
||||
<For each={props.generators}>
|
||||
{(generator) => (
|
||||
<Group>
|
||||
@@ -65,7 +72,8 @@ export const VarsForm = (props: VarsFormProps) => {
|
||||
{generator.name}
|
||||
</Typography>
|
||||
<div>
|
||||
Bound to module (shared): {generator.share ? "True" : "False"}
|
||||
Bound to module (shared):{" "}
|
||||
{generator.share ? "True" : "False"}
|
||||
</div>
|
||||
<For each={generator.prompts}>
|
||||
{(prompt) => (
|
||||
@@ -123,22 +131,28 @@ export const VarsForm = (props: VarsFormProps) => {
|
||||
</Group>
|
||||
)}
|
||||
</For>
|
||||
</Show>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit">Submit</button>
|
||||
{props.footer}
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
export const VarsStep = (props: StepProps<VarsValues>) => {
|
||||
type VarsStepProps = StepProps<VarsValues> & {
|
||||
fullClosure?: boolean;
|
||||
};
|
||||
|
||||
export const VarsStep = (props: VarsStepProps) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const generatorsQuery = createQuery(() => ({
|
||||
queryKey: [props.dir, props.machine_id, "generators"],
|
||||
queryKey: [props.dir, props.machine_id, "generators", props.fullClosure],
|
||||
queryFn: async () => {
|
||||
const result = await callApi("get_generators_closure", {
|
||||
base_dir: props.dir,
|
||||
machine_name: props.machine_id,
|
||||
full_closure: props.fullClosure,
|
||||
});
|
||||
if (result.status === "error") throw new Error("Failed to fetch data");
|
||||
return result.data;
|
||||
@@ -181,6 +195,7 @@ export const VarsStep = (props: StepProps<VarsValues>) => {
|
||||
dir={props.dir}
|
||||
handleSubmit={handleSubmit}
|
||||
generators={generators()}
|
||||
footer={props.footer}
|
||||
/>
|
||||
)}
|
||||
</Match>
|
||||
@@ -196,19 +211,40 @@ export const VarsPage = () => {
|
||||
if (searchParams?.action === "update") {
|
||||
navigate(`/machines/${params.id}?action=update`);
|
||||
} else {
|
||||
toast.error("Invalid action for vars page");
|
||||
navigate(-1);
|
||||
}
|
||||
};
|
||||
const fullClosure = searchParams?.full_closure !== undefined;
|
||||
const footer = (
|
||||
<footer class="flex justify-end gap-y-3 border-t border-secondary-200 pt-5">
|
||||
<Button
|
||||
type="submit"
|
||||
// disabled={formStore.submitting || !formStore.dirty}
|
||||
>
|
||||
Update edits
|
||||
</Button>
|
||||
</footer>
|
||||
);
|
||||
return (
|
||||
<div class="p-1">
|
||||
{/* BackButton and header */}
|
||||
<BackButton />
|
||||
<div class="p-2">
|
||||
<h3 class="text-2xl">{params.id}</h3>
|
||||
</div>
|
||||
|
||||
{/* VarsStep component */}
|
||||
<Show when={activeURI()}>
|
||||
{(uri) => (
|
||||
<VarsStep
|
||||
machine_id={params.id}
|
||||
dir={uri()}
|
||||
handleNext={handleNext}
|
||||
footer
|
||||
footer={footer}
|
||||
fullClosure={fullClosure}
|
||||
/>
|
||||
)}
|
||||
</Show>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -684,7 +684,7 @@ def test_api_set_prompts(
|
||||
generators = get_generators_closure(
|
||||
machine_name="my_machine",
|
||||
base_dir=flake.path,
|
||||
regenerate=True,
|
||||
full_closure=True,
|
||||
include_previous_values=True,
|
||||
)
|
||||
assert len(generators) == 1
|
||||
|
||||
@@ -315,10 +315,10 @@ def _get_previous_value(
|
||||
def get_closure(
|
||||
machine: "Machine",
|
||||
generator_name: str | None,
|
||||
regenerate: bool,
|
||||
full_closure: bool,
|
||||
include_previous_values: bool = False,
|
||||
) -> list[Generator]:
|
||||
from .graph import all_missing_closure, full_closure
|
||||
from . import graph
|
||||
|
||||
vars_generators = machine.vars_generators()
|
||||
generators: dict[str, Generator] = {
|
||||
@@ -331,12 +331,12 @@ def get_closure(
|
||||
|
||||
result_closure = []
|
||||
if generator_name is None: # all generators selected
|
||||
if regenerate:
|
||||
result_closure = full_closure(generators)
|
||||
if full_closure:
|
||||
result_closure = graph.full_closure(generators)
|
||||
else:
|
||||
result_closure = all_missing_closure(generators)
|
||||
result_closure = graph.all_missing_closure(generators)
|
||||
# specific generator selected
|
||||
elif regenerate:
|
||||
elif full_closure:
|
||||
result_closure = requested_closure([generator_name], generators)
|
||||
else:
|
||||
result_closure = minimal_closure([generator_name], generators)
|
||||
@@ -353,7 +353,7 @@ def get_closure(
|
||||
def get_generators_closure(
|
||||
machine_name: str,
|
||||
base_dir: Path,
|
||||
regenerate: bool = False,
|
||||
full_closure: bool = False,
|
||||
include_previous_values: bool = False,
|
||||
) -> list[Generator]:
|
||||
from clan_cli.machines.machines import Machine
|
||||
@@ -361,7 +361,7 @@ def get_generators_closure(
|
||||
return get_closure(
|
||||
machine=Machine(name=machine_name, flake=Flake(str(base_dir))),
|
||||
generator_name=None,
|
||||
regenerate=regenerate,
|
||||
full_closure=full_closure,
|
||||
include_previous_values=include_previous_values,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user