moved some basic value lists to database

This commit is contained in:
2026-01-14 18:52:29 +01:00
parent 73ebe6f00d
commit 7775170634
9 changed files with 550 additions and 8 deletions
+125
View File
@@ -3307,3 +3307,128 @@ func getStandBonusPoints(stand string) map[string]int {
return make(map[string]int) return make(map[string]int)
} }
} }
// GetDatasheetOptions returns all available options for datasheet select boxes
func GetDatasheetOptions(c *gin.Context) {
logger.Debug("GetDatasheetOptions aufgerufen")
characterID := c.Param("id")
// Load character to get their weapon skills
var character models.Char
err := character.FirstID(characterID)
if err != nil {
logger.Error("GetDatasheetOptions: Charakter nicht gefunden - ID: %s, Error: %s", characterID, err.Error())
respondWithError(c, http.StatusNotFound, "Character not found")
return
}
// Get all available weapons from database
var allWeapons []models.Weapon
if err := database.DB.Find(&allWeapons).Error; err != nil {
logger.Error("GetDatasheetOptions: Fehler beim Laden der Waffen: %s", err.Error())
respondWithError(c, http.StatusInternalServerError, "Failed to load weapons")
return
}
// Filter weapons based on character's weapon skills
characterWeaponSkills := make(map[string]bool)
for _, skill := range character.Waffenfertigkeiten {
characterWeaponSkills[skill.Name] = true
}
availableWeapons := []string{}
for _, weapon := range allWeapons {
if characterWeaponSkills[weapon.SkillRequired] {
availableWeapons = append(availableWeapons, weapon.Name)
}
}
// Load misc lookup data from database
genders, err := gsmaster.GetMiscLookupByKey("gender")
if err != nil {
logger.Error("GetDatasheetOptions: Fehler beim Laden der Geschlechter: %s", err.Error())
respondWithError(c, http.StatusInternalServerError, "Failed to load genders")
return
}
races, err := gsmaster.GetMiscLookupByKey("races")
if err != nil {
logger.Error("GetDatasheetOptions: Fehler beim Laden der Rassen: %s", err.Error())
respondWithError(c, http.StatusInternalServerError, "Failed to load races")
return
}
origins, err := gsmaster.GetMiscLookupByKey("origins")
if err != nil {
logger.Error("GetDatasheetOptions: Fehler beim Laden der Herkünfte: %s", err.Error())
respondWithError(c, http.StatusInternalServerError, "Failed to load origins")
return
}
socialClasses, err := gsmaster.GetMiscLookupByKey("social_classes")
if err != nil {
logger.Error("GetDatasheetOptions: Fehler beim Laden der Stände: %s", err.Error())
respondWithError(c, http.StatusInternalServerError, "Failed to load social classes")
return
}
faiths, err := gsmaster.GetMiscLookupByKey("faiths")
if err != nil {
logger.Error("GetDatasheetOptions: Fehler beim Laden der Glaubensrichtungen: %s", err.Error())
respondWithError(c, http.StatusInternalServerError, "Failed to load faiths")
return
}
handedness, err := gsmaster.GetMiscLookupByKey("handedness")
if err != nil {
logger.Error("GetDatasheetOptions: Fehler beim Laden der Händigkeiten: %s", err.Error())
respondWithError(c, http.StatusInternalServerError, "Failed to load handedness")
return
}
// Convert to string arrays
genderValues := make([]string, len(genders))
for i, g := range genders {
genderValues[i] = g.Value
}
raceValues := make([]string, len(races))
for i, r := range races {
raceValues[i] = r.Value
}
originValues := make([]string, len(origins))
for i, o := range origins {
originValues[i] = o.Value
}
socialClassValues := make([]string, len(socialClasses))
for i, sc := range socialClasses {
socialClassValues[i] = sc.Value
}
faithValues := make([]string, len(faiths))
for i, f := range faiths {
faithValues[i] = f.Value
}
handednessValues := make([]string, len(handedness))
for i, h := range handedness {
handednessValues[i] = h.Value
}
// Return all options
options := gin.H{
"gender": genderValues,
"races": raceValues,
"origins": originValues,
"social_classes": socialClassValues,
"faiths": faithValues,
"handedness": handednessValues,
"specializations": availableWeapons,
}
logger.Debug("GetDatasheetOptions: Erfolgreich geladen - %d verfügbare Waffen", len(availableWeapons))
c.JSON(http.StatusOK, options)
}
+140
View File
@@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"os" "os"
@@ -975,3 +976,142 @@ func TestListCharacters(t *testing.T) {
assert.Equal(t, 0, len(response.SelfOwned), "Should return empty list for userID 0") assert.Equal(t, 0, len(response.SelfOwned), "Should return empty list for userID 0")
}) })
} }
func TestGetDatasheetOptions(t *testing.T) {
// Setup test environment
original := os.Getenv("ENVIRONMENT")
os.Setenv("ENVIRONMENT", "test")
t.Cleanup(func() {
if original != "" {
os.Setenv("ENVIRONMENT", original)
} else {
os.Unsetenv("ENVIRONMENT")
}
})
// Setup test database
database.SetupTestDB(true, true)
defer database.ResetTestDB()
err := models.MigrateStructure()
assert.NoError(t, err)
/*
// Populate misc lookup data
err = models.PopulateMiscLookupData()
assert.NoError(t, err)
*/
// Create test character with weapon skill
testChar := &models.Char{
BamortBase: models.BamortBase{
Name: "Test Character",
},
Typ: "Krieger",
Rasse: "Mensch",
Waffenfertigkeiten: []models.SkWaffenfertigkeit{
{
SkFertigkeit: models.SkFertigkeit{
BamortCharTrait: models.BamortCharTrait{
BamortBase: models.BamortBase{
Name: "Langschwert",
},
},
},
},
},
}
err = testChar.Create()
assert.NoError(t, err)
assert.NotZero(t, testChar.ID, "Character ID should be set after Create")
// Setup Gin context
gin.SetMode(gin.TestMode)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
// Use string conversion of actual character ID
c.Params = gin.Params{{Key: "id", Value: fmt.Sprintf("%d", testChar.ID)}}
// Call the handler
GetDatasheetOptions(c)
// Assert response
assert.Equal(t, http.StatusOK, w.Code)
var response map[string]interface{}
err = json.Unmarshal(w.Body.Bytes(), &response)
assert.NoError(t, err)
// Verify all expected keys exist
assert.Contains(t, response, "gender")
assert.Contains(t, response, "races")
assert.Contains(t, response, "origins")
assert.Contains(t, response, "social_classes")
assert.Contains(t, response, "faiths")
assert.Contains(t, response, "handedness")
assert.Contains(t, response, "specializations")
// Verify data from database
genders := response["gender"].([]interface{})
assert.Equal(t, 3, len(genders))
assert.Contains(t, genders, "divers")
assert.Contains(t, genders, "männlich")
assert.Contains(t, genders, "weiblich")
races := response["races"].([]interface{})
assert.Equal(t, 5, len(races))
assert.Contains(t, races, "Elf")
assert.Contains(t, races, "Mensch")
origins := response["origins"].([]interface{})
assert.Equal(t, 15, len(origins))
assert.Contains(t, origins, "Albai")
socialClasses := response["social_classes"].([]interface{})
assert.Equal(t, 3, len(socialClasses))
assert.Contains(t, socialClasses, "Adel")
assert.Contains(t, socialClasses, "Mittelschicht")
faiths := response["faiths"].([]interface{})
assert.Equal(t, 5, len(faiths))
assert.Contains(t, faiths, "Druide")
assert.Contains(t, faiths, "Keine")
handedness := response["handedness"].([]interface{})
assert.Equal(t, 3, len(handedness))
assert.Contains(t, handedness, "beidhändig")
assert.Contains(t, handedness, "links")
assert.Contains(t, handedness, "rechts")
}
func TestGetDatasheetOptions_CharacterNotFound(t *testing.T) {
// Setup test environment
original := os.Getenv("ENVIRONMENT")
os.Setenv("ENVIRONMENT", "test")
t.Cleanup(func() {
if original != "" {
os.Setenv("ENVIRONMENT", original)
} else {
os.Unsetenv("ENVIRONMENT")
}
})
// Setup test database
database.SetupTestDB(true, true)
defer database.ResetTestDB()
err := models.MigrateStructure()
assert.NoError(t, err)
// Setup Gin context with non-existent character ID
gin.SetMode(gin.TestMode)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Params = gin.Params{{Key: "id", Value: "99999"}}
// Call the handler
GetDatasheetOptions(c)
// Assert error response
assert.Equal(t, http.StatusNotFound, w.Code)
}
+1
View File
@@ -12,6 +12,7 @@ func RegisterRoutes(r *gin.RouterGroup) {
charGrp.PUT("/:id", UpdateCharacter) charGrp.PUT("/:id", UpdateCharacter)
charGrp.DELETE("/:id", DeleteCharacter) charGrp.DELETE("/:id", DeleteCharacter)
charGrp.PUT("/:id/image", UpdateCharacterImage) charGrp.PUT("/:id/image", UpdateCharacterImage)
charGrp.GET("/:id/datasheet-options", GetDatasheetOptions)
// Erfahrung und Vermögen // Erfahrung und Vermögen
charGrp.GET("/:id/experience-wealth", GetCharacterExperienceAndWealth) // NewSystem charGrp.GET("/:id/experience-wealth", GetCharacterExperienceAndWealth) // NewSystem
+10
View File
@@ -59,6 +59,16 @@ func main() {
database.ConnectDatabase() database.ConnectDatabase()
logger.Info("Datenbankverbindung erfolgreich") logger.Info("Datenbankverbindung erfolgreich")
/*
// Populate initial misc lookup data
logger.Debug("Initialisiere Misc-Lookup-Daten...")
if err := models.PopulateMiscLookupData(); err != nil {
logger.Warn("Fehler beim Initialisieren der Misc-Lookup-Daten: %s", err.Error())
} else {
logger.Info("Misc-Lookup-Daten erfolgreich initialisiert")
}
*/
// Initialize PDF templates // Initialize PDF templates
logger.Debug("Initialisiere PDF-Templates...") logger.Debug("Initialisiere PDF-Templates...")
if err := pdfrender.InitializeTemplates("/app/default_templates", cfg.TemplatesDir); err != nil { if err := pdfrender.InitializeTemplates("/app/default_templates", cfg.TemplatesDir); err != nil {
+77
View File
@@ -0,0 +1,77 @@
package gsmaster
import (
"bamort/database"
"bamort/models"
)
// GetMiscLookupByKey retrieves all values for a given key
func GetMiscLookupByKey(key string) ([]models.MiscLookup, error) {
var items []models.MiscLookup
err := database.DB.Where("`key` = ?", key).Order("value ASC").Find(&items).Error
return items, err
}
/*
// PopulateMiscLookupData populates initial misc lookup data if table is empty
func PopulateMiscLookupData() error {
// Check if data already exists
var count int64
if err := database.DB.Model(&models.MiscLookup{}).Count(&count).Error; err != nil {
return err
}
if count > 0 {
return nil // Data already exists
}
// Define initial data
initialData := []struct {
key string
values []string
}{
{
key: "gender",
values: []string{"männlich", "weiblich", "divers"},
},
{
key: "races",
values: []string{"Mensch", "Elf", "Zwerg", "Gnom", "Halbling"},
},
{
key: "origins",
values: []string{
"Albai", "Aran", "Chryseia", "Clanngadarn", "Erainn",
"Eschar", "Fuardain", "Ikengabecken", "KanThaiPan", "Küstenstaaten",
"Moravod", "Nahuatlan", "Rawindra", "Twyneddin", "Valian",
},
},
{
key: "social_classes",
values: []string{"Volk", "Mittelschicht", "Adel"},
},
{
key: "faiths",
values: []string{"Keine", "Nathir", "Deis Albai", "Mahal", "Druide"},
},
{
key: "handedness",
values: []string{"rechts", "links", "beidhändig"},
},
}
// Insert data
for _, item := range initialData {
for _, value := range item.values {
misc := models.MiscLookup{
Key: item.key,
Value: value,
}
if err := database.DB.Create(&misc).Error; err != nil {
return err
}
}
}
return nil
}
*/
+123
View File
@@ -0,0 +1,123 @@
package gsmaster
import (
"bamort/database"
"bamort/models"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestMiscLookup_TableName(t *testing.T) {
misc := models.MiscLookup{}
assert.Equal(t, "gsm_misc", misc.TableName())
}
func TestMiscLookup_CreateAndRetrieve(t *testing.T) {
database.SetupTestDB()
// Create test data
testData := []models.MiscLookup{
{Key: "gender", Value: "männlich"},
{Key: "gender", Value: "weiblich"},
{Key: "races", Value: "Mensch"},
{Key: "races", Value: "Elf"},
}
// Insert test data
for _, item := range testData {
err := database.DB.Create(&item).Error
require.NoError(t, err)
}
// Retrieve by key
genders, err := GetMiscLookupByKey("gender")
require.NoError(t, err)
assert.Len(t, genders, 2)
assert.Equal(t, "männlich", genders[0].Value)
assert.Equal(t, "weiblich", genders[1].Value)
races, err := GetMiscLookupByKey("races")
require.NoError(t, err)
assert.Len(t, races, 2)
}
func TestGetMiscLookupByKey_NotFound(t *testing.T) {
database.SetupTestDB()
items, err := GetMiscLookupByKey("nonexistent")
require.NoError(t, err)
assert.Empty(t, items)
}
func TestMiscLookup_WithSourceInfo(t *testing.T) {
database.SetupTestDB()
misc := models.MiscLookup{
Key: "test_key",
Value: "test_value",
SourceID: 1,
PageNumber: 42,
}
err := database.DB.Create(&misc).Error
require.NoError(t, err)
assert.NotZero(t, misc.ID)
// Retrieve and verify
var retrieved models.MiscLookup
err = database.DB.First(&retrieved, misc.ID).Error
require.NoError(t, err)
assert.Equal(t, "test_key", retrieved.Key)
assert.Equal(t, "test_value", retrieved.Value)
assert.Equal(t, uint(1), retrieved.SourceID)
assert.Equal(t, 42, retrieved.PageNumber)
}
/*
func TestPopulateMiscLookupData(t *testing.T) {
database.SetupTestDB()
// First population should succeed
err := PopulateMiscLookupData()
require.NoError(t, err)
// Verify all keys have data
expectedCounts := map[string]int{
"gender": 3,
"races": 5,
"origins": 15,
"social_classes": 3,
"faiths": 5,
"handedness": 3,
}
for key, expectedCount := range expectedCounts {
items, err := GetMiscLookupByKey(key)
require.NoError(t, err)
assert.Len(t, items, expectedCount, "Expected %d items for key %s", expectedCount, key)
}
// Verify specific values
genders, _ := GetMiscLookupByKey("gender")
assert.Contains(t, []string{"männlich", "weiblich", "divers"}, genders[0].Value)
races, _ := GetMiscLookupByKey("races")
raceValues := make([]string, len(races))
for i, r := range races {
raceValues[i] = r.Value
}
assert.Contains(t, raceValues, "Mensch")
assert.Contains(t, raceValues, "Elf")
// Second population should not duplicate data
err = PopulateMiscLookupData()
require.NoError(t, err)
var totalCount int64
err = database.DB.Model(&MiscLookup{}).Count(&totalCount).Error
require.NoError(t, err)
assert.Equal(t, int64(34), totalCount, "Should not duplicate data on second population")
}
*/
+1
View File
@@ -61,6 +61,7 @@ func gsMasterMigrateStructure(db ...*gorm.DB) error {
&Container{}, &Container{},
&Transportation{}, &Transportation{},
&Believe{}, &Believe{},
&MiscLookup{},
) )
if err != nil { if err != nil {
return err return err
+14
View File
@@ -128,6 +128,15 @@ type Believe struct {
PageNumber int `json:"page_number,omitempty"` // Seitenzahl im Quellenbuch PageNumber int `json:"page_number,omitempty"` // Seitenzahl im Quellenbuch
} }
// MiscLookup represents miscellaneous lookup values like gender, race, origin, etc.
type MiscLookup struct {
ID uint `gorm:"primaryKey" json:"id"`
Key string `gorm:"column:key;type:varchar(50);index;not null" json:"key"`
Value string `gorm:"type:varchar(255);not null" json:"value"`
SourceID uint `json:"source_id,omitempty"`
PageNumber int `json:"page_number,omitempty"`
}
func (object *Skill) TableName() string { func (object *Skill) TableName() string {
dbPrefix := "gsm" dbPrefix := "gsm"
return dbPrefix + "_" + "skills" return dbPrefix + "_" + "skills"
@@ -669,3 +678,8 @@ func GetBelievesByActiveSources(gameSystem string) ([]Believe, error) {
Find(&believes).Error Find(&believes).Error
return believes, err return believes, err
} }
// TableName specifies the table name for MiscLookup
func (MiscLookup) TableName() string {
return "gsm_misc"
}
+59 -8
View File
@@ -49,7 +49,9 @@
@dblclick="startEditProp('gender', character.gender)" @dblclick="startEditProp('gender', character.gender)"
class="editable-prop" class="editable-prop"
>{{ character.gender || 'x' }}</span> >{{ character.gender || 'x' }}</span>
<input v-else v-model="editPropValue" @blur="saveProp('gender')" @keyup.enter="saveProp('gender')" @keyup.esc="cancelEditProp" ref="propInput" class="prop-input" /> <select v-else v-model="editPropValue" @blur="saveProp('gender')" @keyup.enter="saveProp('gender')" @keyup.esc="cancelEditProp" ref="propInput" class="prop-input">
<option v-for="option in getSelectOptions('gender')" :key="option" :value="option">{{ option }}</option>
</select>
), ),
Grad: Grad:
<span <span
@@ -64,21 +66,27 @@
@dblclick="startEditProp('rasse', character.rasse)" @dblclick="startEditProp('rasse', character.rasse)"
class="editable-prop" class="editable-prop"
>{{ character.rasse || 'x' }}</span> >{{ character.rasse || 'x' }}</span>
<input v-else v-model="editPropValue" @blur="saveProp('rasse')" @keyup.enter="saveProp('rasse')" @keyup.esc="cancelEditProp" ref="propInput" class="prop-input" />, <select v-else v-model="editPropValue" @blur="saveProp('rasse')" @keyup.enter="saveProp('rasse')" @keyup.esc="cancelEditProp" ref="propInput" class="prop-input">
<option v-for="option in getSelectOptions('rasse')" :key="option" :value="option">{{ option }}</option>
</select>,
Heimat: Heimat:
<span <span
v-if="editingProp !== 'origin'" v-if="editingProp !== 'origin'"
@dblclick="startEditProp('origin', character.origin)" @dblclick="startEditProp('origin', character.origin)"
class="editable-prop" class="editable-prop"
>{{ character.origin || '-' }}</span> >{{ character.origin || '-' }}</span>
<input v-else v-model="editPropValue" @blur="saveProp('origin')" @keyup.enter="saveProp('origin')" @keyup.esc="cancelEditProp" ref="propInput" class="prop-input" />, <select v-else v-model="editPropValue" @blur="saveProp('origin')" @keyup.enter="saveProp('origin')" @keyup.esc="cancelEditProp" ref="propInput" class="prop-input">
<option v-for="option in getSelectOptions('origin')" :key="option" :value="option">{{ option }}</option>
</select>,
Stand: Stand:
<span <span
v-if="editingProp !== 'social_class'" v-if="editingProp !== 'social_class'"
@dblclick="startEditProp('social_class', character.social_class)" @dblclick="startEditProp('social_class', character.social_class)"
class="editable-prop" class="editable-prop"
>{{ character.social_class || '-' }}</span> >{{ character.social_class || '-' }}</span>
<input v-else v-model="editPropValue" @blur="saveProp('social_class')" @keyup.enter="saveProp('social_class')" @keyup.esc="cancelEditProp" ref="propInput" class="prop-input" />. <select v-else v-model="editPropValue" @blur="saveProp('social_class')" @keyup.enter="saveProp('social_class')" @keyup.esc="cancelEditProp" ref="propInput" class="prop-input">
<option v-for="option in getSelectOptions('social_class')" :key="option" :value="option">{{ option }}</option>
</select>.
</p> </p>
<p v-if="character.rasse==='Zwerg'"> <p v-if="character.rasse==='Zwerg'">
Hort für Grad {{ character.grad || 'x' }}: 125 GS, für nächsten Grad: 250 GS. Hort für Grad {{ character.grad || 'x' }}: 125 GS, für nächsten Grad: 250 GS.
@@ -90,7 +98,10 @@
@dblclick="startEditProp('spezialisierung', character.spezialisierung)" @dblclick="startEditProp('spezialisierung', character.spezialisierung)"
class="editable-prop" class="editable-prop"
>{{ character.spezialisierung || '-' }}</span> >{{ character.spezialisierung || '-' }}</span>
<input v-else v-model="editPropValue" @blur="saveProp('spezialisierung')" @keyup.enter="saveProp('spezialisierung')" @keyup.esc="cancelEditProp" ref="propInput" class="prop-input" />. <select v-else v-model="editPropValue" @blur="saveProp('spezialisierung')" @keyup.enter="saveProp('spezialisierung')" @keyup.esc="cancelEditProp" ref="propInput" class="prop-input" style="width: 300px;">
<option value="">-</option>
<option v-for="option in getSelectOptions('spezialisierung')" :key="option" :value="option">{{ option }}</option>
</select>.
</p> </p>
<p> <p>
Alter: Alter:
@@ -105,7 +116,9 @@
<span v-else-if="character.hand=='links'">Linkshänder</span> <span v-else-if="character.hand=='links'">Linkshänder</span>
<span v-else>Beidhändig</span> <span v-else>Beidhändig</span>
</strong> </strong>
<input v-else v-model="editPropValue" @blur="saveProp('hand')" @keyup.enter="saveProp('hand')" @keyup.esc="cancelEditProp" ref="propInput" class="prop-input" />, <select v-else v-model="editPropValue" @blur="saveProp('hand')" @keyup.enter="saveProp('hand')" @keyup.esc="cancelEditProp" ref="propInput" class="prop-input">
<option v-for="option in getSelectOptions('hand')" :key="option" :value="option">{{ option }}</option>
</select>,
Größe: Größe:
<span <span
v-if="editingProp !== 'groesse'" v-if="editingProp !== 'groesse'"
@@ -154,7 +167,9 @@
@dblclick="startEditProp('glaube', character.glaube)" @dblclick="startEditProp('glaube', character.glaube)"
class="editable-prop" class="editable-prop"
>{{ character.glaube || '-' }}</span> >{{ character.glaube || '-' }}</span>
<input v-else v-model="editPropValue" @blur="saveProp('glaube')" @keyup.enter="saveProp('glaube')" @keyup.esc="cancelEditProp" ref="propInput" class="prop-input" /> <select v-else v-model="editPropValue" @blur="saveProp('glaube')" @keyup.enter="saveProp('glaube')" @keyup.esc="cancelEditProp" ref="propInput" class="prop-input">
<option v-for="option in getSelectOptions('glaube')" :key="option" :value="option">{{ option }}</option>
</select>
</p> </p>
<p> <p>
<strong>Merkmale:</strong> <strong>Merkmale:</strong>
@@ -208,6 +223,7 @@ export default {
editingProp: null, editingProp: null,
editPropValue: '', editPropValue: '',
editPropType: 'text', editPropType: 'text',
datasheetOptions: null,
characterStats: [ characterStats: [
{ label: 'stats.strength', path: 'eigenschaften.6.value' }, { label: 'stats.strength', path: 'eigenschaften.6.value' },
{ label: 'stats.dexterity', path: 'eigenschaften.1.value' }, { label: 'stats.dexterity', path: 'eigenschaften.1.value' },
@@ -228,6 +244,17 @@ export default {
} }
}, },
methods: { methods: {
async loadDatasheetOptions() {
if (this.datasheetOptions) return
try {
const response = await API.get(`/api/characters/${this.character.id}/datasheet-options`)
this.datasheetOptions = response.data
} catch (error) {
console.error('Failed to load datasheet options:', error)
alert('Fehler beim Laden der Auswahloptionen')
}
},
handleImageUpdate(newImage) { handleImageUpdate(newImage) {
this.$emit('character-updated') this.$emit('character-updated')
}, },
@@ -283,6 +310,13 @@ export default {
this.editValue = '' this.editValue = ''
}, },
startEditProp(prop, value, type = 'text') { startEditProp(prop, value, type = 'text') {
// Load options if this is a select field
const selectFields = ['gender', 'rasse', 'origin', 'social_class', 'glaube', 'hand', 'spezialisierung']
if (selectFields.includes(prop)) {
this.loadDatasheetOptions()
type = 'select'
}
this.editingProp = prop this.editingProp = prop
this.editPropValue = value || '' this.editPropValue = value || ''
this.editPropType = type this.editPropType = type
@@ -291,7 +325,9 @@ export default {
const input = Array.isArray(this.$refs.propInput) ? this.$refs.propInput[0] : this.$refs.propInput const input = Array.isArray(this.$refs.propInput) ? this.$refs.propInput[0] : this.$refs.propInput
if (input) { if (input) {
input.focus() input.focus()
input.select() if (type !== 'select') {
input.select()
}
} }
} }
}) })
@@ -331,6 +367,21 @@ export default {
this.cancelEditProp() this.cancelEditProp()
} }
}, },
getSelectOptions(prop) {
if (!this.datasheetOptions) return []
const optionMap = {
'gender': 'gender',
'rasse': 'races',
'origin': 'origins',
'social_class': 'social_classes',
'glaube': 'faiths',
'hand': 'handedness',
'spezialisierung': 'specializations'
}
return this.datasheetOptions[optionMap[prop]] || []
},
cancelEditProp() { cancelEditProp() {
this.editingProp = null this.editingProp = null
this.editPropValue = '' this.editPropValue = ''