Implementiere PDF-Highlighting für Kennzahlen (Ticket #31)
parent
76a060a563
commit
0dd3785fdd
|
|
@ -0,0 +1,30 @@
|
|||
import { Box } from '@mui/material';
|
||||
|
||||
type Props = {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
type: 'all' | 'selected';
|
||||
};
|
||||
|
||||
// Eine farbige Box, die über dem PDF angezeigt wird
|
||||
export default function HighlightOverlay({ x, y, width, height, type }: Props) {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
top: y,
|
||||
left: x,
|
||||
width: width,
|
||||
height: height,
|
||||
backgroundColor: type === 'all' ? 'rgba(255, 255, 0, 0.4)' : 'rgba(255, 165, 0, 0.4)',
|
||||
border: '1px solid',
|
||||
borderColor: type === 'all' ? '#FFD700' : '#FF8C00',
|
||||
borderRadius: '2px',
|
||||
pointerEvents: 'none',
|
||||
zIndex: 10,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import {
|
|||
import SearchIcon from '@mui/icons-material/Search';
|
||||
import EditIcon from '@mui/icons-material/Edit';
|
||||
import { useState } from 'react';
|
||||
import { Dispatch, SetStateAction } from 'react';
|
||||
|
||||
|
||||
// Beispiel-Daten
|
||||
|
|
@ -19,7 +20,12 @@ import {
|
|||
];
|
||||
|
||||
// React-Komponente
|
||||
export default function KennzahlenTable() {
|
||||
|
||||
type Props = {
|
||||
setSelectedLabel: Dispatch<SetStateAction<string | null>>;
|
||||
};
|
||||
export default function KennzahlenTable({ setSelectedLabel }: Props) {
|
||||
|
||||
// Zustand für bearbeitbare Daten
|
||||
const [rows, setRows] = useState(exampleData);
|
||||
|
||||
|
|
@ -67,7 +73,13 @@ import {
|
|||
else if (row.status === 'warning') borderColor = '#f6ed48';
|
||||
|
||||
return (
|
||||
<TableRow key={index}>
|
||||
<TableRow
|
||||
key={index}
|
||||
onClick={() => setSelectedLabel(row.label)}
|
||||
hover
|
||||
sx={{ cursor: 'pointer' }}
|
||||
>
|
||||
|
||||
{/* Kennzahl */}
|
||||
<TableCell>{row.label}</TableCell>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
// Beispielhafte Highlight-Daten mit Labels
|
||||
export const highlightData = [
|
||||
{
|
||||
label: 'Risikoprofil',
|
||||
page: 1,
|
||||
x: 100,
|
||||
y: 200,
|
||||
width: 120,
|
||||
height: 20,
|
||||
type: 'all', // gelb
|
||||
},
|
||||
{
|
||||
label: 'Risikoprofil',
|
||||
page: 1,
|
||||
x: 100,
|
||||
y: 300,
|
||||
width: 140,
|
||||
height: 25,
|
||||
type: 'selected', // orange (nur wenn ausgewählt)
|
||||
}
|
||||
];
|
||||
|
|
@ -6,13 +6,22 @@ import { Box, IconButton } from '@mui/material';
|
|||
import ArrowCircleLeftIcon from '@mui/icons-material/ArrowCircleLeft';
|
||||
import ArrowCircleRightIcon from '@mui/icons-material/ArrowCircleRight';
|
||||
import testPDF from '/example.pdf';
|
||||
import HighlightOverlay from './HighlightOverlay';
|
||||
import { highlightData } from './highlightData';
|
||||
|
||||
|
||||
|
||||
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
|
||||
"pdfjs-dist/build/pdf.worker.min.mjs",
|
||||
import.meta.url,
|
||||
).toString();
|
||||
|
||||
export default function PDFViewer() {
|
||||
type Props = {
|
||||
selectedLabel: string | null;
|
||||
};
|
||||
|
||||
export default function PDFViewer({ selectedLabel }: Props) {
|
||||
const [numPages, setNumPages] = useState<number | null>(null);
|
||||
const [pageNumber, setPageNumber] = useState(1);
|
||||
const [containerWidth, setContainerWidth] = useState<number | null>(null);
|
||||
|
|
@ -56,17 +65,34 @@ export default function PDFViewer() {
|
|||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Document file={testPDF}
|
||||
onLoadSuccess={onDocumentLoadSuccess}
|
||||
onLoadError={(error) => console.error('Es gab ein Fehler beim Laden des PDFs:', error)}
|
||||
onSourceError={(error) => console.error('Ungültige PDF:', error)}>
|
||||
{containerWidth && (
|
||||
<Page
|
||||
pageNumber={pageNumber}
|
||||
width={containerWidth * 0.8}
|
||||
<Document
|
||||
file={testPDF}
|
||||
onLoadSuccess={onDocumentLoadSuccess}
|
||||
onLoadError={(error) => console.error('Fehler beim Laden:', error)}
|
||||
onSourceError={(error) => console.error('Ungültige PDF:', error)}
|
||||
>
|
||||
{containerWidth && (
|
||||
<Box position="relative">
|
||||
<Page
|
||||
pageNumber={pageNumber}
|
||||
width={containerWidth * 0.8}
|
||||
/>
|
||||
|
||||
{/* Highlights einfügen */}
|
||||
{highlightData
|
||||
.filter((h) => h.page === pageNumber)
|
||||
.map((h, idx) => (
|
||||
<HighlightOverlay
|
||||
key={idx}
|
||||
{...h}
|
||||
type={selectedLabel && h.label === selectedLabel ? 'selected' : 'all'}
|
||||
/>
|
||||
)}
|
||||
|
||||
))}
|
||||
</Box>
|
||||
)}
|
||||
</Document>
|
||||
|
||||
</Box>
|
||||
<Box
|
||||
mt={2}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import {createFileRoute, useNavigate} from '@tanstack/react-router';
|
|||
import PDFViewer from '../components/pdfViewer';
|
||||
import ContentPasteIcon from '@mui/icons-material/ContentPaste';
|
||||
import KennzahlenTable from "../components/KennzahlenTable";
|
||||
import { useState } from 'react';
|
||||
|
||||
|
||||
export const Route = createFileRoute('/extractedResult')({
|
||||
|
|
@ -10,6 +11,7 @@ export const Route = createFileRoute('/extractedResult')({
|
|||
});
|
||||
|
||||
function ExtractedResultsPage() {
|
||||
const [selectedLabel, setSelectedLabel] = useState<string | null>(null);
|
||||
const navigate = useNavigate();
|
||||
const status: 'green' | 'yellow' | 'red' = 'red';
|
||||
|
||||
|
|
@ -57,7 +59,8 @@ function ExtractedResultsPage() {
|
|||
overflow: 'auto', // Scrollen falls Tabelle zu lang
|
||||
}}
|
||||
>
|
||||
<KennzahlenTable />
|
||||
<KennzahlenTable setSelectedLabel={setSelectedLabel} />
|
||||
|
||||
</Paper>
|
||||
|
||||
<Box
|
||||
|
|
@ -78,7 +81,7 @@ function ExtractedResultsPage() {
|
|||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<PDFViewer/>
|
||||
<PDFViewer selectedLabel={selectedLabel} />
|
||||
</Paper>
|
||||
<Box mt={2} display="flex" justifyContent="flex-end" gap={2}>
|
||||
<Button
|
||||
|
|
|
|||
Loading…
Reference in New Issue