Open Brain documents from their title
Clicking a document's title fetches the original file from the engine: viewable formats open in a new tab, the rest (or a blocked tab) download under the original name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useRef, useState, type ReactNode } from 'react'
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import {
|
||||
answerVersion, buildKnowledge, deleteDocument, knowledgeDetail, listDocuments, NEEDS_ANSWER, supportedExtensions, uploadDocument,
|
||||
answerVersion, buildKnowledge, deleteDocument, documentFile, knowledgeDetail, listDocuments, NEEDS_ANSWER, supportedExtensions, uploadDocument,
|
||||
type Source,
|
||||
} from '../api/engine'
|
||||
import { Icon } from '../components/Icon'
|
||||
@@ -154,7 +154,7 @@ function DocumentRow({ doc }: { doc: Source }) {
|
||||
<div className="result-row">
|
||||
<span className={`file-icon ${doc.format.toLowerCase()}`}>{doc.format.slice(0, 4)}</span>
|
||||
<div style={{ minWidth: 0, flex: 1 }}>
|
||||
<b>{doc.title}</b>
|
||||
<OpenButton doc={doc} />
|
||||
<div><small>{new Date(doc.createdAt).toLocaleDateString(locale())}</small></div>
|
||||
{phase === 'working' && <Progress doc={doc} />}
|
||||
{(phase === 'answer' || phase === 'failed') && <KnowledgeAction doc={doc} />}
|
||||
@@ -165,6 +165,36 @@ function DocumentRow({ doc }: { doc: Source }) {
|
||||
)
|
||||
}
|
||||
|
||||
// Formats a browser can show in a tab; anything else is saved under its original name.
|
||||
const VIEWABLE = new Set(['pdf', 'png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'txt', 'md', 'csv', 'mp3', 'wav', 'm4a', 'ogg', 'mp4', 'webm', 'mov'])
|
||||
|
||||
function OpenButton({ doc }: { doc: Source }) {
|
||||
const [busy, setBusy] = useState(false)
|
||||
async function open() {
|
||||
const inTab = VIEWABLE.has(doc.format.toLowerCase())
|
||||
// Opened before the fetch: a tab opened after an await counts as a popup and is blocked.
|
||||
const tab = inTab ? window.open('', '_blank') : null
|
||||
setBusy(true)
|
||||
try {
|
||||
const url = URL.createObjectURL(await documentFile(doc.docId))
|
||||
if (tab) tab.location.href = url
|
||||
// Not viewable, or the tab was blocked: save it instead of doing nothing.
|
||||
else Object.assign(document.createElement('a'), { href: url, download: doc.originalName }).click()
|
||||
setTimeout(() => URL.revokeObjectURL(url), 60_000)
|
||||
} catch (e) {
|
||||
tab?.close()
|
||||
toast((e as Error).message, { error: true })
|
||||
} finally {
|
||||
setBusy(false)
|
||||
}
|
||||
}
|
||||
return (
|
||||
<button className="doc-title" disabled={busy} title={t('brain.open', { name: doc.originalName })} onClick={open}>
|
||||
{doc.title}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
function StatusBadge({ doc, phase }: { doc: Source; phase: Phase }) {
|
||||
const label = {
|
||||
ready: t('brain.statusReady'),
|
||||
|
||||
Reference in New Issue
Block a user