Compare commits

..

No commits in common. "3d6458ffb028e934ab813d384088023f514972de" and "5d0a5ab3c3e939368fa3446aa16611f7d8ab9472" have entirely different histories.

2 changed files with 54 additions and 101 deletions

View File

@ -7,7 +7,6 @@ import type { Kennzahl } from "../types/kpi";
import { typeDisplayMapping } from "../types/kpi";
import Snackbar from "@mui/material/Snackbar";
import MuiAlert from "@mui/material/Alert";
import { API_HOST } from "../util/api";
interface KPIFormProps {
@ -30,7 +29,6 @@ const emptyKPI: Partial<Kennzahl> = {
export function KPIForm({ mode, initialData, onSave, onCancel, loading = false, resetTrigger }: KPIFormProps) {
const [formData, setFormData] = useState<Partial<Kennzahl>>(emptyKPI);
const [originalExamples, setOriginalExamples] = useState<Array<{ sentence: string; value: string }>>([]);
const [isSaving, setIsSaving] = useState(false);
const [snackbarOpen, setSnackbarOpen] = useState(false);
const [snackbarMessage, setSnackbarMessage] = useState("");
@ -39,20 +37,14 @@ export function KPIForm({ mode, initialData, onSave, onCancel, loading = false,
useEffect(() => {
if (mode === 'edit' && initialData) {
setOriginalExamples(initialData.examples || []);
setFormData({
...initialData,
examples: [{ sentence: '', value: '' }]
});
setFormData(initialData);
} else if (mode === 'add') {
setOriginalExamples([]);
setFormData(emptyKPI);
}
}, [mode, initialData]);
useEffect(() => {
if (mode === 'add') {
setOriginalExamples([]);
setFormData(emptyKPI);
}
}, [resetTrigger]);
@ -72,30 +64,24 @@ export function KPIForm({ mode, initialData, onSave, onCancel, loading = false,
setSnackbarMessage("Mindestens ein Beispielsatz ist erforderlich");
setSnackbarSeverity("error");
setSnackbarOpen(true);
return;
}
const newExamples = formData.examples.filter(ex => ex.sentence?.trim() && ex.value?.trim());
if (newExamples.length === 0) {
setSnackbarMessage('Mindestens ein vollständiger Beispielsatz ist erforderlich.');
setSnackbarSeverity("error");
setSnackbarOpen(true);
return;
}
for (const ex of newExamples) {
for (const ex of formData.examples) {
if (!ex.sentence?.trim() || !ex.value?.trim()) {
setSnackbarMessage('Alle Beispielsätze müssen vollständig sein.');
setSnackbarSeverity("error");
setSnackbarOpen(true);
return;
}
}
setIsSaving(true);
try {
const spacyEntries = generateSpacyEntries({ ...formData, examples: newExamples });
const spacyEntries = generateSpacyEntries(formData);
// Für jeden einzelnen Beispielsatz:
for (const entry of spacyEntries) {
@ -106,7 +92,7 @@ export function KPIForm({ mode, initialData, onSave, onCancel, loading = false,
localStorage.setItem("spacyData", JSON.stringify(updated));
// POST Request an das Flask-Backend
const response = await fetch(`${API_HOST}/api/spacy/append-training-entry/`, {
const response = await fetch("http://localhost:5050/api/spacy/append-training-entry", {
method: "POST",
headers: {
"Content-Type": "application/json"
@ -123,10 +109,6 @@ export function KPIForm({ mode, initialData, onSave, onCancel, loading = false,
console.log("SpaCy-Eintrag gespeichert:", data);
}
const allExamples = mode === 'edit'
? [...originalExamples, ...newExamples]
: newExamples;
// Dann in die DB speichern
await onSave({
name: formData.name!,
@ -134,18 +116,11 @@ export function KPIForm({ mode, initialData, onSave, onCancel, loading = false,
type: formData.type || 'string',
position: formData.position ?? 0,
active: formData.active ?? true,
examples: allExamples,
examples: formData.examples ?? [],
is_trained: false,
});
// Formular zurücksetzen:
if (mode === 'add') {
setFormData(emptyKPI);
} else {
setFormData(prev => ({
...prev,
examples: [{ sentence: '', value: '' }]
}));
}
setFormData(emptyKPI);
setSnackbarMessage("Beispielsätze gespeichert. Jetzt auf -Neu trainieren- klicken oder weitere Kennzahlen hinzufügen.");
@ -265,69 +240,45 @@ export function KPIForm({ mode, initialData, onSave, onCancel, loading = false,
</FormControl>
</Box>
<Divider sx={{ my: 3 }} />
<Box mb={4}>
<FormControlLabel
control={
<Checkbox
checked={formData.active !== false}
onChange={(e) => updateField('active', e.target.checked)}
sx={{
color: '#666666',
'&.Mui-checked': {
color: '#333333',
},
'&:hover': {
backgroundColor: 'rgba(102, 102, 102, 0.04)',
}
}}
{mode === 'add' && (
<>
<Divider sx={{ my: 3 }} />
<Box mb={4}>
<FormControlLabel
control={
<Checkbox
checked={formData.active !== false}
onChange={(e) => updateField('active', e.target.checked)}
sx={{ color: '#383838' }}
/>
}
label="Aktiv"
/>
}
label="Aktiv"
/>
<Typography variant="body2" color="text.secondary" ml={4}>
Die Kennzahl ist aktiv und wird angezeigt
</Typography>
</Box>
<Box mt={3}>
<FormControlLabel
control={
<Checkbox
checked={formData.mandatory || false}
onChange={(e) => updateField('mandatory', e.target.checked)}
sx={{
color: '#666666',
'&.Mui-checked': {
color: '#333333',
},
'&:hover': {
backgroundColor: 'rgba(102, 102, 102, 0.04)',
}
}}
<Typography variant="body2" color="text.secondary" ml={4}>
Die Kennzahl ist aktiv und wird angezeigt
</Typography>
</Box>
<Box mt={3}>
<FormControlLabel
control={
<Checkbox
checked={formData.mandatory || false}
onChange={(e) => updateField('mandatory', e.target.checked)}
sx={{ color: '#383838' }}
/>
}
label="Erforderlich"
/>
}
label="Erforderlich"
/>
<Typography variant="body2" color="text.secondary" ml={4}>
Die Kennzahl erlaubt keine leeren Werte
</Typography>
</Box>
<Divider sx={{ my: 3 }} />
{/* Hinweistext wie viele Beispielsätzen vorhanden sind*/}
{mode === 'edit' && originalExamples.length > 0 && (
<Box mb={2} p={2} sx={{ backgroundColor: '#e3f2fd', border: '1px solid #90caf9', borderRadius: 2 }}>
<Typography variant="body1" sx={{ fontWeight: 'bold', mb: 1 }}>
Vorhandene Beispielsätze: {originalExamples.length}
</Typography>
<Typography variant="body2">
Diese Kennzahl hat bereits {originalExamples.length} Beispielsätze. Neue Beispielsätze werden zu den vorhandenen hinzugefügt.
</Typography>
</Box>
<Typography variant="body2" color="text.secondary" ml={4}>
Die Kennzahl erlaubt keine leeren Werte
</Typography>
</Box>
</>
)}
<Divider sx={{ my: 3 }} />
{/* Hinweistext vor Beispielsätzen */}
<Box mb={2} p={2} sx={{ backgroundColor: '#fff8e1', border: '1px solid #ffe082', borderRadius: 2 }}>
<Typography variant="body1" sx={{ fontWeight: 'bold', mb: 1 }}>

View File

@ -188,10 +188,6 @@ export default function PDFViewer({
);
}, []);
const contentWidth = baseWidth ? baseWidth * 0.98 * zoomLevel : 0;
const containerWidth = baseWidth ? baseWidth : 0;
const willOverflow = contentWidth > containerWidth;
return (
<Box
display="flex"
@ -201,6 +197,11 @@ export default function PDFViewer({
width="100%"
maxWidth="850px"
margin="0 auto"
sx={{
backgroundColor: "#f5f5f5",
borderRadius: 2,
boxShadow: 2,
}}
>
<Box
ref={containerRef}
@ -212,10 +213,11 @@ export default function PDFViewer({
borderRadius: 0,
boxShadow: "none",
overflow: "auto",
display: willOverflow ? "block" : "flex",
justifyContent: willOverflow ? "flex-start" : "center",
alignItems: willOverflow ? "flex-start" : "center",
padding: willOverflow ? `${Math.max(0, (500 - (contentWidth * (500 / containerWidth))) / 2)}px ${Math.max(0, (containerWidth - contentWidth) / 2)}px` : 0,
display: "flex",
justifyContent: "center",
alignItems: "center",
marginTop: 2,
marginBottom: 2,
}}
>
<Document