add state

This commit is contained in:
mbecker20
2024-03-31 09:39:16 -07:00
parent e2244429ce
commit fc602054ba
12 changed files with 98 additions and 66 deletions

View File

@@ -203,8 +203,8 @@ impl From<Operation> for monitor_client::entities::Operation {
Operation::ModifyUserPermissions => {
UpdateUserPermissionsOnTarget
}
Operation::AutoBuild => AutoBuild,
Operation::AutoPull => AutoPull,
Operation::AutoBuild => RunBuild,
Operation::AutoPull => PullRepo,
}
}
}

View File

@@ -1,3 +1,4 @@
use derive_variants::EnumVariants;
use resolver_api::HasResponse;
use serde::{Deserialize, Serialize};
use typeshare::typeshare;
@@ -17,7 +18,8 @@ pub use server::*;
pub trait MonitorExecuteRequest: HasResponse {}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone)]
#[derive(Debug, Clone, Serialize, Deserialize, EnumVariants)]
#[variant_derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(tag = "type", content = "params")]
pub enum Execution {
/// For new executions upon instantiation

View File

@@ -368,8 +368,4 @@ pub enum Operation {
// user
UpdateUserPermissions,
UpdateUserPermissionsOnTarget,
// github webhook automation
AutoBuild,
AutoPull,
}

View File

@@ -141,6 +141,7 @@ export type GetBuildResponse = Build;
export interface BuildListItemInfo {
last_built_at: I64;
version: Version;
repo: string;
}
export type BuildListItem = ResourceListItem<BuildListItemInfo>;
@@ -1728,14 +1729,14 @@ export interface AwsBuilderConfig {
region: string;
instance_type: string;
volume_gb: number;
/** The port periphery will be running on */
port: number;
ami_id: string;
subnet_id: string;
security_group_ids: string[];
key_pair_name: string;
assign_public_ip: boolean;
use_public_ip: boolean;
/** The port periphery will be running on */
port: number;
github_accounts?: string[];
docker_accounts?: string[];
}

View File

@@ -72,6 +72,10 @@ const BuildTable = () => {
);
},
},
{
header: "Repo",
accessorKey: "info.repo"
},
{
header: "Version",
accessorFn: ({ info }) => fmt_version(info.version),
@@ -113,6 +117,7 @@ export const BuildComponents: RequiredResourceComponents = {
</div>
);
},
Status: () => <>Build</>,
Page: {
Config: ({ id }) => <BuildConfig id={id} />,
},

View File

