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
13 changes: 13 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ A modern, responsive web management console for RustFS distributed file system,
### UI & Styling

- **[Tailwind CSS v4](https://tailwindcss.com/)** - Utility-first CSS framework
- **[shadcn/ui](https://ui.shadcn.com/)** - High-quality component library based on Radix UI
- **[shadcn/ui](https://ui.shadcn.com/)** - High-quality component library based on Base UI
- **[Remix Icon](https://remixicon.com/)** - Icon library
- **[next-themes](https://github.com/pacocoursey/next-themes)** - Theme switching support

Expand Down
2 changes: 1 addition & 1 deletion app/(dashboard)/_components/performance-server-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function PerformanceServerList({ servers, t }: { servers: ServerInfo[]; t
</span>
</CardHeader>
<CardContent>
<Accordion type="single" collapsible className="space-y-2">
<Accordion className="space-y-2">
{servers.map((server, index) => (
<AccordionItem key={server.endpoint ?? index} value={String(index)}>
<AccordionTrigger>
Expand Down
14 changes: 8 additions & 6 deletions app/(dashboard)/site-replication/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -354,12 +354,14 @@ export default function SiteReplicationPage() {

return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button type="button" variant="ghost" size="icon-sm" disabled={isBusy}>
<RiMore2Line className="size-4" aria-hidden />
<span className="sr-only">{t("Actions")}</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuTrigger
render={
<Button type="button" variant="ghost" size="icon-sm" disabled={isBusy}>
<RiMore2Line className="size-4" aria-hidden />
<span className="sr-only">{t("Actions")}</span>
</Button>
}
/>
<DropdownMenuContent align="end">
<DropdownMenuLabel>{peer.name || t("Peer site")}</DropdownMenuLabel>
{canManageSites ? (
Expand Down
24 changes: 14 additions & 10 deletions app/(dashboard)/sse/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -700,11 +700,13 @@ export default function SSEPage() {

{hasConfiguration && (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button size="sm" variant="outline">
{t("Advanced Actions")}
</Button>
</DropdownMenuTrigger>
<DropdownMenuTrigger
render={
<Button size="sm" variant="outline">
{t("Advanced Actions")}
</Button>
}
/>
<DropdownMenuContent align="end">
<DropdownMenuItem disabled={!isRunning || clearingCache} onClick={handleClearCache}>
{clearingCache ? t("Clearing cache...") : t("Clear Cache")}
Expand Down Expand Up @@ -1069,11 +1071,13 @@ export default function SSEPage() {
<TableCell>
<div className="flex justify-end">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button size="sm" variant="outline">
{t("Actions")}
</Button>
</DropdownMenuTrigger>
<DropdownMenuTrigger
render={
<Button size="sm" variant="outline">
{t("Actions")}
</Button>
}
/>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setSelectedKeyId(key.key_id)}>
{t("View Details")}
Expand Down
21 changes: 11 additions & 10 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-sans);
--font-mono: var(--font-geist-mono);
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
Expand Down Expand Up @@ -45,11 +43,11 @@
--radius-2xl: calc(var(--radius) + 8px);
--radius-3xl: calc(var(--radius) + 12px);
--radius-4xl: calc(var(--radius) + 16px);
--font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
--font-heading: ui-monospace, "SFMono-Regular", "SF Mono", Menlo, Consolas, monospace;
}

:root {
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
Expand All @@ -62,7 +60,7 @@
--muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.58 0.22 27);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
Expand All @@ -71,7 +69,7 @@
--chart-3: oklch(0.546 0.245 262.881);
--chart-4: oklch(0.488 0.243 264.376);
--chart-5: oklch(0.424 0.199 265.638);
--radius: 0;
--radius: 0.625rem;
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
Expand All @@ -80,8 +78,8 @@
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
--font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
--font-geist-mono: ui-monospace, "SFMono-Regular", "SF Mono", Menlo, Consolas, monospace;
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
}

.dark {
Expand All @@ -91,13 +89,13 @@
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.87 0 0);
--primary: oklch(0.922 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.371 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
Expand Down Expand Up @@ -125,6 +123,9 @@
body {
@apply bg-background text-foreground;
}
html {
@apply font-sans;
}
}

@keyframes fadeInWord {
Expand Down
2 changes: 1 addition & 1 deletion components.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "radix-lyra",
"style": "base-lyra",
"rsc": true,
"tsx": true,
"tailwind": {
Expand Down
8 changes: 2 additions & 6 deletions components/access-keys/edit-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,8 @@ export function AccessKeysEditItem({ open, onOpenChange, row, onSuccess }: Acces
}

return (
<Dialog open={open} onOpenChange={closeModal}>
<DialogContent
className="sm:max-w-6xl"
onPointerDownOutside={(e) => e.preventDefault()}
onInteractOutside={(e) => e.preventDefault()}
>
<Dialog open={open} onOpenChange={closeModal} disablePointerDismissal>
<DialogContent className="sm:max-w-6xl">
<DialogHeader>
<DialogTitle>{t("Edit Key")}</DialogTitle>
</DialogHeader>
Expand Down
8 changes: 2 additions & 6 deletions components/access-keys/new-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,8 @@ export function AccessKeysNewItem({ visible, onVisibleChange, onSuccess, onNotic
}

return (
<Dialog open={visible} onOpenChange={closeModal}>
<DialogContent
className={cn("sm:max-w-xl", !impliedPolicy && "sm:max-w-6xl")}
onPointerDownOutside={(e) => e.preventDefault()}
onInteractOutside={(e) => e.preventDefault()}
>
<Dialog open={visible} onOpenChange={closeModal} disablePointerDismissal>
<DialogContent className={cn("sm:max-w-xl", !impliedPolicy && "sm:max-w-6xl")}>
<DialogHeader>
<DialogTitle>{t("Create Key")}</DialogTitle>
</DialogHeader>
Expand Down
158 changes: 87 additions & 71 deletions components/app-sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,79 +170,95 @@ export function AppSidebar() {
{group.map((item) => (
<Collapsible
key={item.label}
asChild
defaultOpen={hasChildren(item) && isRouteActive(item)}
className="group/collapsible"
>
{hasChildren(item) ? (
<SidebarMenuItem>
<CollapsibleTrigger asChild>
<SidebarMenuButton
isActive={isRouteActive(item)}
tooltip={getLabel(item)}
className="gap-3"
>
<NavIcon name={item.icon} />
<span className="flex-1 truncate">{getLabel(item)}</span>
<RiArrowRightSLine className="size-4 shrink-0 transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" />
</SidebarMenuButton>
</CollapsibleTrigger>
<CollapsibleContent>
<SidebarMenuSub className="border-l-0 border-s rtl:-translate-x-px">
{item.children!.map((child) => (
<SidebarMenuSubItem key={child.label}>
{isExternal(child) ? (
<SidebarMenuSubButton asChild size="sm">
<a
href={normalizedTo(child)}
target="_blank"
rel="noopener noreferrer"
className="flex w-full items-center gap-2"
>
<NavIcon name={child.icon} />
<span className="truncate">{getLabel(child)}</span>
<RiExternalLinkLine className="ms-auto size-3 text-muted-foreground" />
</a>
</SidebarMenuSubButton>
) : (
<SidebarMenuSubButton asChild size="sm" isActive={isRouteActive(child)}>
<Link href={normalizedTo(child)} className="flex w-full items-center gap-2">
<NavIcon name={child.icon} />
<span className="truncate">{getLabel(child)}</span>
</Link>
</SidebarMenuSubButton>
)}
</SidebarMenuSubItem>
))}
</SidebarMenuSub>
</CollapsibleContent>
</SidebarMenuItem>
) : (
<SidebarMenuItem>
{isExternal(item) ? (
<SidebarMenuButton asChild tooltip={getLabel(item)}>
<a
href={normalizedTo(item)}
target="_blank"
rel="noopener noreferrer"
className="flex w-full items-center gap-3"
>
<NavIcon name={item.icon} />
<span className="flex-1 truncate">{getLabel(item)}</span>
<RiExternalLinkLine className="size-3.5 text-muted-foreground" />
</a>
</SidebarMenuButton>
) : (
<SidebarMenuButton asChild isActive={isRouteActive(item)} tooltip={getLabel(item)}>
<Link href={normalizedTo(item)} className="flex w-full items-center gap-3">
<NavIcon name={item.icon} />
<span className="flex-1 truncate">{getLabel(item)}</span>
</Link>
</SidebarMenuButton>
)}
</SidebarMenuItem>
)}
</Collapsible>
render={
hasChildren(item) ? (
<SidebarMenuItem>
<CollapsibleTrigger
render={
<SidebarMenuButton
isActive={isRouteActive(item)}
tooltip={getLabel(item)}
className="gap-3"
>
<NavIcon name={item.icon} />
<span className="flex-1 truncate">{getLabel(item)}</span>
<RiArrowRightSLine className="size-4 shrink-0 transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" />
</SidebarMenuButton>
}
/>
<CollapsibleContent>
<SidebarMenuSub className="border-l-0 border-s rtl:-translate-x-px">
{item.children!.map((child) => (
<SidebarMenuSubItem key={child.label}>
{isExternal(child) ? (
<SidebarMenuSubButton
size="sm"
render={
<a
href={normalizedTo(child)}
target="_blank"
rel="noopener noreferrer"
className="flex w-full items-center gap-2"
>
<NavIcon name={child.icon} />
<span className="truncate">{getLabel(child)}</span>
<RiExternalLinkLine className="ms-auto size-3 text-muted-foreground" />
</a>
}
/>
) : (
<SidebarMenuSubButton
size="sm"
isActive={isRouteActive(child)}
render={
<Link href={normalizedTo(child)} className="flex w-full items-center gap-2">
<NavIcon name={child.icon} />
<span className="truncate">{getLabel(child)}</span>
</Link>
}
/>
)}
</SidebarMenuSubItem>
))}
</SidebarMenuSub>
</CollapsibleContent>
</SidebarMenuItem>
) : (
<SidebarMenuItem>
{isExternal(item) ? (
<SidebarMenuButton
tooltip={getLabel(item)}
render={
<a
href={normalizedTo(item)}
target="_blank"
rel="noopener noreferrer"
className="flex w-full items-center gap-3"
>
<NavIcon name={item.icon} />
<span className="flex-1 truncate">{getLabel(item)}</span>
<RiExternalLinkLine className="size-3.5 text-muted-foreground" />
</a>
}
/>
) : (
<SidebarMenuButton
isActive={isRouteActive(item)}
tooltip={getLabel(item)}
render={
<Link href={normalizedTo(item)} className="flex w-full items-center gap-3">
<NavIcon name={item.icon} />
<span className="flex-1 truncate">{getLabel(item)}</span>
</Link>
}
/>
)}
</SidebarMenuItem>
)
}
/>
))}
</SidebarMenu>
</SidebarGroupContent>
Expand Down
4 changes: 2 additions & 2 deletions components/buckets/info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ export function BucketInfo({ bucketName }: BucketInfoProps) {
<Field>
<FieldLabel>{t("Encryption Type")}</FieldLabel>
<FieldContent>
<Select value={encryptFormType} onValueChange={setEncryptFormType}>
<Select value={encryptFormType} onValueChange={(value) => setEncryptFormType(value ?? "")}>
<SelectTrigger className="w-full">
<SelectValue placeholder={t("Please select encryption type")} />
</SelectTrigger>
Expand All @@ -818,7 +818,7 @@ export function BucketInfo({ bucketName }: BucketInfoProps) {
<Field>
<FieldLabel>KMS Key ID</FieldLabel>
<FieldContent>
<Select value={encryptFormKmsKeyId} onValueChange={setEncryptFormKmsKeyId}>
<Select value={encryptFormKmsKeyId} onValueChange={(value) => setEncryptFormKmsKeyId(value ?? "")}>
<SelectTrigger className="w-full">
<SelectValue placeholder={t("Please select KMS key")} />
</SelectTrigger>
Expand Down
Loading
Loading