Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions app/(auth)/auth/oidc-callback/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ export default function OidcCallbackPage() {
}, [credentialsSet, isAuthenticated, hasResolvedFirstRoute, firstAccessibleRoute, router])

return (
<div className="flex min-h-screen items-center justify-center bg-gray-100 dark:bg-neutral-800">
<div className="flex min-h-screen items-center justify-center bg-muted">
<div className="text-center">
<div className="mb-4 h-8 w-8 animate-spin rounded-full border-4 border-gray-300 border-t-blue-600 mx-auto" />
<p className="text-gray-600 dark:text-neutral-400">{t("Completing SSO login...")}</p>
<div className="mx-auto mb-4 h-8 w-8 animate-spin rounded-full border-4 border-muted-foreground/25 border-t-primary" />
<p className="text-muted-foreground">{t("Completing SSO login")}</p>
</div>
</div>
)
Expand Down
45 changes: 30 additions & 15 deletions app/(auth)/config/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,25 +101,25 @@ function ConfigPageContent() {
}

return (
<div className="flex min-h-screen flex-col items-center justify-center bg-gray-100 dark:bg-neutral-800 lg:p-20">
<div className="relative flex min-h-screen flex-col items-center justify-center overflow-hidden bg-muted p-4 sm:p-6 lg:p-20">
<Image
src={buildRoute("/backgrounds/scillate.svg")}
alt=""
fill
priority
sizes="100vw"
className="absolute inset-0 z-0 opacity-45 object-cover"
/>
<div className="z-10 mx-auto flex max-h-[85vh] w-full max-w-7xl flex-1 flex-col overflow-hidden rounded-lg shadow-lg dark:border-neutral-700 dark:bg-neutral-800 lg:flex-row">
<div className="z-10 mx-auto flex w-full max-w-7xl flex-col overflow-hidden border bg-card shadow-none lg:min-h-[560px] lg:flex-row">
<div className="hidden w-1/2 lg:block">
<AuthHeroStatic />
</div>
<div className="flex w-full flex-col items-center justify-center bg-white dark:border-neutral-700 dark:bg-neutral-900 lg:w-1/2">
<div className="flex w-full flex-col items-center justify-center bg-card lg:w-1/2">
<div className="max-w-sm w-full space-y-6 p-4 sm:p-7">
<ThemeLogo width={112} height={24} className="max-w-28" />
<ThemeLogo width={112} height={24} priority />
<div className="py-6">
<h1 className="block text-2xl font-bold text-gray-800 dark:text-white">{t("Server Configuration")}</h1>
<p className="mt-2 text-sm text-gray-600 dark:text-neutral-400">
{t("Please configure your RustFS server address")}
</p>
<h1 className="block text-2xl font-bold text-foreground">{t("Server Configuration")}</h1>
<p className="mt-2 text-sm text-muted-foreground">{t("Please configure your RustFS server address")}</p>
</div>

<div className="mt-5 space-y-4">
Expand All @@ -131,9 +131,12 @@ function ConfigPageContent() {
<FieldContent>
<Input
id="serverHost"
name="serverHost"
value={serverHost}
onChange={(e) => setServerHost(e.target.value)}
type="text"
type="url"
autoComplete="off"
spellCheck={false}
placeholder={t("Please enter server address (e.g., http://localhost:9000)")}
/>
</FieldContent>
Expand All @@ -142,16 +145,28 @@ function ConfigPageContent() {
</FieldDescription>
</Field>

<div className="flex gap-3">
<Button type="submit" className="flex-1" disabled={isSaving}>
<div className="flex flex-col gap-3 sm:flex-row">
<Button type="submit" className="w-full sm:flex-1" disabled={isSaving}>
{t("Save Configuration")}
</Button>

<Button type="button" variant="outline" onClick={resetToCurrentHost} disabled={isSaving}>
<Button
type="button"
variant="outline"
className="w-full sm:w-auto"
onClick={resetToCurrentHost}
disabled={isSaving}
>
{t("Reset")}
</Button>

<Button type="button" variant="outline" onClick={skipConfig} disabled={isSaving}>
<Button
type="button"
variant="outline"
className="w-full sm:w-auto"
onClick={skipConfig}
disabled={isSaving}
>
{t("Skip")}
</Button>
</div>
Expand All @@ -160,9 +175,9 @@ function ConfigPageContent() {
</div>

<div className="my-8">
<p className="text-sm text-gray-600 dark:text-neutral-400">
<p className="text-sm text-muted-foreground">
{t("Need help?")}{" "}
<Link href={docs} className="text-blue-600 hover:underline">
<Link href={docs} className="text-foreground underline-offset-4 hover:underline">
{t("View Documentation")}
</Link>
</p>
Expand Down
6 changes: 5 additions & 1 deletion app/(auth)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
export default function AuthLayout({ children }: { children: React.ReactNode }) {
return <div className="min-h-screen">{children}</div>
return (
<main id="main-content" tabIndex={-1} className="min-h-screen min-w-0">
{children}
</main>
)
}
10 changes: 5 additions & 5 deletions app/(dashboard)/403/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ export default function ForbiddenPage() {
<EmptyContent className="max-w-sm text-center">
<EmptyHeader>
<EmptyMedia variant="icon" className="mx-auto">
<svg viewBox="0 0 48 48" fill="none" className="h-12 w-12">
<circle cx="24" cy="24" r="22" fill="#F3F4F6" stroke="#E5E7EB" strokeWidth="2" />
<svg viewBox="0 0 48 48" fill="none" className="h-12 w-12 text-muted-foreground" aria-hidden>
<circle cx="24" cy="24" r="22" className="fill-muted stroke-border" strokeWidth="2" />
<path
d="M16 21V19a8 8 0 0116 0v2"
stroke="#A3A3A3"
className="stroke-muted-foreground"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<rect x="16" y="28" width="16" height="4" rx="2" fill="#A3A3A3" />
<rect x="22" y="32" width="4" height="4" rx="2" fill="#A3A3A3" />
<rect x="16" y="28" width="16" height="4" rx="2" className="fill-muted-foreground" />
<rect x="22" y="32" width="4" height="4" rx="2" className="fill-muted-foreground" />
</svg>
</EmptyMedia>
<EmptyTitle>{t("Access Denied")}</EmptyTitle>
Expand Down
12 changes: 6 additions & 6 deletions app/(dashboard)/_components/performance-infrastructure-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,27 @@ export function PerformanceInfrastructureCard({
</CardHeader>
<CardContent>
<div className="grid gap-4 lg:grid-cols-2">
<div className="rounded-lg border bg-muted/40 p-4">
<div className="border bg-muted/40 p-4">
<p className="text-sm font-medium text-muted-foreground">{t("Servers")}</p>
<div className="mt-4 grid gap-3 sm:grid-cols-2">
<div className="rounded-md border bg-background p-3">
<div className="border bg-background p-3">
<p className="text-xs text-muted-foreground">{t("Online")}</p>
<p className="mt-1 text-xl font-semibold text-foreground">{onlineServers}</p>
</div>
<div className="rounded-md border bg-background p-3">
<div className="border bg-background p-3">
<p className="text-xs text-muted-foreground">{t("Offline")}</p>
<p className="mt-1 text-xl font-semibold text-foreground">{offlineServers}</p>
</div>
</div>
</div>
<div className="rounded-lg border bg-muted/40 p-4">
<div className="border bg-muted/40 p-4">
<p className="text-sm font-medium text-muted-foreground">{t("Disks")}</p>
<div className="mt-4 grid gap-3 sm:grid-cols-2">
<div className="rounded-md border bg-background p-3">
<div className="border bg-background p-3">
<p className="text-xs text-muted-foreground">{t("Online")}</p>
<p className="mt-1 text-xl font-semibold text-foreground">{onlineDisks}</p>
</div>
<div className="rounded-md border bg-background p-3">
<div className="border bg-background p-3">
<p className="text-xs text-muted-foreground">{t("Offline")}</p>
<p className="mt-1 text-xl font-semibold text-foreground">{offlineDisks}</p>
</div>
Expand Down
6 changes: 3 additions & 3 deletions app/(dashboard)/_components/performance-server-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ export function PerformanceServerList({ servers, t }: { servers: ServerInfo[]; t
<div className="flex items-center gap-2 self-start sm:self-auto">
<span className="text-sm text-muted-foreground">{t("Sort by")}</span>
<Select value={sortBy} onValueChange={(value) => setSortBy(value as PerformanceServerSort)}>
<SelectTrigger className="w-[180px] shadow-none">
<SelectTrigger className="w-[180px] shadow-none" aria-label={t("Sort by")}>
<SelectValue placeholder={t("Default")} />
</SelectTrigger>
<SelectContent>
Expand All @@ -171,12 +171,12 @@ export function PerformanceServerList({ servers, t }: { servers: ServerInfo[]; t
value={server.endpoint ? `${server.endpoint}-${originalIndex}` : `server-${originalIndex}`}
>
<AccordionTrigger>
<div className="flex flex-col gap-2 text-left sm:flex-row sm:items-center sm:gap-4">
<div className="flex flex-col gap-2 text-start sm:flex-row sm:items-center sm:gap-4">
<div className="flex items-center gap-2">
<span
className={cn(
"inline-flex h-2 w-2 rounded-full",
server.state === "online" ? "bg-emerald-500" : "bg-rose-500",
server.state === "online" ? "bg-primary" : "bg-destructive",
)}
/>
<span className="font-semibold">{server.endpoint ?? "--"}</span>
Expand Down
4 changes: 2 additions & 2 deletions app/(dashboard)/_components/performance-usage-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ export function PerformanceUsageCard({
</div>
<div className="w-full max-w-xs space-y-2">
<Progress value={usedPercent} className="h-2" />
<p className="text-right text-xs text-muted-foreground">{usedPercent.toFixed(0)}%</p>
<p className="text-end text-xs text-muted-foreground">{usedPercent.toFixed(0)}%</p>
</div>
</div>

<div className="grid gap-3 sm:grid-cols-3">
{usageStats.map((item) => (
<div key={item.label} className="rounded-lg border bg-muted/40 p-4">
<div key={item.label} className="border bg-muted/40 p-4">
<p className="text-xs uppercase text-muted-foreground">{item.label}</p>
<p className="mt-2 text-sm font-medium text-foreground">{item.value}</p>
</div>
Expand Down
12 changes: 6 additions & 6 deletions app/(dashboard)/access-keys/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import { UserNotice } from "@/components/user/notice"
import { useAccessKeys } from "@/hooks/use-access-keys"
import { useDialog } from "@/lib/feedback/dialog"
import { useMessage } from "@/lib/feedback/message"
import { formatDateTime } from "@/lib/functions"
import type { ColumnDef } from "@tanstack/react-table"
import dayjs from "dayjs"

interface RowData {
accessKey: string
Expand Down Expand Up @@ -89,7 +89,7 @@ export default function AccessKeysPage() {
header: () => t("Expiration"),
cell: ({ row }) =>
row.original.expiration && row.original.expiration !== "9999-01-01T00:00:00Z"
? dayjs(row.original.expiration).format("YYYY-MM-DD HH:mm")
? formatDateTime(row.original.expiration)
: "-",
},
{
Expand Down Expand Up @@ -121,13 +121,13 @@ export default function AccessKeysPage() {
<div className="flex justify-center gap-2">
{canEditAccessKey ? (
<Button variant="outline" size="sm" onClick={() => openEditItem(row.original)}>
<RiEdit2Line className="size-4" />
<RiEdit2Line className="size-4" aria-hidden />
<span>{t("Edit")}</span>
</Button>
) : null}
{canDeleteAccessKey ? (
<Button variant="outline" size="sm" onClick={() => confirmDeleteSingle(row.original)}>
<RiDeleteBin5Line className="size-4" />
<RiDeleteBin5Line className="size-4" aria-hidden />
<span>{t("Delete")}</span>
</Button>
) : null}
Expand Down Expand Up @@ -222,13 +222,13 @@ export default function AccessKeysPage() {
/>
{selectedKeys.length > 0 && canBulkDeleteAccessKeys && (
<Button variant="outline" disabled={!selectedKeys.length} onClick={deleteSelected}>
<RiDeleteBin5Line className="size-4" />
<RiDeleteBin5Line className="size-4" aria-hidden />
<span>{t("Delete Selected")}</span>
</Button>
)}
{canCreateAccessKey ? (
<Button variant="outline" onClick={() => setNewItemVisible(true)}>
<RiAddLine className="size-4" />
<RiAddLine className="size-4" aria-hidden />
<span>{t("Add Access Key")}</span>
</Button>
) : null}
Expand Down
21 changes: 8 additions & 13 deletions app/(dashboard)/browser/content.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client"

import * as React from "react"
import Link from "next/link"
import { useRouter, useSearchParams } from "next/navigation"
import { useTranslation } from "react-i18next"
import { Page } from "@/components/page"
Expand Down Expand Up @@ -161,19 +162,13 @@ export function BrowserContent({ bucketName, keyPath = "", preview = false, prev
<Page>
<PageHeader>
<div className="flex items-center gap-4 min-w-[40vw]">
<h1
className="text-2xl font-bold cursor-pointer"
onClick={() => router.push(bucketPath())}
role="button"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault()
router.push(bucketPath())
}
}}
>
{bucketName}
<h1 className="min-w-0 text-2xl font-bold text-pretty">
<Link
href={bucketPath()}
className="truncate hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
>
{bucketName}
</Link>
</h1>
<ObjectPathLinks objectKey={keyPath} bucketName={bucketName} onClick={handlePathClick} />
</div>
Expand Down
23 changes: 11 additions & 12 deletions app/(dashboard)/browser/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@ import { useSystem } from "@/hooks/use-system"
import { usePermissions } from "@/hooks/use-permissions"
import { useDialog } from "@/lib/feedback/dialog"
import { useMessage } from "@/lib/feedback/message"
import { niceBytes } from "@/lib/functions"
import { formatDateTime, formatInteger, niceBytes } from "@/lib/functions"
import { normalizeDateToIso } from "@/lib/safe-date"
import { BrowserContent } from "./content"
import type { ColumnDef } from "@tanstack/react-table"
import dayjs from "dayjs"

interface BucketRow {
Name: string
Expand Down Expand Up @@ -208,17 +207,17 @@ function BrowserBucketsPage() {
cell: ({ row }) => (
<Link
href={`/browser?bucket=${encodeURIComponent(row.original.Name)}`}
className="flex items-center gap-2 text-primary hover:underline"
className="flex min-w-0 max-w-full items-center gap-2 text-primary hover:underline focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring/50"
>
<RiArchiveLine className="size-4" />
{row.original.Name}
<RiArchiveLine className="size-4 shrink-0" aria-hidden />
<span className="min-w-0 truncate">{row.original.Name}</span>
</Link>
),
},
{
header: () => t("Creation Date"),
accessorKey: "CreationDate",
cell: ({ row }) => dayjs(row.original.CreationDate).format("YYYY-MM-DD HH:mm:ss"),
cell: ({ row }) => formatDateTime(row.original.CreationDate),
},
]

Expand All @@ -228,7 +227,7 @@ function BrowserBucketsPage() {
accessorKey: "Count",
cell: ({ row }) =>
typeof row.original.Count === "number" ? (
row.original.Count.toLocaleString()
formatInteger(row.original.Count)
) : usageLoading ? (
<Spinner className="size-3 text-muted-foreground" />
) : (
Expand All @@ -251,7 +250,7 @@ function BrowserBucketsPage() {
cell: ({ row }) => {
if (typeof row.original.IsPublic === "boolean") {
return row.original.IsPublic ? (
<span className="text-red-600 dark:text-red-400">{t("Public")}</span>
<span className="text-destructive">{t("Public")}</span>
) : (
<span className="text-muted-foreground">{t("Private")}</span>
)
Expand All @@ -272,12 +271,12 @@ function BrowserBucketsPage() {
size="sm"
onClick={() => router.push(`/buckets?bucket=${encodeURIComponent(row.original.Name)}`)}
>
<RiSettings5Line className="size-4" />
<RiSettings5Line className="size-4" aria-hidden />
<span>{t("Settings")}</span>
</Button>
{canCapability("bucket.delete", { bucket: row.original.Name }) ? (
<Button variant="outline" size="sm" onClick={() => confirmDelete(row.original)}>
<RiDeleteBin5Line className="size-4" />
<RiDeleteBin5Line className="size-4" aria-hidden />
<span>{t("Delete")}</span>
</Button>
) : null}
Expand Down Expand Up @@ -343,12 +342,12 @@ function BrowserBucketsPage() {
/>
{canCreateBucket ? (
<Button variant="outline" onClick={() => setFormVisible(true)}>
<RiAddLine className="size-4" />
<RiAddLine className="size-4" aria-hidden />
<span>{t("Create Bucket")}</span>
</Button>
) : null}
<Button variant="outline" onClick={() => fetchBuckets({ force: true })}>
<RiRefreshLine className="size-4" />
<RiRefreshLine className="size-4" aria-hidden />
<span>{t("Refresh")}</span>
</Button>
</>
Expand Down
2 changes: 1 addition & 1 deletion app/(dashboard)/buckets/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default function BucketSettingsPage() {
<Page>
<PageHeader>
<h1 className="text-2xl font-bold">
{t("Bucket")}: {bucketName || "..."}
{t("Bucket")}: {bucketName || ""}
</h1>
</PageHeader>

Expand Down
2 changes: 1 addition & 1 deletion app/(dashboard)/events/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function EventsPage() {
<PageHeader
actions={
<Button variant="outline" nativeButton={false} render={<Link href="/events" />}>
<RiArrowLeftLine className="size-4" />
<RiArrowLeftLine className="size-4" aria-hidden />
<span>{t("Buckets")}</span>
</Button>
}
Expand Down
Loading
Loading