Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: skeleton for projects/docker/swarm #1034

Open
wants to merge 1 commit into
base: canary
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
} from "@/components/ui/table";
import { type RouterOutputs, api } from "@/utils/api";
import { columns } from "./colums";
import { Skeleton } from "@/components/ui/skeleton";
export type Container = NonNullable<
RouterOutputs["docker"]["getContainers"]
>[0];
Expand Down Expand Up @@ -70,6 +71,47 @@ export const ShowContainers = ({ serverId }: Props) => {
},
});

if (isLoading) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to separate the skeleton concept in another package ?

return (
<div className="mt-6 grid gap-4 pb-20 w-full">
<div className="flex flex-col gap-4 w-full overflow-auto">
<div className="flex items-center gap-2 max-sm:flex-wrap">
<Skeleton className="h-10 md:max-w-sm w-full" />
<Skeleton className="h-10 w-32 sm:ml-auto max-sm:w-full" />
</div>
<div className="rounded-md border">
<Table>
<TableHeader>
<TableRow>
<TableHead className="w-[40%]"><Skeleton className="h-4 w-32" /></TableHead>
<TableHead className="w-[20%]"><Skeleton className="h-4 w-20" /></TableHead>
<TableHead className="w-[20%]"><Skeleton className="h-4 w-24" /></TableHead>
<TableHead className="w-[20%]"><Skeleton className="h-4 w-20" /></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{Array.from({ length: 12 }).map((_, i) => (
<TableRow key={i} className="h-16">
<TableCell><Skeleton className="h-4 w-[90%]" /></TableCell>
<TableCell><Skeleton className="h-6 w-20 rounded-full" /></TableCell>
<TableCell><Skeleton className="h-4 w-32" /></TableCell>
<TableCell><Skeleton className="h-4 w-40" /></TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
<div className="flex items-center justify-end space-x-2 py-4">
<div className="space-x-2 flex flex-wrap">
<Skeleton className="h-9 w-20" />
<Skeleton className="h-9 w-20" />
</div>
</div>
</div>
</div>
)
}

return (
<div className="mt-6 grid gap-4 pb-20 w-full">
<div className="flex flex-col gap-4 w-full overflow-auto">
Expand Down Expand Up @@ -110,13 +152,7 @@ export const ShowContainers = ({ serverId }: Props) => {
</DropdownMenu>
</div>
<div className="rounded-md border">
{isLoading ? (
<div className="w-full flex-col gap-2 flex items-center justify-center h-[55vh]">
<span className="text-muted-foreground text-lg font-medium">
Loading...
</span>
</div>
) : data?.length === 0 ? (
{data?.length === 0 ? (
<div className="flex-col gap-2 flex items-center justify-center h-[55vh]">
<span className="text-muted-foreground text-lg font-medium">
No results.
Expand Down
37 changes: 35 additions & 2 deletions apps/dokploy/components/dashboard/projects/show.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ import { Fragment } from "react";
import { toast } from "sonner";
import { ProjectEnvironment } from "./project-environment";
import { UpdateProject } from "./update";
import { Skeleton } from "@/components/ui/skeleton";

export const ShowProjects = () => {
const utils = api.useUtils();
const { data } = api.project.all.useQuery();
const { data, isLoading } = api.project.all.useQuery();
const { data: auth } = api.auth.get.useQuery();
const { data: user } = api.user.byAuthId.useQuery(
{
Expand All @@ -51,6 +52,38 @@ export const ShowProjects = () => {
);
const { mutateAsync } = api.project.remove.useMutation();

if (isLoading) {
return (
<div className="mt-6 w-full grid sm:grid-cols-2 lg:grid-cols-3 flex-wrap gap-5 pb-10">
{Array.from({ length: 12 }).map((_, i) => (
<div key={i} className="w-full lg:max-w-md">
<Card className="group relative w-full bg-transparent">
<CardHeader>
<CardTitle className="flex items-center justify-between gap-2">
<span className="flex flex-col gap-1.5">
<div className="flex items-center gap-2">
<Skeleton className="size-4" />
<Skeleton className="h-5 w-32" />
</div>
<Skeleton className="h-4 w-48" />
</span>
<Skeleton className="size-8 rounded-md" />
</CardTitle>
</CardHeader>
<CardFooter className="pt-4">
<div className="space-y-1 text-sm flex flex-row justify-between w-full gap-4">
<Skeleton className="h-4 w-20" />
<Skeleton className="h-4 w-24" />
</div>
</CardFooter>
</Card>
</div>
))}
</div>
);

}

return (
<>
{data?.length === 0 && (
Expand All @@ -61,7 +94,7 @@ export const ShowProjects = () => {
</span>
</div>
)}
<div className="mt-6 w-full grid sm:grid-cols-2 lg:grid-cols-3 flex-wrap gap-5 pb-10">
<div className="mt-6 w-full grid sm:grid-cols-2 lg:grid-cols-3 flex-wrap gap-5 pb-10">
{data?.map((project) => {
const emptyServices =
project?.mariadb.length === 0 &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from "lucide-react";
import { ShowNodeApplications } from "../applications/show-applications";
import { ShowNodeConfig } from "./show-node-config";
import { Skeleton } from "@/components/ui/skeleton";

export interface SwarmList {
ID: string;
Expand All @@ -33,29 +34,6 @@ export function NodeCard({ node, serverId }: Props) {
serverId,
});


if (isLoading) {
return (
<Card className="w-full bg-background">
<CardHeader>
<CardTitle className="flex items-center justify-between text-lg">
<span className="flex items-center gap-2">
{node.Hostname}
</span>
<Badge variant="green">
{node.ManagerStatus || "Worker"}
</Badge>
</CardTitle>
</CardHeader>
<CardContent>
<div className="flex items-center justify-center">
<Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
</div>
</CardContent>
</Card>
);
}

return (
<Card className="w-full bg-background">
<CardHeader>
Expand Down Expand Up @@ -117,7 +95,7 @@ export function NodeCard({ node, serverId }: Props) {
</div>

<div className="flex justify-end w-full space-x-4">
<ShowNodeConfig nodeId={node.ID} serverId={serverId} />
<ShowNodeConfig nodeId={node.ID} serverId={serverId} />
<ShowNodeApplications serverId={serverId} />
</div>
</div>
Expand Down
67 changes: 62 additions & 5 deletions apps/dokploy/components/dashboard/swarm/monitoring-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {
Server,
} from "lucide-react";
import { NodeCard } from "./details/details-card";
import { Skeleton } from "@/components/ui/skeleton";
import { Separator } from "@/components/ui/separator";

interface Props {
serverId?: string;
Expand All @@ -28,13 +30,68 @@ export default function SwarmMonitorCard({ serverId }: Props) {

if (isLoading) {
return (
<div className="w-full max-w-7xl mx-auto">
<div className="mb-6 border min-h-[55vh] rounded-lg h-full">
<div className="flex items-center justify-center h-full text-muted-foreground">
<Loader2 className="h-6 w-6 animate-spin" />
</div>
<div className="min-h-screen">
<div className="w-full max-w-7xl mx-auto space-y-6 py-4">
<div className="space-y-4">
<Skeleton className="h-8 w-1/3" />
<Skeleton className="h-5 w-2/5" />
</div>

<div className="grid gap-6 md:grid-cols-3">
{Array.from({ length: 3 }).map((_, i) => (
<div key={i} className="p-4 border rounded-md">
<div className="flex flex-row items-center justify-between mb-4">
<Skeleton className="h-4 w-1/4" />
<Skeleton className="h-8 w-8 rounded-md" />
</div>
<Skeleton className="h-6 w-1/2" />
</div>
))}
</div>

<Card className="w-full bg-background">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indendation inconsistency here :/

Maybe you should fix it ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Piggy-backing off this comment, I'd happy to create a PR with Prettier with current conventions + Tailwind plugin to sort Tailwind classes to avoid mistakes like this. Ping me and I'll set some time for that.

<CardHeader>
<CardTitle className="text-lg">
<Skeleton className="h-6 w-32" />
</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-6">
<div className="flex flex-wrap items-center justify-between">
<div className="flex items-center space-x-4 p-2 rounded-xl border">
<Skeleton className="h-2.5 w-2.5 rounded-full" />
<Skeleton className="h-5 w-32" />
<Skeleton className="h-6 w-20 rounded-full" />
</div>
<div className="flex flex-wrap items-center space-x-4">
<Skeleton className="h-6 w-28 rounded-full" />
<Skeleton className="h-6 w-32 rounded-full" />
</div>
</div>

<Separator />

<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
{Array.from({ length: 4 }).map((_, i) => (
<div key={i} className="space-y-2 flex flex-col items-center text-center">
<div className="flex items-center text-sm">
<Skeleton className="mr-2 h-4 w-4" />
<Skeleton className="h-4 w-24" />
</div>
<Skeleton className="h-4 w-16" />
</div>
))}
</div>

<div className="flex justify-end w-full space-x-4">
<Skeleton className="h-10 w-32" />
<Skeleton className="h-10 w-32" />
</div>
</div>
</CardContent>
</Card>
</div>
</div>
);
}

Expand Down
15 changes: 15 additions & 0 deletions apps/dokploy/components/ui/skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { cn } from "@/lib/utils"

function Skeleton({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) {
return (
<div
className={cn("animate-pulse rounded-md bg-muted", className)}
{...props}
/>
)
}

export { Skeleton }
Loading