diff --git a/pkgs/clan-app/ui/src/routes/Clan/Clan.tsx b/pkgs/clan-app/ui/src/routes/Clan/Clan.tsx index 10116caf8..e2a3d15d7 100644 --- a/pkgs/clan-app/ui/src/routes/Clan/Clan.tsx +++ b/pkgs/clan-app/ui/src/routes/Clan/Clan.tsx @@ -36,6 +36,11 @@ import { createForm, FieldValues, reset } from "@modular-forms/solid"; import { Sidebar } from "@/src/components/Sidebar/Sidebar"; import { UseQueryResult } from "@tanstack/solid-query"; import { ListClansModal } from "@/src/modals/ListClansModal/ListClansModal"; +import { + InventoryInstance, + ServiceWorkflow, +} from "@/src/workflows/Service/Service"; +import { useApiClient } from "@/src/hooks/ApiClient"; interface ClanContextProps { clanURI: string; @@ -179,7 +184,10 @@ const ClanSceneController = (props: RouteSectionProps) => { const navigate = useNavigate(); - const [dialogHandlers, setDialogHandlers] = createSignal<{ + const [showService, setShowService] = createSignal(false); + + const [showModal, setShowModal] = createSignal(false); + const [currentPromise, setCurrentPromise] = createSignal<{ resolve: ({ id }: { id: string }) => void; reject: (err: unknown) => void; } | null>(null); @@ -187,7 +195,15 @@ const ClanSceneController = (props: RouteSectionProps) => { const onCreate = async (): Promise<{ id: string }> => { return new Promise((resolve, reject) => { setShowModal(true); - setDialogHandlers({ resolve, reject }); + setCurrentPromise({ resolve, reject }); + }); + }; + + const onAddService = async (): Promise<{ id: string }> => { + return new Promise((resolve, reject) => { + setShowService(true); + console.log("setting current promise"); + setCurrentPromise({ resolve, reject }); }); }; @@ -217,8 +233,6 @@ const ClanSceneController = (props: RouteSectionProps) => { return { id: values.name }; }; - const [showModal, setShowModal] = createSignal(false); - const [loadingError, setLoadingError] = createSignal< { title: string; description: string } | undefined >(); @@ -265,6 +279,26 @@ const ClanSceneController = (props: RouteSectionProps) => { }), ); + const client = useApiClient(); + const handleSubmitService = async (instance: InventoryInstance) => { + console.log("Create Instance", instance); + const call = client.fetch("create_service_instance", { + flake: { + identifier: ctx.clanURI, + }, + module_ref: instance.module, + roles: instance.roles, + }); + const result = await call.result; + + if (result.status === "error") { + console.error("Error creating service instance", result.errors); + } + // + currentPromise()?.resolve({ id: "0" }); + setShowService(false); + }; + return ( <> @@ -274,15 +308,15 @@ const ClanSceneController = (props: RouteSectionProps) => { { setShowModal(false); - dialogHandlers()?.reject(new Error("User cancelled")); + currentPromise()?.reject(new Error("User cancelled")); }} onSubmit={async (values) => { try { const result = await sendCreate(values); - dialogHandlers()?.resolve(result); + currentPromise()?.resolve(result); setShowModal(false); } catch (err) { - dialogHandlers()?.reject(err); + currentPromise()?.reject(err); setShowModal(false); } }} @@ -297,10 +331,22 @@ const ClanSceneController = (props: RouteSectionProps) => { + { + setShowService(false); + currentPromise()?.resolve({ id: "0" }); + }} + /> + + } onCreate={onCreate} clanURI={ctx.clanURI} sceneStore={() => store.sceneData?.[ctx.clanURI]} diff --git a/pkgs/clan-app/ui/src/scene/cubes.css b/pkgs/clan-app/ui/src/scene/cubes.css index 9be825105..063fe6ad8 100644 --- a/pkgs/clan-app/ui/src/scene/cubes.css +++ b/pkgs/clan-app/ui/src/scene/cubes.css @@ -4,6 +4,8 @@ cursor: pointer; } +/*
+ */ .toolbar-container { @apply absolute bottom-10 z-10 w-full; @apply flex justify-center items-center; diff --git a/pkgs/clan-app/ui/src/scene/cubes.tsx b/pkgs/clan-app/ui/src/scene/cubes.tsx index ef3e322f8..b20024c2a 100644 --- a/pkgs/clan-app/ui/src/scene/cubes.tsx +++ b/pkgs/clan-app/ui/src/scene/cubes.tsx @@ -1,4 +1,11 @@ -import { createSignal, createEffect, onCleanup, onMount, on } from "solid-js"; +import { + createSignal, + createEffect, + onCleanup, + onMount, + on, + JSX, +} from "solid-js"; import "./cubes.css"; import * as THREE from "three"; @@ -34,12 +41,14 @@ function garbageCollectGroup(group: THREE.Group) { export function CubeScene(props: { cubesQuery: MachinesQueryResult; onCreate: () => Promise<{ id: string }>; + onAddService: () => Promise<{ id: string }>; selectedIds: Accessor>; onSelect: (v: Set) => void; sceneStore: Accessor; setMachinePos: (machineId: string, pos: [number, number] | null) => void; isLoading: boolean; clanURI: string; + toolbarPopup?: JSX.Element; }) { let container: HTMLDivElement; let scene: THREE.Scene; @@ -213,7 +222,7 @@ export function CubeScene(props: { controls = new MapControls(camera, renderer.domElement); controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled controls.mouseButtons.RIGHT = null; - controls.enableRotate = false; + // controls.enableRotate = false; controls.minZoom = 1.2; controls.maxZoom = 3.5; controls.addEventListener("change", () => { @@ -543,6 +552,9 @@ export function CubeScene(props: { <>
(container = el)} />
+
+ {props.toolbarPopup} +