feat(politics): update title eligibility messages and logic in PoliticsView

This commit is contained in:
Torsten Schulz (local)
2026-08-19 15:06:44 +02:00
parent 4cacc3c7a7
commit a8a13ac25a
4 changed files with 18 additions and 32 deletions

View File

@@ -7195,29 +7195,9 @@ class FalukantService extends BaseService {
order: [['hierarchyLevel', 'ASC'], ['id', 'ASC']] order: [['hierarchyLevel', 'ASC'], ['id', 'ASC']]
}); });
const nameToId = new Map(allTypes.map((t) => [t.name, t.id])); const nameToId = new Map(allTypes.map((t) => [t.name, t.id]));
const titleId = character.titleOfNobility ?? character.nobleTitle?.id; const titles = await TitleOfNobility.findAll({ attributes: ['labelTr', 'level'] });
const allowedOfficeNames = await getAllowedOfficeTypeNamesByTitle(titleId); const titleByLabel = new Map(titles.map((title) => [title.labelTr, title]));
const [titles, officeEligibilityBenefits] = await Promise.all([ const characterTitleLabel = character.nobleTitle?.labelTr;
TitleOfNobility.findAll({ attributes: ['id', 'labelTr', 'level'] }),
TitleBenefit.findAll({
where: { benefitType: 'office_eligibility' },
attributes: ['titleId', 'parameters']
})
]);
const titleById = new Map(titles.map((title) => [Number(title.id), title]));
const minimumTitleByOfficeName = new Map();
for (const benefit of officeEligibilityBenefits) {
const officeNames = benefit.parameters?.officeTypeNames;
const title = titleById.get(Number(benefit.titleId));
if (!Array.isArray(officeNames) || !title) continue;
for (const officeName of officeNames) {
const currentMinimum = minimumTitleByOfficeName.get(officeName);
if (!currentMinimum || title.level < currentMinimum.level) {
minimumTitleByOfficeName.set(officeName, title);
}
}
}
return allTypes.map((typeRow) => { return allTypes.map((typeRow) => {
const type = typeRow.get({ plain: true }); const type = typeRow.get({ plain: true });
@@ -7225,6 +7205,9 @@ class FalukantService extends BaseService {
const requiredOfficeNames = [...new Set( const requiredOfficeNames = [...new Set(
prereqRows.flatMap((pr) => Array.isArray(pr?.prerequisite?.jobs) ? pr.prerequisite.jobs : []) prereqRows.flatMap((pr) => Array.isArray(pr?.prerequisite?.jobs) ? pr.prerequisite.jobs : [])
)]; )];
const requiredTitleLabels = [...new Set(
prereqRows.flatMap((pr) => Array.isArray(pr?.prerequisite?.titles) ? pr.prerequisite.titles : [])
)];
const matchedOfficeNames = requiredOfficeNames.filter((officeName) => { const matchedOfficeNames = requiredOfficeNames.filter((officeName) => {
const reqId = nameToId.get(officeName); const reqId = nameToId.get(officeName);
@@ -7232,9 +7215,12 @@ class FalukantService extends BaseService {
}); });
const prerequisitesMet = requiredOfficeNames.length === 0 || matchedOfficeNames.length > 0; const prerequisitesMet = requiredOfficeNames.length === 0 || matchedOfficeNames.length > 0;
const titleEligible = allowedOfficeNames.size === 0 || allowedOfficeNames.has(type.name); const titleEligible = requiredTitleLabels.length === 0 || requiredTitleLabels.includes(characterTitleLabel);
const canApplyNow = canApplyByAge && titleEligible && prerequisitesMet; const canApplyNow = canApplyByAge && titleEligible && prerequisitesMet;
const requiredTitle = minimumTitleByOfficeName.get(type.name); const requiredTitle = requiredTitleLabels
.map((titleLabel) => titleByLabel.get(titleLabel))
.filter(Boolean)
.sort((a, b) => a.level - b.level)[0];
return { return {
officeTypeId: type.id, officeTypeId: type.id,

View File

@@ -1611,8 +1611,8 @@
"yes": "Ja", "yes": "Ja",
"no": "Nein", "no": "Nein",
"blockedByAge": "Mindestalter nicht erreicht", "blockedByAge": "Mindestalter nicht erreicht",
"blockedByTitle": "Benötigter Stand: mindestens {title}", "blockedByTitle": "Standesvoraussetzung nicht erfüllt",
"unknownRequiredTitle": "unbekannt", "blockedByTitleMinimum": "Benötigter Stand: mindestens {title}",
"blockedByPrerequisites": "Vorherige Ämter fehlen" "blockedByPrerequisites": "Vorherige Ämter fehlen"
}, },
"too_young": "Dein Charakter ist noch zu jung. Eine Bewerbung ist erst ab 16 Jahren möglich.", "too_young": "Dein Charakter ist noch zu jung. Eine Bewerbung ist erst ab 16 Jahren möglich.",

View File

@@ -797,8 +797,8 @@
"yes": "Yes", "yes": "Yes",
"no": "No", "no": "No",
"blockedByAge": "Minimum age not met", "blockedByAge": "Minimum age not met",
"blockedByTitle": "Required title: at least {title}", "blockedByTitle": "Title requirement not met",
"unknownRequiredTitle": "unknown", "blockedByTitleMinimum": "Required title: at least {title}",
"blockedByPrerequisites": "Required prior offices missing" "blockedByPrerequisites": "Required prior offices missing"
}, },
"too_young": "Your character is too young. Applications are only possible from age 16.", "too_young": "Your character is too young. Applications are only possible from age 16.",

View File

@@ -180,11 +180,12 @@
: $t('falukant.politics.officesTab.no') }} : $t('falukant.politics.officesTab.no') }}
<template v-if="!office.canApplyNow"> <template v-if="!office.canApplyNow">
<span v-if="!office.canApplyByAge"> · {{ $t('falukant.politics.officesTab.blockedByAge') }}</span> <span v-if="!office.canApplyByAge"> · {{ $t('falukant.politics.officesTab.blockedByAge') }}</span>
<span v-if="!office.titleEligible"> <span v-if="!office.titleEligible && office.requiredTitleLabelTr">
· {{ $t('falukant.politics.officesTab.blockedByTitle', { · {{ $t('falukant.politics.officesTab.blockedByTitleMinimum', {
title: formatRequiredTitle(office.requiredTitleLabelTr, office.characterGender) title: formatRequiredTitle(office.requiredTitleLabelTr, office.characterGender)
}) }} }) }}
</span> </span>
<span v-else-if="!office.titleEligible"> · {{ $t('falukant.politics.officesTab.blockedByTitle') }}</span>
<span v-if="!office.prerequisitesMet"> · {{ $t('falukant.politics.officesTab.blockedByPrerequisites') }}</span> <span v-if="!office.prerequisitesMet"> · {{ $t('falukant.politics.officesTab.blockedByPrerequisites') }}</span>
</template> </template>
</span> </span>
@@ -369,7 +370,6 @@ export default {
}, },
methods: { methods: {
formatRequiredTitle(titleLabelTr, gender) { formatRequiredTitle(titleLabelTr, gender) {
if (!titleLabelTr) return this.$t('falukant.politics.officesTab.unknownRequiredTitle');
return this.$t(`falukant.titles.${gender === 'female' ? 'female' : 'male'}.${titleLabelTr}`); return this.$t(`falukant.titles.${gender === 'female' ? 'female' : 'male'}.${titleLabelTr}`);
}, },
formatPoliticalCharacterName(character) { formatPoliticalCharacterName(character) {