u
This commit is contained in:
@@ -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 };
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user