Skip to content

Commit

Permalink
Extracting table components
Browse files Browse the repository at this point in the history
  • Loading branch information
selfcontained committed Nov 13, 2023
1 parent 363c3d4 commit b368820
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 27 deletions.
68 changes: 68 additions & 0 deletions components/dashboard/src/components/podkit/tables/Table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* Copyright (c) 2023 Gitpod GmbH. All rights reserved.
* Licensed under the GNU Affero General Public License (AGPL).
* See License.AGPL.txt in the project root for license information.
*/

import { cn } from "@podkit/lib/cn";
import React from "react";

type HideableCellProps = {
hideOnSmallScreen?: boolean;
};

export const Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(
({ className, ...props }, ref) => {
return (
<div className="relative w-full overflow-auto">
<table ref={ref} className={cn("w-full text-sm text-left", className)} {...props} />
</div>
);
},
);
Table.displayName = "Table";

export const TableHeader = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
({ className, ...props }, ref) => {
return (
<thead
ref={ref}
className="[&_th]:p-3 [&_th]:bg-gray-100 dark:[&_th]:bg-gray-800 [&_th:first-child]:rounded-tl-md [&_th:last-child]:rounded-tr-md text-semibold"
{...props}
/>
);
},
);
TableHeader.displayName = "TableHeader";

export const TableRow = React.forwardRef<HTMLTableRowElement, React.HTMLAttributes<HTMLTableRowElement>>(
({ className, ...props }, ref) => {
return <tr ref={ref} className="border-b dark:border-gray-700" {...props} />;
},
);
TableRow.displayName = "TableRow";

export const TableHead = React.forwardRef<
HTMLTableCellElement,
React.ThHTMLAttributes<HTMLTableCellElement> & HideableCellProps
>(({ hideOnSmallScreen, className, ...props }, ref) => {
return <th ref={ref} className={cn(hideOnSmallScreen && "hidden md:table-cell", className)} {...props} />;
});
TableHead.displayName = "TableHead";

export const TableBody = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
({ className, ...props }, ref) => {
return (
<tbody ref={ref} className="[&_td]:p-3 [&_td:last-child]:text-right [&_tr]:hover:bg-muted/5" {...props} />
);
},
);
TableBody.displayName = "TableBody";

export const TableCell = React.forwardRef<
HTMLTableCellElement,
React.TdHTMLAttributes<HTMLTableCellElement> & HideableCellProps
>(({ hideOnSmallScreen, className, ...props }, ref) => {
return <td ref={ref} className={cn(hideOnSmallScreen && "hidden md:table-cell", className)} {...props} />;
});
TableCell.displayName = "TableCell";
26 changes: 14 additions & 12 deletions components/dashboard/src/repositories/list/RepoListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Configuration } from "@gitpod/public-api/lib/gitpod/v1/configuration_pb
import { LinkButton } from "@podkit/buttons/LinkButton";
import { cn } from "@podkit/lib/cn";
import { AlertTriangleIcon, CheckCircle2Icon } from "lucide-react";
import { TableCell, TableRow } from "@podkit/tables/Table";

type Props = {
configuration: Configuration;
Expand All @@ -25,39 +26,40 @@ export const RepositoryListItem: FC<Props> = ({ configuration }) => {
.toLocaleDateString("en-US", { year: "numeric", month: "short", day: "numeric" }) ?? "";

return (
<tr className="border-b transition-colors hover:bg-muted/50">
<td>
<TableRow>
<TableCell>
<div className="flex flex-col gap-1">
<Text className="font-semibold">{configuration.name}</Text>
{/* We show the url on a 2nd line for smaller screens since we hide the column */}
<TextMuted className="inline md:hidden text-sm">{url}</TextMuted>
</div>
</td>
</TableCell>

<td className="hidden md:table-cell">
<TableCell hideOnSmallScreen>
<TextMuted className="text-sm">{url}</TextMuted>
</td>
</TableCell>

<td className="hidden md:table-cell">{created}</td>
<TableCell hideOnSmallScreen>{created}</TableCell>

<td className="hidden md:table-cell">
<TableCell hideOnSmallScreen>
<div className="flex flex-row gap-1 items-center">
{prebuildsEnabled ? (
<CheckCircle2Icon size={20} className="text-green-500" />
) : (
<AlertTriangleIcon size={20} className="text-red-500" />
)}

<TextMuted className={cn(!prebuildsEnabled && "text-red-500")}>
<TextMuted className={cn(!prebuildsEnabled && "text-red-500 dark:text-red-500")}>
{prebuildsEnabled ? "Enabled" : "Disabled"}
</TextMuted>
</div>
</td>
</TableCell>

<td>
<TableCell>
<LinkButton href={`/repositories/${configuration.id}`} variant="secondary">
View
</LinkButton>
</td>
</tr>
</TableCell>
</TableRow>
);
};
39 changes: 24 additions & 15 deletions components/dashboard/src/repositories/list/RepositoryList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { PageHeading } from "@podkit/layout/PageHeading";
import { Button } from "@podkit/buttons/Button";
import { useDocumentTitle } from "../../hooks/use-document-title";
import { PaginationControls, PaginationCountText } from "./PaginationControls";
import { Table, TableBody, TableHead, TableHeader, TableRow } from "@podkit/tables/Table";

const RepositoryListPage: FC = () => {
useDocumentTitle("Imported repositories");
Expand Down Expand Up @@ -97,30 +98,38 @@ const RepositoryListPage: FC = () => {
</div>

<div className="relative w-full overflow-auto mt-2">
<table className="w-full text-left text-sm">
<Table>
{/* TODO: Add sorting controls */}
<thead className="[&_th]:p-3 [&_th]:bg-gray-100 [&_th:first-child]:rounded-tl-md [&_th:last-child]:rounded-tr-md text-semibold">
<tr className="border-b">
<th className="w-48">Name</th>
<th className="hidden md:table-cell">Repository</th>
<th className="hidden md:table-cell w-32">Created</th>
<th className="hidden md:table-cell w-24">Prebuilds</th>
<TableHeader>
<TableRow>
<TableHead className="w-52">Name</TableHead>
<TableHead hideOnSmallScreen>Repository</TableHead>
<TableHead className="w-32" hideOnSmallScreen>
Created
</TableHead>
<TableHead className="w-24" hideOnSmallScreen>
Prebuilds
</TableHead>
{/* Action column, loading status in header */}
<th className="w-24 text-right">
<TableHead className="w-24 text-right">
{isFetching && isPreviousData && (
<div className="flex flex-right justify-end items-center">
<LoaderIcon className="animate-spin text-gray-500" size={20} />
{/* TODO: Make a LoadingIcon component */}
<LoaderIcon
className="animate-spin text-gray-500 dark:text-gray-300"
size={20}
/>
</div>
)}
</th>
</tr>
</thead>
<tbody className="[&_td]:p-3 [&_td:last-child]:text-right">
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{data?.configurations.map((configuration) => (
<RepositoryListItem key={configuration.id} configuration={configuration} />
))}
</tbody>
</table>
</TableBody>
</Table>

{totalPages > 1 && (
<PaginationControls
Expand Down

0 comments on commit b368820

Please sign in to comment.