Skip to content

Repo List - Style updates #19157

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

Merged
merged 11 commits into from
Dec 1, 2023
2 changes: 1 addition & 1 deletion components/dashboard/src/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
className={classNames(
"cursor-pointer my-auto",
"text-sm font-medium whitespace-nowrap",
"rounded-xl focus:outline-none focus:ring transition ease-in-out",
"rounded-lg focus:outline-none focus:ring transition ease-in-out",
spacing === "compact" ? ["px-1 py-1"] : null,
spacing === "default" ? ["px-4 py-2"] : null,
type === "primary"
Expand Down
15 changes: 3 additions & 12 deletions components/dashboard/src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ import { useLocation } from "react-router";
import { useDocumentTitle } from "../hooks/use-document-title";
import { Separator } from "./Separator";
import TabMenuItem from "./TabMenuItem";
import { Heading1, Subheading } from "@podkit/typography/Headings";
import { PageHeading } from "@podkit/layout/PageHeading";

export interface HeaderProps {
title: string;
complexTitle?: React.ReactElement;
subtitle: string | React.ReactElement;
tabs?: TabEntry[];
}
Expand All @@ -28,16 +27,8 @@ export default function Header(p: HeaderProps) {
useDocumentTitle(`${p.title}`);
return (
<div className="app-container border-gray-200 dark:border-gray-800">
<div className="flex pb-8 pt-6">
<div className="w-full">
{p.complexTitle ? p.complexTitle : <Heading1 tracking="tight">{p.title}</Heading1>}
{typeof p.subtitle === "string" ? (
<Subheading tracking="wide">{p.subtitle}</Subheading>
) : (
p.subtitle
)}
</div>
</div>
<PageHeading title={p.title} subtitle={p.subtitle} />

<nav className="flex">
{p.tabs?.map((entry) => (
<TabMenuItem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export const SelectInput: FunctionComponent<SelectInputProps> = memo(
return (
<select
id={id}
className={classNames("w-full max-w-lg", className)}
className={classNames("w-full max-w-lg text-sm", className)}
value={value}
disabled={disabled}
required={required}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ export const TextInput: FunctionComponent<TextInputProps> = memo(
return (
<input
id={id}
className={cn("w-full max-w-lg dark:text-[#A8A29E]", className)}
// 7px top/bottom padding ensures height matches buttons (36px)
className={cn("py-[7px] w-full max-w-lg rounded-lg dark:text-[#A8A29E]", "text-sm", className)}
value={value}
type={type}
placeholder={placeholder}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { cva, VariantProps } from "class-variance-authority";
import { cn } from "@podkit/lib/cn";

export const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-xl text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
"inline-flex items-center justify-center whitespace-nowrap rounded-lg text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,16 @@ import { Heading1, Subheading } from "@podkit/typography/Headings";
import { FC, ReactNode } from "react";

type PageHeadingProps = {
title: string;
subtitle?: string;
action?: ReactNode;
title: ReactNode;
subtitle?: ReactNode;
};
export const PageHeading: FC<PageHeadingProps> = ({ title, subtitle, action }) => {
export const PageHeading: FC<PageHeadingProps> = ({ title, subtitle }) => {
return (
<div className="flex flex-row flex-wrap justify-between py-8 gap-2">
<div>
<Heading1>{title}</Heading1>
{subtitle && <Subheading>{subtitle}</Subheading>}
</div>
{action && action}
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import { Delayed } from "./Delayed";
import { FC } from "react";

type Props = {
size?: number;
delay?: boolean;
};
export const LoadingState: FC<Props> = ({ delay = true }) => {
const loader = <Loader2 className="animate-spin" />;
export const LoadingState: FC<Props> = ({ delay = true, size = 24 }) => {
const loader = <Loader2 className="animate-spin" size={size} />;

if (!delay) {
return loader;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,15 @@ export const SortableTableHead = React.forwardRef<
{...props}
aria-sort={sortOrder === "asc" ? "ascending" : sortOrder === "desc" ? "descending" : "none"}
>
<Button variant="ghost" onClick={handleClick} className="flex flex-row items-center gap-1">
<Button
variant="ghost"
onClick={handleClick}
className="flex flex-row items-center gap-1 font-semibold p-0 -h-9"
>
{children}
{/* keep element in dom to preserve space */}
<span className={cn(!sortOrder && "invisible")}>
{sortOrder === "asc" ? <ChevronUpIcon size={20} /> : <ChevronDownIcon size={20} />}
{sortOrder === "asc" ? <ChevronUpIcon size={16} /> : <ChevronDownIcon size={16} />}
</span>
</Button>
</TableHead>
Expand Down
8 changes: 6 additions & 2 deletions components/dashboard/src/components/podkit/tables/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const TableHeader = React.forwardRef<HTMLTableSectionElement, React.HTMLA
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"
className="[&_th]:py-2 [&_th]:px-4 [&_th]:bg-gray-100 [&_th]:font-semibold dark:[&_th]:bg-gray-800 [&_th:first-child]:rounded-tl-md [&_th:last-child]:rounded-tr-md"
Copy link
Member

Choose a reason for hiding this comment

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

Could you please explain what this [&_th] syntax does?

On the Tailwind playground, [&_th]:py-2 translates to the following, but it did not help too much 😄.

.\[\&_th\]\:py-2 th{
  padding-top: 0.5rem;
  padding-bottom: 0.5rem
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It applies the padding to any descendant <th> of the <thead> component.

{...props}
/>
);
Expand All @@ -53,7 +53,11 @@ 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} />
<tbody
ref={ref}
className="[&_td]:py-3 [&_td]:px-4 [&_td:last-child]:text-right [&_tr]:hover:bg-muted/5"
{...props}
/>
);
},
);
Expand Down
4 changes: 2 additions & 2 deletions components/dashboard/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
input[type="email"],
input[type="url"],
select {
@apply block w-56 text-gray-600 dark:text-gray-400 dark:bg-gray-800 bg-white rounded-md border border-gray-300 dark:border-gray-500 focus:border-gray-400 dark:focus:border-gray-400 focus:ring-0;
@apply block w-56 text-gray-600 dark:text-gray-400 dark:bg-gray-800 bg-white rounded-lg border border-gray-300 dark:border-gray-500 focus:border-gray-400 dark:focus:border-gray-400 focus:ring-0;
}
textarea::placeholder,
input[type="text"]::placeholder,
Expand Down Expand Up @@ -102,7 +102,7 @@

/* Search */
input[type="search"] {
@apply border-0 dark:bg-gray-800 bg-gray-50 text-gray-600 dark:text-gray-400 rounded-md focus:border-gray-400 dark:focus:border-gray-400 focus:outline-none focus:ring ring-0 focus:ring-blue-400 dark:focus:ring-blue-500 transition ease-in-out;
@apply border-0 dark:bg-gray-800 bg-gray-50 text-gray-600 dark:text-gray-400 rounded-lg focus:border-gray-400 dark:focus:border-gray-400 focus:outline-none focus:ring ring-0 focus:ring-blue-400 dark:focus:ring-blue-500 transition ease-in-out;
}
input[type="checkbox"] {
@apply disabled:opacity-50;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const ConfigurationDetailPage: FC = () => {
let { path, url } = useRouteMatch();

const { data, error, isLoading, refetch } = useConfiguration(id);
const prebuildsEnabled = !!data?.prebuildSettings?.enabled;

const settingsMenu = useMemo(() => {
const menu: SubmenuItemProps[] = [
Expand All @@ -36,7 +37,7 @@ const ConfigurationDetailPage: FC = () => {
{
title: "Prebuilds",
link: [`${url}/prebuilds`],
icon: <AlertTriangle size={20} />,
icon: !prebuildsEnabled ? <AlertTriangle size={20} /> : undefined,
},
{
title: "Environment variables",
Expand All @@ -48,7 +49,7 @@ const ConfigurationDetailPage: FC = () => {
},
];
return menu;
}, [url]);
}, [prebuildsEnabled, url]);

return (
<div className="w-full">
Expand Down
11 changes: 4 additions & 7 deletions components/dashboard/src/repositories/list/RepoListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { TextMuted } from "@podkit/typography/TextMuted";
import { Text } from "@podkit/typography/Text";
import { LinkButton } from "@podkit/buttons/LinkButton";
import type { Configuration } from "@gitpod/public-api/lib/gitpod/v1/configuration_pb";
import { cn } from "@podkit/lib/cn";
import { AlertTriangleIcon, CheckCircle2Icon } from "lucide-react";
import { TableCell, TableRow } from "@podkit/tables/Table";

Expand All @@ -31,12 +30,12 @@ export const RepositoryListItem: FC<Props> = ({ configuration }) => {
<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>
<TextMuted className="inline md:hidden text-sm break-all">{url}</TextMuted>
</div>
</TableCell>

<TableCell hideOnSmallScreen>
<TextMuted className="text-sm">{url}</TextMuted>
<TextMuted className="text-sm break-all">{url}</TextMuted>
</TableCell>

<TableCell hideOnSmallScreen>{created}</TableCell>
Expand All @@ -46,12 +45,10 @@ export const RepositoryListItem: FC<Props> = ({ configuration }) => {
{prebuildsEnabled ? (
<CheckCircle2Icon size={20} className="text-green-500" />
) : (
<AlertTriangleIcon size={20} className="text-red-500" />
<AlertTriangleIcon size={20} className="text-kumquat-base" />
Copy link
Member

Choose a reason for hiding this comment

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

Love that we're making this less scary, no prebuild shaming!

)}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { FC, useCallback, useEffect, useMemo, useState } from "react";
import { useHistory } from "react-router-dom";
import { useListConfigurations } from "../../data/configurations/configuration-queries";
import { PageHeading } from "@podkit/layout/PageHeading";
import { Button } from "@podkit/buttons/Button";
import { useDocumentTitle } from "../../hooks/use-document-title";
import { ImportRepositoryModal } from "../create/ImportRepositoryModal";
import type { Configuration } from "@gitpod/public-api/lib/gitpod/v1/configuration_pb";
Expand Down Expand Up @@ -88,9 +87,6 @@ const RepositoryListPage: FC = () => {
<PageHeading
title="Imported repositories"
subtitle="Configure and refine the experience of working with a repository in Gitpod"
action={
showTable && <Button onClick={() => setShowCreateProjectModal(true)}>Import Repository</Button>
}
/>

{isLoading && <LoadingState />}
Expand All @@ -106,6 +102,7 @@ const RepositoryListPage: FC = () => {
isFetchingNextPage={isFetchingNextPage}
hasNextPage={!!hasNextPage}
hasMoreThanOnePage={hasMoreThanOnePage}
onImport={() => setShowCreateProjectModal(true)}
onLoadNextPage={() => fetchNextPage()}
onSearchTermChange={setSearchTerm}
onSort={handleSort}
Expand Down
20 changes: 14 additions & 6 deletions components/dashboard/src/repositories/list/RepositoryTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Subheading } from "@podkit/typography/Headings";
import { cn } from "@podkit/lib/cn";
import { SortableTableHead, TableSortOrder } from "@podkit/tables/SortableTable";
import { LoadingState } from "@podkit/loading/LoadingState";
import { Button } from "@podkit/buttons/Button";

type Props = {
configurations: Configuration[];
Expand All @@ -25,6 +26,7 @@ type Props = {
hasMoreThanOnePage: boolean;
isSearching: boolean;
isFetchingNextPage: boolean;
onImport: () => void;
onSearchTermChange: (val: string) => void;
onLoadNextPage: () => void;
onSort: (columnName: string, direction: TableSortOrder) => void;
Expand All @@ -39,26 +41,32 @@ export const RepositoryTable: FC<Props> = ({
hasMoreThanOnePage,
isSearching,
isFetchingNextPage,
onImport,
onSearchTermChange,
onLoadNextPage,
onSort,
}) => {
return (
<>
{/* Search/Filter bar */}
<div className="flex flex-row flex-wrap justify-between items-center">
<div className="flex flex-row flex-wrap gap-2 items-center">
{/* TODO: Add search icon on left and decide on pulling Inputs into podkit */}
<div className="flex flex-col-reverse md:flex-row flex-wrap justify-between items-center gap-2">
<div className="flex flex-row flex-wrap items-center w-full md:w-auto">
{/* TODO: Add search icon on left - need to revisit TextInputs for podkit - and remove global styles */}
<TextInput
className="w-80"
className="w-full max-w-none md:w-80"
value={searchTerm}
onChange={onSearchTermChange}
placeholder="Search imported repositories"
/>
{/* TODO: Add prebuild status filter dropdown */}
</div>

{/* TODO: Consider making all podkit buttons behave this way, full width on small screen */}
<Button className="w-full md:w-auto" onClick={onImport}>
Import Repository
</Button>
</div>
<div className="relative w-full overflow-auto mt-2">
<div className="relative w-full overflow-auto mt-4">
{configurations.length > 0 ? (
<Table>
<TableHeader>
Expand Down Expand Up @@ -88,7 +96,7 @@ export const RepositoryTable: FC<Props> = ({
<TableHead className="w-24 text-right">
{isSearching && (
<div className="flex flex-right justify-end items-center">
<LoadingState delay={false} />
<LoadingState delay={false} size={16} />
</div>
)}
</TableHead>
Expand Down