made efficent handler for spells
added routes for spells maintanance updated model for spells with more fields, default values moved update handlers inside spell and skill components
This commit is contained in:
@@ -7,7 +7,6 @@
|
||||
<component
|
||||
:is="currentView"
|
||||
:mdata="mdata"
|
||||
@update-skill="handleSkillUpdate"
|
||||
/>
|
||||
</div>
|
||||
<!-- Submenu -->
|
||||
@@ -31,8 +30,8 @@
|
||||
<script>
|
||||
import API from '../utils/api'
|
||||
import SkillView from "./maintenance/SkillView.vue"; // Component for character history
|
||||
/*import WeaponSkillView from "./maintenance/WeaponSkillView.vue"; // Component for character equipment
|
||||
import SpellView from "./maintenance/SpellView.vue"; // Component for character history
|
||||
/*import WeaponSkillView from "./maintenance/WeaponSkillView.vue"; // Component for character equipment
|
||||
import EquipmentView from "./maintenance/EquipmentView.vue"; // Component for character equipment
|
||||
import WeaponView from "./maintenance/WeaponView.vue"; // Component for character history
|
||||
*/
|
||||
@@ -43,8 +42,8 @@ export default {
|
||||
//props: ["id"], // Receive the route parameter as a prop
|
||||
components: {
|
||||
SkillView,
|
||||
/*WeaponSkillView,
|
||||
SpellView,
|
||||
/*WeaponSkillView,
|
||||
WeaponView,
|
||||
EquipmentView,*/
|
||||
},
|
||||
@@ -54,7 +53,8 @@ export default {
|
||||
skills: [],
|
||||
skillcategories: [],
|
||||
weaponskills: [],
|
||||
spells: []
|
||||
spells: [],
|
||||
spellcategories: [],
|
||||
},
|
||||
loading: true,
|
||||
/*
|
||||
@@ -67,8 +67,8 @@ export default {
|
||||
lastView: "SkillView",
|
||||
menus: [
|
||||
{ id: 0, name: "skill", component: "SkillView" },
|
||||
/*{ id: 1, name: "weaponskill", component: "WeaponSkillView" },
|
||||
{ id: 2, name: "spell", component: "SpellView" },
|
||||
/*{ id: 1, name: "weaponskill", component: "WeaponSkillView" },
|
||||
{ id: 3, name: "equipment", component: "EquipmentView" },
|
||||
{ id: 1, name: "weapon", component: "WeaponView" },
|
||||
*/
|
||||
@@ -99,28 +99,7 @@ export default {
|
||||
changeView(view) {
|
||||
this.lastView = this.currentView;
|
||||
this.currentView = view;
|
||||
},
|
||||
async handleSkillUpdate({ index, skill }) {
|
||||
try {
|
||||
const response = await API.put(
|
||||
`/api/maintenance/skills/${skill.id}`, skill,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('token')}` ,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
)
|
||||
if (!response.statusText== "OK") throw new Error('Update failed');
|
||||
const updatedSkill = response.data;
|
||||
// Update the skill in mdata
|
||||
this.mdata.skills = this.mdata.skills.map(s =>
|
||||
s.id === updatedSkill.id ? updatedSkill : s
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Failed to update skill:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -122,6 +122,7 @@
|
||||
|
||||
|
||||
<script>
|
||||
import API from '../../utils/api'
|
||||
export default {
|
||||
name: "SkillView",
|
||||
props: {
|
||||
@@ -178,7 +179,8 @@ export default {
|
||||
this.editedItem = { ...this.filteredAndSortedSkills[index] };
|
||||
},
|
||||
saveEdit(index) {
|
||||
this.$emit('update-skill', { index, skill: this.editedItem });
|
||||
//this.$emit('update-skill', { index, skill: this.editedItem });
|
||||
this.handleSkillUpdate({ index, skill: this.editedItem });
|
||||
this.editingIndex = -1;
|
||||
this.editedItem = null;
|
||||
},
|
||||
@@ -193,6 +195,27 @@ export default {
|
||||
this.sortField = field;
|
||||
this.sortAsc = true;
|
||||
}
|
||||
},
|
||||
async handleSkillUpdate({ index, skill }) {
|
||||
try {
|
||||
const response = await API.put(
|
||||
`/api/maintenance/skills/${skill.id}`, skill,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('token')}` ,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
)
|
||||
if (!response.statusText== "OK") throw new Error('Update failed');
|
||||
const updatedSkill = response.data;
|
||||
// Update the skill in mdata
|
||||
this.mdata.skills = this.mdata.skills.map(s =>
|
||||
s.id === updatedSkill.id ? updatedSkill : s
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Failed to update skill:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,43 +1,85 @@
|
||||
<template>
|
||||
<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('Spell')}...`"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cd-view">
|
||||
<div class="cd-list">
|
||||
<div class="tables-container">
|
||||
<h2 style="line-height: 1.5; margin-top: 5px;"><!-- {{ character.name }}'s -->Fertigkeiten</h2>
|
||||
<table class="cd-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="cd-table-header" width="60%">{{ $t('skill.name') }}</th>
|
||||
<th class="cd-table-header" width="35">{{ $t('skill.value') }}</th>
|
||||
<th class="cd-table-header" width="35">{{ $t('skill.bonus') }}</th>
|
||||
<th class="cd-table-header" width="35">{{ $t('skill.pp') }}</th>
|
||||
<!-- <th class="cd-table-header">{{ $t('skill.description') }}</th>-->
|
||||
<th class="cd-table-header" width="30%">{{ $t('skill.note') }}</th>
|
||||
<th class="cd-table-header">{{ $t('spell.id') }}</th>
|
||||
<th class="cd-table-header">{{ $t('spell.category') }}<button @click="sortBy('category')">-{{ sortField === 'category' ? (sortAsc ? '↑' : '↓') : '' }}</button></th>
|
||||
<th class="cd-table-header">{{ $t('spell.name') }} <button @click="sortBy('name')">-{{ sortField === 'name' ? (sortAsc ? '↑' : '↓') : '' }}</button></th>
|
||||
<th class="cd-table-header">{{ $t('spell.level') }}</th>
|
||||
<th class="cd-table-header">{{ $t('spell.apverbrauch') }}</th>
|
||||
<th class="cd-table-header">{{ $t('spell.zauberdauer') }}</th>
|
||||
<th class="cd-table-header">{{ $t('spell.reichweite') }}</th>
|
||||
<th class="cd-table-header">{{ $t('spell.wirkungsziel') }}</th>
|
||||
<th class="cd-table-header">{{ $t('spell.wirkungsbereich') }}</th>
|
||||
<th class="cd-table-header">{{ $t('spell.wirkungsdauer') }}</th>
|
||||
<th class="cd-table-header">{{ $t('spell.ursprung') }}</th>
|
||||
<th class="cd-table-header">{{ $t('spell.description') }}</th>
|
||||
<th class="cd-table-header">{{ $t('spell.quelle') }}</th>
|
||||
<th class="cd-table-header">{{ $t('spell.system') }}</th>
|
||||
<th class="cd-table-header"> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<template v-for="skills,categorie in character.categorizedskills">
|
||||
<tr>
|
||||
<td colspan="6">{{ categorie || '-' }}</td>
|
||||
</tr>
|
||||
<template v-for="skill in skills">
|
||||
<tr>
|
||||
<td>{{ skill.name || '-' }}</td>
|
||||
<td>{{ skill.fertigkeitswert || '-' }}</td>
|
||||
<td>{{ skill.bonus || '0' }}</td>
|
||||
<td>{{ skill.pp || '0' }}</td>
|
||||
<!-- <td>{{ skill.beschreibung || '-' }}</td>-->
|
||||
<td>{{ skill.bemerkung || '-' }}</td>
|
||||
<template v-for="(dtaItem, index) in filteredAndSortedSpells" :key="dtaItem.id">
|
||||
<tr v-if="editingIndex !== index">
|
||||
<td>{{ dtaItem.id || '' }}</td>
|
||||
<td>{{ dtaItem.category|| '-' }}</td>
|
||||
<td>{{ dtaItem.name || '-' }}</td>
|
||||
<td>{{ dtaItem.level || '0' }}</td>
|
||||
<td>{{ dtaItem.ap || '0' }}</td>
|
||||
<td>{{ dtaItem.zauberdauer || '-' }}</td>
|
||||
<td>{{ dtaItem.reichweite || '0' }}</td>
|
||||
<td>{{ dtaItem.wirkungsziel || '-' }}</td>
|
||||
<td>{{ dtaItem.wirkungsbereich || '-' }}</td>
|
||||
<td>{{ dtaItem.wirkungsdauer || '-' }}</td>
|
||||
<td>{{ dtaItem.ursprung || '-' }}</td>
|
||||
<td>{{ dtaItem.beschreibung || '-' }}</td>
|
||||
<td>{{ dtaItem.quelle || '-' }}</td>
|
||||
<td>{{ dtaItem.system || 'midgard' }}</td>
|
||||
<td>
|
||||
<button @click="startEdit(index)">Edit</button>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</template>
|
||||
<template v-for="skill in character.waffenfertigkeiten">
|
||||
<tr>
|
||||
<td>{{ skill.name || '-' }}</td>
|
||||
<td>{{ skill.fertigkeitswert || '-' }}</td>
|
||||
<td>{{ skill.bonus || '0' }}</td>
|
||||
<td>{{ skill.pp || '0' }}</td>
|
||||
<!-- <td>{{ skill.beschreibung || '-' }}</td> -->
|
||||
<td>{{ skill.bemerkung || '-' }}</td>
|
||||
<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['spellcategories']"
|
||||
:key="category"
|
||||
:value="category">
|
||||
{{ category }}
|
||||
</option>
|
||||
</select></td>
|
||||
<td><input v-model="editedItem.name"/></td>
|
||||
<td><input v-model.number="editedItem.level" type="number" style="width:40px;"/></td>
|
||||
<td><input v-model="editedItem.ap" style="width:40px;"/></td>
|
||||
<td><input v-model="editedItem.zauberdauer" /></td>
|
||||
<td><input v-model="editedItem.reichweite" style="width:40px;"/></td>
|
||||
<td><input v-model="editedItem.wirkungsziel" /></td>
|
||||
<td><input v-model="editedItem.wirkungsbereich" /></td>
|
||||
<td><input v-model="editedItem.wirkungsdauer" /></td>
|
||||
<td><input v-model="editedItem.ursprung" /></td>
|
||||
<td><input v-model="editedItem.beschreibung" /></td>
|
||||
<td><input v-model="editedItem.quelle" style="width:80px;"/></td>
|
||||
<td><input v-model="editedItem.system" style="width:80px;"/></td>
|
||||
<td>
|
||||
<button @click="saveEdit(index)">Save</button>
|
||||
<button @click="cancelEdit">Cancel</button>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
@@ -47,7 +89,25 @@
|
||||
</div> <!--- end character -datasheet-->
|
||||
</template>
|
||||
|
||||
<!-- <style scoped> -->
|
||||
<style>
|
||||
.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;
|
||||
}
|
||||
.tables-container {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
@@ -74,13 +134,101 @@
|
||||
|
||||
|
||||
<script>
|
||||
import API from '../../utils/api'
|
||||
export default {
|
||||
name: "SpellView",
|
||||
props: {
|
||||
character: {
|
||||
mdata: {
|
||||
type: Object,
|
||||
required: true
|
||||
required: true,
|
||||
default: () => ({
|
||||
spells: [],
|
||||
spellcategories: []
|
||||
})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
searchTerm: '',
|
||||
sortField: 'name',
|
||||
sortAsc: true,
|
||||
editingIndex: -1,
|
||||
editedItem: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
filteredAndSortedSpells() {
|
||||
if (!this.mdata?.spells) return [];
|
||||
|
||||
return [...this.mdata.spells]
|
||||
.filter(spell => {
|
||||
const searchLower = this.searchTerm.toLowerCase();
|
||||
return !this.searchTerm ||
|
||||
spell.name?.toLowerCase().includes(searchLower) ||
|
||||
spell.category?.toLowerCase().includes(searchLower);
|
||||
})
|
||||
.sort((a, b) => {
|
||||
const aValue = (a[this.sortField] || '').toLowerCase();
|
||||
const bValue = (b[this.sortField] || '').toLowerCase();
|
||||
return this.sortAsc
|
||||
? aValue.localeCompare(bValue)
|
||||
: bValue.localeCompare(aValue);
|
||||
});
|
||||
},
|
||||
sortedSpells() {
|
||||
return [...this.mdata.spells].sort((a, b) => {
|
||||
const aValue = (a[this.sortField] || '').toLowerCase();
|
||||
const bValue = (b[this.sortField] || '').toLowerCase();
|
||||
return this.sortAsc
|
||||
? aValue.localeCompare(bValue)
|
||||
: bValue.localeCompare(aValue);
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
startEdit(index) {
|
||||
this.editingIndex = index;
|
||||
this.editedItem = { ...this.filteredAndSortedSpells[index] };
|
||||
},
|
||||
saveEdit(index) {
|
||||
//this.$emit('update-spell', { index, spell: this.editedItem });
|
||||
this.handleSpellUpdate( { index, spell: this.editedItem });
|
||||
this.editingIndex = -1;
|
||||
this.editedItem = null;
|
||||
},
|
||||
cancelEdit() {
|
||||
this.editingIndex = -1;
|
||||
this.editedItem = null;
|
||||
},
|
||||
sortBy(field) {
|
||||
if (this.sortField === field) {
|
||||
this.sortAsc = !this.sortAsc;
|
||||
} else {
|
||||
this.sortField = field;
|
||||
this.sortAsc = true;
|
||||
}
|
||||
},
|
||||
async handleSpellUpdate({ index, spell }) {
|
||||
try {
|
||||
const response = await API.put(
|
||||
`/api/maintenance/spells/${spell.id}`, spell,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('token')}` ,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
)
|
||||
if (!response.statusText== "OK") throw new Error('Update failed');
|
||||
const updatedSkill = response.data;
|
||||
// Update the spell in mdata
|
||||
this.mdata.spells = this.mdata.spells.map(s =>
|
||||
s.id === updatedSkill.id ? updatedSkill : s
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Failed to update spell:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
+14
-2
@@ -58,12 +58,24 @@ export default {
|
||||
initialwert:'Startwert',
|
||||
},
|
||||
spell:{
|
||||
id:'ID',
|
||||
category:'Kategorie',
|
||||
name:'Name',
|
||||
description:'Beschreibung',
|
||||
bonus:'Bonus',
|
||||
pp:'AP',
|
||||
level:'Stufe',
|
||||
art:'Art', //GestenZauber, GedankenZauber, WortZauber
|
||||
apverbrauch:'AP',
|
||||
zauberdauer:'Zauberdauer',
|
||||
reichweite:'Reichweite',
|
||||
wirkungsziel:'Wirkungsziel',
|
||||
wirkungsbereich:'Wirkungsbereich',
|
||||
wirkungsdauer:'Wirkungsdauer',
|
||||
ursprung:'Ursprung',
|
||||
quelle:'Quelle',
|
||||
system:'System',
|
||||
|
||||
},
|
||||
Spell:'Zauber',
|
||||
weapon:{
|
||||
name:'Name',
|
||||
description:'Beschreibung',
|
||||
|
||||
Reference in New Issue
Block a user