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{
|
feC := &models.FeChar{
|
||||||
Char: *object,
|
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)
|
skills, innateSkills, categories := splitSkills(object.Fertigkeiten)
|
||||||
feC.Fertigkeiten = skills
|
feC.Fertigkeiten = skills
|
||||||
feC.InnateSkills = innateSkills
|
feC.InnateSkills = innateSkills
|
||||||
@@ -199,6 +205,32 @@ func ToFeChar(object *models.Char) *models.FeChar {
|
|||||||
return feC
|
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) {
|
func splitSkills(object []models.SkFertigkeit) ([]models.SkFertigkeit, []models.SkFertigkeit, map[string][]models.SkFertigkeit) {
|
||||||
var normSkills []models.SkFertigkeit
|
var normSkills []models.SkFertigkeit
|
||||||
var innateSkills []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)
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,15 @@
|
|||||||
<div class="tables-container">
|
<div class="tables-container">
|
||||||
<div class="table-wrapper-left">
|
<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 -->
|
<!-- Lernmodus Toggle Button -->
|
||||||
<div v-if="isOwner" class="learning-mode-controls">
|
<div v-if="isOwner" class="learning-mode-controls">
|
||||||
<!-- Ressourcen-Anzeige (nur sichtbar wenn Lernmodus aktiv) -->
|
<!-- Ressourcen-Anzeige (nur sichtbar wenn Lernmodus aktiv) -->
|
||||||
@@ -64,8 +73,42 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<template v-for="skill in skills">
|
<template v-for="skill in skills">
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ skill.name || '-' }}</td>
|
<td>
|
||||||
<td>{{ skill.fertigkeitswert || '-' }}</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>{{ skill.bonus || '0' }}</td>
|
||||||
<td class="pp-cell">
|
<td class="pp-cell">
|
||||||
<div v-if="isOwner" class="pp-container">
|
<div v-if="isOwner" class="pp-container">
|
||||||
@@ -88,7 +131,23 @@
|
|||||||
</div>
|
</div>
|
||||||
<span v-else>{{ skill.pp || '0' }}</span>
|
<span v-else>{{ skill.pp || '0' }}</span>
|
||||||
</td>
|
</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">
|
<td v-if="learningMode" class="action-cell">
|
||||||
<button
|
<button
|
||||||
@click="improveSkill(skill)"
|
@click="improveSkill(skill)"
|
||||||
@@ -106,8 +165,42 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<template v-for="skill in character.waffenfertigkeiten">
|
<template v-for="skill in character.waffenfertigkeiten">
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ skill.name || '-' }}</td>
|
<td>
|
||||||
<td>{{ skill.fertigkeitswert || '-' }}</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>{{ skill.bonus || '0' }}</td>
|
||||||
<td class="pp-cell">
|
<td class="pp-cell">
|
||||||
<div v-if="isOwner" class="pp-container">
|
<div v-if="isOwner" class="pp-container">
|
||||||
@@ -130,7 +223,23 @@
|
|||||||
</div>
|
</div>
|
||||||
<span v-else>{{ skill.pp || '0' }}</span>
|
<span v-else>{{ skill.pp || '0' }}</span>
|
||||||
</td>
|
</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">
|
<td v-if="learningMode" class="action-cell">
|
||||||
<button
|
<button
|
||||||
@click="improveWeaponSkill(skill)"
|
@click="improveWeaponSkill(skill)"
|
||||||
@@ -318,6 +427,11 @@ export default {
|
|||||||
selectedSkillToLearn: null,
|
selectedSkillToLearn: null,
|
||||||
selectedLearningType: 'improve', // 'improve', 'learn', 'spell'
|
selectedLearningType: 'improve', // 'improve', 'learn', 'spell'
|
||||||
|
|
||||||
|
// Inline editing
|
||||||
|
editingSkillId: null,
|
||||||
|
editingField: null,
|
||||||
|
editValue: '',
|
||||||
|
|
||||||
isLoading: false
|
isLoading: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -623,6 +737,72 @@ export default {
|
|||||||
skill.pp = ppMap[skill.name] || 0;
|
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