diff --git a/pkgs/clan-app/shell.nix b/pkgs/clan-app/shell.nix index 7d123a9b4..6f66c1953 100644 --- a/pkgs/clan-app/shell.nix +++ b/pkgs/clan-app/shell.nix @@ -29,7 +29,7 @@ let ]); in mkShell { - inherit (clan-app) nativeBuildInputs; + inherit (clan-app) nativeBuildInputs propagatedBuildInputs; inputsFrom = [ self'.devShells.default ]; diff --git a/pkgs/clan-cli/clan_cli/api/serde.py b/pkgs/clan-cli/clan_cli/api/serde.py index 0f9c5d1fc..57345c3db 100644 --- a/pkgs/clan-cli/clan_cli/api/serde.py +++ b/pkgs/clan-cli/clan_cli/api/serde.py @@ -90,7 +90,9 @@ def from_dict(t: type[T], data: Any) -> T: """ adapter = TypeAdapter(t) try: - return adapter.validate_python(data) + return adapter.validate_python( + data, + ) except ValidationError as e: fst_error: ErrorDetails = e.errors()[0] if not fst_error: diff --git a/pkgs/clan-cli/clan_cli/api/util.py b/pkgs/clan-cli/clan_cli/api/util.py index 505fab545..2dd4e03c1 100644 --- a/pkgs/clan-cli/clan_cli/api/util.py +++ b/pkgs/clan-cli/clan_cli/api/util.py @@ -74,7 +74,9 @@ def type_to_dict(t: Any, scope: str = "", type_map: dict[TypeVar, type] = {}) -> if dataclasses.is_dataclass(t): fields = dataclasses.fields(t) properties = { - f.name: type_to_dict(f.type, f"{scope} {t.__name__}.{f.name}", type_map) + f.metadata.get("alias", f.name): type_to_dict( + f.type, f"{scope} {t.__name__}.{f.name}", type_map + ) for f in fields if not f.name.startswith("_") } diff --git a/pkgs/clan-cli/tests/test_deserializers.py b/pkgs/clan-cli/tests/test_deserializers.py index c93fa041f..f87b65adc 100644 --- a/pkgs/clan-cli/tests/test_deserializers.py +++ b/pkgs/clan-cli/tests/test_deserializers.py @@ -140,6 +140,21 @@ def test_alias_field() -> None: assert dataclass_to_dict(person, use_alias=False) == {"name": "John"} +def test_alias_field_from_orig_name() -> None: + """ + Field declares an alias. But the data is provided with the field name. + """ + + @dataclass + class Person: + name: str = field(metadata={"alias": "--user-name--"}) + + data = {"user": "John"} + + with pytest.raises(ClanError): + from_dict(Person, data) + + def test_path_field() -> None: @dataclass class Person: diff --git a/pkgs/webview-ui/app/src/Routes.tsx b/pkgs/webview-ui/app/src/Routes.tsx index aceef3271..a9a618fff 100644 --- a/pkgs/webview-ui/app/src/Routes.tsx +++ b/pkgs/webview-ui/app/src/Routes.tsx @@ -9,6 +9,7 @@ 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; @@ -63,6 +64,11 @@ export const routes = { label: "deploy", icon: "content_copy", }, + diskConfig: { + child: DiskView, + label: "diskConfig", + icon: "disk", + }, }; interface RouterProps { diff --git a/pkgs/webview-ui/app/src/routes/disk/view.tsx b/pkgs/webview-ui/app/src/routes/disk/view.tsx new file mode 100644 index 000000000..c9798c119 --- /dev/null +++ b/pkgs/webview-ui/app/src/routes/disk/view.tsx @@ -0,0 +1,33 @@ +import { callApi } from "@/src/api"; +import { activeURI } from "@/src/App"; +import { createQuery } from "@tanstack/solid-query"; +import { createEffect } from "solid-js"; + +export function DiskView() { + const query = createQuery(() => ({ + queryKey: ["disk", activeURI], + queryFn: async () => { + const currUri = activeURI(); + if (currUri) { + // Example of calling an API + const result = await callApi("get_inventory", { base_path: currUri }); + if (result.status === "error") throw new Error("Failed to fetch data"); + + return result.data; + } + }, + })); + createEffect(() => { + // Example debugging the data + console.log(query.data); + }); + return ( +
+

Configure Disk

+

+ Select machine then configure the disk. Required before installing for + the first time. +

+
+ ); +}