From d8342304c1873cb9338da6ce3faf3bbce05409ea Mon Sep 17 00:00:00 2001 From: s8613 Date: Fri, 13 Jun 2025 12:31:44 +0200 Subject: [PATCH 1/3] Added style and function to the details kpi page. Fixed paging bug that when clicking on page, page no longer changes with arrows. Fixed styling of the table. --- .../src/components/KennzahlenTable.tsx | 190 +++++---- project/frontend/src/components/pdfViewer.tsx | 30 +- .../src/routes/extractedResult.$pitchBook.tsx | 31 +- .../extractedResult_.$pitchBook.$kpi.tsx | 366 +++++++++++++++++- 4 files changed, 507 insertions(+), 110 deletions(-) diff --git a/project/frontend/src/components/KennzahlenTable.tsx b/project/frontend/src/components/KennzahlenTable.tsx index 3f2fe75..acc8d47 100644 --- a/project/frontend/src/components/KennzahlenTable.tsx +++ b/project/frontend/src/components/KennzahlenTable.tsx @@ -3,7 +3,6 @@ import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline"; import SearchIcon from "@mui/icons-material/Search"; import { Box, - IconButton, Link, Paper, Table, @@ -13,6 +12,7 @@ import { TableHead, TableRow, TextField, + Tooltip, } from "@mui/material"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { useNavigate } from "@tanstack/react-router"; @@ -32,7 +32,7 @@ const SETTINGS = [ interface KennzahlenTableProps { onPageClick?: (page: number) => void; - pdfId: string; // Neue Prop für die PDF-ID + pdfId: string; data: { [key: string]: { label: string; @@ -44,7 +44,6 @@ interface KennzahlenTableProps { }; } -// React-Komponente export default function KennzahlenTable({ onPageClick, data, @@ -121,6 +120,16 @@ export default function KennzahlenTable({ } }; + const handleNavigateToDetail = (settingName: string) => { + navigate({ + to: "/extractedResult/$pitchBook/$kpi", + params: { + pitchBook: pdfId, + kpi: settingName, + }, + }); + }; + return ( @@ -132,7 +141,7 @@ export default function KennzahlenTable({ Wert - + Seite @@ -147,89 +156,122 @@ export default function KennzahlenTable({ })) .map((row) => { let borderColor = "transparent"; - if ( - row.setting.mandatory && + const hasMultipleValues = row.extractedValues.length > 1; + const hasNoValue = row.setting.mandatory && (row.extractedValues.length === 0 || - row.extractedValues.at(0)?.entity === "") - ) + row.extractedValues.at(0)?.entity === ""); + + if (hasNoValue) { borderColor = "red"; - else if (row.extractedValues.length > 1) borderColor = "#f6ed48"; + } else if (hasMultipleValues) { + borderColor = "#f6ed48"; + } return ( {row.setting.name} - startEditing( - row.extractedValues.at(0)?.entity || "", - row.setting.name, - ) - } + onClick={() => { + // Only allow inline editing for non-multiple value cells + if (!hasMultipleValues) { + startEditing( + row.extractedValues.at(0)?.entity || "", + row.setting.name, + ); + } else { + // Navigate to detail page for multiple values + handleNavigateToDetail(row.setting.name); + } + }} > - + {hasMultipleValues ? ( + + Problem
+ Mehrere Werte für die Kennzahl gefunden. + + } + placement="bottom" + arrow + > + + + + {row.extractedValues.at(0)?.entity || "—"} + + + + +
+ ) : ( - {row.setting.mandatory && - row.extractedValues.length === 0 && ( + + {hasNoValue && ( )} - {editingIndex === row.setting.name ? ( - setEditValue(e.target.value)} - onKeyDown={(e) => - handleKeyPress(e, row.setting.name) - } - onBlur={() => handleSave(row.setting.name)} - autoFocus - size="small" - fullWidth - variant="standard" - sx={{ margin: "-8px 0" }} - /> - ) : ( - - {row.extractedValues.at(0)?.entity || "—"} - - )} - - {row.extractedValues.length > 1 && ( - - navigate({ - to: "/extractedResult/$pitchBook/$kpi", - params: { - pitchBook: pdfId, - kpi: row.setting.name, - }, - }) - } - > - - - )} - {row.extractedValues.length <= 1 && ( + {editingIndex === row.setting.name ? ( + setEditValue(e.target.value)} + onKeyDown={(e) => + handleKeyPress(e, row.setting.name) + } + onBlur={() => handleSave(row.setting.name)} + autoFocus + size="small" + fullWidth + variant="standard" + sx={{ margin: "-8px 0" }} + /> + ) : ( + + {row.extractedValues.at(0)?.entity || "—"} + + )} + - )} -
+ + )}
- + @@ -262,4 +304,4 @@ export default function KennzahlenTable({
); -} +} \ No newline at end of file diff --git a/project/frontend/src/components/pdfViewer.tsx b/project/frontend/src/components/pdfViewer.tsx index a24fa9f..5abc1f4 100644 --- a/project/frontend/src/components/pdfViewer.tsx +++ b/project/frontend/src/components/pdfViewer.tsx @@ -10,11 +10,13 @@ import { socket } from "../socket"; interface PDFViewerProps { pitchBookId: string; currentPage?: number; + onPageChange?: (page: number) => void; } export default function PDFViewer({ pitchBookId, currentPage, + onPageChange, }: PDFViewerProps) { const [numPages, setNumPages] = useState(null); const [pageNumber, setPageNumber] = useState(currentPage || 1); @@ -42,7 +44,7 @@ export default function PDFViewer({ if (currentPage && currentPage !== pageNumber) { setPageNumber(currentPage); } - }, [currentPage, pageNumber]); + }, [currentPage]); useEffect(() => { const handleProgress = (data: { id: number; progress: number }) => { @@ -58,6 +60,11 @@ export default function PDFViewer({ }; }, [pitchBookId]); + const handlePageChange = (newPage: number) => { + setPageNumber(newPage); + onPageChange?.(newPage); + }; + return ( console.error("Ungültige PDF:", error)} > {containerWidth && ( - + )} setPageNumber((p) => p - 1)} + onClick={() => handlePageChange(pageNumber - 1)} > - {pageNumber} / {numPages} - + {pageNumber} / {numPages} + = (numPages || 1)} - onClick={() => setPageNumber((p) => p + 1)} + onClick={() => handlePageChange(pageNumber + 1)} > ); -} +} \ No newline at end of file diff --git a/project/frontend/src/routes/extractedResult.$pitchBook.tsx b/project/frontend/src/routes/extractedResult.$pitchBook.tsx index db7c47e..cf5a860 100644 --- a/project/frontend/src/routes/extractedResult.$pitchBook.tsx +++ b/project/frontend/src/routes/extractedResult.$pitchBook.tsx @@ -41,8 +41,7 @@ function ExtractedResultsPage() { }} /> - Kennzahlen extrahiert aus:
- FONDSNAME: TODO + Extrahierte Kennzahlen
- + - + + + + + + + + Achtung + + + + Alle vorgenommenen Änderungen werden verworfen. + + + + + + + + ); -} +} \ No newline at end of file From b3805b2afe79ca9dc7765a031a5e17c9b2fdb63d Mon Sep 17 00:00:00 2001 From: s8613 Date: Fri, 13 Jun 2025 12:50:27 +0200 Subject: [PATCH 2/3] Fixed multiple values being the same logic error. --- .../src/routes/extractedResult.$pitchBook.tsx | 5 +-- .../extractedResult_.$pitchBook.$kpi.tsx | 40 ++++++++++--------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/project/frontend/src/routes/extractedResult.$pitchBook.tsx b/project/frontend/src/routes/extractedResult.$pitchBook.tsx index cf5a860..c2d57f7 100644 --- a/project/frontend/src/routes/extractedResult.$pitchBook.tsx +++ b/project/frontend/src/routes/extractedResult.$pitchBook.tsx @@ -50,7 +50,7 @@ function ExtractedResultsPage() { sx={{ width: "100vw", maxWidth: "100%", - height: "80vh", + height: "85vh", mt: 4, }} > @@ -76,10 +76,9 @@ function ExtractedResultsPage() { display="flex" flexDirection="column" justifyContent="space-between" - gap={5} + gap={3} sx={{ width: "55%", - height: "100%", maxHeight: "95%" }} > diff --git a/project/frontend/src/routes/extractedResult_.$pitchBook.$kpi.tsx b/project/frontend/src/routes/extractedResult_.$pitchBook.$kpi.tsx index f3e5dbd..ccf34b8 100644 --- a/project/frontend/src/routes/extractedResult_.$pitchBook.$kpi.tsx +++ b/project/frontend/src/routes/extractedResult_.$pitchBook.$kpi.tsx @@ -41,13 +41,13 @@ function ExtractedResultsPage() { } = useSuspenseQuery(kpiQueryOptions(pitchBook)); const kpiValues = kpiData[kpi.toUpperCase()] || []; - - const [selectedValue, setSelectedValue] = useState(kpiValues[0]?.entity || ''); + const [selectedIndex, setSelectedIndex] = useState(0); const [currentPage, setCurrentPage] = useState(kpiValues[0]?.page || 1); const [showConfirmDialog, setShowConfirmDialog] = useState(false); const [hasChanges, setHasChanges] = useState(false); const [customValue, setCustomValue] = useState(''); const originalValue = kpiValues[0]?.entity || ''; + const selectedValue = selectedIndex === -1 ? customValue : (kpiValues[selectedIndex]?.entity || ''); useEffect(() => { setHasChanges(selectedValue !== originalValue); @@ -78,8 +78,11 @@ function ExtractedResultsPage() { const handleRadioChange = (event: React.ChangeEvent) => { const value = event.target.value; - setSelectedValue(value); - if (value !== 'custom') { + if (value === 'custom') { + setSelectedIndex(-1); + } else { + const index = parseInt(value); + setSelectedIndex(index); setCustomValue(''); } }; @@ -87,7 +90,12 @@ function ExtractedResultsPage() { const handleCustomValueChange = (event: React.ChangeEvent) => { const value = event.target.value; setCustomValue(value); - setSelectedValue(value); + setSelectedIndex(-1); + }; + + const handleRowClick = (index: number) => { + setSelectedIndex(index); + setCustomValue(''); }; const handleBackClick = () => { @@ -134,7 +142,7 @@ function ExtractedResultsPage() { sx={{ width: "100vw", maxWidth: "100%", - height: "80vh", + height: "85vh", mt: 4, }} > @@ -170,7 +178,7 @@ function ExtractedResultsPage() { '&:hover': { backgroundColor: '#f9f9f9' }, cursor: 'pointer' }} - onClick={() => setSelectedValue(item.entity)} + onClick={() => handleRowClick(index)} > { - if (customValue) { - setSelectedValue(customValue); - } + setSelectedIndex(-1); }} > Überprüfung Annehmen From 082317318aac36893cdb5fa3978b0a92eabad25a Mon Sep 17 00:00:00 2001 From: Jaronim Pracht Date: Fri, 13 Jun 2025 21:29:34 +0200 Subject: [PATCH 3/3] Update ExtractedResultsPage to fetch and pass settings to KennzahlenTable --- .../frontend/src/components/ConfigTable.tsx | 615 +++++++++--------- .../src/components/KennzahlenTable.tsx | 38 +- .../src/routes/extractedResult.$pitchBook.tsx | 23 +- project/frontend/src/util/api.ts | 14 +- project/frontend/src/util/query.ts | 8 +- 5 files changed, 377 insertions(+), 321 deletions(-) diff --git a/project/frontend/src/components/ConfigTable.tsx b/project/frontend/src/components/ConfigTable.tsx index 017d113..74675d7 100644 --- a/project/frontend/src/components/ConfigTable.tsx +++ b/project/frontend/src/components/ConfigTable.tsx @@ -1,322 +1,353 @@ -import { Box, Tooltip, CircularProgress, Typography } from "@mui/material"; import DragIndicatorIcon from "@mui/icons-material/DragIndicator"; -import { useEffect, useState } from "react"; +import { Box, CircularProgress, Tooltip, Typography } from "@mui/material"; import { useNavigate } from "@tanstack/react-router"; +import { useEffect, useState } from "react"; import type { Kennzahl } from "../types/kpi"; import { getDisplayType } from "../types/kpi"; +import { fetchKennzahlen as fetchK } from "../util/api"; export function ConfigTable() { - const navigate = useNavigate(); - const [kennzahlen, setKennzahlen] = useState([]); - const [draggedItem, setDraggedItem] = useState(null); - const [isUpdatingPositions, setIsUpdatingPositions] = useState(false); - const [loading, setLoading] = useState(true); + const navigate = useNavigate(); + const [kennzahlen, setKennzahlen] = useState([]); + const [draggedItem, setDraggedItem] = useState(null); + const [isUpdatingPositions, setIsUpdatingPositions] = useState(false); + const [loading, setLoading] = useState(true); - useEffect(() => { - const fetchKennzahlen = async () => { - while (true) { - try { - console.log('Fetching kennzahlen from API...'); - const response = await fetch(`http://localhost:5050/api/kpi_setting/`); - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } + useEffect(() => { + const fetchKennzahlen = async () => { + while (true) { + try { + console.log("Fetching kennzahlen from API..."); + const data = await fetchK(); + console.log("Fetched kennzahlen:", data); + const sortedData = data.sort( + (a: Kennzahl, b: Kennzahl) => a.position - b.position, + ); + setKennzahlen(sortedData); + setLoading(false); + break; + } catch (err) { + console.error("Error fetching kennzahlen:", err); + await new Promise((resolve) => setTimeout(resolve, 2000)); + } + } + }; - const data = await response.json(); - console.log('Fetched kennzahlen:', data); - const sortedData = data.sort((a: Kennzahl, b: Kennzahl) => a.position - b.position); - setKennzahlen(sortedData); - setLoading(false); - break; - } catch (err) { - console.error('Error fetching kennzahlen:', err); - await new Promise(resolve => setTimeout(resolve, 2000)); - } - } - }; + fetchKennzahlen(); + }, []); - fetchKennzahlen(); - }, []); + const handleToggleActive = async (id: number) => { + const kennzahl = kennzahlen.find((k) => k.id === id); + if (!kennzahl) return; - const handleToggleActive = async (id: number) => { - const kennzahl = kennzahlen.find(k => k.id === id); - if (!kennzahl) return; + try { + const response = await fetch( + `http://localhost:5050/api/kpi_setting/${id}`, + { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + active: !kennzahl.active, + }), + }, + ); - try { - const response = await fetch(`http://localhost:5050/api/kpi_setting/${id}`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - active: !kennzahl.active - }), - }); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } + const updatedKennzahl = await response.json(); + setKennzahlen((prev) => + prev.map((item) => (item.id === id ? updatedKennzahl : item)), + ); + } catch (err) { + console.error("Error toggling active status:", err); + setKennzahlen((prev) => + prev.map((item) => (item.id === id ? kennzahl : item)), + ); + } + }; - const updatedKennzahl = await response.json(); - setKennzahlen(prev => - prev.map(item => - item.id === id ? updatedKennzahl : item - ) - ); - } catch (err) { - console.error('Error toggling active status:', err); - setKennzahlen(prev => - prev.map(item => - item.id === id ? kennzahl : item - ) - ); - } - }; + const updatePositionsInBackend = async (reorderedKennzahlen: Kennzahl[]) => { + setIsUpdatingPositions(true); + try { + const positionUpdates = reorderedKennzahlen.map((kennzahl, index) => ({ + id: kennzahl.id, + position: index + 1, + })); - const updatePositionsInBackend = async (reorderedKennzahlen: Kennzahl[]) => { - setIsUpdatingPositions(true); - try { - const positionUpdates = reorderedKennzahlen.map((kennzahl, index) => ({ - id: kennzahl.id, - position: index + 1 - })); + const response = await fetch( + `http://localhost:5050/api/kpi_setting/update-kpi-positions`, + { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(positionUpdates), + }, + ); - const response = await fetch(`http://localhost:5050/api/kpi_setting/update-kpi-positions`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(positionUpdates), - }); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } + const updatedKennzahlen = await response.json(); + setKennzahlen(updatedKennzahlen); + } catch (err) { + console.error("Error updating positions:", err); + window.location.reload(); + } finally { + setIsUpdatingPositions(false); + } + }; - const updatedKennzahlen = await response.json(); - setKennzahlen(updatedKennzahlen); - } catch (err) { - console.error('Error updating positions:', err); - window.location.reload(); - } finally { - setIsUpdatingPositions(false); - } - }; + const handleDragStart = ( + e: React.DragEvent, + item: Kennzahl, + ) => { + setDraggedItem(item); + e.dataTransfer.effectAllowed = "move"; + }; - const handleDragStart = (e: React.DragEvent, item: Kennzahl) => { - setDraggedItem(item); - e.dataTransfer.effectAllowed = "move"; - }; + const handleDragOver = (e: React.DragEvent) => { + e.preventDefault(); + e.dataTransfer.dropEffect = "move"; + }; - const handleDragOver = (e: React.DragEvent) => { - e.preventDefault(); - e.dataTransfer.dropEffect = "move"; - }; + const handleDrop = async ( + e: React.DragEvent, + targetItem: Kennzahl, + ) => { + e.preventDefault(); + if (!draggedItem || draggedItem.id === targetItem.id) return; - const handleDrop = async (e: React.DragEvent, targetItem: Kennzahl) => { - e.preventDefault(); - if (!draggedItem || draggedItem.id === targetItem.id) return; + const draggedIndex = kennzahlen.findIndex( + (item) => item.id === draggedItem.id, + ); + const targetIndex = kennzahlen.findIndex( + (item) => item.id === targetItem.id, + ); - const draggedIndex = kennzahlen.findIndex(item => item.id === draggedItem.id); - const targetIndex = kennzahlen.findIndex(item => item.id === targetItem.id); + const newKennzahlen = [...kennzahlen]; + const [removed] = newKennzahlen.splice(draggedIndex, 1); + newKennzahlen.splice(targetIndex, 0, removed); - const newKennzahlen = [...kennzahlen]; - const [removed] = newKennzahlen.splice(draggedIndex, 1); - newKennzahlen.splice(targetIndex, 0, removed); + setKennzahlen(newKennzahlen); + setDraggedItem(null); + await updatePositionsInBackend(newKennzahlen); + }; - setKennzahlen(newKennzahlen); - setDraggedItem(null); - await updatePositionsInBackend(newKennzahlen); - }; + const handleDragEnd = () => { + setDraggedItem(null); + }; - const handleDragEnd = () => { - setDraggedItem(null); - }; + const handleRowClick = (kennzahl: Kennzahl, e: React.MouseEvent) => { + if (draggedItem || isUpdatingPositions) { + return; + } - const handleRowClick = (kennzahl: Kennzahl, e: React.MouseEvent) => { - if (draggedItem || isUpdatingPositions) { - return; - } + const target = e.target as HTMLElement; + if ( + target.tagName === "INPUT" && + (target as HTMLInputElement).type === "checkbox" + ) { + return; + } - const target = e.target as HTMLElement; - if (target.tagName === 'INPUT' && (target as HTMLInputElement).type === 'checkbox') { - return; - } + if (target.closest(".drag-handle")) { + return; + } - if (target.closest('.drag-handle')) { - return; - } + console.log("Navigating to detail page for KPI:", kennzahl); + console.log("KPI ID:", kennzahl.id); - console.log('Navigating to detail page for KPI:', kennzahl); - console.log('KPI ID:', kennzahl.id); + navigate({ + to: `/config-detail/$kpiId`, + params: { kpiId: kennzahl.id.toString() }, + }); + }; - navigate({ - to: `/config-detail/$kpiId`, - params: { kpiId: kennzahl.id.toString() } - }); - }; + if (loading) { + return ( + + + Lade Kennzahlen-Konfiguration... + + ); + } - if (loading) { - return ( - - - Lade Kennzahlen-Konfiguration... - - ); - } - - return ( - - - - - - - - - - - - {kennzahlen.map((kennzahl) => ( - handleDragStart(e, kennzahl)} - onDragOver={handleDragOver} - onDrop={(e) => handleDrop(e, kennzahl)} - onDragEnd={handleDragEnd} - onClick={(e) => handleRowClick(kennzahl, e)} - style={{ - borderBottom: "1px solid #e0e0e0", - cursor: isUpdatingPositions ? "default" : "pointer", - backgroundColor: draggedItem?.id === kennzahl.id ? "#f0f0f0" : "white", - opacity: draggedItem?.id === kennzahl.id ? 0.5 : 1 - }} - onMouseEnter={(e) => { - if (!draggedItem && !isUpdatingPositions) { - e.currentTarget.style.backgroundColor = "#f9f9f9"; - } - }} - onMouseLeave={(e) => { - if (!draggedItem && !isUpdatingPositions) { - e.currentTarget.style.backgroundColor = "white"; - } - }} - > - - - - - - ))} - -
- - Aktiv - - Name - - Format -
-
- - Neuanordnung der Kennzahlen
- Hier können Sie die Kennzahlen nach Belieben per Drag and Drop neu anordnen. - - } - placement="left" - arrow - > - -
-
-
- handleToggleActive(kennzahl.id)} - disabled={isUpdatingPositions} - style={{ - width: "18px", - height: "18px", - cursor: isUpdatingPositions ? "default" : "pointer", - accentColor: "#383838" - }} - onClick={(e) => e.stopPropagation()} - /> - - - {kennzahl.name} - - - - {getDisplayType(kennzahl.type)} - -
-
- ); -} \ No newline at end of file + return ( + + + + + + + + + + + {kennzahlen.map((kennzahl) => ( + handleDragStart(e, kennzahl)} + onDragOver={handleDragOver} + onDrop={(e) => handleDrop(e, kennzahl)} + onDragEnd={handleDragEnd} + onClick={(e) => handleRowClick(kennzahl, e)} + style={{ + borderBottom: "1px solid #e0e0e0", + cursor: isUpdatingPositions ? "default" : "pointer", + backgroundColor: + draggedItem?.id === kennzahl.id ? "#f0f0f0" : "white", + opacity: draggedItem?.id === kennzahl.id ? 0.5 : 1, + }} + onMouseEnter={(e) => { + if (!draggedItem && !isUpdatingPositions) { + e.currentTarget.style.backgroundColor = "#f9f9f9"; + } + }} + onMouseLeave={(e) => { + if (!draggedItem && !isUpdatingPositions) { + e.currentTarget.style.backgroundColor = "white"; + } + }} + > + + + + + + ))} + +
+ + Aktiv + + Name + + Format +
+
+ + Neuanordnung der Kennzahlen +
+ Hier können Sie die Kennzahlen nach Belieben per Drag + and Drop neu anordnen. + + } + placement="left" + arrow + > + +
+
+
+ handleToggleActive(kennzahl.id)} + disabled={isUpdatingPositions} + style={{ + width: "18px", + height: "18px", + cursor: isUpdatingPositions ? "default" : "pointer", + accentColor: "#383838", + }} + onClick={(e) => e.stopPropagation()} + /> + + + {kennzahl.name} + + + + {getDisplayType(kennzahl.type)} + +
+
+ ); +} diff --git a/project/frontend/src/components/KennzahlenTable.tsx b/project/frontend/src/components/KennzahlenTable.tsx index acc8d47..406798e 100644 --- a/project/frontend/src/components/KennzahlenTable.tsx +++ b/project/frontend/src/components/KennzahlenTable.tsx @@ -1,3 +1,4 @@ +import type { Kennzahl } from "@/types/kpi"; import EditIcon from "@mui/icons-material/Edit"; import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline"; import SearchIcon from "@mui/icons-material/Search"; @@ -20,19 +21,10 @@ import { useState } from "react"; import type { KeyboardEvent } from "react"; import { fetchPutKPI } from "../util/api"; -const SETTINGS = [ - { name: "Rendite", position: 1, active: true, mandatory: true }, - { name: "Ausschüttungsrendite", position: 2, active: true, mandatory: true }, - { name: "Laufzeit", position: 3, active: true, mandatory: true }, - { name: "Länderallokation", position: 4, active: true, mandatory: true }, - { name: "Managmentgebühren", position: 5, active: true, mandatory: true }, - { name: "Risikoprofil", position: 6, active: false, mandatory: true }, - { name: "Irgendwas", position: 7, active: true, mandatory: true }, -]; - interface KennzahlenTableProps { onPageClick?: (page: number) => void; pdfId: string; + settings: Kennzahl[]; data: { [key: string]: { label: string; @@ -48,6 +40,7 @@ export default function KennzahlenTable({ onPageClick, data, pdfId, + settings, }: KennzahlenTableProps) { const [editingIndex, setEditingIndex] = useState(""); const [editValue, setEditValue] = useState(""); @@ -148,7 +141,8 @@ export default function KennzahlenTable({ - {SETTINGS.filter((setting) => setting.active) + {settings + .filter((setting) => setting.active) .sort((a, b) => a.position - b.position) .map((setting) => ({ setting: setting, @@ -157,7 +151,8 @@ export default function KennzahlenTable({ .map((row) => { let borderColor = "transparent"; const hasMultipleValues = row.extractedValues.length > 1; - const hasNoValue = row.setting.mandatory && + const hasNoValue = + row.setting.mandatory && (row.extractedValues.length === 0 || row.extractedValues.at(0)?.entity === ""); @@ -188,7 +183,8 @@ export default function KennzahlenTable({ - Problem
+ Problem +
Mehrere Werte für die Kennzahl gefunden. } @@ -205,9 +201,9 @@ export default function KennzahlenTable({ justifyContent: "space-between", width: "100%", cursor: "pointer", - '&:hover': { - backgroundColor: '#f5f5f5' - } + "&:hover": { + backgroundColor: "#f5f5f5", + }, }} > - +
) : ( @@ -304,4 +300,4 @@ export default function KennzahlenTable({ ); -} \ No newline at end of file +} diff --git a/project/frontend/src/routes/extractedResult.$pitchBook.tsx b/project/frontend/src/routes/extractedResult.$pitchBook.tsx index c2d57f7..6878542 100644 --- a/project/frontend/src/routes/extractedResult.$pitchBook.tsx +++ b/project/frontend/src/routes/extractedResult.$pitchBook.tsx @@ -5,12 +5,15 @@ import { createFileRoute, useNavigate } from "@tanstack/react-router"; import { useState } from "react"; import KennzahlenTable from "../components/KennzahlenTable"; import PDFViewer from "../components/pdfViewer"; -import { kpiQueryOptions } from "../util/query"; +import { kpiQueryOptions, settingsQueryOptions } from "../util/query"; export const Route = createFileRoute("/extractedResult/$pitchBook")({ component: ExtractedResultsPage, loader: ({ context: { queryClient }, params: { pitchBook } }) => - queryClient.ensureQueryData(kpiQueryOptions(pitchBook)), + Promise.allSettled([ + queryClient.ensureQueryData(kpiQueryOptions(pitchBook)), + queryClient.ensureQueryData(settingsQueryOptions()), + ]), }); function ExtractedResultsPage() { @@ -26,6 +29,7 @@ function ExtractedResultsPage() { }[status]; const { data: kpi } = useSuspenseQuery(kpiQueryOptions(pitchBook)); + const { data: settings } = useSuspenseQuery(settingsQueryOptions()); return ( @@ -67,6 +71,7 @@ function ExtractedResultsPage() { }} > - +