feat: Unterstützung von asynchroner Dateneingabe für DocFullView Komponente

- DocFullView aktualisiert, um Daten als Uint8Array oder Promise<Uint8Array> zu akzeptieren
- Asynchrones Handling in useEffect hinzugefügt, um Daten vor der Erstellung der Objekt-URL aufzulösen
- Verbesserte Bereinigungslogik, um die Objekt-URL richtig zu widerrufen
- Geänderte Format-Prop ist nun erforderlich
This commit is contained in:
tekh 2025-07-16 15:26:51 +02:00
parent 8c7e18637a
commit 2adcc217af
2 changed files with 31 additions and 13 deletions

View File

@ -26,8 +26,8 @@ const getMimeType = (format: FileFormat): string => {
};
type DocFullViewProps = {
data: Uint8Array;
format?: FileFormat;
data: Uint8Array | Promise<Uint8Array>;
format: FileFormat;
open: boolean;
handleClose: () => void;
}
@ -46,16 +46,31 @@ export default function DocFullView({ data, format, open, handleClose }: DocFull
const [objectUrl, setObjectUrl] = useState<string | null>(null);
useEffect(() => {
if (!data || !format)
return undefined;
let isMounted = true;
let url: string | null = null;
const processData = async () => {
try {
const resolvedData = await data;
const mimeType = getMimeType(format);
const blob = new Blob([data], { type: mimeType });
const url = URL.createObjectURL(blob);
const blob = new Blob([resolvedData], { type: mimeType });
url = URL.createObjectURL(blob);
if (isMounted) {
setObjectUrl(url);
}
} catch (err) {
console.error('Data resolution error:', err);
}
};
processData();
return () => {
isMounted = false;
if (url) {
URL.revokeObjectURL(url);
}
};
}, [data, format]);

View File

@ -1,4 +1,4 @@
import { _documents } from "src/_mock"
import { _documents, _genFile } from "src/_mock"
export type FileFormat =
| 'pdf'
@ -37,13 +37,16 @@ export class Doc {
id!: number;
name!: string;
data!: Uint8Array;
addedWhen!: Date;
addedWho!: string;
changedWhen?: Date;
changedWho?: string;
attributes: Array<DocAttribute> = [];
get data(): Promise<Uint8Array> {
return Promise.resolve(_genFile(this.name)!);
}
getChangedInfo(separator: string = " | "): string | null {
const who = this.changedWho?.trim();
const when = this.changedWhen?.toLocaleDateString('de-DE');
@ -55,7 +58,7 @@ export class Doc {
return [who, when].filter(Boolean).join(separator);
}
get extension(): FileFormat | undefined {
get extension(): FileFormat {
const parts = this.name.split('.');
if (parts.length > 1 && parts[parts.length - 1].trim() !== '') {
const ext = parts[parts.length - 1].toLowerCase();
@ -63,7 +66,7 @@ export class Doc {
if (validExtensions.includes(ext as FileFormat))
return ext as FileFormat;
}
return undefined;
throw new Error(`Invalid or missing file extension in filename: "${this.name}". Supported extensions are: ${validExtensions.join(', ')}.`);
}
get iconSrc(): string {