mirror of
https://github.com/rustfs/console.git
synced 2026-11-02 22:02:07 +08:00
116 lines
3.9 KiB
TypeScript
116 lines
3.9 KiB
TypeScript
"use client"
|
|
|
|
import * as React from "react"
|
|
import { useTranslation } from "react-i18next"
|
|
import { RiDownloadLine, RiErrorWarningLine } from "@remixicon/react"
|
|
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"
|
|
import { Button } from "@/components/ui/button"
|
|
import { Field, FieldContent, FieldLabel } from "@/components/ui/field"
|
|
import { CopyInput } from "@/components/copy-input"
|
|
import { download } from "@/lib/export-file"
|
|
|
|
export interface CredentialsData {
|
|
credentials?: { accessKey?: string; secretKey?: string }
|
|
url?: string
|
|
}
|
|
|
|
interface UserNoticeProps {
|
|
open: boolean
|
|
onOpenChange: (open: boolean) => void
|
|
data?: CredentialsData | null
|
|
onClose?: () => void
|
|
title?: string
|
|
}
|
|
|
|
export function UserNotice({ open, onOpenChange, data, onClose, title }: UserNoticeProps) {
|
|
const { t } = useTranslation()
|
|
const accessKey = data?.credentials?.accessKey ?? ""
|
|
const secretKey = data?.credentials?.secretKey ?? ""
|
|
const url = data?.url ?? ""
|
|
const hasCredentials = Boolean(accessKey && secretKey)
|
|
|
|
const closeModal = React.useCallback(() => {
|
|
onOpenChange(false)
|
|
onClose?.()
|
|
}, [onOpenChange, onClose])
|
|
|
|
const exportFile = React.useCallback(() => {
|
|
if (!accessKey || !secretKey) return
|
|
download(
|
|
"credentials.json",
|
|
JSON.stringify({
|
|
url,
|
|
accessKey,
|
|
secretKey,
|
|
api: "s3v4",
|
|
path: "auto",
|
|
}),
|
|
)
|
|
closeModal()
|
|
}, [url, accessKey, secretKey, closeModal])
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={() => undefined} disablePointerDismissal>
|
|
<DialogContent
|
|
className="max-h-[min(90dvh,40rem)] grid-rows-[auto_minmax(0,1fr)_auto] gap-0 overflow-hidden p-0 sm:max-w-md"
|
|
showCloseButton={false}
|
|
>
|
|
<DialogHeader className="border-b px-4 py-3">
|
|
<DialogTitle>{title ?? t("New user has been created")}</DialogTitle>
|
|
</DialogHeader>
|
|
|
|
<div className="min-h-0 space-y-4 overflow-y-auto overscroll-contain p-4">
|
|
<div className="flex gap-3 border bg-muted/30 p-3" role="note">
|
|
<RiErrorWarningLine className="mt-0.5 size-4 shrink-0 text-foreground" aria-hidden />
|
|
<div className="min-w-0 space-y-1">
|
|
<p className="text-sm font-medium">{t("Warning")}</p>
|
|
<p className="text-sm text-muted-foreground">
|
|
{t("The secret key is shown only once. Copy or export it before closing.")}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<Field>
|
|
<FieldLabel htmlFor="created-access-key">{t("Access Key")}</FieldLabel>
|
|
<FieldContent>
|
|
<CopyInput
|
|
id="created-access-key"
|
|
value={accessKey}
|
|
readOnly
|
|
copyIcon
|
|
copyLabel={`${t("Copy")} ${t("Access Key")}`}
|
|
aria-label={t("Access Key")}
|
|
className="w-full"
|
|
/>
|
|
</FieldContent>
|
|
</Field>
|
|
<Field>
|
|
<FieldLabel htmlFor="created-secret-key">{t("Secret Key")}</FieldLabel>
|
|
<FieldContent>
|
|
<CopyInput
|
|
id="created-secret-key"
|
|
value={secretKey}
|
|
readOnly
|
|
copyIcon
|
|
copyLabel={`${t("Copy")} ${t("Secret Key")}`}
|
|
aria-label={t("Secret Key")}
|
|
className="w-full"
|
|
/>
|
|
</FieldContent>
|
|
</Field>
|
|
</div>
|
|
|
|
<DialogFooter className="border-t bg-muted/20 px-4 py-3">
|
|
<Button type="button" variant="outline" onClick={closeModal}>
|
|
{t("Close")}
|
|
</Button>
|
|
<Button type="button" variant="default" onClick={exportFile} disabled={!hasCredentials}>
|
|
<RiDownloadLine className="size-4" aria-hidden />
|
|
{t("Download")}
|
|
</Button>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
}
|