diff --git a/pkgs/clan-app/ui/src/components/Sidebar/SidebarBody.tsx b/pkgs/clan-app/ui/src/components/Sidebar/SidebarBody.tsx
index ccd762208..a5757bacb 100644
--- a/pkgs/clan-app/ui/src/components/Sidebar/SidebarBody.tsx
+++ b/pkgs/clan-app/ui/src/components/Sidebar/SidebarBody.tsx
@@ -3,7 +3,7 @@ import { A } from "@solidjs/router";
import { Accordion } from "@kobalte/core/accordion";
import Icon from "../Icon/Icon";
import { Typography } from "@/src/components/Typography/Typography";
-import { For, Suspense } from "solid-js";
+import { For } from "solid-js";
import { MachineStatus } from "@/src/components/MachineStatus/MachineStatus";
import { buildMachinePath, useClanURI } from "@/src/hooks/clan";
import { useMachinesQuery } from "@/src/queries/queries";
@@ -89,21 +89,19 @@ export const SidebarBody = (props: SidebarProps) => {
-
-
-
+
diff --git a/pkgs/clan-app/ui/src/components/Sidebar/SidebarHeader.tsx b/pkgs/clan-app/ui/src/components/Sidebar/SidebarHeader.tsx
index d22c75fc3..c0acc59db 100644
--- a/pkgs/clan-app/ui/src/components/Sidebar/SidebarHeader.tsx
+++ b/pkgs/clan-app/ui/src/components/Sidebar/SidebarHeader.tsx
@@ -4,7 +4,7 @@ import { DropdownMenu } from "@kobalte/core/dropdown-menu";
import { useNavigate } from "@solidjs/router";
import { Typography } from "../Typography/Typography";
import { createSignal, For, Suspense } from "solid-js";
-import { useAllClanDetailsQuery } from "@/src/queries/queries";
+import { useClanListQuery } from "@/src/queries/queries";
import { navigateToClan, useClanURI } from "@/src/hooks/clan";
import { clanURIs } from "@/src/stores/clan";
@@ -15,7 +15,7 @@ export const SidebarHeader = () => {
// get information about the current active clan
const clanURI = useClanURI();
- const allClans = useAllClanDetailsQuery(clanURIs());
+ const allClans = useClanListQuery(clanURIs());
const activeClan = () => allClans.find(({ data }) => data?.uri === clanURI);
diff --git a/pkgs/clan-app/ui/src/hooks/api.ts b/pkgs/clan-app/ui/src/hooks/api.ts
index c164c9f75..282edd77d 100644
--- a/pkgs/clan-app/ui/src/hooks/api.ts
+++ b/pkgs/clan-app/ui/src/hooks/api.ts
@@ -67,7 +67,7 @@ export const callApi = (
const op_key = backendOpts?.op_key ?? crypto.randomUUID();
- let req: BackendSendType = {
+ const req: BackendSendType = {
body: args,
header: {
...backendOpts,
diff --git a/pkgs/clan-app/ui/src/queries/queries.ts b/pkgs/clan-app/ui/src/queries/queries.ts
index 38e880400..387b2d764 100644
--- a/pkgs/clan-app/ui/src/queries/queries.ts
+++ b/pkgs/clan-app/ui/src/queries/queries.ts
@@ -3,8 +3,12 @@ import { callApi, SuccessData } from "../hooks/api";
import { encodeBase64 } from "@/src/hooks/clan";
export type ClanDetails = SuccessData<"get_clan_details">;
+export type ClanDetailsWithURI = ClanDetails & { uri: string };
+
export type ListMachines = SuccessData<"list_machines">;
+
export type MachinesQueryResult = UseQueryResult;
+export type ClanListQueryResult = UseQueryResult[];
export const useMachinesQuery = (clanURI: string) =>
useQuery(() => ({
@@ -48,7 +52,7 @@ export const useClanDetailsQuery = (clanURI: string) =>
},
}));
-export const useAllClanDetailsQuery = (clanURIs: string[]) =>
+export const useClanListQuery = (clanURIs: string[]): ClanListQueryResult =>
useQueries(() => ({
queries: clanURIs.map((clanURI) => ({
queryKey: ["clans", encodeBase64(clanURI), "details"],
diff --git a/pkgs/clan-app/ui/src/routes/Clan/Clan.tsx b/pkgs/clan-app/ui/src/routes/Clan/Clan.tsx
index c26a35e97..d6211fc05 100644
--- a/pkgs/clan-app/ui/src/routes/Clan/Clan.tsx
+++ b/pkgs/clan-app/ui/src/routes/Clan/Clan.tsx
@@ -15,9 +15,14 @@ import {
useClanURI,
} from "@/src/hooks/clan";
import { CubeScene } from "@/src/scene/cubes";
-import { MachinesQueryResult, useMachinesQuery } from "@/src/queries/queries";
+import {
+ ClanListQueryResult,
+ MachinesQueryResult,
+ useClanListQuery,
+ useMachinesQuery,
+} from "@/src/queries/queries";
import { callApi } from "@/src/hooks/api";
-import { store, setStore } from "@/src/stores/clan";
+import { store, setStore, clanURIs } from "@/src/stores/clan";
import { produce } from "solid-js/store";
import { Button } from "@/src/components/Button/Button";
import { Splash } from "@/src/scene/splash";
@@ -42,10 +47,12 @@ export const Clan: Component = (props) => {
interface CreateFormValues extends FieldValues {
name: string;
}
+
interface MockProps {
onClose: () => void;
onSubmit: (formValues: CreateFormValues) => void;
}
+
const MockCreateMachine = (props: MockProps) => {
let container: Node;
@@ -173,7 +180,26 @@ const ClanSceneController = (props: RouteSectionProps) => {
return (
- {({ query }) => {
+ {({ clansQuery, machinesQuery }) => {
+ // a combination of the individual clan details query status and the machines query status
+ // the cube scene needs the machines query, the sidebar needs the clans query and machines query results
+ // so we wait on both before removing the loader to avoid any loading artefacts
+ const isLoading = (): boolean => {
+ // check the machines query first
+ if (machinesQuery.isLoading) {
+ return true;
+ }
+
+ // otherwise iterate the clans query and return early if we find a queries that is still loading
+ for (const query of clansQuery) {
+ if (query.isLoading) {
+ return true;
+ }
+ }
+
+ return false;
+ };
+
return (
<>
@@ -217,7 +243,7 @@ const ClanSceneController = (props: RouteSectionProps) => {
ghost
onClick={() => {
console.log("Refetching API");
- query.refetch();
+ machinesQuery.refetch();
}}
>
Refetch API
@@ -225,7 +251,9 @@ const ClanSceneController = (props: RouteSectionProps) => {
{/* TODO: Add minimal display time */}
@@ -233,8 +261,8 @@ const ClanSceneController = (props: RouteSectionProps) => {
{
const clanURI = useClanURI();
@@ -268,10 +296,14 @@ const ClanSceneController = (props: RouteSectionProps) => {
const SceneDataProvider = (props: {
clanURI: string;
- children: (sceneData: { query: MachinesQueryResult }) => JSX.Element;
+ children: (sceneData: {
+ clansQuery: ClanListQueryResult;
+ machinesQuery: MachinesQueryResult;
+ }) => JSX.Element;
}) => {
+ const clansQuery = useClanListQuery(clanURIs());
const machinesQuery = useMachinesQuery(props.clanURI);
// This component can be used to provide scene data or context if needed
- return props.children({ query: machinesQuery });
+ return props.children({ clansQuery, machinesQuery });
};