Edit in skill view (#32)
* added editing to SkillView * added bonus for leiteigenschaft to skill
This commit is contained in:
@@ -191,6 +191,12 @@ func ToFeChar(object *models.Char) *models.FeChar {
|
||||
feC := &models.FeChar{
|
||||
Char: *object,
|
||||
}
|
||||
for idx, fertigkeit := range object.Fertigkeiten {
|
||||
fertigkeit.Bonus = GetSkillBonus(&object.Eigenschaften, &fertigkeit)
|
||||
if fertigkeit.Bonus > 0 {
|
||||
object.Fertigkeiten[idx].Bonus = fertigkeit.Bonus
|
||||
}
|
||||
}
|
||||
skills, innateSkills, categories := splitSkills(object.Fertigkeiten)
|
||||
feC.Fertigkeiten = skills
|
||||
feC.InnateSkills = innateSkills
|
||||
@@ -199,6 +205,32 @@ func ToFeChar(object *models.Char) *models.FeChar {
|
||||
return feC
|
||||
}
|
||||
|
||||
func GetSkillBonus(eigenschaften *[]models.Eigenschaft, skill *models.SkFertigkeit) int {
|
||||
bonus := 0
|
||||
gsmsk := skill.GetSkillByName()
|
||||
if gsmsk.Bonuseigenschaft != "check" {
|
||||
for _, eigenschaft := range *eigenschaften {
|
||||
if eigenschaft.Name == gsmsk.Bonuseigenschaft {
|
||||
if eigenschaft.Value < 6 {
|
||||
bonus = -2
|
||||
break
|
||||
} else if eigenschaft.Value < 21 {
|
||||
bonus = -1
|
||||
break
|
||||
} else if eigenschaft.Value > 81 && eigenschaft.Value < 96 {
|
||||
bonus = 1
|
||||
break
|
||||
} else if eigenschaft.Value >= 96 {
|
||||
bonus = 2
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
skill.Bonus = bonus
|
||||
return bonus
|
||||
}
|
||||
|
||||
func splitSkills(object []models.SkFertigkeit) ([]models.SkFertigkeit, []models.SkFertigkeit, map[string][]models.SkFertigkeit) {
|
||||
var normSkills []models.SkFertigkeit
|
||||
var innateSkills []models.SkFertigkeit
|
||||
|
||||
@@ -1198,3 +1198,15 @@ func TestSearchBeliefs(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestToFeChar(t *testing.T) {
|
||||
// Setup test database
|
||||
database.SetupTestDB(true)
|
||||
defer database.ResetTestDB()
|
||||
char := &models.Char{}
|
||||
char.FirstID("18")
|
||||
feChar := ToFeChar(char)
|
||||
assert.Equal(t, "18", feChar.ID)
|
||||
assert.Equal(t, 2, feChar.Fertigkeiten[6].Bonus)
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,16 @@
|
||||
<div class="cd-list">
|
||||
<div class="tables-container">
|
||||
<div class="table-wrapper-left">
|
||||
<div class="header-section">
|
||||
<div class="header-section">
|
||||
<span
|
||||
v-if="isOwner"
|
||||
class="help-icon"
|
||||
:title="$t('characters.datasheet.editHelp')"
|
||||
role="img"
|
||||
:aria-label="$t('characters.datasheet.editHelp')"
|
||||
>
|
||||
?
|
||||
</span>
|
||||
<!-- Lernmodus Toggle Button -->
|
||||
<div v-if="isOwner" class="learning-mode-controls">
|
||||
<!-- Ressourcen-Anzeige (nur sichtbar wenn Lernmodus aktiv) -->
|
||||
@@ -64,8 +73,42 @@
|
||||
</tr>
|
||||
<template v-for="skill in skills">
|
||||
<tr>
|
||||
<td>{{ skill.name || '-' }}</td>
|
||||
<td>{{ skill.fertigkeitswert || '-' }}</td>
|
||||
<td>
|
||||
<span
|
||||
v-if="!isEditingSkill(skill, 'name')"
|
||||
@dblclick="isOwner ? startEditSkill(skill, 'name') : null"
|
||||
:class="{ 'editable-prop': isOwner }"
|
||||
>{{ skill.name || '-' }}</span>
|
||||
<input
|
||||
v-else
|
||||
v-model="editValue"
|
||||
@blur="saveEditSkill(skill, 'name')"
|
||||
@keyup.enter="saveEditSkill(skill, 'name')"
|
||||
@keyup.esc="cancelEditSkill"
|
||||
ref="editInput"
|
||||
class="prop-input"
|
||||
type="text"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<span
|
||||
v-if="!isEditingSkill(skill, 'fertigkeitswert')"
|
||||
@dblclick="isOwner ? startEditSkill(skill, 'fertigkeitswert') : null"
|
||||
:class="{ 'editable-prop': isOwner }"
|
||||
>{{ skill.fertigkeitswert || '-' }}</span>
|
||||
<input
|
||||
v-else
|
||||
v-model="editValue"
|
||||
@blur="saveEditSkill(skill, 'fertigkeitswert')"
|
||||
@keyup.enter="saveEditSkill(skill, 'fertigkeitswert')"
|
||||
@keyup.esc="cancelEditSkill"
|
||||
ref="editInput"
|
||||
class="prop-input"
|
||||
type="number"
|
||||
min="0"
|
||||
max="20"
|
||||
/>
|
||||
</td>
|
||||
<td>{{ skill.bonus || '0' }}</td>
|
||||
<td class="pp-cell">
|
||||
<div v-if="isOwner" class="pp-container">
|
||||
@@ -88,7 +131,23 @@
|
||||
</div>
|
||||
<span v-else>{{ skill.pp || '0' }}</span>
|
||||
</td>
|
||||
<td>{{ skill.bemerkung || '-' }}</td>
|
||||
<td>
|
||||
<span
|
||||
v-if="!isEditingSkill(skill, 'bemerkung')"
|
||||
@dblclick="isOwner ? startEditSkill(skill, 'bemerkung') : null"
|
||||
:class="{ 'editable-prop': isOwner }"
|
||||
>{{ skill.bemerkung || '-' }}</span>
|
||||
<input
|
||||
v-else
|
||||
v-model="editValue"
|
||||
@blur="saveEditSkill(skill, 'bemerkung')"
|
||||
@keyup.enter="saveEditSkill(skill, 'bemerkung')"
|
||||
@keyup.esc="cancelEditSkill"
|
||||
ref="editInput"
|
||||
class="prop-input"
|
||||
type="text"
|
||||
/>
|
||||
</td>
|
||||
<td v-if="learningMode" class="action-cell">
|
||||
<button
|
||||
@click="improveSkill(skill)"
|
||||
@@ -106,8 +165,42 @@
|
||||
</tr>
|
||||
<template v-for="skill in character.waffenfertigkeiten">
|
||||
<tr>
|
||||
<td>{{ skill.name || '-' }}</td>
|
||||
<td>{{ skill.fertigkeitswert || '-' }}</td>
|
||||
<td>
|
||||
<span
|
||||
v-if="!isEditingSkill(skill, 'name')"
|
||||
@dblclick="isOwner ? startEditSkill(skill, 'name') : null"
|
||||
:class="{ 'editable-prop': isOwner }"
|
||||
>{{ skill.name || '-' }}</span>
|
||||
<input
|
||||
v-else
|
||||
v-model="editValue"
|
||||
@blur="saveEditSkill(skill, 'name')"
|
||||
@keyup.enter="saveEditSkill(skill, 'name')"
|
||||
@keyup.esc="cancelEditSkill"
|
||||
ref="editInput"
|
||||
class="prop-input"
|
||||
type="text"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<span
|
||||
v-if="!isEditingSkill(skill, 'fertigkeitswert')"
|
||||
@dblclick="isOwner ? startEditSkill(skill, 'fertigkeitswert') : null"
|
||||
:class="{ 'editable-prop': isOwner }"
|
||||
>{{ skill.fertigkeitswert || '-' }}</span>
|
||||
<input
|
||||
v-else
|
||||
v-model="editValue"
|
||||
@blur="saveEditSkill(skill, 'fertigkeitswert')"
|
||||
@keyup.enter="saveEditSkill(skill, 'fertigkeitswert')"
|
||||
@keyup.esc="cancelEditSkill"
|
||||
ref="editInput"
|
||||
class="prop-input"
|
||||
type="number"
|
||||
min="0"
|
||||
max="20"
|
||||
/>
|
||||
</td>
|
||||
<td>{{ skill.bonus || '0' }}</td>
|
||||
<td class="pp-cell">
|
||||
<div v-if="isOwner" class="pp-container">
|
||||
@@ -130,7 +223,23 @@
|
||||
</div>
|
||||
<span v-else>{{ skill.pp || '0' }}</span>
|
||||
</td>
|
||||
<td>{{ skill.bemerkung || '-' }}</td>
|
||||
<td>
|
||||
<span
|
||||
v-if="!isEditingSkill(skill, 'bemerkung')"
|
||||
@dblclick="isOwner ? startEditSkill(skill, 'bemerkung') : null"
|
||||
:class="{ 'editable-prop': isOwner }"
|
||||
>{{ skill.bemerkung || '-' }}</span>
|
||||
<input
|
||||
v-else
|
||||
v-model="editValue"
|
||||
@blur="saveEditSkill(skill, 'bemerkung')"
|
||||
@keyup.enter="saveEditSkill(skill, 'bemerkung')"
|
||||
@keyup.esc="cancelEditSkill"
|
||||
ref="editInput"
|
||||
class="prop-input"
|
||||
type="text"
|
||||
/>
|
||||
</td>
|
||||
<td v-if="learningMode" class="action-cell">
|
||||
<button
|
||||
@click="improveWeaponSkill(skill)"
|
||||
@@ -318,6 +427,11 @@ export default {
|
||||
selectedSkillToLearn: null,
|
||||
selectedLearningType: 'improve', // 'improve', 'learn', 'spell'
|
||||
|
||||
// Inline editing
|
||||
editingSkillId: null,
|
||||
editingField: null,
|
||||
editValue: '',
|
||||
|
||||
isLoading: false
|
||||
};
|
||||
},
|
||||
@@ -623,6 +737,72 @@ export default {
|
||||
skill.pp = ppMap[skill.name] || 0;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// Inline editing methods
|
||||
getSkillId(skill) {
|
||||
// Create unique ID combining name and type
|
||||
return `${skill.name}_${skill.kategorie || 'weapon'}`;
|
||||
},
|
||||
|
||||
startEditSkill(skill, field) {
|
||||
if (!this.isOwner) return;
|
||||
|
||||
this.editingSkillId = this.getSkillId(skill);
|
||||
this.editingField = field;
|
||||
this.editValue = skill[field] || '';
|
||||
|
||||
this.$nextTick(() => {
|
||||
const input = this.$refs.editInput;
|
||||
if (input) {
|
||||
const element = Array.isArray(input) ? input[0] : input;
|
||||
if (element) {
|
||||
element.focus();
|
||||
if (element.select) element.select();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
async saveEditSkill(skill, field) {
|
||||
if (this.editingSkillId === null) return;
|
||||
|
||||
let newValue = this.editValue;
|
||||
|
||||
// Validate and convert for fertigkeitswert
|
||||
if (field === 'fertigkeitswert') {
|
||||
newValue = parseInt(this.editValue);
|
||||
if (isNaN(newValue) || newValue < 0 || newValue > 20) {
|
||||
alert('Fertigkeitswert muss zwischen 0 und 20 liegen.');
|
||||
this.cancelEditSkill();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Update local character object
|
||||
skill[field] = newValue;
|
||||
|
||||
try {
|
||||
// Save to backend
|
||||
await API.put(`/api/characters/${this.character.id}`, this.character);
|
||||
|
||||
this.$emit('character-updated');
|
||||
this.cancelEditSkill();
|
||||
} catch (error) {
|
||||
console.error('Failed to update skill:', error);
|
||||
alert('Fehler beim Speichern: ' + (error.response?.data?.error || error.message));
|
||||
this.cancelEditSkill();
|
||||
}
|
||||
},
|
||||
|
||||
cancelEditSkill() {
|
||||
this.editingSkillId = null;
|
||||
this.editingField = null;
|
||||
this.editValue = '';
|
||||
},
|
||||
|
||||
isEditingSkill(skill, field) {
|
||||
return this.editingSkillId === this.getSkillId(skill) && this.editingField === field;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user