Skip to content
This repository was archived by the owner on Jan 31, 2025. It is now read-only.

Commit b958db4

Browse files
committed
1 parent b7c1225 commit b958db4

File tree

7 files changed

+77
-40
lines changed

7 files changed

+77
-40
lines changed

apps/hub/src/components/breadcrumbs/environment-breadcrumb.tsx

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import { EnvironmentSelect } from "@/domains/project/components/environment-select";
2-
import { useNavigate } from "@tanstack/react-router";
2+
import { projectEnvironmentQueryOptions } from "@/domains/project/queries";
3+
import { useSuspenseQuery } from "@tanstack/react-query";
4+
import { Link, useNavigate } from "@tanstack/react-router";
5+
import { useContext } from "react";
6+
import { Fragment } from "react/jsx-runtime";
7+
import { NavItem } from "../header/nav-item";
8+
import { MobileBreadcrumbsContext } from "./mobile-breadcrumbs";
39
import { ProjectBreadcrumb } from "./project-breadcrumb";
410
import { Separator } from "./separator";
511

@@ -12,6 +18,9 @@ export function EnvironmentBreadcrumb({
1218
environmentId,
1319
projectId,
1420
}: EnvironmentBreadcrumbProps) {
21+
const { data } = useSuspenseQuery(
22+
projectEnvironmentQueryOptions({ projectId, environmentId }),
23+
);
1524
const navigate = useNavigate();
1625

1726
const handleEnvironmentChange = (environmentId: string) => {
@@ -20,13 +29,24 @@ export function EnvironmentBreadcrumb({
2029
params: { projectId, environmentId },
2130
});
2231
};
32+
const isMobile = useContext(MobileBreadcrumbsContext);
33+
34+
const Element = isMobile ? NavItem : Fragment;
2335

2436
return (
2537
<>
2638
<ProjectBreadcrumb projectId={projectId} />
2739
<Separator />
28-
<div>
40+
<Element>
41+
<Link
42+
to="/projects/$projectId/environments/$environmentId"
43+
params={{ projectId, environmentId }}
44+
className="flex items-center gap-2"
45+
>
46+
{data.namespace.displayName}
47+
</Link>
2948
<EnvironmentSelect
49+
variant="discrete"
3050
projectId={projectId}
3151
value={environmentId}
3252
onCreateClick={() =>
@@ -35,7 +55,7 @@ export function EnvironmentBreadcrumb({
3555
showCreateEnvironment
3656
onValueChange={handleEnvironmentChange}
3757
/>
38-
</div>
58+
</Element>
3959
</>
4060
);
4161
}

apps/hub/src/components/breadcrumbs/group-breadcrumb.tsx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,29 +34,29 @@ export function GroupBreadcrumb({ groupId }: GroupBreadcrumbProps) {
3434

3535
return (
3636
<Element>
37+
<Link
38+
to="/teams/$groupId"
39+
params={{ groupId }}
40+
className="flex items-center gap-2"
41+
>
42+
<GroupAvatar
43+
avatarUrl={data.avatarUrl}
44+
displayName={data.displayName}
45+
className={isMobile ? "size-4" : "size-5"}
46+
/>
47+
{data.displayName}
48+
</Link>
3749
{groupsCount > 1 ? (
3850
<GroupSelect
51+
variant="discrete"
3952
showCreateGroup
4053
onCreateClick={() =>
4154
navigate({ to: ".", search: { modal: "create-group" } })
4255
}
4356
value={groupId}
4457
onValueChange={handleGroupChange}
4558
/>
46-
) : (
47-
<Link
48-
to="/teams/$groupId"
49-
params={{ groupId }}
50-
className="flex items-center gap-2"
51-
>
52-
<GroupAvatar
53-
avatarUrl={data.avatarUrl}
54-
displayName={data.displayName}
55-
className={isMobile ? "size-4" : "size-5"}
56-
/>
57-
{data.displayName}
58-
</Link>
59-
)}
59+
) : null}
6060
</Element>
6161
);
6262
}

apps/hub/src/components/breadcrumbs/project-breadcrumb.tsx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,21 @@ export function ProjectBreadcrumb({ projectId }: ProjectBreadcrumbProps) {
3939
<GroupBreadcrumb groupId={data.developerGroupId} />
4040
<Separator />
4141
<Element>
42+
<Link
43+
to="/projects/$projectId"
44+
params={{ projectId }}
45+
className="flex items-center gap-2"
46+
>
47+
<ProjectAvatar
48+
displayName={data.displayName}
49+
logoUrl={data.logoUrl}
50+
className={isMobile ? "size-4" : "size-5"}
51+
/>
52+
{data.displayName}
53+
</Link>
4254
{projectsCount > 1 ? (
4355
<GroupProjectSelect
56+
variant="discrete"
4457
showCreateProject
4558
onCreateClick={() =>
4659
navigate({
@@ -55,20 +68,7 @@ export function ProjectBreadcrumb({ projectId }: ProjectBreadcrumbProps) {
5568
value={projectId}
5669
onValueChange={handleProjectChange}
5770
/>
58-
) : (
59-
<Link
60-
to="/projects/$projectId"
61-
params={{ projectId }}
62-
className="flex items-center gap-2"
63-
>
64-
<ProjectAvatar
65-
displayName={data.displayName}
66-
logoUrl={data.logoUrl}
67-
className={isMobile ? "size-4" : "size-5"}
68-
/>
69-
{data.displayName}
70-
</Link>
71-
)}
71+
) : null}
7272
</Element>
7373
</>
7474
);

apps/hub/src/domains/group/components/group-select.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ import { type ComponentProps, useCallback } from "react";
1616
interface GroupSelectProps extends ComponentProps<typeof Select> {
1717
showCreateGroup?: boolean;
1818
onCreateClick?: () => void;
19+
variant?: ComponentProps<typeof SelectTrigger>["variant"];
1920
}
2021

2122
export function GroupSelect({
2223
showCreateGroup,
2324
onCreateClick,
2425
onValueChange,
26+
variant,
2527
...props
2628
}: GroupSelectProps) {
2729
const { data } = useSuspenseQuery(projectsQueryOptions());
@@ -39,7 +41,7 @@ export function GroupSelect({
3941

4042
return (
4143
<Select {...props} onValueChange={handleValueChange}>
42-
<SelectTrigger>
44+
<SelectTrigger variant={variant}>
4345
<SelectValue placeholder="Select team..." />
4446
</SelectTrigger>
4547
<SelectContent>

apps/hub/src/domains/project/components/environment-select.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ interface EnvironmentSelectProps extends ComponentProps<typeof Select> {
1616
projectId: string;
1717
showCreateEnvironment?: boolean;
1818
onCreateClick?: () => void;
19+
variant?: ComponentProps<typeof SelectTrigger>["variant"];
1920
}
2021

2122
export function EnvironmentSelect({
2223
showCreateEnvironment,
2324
onCreateClick,
2425
onValueChange,
2526
projectId,
27+
variant,
2628
...props
2729
}: EnvironmentSelectProps) {
2830
const { data } = useSuspenseQuery(projectEnvironmentsQueryOptions(projectId));
@@ -40,7 +42,7 @@ export function EnvironmentSelect({
4042

4143
return (
4244
<Select {...props} onValueChange={handleValueChange}>
43-
<SelectTrigger>
45+
<SelectTrigger variant={variant}>
4446
<SelectValue placeholder="Select environment..." />
4547
</SelectTrigger>
4648
<SelectContent>

apps/hub/src/domains/project/components/group-project-select.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ interface GroupProjectSelectProps extends ComponentProps<typeof Select> {
1717
groupId: string;
1818
showCreateProject?: boolean;
1919
onCreateClick?: () => void;
20+
variant?: ComponentProps<typeof SelectTrigger>["variant"];
2021
}
2122

2223
export function GroupProjectSelect({
2324
groupId,
2425
showCreateProject,
2526
onCreateClick,
2627
onValueChange,
28+
variant,
2729
...props
2830
}: GroupProjectSelectProps) {
2931
const { data } = useSuspenseQuery(groupProjectsQueryOptions(groupId));
@@ -41,7 +43,7 @@ export function GroupProjectSelect({
4143

4244
return (
4345
<Select onValueChange={handleValueChange} {...props}>
44-
<SelectTrigger>
46+
<SelectTrigger variant={variant}>
4547
<SelectValue placeholder="Select project..." />
4648
</SelectTrigger>
4749
<SelectContent>

packages/components/src/ui/select.tsx

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import * as SelectPrimitive from "@radix-ui/react-select";
44
import * as React from "react";
55

6-
import { faCheck, faChevronDown, faChevronUp } from "@rivet-gg/icons";
6+
import { faCheck, faChevronDown, faChevronUp, faSelect } from "@rivet-gg/icons";
77
import { Icon } from "@rivet-gg/icons";
88
import { cn } from "../lib/utils";
99

@@ -16,19 +16,30 @@ const SelectValue = SelectPrimitive.Value;
1616

1717
const SelectTrigger = React.forwardRef<
1818
React.ElementRef<typeof SelectPrimitive.Trigger>,
19-
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
20-
>(({ className, children, ...props }, ref) => (
19+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> & {
20+
variant?: "discrete";
21+
}
22+
>(({ className, children, variant, ...props }, ref) => (
2123
<SelectPrimitive.Trigger
2224
ref={ref}
2325
className={cn(
24-
"flex whitespace-nowrap h-10 w-full items-center justify-between gap-2 rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
26+
"flex group/select whitespace-nowrap hover:bg-secondary transition-colors h-10 w-full items-center justify-between gap-2 rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
27+
{
28+
"border-0 w-auto ring-0 px-1 focus:ring-0 focus:ring-transparent aria-expanded:bg-secondary":
29+
variant === "discrete",
30+
},
2531
className,
2632
)}
2733
{...props}
2834
>
29-
{children}
35+
{variant === "discrete" ? null : children}
3036
<SelectPrimitive.Icon asChild>
31-
<Icon icon={faChevronDown} className="h-4 w-4 opacity-50" />
37+
<Icon
38+
icon={variant === "discrete" ? faSelect : faChevronDown}
39+
className={cn(
40+
"h-4 w-4 group-hover/select:opacity-100 transition-opacity group-aria-expanded/select:opacity-100 opacity-50",
41+
)}
42+
/>
3243
</SelectPrimitive.Icon>
3344
</SelectPrimitive.Trigger>
3445
));

0 commit comments

Comments
 (0)