diff --git a/apps/hub/src/domains/project/components/servers/server-logs-tab.tsx b/apps/hub/src/domains/project/components/servers/server-logs-tab.tsx index 92773167..e48286e0 100644 --- a/apps/hub/src/domains/project/components/servers/server-logs-tab.tsx +++ b/apps/hub/src/domains/project/components/servers/server-logs-tab.tsx @@ -2,6 +2,7 @@ import type { Rivet } from "@rivet-gg/api"; import { Button, LogsView, WithTooltip } from "@rivet-gg/components"; import { Icon, faSave } from "@rivet-gg/icons"; import { useSuspenseQuery } from "@tanstack/react-query"; +import { differenceInHours } from "date-fns"; import { saveAs } from "file-saver"; import { serverLogsQueryOptions } from "../../queries"; @@ -10,6 +11,7 @@ interface ServerLogsTabProps { environmentId: string; serverId: string; logType: Rivet.servers.LogStream; + createdAt: number; } export function ServerLogsTab({ @@ -17,6 +19,7 @@ export function ServerLogsTab({ environmentId, serverId, logType, + createdAt, }: ServerLogsTabProps) { const { data: { timestamps, lines }, @@ -29,32 +32,38 @@ export function ServerLogsTab({ }), ); + const areLogsRetained = differenceInHours(Date.now(), createdAt) < 24 * 3; + return ( - saveAs( - new Blob([lines.join("\n")], { - type: "text/plain;charset=utf-8", - }), - "logs.txt", - ) - } - > - - - } - /> + lines.length > 0 ? ( + + saveAs( + new Blob([lines.join("\n")], { + type: "text/plain;charset=utf-8", + }), + "logs.txt", + ) + } + > + + + } + /> + ) : null } /> ); diff --git a/apps/hub/src/domains/project/components/servers/server-status.tsx b/apps/hub/src/domains/project/components/servers/server-status.tsx index e43693d0..bf5f7612 100644 --- a/apps/hub/src/domains/project/components/servers/server-status.tsx +++ b/apps/hub/src/domains/project/components/servers/server-status.tsx @@ -1,12 +1,15 @@ import type { Rivet } from "@rivet-gg/api"; +import { cn } from "@rivet-gg/components"; import { ServerStatusIndicator } from "./server-status-indicator"; import { ServerStatusLabel } from "./server-status-label"; -interface ServerStatusProps extends Rivet.servers.Server {} +interface ServerStatusProps extends Rivet.servers.Server { + className?: string; +} -export const ServerStatus = (props: ServerStatusProps) => { +export const ServerStatus = ({ className, ...props }: ServerStatusProps) => { return ( -
+
diff --git a/apps/hub/src/domains/project/components/servers/server-tags.tsx b/apps/hub/src/domains/project/components/servers/server-tags.tsx index 030c848b..011ccb50 100644 --- a/apps/hub/src/domains/project/components/servers/server-tags.tsx +++ b/apps/hub/src/domains/project/components/servers/server-tags.tsx @@ -1,35 +1,74 @@ -import { Badge, cn } from "@rivet-gg/components"; +import { + CopyButton, + Slot, + Slottable, + WithTooltip, + cn, +} from "@rivet-gg/components"; +import { Icon, faTag } from "@rivet-gg/icons"; +import { type ReactNode, forwardRef } from "react"; const BUILT_IN_TAGS = ["current", "rivet/latest", "enabled", "rivet/enabled"]; +const Tag = forwardRef< + HTMLSpanElement, + { children: ReactNode; className?: string } +>(({ children, className, ...props }, ref) => ( + + + {children} + +)); + interface ServerTagsProps { tags?: unknown; excludeBuiltIn?: boolean; className?: string; + truncate?: boolean; } export function ServerTags({ tags = {}, excludeBuiltIn = false, + truncate = true, className, }: ServerTagsProps) { return ( -
+
{tags && typeof tags === "object" ? Object.entries(tags) .filter(([key]) => excludeBuiltIn ? !BUILT_IN_TAGS.includes(key) : true, ) .sort(([a], [b]) => a.localeCompare(b)) - .map(([key, value]) => ( - - {key}={value} - - )) + .map(([key, value]) => + truncate ? ( + + + + + + } + /> + ) : ( + + + {key}={value} + + + ), + ) : null}
); diff --git a/apps/hub/src/domains/project/components/servers/servers-list-panel.tsx b/apps/hub/src/domains/project/components/servers/servers-list-panel.tsx index b9a45bb8..f11d1db6 100644 --- a/apps/hub/src/domains/project/components/servers/servers-list-panel.tsx +++ b/apps/hub/src/domains/project/components/servers/servers-list-panel.tsx @@ -1,6 +1,5 @@ import type { Rivet } from "@rivet-gg/api"; import { - Badge, Button, RelativeTime, ScrollArea, @@ -99,20 +98,21 @@ function ServerRow({
- + - + {server.id.split("-")[0]}
@@ -120,7 +120,11 @@ function ServerRow({ content={ <>

Tags

- + } /> diff --git a/apps/hub/src/domains/project/components/servers/servers-list-preview.tsx b/apps/hub/src/domains/project/components/servers/servers-list-preview.tsx index 55e31998..166d11d8 100644 --- a/apps/hub/src/domains/project/components/servers/servers-list-preview.tsx +++ b/apps/hub/src/domains/project/components/servers/servers-list-preview.tsx @@ -27,7 +27,7 @@ export function ServersListPreview({ autoSaveId="rivet-project-backend-logs" direction={isMd ? "horizontal" : "vertical"} > - +
- +
}> - - Please select a server from the list on the left. - + Please select a server from the list. ); } diff --git a/apps/hub/src/domains/project/components/servers/servers-server-details.tsx b/apps/hub/src/domains/project/components/servers/servers-server-details.tsx index f126adfa..9e3f02eb 100644 --- a/apps/hub/src/domains/project/components/servers/servers-server-details.tsx +++ b/apps/hub/src/domains/project/components/servers/servers-server-details.tsx @@ -1,9 +1,10 @@ import { Button, - CopyButton, + ClickToCopy, Flex, LogsView, Skeleton, + SmallText, Tabs, TabsContent, TabsList, @@ -12,8 +13,10 @@ import { } from "@rivet-gg/components"; import { ErrorBoundary } from "@sentry/react"; import { useSuspenseQuery } from "@tanstack/react-query"; +import { formatISO } from "date-fns"; import { Suspense } from "react"; import { serverQueryOptions, useDestroyServerMutation } from "../../queries"; +import { ServerDatacenter } from "./server-datacenter"; import { ServerLogsTab } from "./server-logs-tab"; import { ServerNetworkTab } from "./server-network-tab"; import { ServerRuntimeTab } from "./server-runtime-tab"; @@ -57,27 +60,76 @@ export function ServersServerDetails({ } > - - - - - - - + + + + {!data.destroyTs ? ( ) : null} - - - +
+ + + +
+
+
+

Region

+ + + +
+ + + + + + + + + + +
}> }> ( }, ); -interface CopyButtonProps { +interface CopyButtonProps extends ComponentProps { children: ReactNode; value: string; } -export function CopyButton({ children, value }: CopyButtonProps) { +export const CopyButton = forwardRef( + ({ children, value, ...props }, ref) => { + const handleClick: MouseEventHandler = (event) => { + navigator.clipboard.writeText(value); + toast.success("Copied to clipboard"); + props.onClick?.(event); + }; + return ( + + {children} + + ); + }, +); + +interface ClickToCopyProps { + children: ReactNode; + value: string; +} + +export function ClickToCopy({ children, value }: ClickToCopyProps) { const handleClick = () => { navigator.clipboard.writeText(value); toast.success("Copied to clipboard"); }; - return {children}; + return ( + {children}} + /> + ); } diff --git a/packages/components/src/ui/button.tsx b/packages/components/src/ui/button.tsx index a1c778e6..4297ce94 100644 --- a/packages/components/src/ui/button.tsx +++ b/packages/components/src/ui/button.tsx @@ -12,7 +12,7 @@ import { } from "./helpers"; const buttonVariants = cva( - "group group/button inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:z-10 relative aria-disabled:pointer-events-none aria-disabled:opacity-50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:size-4", + "group group/button inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:z-10 relative aria-disabled:pointer-events-none aria-disabled:opacity-50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:size-[1em]", { variants: { variant: { diff --git a/packages/components/src/ui/typography.tsx b/packages/components/src/ui/typography.tsx index c18b4be2..87c2b678 100644 --- a/packages/components/src/ui/typography.tsx +++ b/packages/components/src/ui/typography.tsx @@ -196,8 +196,8 @@ const SmallText = forwardRef>(