This commit is contained in:
seb
2026-10-16 13:51:18 +02:00
parent d851c6e1e9
commit 764d6f850a
12 changed files with 2211 additions and 328 deletions

View File

@@ -184,15 +184,46 @@ function getMimeTypeFallback(category, filename) {
}
/**
* Trigger download of an attachment in the browser.
* @param {object} attachment
* Format bytes into human-readable kb size for data extraction pills (e.g. "2.4 kb" or "12 kb").
* @param {number} bytes
* @returns {string}
*/
export function downloadAttachment(attachment) {
if (!attachment) return;
const link = document.createElement('a');
link.href = attachment.dataUrl || (attachment.url ? attachment.url : '');
link.download = attachment.name || 'anhang';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
export function formatExtractionSize(bytes) {
const b = Number(bytes) || 0;
const kb = b / 1024;
if (kb < 1) {
return `${Math.max(0.1, kb).toFixed(1)} kb`;
}
return `${kb.toFixed(kb >= 10 ? 0 : 1)} kb`;
}
/**
* Parses extraction text blocks (e.g. `Text for Data Extraction:\n```\n...```\n` or `Text aus „...“:\n```\n...```\n`)
* from a message string, returning the extracted snippets as structured pills and the remaining text.
* @param {string} rawText
* @returns {{ extractions: Array<{ text: string, size: number, label: string }>, cleanText: string }}
*/
export function parseExtractionsFromText(rawText) {
if (typeof rawText !== 'string' || !rawText) {
return { extractions: [], cleanText: '' };
}
const extractionRegex = /(?:Text for Data Extraction|Text aus „[^“]+“):\s*```(?:\w+)?\n([\s\S]*?)```/g;
const extractions = [];
let match;
while ((match = extractionRegex.exec(rawText)) !== null) {
const content = (match[1] || '').trim();
if (content) {
const size = new Blob([content]).size;
extractions.push({
text: content,
size,
label: `Text for Data Extraction - ${formatExtractionSize(size)}`,
});
}
}
const cleanText = rawText.replace(extractionRegex, '').trim();
return { extractions, cleanText };
}

View File

@@ -9,6 +9,7 @@ import ChatBubbleOutlineRoundedIcon from '@mui/icons-material/ChatBubbleOutlineR
import DeleteOutlineOutlinedIcon from '@mui/icons-material/DeleteOutlineOutlined';
import { tileBaseSx, TILE_SIZE } from 'dashgui/tiles';
import SkeleHashImage from '../settings/SkeleHashImage';
import { enqueueSnackbar } from 'notistack';
import { generateTextThumbnail } from '../../utils/textThumbnail';
import chatAutomat from '../../automats/chatAutomat';
import {
@@ -79,20 +80,44 @@ export class Attachment extends PureComponent {
let textContent = attachment.text || '';
if (!textContent && (attachment.file instanceof Blob || attachment.file instanceof File)) {
try {
textContent = await attachment.file.text();
} catch (err) {
console.error('Fehler beim Lesen des Texts:', err);
if (attachment.file.size > 0) {
try {
textContent = await attachment.file.text();
} catch (err) {
console.error('Fehler beim Lesen des Texts:', err);
}
} else {
const docId = this.props.docId ?? attachment.manifestId;
const fileId = attachment.fileId ?? attachment.id;
const kind = this.props.kind || 'delivery';
const prefix = kind === 'delivery' ? 'delivery' : kind === 'quote' ? 'quote' : 'order';
if (docId != null && fileId != null) {
try {
const res = await fetch(`/api/${prefix}/${encodeURIComponent(docId)}/file/${encodeURIComponent(fileId)}`, {
credentials: 'include',
});
if (res.ok) {
textContent = await res.text();
}
} catch (fetchErr) {
console.error('Fehler beim Laden der Datei:', fetchErr);
}
}
}
}
const trimmed = (textContent || '').trim();
if (!trimmed) return;
if (!trimmed) {
enqueueSnackbar('Datei enthält keinen Text zum Erwähnen im Chat.', { variant: 'warning' });
return;
}
const title = attachment.name ? `Text aus „${attachment.name}“:` : 'Text:';
const quote = `${title}\n\`\`\`\n${trimmed}\n\`\`\``;
chatAutomat.actions.insertPrompt(quote);
const size = attachment.size || new Blob([trimmed]).size;
chatAutomat.actions.insertExtractionSnippet({
text: trimmed,
size,
});
enqueueSnackbar('Text im Chat erwähnt', { variant: 'success' });
};
handleDelete = (e) => {
@@ -265,6 +290,7 @@ export class Attachment extends PureComponent {
disabled={disabled}
onClick={this.handleRescan}
aria-label="Zu Text"
title="Zu Text"
sx={{
bgcolor: SCRIM_ACTION,
color: WHITE,
@@ -285,6 +311,7 @@ export class Attachment extends PureComponent {
disabled={disabled}
onClick={this.handleMentionInChat}
aria-label="Im Chat erwähnen"
title="Im Chat erwähnen"
sx={{
bgcolor: SCRIM_ACTION,
color: WHITE,
@@ -304,6 +331,7 @@ export class Attachment extends PureComponent {
disabled={disabled}
onClick={this.handleDelete}
aria-label="Löschen"
title="Löschen"
sx={{
bgcolor: SCRIM_ACTION,
color: WHITE,