mirror of
https://github.com/andwati/dokploy.git
synced 2026-11-11 14:35:17 +00:00
Feat/add sidebar (#1084)
* refactor: add sidebar * chore: add deps * refactor: update sidebar * refactor: another layout * refactor: update variant * refactor: change layout * refactor: change variant * refactor: enhance sidebar navigation with active state management * feat: add project button to dashboard * Merge branch 'canary' into feat/add-sidebar * refactor: add loader * refactor: update destinations and refactor * refactor: ui refactor certificates * refactor: delete unused files * refactor: remove unused files and duplicate registry * refactor: update style registry * refactor: add new design registry * refactor: enhance git providers * refactor: remove duplicate files * refactor: update * refactor: update users * refactor: delete unused files * refactor: update profile * refactor: apply changes * refactor: update UI * refactor: enhance Docker monitoring UI layout * refactor: add theme toggle and language selection to user navigation (#1083) * refactor: remove unused files * feat: add filter to services * refactor: add active items * refactor: remove tab prop * refactor: remove unused files * refactor: remove duplicated files * refactor: remove unused files * refactor: remove duplicate files * refactor: remove unused files * refactor: delete unused files * refactor: remove unsued files * refactor: delete unused files * refactor: lint * refactor: remove unused secuirty * refactor: delete unused files * refactor: delete unused files * remove imports * refactor: add update button * refactor: delete unused files * refactor: remove unused code * refactor: remove unused files * refactor: update login page * refactor: update login UI * refactor: update ui reset password * refactor: add justify end * feat: add suscriptions * feat: add sheet * feat: add logs for postgres * feat: add logs for all databases * feat: add server logs with drawer logs * refactor: remove unused files * refactor: add refetch when closing * refactor: fix linter * chore: bump node-20 * revert * refactor: fix conflicts * refactor: update * refactor: add missing deps * refactor: delete duplicate files * refactor: delete unsued files * chore: lint * refactor: remove unsued file * refactor: add refetch * refactor: remove duplicated files * refactor: delete unused files * refactor: update setup onboarding * refactor: add breadcrumb * refactor: apply updates * refactor: add faker * refactor: use 0 in validation * refactor: show correct state * refactor: update --------- Co-authored-by: vishalkadam47 <[email protected]> Co-authored-by: Vishal kadam <[email protected]>
This commit is contained in:
co-authored by
vishalkadam47
Vishal kadam
parent
87f4c7b71b
commit
a104867ed2
@@ -9,10 +9,18 @@ import {
|
||||
getSortedRowModel,
|
||||
useReactTable,
|
||||
} from "@tanstack/react-table";
|
||||
import { ChevronDown } from "lucide-react";
|
||||
import { ChevronDown, Container } from "lucide-react";
|
||||
import * as React from "react";
|
||||
|
||||
import { AlertBlock } from "@/components/shared/alert-block";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuCheckboxItem,
|
||||
@@ -71,139 +79,164 @@ export const ShowContainers = ({ serverId }: Props) => {
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="mt-6 grid gap-4 pb-20 w-full">
|
||||
<div className="flex flex-col gap-4 w-full">
|
||||
<div className="flex items-center gap-2 max-sm:flex-wrap">
|
||||
<Input
|
||||
placeholder="Filter by name..."
|
||||
value={(table.getColumn("name")?.getFilterValue() as string) ?? ""}
|
||||
onChange={(event) =>
|
||||
table.getColumn("name")?.setFilterValue(event.target.value)
|
||||
}
|
||||
className="md:max-w-sm"
|
||||
/>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline" className="sm:ml-auto max-sm:w-full">
|
||||
Columns <ChevronDown className="ml-2 h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
{table
|
||||
.getAllColumns()
|
||||
.filter((column) => column.getCanHide())
|
||||
.map((column) => {
|
||||
return (
|
||||
<DropdownMenuCheckboxItem
|
||||
key={column.id}
|
||||
className="capitalize"
|
||||
checked={column.getIsVisible()}
|
||||
onCheckedChange={(value) =>
|
||||
column.toggleVisibility(!!value)
|
||||
}
|
||||
>
|
||||
{column.id}
|
||||
</DropdownMenuCheckboxItem>
|
||||
);
|
||||
})}
|
||||
</DropdownMenuContent>
|
||||
</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 ? (
|
||||
<div className="flex-col gap-2 flex items-center justify-center h-[55vh]">
|
||||
<span className="text-muted-foreground text-lg font-medium">
|
||||
No results.
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<Table>
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<TableHead key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext(),
|
||||
<div className="w-full">
|
||||
<Card className="h-full bg-sidebar p-2.5 rounded-xl max-w-8xl mx-auto">
|
||||
<div className="rounded-xl bg-background shadow-md ">
|
||||
<CardHeader className="">
|
||||
<CardTitle className="text-xl flex flex-row gap-2">
|
||||
<Container className="size-6 text-muted-foreground self-center" />
|
||||
Docker Containers
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
See all the containers of your dokploy server
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-2 py-8 border-t">
|
||||
<div className="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">
|
||||
<Input
|
||||
placeholder="Filter by name..."
|
||||
value={
|
||||
(table.getColumn("name")?.getFilterValue() as string) ??
|
||||
""
|
||||
}
|
||||
onChange={(event) =>
|
||||
table
|
||||
.getColumn("name")
|
||||
?.setFilterValue(event.target.value)
|
||||
}
|
||||
className="md:max-w-sm"
|
||||
/>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="sm:ml-auto max-sm:w-full"
|
||||
>
|
||||
Columns <ChevronDown className="ml-2 h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
{table
|
||||
.getAllColumns()
|
||||
.filter((column) => column.getCanHide())
|
||||
.map((column) => {
|
||||
return (
|
||||
<DropdownMenuCheckboxItem
|
||||
key={column.id}
|
||||
className="capitalize"
|
||||
checked={column.getIsVisible()}
|
||||
onCheckedChange={(value) =>
|
||||
column.toggleVisibility(!!value)
|
||||
}
|
||||
>
|
||||
{column.id}
|
||||
</DropdownMenuCheckboxItem>
|
||||
);
|
||||
})}
|
||||
</DropdownMenuContent>
|
||||
</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 ? (
|
||||
<div className="flex-col gap-2 flex items-center justify-center h-[55vh]">
|
||||
<span className="text-muted-foreground text-lg font-medium">
|
||||
No results.
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<Table>
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<TableHead key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext(),
|
||||
)}
|
||||
</TableHead>
|
||||
);
|
||||
})}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{table?.getRowModel()?.rows?.length ? (
|
||||
table.getRowModel().rows.map((row) => (
|
||||
<TableRow
|
||||
key={row.id}
|
||||
data-state={row.getIsSelected() && "selected"}
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell key={cell.id}>
|
||||
{flexRender(
|
||||
cell.column.columnDef.cell,
|
||||
cell.getContext(),
|
||||
)}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
))
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={columns.length}
|
||||
className="h-24 text-center"
|
||||
>
|
||||
{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>
|
||||
) : (
|
||||
<>No results.</>
|
||||
)}
|
||||
</TableHead>
|
||||
);
|
||||
})}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{table?.getRowModel()?.rows?.length ? (
|
||||
table.getRowModel().rows.map((row) => (
|
||||
<TableRow
|
||||
key={row.id}
|
||||
data-state={row.getIsSelected() && "selected"}
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell key={cell.id}>
|
||||
{flexRender(
|
||||
cell.column.columnDef.cell,
|
||||
cell.getContext(),
|
||||
)}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
))
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={columns.length}
|
||||
className="h-24 text-center"
|
||||
>
|
||||
{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>
|
||||
) : (
|
||||
<>No results.</>
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
)}
|
||||
</div>
|
||||
{data && data?.length > 0 && (
|
||||
<div className="flex items-center justify-end space-x-2 py-4">
|
||||
<div className="space-x-2 flex flex-wrap">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => table.previousPage()}
|
||||
disabled={!table.getCanPreviousPage()}
|
||||
>
|
||||
Previous
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => table.nextPage()}
|
||||
disabled={!table.getCanNextPage()}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
)}
|
||||
</div>
|
||||
{data && data?.length > 0 && (
|
||||
<div className="flex items-center justify-end space-x-2 py-4">
|
||||
<div className="space-x-2 flex flex-wrap">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => table.previousPage()}
|
||||
disabled={!table.getCanPreviousPage()}
|
||||
>
|
||||
Previous
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => table.nextPage()}
|
||||
disabled={!table.getCanNextPage()}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user