feat(mcp): подготовить сервер и доступ к приёмке
This commit is contained in:
commit
bf3d50e1ff
3835 files changed
+537122
No files matched your search
@@ -0,0 +1,36 @@
|
||||
"use client"
|
||||
|
||||
import { useEffect, useRef, useState } from "react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { humanArtifactError, humanArtifactReceipt } from "@/shared/api/mcp-artifact"
|
||||
import type { McpApi } from "@/shared/api/mcp"
|
||||
|
||||
function ArtifactDownload({ api, receipt }: { api: McpApi; receipt: unknown }) {
|
||||
const [busy, setBusy] = useState(false), [error, setError] = useState(""), [saved, setSaved] = useState(false)
|
||||
const controller = useRef<AbortController | null>(null)
|
||||
useEffect(() => () => controller.current?.abort(), [])
|
||||
const download = async () => {
|
||||
if (controller.current) return
|
||||
const request = new AbortController()
|
||||
controller.current = request
|
||||
setBusy(true); setError(""); setSaved(false)
|
||||
try { await api.downloadArtifact(receipt, request.signal); if (!request.signal.aborted) setSaved(true) }
|
||||
catch (failure) { if (!request.signal.aborted) setError(humanArtifactError(failure)) }
|
||||
finally { if (!request.signal.aborted) setBusy(false); controller.current = null }
|
||||
}
|
||||
return <div className="flex flex-col items-start gap-2">
|
||||
<Button variant="outline" disabled={busy} aria-busy={busy} onClick={() => { void download() }}>{busy ? "Скачивание…" : "Скачать файл"}</Button>
|
||||
{error && <p role="alert" className="text-sm text-destructive">{error}</p>}
|
||||
<p role="status" aria-live="polite" className="text-xs text-muted-foreground">{busy ? "Получаем файл с проверкой доступа…" : saved ? "Файл передан браузеру для сохранения." : "Файл доступен владельцу через авторизацию портала. Срок хранения ограничен."}</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
export function ArtifactDownloads({ api, operation }: { api: McpApi; operation: Record<string, unknown> }) {
|
||||
if (operation.state !== "applied" || !Array.isArray(operation.artifactReceipts)) return null
|
||||
const receipts = [...new Map(operation.artifactReceipts.flatMap(value => {
|
||||
const receipt = humanArtifactReceipt(value)
|
||||
return receipt ? [[receipt.artifactId, value] as const] : []
|
||||
})).entries()]
|
||||
if (!receipts.length) return null
|
||||
return <div className="flex flex-col gap-3 rounded-md border p-3"><h3 className="text-sm font-medium">Файлы операции</h3>{receipts.map(([id, receipt]) => <ArtifactDownload key={id} api={api} receipt={receipt} />)}</div>
|
||||
}
|
||||
Reference in new issue
Block a user