Update maintenance Component for Spells
This commit is contained in:
@@ -161,6 +161,7 @@ func GetMasterData(c *gin.Context) {
|
|||||||
Weapons []models.Weapon `json:"weapons"`
|
Weapons []models.Weapon `json:"weapons"`
|
||||||
SkillCategories []string `json:"skillcategories"`
|
SkillCategories []string `json:"skillcategories"`
|
||||||
SpellCategories []string `json:"spellcategories"`
|
SpellCategories []string `json:"spellcategories"`
|
||||||
|
Sources []models.Source `json:"sources"`
|
||||||
}
|
}
|
||||||
var dta dtaStruct
|
var dta dtaStruct
|
||||||
var err error
|
var err error
|
||||||
@@ -186,6 +187,10 @@ func GetMasterData(c *gin.Context) {
|
|||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve Weapons"})
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve Weapons"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if err := database.DB.Find(&dta.Sources).Error; err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve Sources"})
|
||||||
|
return
|
||||||
|
}
|
||||||
dta.SkillCategories, err = ski.GetSkillCategories()
|
dta.SkillCategories, err = ski.GetSkillCategories()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve SkillCategories" + err.Error()})
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve SkillCategories" + err.Error()})
|
||||||
|
|||||||
@@ -27,8 +27,11 @@ func RegisterRoutes(r *gin.RouterGroup) {
|
|||||||
maintGrp.DELETE("/weaponskills/:id", DeleteMDWeaponSkill)
|
maintGrp.DELETE("/weaponskills/:id", DeleteMDWeaponSkill)
|
||||||
|
|
||||||
maintGrp.GET("/spells", GetMDSpells)
|
maintGrp.GET("/spells", GetMDSpells)
|
||||||
|
maintGrp.GET("/spells-enhanced", GetEnhancedMDSpells) // New enhanced endpoint
|
||||||
maintGrp.GET("/spells/:id", GetMDSpell)
|
maintGrp.GET("/spells/:id", GetMDSpell)
|
||||||
|
maintGrp.GET("/spells-enhanced/:id", GetEnhancedMDSpell) // New enhanced endpoint
|
||||||
maintGrp.PUT("/spells/:id", UpdateMDSpell)
|
maintGrp.PUT("/spells/:id", UpdateMDSpell)
|
||||||
|
maintGrp.PUT("/spells-enhanced/:id", UpdateEnhancedMDSpell) // New enhanced endpoint
|
||||||
maintGrp.POST("/spells", AddSpell)
|
maintGrp.POST("/spells", AddSpell)
|
||||||
maintGrp.DELETE("/spells/:id", DeleteMDSpell)
|
maintGrp.DELETE("/spells/:id", DeleteMDSpell)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,147 @@
|
|||||||
|
package gsmaster
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bamort/database"
|
||||||
|
"bamort/models"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SpellWithCategories represents a spell with enhanced information
|
||||||
|
type SpellWithCategories struct {
|
||||||
|
models.Spell
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSpellWithCategories retrieves a spell with all its information
|
||||||
|
func GetSpellWithCategories(spellID uint) (*SpellWithCategories, error) {
|
||||||
|
var spell models.Spell
|
||||||
|
if err := database.DB.First(&spell, spellID).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := &SpellWithCategories{
|
||||||
|
Spell: spell,
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllSpellsWithCategories retrieves all spells
|
||||||
|
func GetAllSpellsWithCategories() ([]SpellWithCategories, error) {
|
||||||
|
var spells []models.Spell
|
||||||
|
if err := database.DB.Find(&spells).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]SpellWithCategories, len(spells))
|
||||||
|
for i, spell := range spells {
|
||||||
|
spellWithCats, err := GetSpellWithCategories(spell.ID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result[i] = *spellWithCats
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SpellUpdateRequest represents the request to update a spell
|
||||||
|
type SpellUpdateRequest struct {
|
||||||
|
models.Spell
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateSpellWithCategories updates a spell
|
||||||
|
func UpdateSpellWithCategories(spellID uint, req SpellUpdateRequest) error {
|
||||||
|
// Start transaction
|
||||||
|
return database.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
|
// Update spell info
|
||||||
|
if err := tx.Model(&models.Spell{}).Where("id = ?", spellID).Updates(req.Spell).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== Handler Functions =====
|
||||||
|
|
||||||
|
// GetEnhancedMDSpells returns spells with enhanced information
|
||||||
|
func GetEnhancedMDSpells(c *gin.Context) {
|
||||||
|
spells, err := GetAllSpellsWithCategories()
|
||||||
|
if err != nil {
|
||||||
|
respondWithError(c, http.StatusInternalServerError, "Failed to retrieve spells: "+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also get learning sources and categories for the dropdowns
|
||||||
|
var sources []models.Source
|
||||||
|
database.DB.Where("is_active = ?", true).Find(&sources)
|
||||||
|
|
||||||
|
// Get spell categories
|
||||||
|
var spell models.Spell
|
||||||
|
categories, err := spell.GetSpellCategories()
|
||||||
|
if err != nil {
|
||||||
|
respondWithError(c, http.StatusInternalServerError, "Failed to retrieve spell categories: "+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"spells": spells,
|
||||||
|
"sources": sources,
|
||||||
|
"categories": categories,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEnhancedMDSpell returns a single spell with enhanced information
|
||||||
|
func GetEnhancedMDSpell(c *gin.Context) {
|
||||||
|
idStr := c.Param("id")
|
||||||
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
respondWithError(c, http.StatusBadRequest, "Invalid ID")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
spell, err := GetSpellWithCategories(uint(id))
|
||||||
|
if err != nil {
|
||||||
|
respondWithError(c, http.StatusNotFound, "Spell not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, spell)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateEnhancedMDSpell updates a spell
|
||||||
|
func UpdateEnhancedMDSpell(c *gin.Context) {
|
||||||
|
idStr := c.Param("id")
|
||||||
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
respondWithError(c, http.StatusBadRequest, "Invalid ID")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var req SpellUpdateRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
respondWithError(c, http.StatusBadRequest, "Invalid request: "+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the ID matches
|
||||||
|
req.Spell.ID = uint(id)
|
||||||
|
|
||||||
|
if err := UpdateSpellWithCategories(uint(id), req); err != nil {
|
||||||
|
respondWithError(c, http.StatusInternalServerError, "Failed to update spell: "+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return updated spell
|
||||||
|
spell, err := GetSpellWithCategories(uint(id))
|
||||||
|
if err != nil {
|
||||||
|
respondWithError(c, http.StatusInternalServerError, "Failed to retrieve updated spell")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, spell)
|
||||||
|
}
|
||||||
@@ -46,13 +46,45 @@
|
|||||||
|
|
||||||
<div class="cd-view">
|
<div class="cd-view">
|
||||||
<div class="cd-list">
|
<div class="cd-list">
|
||||||
|
<!-- Filter Row -->
|
||||||
|
<div class="filter-row">
|
||||||
|
<div class="filter-item">
|
||||||
|
<label>{{ $t('spell.category') }}:</label>
|
||||||
|
<select v-model="filterCategory">
|
||||||
|
<option value="">{{ $t('all') || 'All' }}</option>
|
||||||
|
<option v-for="cat in availableCategories" :key="cat" :value="cat">{{ cat }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="filter-item">
|
||||||
|
<label>{{ $t('spell.level') }}:</label>
|
||||||
|
<select v-model="filterLevel">
|
||||||
|
<option value="">{{ $t('all') || 'All' }}</option>
|
||||||
|
<option v-for="level in availableLevels" :key="level" :value="level">{{ level }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="filter-item">
|
||||||
|
<label>{{ $t('spell.ursprung') }}:</label>
|
||||||
|
<select v-model="filterUrsprung">
|
||||||
|
<option value="">{{ $t('all') || 'All' }}</option>
|
||||||
|
<option v-for="ursprung in availableUrsprungs" :key="ursprung" :value="ursprung">{{ ursprung }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<button @click="clearFilters" class="btn-clear-filters">{{ $t('clearFilters') || 'Clear Filters' }}</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="tables-container">
|
<div class="tables-container">
|
||||||
<table class="cd-table">
|
<table class="cd-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="cd-table-header">{{ $t('spell.id') }}</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">
|
||||||
<th class="cd-table-header">{{ $t('spell.name') }} <button @click="sortBy('name')">-{{ sortField === 'name' ? (sortAsc ? '↑' : '↓') : '' }}</button></th>
|
{{ $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.level') }}</th>
|
||||||
<th class="cd-table-header">{{ $t('spell.apverbrauch') }}</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.zauberdauer') }}</th>
|
||||||
@@ -82,36 +114,103 @@
|
|||||||
<td>{{ dtaItem.wirkungsdauer || '-' }}</td>
|
<td>{{ dtaItem.wirkungsdauer || '-' }}</td>
|
||||||
<td>{{ dtaItem.ursprung || '-' }}</td>
|
<td>{{ dtaItem.ursprung || '-' }}</td>
|
||||||
<td>{{ dtaItem.beschreibung || '-' }}</td>
|
<td>{{ dtaItem.beschreibung || '-' }}</td>
|
||||||
<td>{{ dtaItem.quelle || '-' }}</td>
|
<td>{{ formatQuelle(dtaItem) }}</td>
|
||||||
<td>{{ dtaItem.system || 'midgard' }}</td>
|
<td>{{ dtaItem.system || 'midgard' }}</td>
|
||||||
<td>
|
<td>
|
||||||
<button @click="startEdit(index)">Edit</button>
|
<button @click="startEdit(index)">Edit</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<!-- Edit Mode -->
|
||||||
<tr v-else>
|
<tr v-else>
|
||||||
<td><input v-model="editedItem.id" style="width:20px;"/></td>
|
<td><input v-model="editedItem.id" style="width:20px;" disabled /></td>
|
||||||
<td><select v-model="editedItem.category" style="width:80px;">
|
<td colspan="14">
|
||||||
<option v-for="category in mdata['spellcategories']"
|
<!-- Expanded edit form -->
|
||||||
:key="category"
|
<div class="edit-form">
|
||||||
:value="category">
|
<div class="edit-row">
|
||||||
{{ category }}
|
<div class="edit-field">
|
||||||
</option>
|
<label>{{ $t('spell.name') }}:</label>
|
||||||
</select></td>
|
<input v-model="editedItem.name" />
|
||||||
<td><input v-model="editedItem.name"/></td>
|
</div>
|
||||||
<td><input v-model.number="editedItem.level" type="number" style="width:40px;"/></td>
|
<div class="edit-field">
|
||||||
<td><input v-model="editedItem.ap" style="width:40px;"/></td>
|
<label>{{ $t('spell.category') }}:</label>
|
||||||
<td><input v-model="editedItem.zauberdauer" /></td>
|
<select v-model="editedItem.category" style="width:120px;">
|
||||||
<td><input v-model="editedItem.reichweite" style="width:40px;"/></td>
|
<option v-for="category in mdata['spellcategories']" :key="category" :value="category">
|
||||||
<td><input v-model="editedItem.wirkungsziel" /></td>
|
{{ category }}
|
||||||
<td><input v-model="editedItem.wirkungsbereich" /></td>
|
</option>
|
||||||
<td><input v-model="editedItem.wirkungsdauer" /></td>
|
</select>
|
||||||
<td><input v-model="editedItem.ursprung" /></td>
|
</div>
|
||||||
<td><input v-model="editedItem.beschreibung" /></td>
|
<div class="edit-field">
|
||||||
<td><input v-model="editedItem.quelle" style="width:80px;"/></td>
|
<label>{{ $t('spell.level') }}:</label>
|
||||||
<td><input v-model="editedItem.system" style="width:80px;"/></td>
|
<input v-model.number="editedItem.level" type="number" style="width:60px;" />
|
||||||
<td>
|
</div>
|
||||||
<button @click="saveEdit(index)">Save</button>
|
<div class="edit-field">
|
||||||
<button @click="cancelEdit">Cancel</button>
|
<label>{{ $t('spell.apverbrauch') }}:</label>
|
||||||
|
<input v-model="editedItem.ap" style="width:60px;" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="edit-row">
|
||||||
|
<div class="edit-field">
|
||||||
|
<label>{{ $t('spell.zauberdauer') }}:</label>
|
||||||
|
<input v-model="editedItem.zauberdauer" style="width:120px;" />
|
||||||
|
</div>
|
||||||
|
<div class="edit-field">
|
||||||
|
<label>{{ $t('spell.reichweite') }}:</label>
|
||||||
|
<input v-model="editedItem.reichweite" style="width:120px;" />
|
||||||
|
</div>
|
||||||
|
<div class="edit-field">
|
||||||
|
<label>{{ $t('spell.wirkungsdauer') }}:</label>
|
||||||
|
<input v-model="editedItem.wirkungsdauer" style="width:120px;" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="edit-row">
|
||||||
|
<div class="edit-field">
|
||||||
|
<label>{{ $t('spell.wirkungsziel') }}:</label>
|
||||||
|
<input v-model="editedItem.wirkungsziel" style="width:150px;" />
|
||||||
|
</div>
|
||||||
|
<div class="edit-field">
|
||||||
|
<label>{{ $t('spell.wirkungsbereich') }}:</label>
|
||||||
|
<input v-model="editedItem.wirkungsbereich" style="width:150px;" />
|
||||||
|
</div>
|
||||||
|
<div class="edit-field">
|
||||||
|
<label>{{ $t('spell.ursprung') }}:</label>
|
||||||
|
<input v-model="editedItem.ursprung" style="width:120px;" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="edit-row">
|
||||||
|
<div class="edit-field full-width">
|
||||||
|
<label>{{ $t('spell.description') }}:</label>
|
||||||
|
<input v-model="editedItem.beschreibung" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="edit-row">
|
||||||
|
<div class="edit-field">
|
||||||
|
<label>{{ $t('spell.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('spell.page') || 'Page' }}:</label>
|
||||||
|
<input v-model.number="editedItem.page_number" type="number" style="width:60px;" />
|
||||||
|
</div>
|
||||||
|
<div class="edit-field">
|
||||||
|
<label>{{ $t('spell.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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
@@ -255,27 +354,74 @@ export default {
|
|||||||
editedItem: null,
|
editedItem: null,
|
||||||
selectedFile: null,
|
selectedFile: null,
|
||||||
importing: false,
|
importing: false,
|
||||||
importResult: null
|
importResult: null,
|
||||||
|
filterCategory: '',
|
||||||
|
filterLevel: '',
|
||||||
|
filterUrsprung: '',
|
||||||
|
enhancedSpells: [],
|
||||||
|
availableSources: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async created() {
|
||||||
|
await this.loadEnhancedSpells()
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
availableCategories() {
|
||||||
|
const categories = new Set()
|
||||||
|
this.enhancedSpells.forEach(spell => {
|
||||||
|
if (spell.category) categories.add(spell.category)
|
||||||
|
})
|
||||||
|
return Array.from(categories).sort()
|
||||||
|
},
|
||||||
|
availableLevels() {
|
||||||
|
const levels = new Set()
|
||||||
|
this.enhancedSpells.forEach(spell => {
|
||||||
|
if (spell.level !== null && spell.level !== undefined) levels.add(spell.level)
|
||||||
|
})
|
||||||
|
return Array.from(levels).sort((a, b) => a - b)
|
||||||
|
},
|
||||||
|
availableUrsprungs() {
|
||||||
|
const ursprungs = new Set()
|
||||||
|
this.enhancedSpells.forEach(spell => {
|
||||||
|
if (spell.ursprung) ursprungs.add(spell.ursprung)
|
||||||
|
})
|
||||||
|
return Array.from(ursprungs).sort()
|
||||||
|
},
|
||||||
filteredAndSortedSpells() {
|
filteredAndSortedSpells() {
|
||||||
if (!this.mdata?.spells) return [];
|
let filtered = [...this.enhancedSpells]
|
||||||
|
|
||||||
return [...this.mdata.spells]
|
// Apply search filter
|
||||||
.filter(spell => {
|
if (this.searchTerm) {
|
||||||
const searchLower = this.searchTerm.toLowerCase();
|
const searchLower = this.searchTerm.toLowerCase()
|
||||||
return !this.searchTerm ||
|
filtered = filtered.filter(spell =>
|
||||||
spell.name?.toLowerCase().includes(searchLower) ||
|
spell.name?.toLowerCase().includes(searchLower) ||
|
||||||
spell.category?.toLowerCase().includes(searchLower);
|
spell.category?.toLowerCase().includes(searchLower)
|
||||||
})
|
)
|
||||||
.sort((a, b) => {
|
}
|
||||||
const aValue = (a[this.sortField] || '').toLowerCase();
|
|
||||||
const bValue = (b[this.sortField] || '').toLowerCase();
|
// Apply category filter
|
||||||
return this.sortAsc
|
if (this.filterCategory) {
|
||||||
? aValue.localeCompare(bValue)
|
filtered = filtered.filter(spell => spell.category === this.filterCategory)
|
||||||
: bValue.localeCompare(aValue);
|
}
|
||||||
});
|
|
||||||
|
// Apply level filter
|
||||||
|
if (this.filterLevel !== '') {
|
||||||
|
filtered = filtered.filter(spell => spell.level === this.filterLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply ursprung filter
|
||||||
|
if (this.filterUrsprung) {
|
||||||
|
filtered = filtered.filter(spell => spell.ursprung === this.filterUrsprung)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
},
|
},
|
||||||
sortedSpells() {
|
sortedSpells() {
|
||||||
return [...this.mdata.spells].sort((a, b) => {
|
return [...this.mdata.spells].sort((a, b) => {
|
||||||
@@ -288,15 +434,55 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
startEdit(index) {
|
async loadEnhancedSpells() {
|
||||||
this.editingIndex = index;
|
try {
|
||||||
this.editedItem = { ...this.filteredAndSortedSpells[index] };
|
const response = await API.get('/api/maintenance/spells-enhanced')
|
||||||
|
this.enhancedSpells = response.data.spells || []
|
||||||
|
this.availableSources = response.data.sources || []
|
||||||
|
// Also update mdata for compatibility
|
||||||
|
if (response.data.categories) {
|
||||||
|
this.mdata.spellcategories = response.data.categories
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to load enhanced spells:', error)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
saveEdit(index) {
|
startEdit(index) {
|
||||||
//this.$emit('update-spell', { index, spell: this.editedItem });
|
const spell = this.filteredAndSortedSpells[index]
|
||||||
this.handleSpellUpdate( { index, spell: this.editedItem });
|
this.editedItem = {
|
||||||
this.editingIndex = -1;
|
...spell,
|
||||||
this.editedItem = null;
|
sourceCode: this.getSourceCode(spell.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/spells-enhanced/${this.editedItem.id}`,
|
||||||
|
updateData
|
||||||
|
)
|
||||||
|
|
||||||
|
// Update the spell in the list using splice for proper reactivity
|
||||||
|
const spellIndex = this.enhancedSpells.findIndex(s => s.id === this.editedItem.id)
|
||||||
|
if (spellIndex !== -1) {
|
||||||
|
this.enhancedSpells.splice(spellIndex, 1, response.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.editingIndex = -1
|
||||||
|
this.editedItem = null
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to save spell:', error)
|
||||||
|
alert('Failed to save spell: ' + (error.response?.data?.error || error.message))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
cancelEdit() {
|
cancelEdit() {
|
||||||
this.editingIndex = -1;
|
this.editingIndex = -1;
|
||||||
@@ -397,9 +583,38 @@ export default {
|
|||||||
if (response.data.spells) {
|
if (response.data.spells) {
|
||||||
this.mdata.spells = response.data.spells;
|
this.mdata.spells = response.data.spells;
|
||||||
}
|
}
|
||||||
|
if (response.data.sources) {
|
||||||
|
this.availableSources = response.data.sources;
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to refresh spells data:', error);
|
console.error('Failed to refresh spells data:', error);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
formatQuelle(spell) {
|
||||||
|
if (spell.source_id && this.availableSources.length > 0) {
|
||||||
|
const source = this.availableSources.find(s => s.id === spell.source_id)
|
||||||
|
if (source) {
|
||||||
|
if (spell.page_number) {
|
||||||
|
return `${source.code}:${spell.page_number}`
|
||||||
|
} else {
|
||||||
|
// No page number - show code and quelle if available
|
||||||
|
const quelle = spell.quelle ? ` (${spell.quelle})` : ''
|
||||||
|
return `${source.code}${quelle}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return spell.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.filterCategory = ''
|
||||||
|
this.filterLevel = ''
|
||||||
|
this.filterUrsprung = ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user