diff --git a/backend/services/falukantService.js b/backend/services/falukantService.js index ecfde99..6413d7a 100644 --- a/backend/services/falukantService.js +++ b/backend/services/falukantService.js @@ -3439,7 +3439,7 @@ class FalukantService extends BaseService { { motherCharacterId: { [Op.in]: userCharacterIds } } ] }, - attributes: ['childCharacterId', 'nameSet', 'isHeir', 'legitimacy', 'birthContext', 'publicKnown', 'createdAt'] + attributes: ['childCharacterId', 'nameSet', 'isHeir', 'legitimacy', 'birthContext', 'publicKnown', 'createdAt', 'fatherCharacterId', 'motherCharacterId'] }) : []; const childCharIds = [...new Set(childRels.map(r => r.childCharacterId))]; @@ -3451,7 +3451,57 @@ class FalukantService extends BaseService { }) : []; const childCharMap = Object.fromEntries(childChars.map(c => [c.id, c])); - const children = childRels.map(rel => { + + const otherParentIds = new Set(); + const relMeta = childRels.map((rel) => { + const fatherId = rel.fatherCharacterId; + const motherId = rel.motherCharacterId; + const userIsFather = userCharacterIds.includes(fatherId); + const userIsMother = userCharacterIds.includes(motherId); + let otherParentId = null; + let playerRole = null; + if (userIsFather && userIsMother) { + otherParentId = null; + playerRole = null; + } else if (userIsFather) { + otherParentId = motherId; + playerRole = 'father'; + } else if (userIsMother) { + otherParentId = fatherId; + playerRole = 'mother'; + } + if (otherParentId != null) { + otherParentIds.add(otherParentId); + } + return { rel, otherParentId, playerRole }; + }); + + const otherParentChars = otherParentIds.size + ? await FalukantCharacter.findAll({ + where: { id: { [Op.in]: [...otherParentIds] } }, + attributes: ['id', 'gender', 'titleOfNobility'], + include: [ + { model: FalukantPredefineFirstname, as: 'definedFirstName', attributes: ['name'] }, + { model: TitleOfNobility, as: 'nobleTitle', attributes: ['labelTr'] } + ] + }) + : []; + const otherParentMap = Object.fromEntries( + otherParentChars.map((c) => { + const plain = c.get({ plain: true }); + return [ + plain.id, + { + characterId: plain.id, + firstName: plain.definedFirstName?.name || 'Unknown', + gender: plain.gender || 'male', + nobleTitle: plain.nobleTitle?.labelTr || 'noncivil', + } + ]; + }) + ); + + const children = relMeta.map(({ rel, otherParentId, playerRole }) => { const kid = childCharMap[rel.childCharacterId]; return { childCharacterId: rel.childCharacterId, @@ -3464,6 +3514,8 @@ class FalukantService extends BaseService { birthContext: rel.birthContext || 'marriage', publicKnown: !!rel.publicKnown, _createdAt: rel.createdAt, + playerRole, + otherParent: otherParentId != null ? (otherParentMap[otherParentId] || null) : null, }; }); // Sort children globally by relation createdAt ascending (older first) diff --git a/frontend/src/dialogues/falukant/ChildDetailsDialog.vue b/frontend/src/dialogues/falukant/ChildDetailsDialog.vue index d6fd02a..82a4db3 100644 --- a/frontend/src/dialogues/falukant/ChildDetailsDialog.vue +++ b/frontend/src/dialogues/falukant/ChildDetailsDialog.vue @@ -27,6 +27,14 @@ {{ $t('falukant.family.children.gender') }} {{ $t(`falukant.titles.${child.gender}.noncivil`) }} + + {{ $t('falukant.family.children.birthContextLabel') }} + {{ $t('falukant.family.children.birthContextLong.' + child.birthContext) }} + + + {{ $t('falukant.family.children.otherParent') }} + {{ otherParentDisplay }} + {{ $t('falukant.family.children.heir') }} @@ -58,6 +66,16 @@ export default { child: null }; }, + computed: { + otherParentDisplay() { + if (!this.child?.otherParent) { + return this.$t('falukant.family.children.otherParentUnknown'); + } + const o = this.child.otherParent; + const title = this.$t(`falukant.titles.${o.gender}.${o.nobleTitle}`); + return `${title} ${o.firstName}`.trim(); + } + }, methods: { open(child) { this.child = child; diff --git a/frontend/src/i18n/locales/de/falukant.json b/frontend/src/i18n/locales/de/falukant.json index a603a13..793b454 100644 --- a/frontend/src/i18n/locales/de/falukant.json +++ b/frontend/src/i18n/locales/de/falukant.json @@ -659,6 +659,17 @@ "acknowledged_bastard": "Anerkannt unehelich", "hidden_bastard": "Unehelich" }, + "otherParent": "Anderes Elternteil", + "otherParentUnknown": "Unbekannt", + "birthContextLabel": "Herkunft", + "birthContextShort": { + "marriage": "Ehe", + "lover": "Liebschaft" + }, + "birthContextLong": { + "marriage": "Aus der Ehe", + "lover": "Aus einer Liebschaft" + }, "details": { "title": "Kind-Details" } diff --git a/frontend/src/i18n/locales/en/falukant.json b/frontend/src/i18n/locales/en/falukant.json index 0425433..4629eea 100644 --- a/frontend/src/i18n/locales/en/falukant.json +++ b/frontend/src/i18n/locales/en/falukant.json @@ -653,10 +653,21 @@ "acknowledged_bastard": "Acknowledged illegitimate", "hidden_bastard": "Illegitimate" }, + "otherParent": "Other parent", + "otherParentUnknown": "Unknown", + "birthContextLabel": "Origin", + "birthContextShort": { + "marriage": "Marriage", + "lover": "Affair" + }, + "birthContextLong": { + "marriage": "From marriage", + "lover": "From an affair" + }, "details": { "title": "Child Details" } - , + }, "taxes": { "title": "Taxes", "loading": "Loading tax data...", @@ -665,7 +676,6 @@ "region": "Region", "taxPercent": "Tax %" } - } }, "spouse": { "traitsToggle": "Character traits", diff --git a/frontend/src/i18n/locales/es/falukant.json b/frontend/src/i18n/locales/es/falukant.json index f4c8e4a..2dc5692 100644 --- a/frontend/src/i18n/locales/es/falukant.json +++ b/frontend/src/i18n/locales/es/falukant.json @@ -640,6 +640,17 @@ "acknowledged_bastard": "Ilegítimo reconocido", "hidden_bastard": "Ilegítimo" }, + "otherParent": "Otro progenitor", + "otherParentUnknown": "Desconocido", + "birthContextLabel": "Origen", + "birthContextShort": { + "marriage": "Matrimonio", + "lover": "Amorío" + }, + "birthContextLong": { + "marriage": "Del matrimonio", + "lover": "De una relación amorosa" + }, "details": { "title": "Detalles del hijo" } diff --git a/frontend/src/views/falukant/FamilyView.vue b/frontend/src/views/falukant/FamilyView.vue index 91d2725..f9f0233 100644 --- a/frontend/src/views/falukant/FamilyView.vue +++ b/frontend/src/views/falukant/FamilyView.vue @@ -278,6 +278,7 @@ {{ $t('falukant.family.children.name') }} + {{ $t('falukant.family.children.otherParent') }} {{ $t('falukant.family.children.age') }} {{ $t('falukant.family.children.heir') }} {{ $t('falukant.family.children.actions') }} @@ -295,6 +296,15 @@ + + {{ formatOtherParentLine(child) }} + + {{ birthContextShortLabel(child.birthContext) }} + + {{ child.age }} {{ $t('falukant.family.children.isHeir') }} @@ -720,6 +730,21 @@ export default { this.$refs.childDetailsDialog?.open(child); }, + formatOtherParentLine(child) { + if (!child?.otherParent) { + return this.$t('falukant.family.children.otherParentUnknown'); + } + const o = child.otherParent; + const title = this.$t(`falukant.titles.${o.gender}.${o.nobleTitle}`); + return `${title} ${o.firstName}`.trim(); + }, + + birthContextShortLabel(context) { + const key = `falukant.family.children.birthContextShort.${context}`; + const t = this.$t(key); + return t === key ? context : t; + }, + async setAsHeir(child) { if (!child.childCharacterId) { showError(this, 'tr:falukant.family.children.heirSetError'); @@ -1218,6 +1243,20 @@ export default { font-weight: 700; } +.child-origin-badge--context { + margin-left: 6px; + margin-top: 4px; +} + +.child-other-parent-cell { + max-width: 14rem; + vertical-align: top; +} + +.child-other-parent-name { + display: block; +} + .lovers-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));