Erweitert die Funktionalität zur Erstellung und Aktualisierung von vordefinierten Aktivitäten, indem das Feld für Zeichnungsdaten in den entsprechenden Controllern, Modellen und Services hinzugefügt wird. Aktualisiert die Benutzeroberfläche in CourtDrawingTool.vue und PredefinedActivities.vue, um die Handhabung von Zeichnungsdaten zu verbessern und die Logik für das Laden und Speichern von Zeichnungen zu optimieren.
This commit is contained in:
@@ -5,8 +5,8 @@ import fs from 'fs';
|
||||
|
||||
export const createPredefinedActivity = async (req, res) => {
|
||||
try {
|
||||
const { name, code, description, durationText, duration, imageLink } = req.body;
|
||||
const predefinedActivity = await predefinedActivityService.createPredefinedActivity({ name, code, description, durationText, duration, imageLink });
|
||||
const { name, code, description, durationText, duration, imageLink, drawingData } = req.body;
|
||||
const predefinedActivity = await predefinedActivityService.createPredefinedActivity({ name, code, description, durationText, duration, imageLink, drawingData });
|
||||
res.status(201).json(predefinedActivity);
|
||||
} catch (error) {
|
||||
console.error('[createPredefinedActivity] - Error:', error);
|
||||
@@ -42,8 +42,8 @@ export const getPredefinedActivityById = async (req, res) => {
|
||||
export const updatePredefinedActivity = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { name, code, description, durationText, duration, imageLink } = req.body;
|
||||
const updatedActivity = await predefinedActivityService.updatePredefinedActivity(id, { name, code, description, durationText, duration, imageLink });
|
||||
const { name, code, description, durationText, duration, imageLink, drawingData } = req.body;
|
||||
const updatedActivity = await predefinedActivityService.updatePredefinedActivity(id, { name, code, description, durationText, duration, imageLink, drawingData });
|
||||
res.status(200).json(updatedActivity);
|
||||
} catch (error) {
|
||||
console.error('[updatePredefinedActivity] - Error:', error);
|
||||
|
||||
@@ -19,6 +19,11 @@ const PredefinedActivity = sequelize.define('PredefinedActivity', {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: true,
|
||||
},
|
||||
drawingData: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: true,
|
||||
comment: 'JSON string with metadata for Court Drawing Tool'
|
||||
},
|
||||
durationText: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
|
||||
@@ -15,6 +15,7 @@ class PredefinedActivityService {
|
||||
durationText: data.durationText,
|
||||
duration: data.duration,
|
||||
imageLink: data.imageLink,
|
||||
drawingData: data.drawingData ? JSON.stringify(data.drawingData) : null,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -32,6 +33,7 @@ class PredefinedActivityService {
|
||||
durationText: data.durationText,
|
||||
duration: data.duration,
|
||||
imageLink: data.imageLink,
|
||||
drawingData: data.drawingData ? JSON.stringify(data.drawingData) : null,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -176,7 +176,6 @@
|
||||
<div class="tool-controls">
|
||||
<button @click="clearCanvas" class="btn-secondary btn-small">Löschen</button>
|
||||
<button @click="saveDrawing" class="btn-primary btn-small">Speichern</button>
|
||||
<button @click="loadDrawing" class="btn-secondary btn-small">Laden</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -196,6 +195,10 @@ export default {
|
||||
drawingData: { // Added for loading saved drawing data
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
allowImageUpload: { // Neu: steuert, ob das Tool ein Bild erzeugt/hochlädt
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -1092,7 +1095,7 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
async saveDrawing() {
|
||||
async saveDrawing() {
|
||||
console.log('CourtDrawingTool: saveDrawing called');
|
||||
|
||||
try {
|
||||
@@ -1116,7 +1119,10 @@ export default {
|
||||
};
|
||||
|
||||
console.log('CourtDrawingTool: drawingData created:', drawingData);
|
||||
|
||||
// Immer Metadaten nach oben geben
|
||||
this.$emit('update-drawing-data', drawingData);
|
||||
|
||||
if (this.allowImageUpload) {
|
||||
// Konvertiere DataURL zu Blob für Upload
|
||||
const response = await fetch(dataURL);
|
||||
const blob = await response.blob();
|
||||
@@ -1132,9 +1138,15 @@ export default {
|
||||
console.log('CourtDrawingTool: emitting upload-image event');
|
||||
this.$emit('upload-image', file, drawingData);
|
||||
console.log('CourtDrawingTool: upload-image event emitted');
|
||||
|
||||
// Emittiere das File für Upload (Parent-Komponente macht den Upload)
|
||||
console.log('CourtDrawingTool: File ready for upload');
|
||||
} else {
|
||||
// Kein Bild-Upload mehr: gebe lediglich die Zeichnungsdaten an den Parent weiter,
|
||||
// damit Felder (Kürzel/Name/Beschreibung) gefüllt werden können
|
||||
this.$emit('update-fields', {
|
||||
code: this.getFullCode ? this.getFullCode() : '',
|
||||
name: this.getFullTitle ? this.getFullTitle() : '',
|
||||
description: ''
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('CourtDrawingTool: Error in saveDrawing:', error);
|
||||
}
|
||||
|
||||
@@ -81,8 +81,10 @@
|
||||
v-model="editModel.drawingData"
|
||||
:activity-id="editModel.id"
|
||||
:drawing-data="editModel.drawingData"
|
||||
:allow-image-upload="false"
|
||||
@save="onDrawingSave"
|
||||
@update-fields="onUpdateFields"
|
||||
@update-drawing-data="onUpdateDrawingData"
|
||||
@upload-image="onDrawingImageUpload"
|
||||
@image-uploaded="onImageUploaded"
|
||||
/>
|
||||
@@ -150,6 +152,15 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
parseDrawingData(value) {
|
||||
if (!value) return null;
|
||||
if (typeof value === 'object') return value;
|
||||
try { return JSON.parse(value); } catch (e) { return null; }
|
||||
},
|
||||
normalizeActivity(activity, images) {
|
||||
const drawingData = this.parseDrawingData(activity && activity.drawingData);
|
||||
return { ...(activity || {}), drawingData };
|
||||
},
|
||||
async reload() {
|
||||
const r = await apiClient.get('/predefined-activities');
|
||||
this.activities = r.data || [];
|
||||
@@ -159,23 +170,12 @@ export default {
|
||||
const r = await apiClient.get(`/predefined-activities/${a.id}`);
|
||||
const { images, ...activity } = r.data;
|
||||
this.images = images || [];
|
||||
|
||||
// Lade Zeichnungsdaten aus dem ersten Bild, falls vorhanden
|
||||
let drawingData = null;
|
||||
if (images && images.length > 0 && images[0].drawingData) {
|
||||
try {
|
||||
drawingData = JSON.parse(images[0].drawingData);
|
||||
console.log('PredefinedActivities: Loaded drawingData:', drawingData);
|
||||
} catch (error) {
|
||||
console.error('PredefinedActivities: Error parsing drawingData:', error);
|
||||
}
|
||||
} else {
|
||||
// Keine Bilder vorhanden - setze drawingData explizit auf null
|
||||
console.log('PredefinedActivities: No images found, setting drawingData to null');
|
||||
drawingData = null;
|
||||
// Server-Daten normalisieren und ggf. image-drawingData fallbacken
|
||||
let model = this.normalizeActivity(activity, images);
|
||||
if (!model.drawingData && images && images.length > 0 && images[0].drawingData) {
|
||||
model.drawingData = this.parseDrawingData(images[0].drawingData);
|
||||
}
|
||||
|
||||
this.editModel = { ...activity, drawingData };
|
||||
this.editModel = model;
|
||||
},
|
||||
async reloadImages() {
|
||||
if (this.editModel && this.editModel.id) {
|
||||
@@ -226,11 +226,14 @@ export default {
|
||||
|
||||
if (this.editModel.id) {
|
||||
const { id, ...payload } = this.editModel;
|
||||
if (payload.drawingData && typeof payload.drawingData === 'object') {
|
||||
payload.drawingData = payload.drawingData;
|
||||
}
|
||||
const r = await apiClient.put(`/predefined-activities/${id}`, payload);
|
||||
this.editModel = r.data;
|
||||
this.editModel = this.normalizeActivity(r.data);
|
||||
} else {
|
||||
const r = await apiClient.post('/predefined-activities', this.editModel);
|
||||
this.editModel = r.data;
|
||||
this.editModel = this.normalizeActivity(r.data);
|
||||
}
|
||||
|
||||
// Nach dem Speichern (sowohl CREATE als auch UPDATE): Bild hochladen falls vorhanden
|
||||
@@ -328,6 +331,11 @@ export default {
|
||||
this.editModel.description = fields.description;
|
||||
}
|
||||
},
|
||||
onUpdateDrawingData(data) {
|
||||
if (this.editModel) {
|
||||
this.editModel.drawingData = data;
|
||||
}
|
||||
},
|
||||
|
||||
async onDrawingImageUpload(file, drawingData) {
|
||||
console.log('onDrawingImageUpload called with file:', file);
|
||||
|
||||
Reference in New Issue
Block a user