From 84b1b4e57bc8b7c591cf569dc93073a6d986f6e5 Mon Sep 17 00:00:00 2001 From: mbecker20 Date: Sat, 26 Mar 2022 06:37:18 -0700 Subject: [PATCH] updates --- core/src/messages/deployments/deploy.ts | 6 +- frontend/public/icons/download.svg | 7 + frontend/public/icons/upload.svg | 7 + .../src/components/deployment/Actions.tsx | 162 ++++++++++++------ .../deployment/Deployment.module.css | 5 + .../src/components/deployment/Updates.tsx | 26 ++- frontend/src/components/update/Update.tsx | 54 +++++- .../src/components/update/update.module.css | 14 +- .../src/components/util/ConfirmButton.tsx | 4 +- frontend/src/components/util/icons/Icon.tsx | 4 +- .../src/components/util/menu/Menu.module.css | 4 +- frontend/src/state/hooks.ts | 1 - frontend/src/state/socket.ts | 1 + util/docker.ts | 4 +- 14 files changed, 225 insertions(+), 74 deletions(-) create mode 100644 frontend/public/icons/download.svg create mode 100644 frontend/public/icons/upload.svg diff --git a/core/src/messages/deployments/deploy.ts b/core/src/messages/deployments/deploy.ts index 7ed3ced37..05a417606 100644 --- a/core/src/messages/deployments/deploy.ts +++ b/core/src/messages/deployments/deploy.ts @@ -31,9 +31,9 @@ async function deployDeployment( app.deployActionStates.set(deploymentID, DEPLOYING, true); app.broadcast(DEPLOY, { complete: false, deploymentID }); try { - const server = deployment.serverID - ? await app.servers.findById(deployment.serverID) - : undefined; + const server = deployment.serverID === app.core._id + ? undefined + : await app.servers.findById(deployment.serverID!); if (server) { // delete the container on periphery await deletePeripheryContainer(server, deployment.containerName!); diff --git a/frontend/public/icons/download.svg b/frontend/public/icons/download.svg new file mode 100644 index 000000000..0a92cb856 --- /dev/null +++ b/frontend/public/icons/download.svg @@ -0,0 +1,7 @@ + + + download + + + + diff --git a/frontend/public/icons/upload.svg b/frontend/public/icons/upload.svg new file mode 100644 index 000000000..f61e158d4 --- /dev/null +++ b/frontend/public/icons/upload.svg @@ -0,0 +1,7 @@ + + + upload + + + + diff --git a/frontend/src/components/deployment/Actions.tsx b/frontend/src/components/deployment/Actions.tsx index 47790fd51..91aad421c 100644 --- a/frontend/src/components/deployment/Actions.tsx +++ b/frontend/src/components/deployment/Actions.tsx @@ -1,68 +1,124 @@ import { ContainerStatus, Deployment } from "@monitor/types"; -import { Component, Match, Switch } from "solid-js"; +import { Component, Match, Show, Switch } from "solid-js"; +import { pushNotification } from "../.."; +import { + DELETE_CONTAINER, + DEPLOY, + START_CONTAINER, + STOP_CONTAINER, +} from "../../state/actions"; +import { useAppState } from "../../state/StateProvider"; import { combineClasses } from "../../util/helpers"; +import ConfirmButton from "../util/ConfirmButton"; import Icon from "../util/icons/Icon"; import Flex from "../util/layout/Flex"; import Grid from "../util/layout/Grid"; import s from "./deployment.module.css"; const Actions: Component<{ deployment: Deployment }> = (p) => { + const { ws } = useAppState(); return ( - -
actions
- - - - deploy{" "} - - - + + +
actions
+ + + + deploy{" "} + + { + ws.send(DEPLOY, { deploymentID: p.deployment._id }); + pushNotification("ok", `deploying ${p.deployment.name}...`); + }} + > + + + { + ws.send(DELETE_CONTAINER, { + deploymentID: p.deployment._id, + }); + pushNotification("ok", `removing container...`); + }} + > + + + -
- - container{" "} - - -
+ + container{" "} + { + ws.send(STOP_CONTAINER, { deploymentID: p.deployment._id }); + pushNotification("ok", `stopping container`); + }} + > + + + + - - - deploy{" "} - - - - - container{" "} - - - + + + deploy{" "} + { + ws.send(DEPLOY, { deploymentID: p.deployment._id }); + pushNotification("ok", `deploying ${p.deployment.name}...`); + }} + > + + + { + ws.send(DELETE_CONTAINER, { deploymentID: p.deployment._id }); + pushNotification("ok", `removing container...`); + }} + > + + + + + container{" "} + { + ws.send(START_CONTAINER, { deploymentID: p.deployment._id }); + pushNotification("ok", `starting container...`); + }} + > + + + + - - - deploy{" "} - - - -
-
+ + + deploy{" "} + { + ws.send(DEPLOY, { deploymentID: p.deployment._id }); + pushNotification("ok", `deploying ${p.deployment.name}...`); + }} + > + + + + + + + ); }; diff --git a/frontend/src/components/deployment/Deployment.module.css b/frontend/src/components/deployment/Deployment.module.css index 7d75a4b86..ef58c2fce 100644 --- a/frontend/src/components/deployment/Deployment.module.css +++ b/frontend/src/components/deployment/Deployment.module.css @@ -39,6 +39,11 @@ padding: 0.5rem; } +.UpdatesContainer { + max-height: 50vh; + overflow: scroll; +} + .Update { background-color: rgb(69, 34, 96); } diff --git a/frontend/src/components/deployment/Updates.tsx b/frontend/src/components/deployment/Updates.tsx index 487ca887d..b5c633c66 100644 --- a/frontend/src/components/deployment/Updates.tsx +++ b/frontend/src/components/deployment/Updates.tsx @@ -1,15 +1,31 @@ -import { Component, For, Show } from "solid-js"; +import { Component, For, onCleanup, Show } from "solid-js"; import { useArray, useUpdates } from "../../state/hooks"; import { combineClasses } from "../../util/helpers"; import Grid from "../util/layout/Grid"; import s from "./deployment.module.css"; import Update from "../update/Update"; import { getUpdates } from "../../util/query"; +import { useAppState } from "../../state/StateProvider"; +import { ADD_UPDATE } from "../../state/actions"; const Updates: Component<{ deploymentID: string }> = (p) => { + const { ws } = useAppState(); const selectedUpdates = useArray(() => getUpdates({ deploymentID: p.deploymentID }) ); + const listener = ({ data }: { data: string }) => { + const message = JSON.parse(data); + if ( + message.type === ADD_UPDATE && + message.update.deploymentID === p.deploymentID + ) { + selectedUpdates.add(message.update); + } + }; + ws.socket.addEventListener("message", listener); + onCleanup(() => { + ws.socket.removeEventListener("message", listener); + }); return ( = (p) => { >
updates
- - {(update) => } - + + + {(update) => } + +
); diff --git a/frontend/src/components/update/Update.tsx b/frontend/src/components/update/Update.tsx index 255531e7a..9943bde3e 100644 --- a/frontend/src/components/update/Update.tsx +++ b/frontend/src/components/update/Update.tsx @@ -1,10 +1,16 @@ import { Update as UpdateType } from "@monitor/types"; import { Component, Show } from "solid-js"; import { useAppState } from "../../state/StateProvider"; -import { combineClasses, readableOperation, readableTimestamp } from "../../util/helpers"; +import { + combineClasses, + readableOperation, + readableTimestamp, +} from "../../util/helpers"; +import { useToggle } from "../../util/hooks"; import Icon from "../util/icons/Icon"; import Flex from "../util/layout/Flex"; import Grid from "../util/layout/Grid"; +import CenterMenu from "../util/menu/CenterMenu"; import s from "./update.module.css"; const Update: Component<{ update: UpdateType; showName: boolean }> = (p) => { @@ -33,7 +39,20 @@ const Update: Component<{ update: UpdateType; showName: boolean }> = (p) => { } else { return op; } + }; + const log = () => { + const outText = p.update.log.stdout + ? `stdout:\n\n${p.update.log.stdout}` + + (p.update.log.stderr ? "\n\n" : "") + : ""; + const errText = p.update.log.stderr + ? `stderr:\n\n${p.update.log.stderr}` + : ""; + return outText + errText; } + const [showCommand, toggleShowCommand] = useToggle(); + const [showLog, toggleShowLog] = useToggle(); + const [showNote, toggleShowNote] = useToggle(); return ( @@ -46,7 +65,13 @@ const Update: Component<{ update: UpdateType; showName: boolean }> = (p) => { "grid-template-rows": "1fr 1fr", }} > -
{operation()}
+
+ {operation()} +
{readableTimestamp(p.update.timestamp)}
@@ -56,12 +81,31 @@ const Update: Component<{ update: UpdateType; showName: boolean }> = (p) => { {/* show command */} - + } + content={
{p.update.command}
} + /> + - + } + content={
} + />
{/* show log */} - + } + content={
{log()}
} + />
diff --git a/frontend/src/components/update/update.module.css b/frontend/src/components/update/update.module.css index ff954aab1..ae9b6eea7 100644 --- a/frontend/src/components/update/update.module.css +++ b/frontend/src/components/update/update.module.css @@ -1,4 +1,16 @@ .Update { - background-color: rgb(98, 46, 46); + background-color: rgb(83, 37, 37); padding: 0.75rem; +} + +.Log { + white-space: pre-line; + overflow-wrap: anywhere; + word-wrap: break-word; + max-height: 80vh; + overflow: scroll; + tab-size: 2; + -moz-tab-size: 2; + width: 40rem; + max-width: 90vw; } \ No newline at end of file diff --git a/frontend/src/components/util/ConfirmButton.tsx b/frontend/src/components/util/ConfirmButton.tsx index 749b4701e..e6d1da5a7 100644 --- a/frontend/src/components/util/ConfirmButton.tsx +++ b/frontend/src/components/util/ConfirmButton.tsx @@ -2,7 +2,7 @@ import { Component, createSignal, JSX } from "solid-js"; const ConfirmButton: Component<{ onConfirm: () => void; - color?: "red" | "green" | "blue"; + color?: "red" | "green" | "blue" | "orange"; style?: JSX.CSSProperties; }> = (p) => { const [confirm, set] = createSignal(false); @@ -20,7 +20,7 @@ const ConfirmButton: Component<{ set(confirm => !confirm); }} > - {confirm() ? "Confirm" : p.children} + {confirm() ? "confirm" : p.children} ); }; diff --git a/frontend/src/components/util/icons/Icon.tsx b/frontend/src/components/util/icons/Icon.tsx index c58877042..7e31d92f1 100644 --- a/frontend/src/components/util/icons/Icon.tsx +++ b/frontend/src/components/util/icons/Icon.tsx @@ -24,7 +24,9 @@ export type IconType = | "reset" | "plus" | "minus" - | "floppy-disk"; + | "floppy-disk" + | "download" + | "upload"; const Icon: Component<{ type: IconType; diff --git a/frontend/src/components/util/menu/Menu.module.css b/frontend/src/components/util/menu/Menu.module.css index c949a2d0d..fbfa446e1 100644 --- a/frontend/src/components/util/menu/Menu.module.css +++ b/frontend/src/components/util/menu/Menu.module.css @@ -115,14 +115,14 @@ } .CenterMenuContainer { - position: absolute; + position: fixed; z-index: 200; top: 0; left: 0; width: 100vw; height: 100vh; place-items: center; - background-color: rgba(0, 0, 0, 0.1); + background-color: rgba(0, 0, 0, 0.2); } .CenterMenuTitle { diff --git a/frontend/src/state/hooks.ts b/frontend/src/state/hooks.ts index 0f22ac45a..803c149a1 100644 --- a/frontend/src/state/hooks.ts +++ b/frontend/src/state/hooks.ts @@ -85,7 +85,6 @@ export function useUpdates(query?: Parameters[0]) { export function useArray(query: () => Promise) { const [collection, set] = createSignal(); createEffect(() => { - console.log("running query") query().then(set); }) const add = (item: T) => { diff --git a/frontend/src/state/socket.ts b/frontend/src/state/socket.ts index 2e1d61eb7..1ef026fcd 100644 --- a/frontend/src/state/socket.ts +++ b/frontend/src/state/socket.ts @@ -33,6 +33,7 @@ function socket(state: State) { }); return { + socket: ws, send: (type: string, message: T) => { ws.send(JSON.stringify({ ...message, type })); }, diff --git a/util/docker.ts b/util/docker.ts index 5289c72e8..7345ac6b1 100644 --- a/util/docker.ts +++ b/util/docker.ts @@ -118,7 +118,7 @@ export async function dockerRun( repoMount?: { repoFolder: string; containerMount: string } ) { const command = - `docker pull ${image}${latest && ":latest"} && docker run -d` + + `docker pull ${image}${latest ? ":latest" : ""} && docker run -d` + name(containerName) + containerUserString(containerUser) + portsString(ports) + @@ -173,7 +173,7 @@ function repoVolume( function restartString(restart?: string) { return restart - ? ` --restart=${restart}${restart === "on-failure" ? ":10" : ""}` + ? ` --restart ${restart}${restart === "on-failure" ? ":10" : ""}` : ""; }