Clan-app: example disk view
This commit is contained in:
@@ -29,7 +29,7 @@ let
|
||||
]);
|
||||
in
|
||||
mkShell {
|
||||
inherit (clan-app) nativeBuildInputs;
|
||||
inherit (clan-app) nativeBuildInputs propagatedBuildInputs;
|
||||
|
||||
inputsFrom = [ self'.devShells.default ];
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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("_")
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 {
|
||||
|
||||
33
pkgs/webview-ui/app/src/routes/disk/view.tsx
Normal file
33
pkgs/webview-ui/app/src/routes/disk/view.tsx
Normal file
@@ -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 (
|
||||
<div>
|
||||
<h1>Configure Disk</h1>
|
||||
<p>
|
||||
Select machine then configure the disk. Required before installing for
|
||||
the first time.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user