Skip to content

Configuration details #18960

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

Closed
wants to merge 53 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
efdd2c3
Configuration
filiptronicek Oct 19, 2023
1164886
Merge branch 'main' of https://github.com/gitpod-io/gitpod
filiptronicek Oct 19, 2023
d03ec25
podkit augment
filiptronicek Oct 19, 2023
932ee2a
update heading to podkit
filiptronicek Oct 19, 2023
353008f
fix one last link
filiptronicek Oct 19, 2023
bfb09c1
Fix
filiptronicek Oct 19, 2023
d18d871
Bottom margin to container
filiptronicek Oct 19, 2023
becdb7a
Env vars component
filiptronicek Oct 19, 2023
2c1e791
Fix margin
filiptronicek Oct 19, 2023
e69fab6
poof
filiptronicek Oct 19, 2023
dc25d6a
Project env var mutation and queries
filiptronicek Oct 19, 2023
47c1182
tweaks
filiptronicek Oct 20, 2023
8a0e806
Improve copy
filiptronicek Oct 20, 2023
d4f2d6e
More tweaks
filiptronicek Oct 20, 2023
f9fd4d8
Merge branch 'main' into ft/configurations-details
filiptronicek Oct 21, 2023
f805b36
Add missing margin
filiptronicek Oct 21, 2023
3659e81
QuestionTooltip
filiptronicek Oct 21, 2023
630969a
Reset button styles
filiptronicek Oct 22, 2023
f9b3962
Color the ?
filiptronicek Oct 22, 2023
720847e
Another color update
filiptronicek Oct 22, 2023
5f4e30f
Constraint max tooltip width
filiptronicek Oct 22, 2023
fbacace
capitalize on workspaces 🤑
filiptronicek Oct 23, 2023
62921b7
Dropdown test
filiptronicek Oct 23, 2023
348d97a
Icon from lucide
filiptronicek Oct 24, 2023
6377578
Unstyled buttons
filiptronicek Oct 24, 2023
ed51435
Fix focus to hover
filiptronicek Oct 24, 2023
ed84249
onClick to onSelect
filiptronicek Oct 24, 2023
d243d46
Rename components
filiptronicek Oct 27, 2023
010bb43
Get rid of useless required prop checking
filiptronicek Oct 27, 2023
fad49dc
fix delete callback
filiptronicek Oct 27, 2023
2db913d
Bollocks
filiptronicek Oct 27, 2023
9a31528
Add bg color to dropdown items
filiptronicek Oct 27, 2023
348aa6f
Remove stuff
filiptronicek Oct 27, 2023
6b6d47f
Use mutation loading prop
filiptronicek Oct 27, 2023
7545748
Defer Podkit button to follow-up
filiptronicek Oct 28, 2023
6745f2a
Revert "Defer Podkit button to follow-up"
filiptronicek Oct 28, 2023
1df051b
Button component migrations
filiptronicek Oct 28, 2023
b24ccdd
Add additional focus ring classes
filiptronicek Oct 28, 2023
359d63f
Add LoadingButton and LinkButton
filiptronicek Oct 28, 2023
21794ed
👨‍🚒
filiptronicek Oct 28, 2023
95b8caa
Loading button stroke width
filiptronicek Oct 28, 2023
2dc3637
Bump width
filiptronicek Oct 28, 2023
a2e27b5
Merge branch 'main' into ft/configurations-details
filiptronicek Oct 28, 2023
5386f40
Loading -> disabled
filiptronicek Oct 28, 2023
32ed30d
Pass props through in to LoadingButton
filiptronicek Oct 28, 2023
6d151da
😏
filiptronicek Oct 28, 2023
bf4c74c
Play around with the dropdown backgrounds
filiptronicek Oct 28, 2023
dfb73e7
Tweaks
filiptronicek Oct 28, 2023
3ad68b0
Fix destructive button styles
filiptronicek Oct 28, 2023
4a7e8c6
Refactor env vars
filiptronicek Oct 28, 2023
66862c9
Fix dropdown border
filiptronicek Oct 28, 2023
44482f8
Condirenderi
filiptronicek Oct 28, 2023
3db8e92
More border fixes
filiptronicek Oct 28, 2023
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
4 changes: 4 additions & 0 deletions components/dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
"@connectrpc/connect-web": "1.1.2",
"@gitpod/gitpod-protocol": "0.1.5",
"@gitpod/public-api": "0.1.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-tooltip": "^1.0.7",
"@stripe/react-stripe-js": "^1.7.2",
"@stripe/stripe-js": "^1.29.0",
"@tanstack/query-async-storage-persister": "^4.29.19",
Expand All @@ -17,6 +19,7 @@
"@tanstack/react-query-persist-client": "^4.29.19",
"@types/react-datepicker": "^4.8.0",
"buffer": "^4.3.0",
"class-variance-authority": "^0.7.0",
"classnames": "^2.3.1",
"configcat-js": "^6.0.0",
"countries-list": "^2.6.1",
Expand Down Expand Up @@ -45,6 +48,7 @@
"setimmediate": "^1.0.5",
"stream-browserify": "^2.0.1",
"tailwind-merge": "^1.14.0",
"tailwindcss-animate": "^1.0.7",
"url": "^0.11.1",
"util": "^0.11.1",
"validator": "^13.9.0",
Expand Down
12 changes: 7 additions & 5 deletions components/dashboard/src/app/AppRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,11 @@ const WorkspacesSearch = React.lazy(() => import(/* webpackPrefetch: true */ "..
const ProjectsSearch = React.lazy(() => import(/* webpackPrefetch: true */ "../admin/ProjectsSearch"));
const TeamsSearch = React.lazy(() => import(/* webpackPrefetch: true */ "../admin/TeamsSearch"));
const Usage = React.lazy(() => import(/* webpackPrefetch: true */ "../Usage"));
const RepositoryListPage = React.lazy(() => import(/* webpackPrefetch: true */ "../repositories/list/RepositoryList"));
const RepositoryDetailPage = React.lazy(
() => import(/* webpackPrefetch: true */ "../repositories/detail/RepositoryDetail"),
const ConfigurationListPage = React.lazy(
() => import(/* webpackPrefetch: true */ "../configurations/list/ConfigurationList"),
);
const ConfigurationDetailPage = React.lazy(
() => import(/* webpackPrefetch: true */ "../configurations/detail/ConfigurationDetail"),
);

export const AppRoutes = () => {
Expand Down Expand Up @@ -218,8 +220,8 @@ export const AppRoutes = () => {

{repoConfigListAndDetail && (
<>
<Route exact path="/repositories" component={RepositoryListPage} />
<Route exact path="/repositories/:id" component={RepositoryDetailPage} />
<Route exact path="/configurations" component={ConfigurationListPage} />
<Route exact path="/configurations/:id" component={ConfigurationDetailPage} />
</>
)}
{/* basic redirect for old team slugs */}
Expand Down
4 changes: 2 additions & 2 deletions components/dashboard/src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Heading1, Subheading } from "./typography/headings";
export interface HeaderProps {
title: string;
complexTitle?: React.ReactElement;
subtitle: string | React.ReactElement;
subtitle?: string | React.ReactElement;
tabs?: TabEntry[];
}

Expand All @@ -31,7 +31,7 @@ export default function Header(p: HeaderProps) {
<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" ? (
{p.subtitle && typeof p.subtitle === "string" ? (
<Subheading tracking="wide">{p.subtitle}</Subheading>
) : (
p.subtitle
Expand Down
103 changes: 103 additions & 0 deletions components/dashboard/src/components/podkit/button/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/**
* 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 * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, VariantProps } from "class-variance-authority";
import { cn } from "@podkit/lib/cn";
import { Link } from "react-router-dom";
import { Loader2 } from "lucide-react";

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",
{
variants: {
variant: {
default:
"bg-gray-900 hover:bg-gray-800 dark:bg-kumquat-base dark:hover:bg-kumquat-ripe text-gray-50 dark:text-gray-900",
destructive: "bg-red-600 hover:bg-red-700 text-gray-100 dark:text-red-100",
outline: "border border-input bg-transparent hover:bg-kumquat-ripe hover:text-gray-600",
secondary:
"bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 text-gray-500 dark:text-gray-100 hover:text-gray-600",
ghost: "hover:bg-kumquat-ripe hover:text-gray-600",
link: "text-gray-500 dark:text-gray-100 underline-offset-4 hover:underline",
},
size: {
default: "h-9 px-4 py-2",
sm: "h-8 rounded-md px-3 text-xs",
lg: "h-10 rounded-md px-8",
icon: "h-9 w-9",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
},
);

export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}

export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
disabled={props.disabled}
{...props}
/>
);
},
);
Button.displayName = "Button";

export interface LoadingButtonProps extends ButtonProps {
loading: boolean;
asChild?: false;
}

export const LoadingButton = React.forwardRef<HTMLButtonElement, LoadingButtonProps>(
({ className, variant, size, children, loading, disabled, ...props }, ref) => {
return (
<Button
disabled={disabled || loading}
ref={ref}
className={cn("flex items-center gap-2", className)}
{...props}
>
{/* todo: make the layout consistent / animate thew width change */}
{loading && <Loader2 strokeWidth={3} className="animate-spin" size={16} />}
<span>{children}</span>
</Button>
);
},
);
LoadingButton.displayName = "LoadingButton";

export interface LinkButtonProps extends ButtonProps {
asChild?: false;
href: string;
}

/**
* A HTML anchor element styled as a button.
*/
export const LinkButton = React.forwardRef<HTMLButtonElement, LinkButtonProps>(
({ className, variant, size, asChild, children, href, ...props }, ref) => {
return (
<Button className="transition-width" asChild {...props} ref={ref}>
<Link to={href}>{children}</Link>
</Button>
);
},
);
LinkButton.displayName = "LinkButton";
184 changes: 184 additions & 0 deletions components/dashboard/src/components/podkit/drop-down/DropDown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
/**
* 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 * as React from "react";
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
import { Check, ChevronRight, Circle } from "lucide-react";
import { cn } from "@podkit/lib/cn";

const DropdownMenu = DropdownMenuPrimitive.Root;

const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;

const DropdownMenuGroup = DropdownMenuPrimitive.Group;

const DropdownMenuPortal = DropdownMenuPrimitive.Portal;

const DropdownMenuSub = DropdownMenuPrimitive.Sub;

const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;

const DropdownMenuSubTrigger = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
inset?: boolean;
}
>(({ className, inset, children, ...props }, ref) => (
<DropdownMenuPrimitive.SubTrigger
ref={ref}
className={cn(
"flex cursor-default select-none items-center rounded-lg px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
inset && "pl-8",
className,
)}
{...props}
>
{children}
<ChevronRight className="ml-auto h-4 w-4" />
</DropdownMenuPrimitive.SubTrigger>
));
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;

const DropdownMenuSubContent = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
>(({ className, ...props }, ref) => (
<DropdownMenuPrimitive.SubContent
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-gray-200 dark:border-gray-800 p-1 shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
)}
{...props}
/>
));
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;

const DropdownMenuContent = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<DropdownMenuPrimitive.Portal>
<DropdownMenuPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={cn(
"z-50 min-w-[8rem] w-48 overflow-hidden rounded-md border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900 p-1 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
)}
{...props}
/>
</DropdownMenuPrimitive.Portal>
));
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;

const DropdownMenuItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
inset?: boolean;
}
>(({ className, inset, ...props }, ref) => (
<DropdownMenuPrimitive.Item
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center px-2 py-1.5 text-sm outline-none bg-white dark:bg-gray-900 focus:text-gray-800 dark:focus:text-gray-100 focus:bg-gray-100 dark:focus:bg-gray-700 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
inset && "pl-8",
className,
)}
{...props}
/>
));
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;

const DropdownMenuCheckboxItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
>(({ className, children, checked, ...props }, ref) => (
<DropdownMenuPrimitive.CheckboxItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className,
)}
checked={checked}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<DropdownMenuPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</DropdownMenuPrimitive.ItemIndicator>
</span>
{children}
</DropdownMenuPrimitive.CheckboxItem>
));
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;

const DropdownMenuRadioItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
>(({ className, children, ...props }, ref) => (
<DropdownMenuPrimitive.RadioItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className,
)}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<DropdownMenuPrimitive.ItemIndicator>
<Circle className="h-2 w-2 fill-current" />
</DropdownMenuPrimitive.ItemIndicator>
</span>
{children}
</DropdownMenuPrimitive.RadioItem>
));
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;

const DropdownMenuLabel = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
inset?: boolean;
}
>(({ className, inset, ...props }, ref) => (
<DropdownMenuPrimitive.Label
ref={ref}
className={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
{...props}
/>
));
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;

const DropdownMenuSeparator = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
>(({ className, ...props }, ref) => (
<DropdownMenuPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-muted", className)} {...props} />
));
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;

const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
return <span className={cn("ml-auto text-xs tracking-widest opacity-60", className)} {...props} />;
};
DropdownMenuShortcut.displayName = "DropdownMenuShortcut";

export {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuCheckboxItem,
DropdownMenuRadioItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuGroup,
DropdownMenuPortal,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuRadioGroup,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* 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 { FC } from "react";
import { HelpCircle } from "lucide-react";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./Tooltip";

interface QuestionTooltipProps {
className?: string;
}

export const QuestionTooltip: FC<QuestionTooltipProps> = ({ className, children }) => {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger className="p-0 mx-1 bg-transparent text-black dark:text-white">
<HelpCircle className="text-blue-500" size={16} />
</TooltipTrigger>
<TooltipContent>{children}</TooltipContent>
</Tooltip>
</TooltipProvider>
);
};
Loading