2025-01-18 20:59:35 +01:00
|
|
|
<template>
|
2025-01-18 20:59:54 +01:00
|
|
|
<div class="header-section">
|
|
|
|
|
<h2>{{ $t('maintenance') }}</h2>
|
|
|
|
|
<!-- Add search input -->
|
|
|
|
|
<div class="search-box">
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
v-model="searchTerm"
|
|
|
|
|
:placeholder="`${$t('search')} ${$t('WaeponSkill')}...`"
|
|
|
|
|
/>
|
2026-02-04 22:18:37 +01:00
|
|
|
<button @click="startCreate" class="btn-primary">{{ $t('newEntry') }}</button>
|
2025-01-18 20:59:54 +01:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-01-18 20:59:35 +01:00
|
|
|
<div class="cd-view">
|
|
|
|
|
<div class="cd-list">
|
2026-01-02 10:21:29 +01:00
|
|
|
<!-- Filter Row -->
|
|
|
|
|
<div class="filter-row">
|
|
|
|
|
<div class="filter-item">
|
2026-01-12 16:36:35 +01:00
|
|
|
<label>{{ $t('weaponskill.difficulty') }}:</label>
|
|
|
|
|
<select v-model="filterDifficulty">
|
2026-01-02 10:21:29 +01:00
|
|
|
<option value="">{{ $t('all') || 'All' }}</option>
|
2026-01-12 16:36:35 +01:00
|
|
|
<option v-for="diff in availableDifficulties" :key="diff" :value="diff">{{ diff }}</option>
|
2026-01-02 10:21:29 +01:00
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="filter-item">
|
|
|
|
|
<label>{{ $t('weaponskill.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>
|
|
|
|
|
|
2025-01-18 20:59:35 +01:00
|
|
|
<div class="tables-container">
|
|
|
|
|
<table class="cd-table">
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
2025-01-18 20:59:54 +01:00
|
|
|
<th class="cd-table-header">{{ $t('weaponskill.id') }}</th>
|
|
|
|
|
<th class="cd-table-header">{{ $t('weaponskill.name') }} <button @click="sortBy('name')">-{{ sortField === 'name' ? (sortAsc ? '↑' : '↓') : '' }}</button></th>
|
2026-01-12 16:36:35 +01:00
|
|
|
<th class="cd-table-header">{{ $t('weaponskill.difficulty') }}<button @click="sortBy('difficulty')">-{{ sortField === 'difficulty' ? (sortAsc ? '↑' : '↓') : '' }}</button></th>
|
2025-01-18 20:59:54 +01:00
|
|
|
<th class="cd-table-header">{{ $t('weaponskill.initialwert') }}</th>
|
|
|
|
|
<th class="cd-table-header">{{ $t('weaponskill.description') }}</th>
|
|
|
|
|
<th class="cd-table-header">{{ $t('weaponskill.quelle') }}</th>
|
|
|
|
|
<th class="cd-table-header">{{ $t('weaponskill.system') }}</th>
|
|
|
|
|
<th class="cd-table-header"> </th>
|
2025-01-18 20:59:35 +01:00
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
2026-02-04 22:18:37 +01:00
|
|
|
<tr v-if="creatingNew">
|
|
|
|
|
<td>New</td>
|
|
|
|
|
<td colspan="6">
|
|
|
|
|
<div class="edit-form">
|
|
|
|
|
<div class="edit-row">
|
|
|
|
|
<div class="edit-field">
|
|
|
|
|
<label>{{ $t('weaponskill.name') }}:</label>
|
|
|
|
|
<input v-model="newItem.name" />
|
|
|
|
|
</div>
|
|
|
|
|
<div class="edit-field">
|
|
|
|
|
<label>{{ $t('weaponskill.difficulty') }}:</label>
|
|
|
|
|
<select v-model="newItem.difficulty" style="width:120px;">
|
|
|
|
|
<option value="leicht">leicht</option>
|
|
|
|
|
<option value="normal">normal</option>
|
|
|
|
|
<option value="schwer">schwer</option>
|
|
|
|
|
<option value="sehr schwer">sehr schwer</option>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="edit-field">
|
|
|
|
|
<label>{{ $t('weaponskill.initialwert') }}:</label>
|
|
|
|
|
<input v-model.number="newItem.initialwert" type="number" style="width:60px;" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="edit-row">
|
|
|
|
|
<div class="edit-field full-width">
|
|
|
|
|
<label>{{ $t('weaponskill.description') }}:</label>
|
|
|
|
|
<input v-model="newItem.beschreibung" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="edit-row">
|
|
|
|
|
<div class="edit-field">
|
|
|
|
|
<label>{{ $t('weaponskill.quelle') }}:</label>
|
|
|
|
|
<select v-model="newItem.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('weaponskill.page') || 'Page' }}:</label>
|
|
|
|
|
<input v-model.number="newItem.page_number" type="number" style="width:60px;" />
|
|
|
|
|
</div>
|
|
|
|
|
<div class="edit-field">
|
|
|
|
|
<label>{{ $t('weaponskill.system') }}:</label>
|
|
|
|
|
<select v-model.number="createSelectedSystemId" style="width:140px;">
|
|
|
|
|
<option value="">-</option>
|
|
|
|
|
<option v-for="system in systemOptions" :key="system.id" :value="system.id">
|
|
|
|
|
{{ system.label }}
|
|
|
|
|
</option>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="edit-actions">
|
|
|
|
|
<button @click="saveCreate" class="btn-save">{{ $t('common.save') }}</button>
|
|
|
|
|
<button @click="cancelCreate" class="btn-cancel">{{ $t('common.cancel') }}</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
2025-01-18 20:59:54 +01:00
|
|
|
<template v-for="(dtaItem, index) in filteredAndSortedWaeponSkills" :key="dtaItem.id">
|
|
|
|
|
<tr v-if="editingIndex !== index">
|
|
|
|
|
<td>{{ dtaItem.id || '' }}</td>
|
|
|
|
|
<td>{{ dtaItem.name || '-' }}</td>
|
2026-01-12 16:36:35 +01:00
|
|
|
<td>{{ dtaItem.difficulty || '-' }}</td>
|
2025-01-18 20:59:54 +01:00
|
|
|
<td>{{ dtaItem.initialwert || '0' }}</td>
|
|
|
|
|
<td>{{ dtaItem.beschreibung || '-' }}</td>
|
2026-01-02 10:21:29 +01:00
|
|
|
<td>{{ formatQuelle(dtaItem) }}</td>
|
2026-02-03 17:21:43 +01:00
|
|
|
<td>{{ getSystemCodeById(dtaItem.game_system_id, dtaItem.system || 'midgard') }}</td>
|
2025-01-18 20:59:54 +01:00
|
|
|
<td>
|
2026-02-04 22:18:37 +01:00
|
|
|
<button @click="startEdit(index)">{{ $t('common.edit') }}</button>
|
2025-01-18 20:59:54 +01:00
|
|
|
</td>
|
2025-01-18 20:59:35 +01:00
|
|
|
</tr>
|
2026-01-02 10:21:29 +01:00
|
|
|
<!-- Edit Mode -->
|
2025-01-18 20:59:54 +01:00
|
|
|
<tr v-else>
|
2026-01-02 10:21:29 +01:00
|
|
|
<td><input v-model="editedItem.id" style="width:20px;" disabled /></td>
|
2026-01-12 16:36:35 +01:00
|
|
|
<td colspan="6">
|
2026-01-02 10:21:29 +01:00
|
|
|
<!-- Expanded edit form -->
|
|
|
|
|
<div class="edit-form">
|
|
|
|
|
<div class="edit-row">
|
|
|
|
|
<div class="edit-field">
|
|
|
|
|
<label>{{ $t('weaponskill.name') }}:</label>
|
|
|
|
|
<input v-model="editedItem.name" />
|
|
|
|
|
</div>
|
|
|
|
|
<div class="edit-field">
|
2026-01-12 16:36:35 +01:00
|
|
|
<label>{{ $t('weaponskill.difficulty') }}:</label>
|
|
|
|
|
<select v-model="editedItem.difficulty" style="width:120px;">
|
|
|
|
|
<option value="leicht">leicht</option>
|
|
|
|
|
<option value="normal">normal</option>
|
|
|
|
|
<option value="schwer">schwer</option>
|
|
|
|
|
<option value="sehr schwer">sehr schwer</option>
|
2026-01-02 10:21:29 +01:00
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="edit-field">
|
|
|
|
|
<label>{{ $t('weaponskill.initialwert') }}:</label>
|
|
|
|
|
<input v-model.number="editedItem.initialwert" type="number" style="width:60px;" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="edit-row">
|
|
|
|
|
<div class="edit-field full-width">
|
|
|
|
|
<label>{{ $t('weaponskill.description') }}:</label>
|
|
|
|
|
<input v-model="editedItem.beschreibung" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="edit-row">
|
|
|
|
|
<div class="edit-field">
|
|
|
|
|
<label>{{ $t('weaponskill.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('weaponskill.page') || 'Page' }}:</label>
|
|
|
|
|
<input v-model.number="editedItem.page_number" type="number" style="width:60px;" />
|
|
|
|
|
</div>
|
|
|
|
|
<div class="edit-field">
|
|
|
|
|
<label>{{ $t('weaponskill.system') }}:</label>
|
2026-02-03 17:21:43 +01:00
|
|
|
<select v-model.number="selectedSystemId" style="width:140px;">
|
|
|
|
|
<option value="">-</option>
|
|
|
|
|
<option v-for="system in systemOptions" :key="system.id" :value="system.id">
|
|
|
|
|
{{ system.label }}
|
|
|
|
|
</option>
|
|
|
|
|
</select>
|
2026-01-02 10:21:29 +01:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="edit-actions">
|
2026-02-04 22:18:37 +01:00
|
|
|
<button @click="saveEdit(index)" class="btn-save">{{ $t('common.save') }}</button>
|
|
|
|
|
<button @click="cancelEdit" class="btn-cancel">{{ $t('common.cancel') }}</button>
|
2026-01-02 10:21:29 +01:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-01-18 20:59:54 +01:00
|
|
|
</td>
|
2025-01-18 20:59:35 +01:00
|
|
|
</tr>
|
|
|
|
|
</template>
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</div>
|
|
|
|
|
</div> <!--- end cd-list-->
|
|
|
|
|
</div> <!--- end character -datasheet-->
|
|
|
|
|
</template>
|
|
|
|
|
|
2025-01-18 20:59:54 +01:00
|
|
|
<!-- <style scoped> -->
|
2025-01-18 20:59:35 +01:00
|
|
|
<style>
|
2025-01-18 20:59:54 +01:00
|
|
|
.header-section {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-bottom: 0.3rem;
|
|
|
|
|
height: fit-content;
|
|
|
|
|
padding: 0.5rem;
|
|
|
|
|
}
|
|
|
|
|
.search-box {
|
|
|
|
|
margin-bottom: 1rem;
|
|
|
|
|
}
|
|
|
|
|
.search-box input {
|
|
|
|
|
padding: 0.2rem;
|
|
|
|
|
width: 200px;
|
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
}
|
2025-01-18 20:59:35 +01:00
|
|
|
.tables-container {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 1rem;
|
|
|
|
|
width: 100%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.table-wrapper-left {
|
|
|
|
|
flex: 6;
|
|
|
|
|
min-width: 0; /* Prevent table from overflowing */
|
|
|
|
|
}
|
|
|
|
|
.table-wrapper-right {
|
|
|
|
|
flex: 4;
|
|
|
|
|
min-width: 0; /* Prevent table from overflowing */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.cd-table {
|
|
|
|
|
width: 100%;
|
|
|
|
|
}
|
|
|
|
|
.cd-table-header {
|
|
|
|
|
background-color: #1da766;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
2025-01-18 20:59:54 +01:00
|
|
|
import API from '../../utils/api'
|
2026-02-03 17:21:43 +01:00
|
|
|
import {
|
|
|
|
|
findSystemIdByCode,
|
|
|
|
|
getSourceCode,
|
|
|
|
|
getSystemCodeById,
|
|
|
|
|
loadGameSystems as fetchGameSystems,
|
|
|
|
|
buildSystemOptions,
|
|
|
|
|
} from '../../utils/maintenanceGameSystems'
|
2025-01-18 20:59:35 +01:00
|
|
|
export default {
|
2025-01-18 20:59:54 +01:00
|
|
|
name: "WaeponSkillView",
|
2025-01-18 20:59:35 +01:00
|
|
|
props: {
|
2025-01-18 20:59:54 +01:00
|
|
|
mdata: {
|
2025-01-18 20:59:35 +01:00
|
|
|
type: Object,
|
2025-01-18 20:59:54 +01:00
|
|
|
required: true,
|
|
|
|
|
default: () => ({
|
|
|
|
|
skills: [],
|
|
|
|
|
skillcategories: []
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
searchTerm: '',
|
|
|
|
|
sortField: 'name',
|
|
|
|
|
sortAsc: true,
|
|
|
|
|
editingIndex: -1,
|
2026-01-02 10:21:29 +01:00
|
|
|
editedItem: null,
|
2026-01-12 16:36:35 +01:00
|
|
|
filterDifficulty: '',
|
2026-01-02 10:21:29 +01:00
|
|
|
filterQuelle: '',
|
|
|
|
|
enhancedWeaponSkills: [],
|
2026-01-12 16:36:35 +01:00
|
|
|
availableSources: [],
|
2026-02-03 17:21:43 +01:00
|
|
|
availableDifficultiesData: [],
|
|
|
|
|
gameSystems: [],
|
2026-02-04 22:18:37 +01:00
|
|
|
selectedSystemId: null,
|
|
|
|
|
creatingNew: false,
|
|
|
|
|
newItem: null,
|
|
|
|
|
createSelectedSystemId: null
|
2025-01-18 20:59:54 +01:00
|
|
|
}
|
|
|
|
|
},
|
2026-01-02 10:21:29 +01:00
|
|
|
async created() {
|
2026-02-03 17:21:43 +01:00
|
|
|
await Promise.all([
|
|
|
|
|
this.loadGameSystems(),
|
|
|
|
|
this.loadEnhancedWeaponSkills()
|
|
|
|
|
])
|
2026-01-02 10:21:29 +01:00
|
|
|
},
|
2025-01-18 20:59:54 +01:00
|
|
|
computed: {
|
2026-01-12 16:36:35 +01:00
|
|
|
availableDifficulties() {
|
|
|
|
|
const difficulties = new Set()
|
2026-01-02 10:21:29 +01:00
|
|
|
this.enhancedWeaponSkills.forEach(ws => {
|
2026-01-12 16:36:35 +01:00
|
|
|
if (ws.difficulty) difficulties.add(ws.difficulty)
|
2026-01-02 10:21:29 +01:00
|
|
|
})
|
2026-01-12 16:36:35 +01:00
|
|
|
return Array.from(difficulties).sort()
|
2026-01-02 10:21:29 +01:00
|
|
|
},
|
|
|
|
|
availableQuellen() {
|
|
|
|
|
const quellen = new Set()
|
|
|
|
|
this.enhancedWeaponSkills.forEach(ws => {
|
|
|
|
|
if (ws.source_id && this.availableSources.length > 0) {
|
|
|
|
|
const source = this.availableSources.find(s => s.id === ws.source_id)
|
|
|
|
|
if (source) {
|
|
|
|
|
quellen.add(source.code)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
return Array.from(quellen).sort()
|
|
|
|
|
},
|
2025-01-18 20:59:54 +01:00
|
|
|
filteredAndSortedWaeponSkills() {
|
2026-01-02 10:21:29 +01:00
|
|
|
let filtered = [...this.enhancedWeaponSkills]
|
|
|
|
|
|
|
|
|
|
// Apply search filter
|
|
|
|
|
if (this.searchTerm) {
|
|
|
|
|
const searchLower = this.searchTerm.toLowerCase()
|
|
|
|
|
filtered = filtered.filter(ws =>
|
|
|
|
|
ws.name?.toLowerCase().includes(searchLower) ||
|
2026-01-12 16:36:35 +01:00
|
|
|
ws.difficulty?.toLowerCase().includes(searchLower)
|
2026-01-02 10:21:29 +01:00
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-12 16:36:35 +01:00
|
|
|
// Apply difficulty filter
|
|
|
|
|
if (this.filterDifficulty) {
|
|
|
|
|
filtered = filtered.filter(ws => ws.difficulty === this.filterDifficulty)
|
2026-01-02 10:21:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Apply Quelle filter (only by source code, ignoring page number)
|
|
|
|
|
if (this.filterQuelle) {
|
|
|
|
|
filtered = filtered.filter(ws => {
|
|
|
|
|
if (ws.source_id && this.availableSources.length > 0) {
|
|
|
|
|
const source = this.availableSources.find(s => s.id === ws.source_id)
|
|
|
|
|
return source && source.code === this.filterQuelle
|
|
|
|
|
}
|
|
|
|
|
return false
|
2025-01-18 20:59:54 +01:00
|
|
|
})
|
2026-01-02 10:21:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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
|
2026-02-03 17:21:43 +01:00
|
|
|
},
|
|
|
|
|
systemOptions() {
|
|
|
|
|
return buildSystemOptions(this.gameSystems)
|
2025-01-18 20:59:54 +01:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
2026-02-03 17:21:43 +01:00
|
|
|
async loadGameSystems() {
|
|
|
|
|
try {
|
|
|
|
|
this.gameSystems = await fetchGameSystems()
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Failed to load game systems:', error)
|
|
|
|
|
}
|
|
|
|
|
},
|
2026-01-02 10:21:29 +01:00
|
|
|
async loadEnhancedWeaponSkills() {
|
|
|
|
|
try {
|
|
|
|
|
const response = await API.get('/api/maintenance/weaponskills-enhanced')
|
|
|
|
|
this.enhancedWeaponSkills = response.data.weaponskills || []
|
|
|
|
|
this.availableSources = response.data.sources || []
|
2026-01-12 16:36:35 +01:00
|
|
|
this.availableDifficultiesData = response.data.difficulties || []
|
2026-01-02 10:21:29 +01:00
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Failed to load enhanced weapon skills:', error)
|
|
|
|
|
}
|
|
|
|
|
},
|
2025-01-18 20:59:54 +01:00
|
|
|
startEdit(index) {
|
2026-01-02 10:21:29 +01:00
|
|
|
const weaponSkill = this.filteredAndSortedWaeponSkills[index]
|
|
|
|
|
this.editedItem = {
|
|
|
|
|
...weaponSkill,
|
|
|
|
|
sourceCode: this.getSourceCode(weaponSkill.source_id)
|
|
|
|
|
}
|
2026-02-03 17:21:43 +01:00
|
|
|
this.selectedSystemId = weaponSkill.game_system_id ?? this.findSystemIdByCode(weaponSkill.system)
|
2026-01-02 10:21:29 +01:00
|
|
|
this.editingIndex = index
|
2025-01-18 20:59:54 +01:00
|
|
|
},
|
2026-01-02 10:21:29 +01:00
|
|
|
async saveEdit(index) {
|
|
|
|
|
try {
|
|
|
|
|
// Find source ID from code
|
|
|
|
|
const source = this.availableSources.find(s => s.code === this.editedItem.sourceCode)
|
2026-02-03 17:21:43 +01:00
|
|
|
const selectedSystem = this.gameSystems.find(gs => gs.id === this.selectedSystemId)
|
2026-01-02 10:21:29 +01:00
|
|
|
|
|
|
|
|
const updateData = {
|
|
|
|
|
...this.editedItem,
|
|
|
|
|
source_id: source ? source.id : null,
|
2026-01-12 16:36:35 +01:00
|
|
|
page_number: this.editedItem.page_number || 0,
|
|
|
|
|
difficulty: this.editedItem.difficulty,
|
2026-02-03 17:21:43 +01:00
|
|
|
category: 'Waffen', // Weapon skills always use 'Waffen' category
|
|
|
|
|
system: selectedSystem ? selectedSystem.code : (this.editedItem.system || ''),
|
|
|
|
|
game_system_id: selectedSystem ? selectedSystem.id : (this.editedItem.game_system_id ?? null)
|
2026-01-02 10:21:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const response = await API.put(
|
|
|
|
|
`/api/maintenance/weaponskills-enhanced/${this.editedItem.id}`,
|
|
|
|
|
updateData
|
|
|
|
|
)
|
|
|
|
|
|
2026-01-12 16:36:35 +01:00
|
|
|
// Reload the list to get updated difficulty from backend
|
|
|
|
|
await this.loadEnhancedWeaponSkills()
|
2026-01-02 10:21:29 +01:00
|
|
|
|
|
|
|
|
this.editingIndex = -1
|
|
|
|
|
this.editedItem = null
|
2026-02-03 17:21:43 +01:00
|
|
|
this.selectedSystemId = null
|
2026-01-02 10:21:29 +01:00
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Failed to save weapon skill:', error)
|
|
|
|
|
alert('Failed to save weapon skill: ' + (error.response?.data?.error || error.message))
|
|
|
|
|
}
|
2025-01-18 20:59:54 +01:00
|
|
|
},
|
|
|
|
|
cancelEdit() {
|
2026-01-02 10:21:29 +01:00
|
|
|
this.editingIndex = -1
|
|
|
|
|
this.editedItem = null
|
2026-02-03 17:21:43 +01:00
|
|
|
this.selectedSystemId = null
|
|
|
|
|
},
|
2026-02-04 22:18:37 +01:00
|
|
|
startCreate() {
|
|
|
|
|
this.cancelEdit()
|
|
|
|
|
const defaultSystem = this.gameSystems.find(gs => gs.is_active) || this.gameSystems[0] || null
|
|
|
|
|
this.createSelectedSystemId = defaultSystem ? defaultSystem.id : null
|
|
|
|
|
this.newItem = {
|
|
|
|
|
name: '',
|
|
|
|
|
difficulty: 'leicht',
|
|
|
|
|
initialwert: 0,
|
|
|
|
|
beschreibung: '',
|
|
|
|
|
sourceCode: '',
|
|
|
|
|
page_number: 0,
|
|
|
|
|
system: defaultSystem ? defaultSystem.code : ''
|
|
|
|
|
}
|
|
|
|
|
this.creatingNew = true
|
|
|
|
|
},
|
|
|
|
|
cancelCreate() {
|
|
|
|
|
this.creatingNew = false
|
|
|
|
|
this.newItem = null
|
|
|
|
|
this.createSelectedSystemId = null
|
|
|
|
|
},
|
|
|
|
|
async saveCreate() {
|
|
|
|
|
if (!this.newItem) return
|
|
|
|
|
try {
|
|
|
|
|
const source = this.availableSources.find(s => s.code === this.newItem.sourceCode)
|
|
|
|
|
const selectedSystem = this.gameSystems.find(gs => gs.id === this.createSelectedSystemId)
|
|
|
|
|
|
|
|
|
|
const createData = {
|
|
|
|
|
...this.newItem,
|
|
|
|
|
category: 'Waffen',
|
|
|
|
|
source_id: source ? source.id : null,
|
|
|
|
|
page_number: this.newItem.page_number || 0,
|
|
|
|
|
system: selectedSystem ? selectedSystem.code : (this.newItem.system || ''),
|
|
|
|
|
game_system_id: selectedSystem ? selectedSystem.id : null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const response = await API.post(
|
|
|
|
|
'/api/maintenance/weaponskills-enhanced',
|
|
|
|
|
createData
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
this.enhancedWeaponSkills.push(response.data)
|
|
|
|
|
this.cancelCreate()
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Failed to create weapon skill:', error)
|
|
|
|
|
alert('Failed to create weapon skill: ' + (error.response?.data?.error || error.message))
|
|
|
|
|
}
|
|
|
|
|
},
|
2026-02-03 17:21:43 +01:00
|
|
|
findSystemIdByCode(code) {
|
|
|
|
|
return findSystemIdByCode(this.gameSystems, code)
|
2025-01-18 20:59:54 +01:00
|
|
|
},
|
|
|
|
|
sortBy(field) {
|
|
|
|
|
if (this.sortField === field) {
|
2026-01-02 10:21:29 +01:00
|
|
|
this.sortAsc = !this.sortAsc
|
2025-01-18 20:59:54 +01:00
|
|
|
} else {
|
2026-01-02 10:21:29 +01:00
|
|
|
this.sortField = field
|
|
|
|
|
this.sortAsc = true
|
2025-01-18 20:59:54 +01:00
|
|
|
}
|
|
|
|
|
},
|
2026-01-02 10:21:29 +01:00
|
|
|
formatQuelle(weaponSkill) {
|
|
|
|
|
if (weaponSkill.source_id && this.availableSources.length > 0) {
|
|
|
|
|
const source = this.availableSources.find(s => s.id === weaponSkill.source_id)
|
|
|
|
|
if (source) {
|
|
|
|
|
if (weaponSkill.page_number) {
|
|
|
|
|
return `${source.code}:${weaponSkill.page_number}`
|
|
|
|
|
} else {
|
|
|
|
|
// No page number - show code and quelle if available
|
|
|
|
|
const quelle = weaponSkill.quelle ? ` (${weaponSkill.quelle})` : ''
|
|
|
|
|
return `${source.code}${quelle}`
|
2025-01-18 20:59:54 +01:00
|
|
|
}
|
2026-01-02 10:21:29 +01:00
|
|
|
}
|
2025-01-18 20:59:54 +01:00
|
|
|
}
|
2026-01-02 10:21:29 +01:00
|
|
|
return weaponSkill.quelle || '-'
|
|
|
|
|
},
|
|
|
|
|
getSourceCode(sourceId) {
|
2026-02-03 17:21:43 +01:00
|
|
|
return getSourceCode(this.availableSources, sourceId)
|
|
|
|
|
},
|
|
|
|
|
getSystemCodeById(systemId, fallback = '') {
|
|
|
|
|
return getSystemCodeById(this.gameSystems, systemId, fallback)
|
2026-01-02 10:21:29 +01:00
|
|
|
},
|
|
|
|
|
clearFilters() {
|
|
|
|
|
this.searchTerm = ''
|
2026-01-12 16:36:35 +01:00
|
|
|
this.filterDifficulty = ''
|
2026-01-02 10:21:29 +01:00
|
|
|
this.filterQuelle = ''
|
2025-01-18 20:59:35 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
</script>
|