Update maintenance Component for Equipment

This commit is contained in:
2026-01-02 10:21:29 +01:00
parent a88af48234
commit e9f5ddff48
3 changed files with 345 additions and 45 deletions
@@ -13,13 +13,35 @@
<div class="cd-view">
<div class="cd-list">
<!-- Filter Row -->
<div class="filter-row">
<div class="filter-item">
<label>{{ $t('equipment.personal_item') }}:</label>
<select v-model="filterPersonalItem">
<option value="">{{ $t('all') || 'All' }}</option>
<option value="true">{{ $t('yes') || 'Yes' }}</option>
<option value="false">{{ $t('no') || 'No' }}</option>
</select>
</div>
<div class="filter-item">
<label>{{ $t('equipment.quelle') }}:</label>
<select v-model="filterQuelle">
<option value="">{{ $t('all') || 'All' }}</option>
<option v-for="quelle in availableQuellen" :key="quelle" :value="quelle">{{ quelle }}</option>
</select>
</div>
<button @click="clearFilters" class="btn-clear-filters">{{ $t('clearFilters') || 'Clear Filters' }}</button>
</div>
<div class="tables-container">
<table class="cd-table">
<thead>
<tr>
<th class="cd-table-header">{{ $t('equipment.id') }}</th>
<!-- <th class="cd-table-header">{{ $t('equipment.category') }}<button @click="sortBy('category')">-{{ sortField === 'category' ? (sortAsc ? '' : '') : '' }}</button></th> -->
<th class="cd-table-header">{{ $t('equipment.name') }} <button @click="sortBy('name')">-{{ sortField === 'name' ? (sortAsc ? '' : '') : '' }}</button></th>
<th class="cd-table-header">
{{ $t('equipment.name') }}
<button @click="sortBy('name')">{{ sortField === 'name' ? (sortAsc ? '' : '') : '-' }}</button>
</th>
<th class="cd-table-header">{{ $t('equipment.gewicht') }}</th>
<th class="cd-table-header">{{ $t('equipment.wert') }}</th>
<th class="cd-table-header">{{ $t('equipment.description') }}</th>
@@ -38,32 +60,70 @@
<td>{{ dtaItem.gewicht || '-' }}</td>
<td>{{ dtaItem.wert || '-' }}</td>
<td>{{ dtaItem.beschreibung || '-' }}</td>
<td>{{ dtaItem.quelle || '-' }}</td>
<td>{{ dtaItem.personal_item || '0' }}</td>
<td>{{ formatQuelle(dtaItem) }}</td>
<td><input type="checkbox" :checked="dtaItem.personal_item" disabled /></td>
<td>{{ dtaItem.system || 'midgard' }}</td>
<td>
<button @click="startEdit(index)">Edit</button>
</td>
</tr>
<!-- Edit Mode -->
<tr v-else>
<td><input v-model="editedItem.id" style="width:20px;"/></td>
<!-- <td><select v-model="editedItem.category" style="width:80px;">
<option v-for="category in mdata['equipmentcategories']"
:key="category"
:value="category">
{{ category }}
</option>
</select></td> -->
<td><input v-model="editedItem.name"/></td>
<td><input v-model.number="editedItem.gewicht" type="number" style="width:40px;"/></td>
<td><input v-model="editedItem.wert" /></td>
<td><input v-model="editedItem.beschreibung" /></td>
<td><input v-model="editedItem.quelle" style="width:80px;"/></td>
<td><input type="checkbox" :checked="true" v-model="editedItem.personal_item" style="width:50px;"/></td>
<td><input v-model="editedItem.system" style="width:80px;"/></td>
<td>
<button @click="saveEdit(index)">Save</button>
<button @click="cancelEdit">Cancel</button>
<td><input v-model="editedItem.id" style="width:20px;" disabled /></td>
<td colspan="8">
<!-- Expanded edit form -->
<div class="edit-form">
<div class="edit-row">
<div class="edit-field">
<label>{{ $t('equipment.name') }}:</label>
<input v-model="editedItem.name" />
</div>
<div class="edit-field">
<label>{{ $t('equipment.gewicht') }}:</label>
<input v-model.number="editedItem.gewicht" type="number" style="width:80px;" />
</div>
<div class="edit-field">
<label>{{ $t('equipment.wert') }}:</label>
<input v-model="editedItem.wert" style="width:100px;" />
</div>
</div>
<div class="edit-row">
<div class="edit-field full-width">
<label>{{ $t('equipment.description') }}:</label>
<input v-model="editedItem.beschreibung" />
</div>
</div>
<div class="edit-row">
<div class="edit-field">
<label>{{ $t('equipment.quelle') }}:</label>
<select v-model="editedItem.sourceCode" style="width:100px;">
<option value="">-</option>
<option v-for="source in availableSources" :key="source.code" :value="source.code">
{{ source.code }}
</option>
</select>
</div>
<div class="edit-field">
<label>{{ $t('equipment.page') || 'Page' }}:</label>
<input v-model.number="editedItem.page_number" type="number" style="width:60px;" />
</div>
<div class="edit-field">
<label>{{ $t('equipment.personal_item') }}:</label>
<input type="checkbox" v-model="editedItem.personal_item" />
</div>
<div class="edit-field">
<label>{{ $t('equipment.system') }}:</label>
<input v-model="editedItem.system" style="width:100px;" />
</div>
</div>
<div class="edit-actions">
<button @click="saveEdit(index)" class="btn-save">Save</button>
<button @click="cancelEdit" class="btn-cancel">Cancel</button>
</div>
</div>
</td>
</tr>
</template>
@@ -138,27 +198,65 @@ export default {
sortField: 'name',
sortAsc: true,
editingIndex: -1,
editedItem: null
editedItem: null,
filterPersonalItem: '',
filterQuelle: '',
enhancedEquipment: [],
availableSources: []
}
},
async created() {
await this.loadEnhancedEquipment()
},
computed: {
availableQuellen() {
const quellen = new Set()
this.enhancedEquipment.forEach(equipment => {
if (equipment.source_id && this.availableSources.length > 0) {
const source = this.availableSources.find(s => s.id === equipment.source_id)
if (source) {
quellen.add(source.code)
}
}
})
return Array.from(quellen).sort()
},
filteredAndSortedEquipments() {
if (!this.mdata?.equipment) return [];
let filtered = [...this.enhancedEquipment]
return [...this.mdata.equipment]
.filter(equipment => {
const searchLower = this.searchTerm.toLowerCase();
return !this.searchTerm ||
equipment.name?.toLowerCase().includes(searchLower)
//|| equipment.category?.toLowerCase().includes(searchLower);
// Apply search filter
if (this.searchTerm) {
const searchLower = this.searchTerm.toLowerCase()
filtered = filtered.filter(equipment =>
equipment.name?.toLowerCase().includes(searchLower)
)
}
// Apply personal_item filter
if (this.filterPersonalItem !== '') {
const personalItemValue = this.filterPersonalItem === 'true'
filtered = filtered.filter(equipment => equipment.personal_item === personalItemValue)
}
// Apply Quelle filter (only by source code, ignoring page number)
if (this.filterQuelle) {
filtered = filtered.filter(equipment => {
if (equipment.source_id && this.availableSources.length > 0) {
const source = this.availableSources.find(s => s.id === equipment.source_id)
return source && source.code === this.filterQuelle
}
return false
})
.sort((a, b) => {
const aValue = (a[this.sortField] || '').toLowerCase();
const bValue = (b[this.sortField] || '').toLowerCase();
return this.sortAsc
? aValue.localeCompare(bValue)
: bValue.localeCompare(aValue);
});
}
// Apply sorting
filtered.sort((a, b) => {
const aValue = (a[this.sortField] || '').toString().toLowerCase()
const bValue = (b[this.sortField] || '').toString().toLowerCase()
return this.sortAsc ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue)
})
return filtered
},
sortedEquipments() {
return [...this.mdata.equipment].sort((a, b) => {
@@ -171,15 +269,51 @@ export default {
}
},
methods: {
startEdit(index) {
this.editingIndex = index;
this.editedItem = { ...this.filteredAndSortedEquipments[index] };
async loadEnhancedEquipment() {
try {
const response = await API.get('/api/maintenance/equipment-enhanced')
this.enhancedEquipment = response.data.equipment || []
this.availableSources = response.data.sources || []
} catch (error) {
console.error('Failed to load enhanced equipment:', error)
}
},
saveEdit(index) {
//this.$emit('update-equipment', { index, equipment: this.editedItem });
this.handleEquipmentUpdate( { index, equipment: this.editedItem });
this.editingIndex = -1;
this.editedItem = null;
startEdit(index) {
const equipment = this.filteredAndSortedEquipments[index]
this.editedItem = {
...equipment,
sourceCode: this.getSourceCode(equipment.source_id)
}
this.editingIndex = index
},
async saveEdit(index) {
try {
// Find source ID from code
const source = this.availableSources.find(s => s.code === this.editedItem.sourceCode)
const updateData = {
...this.editedItem,
source_id: source ? source.id : null,
page_number: this.editedItem.page_number || 0
}
const response = await API.put(
`/api/maintenance/equipment-enhanced/${this.editedItem.id}`,
updateData
)
// Update the equipment in the list using splice for proper reactivity
const equipmentIndex = this.enhancedEquipment.findIndex(e => e.id === this.editedItem.id)
if (equipmentIndex !== -1) {
this.enhancedEquipment.splice(equipmentIndex, 1, response.data)
}
this.editingIndex = -1
this.editedItem = null
} catch (error) {
console.error('Failed to save equipment:', error)
alert('Failed to save equipment: ' + (error.response?.data?.error || error.message))
}
},
cancelEdit() {
this.editingIndex = -1;
@@ -193,6 +327,31 @@ export default {
this.sortAsc = true;
}
},
formatQuelle(equipment) {
if (equipment.source_id && this.availableSources.length > 0) {
const source = this.availableSources.find(s => s.id === equipment.source_id)
if (source) {
if (equipment.page_number) {
return `${source.code}:${equipment.page_number}`
} else {
// No page number - show code and quelle if available
const quelle = equipment.quelle ? ` (${equipment.quelle})` : ''
return `${source.code}${quelle}`
}
}
}
return equipment.quelle || '-'
},
getSourceCode(sourceId) {
if (!sourceId || !this.availableSources.length) return ''
const source = this.availableSources.find(s => s.id === sourceId)
return source ? source.code : ''
},
clearFilters() {
this.searchTerm = ''
this.filterPersonalItem = ''
this.filterQuelle = ''
},
async handleEquipmentUpdate({ index, equipment }) {
try {
const response = await API.put(