mirror of
https://github.com/RayLabsHQ/gitea-mirror.git
synced 2025-12-11 05:56:46 +03:00
Dashboard minor UI update
This commit is contained in:
@@ -193,7 +193,7 @@ export function Dashboard() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
{Array.from({ length: 3 }).map((_, i) => (
|
{Array.from({ length: 3 }).map((_, i) => (
|
||||||
<Skeleton key={i} className="h-16 w-full" />
|
<Skeleton key={i} className="h-14 w-full" />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -206,7 +206,7 @@ export function Dashboard() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
{Array.from({ length: 3 }).map((_, i) => (
|
{Array.from({ length: 3 }).map((_, i) => (
|
||||||
<Skeleton key={i} className="h-16 w-full" />
|
<Skeleton key={i} className="h-14 w-full" />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -254,12 +254,11 @@ export function Dashboard() {
|
|||||||
|
|
||||||
<div className="flex flex-col lg:flex-row gap-6 items-start">
|
<div className="flex flex-col lg:flex-row gap-6 items-start">
|
||||||
<div className="w-full lg:w-1/2">
|
<div className="w-full lg:w-1/2">
|
||||||
<RepositoryList repositories={repositories} />
|
<RepositoryList repositories={repositories.slice(0, 8)} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-full lg:w-1/2">
|
<div className="w-full lg:w-1/2">
|
||||||
{/* the api already sends 10 activities only but slicing in case of realtime updates */}
|
<RecentActivity activities={activities.slice(0, 8)} />
|
||||||
<RecentActivity activities={activities.slice(0, 10)} />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -16,27 +16,27 @@ export function RecentActivity({ activities }: RecentActivityProps) {
|
|||||||
<a href="/activity">View All</a>
|
<a href="/activity">View All</a>
|
||||||
</Button>
|
</Button>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="max-h-[300px] sm:max-h-[400px] lg:max-h-[calc(100dvh-22.5rem)] overflow-y-auto">
|
<CardContent>
|
||||||
<div className="flex flex-col divide-y divide-border">
|
<div className="flex flex-col divide-y divide-border">
|
||||||
{activities.length === 0 ? (
|
{activities.length === 0 ? (
|
||||||
<p className="text-sm text-muted-foreground">No recent activity</p>
|
<p className="text-sm text-muted-foreground">No recent activity</p>
|
||||||
) : (
|
) : (
|
||||||
activities.map((activity, index) => (
|
activities.map((activity, index) => (
|
||||||
<div key={index} className="flex items-start gap-x-4 py-4">
|
<div key={index} className="flex items-center gap-x-3 py-3.5">
|
||||||
<div className="relative mt-1">
|
<div className="relative flex-shrink-0">
|
||||||
<div
|
<div
|
||||||
className={`h-2 w-2 rounded-full ${getStatusColor(
|
className={`h-2 w-2 rounded-full ${getStatusColor(
|
||||||
activity.status
|
activity.status
|
||||||
)}`}
|
)}`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1 space-y-1">
|
<div className="flex-1 min-w-0">
|
||||||
<p className="text-sm font-medium leading-none break-words">
|
<div className="text-sm font-medium">
|
||||||
{activity.message}
|
{activity.message}
|
||||||
</p>
|
</div>
|
||||||
<p className="text-xs text-muted-foreground">
|
<div className="text-xs text-muted-foreground mt-1">
|
||||||
{formatDate(activity.timestamp)}
|
{formatDate(activity.timestamp)}
|
||||||
</p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -47,14 +47,13 @@ export function RepositoryList({ repositories }: RepositoryListProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="w-full">
|
<Card className="w-full">
|
||||||
{/* calculating the max height based non the other elements and sizing styles */}
|
|
||||||
<CardHeader className="flex flex-row items-center justify-between">
|
<CardHeader className="flex flex-row items-center justify-between">
|
||||||
<CardTitle>Repositories</CardTitle>
|
<CardTitle>Repositories</CardTitle>
|
||||||
<Button variant="outline" asChild>
|
<Button variant="outline" asChild>
|
||||||
<a href="/repositories">View All</a>
|
<a href="/repositories">View All</a>
|
||||||
</Button>
|
</Button>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="max-h-[300px] sm:max-h-[400px] lg:max-h-[calc(100dvh-22.5rem)] overflow-y-auto">
|
<CardContent>
|
||||||
{repositories.length === 0 ? (
|
{repositories.length === 0 ? (
|
||||||
<div className="flex flex-col items-center justify-center py-6 text-center">
|
<div className="flex flex-col items-center justify-center py-6 text-center">
|
||||||
<GitFork className="h-10 w-10 text-muted-foreground mb-4" />
|
<GitFork className="h-10 w-10 text-muted-foreground mb-4" />
|
||||||
@@ -71,81 +70,72 @@ export function RepositoryList({ repositories }: RepositoryListProps) {
|
|||||||
{repositories.map((repo, index) => (
|
{repositories.map((repo, index) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 sm:gap-x-4 py-4"
|
className="flex items-center gap-x-3 py-3.5"
|
||||||
>
|
>
|
||||||
<div className="flex-1">
|
<div className="relative flex-shrink-0">
|
||||||
<div className="flex items-center flex-wrap gap-2">
|
|
||||||
<h4 className="text-sm font-medium break-all">{repo.name}</h4>
|
|
||||||
{repo.isPrivate && (
|
|
||||||
<span className="rounded-full bg-muted px-2 py-0.5 text-xs">
|
|
||||||
Private
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{repo.isForked && (
|
|
||||||
<span className="rounded-full bg-muted px-2 py-0.5 text-xs">
|
|
||||||
Fork
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2 mt-1">
|
|
||||||
<span className="text-xs text-muted-foreground">
|
|
||||||
{repo.owner}
|
|
||||||
</span>
|
|
||||||
{repo.organization && (
|
|
||||||
<span className="text-xs text-muted-foreground">
|
|
||||||
• {repo.organization}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex items-center gap-2 sm:ml-auto">
|
|
||||||
<div
|
<div
|
||||||
className={`h-2 w-2 rounded-full ${getStatusColor(
|
className={`h-2 w-2 rounded-full ${getStatusColor(
|
||||||
repo.status
|
repo.status
|
||||||
)}`}
|
)}`}
|
||||||
/>
|
/>
|
||||||
<span className="text-xs capitalize w-[3rem] sm:w-auto">
|
</div>
|
||||||
{/* setting the minimum width to 3rem corresponding to the largest status (mirrored) so that all are left alligned */}
|
<div className="flex-1 min-w-0">
|
||||||
|
<div className="flex items-center gap-2 flex-wrap">
|
||||||
|
<h4 className="text-sm font-medium truncate">{repo.name}</h4>
|
||||||
|
{repo.isPrivate && (
|
||||||
|
<span className="rounded-full bg-muted px-2 py-0.5 text-[10px]">
|
||||||
|
Private
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{repo.isForked && (
|
||||||
|
<span className="rounded-full bg-muted px-2 py-0.5 text-[10px]">
|
||||||
|
Fork
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-1.5 mt-1 text-xs text-muted-foreground">
|
||||||
|
<span className="truncate">{repo.owner}</span>
|
||||||
|
{repo.organization && (
|
||||||
|
<>
|
||||||
|
<span>/</span>
|
||||||
|
<span className="truncate">{repo.organization}</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span className={`inline-flex items-center rounded-full px-2.5 py-1 text-[10px] font-medium mr-2
|
||||||
|
${repo.status === 'imported' ? 'bg-yellow-500/10 text-yellow-600 dark:text-yellow-400' :
|
||||||
|
repo.status === 'mirrored' || repo.status === 'synced' ? 'bg-green-500/10 text-green-600 dark:text-green-400' :
|
||||||
|
repo.status === 'mirroring' || repo.status === 'syncing' ? 'bg-blue-500/10 text-blue-600 dark:text-blue-400' :
|
||||||
|
repo.status === 'failed' ? 'bg-red-500/10 text-red-600 dark:text-red-400' :
|
||||||
|
'bg-muted text-muted-foreground'}`}>
|
||||||
{repo.status}
|
{repo.status}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-1 flex-shrink-0">
|
||||||
{(() => {
|
{(() => {
|
||||||
const giteaUrl = getGiteaRepoUrl(repo);
|
const giteaUrl = getGiteaRepoUrl(repo);
|
||||||
|
const giteaEnabled = giteaUrl && ['mirrored', 'synced'].includes(repo.status);
|
||||||
|
|
||||||
// Determine tooltip based on status and configuration
|
return giteaEnabled ? (
|
||||||
let tooltip: string;
|
<Button variant="ghost" size="icon" className="h-8 w-8" asChild>
|
||||||
if (!giteaConfig?.url) {
|
|
||||||
tooltip = "Gitea not configured";
|
|
||||||
} else if (repo.status === 'imported') {
|
|
||||||
tooltip = "Repository not yet mirrored to Gitea";
|
|
||||||
} else if (repo.status === 'failed') {
|
|
||||||
tooltip = "Repository mirroring failed";
|
|
||||||
} else if (repo.status === 'mirroring') {
|
|
||||||
tooltip = "Repository is being mirrored to Gitea";
|
|
||||||
} else if (giteaUrl) {
|
|
||||||
tooltip = "View on Gitea";
|
|
||||||
} else {
|
|
||||||
tooltip = "Gitea repository not available";
|
|
||||||
}
|
|
||||||
|
|
||||||
return giteaUrl ? (
|
|
||||||
<Button variant="ghost" size="icon" asChild>
|
|
||||||
<a
|
<a
|
||||||
href={giteaUrl}
|
href={giteaUrl}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
title={tooltip}
|
title="View on Gitea"
|
||||||
>
|
>
|
||||||
<SiGitea className="h-4 w-4" />
|
<SiGitea className="h-4 w-4" />
|
||||||
</a>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button variant="ghost" size="icon" disabled title={tooltip}>
|
<Button variant="ghost" size="icon" className="h-8 w-8" disabled title="Not mirrored yet">
|
||||||
<SiGitea className="h-4 w-4" />
|
<SiGitea className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
})()}
|
})()}
|
||||||
<Button variant="ghost" size="icon" asChild>
|
<Button variant="ghost" size="icon" className="h-8 w-8" asChild>
|
||||||
<a
|
<a
|
||||||
href={repo.url}
|
href={repo.url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
|||||||
Reference in New Issue
Block a user