@@ -189,6 +189,15 @@ export const DeploymentComponents: RequiredResourceComponents = {
Description,
Info,
Icon,
Status: ({ id }) => {
const state =
useDeployment(id)?.info.state ?? Types.DockerContainerState.Unknown;
return (
<div className={deployment_state_text_color(state)}>
{snake_case_to_upper_space_case(state)}
</div>
);
},
Actions: ({ id }) => (
<div className="flex gap-4">
<RedeployContainer id={id} />

View File

@@ -48,24 +48,27 @@ export const ServerInfo = ({
return (
<>
{showRegion && (
<div className="flex items-center gap-2">
<MapPin className="w-4 h-4" />
{useServer(id)?.info.region}
</div>
<>
<div className="flex items-center gap-2">
<MapPin className="w-4 h-4" />
{useServer(id)?.info.region}
</div>
|
</>
)}
<div className="flex gap-4 text-muted-foreground">
<div className="flex gap-2 items-center">
<Cpu className="w-4 h-4" />
{info?.core_count ?? "N/A"} Core(s)
</div>
<div className="flex gap-2 items-center">
<MemoryStick className="w-4 h-4" />
{stats?.mem_total_gb.toFixed(2) ?? "N/A"} GB
</div>
<div className="flex gap-2 items-center">
<Database className="w-4 h-4" />
{stats?.disk_total_gb.toFixed(2) ?? "N/A"} GB
</div>
<div className="flex gap-2 items-center">
<Cpu className="w-4 h-4" />
{info?.core_count ?? "N/A"} Core(s)
</div>
|
<div className="flex gap-2 items-center">
<MemoryStick className="w-4 h-4" />
{stats?.mem_total_gb.toFixed(2) ?? "N/A"} GB
</div>
|
<div className="flex gap-2 items-center">
<Database className="w-4 h-4" />
{stats?.disk_total_gb.toFixed(2) ?? "N/A"} GB
</div>
</>
);
@@ -195,6 +198,14 @@ const ServerTable = () => {
cell: ({ row }) => <DeploymentCountOnServer id={row.original.id} />,
},
{ header: "Region", accessorKey: "info.region" },
{
header: "State",
cell: ({
row: {
original: { id },
},
}) => <ServerComponents.Status id={id} />,
},
{
header: "Tags",
cell: ({ row }) => {
@@ -216,6 +227,20 @@ export const ServerComponents: RequiredResourceComponents = {
Info: ({ id }) => <ServerInfo id={id} />,
Actions: () => null,
Icon: ServerIconComponent,
Status: ({ id }) => {
const status = useServer(id)?.info.status;
const stateClass =
status === Types.ServerStatus.Ok
? "text-green-500"
: status === Types.ServerStatus.NotOk
? "text-red-500"
: "text-blue-500";
return (
<div className={stateClass}>
{status === Types.ServerStatus.NotOk ? "Not Ok" : status}
</div>
);
},
Page: {
Stats: ({ id }) => <ServerStats server_id={id} />,
Deployments: ({ id }) => {

View File

@@ -1,15 +1,6 @@
import { useRead, useResourceParamType } from "@lib/hooks";
import { ResourceComponents } from "./resources";
import {
Box,
Boxes,
FolderTree,
Key,
Moon,
SunMedium,
Tag,
UserCircle2,
} from "lucide-react";
import { Box, Boxes, FolderTree, Key, Tag, UserCircle2 } from "lucide-react";
import {
DropdownMenu,
DropdownMenuContent,
@@ -24,8 +15,8 @@ import { RESOURCE_TARGETS } from "@lib/utils";
import { Omnibar } from "./omnibar";
import { WsStatusIndicator } from "@lib/socket";
import { HeaderUpdates } from "./updates/header";
import { useEffect, useState } from "react";
import { Logout } from "./util";
import { ThemeToggle } from "@ui/theme";
export const Topbar = () => {
const type = useResourceParamType();
@@ -56,26 +47,6 @@ export const Topbar = () => {
);
};
const ThemeToggle = () => {
const [theme, set] = useState(localStorage.getItem("theme"));
useEffect(() => {
localStorage.setItem("theme", theme ?? "dark");
if (theme === "dark") document.body.classList.remove("dark");
else document.body.classList.add("dark");
}, [theme]);
return (
<Button
variant="ghost"
onClick={() => set(theme === "dark" ? "light" : "dark")}
>
<SunMedium className="w-4 h-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="w-4 h-4 absolute rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
</Button>
);
};
const ResourceTypeDropdown = () => {
const type = useResourceParamType();
const Components = ResourceComponents[type];

View File

@@ -25,11 +25,12 @@ export const Resource = () => {
}
subtitle={
<div className="text-sm text-muted-foreground flex flex-col gap-2">
<div className="flex gap-2">
<Components.Icon id={id} />
<Components.Description id={id} />
</div>
<div className="flex gap-8">
<div className="flex gap-4 items-center">
<div className="flex gap-2 items-center">
<Components.Icon id={id} />
<Components.Status id={id} />
</div>
|
<Components.Info id={id} />
</div>
</div>

View File

@@ -33,7 +33,19 @@ export const UsersPage = () => {
header: "Level",
accessorFn: (user) => (user.admin ? "Admin" : "User"),
},
{ header: "Enabled", accessorKey: "enabled" },
{
header: "Enabled",
cell: ({ row }) => {
const enabledClass = row.original.enabled
? "text-green-500"
: "text-red-500";
return (
<div className={enabledClass}>
{row.original.enabled ? "Enabled" : "Disabled"}
</div>
);
},
},
]}
onRowClick={(user) => nav(`/users/${user._id!.$oid}`)}
/>

View File

@@ -16,6 +16,7 @@ export interface RequiredResourceComponents {
Name: IdComponent;
Description: IdComponent;
Info: IdComponent;
Status: IdComponent;
Actions: IdComponent;
Table: React.FC;

View File

@@ -93,13 +93,22 @@ export function ThemeToggle() {
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme("light")}>
<DropdownMenuItem
className="cursor-pointer"
onClick={() => setTheme("light")}
>
Light
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("dark")}>
<DropdownMenuItem
className="cursor-pointer"
onClick={() => setTheme("dark")}
>
Dark
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("system")}>
<DropdownMenuItem
className="cursor-pointer"
onClick={() => setTheme("system")}
>
System
</DropdownMenuItem>
</DropdownMenuContent>