Compare commits

...

2 Commits

Author SHA1 Message Date
s8613 3d6458ffb0 Removed example for edit mode. 2025-07-01 11:06:20 +02:00
s8613 7eeca5c3ba Fixed extra frame font and small styling issues. 2025-07-01 10:52:56 +02:00
2 changed files with 100 additions and 53 deletions

View File

@ -7,6 +7,7 @@ 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 {
@ -29,6 +30,7 @@ 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("");
@ -37,14 +39,20 @@ export function KPIForm({ mode, initialData, onSave, onCancel, loading = false,
useEffect(() => {
if (mode === 'edit' && initialData) {
setFormData(initialData);
setOriginalExamples(initialData.examples || []);
setFormData({
...initialData,
examples: [{ sentence: '', value: '' }]
});
} else if (mode === 'add') {
setOriginalExamples([]);
setFormData(emptyKPI);
}
}, [mode, initialData]);
useEffect(() => {
if (mode === 'add') {
setOriginalExamples([]);
setFormData(emptyKPI);
}
}, [resetTrigger]);
@ -64,24 +72,30 @@ export function KPIForm({ mode, initialData, onSave, onCancel, loading = false,
setSnackbarMessage("Mindestens ein Beispielsatz ist erforderlich");
setSnackbarSeverity("error");
setSnackbarOpen(true);
return;
}
for (const ex of formData.examples) {
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) {
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);
const spacyEntries = generateSpacyEntries({ ...formData, examples: newExamples });
// Für jeden einzelnen Beispielsatz:
for (const entry of spacyEntries) {
@ -92,7 +106,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("http://localhost:5050/api/spacy/append-training-entry", {
const response = await fetch(`${API_HOST}/api/spacy/append-training-entry/`, {
method: "POST",
headers: {
"Content-Type": "application/json"
@ -109,6 +123,10 @@ 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!,
@ -116,11 +134,18 @@ export function KPIForm({ mode, initialData, onSave, onCancel, loading = false,
type: formData.type || 'string',
position: formData.position ?? 0,
active: formData.active ?? true,
examples: formData.examples ?? [],
examples: allExamples,
is_trained: false,
});
// Formular zurücksetzen:
setFormData(emptyKPI);
if (mode === 'add') {
setFormData(emptyKPI);
} else {
setFormData(prev => ({
...prev,
examples: [{ sentence: '', value: '' }]
}));
}
setSnackbarMessage("Beispielsätze gespeichert. Jetzt auf -Neu trainieren- klicken oder weitere Kennzahlen hinzufügen.");
@ -240,45 +265,69 @@ export function KPIForm({ mode, initialData, onSave, onCancel, loading = false,
</FormControl>
</Box>
<Divider sx={{ my: 3 }} />
{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"
<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)',
}
}}
/>
<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="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 erlaubt keine leeren Werte
</Typography>
</Box>
</>
)}
}
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>
)}
{/* 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,6 +188,10 @@ 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"
@ -197,11 +201,6 @@ export default function PDFViewer({
width="100%"
maxWidth="850px"
margin="0 auto"
sx={{
backgroundColor: "#f5f5f5",
borderRadius: 2,
boxShadow: 2,
}}
>
<Box
ref={containerRef}
@ -213,11 +212,10 @@ export default function PDFViewer({
borderRadius: 0,
boxShadow: "none",
overflow: "auto",
display: "flex",
justifyContent: "center",
alignItems: "center",
marginTop: 2,
marginBottom: 2,
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,
}}
>
<Document