force scrollbar, add header updates etc

This commit is contained in:
karamvir
2023-09-09 13:22:13 -07:00
parent 8ae8c43c3c
commit 6d2287c4e5
6 changed files with 102 additions and 16 deletions

View File

@@ -25,12 +25,13 @@ import {
CardContent,
} from "@ui/card";
import { Logout, ResourceTypeDropdown, ResourcesDropdown } from "./util";
import { HeaderUpdates } from "./updates/header";
export const Layout = () => {
const type = useResourceParamType();
return (
<>
<div className="fixed top-0 border-b bg-background z-50 w-full">
<div className="sticky top-0 border-b bg-background z-50 w-full">
<div className="container flex items-center justify-between py-4 gap-8">
<Link to={"/"} className="text-2xl tracking-widest">
MONITOR
@@ -43,6 +44,7 @@ export const Layout = () => {
<div className="flex">
<Omnibar />
<WsStatusIndicator />
<HeaderUpdates />
<ThemeToggle />
<Logout />
</div>
@@ -62,7 +64,7 @@ interface PageProps {
}
export const Page = ({ title, subtitle, actions, children }: PageProps) => (
<div className="flex flex-col gap-12 container py-32">
<div className="flex flex-col gap-12 container py-16">
<div className="flex flex-col gap-6 lg:flex-row lg:gap-0 lg:items-start justify-between">
<div className="flex flex-col">
<h1 className="text-4xl">{title}</h1>

View File

@@ -17,6 +17,7 @@ import {
} from "./actions";
import { Input } from "@ui/input";
import { DeploymentLogs } from "./logs";
import { Link } from "react-router-dom";
export const useDeployment = (id?: string) =>
useRead("ListDeployments", {}, { refetchInterval: 5000 }).data?.find(
@@ -28,18 +29,26 @@ export const Deployment: RequiredResourceComponents = {
Description: ({ id }) => (
<>{useDeployment(id)?.info.status ?? "Not Deployed"}</>
),
Info: ({ id }) => (
<>
<div className="flex items-center gap-2">
<Server className="w-4 h-4" />
{useServer(useDeployment(id)?.info.server_id)?.name ?? "N/A"}
</div>
<div className="flex items-center gap-2">
<HardDrive className="w-4 h-4" />
{useDeployment(id)?.info.image ?? "N/A"}
</div>
</>
),
Info: ({ id }) => {
const info = useDeployment(id)?.info;
const server = useServer(info?.server_id);
return (
<>
<Link to={`/servers/${server?.id}`} className="flex items-center gap-2">
<Server className="w-4 h-4" />
{server?.name ?? "N/A"}
</Link>
<Link
to={info?.build_id ? `/builds/${info.build_id}` : "."}
className="flex items-center gap-2"
>
<HardDrive className="w-4 h-4" />
{useDeployment(id)?.info.image || "N/A"}
</Link>
</>
);
},
Icon: ({ id }) => {
const s = useDeployment(id)?.info.state;

View File

@@ -65,6 +65,7 @@ export const UpdateDetails = ({
</div>
<div className="flex gap-4">
<div className="flex items-center gap-2">
<Components.Icon id={update.target.id} />
<Components.Name id={update.target.id} />
</div>
{update.version && (

View File

@@ -0,0 +1,74 @@
import { useRead } from "@lib/hooks";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuTrigger,
} from "@ui/dropdown-menu";
import { Bell } from "lucide-react";
import { Button } from "@ui/button";
import { Calendar, User } from "lucide-react";
import { UpdateDetails, UpdateUser } from "./details";
import { UpdateListItem, UpdateStatus } from "@monitor/client/dist/types";
import { ResourceComponents } from "@components/resources";
const fmt_date = (d: Date) =>
`${d.getDate()}/${d.getMonth() + 1} @ ${d.getHours()}:${d.getMinutes()}`;
export const SingleUpdate = ({ update }: { update: UpdateListItem }) => {
const Components =
update.target.type !== "System"
? ResourceComponents[update.target.type]
: null;
return (
<UpdateDetails id={update.id}>
<div className="px-2 py-4 hover:bg-muted transition-colors border-b last:border-none cursor-pointer">
<div className="flex items-center justify-between">
<div className="text-sm w-full">
{update.operation.match(/[A-Z][a-z]+|[0-9]+/g)?.join(" ")}
<div className="text-muted-foreground text-xs">
{Components && <Components.Name id={update.target.id} />}
</div>
</div>
<div className="w-48 text-xs">
<div className="flex items-center gap-2">
<Calendar className="w-4 h-4" />
<div>
{update.status === UpdateStatus.InProgress
? "ongoing"
: fmt_date(new Date(update.start_ts))}
</div>
</div>
<div className="flex items-center gap-2">
<User className="w-4 h-4" />
<UpdateUser user_id={update.operator} />
</div>
</div>
</div>
</div>
</UpdateDetails>
);
};
export const HeaderUpdates = () => {
const updates = useRead("ListUpdates", {}).data;
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon">
<Bell className="w-4 h-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-[500px] h-[500px] overflow-auto">
<DropdownMenuGroup>
{updates?.updates.map((update) => (
<SingleUpdate update={update} key={update.id} />
))}
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
);
};

View File

@@ -10,7 +10,7 @@
}
body {
@apply bg-background text-foreground;
@apply bg-background text-foreground overflow-y-scroll;
font-family: Inter;
}
pre {

View File

@@ -119,7 +119,7 @@ export const WsStatusIndicator = () => {
toast({ title: "surprise", description: "motherfucker" });
return (
<Button variant="ghost" onClick={onclick}>
<Button variant="ghost" onClick={onclick} size="icon" className="ml-4">
<Circle
className={cn(
"w-4 h-4 stroke-none",