Files
thetool/public/js/pages/WarehouseProject/WarehouseProjectModal.js
2025-12-02 14:46:22 +00:00

147 lines
6.5 KiB
JavaScript

Vue.component('warehouse-project-modal', {
props: {
id: { type: [String, Number], required: true },
},
data() {
return {
window: window,
loading: false,
allUsers: [],
project: {
title: '',
description: '',
startDate: null,
endDate: null,
storageLocation: '',
externalTeam: '',
internalTeam: [], // Array of user IDs
status: 'new',
financials: 0.00
},
statusOptions: [
{ text: 'Neu', value: 'new' },
{ text: 'In Bearbeitung', value: 'wip' },
{ text: 'Abgeschlossen', value: 'finished' },
{ text: 'Storniert', value: 'cancelled' }
]
};
},
//language=Vue
template: `
<tt-modal :show="true"
:delete="false"
:title="id === 'create' ? 'Projekt erstellen' : 'Projekt bearbeiten'"
@update:show="$emit('close')"
@submit="submit"
:save-loading="loading"
>
<div style="width: 99%">
<tt-input v-model="project.title" label="Bezeichnung *" sm row required/>
<div class="row">
<div class="col-md-6">
<tt-input v-model="project.startDate" label="Startdatum *" type="date" sm row required/>
</div>
<div class="col-md-6">
<tt-input v-model="project.endDate" label="Enddatum *" type="date" sm row required/>
</div>
</div>
<tt-input v-model="project.storageLocation" label="Lagerort" sm row/>
<div class="form-group row">
<label class="col-sm-3 col-form-label col-form-label-sm">Status *</label>
<div class="col-sm-9">
<select class="form-control form-control-sm" v-model="project.status" required>
<option v-for="opt in statusOptions" :key="opt.value" :value="opt.value">{{ opt.text }}</option>
</select>
</div>
</div>
<!-- Internal Team Select (Create Only or simplified list) -->
<div class="form-group row" v-if="id === 'create'">
<label class="col-sm-3 col-form-label col-form-label-sm">Internes Team</label>
<div class="col-sm-9">
<select class="form-control form-control-sm" v-model="project.internalTeam" multiple style="height: 100px;">
<option v-for="u in allUsers" :key="u.id" :value="u.id">{{ u.name }}</option>
</select>
<small class="text-muted">Strg+Klick für Mehrfachauswahl</small>
</div>
</div>
<tt-textarea v-model="project.externalTeam" label="Externes Team" sm row placeholder="Namen, Firmen, Kontakte..."/>
<tt-textarea v-model="project.description" label="Beschreibung" sm row rows="4"/>
<div v-if="id !== 'create'" class="form-group row">
<label class="col-sm-3 col-form-label col-form-label-sm">Finanzen</label>
<div class="col-sm-9">
<input type="text" class="form-control form-control-sm" :value="formatPrice(project.financials)" disabled>
<small class="text-muted">Wird automatisch berechnet.</small>
</div>
</div>
</div>
</tt-modal>
`,
async mounted() {
this.fetchUsers();
if (this.id !== 'create') {
this.loading = true;
try {
const { data } = await axios.get(`${window.TT_CONFIG["BASE_PATH"]}/WarehouseProject/getById`, { params: { id: this.id } });
if (data) {
this.project = { ...this.project, ...data };
// Ensure dates are in YYYY-MM-DD format for input type="date"
if (this.project.startDate) this.project.startDate = this.formatDateForInput(this.project.startDate);
if (this.project.endDate) this.project.endDate = this.formatDateForInput(this.project.endDate);
}
} catch (e) {
console.error(e);
window.notify('error', 'Projekt konnte nicht geladen werden.');
} finally {
this.loading = false;
}
}
},
methods: {
async fetchUsers() {
try {
const res = await axios.get(`${window.TT_CONFIG["BASE_PATH"]}/WarehouseProject/getUsers`);
this.allUsers = res.data;
} catch(e) { console.error(e); }
},
formatDateForInput(timestamp) {
if (!timestamp) return null;
return new Date(timestamp * 1000).toISOString().split('T')[0];
},
formatPrice(val) {
return new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(val || 0);
},
async submit() {
if (!this.project.title || !this.project.startDate || !this.project.endDate) {
return window.notify('error', 'Bitte füllen Sie alle Pflichtfelder aus (*).');
}
this.loading = true;
try {
const payload = { ...this.project };
if (payload.startDate) payload.startDate = Math.floor(new Date(payload.startDate).getTime() / 1000);
if (payload.endDate) payload.endDate = Math.floor(new Date(payload.endDate).getTime() / 1000);
const url = `${window.TT_CONFIG["BASE_PATH"]}/WarehouseProject/${this.id === 'create' ? 'create' : 'update'}`;
const response = await axios.post(url, payload);
if (response.data.success) {
this.$emit('close');
window.notify('success', response.data.message || 'Gespeichert.');
} else {
window.notify('error', response.data.message || 'Fehler beim Speichern.');
}
} catch (e) {
console.error(e);
window.notify('error', 'Ein Systemfehler ist aufgetreten.');
} finally {
this.loading = false;
}
}
}
});