feat: allow copying object name when previewing (#83)

* feat: 添加复制对象名称功能

* fix: fix typescript build errors
This commit is contained in:
Dacong-wu
2026-03-19 12:14:16 +08:00
committed by GitHub
parent f65732a77d
commit 712a1ec796
2 changed files with 52 additions and 6 deletions
+48
View File
@@ -0,0 +1,48 @@
"use client"
import * as React from "react"
import { useTranslation } from "react-i18next"
import { RiFileCopyLine } from "@remixicon/react"
import { Button } from "@/components/ui/button"
import { copyToClipboard } from "@/lib/clipboard"
import { useMessage } from "@/lib/feedback/message"
import { cn } from "@/lib/utils"
export function CopyButton({ value = "", iconOnly = false }) {
const { t } = useTranslation()
const message = useMessage()
const handleCopy = async (e: React.MouseEvent) => {
// 阻止事件冒泡,防止在表格或卡片中使用时触发父级点击事件
e.stopPropagation()
if (!value) return
try {
await copyToClipboard(value)
message.success(t("Copy Success"))
} catch {
message.error(t("Copy Failed"))
}
}
return (
<Button
type="button"
variant={iconOnly ? "ghost" : "default"}
size={iconOnly ? "sm" : "default"}
className={cn(iconOnly && "shrink-0 outline h-8 w-8 p-0")}
title={t("Copy")}
onClick={handleCopy}
>
{iconOnly ? (
<>
<RiFileCopyLine className="size-[18px]" />
<span className="sr-only">{t("Copy")}</span>
</>
) : (
t("Copy")
)}
</Button>
)
}
+4 -6
View File
@@ -25,6 +25,7 @@ import { ObjectPreviewModal } from "@/components/object/preview-modal"
import { GetObjectCommand, HeadObjectCommand } from "@aws-sdk/client-s3"
import { getSignedUrl } from "@aws-sdk/s3-request-presigner"
import { useS3 } from "@/contexts/s3-context"
import { CopyButton } from "@/components/copy-button"
const ONE_WEEK_SECONDS = 7 * 24 * 60 * 60
@@ -465,9 +466,10 @@ export function ObjectInfo({
<ItemContent className="min-w-0 space-y-3 text-sm overflow-hidden">
<div className="flex items-center justify-between gap-3 min-w-0">
<span className="font-medium text-muted-foreground">{t("Object Name")}</span>
<span className="max-w-[60%] truncate text-right" title={String(object?.Key ?? "")}>
<span className="flex-1 truncate text-right" title={String(object?.Key ?? "")}>
{String(object?.Key ?? "")}
</span>
<CopyButton value={String(object?.Key ?? "")} iconOnly />
</div>
<div className="flex items-center justify-between gap-3 min-w-0">
<span className="font-medium text-muted-foreground">{t("Object Size")}</span>
@@ -721,11 +723,7 @@ export function ObjectInfo({
</DialogContent>
</Dialog>
<ObjectPreviewModal
show={showPreview}
onShowChange={handlePreviewShowChange}
object={previewObject ?? object}
/>
<ObjectPreviewModal show={showPreview} onShowChange={handlePreviewShowChange} object={previewObject ?? object} />
<ObjectVersions
bucketName={bucketName}
objectKey={(object?.Key as string) ?? ""}