Skip to content

Commit a846181

Browse files
authored
New Layout: Wrap banch related pages in a card (#4626)
1 parent c255485 commit a846181

File tree

4 files changed

+83
-14
lines changed

4 files changed

+83
-14
lines changed

frontend/app/src/pages/branches/details.tsx

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@ import { QSP } from "@/config/qsp";
44
import { ArtifactsDiff } from "@/screens/diff/artifact-diff/artifacts-diff";
55
import { NodeDiff } from "@/screens/diff/node-diff";
66

7+
import { Badge } from "@/components/ui/badge";
8+
import { Spinner } from "@/components/ui/spinner";
79
import { useTitle } from "@/hooks/useTitle";
810
import { BranchDetails } from "@/screens/branches/branch-details";
911
import { FilesDiff } from "@/screens/diff/file-diff/files-diff";
1012
import Content from "@/screens/layout/content";
13+
import { branchesState } from "@/state/atoms/branches.atom";
1114
import { constructPath } from "@/utils/fetch";
15+
import { useAtomValue } from "jotai";
1216
import React from "react";
1317
import { Navigate, useParams } from "react-router-dom";
1418
import { StringParam, useQueryParam } from "use-query-params";
@@ -20,20 +24,40 @@ export const BRANCH_TABS = {
2024

2125
export function BranchDetailsPage() {
2226
const { "*": branchName } = useParams();
27+
const branches = useAtomValue(branchesState);
2328
useTitle(`${branchName} details`);
2429

2530
if (!branchName) {
2631
return <Navigate to={constructPath("/branches")} />;
2732
}
2833

34+
if (branches.length === 0) {
35+
return (
36+
<Content.Card className="flex justify-center items-center p-5 min-h-[400px]">
37+
<Spinner />
38+
</Content.Card>
39+
);
40+
}
41+
42+
const branch = branches.find((branch) => branch.name === branchName);
43+
44+
if (!branch) {
45+
return <Navigate to={constructPath("/branches")} />;
46+
}
47+
2948
return (
30-
<Content>
31-
<Content.Title title={<div>Branch - {branchName}</div>} />
49+
<Content.Card>
50+
<header className="p-5 font-bold flex gap-2 items-center">
51+
<h1 className="text-xl">{branch.name}</h1>
52+
{branch.is_default && <Badge variant="blue-outline">default</Badge>}
53+
</header>
3254

3355
<BranchTab />
3456

35-
<BranchContent branchName={branchName} />
36-
</Content>
57+
<Content.CardContent>
58+
<BranchContent branchName={branchName} />
59+
</Content.CardContent>
60+
</Content.Card>
3761
);
3862
}
3963

frontend/app/src/screens/branches/branches-items.tsx

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,10 @@ const BranchesItems = () => {
3232
};
3333

3434
return (
35-
<Content>
36-
<Content.Title
37-
title={
38-
<div className="flex items-center">
39-
<h1 className="mr-2 truncate">Branches</h1>
40-
<Badge>{branches.length}</Badge>
41-
</div>
42-
}
35+
<Content.Card>
36+
<Content.CardTitle
37+
title="Branches"
38+
badgeContent={branches.length}
4339
isReloadLoading={loading}
4440
reload={handleRefresh}
4541
/>
@@ -105,7 +101,7 @@ const BranchesItems = () => {
105101
</li>
106102
))}
107103
</ul>
108-
</Content>
104+
</Content.Card>
109105
);
110106
};
111107

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export const breadcrumbItemStyle =
22
"w-auto h-auto border-none hover:bg-gray-100 py-1 px-2 rounded-md";
33

4-
export const breadcrumbActiveStyle = "bg-indigo-50 text-indigo-700 hover:bg-indigo-100";
4+
export const breadcrumbActiveStyle =
5+
"bg-indigo-50 text-indigo-700 hover:bg-indigo-100 [&>iconify-icon]:text-indigo-700";

frontend/app/src/screens/layout/content.tsx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { Retry } from "@/components/buttons/retry";
2+
import { Badge } from "@/components/ui/badge";
3+
import { Card, CardProps } from "@/components/ui/card";
24
import { classNames } from "@/utils/common";
35
import { HTMLAttributes, ReactNode } from "react";
46

@@ -46,9 +48,55 @@ export const ContentTitle = ({
4648
);
4749
};
4850

51+
export const ContentCard = ({ className, ...props }: CardProps) => {
52+
return <Card className={classNames("p-0 m-2 overflow-hidden", className)} {...props} />;
53+
};
54+
55+
export type ContentCardTitleProps = {
56+
title?: ReactNode;
57+
subtitle?: ReactNode;
58+
description?: ReactNode;
59+
badgeContent?: ReactNode;
60+
reload?: () => void;
61+
isReloadLoading?: boolean;
62+
className?: string;
63+
};
64+
65+
export const ContentCardTitle = ({
66+
badgeContent,
67+
description,
68+
isReloadLoading,
69+
reload,
70+
title,
71+
className,
72+
...props
73+
}: ContentCardTitleProps) => {
74+
return (
75+
<header className={classNames("flex items-center p-5", className)} {...props}>
76+
<div className="flex flex-col gap-0.5 overflow-hidden">
77+
{title && (
78+
<div className="font-bold text-xl flex items-center gap-2">
79+
<div className="truncate">{title}</div>
80+
{badgeContent && <Badge className="text-sm">{badgeContent}</Badge>}
81+
{reload && <Retry isLoading={isReloadLoading} onClick={reload} />}
82+
</div>
83+
)}
84+
{description && <div className="text-sm truncate">{description}</div>}
85+
</div>
86+
</header>
87+
);
88+
};
89+
90+
export const ContentCardContent = ({ className, ...props }: HTMLAttributes<HTMLElement>) => {
91+
return <div className={classNames("p-5 pt-0", className)} {...props} />;
92+
};
93+
4994
export const Content = Object.assign(ContentRoot, {
5095
Title: ContentTitle,
5196
Root: ContentRoot,
97+
Card: ContentCard,
98+
CardTitle: ContentCardTitle,
99+
CardContent: ContentCardContent,
52100
});
53101

54102
export default Content;

0 commit comments

Comments
 (0)