load all deployments in one

This commit is contained in:
mbecker20
2022-04-09 23:54:15 -07:00
parent 753de978c0
commit fe644f4e94
9 changed files with 196 additions and 77 deletions
+62 -24
View File
@@ -13,35 +13,73 @@ import {
getPeripheryContainers,
} from "../util/periphery/container";
async function getDeployments(app: FastifyInstance, serverID: string) {
const server = await app.servers.findById(serverID);
if (!server) return {};
const deployments = await app.deployments.find(
{ serverID: server._id },
"name containerName serverID owners repo"
);
const status = server.isCore
? await deploymentStatusLocal(app)
: await getPeripheryContainers(server);
return intoCollection(
deployments.map((deployment) => ({
...deployment,
status: status[deployment.containerName!] || "not deployed",
}))
);
}
const deployments = fp((app: FastifyInstance, _: {}, done: () => void) => {
// app.get(
// "/api/deployments",
// { onRequest: [app.auth, app.userEnabled] },
// async (req, res) => {
// // returns the periphery deployments on the given serverID
// // returns the core deployments if no serverID is specified
// const { serverID } = req.query as { serverID?: string };
// const server = serverID ? await app.servers.findById(serverID) : app.core;
// if (!server) {
// res.status(400);
// res.send();
// return;
// }
// const deployments = await app.deployments.find(
// { serverID: server._id },
// "name containerName serverID owners repo"
// );
// const status = server.isCore
// ? await deploymentStatusLocal(app)
// : await getPeripheryContainers(server);
// res.send(
// intoCollection(
// deployments.map((deployment) => ({
// ...deployment,
// status: status[deployment.containerName!] || "not deployed",
// }))
// )
// );
// }
// );
app.get(
"/api/deployments",
{ onRequest: [app.auth, app.userEnabled] },
async (req, res) => {
// returns the periphery deployments on the given serverID
// returns the core deployments if no serverID is specified
const { serverID } = req.query as { serverID?: string };
const server = serverID ? await app.servers.findById(serverID) : app.core;
if (!server) {
res.status(400);
res.send();
return;
}
const deployments = await app.deployments.find(
{ serverID: server._id },
"name containerName serverID owners repo"
);
const status = server.isCore
? await deploymentStatusLocal(app)
: await getPeripheryContainers(server);
res.send(
intoCollection(
deployments.map((deployment) => ({
...deployment,
status: status[deployment.containerName!] || "not deployed",
}))
async (_, res) => {
// returns all the deployments
const servers = await app.servers.find({});
const deployments = (
await Promise.all(
servers.map((server) => getDeployments(app, server._id!))
)
);
).reduce((acc, curr) => {
Object.keys(curr).forEach((id) => {
acc[id] = curr[id];
});
return acc;
}, {});
res.send(deployments);
}
);
+1 -1
View File
@@ -11,4 +11,4 @@ export function sendAlert(
message: string
) {
client.send(JSON.stringify({ type: ALERT, status, message }))
}
}
+64 -2
View File
@@ -14,11 +14,68 @@ const Header: Component<{}> = (p) => {
const { servers, deployments, ws, selected } = useAppState();
const deployment = () => deployments.get(selected.id());
const server = () => deployment() && servers.get(deployment()?.serverID!);
const status = () =>
const state = () =>
deployment()!.status === "not deployed"
? "not deployed"
: (deployment()!.status as ContainerStatus).State;
const status = () =>
deployment()!.status === "not deployed"
? undefined
: (deployment()!.status as ContainerStatus).Status.toLowerCase();
const actions = useActionStates();
return (
<Grid gap="0.5rem" class="card shadow">
<Flex alignItems="center" justifyContent="space-between">
<h1>{deployment()!.name}</h1>
<Show
when={!actions.fullDeleting}
fallback={
<button class="red">
<Icon type="trash" />
</button>
}
>
<HoverMenu
target={
<ConfirmButton
onConfirm={() => {
ws.send(DELETE_DEPLOYMENT, { deploymentID: selected.id() });
}}
color="red"
>
<Icon type="trash" />
</ConfirmButton>
}
content="delete deployment"
position="bottom center"
padding="0.5rem"
/>
</Show>
</Flex>
<Flex alignItems="center" justifyContent="space-between">
<HoverMenu
target={
<button
class="grey"
style={{ opacity: 0.8 }}
onClick={() => selected.set(deployment()?.serverID!, "server")}
>
{server()!.name}
</button>
}
content="show server"
position="bottom center"
padding="0.5rem"
/>
<Flex alignItems="center">
<div class={deploymentStatusClass(state())}>{state()}</div>
<Show when={status()}>
<div style={{ opacity: 0.7 }}>{status()}</div>
</Show>
</Flex>
</Flex>
</Grid>
);
return (
<Flex
class="card shadow"
@@ -36,7 +93,12 @@ const Header: Component<{}> = (p) => {
</button>
</Grid>
<Flex alignItems="center">
<div class={deploymentStatusClass(status())}>{status()}</div>
<Grid gap="0.3rem" placeItems="center start">
<div class={deploymentStatusClass(state())}>{state()}</div>
<Show when={status()}>
<div style={{ opacity: 0.7 }}>{status()}</div>
</Show>
</Grid>
<Show
when={!actions.fullDeleting}
fallback={
+25 -13
View File
@@ -33,6 +33,14 @@ const Home: Component<{}> = (p) => {
(id) =>
permissions() > 1 || servers.get(id)!.owners.includes(username()!)
);
const deploymentState = (id: string) =>
deployments.get(id)!.status === "not deployed"
? "not deployed"
: (deployments.get(id)!.status as ContainerStatus).State;
const deploymentStatus = (id: string) =>
deployments.get(id)!.status === "not deployed"
? undefined
: (deployments.get(id)!.status as ContainerStatus).Status.toLowerCase();
return (
<Grid class={s.Home}>
<Grid style={{ height: "fit-content" }}>
@@ -46,19 +54,15 @@ const Home: Component<{}> = (p) => {
<button
class="grey"
onClick={() => selected.set(id, "deployment")}
style={{ "justify-content": "space-between", width: "22rem" }}
>
<h2>{deployments.get(id)!.name}</h2>
<div
class={deploymentStatusClass(
deployments.get(id)!.status === "not deployed"
? "not deployed"
: (deployments.get(id)!.status as ContainerStatus).State
)}
>
{deployments.get(id)!.status === "not deployed"
? "not deployed"
: (deployments.get(id)!.status as ContainerStatus).State}
</div>
<Flex>
<div class={deploymentStatusClass(deploymentState(id))}>
{deploymentState(id)}
</div>
<div style={{ opacity: 0.7 }}>{deploymentStatus(id)}</div>
</Flex>
</button>
)}
</For>
@@ -70,7 +74,11 @@ const Home: Component<{}> = (p) => {
<h1>my servers</h1>
<For each={filteredServerIds()}>
{(id) => (
<button class="grey" onClick={() => selected.set(id, "server")}>
<button
class="grey"
onClick={() => selected.set(id, "server")}
style={{ "justify-content": "space-between", width: "22rem" }}
>
<h2>{servers.get(id)!.name}</h2>
<div
class={serverStatusClass(
@@ -98,7 +106,11 @@ const Home: Component<{}> = (p) => {
<h1>my builds</h1>
<For each={filteredBuildIds()}>
{(id) => (
<button class="grey" onClick={() => selected.set(id, "build")}>
<button
class="grey"
onClick={() => selected.set(id, "build")}
style={{ "justify-content": "space-between", width: "22rem" }}
>
<h2>{builds.get(id)!.name}</h2>
</button>
)}
@@ -22,13 +22,13 @@ const Server: Component<{ id: string }> = (p) => {
);
});
const [open, toggleOpen] = useLocalStorageToggle(p.id);
createEffect(() => {
if (server() && !server()!.isCore) {
getDeployments({ serverID: p.id }).then((more) =>
deployments.addMany(more)
);
}
});
// createEffect(() => {
// if (server() && !server()!.isCore) {
// getDeployments({ serverID: p.id }).then((more) =>
// deployments.addMany(more)
// );
// }
// });
return (
<Show when={server()}>
<div class={combineClasses(s.Server, "shadow")}>
@@ -42,7 +42,7 @@ const Server: Component<{ id: string }> = (p) => {
>
<Flex>
<Icon type="chevron-down" width="1rem" />
<div>{server()?.name}</div>
<h2>{server()?.name}</h2>
</Flex>
<div
class={server()?.status === "OK" ? "green" : "red"}
+15 -11
View File
@@ -43,14 +43,19 @@ export function useSelected({ servers, builds, deployments }: State) {
history.replaceState({ id: "", type: "home" }, "", "/");
setFirstLoad(false);
} else if (selected().type === "deployment" && deployments.loaded()) {
const [type, id] = location.pathname.split("/").filter((val) => val);
if (type !== selected().type || id !== selected().id) {
history.replaceState(
{ id, type },
"",
`${selected().type}/${selected().id}`
);
setFirstLoad(false);
if (!deployments.get(selected().id)) {
const id = deployments.ids()![0];
set(id, "deployment");
} else {
const [type, id] = location.pathname.split("/").filter((val) => val);
if (type !== selected().type || id !== selected().id) {
history.replaceState(
{ type, id },
"",
`${selected().type}/${selected().id}`
);
setFirstLoad(false);
}
}
setFirstLoad(false);
} else if (
@@ -69,7 +74,6 @@ export function useSelected({ servers, builds, deployments }: State) {
"",
`${selected().type}/${selected().id}`
);
setFirstLoad(false);
}
}
setFirstLoad(false);
@@ -123,8 +127,8 @@ export function useBuilds() {
return useCollection(getBuilds);
}
export function useDeployments(query?: Parameters<typeof getDeployments>[0]) {
return useCollection(() => getDeployments(query));
export function useDeployments() {
return useCollection(getDeployments);
}
export function useUpdates(query?: Parameters<typeof getUpdates>[0]) {
+3 -3
View File
@@ -1,8 +1,8 @@
$app-color: #fceade;
$lightgrey: #414852;
$grey: #2c3137;
$darkgrey: #1c1f23;
$lightgrey: #3f454d;
$grey: #25292e;
$darkgrey: #16181b;
$lightblue: #1c63cd;
$blue: #184e9f;
+10 -2
View File
@@ -1,9 +1,18 @@
@use "colors" as c;
@import url("https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@300;400;500&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Work+Sans&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Ubuntu+Mono&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Tajawal&display=swap");
body {
margin: 0;
font-family: "Chakra Petch", sans-serif;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
// font-family: "Chakra Petch", sans-serif;
// font-family: "Work Sans", sans-serif;
// font-family: 'Ubuntu Mono', monospace;
// font-family: "Tajawal", sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
@@ -82,7 +91,6 @@ input::placeholder {
background-color: rgba(c.$grey, 0.8);
}
.grey {
background-color: rgba(c.$grey, 0.8);
}
+8 -13
View File
@@ -39,24 +39,16 @@ export async function getBuildActionState(buildID: string) {
);
}
export async function addOwnerToBuild(
buildID: string,
username: string
) {
export async function addOwnerToBuild(buildID: string, username: string) {
return await client.post(`/api/build/${buildID}/${username}`);
}
export async function removeOwnerFromBuild(
buildID: string,
username: string
) {
export async function removeOwnerFromBuild(buildID: string, username: string) {
return await client.delete(`/api/build/${buildID}/${username}`);
}
export async function getDeployments(query?: { serverID?: string }) {
return await client.get<Deployments>(
"/api/deployments" + generateQuery(query)
);
export async function getDeployments() {
return await client.get<Deployments>("/api/deployments");
}
export async function getDeployment(deploymentID: string) {
@@ -107,7 +99,10 @@ export async function addOwnerToServer(serverID: string, username: string) {
return await client.post(`/api/server/${serverID}/${username}`);
}
export async function removeOwnerFromServer(serverID: string, username: string) {
export async function removeOwnerFromServer(
serverID: string,
username: string
) {
return await client.delete(`/api/server/${serverID}/${username}`);
}