Refactor DirectorInfo and SaleSection components to unify speedLabel logic and remove unnecessary watch properties
- Simplified speedLabel method in DirectorInfo.vue and SaleSection.vue to handle null values and translations more efficiently. - Removed the watch property for branchId in DirectorInfo.vue as it was not needed. - Cleaned up the code by eliminating redundant checks and improving readability. Update translations in falukant.json files - Removed unused keys and cleaned up the structure in both German and English translation files. - Ensured that all necessary translations are still present while removing obsolete entries. Refactor BranchView and PoliticsView components for improved performance and clarity - Removed caching logic for product prices in BranchView.vue to simplify the loading process. - Streamlined the loadCurrentPositions method in PoliticsView.vue by eliminating unnecessary character ID checks and logging. - Enhanced the user experience by ensuring that the application submission process is clearer and more efficient. Clean up MoneyHistoryView and FamilyView components - Removed the graph section from MoneyHistoryView.vue to simplify the UI. - Adjusted the mood display logic in FamilyView.vue to ensure proper translation handling.
This commit is contained in:
@@ -360,7 +360,6 @@ export default {
|
||||
vehicles: [],
|
||||
activeTab: 'production',
|
||||
productPricesCache: {}, // Cache für regionale Preise: { productId: price }
|
||||
productPricesCacheRegionId: null, // regionId, für die der Cache gültig ist
|
||||
tabs: [
|
||||
{ value: 'production', label: 'falukant.branch.tabs.production' },
|
||||
{ value: 'inventory', label: 'falukant.branch.tabs.inventory' },
|
||||
@@ -570,46 +569,30 @@ export default {
|
||||
async loadProductPricesForCurrentBranch() {
|
||||
if (!this.selectedBranch || !this.selectedBranch.regionId) {
|
||||
this.productPricesCache = {};
|
||||
this.productPricesCacheRegionId = null;
|
||||
return;
|
||||
}
|
||||
if (this.productPricesCacheRegionId === this.selectedBranch.regionId && Object.keys(this.productPricesCache).length > 0) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const { data } = await apiClient.get('/api/falukant/products/prices-in-region', {
|
||||
params: {
|
||||
regionId: this.selectedBranch.regionId
|
||||
}
|
||||
});
|
||||
this.productPricesCache = data.prices || {};
|
||||
this.productPricesCacheRegionId = this.selectedBranch.regionId;
|
||||
} catch (error) {
|
||||
console.error(`Error loading product prices for region ${this.selectedBranch.regionId}:`, error);
|
||||
// Fallback: Lade Preise einzeln (alte Methode)
|
||||
console.warn('[BranchView] Falling back to individual product price requests');
|
||||
const prices = {};
|
||||
for (const product of this.products) {
|
||||
try {
|
||||
const { data } = await apiClient.get('/api/falukant/products/price-in-region', {
|
||||
params: {
|
||||
productId: product.id,
|
||||
regionId: this.selectedBranch.regionId
|
||||
}
|
||||
});
|
||||
prices[product.id] = data.price;
|
||||
} catch (err) {
|
||||
console.error(`Error loading price for product ${product.id}:`, err);
|
||||
// Fallback auf Standard-Berechnung
|
||||
const knowledgeFactor = product.knowledges?.[0]?.knowledge || 0;
|
||||
const maxPrice = product.sellCost;
|
||||
const minPrice = maxPrice * 0.6;
|
||||
prices[product.id] = minPrice + (maxPrice - minPrice) * (knowledgeFactor / 100);
|
||||
}
|
||||
|
||||
// Lade Preise für alle Produkte in der aktuellen Region
|
||||
const prices = {};
|
||||
for (const product of this.products) {
|
||||
try {
|
||||
const { data } = await apiClient.get('/api/falukant/products/price-in-region', {
|
||||
params: {
|
||||
productId: product.id,
|
||||
regionId: this.selectedBranch.regionId
|
||||
}
|
||||
});
|
||||
prices[product.id] = data.price;
|
||||
} catch (error) {
|
||||
console.error(`Error loading price for product ${product.id}:`, error);
|
||||
// Fallback auf Standard-Berechnung
|
||||
const knowledgeFactor = product.knowledges?.[0]?.knowledge || 0;
|
||||
const maxPrice = product.sellCost;
|
||||
const minPrice = maxPrice * 0.6;
|
||||
prices[product.id] = minPrice + (maxPrice - minPrice) * (knowledgeFactor / 100);
|
||||
}
|
||||
this.productPricesCache = prices;
|
||||
this.productPricesCacheRegionId = this.selectedBranch?.regionId ?? null;
|
||||
}
|
||||
this.productPricesCache = prices;
|
||||
},
|
||||
|
||||
formatPercent(value) {
|
||||
@@ -721,17 +704,13 @@ export default {
|
||||
},
|
||||
|
||||
speedLabel(value) {
|
||||
if (value == null) return this.$t('falukant.branch.transport.speed.unknown') || '—';
|
||||
if (typeof value === 'object') {
|
||||
const k = value.tr ?? value.id ?? 'unknown';
|
||||
const tKey = `falukant.branch.transport.speed.${k}`;
|
||||
const t = this.$t(tKey);
|
||||
return (t && t !== tKey) ? t : String(k);
|
||||
}
|
||||
const key = String(value);
|
||||
// Expect numeric speeds 1..4; provide localized labels as fallback to raw value
|
||||
const key = value == null ? 'unknown' : String(value);
|
||||
const tKey = `falukant.branch.transport.speed.${key}`;
|
||||
const translated = this.$t(tKey);
|
||||
return (!translated || translated === tKey) ? key : translated;
|
||||
// If translation returns the key (no translation found), fall back to the numeric value
|
||||
if (!translated || translated === tKey) return value;
|
||||
return translated;
|
||||
},
|
||||
|
||||
transportModeLabel(mode) {
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ $t('falukant.family.spouse.mood') }}</td>
|
||||
<td>{{ relationships[0].character2.mood?.tr ? $t(`falukant.mood.${relationships[0].character2.mood.tr}`) : '—' }}</td>
|
||||
<td>{{ $t(`falukant.mood.${relationships[0].character2.mood.tr}`) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ $t('falukant.family.spouse.status') }}</td>
|
||||
|
||||
@@ -9,12 +9,6 @@
|
||||
<button @click="fetchMoneyHistory(1)">{{ $t('falukant.moneyHistory.search') }}</button>
|
||||
</div>
|
||||
|
||||
<div class="graph-section">
|
||||
<button @click="openGraphDialog">
|
||||
{{ $t('falukant.moneyHistory.graph.open') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -48,21 +42,17 @@
|
||||
{{ $t('falukant.moneyHistory.next') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<MoneyHistoryGraphDialog ref="graphDialog" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import StatusBar from '@/components/falukant/StatusBar.vue'
|
||||
import MoneyHistoryGraphDialog from '@/dialogues/falukant/MoneyHistoryGraphDialog.vue'
|
||||
import apiClient from '@/utils/axios.js';
|
||||
|
||||
export default {
|
||||
name: 'MoneyHistoryView',
|
||||
components: {
|
||||
StatusBar,
|
||||
MoneyHistoryGraphDialog,
|
||||
},
|
||||
computed: {
|
||||
locale() {
|
||||
@@ -107,9 +97,6 @@ export default {
|
||||
}
|
||||
return translation !== key ? translation : activity;
|
||||
},
|
||||
openGraphDialog() {
|
||||
this.$refs.graphDialog.open();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -119,10 +106,6 @@ export default {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.graph-section {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="pos in currentPositions" :key="pos.id" :class="{ 'own-position': isOwnPosition(pos) }">
|
||||
<tr v-for="pos in currentPositions" :key="pos.id">
|
||||
<td>{{ $t(`falukant.politics.offices.${pos.officeType.name}`) }}</td>
|
||||
<td>{{ pos.region.name }}</td>
|
||||
<td>
|
||||
@@ -57,7 +57,6 @@
|
||||
|
||||
<!-- OPEN Tab: hier zeigen wir 'openPolitics' -->
|
||||
<div v-else-if="activeTab === 'openPolitics'" class="tab-pane">
|
||||
<p class="politics-age-requirement">{{ $t('falukant.politics.open.ageRequirement') }}</p>
|
||||
<div v-if="loading.openPolitics" class="loading">{{ $t('loading') }}</div>
|
||||
<div v-else class="table-scroll">
|
||||
<table class="politics-table">
|
||||
@@ -66,7 +65,7 @@
|
||||
<th>{{ $t('falukant.politics.open.office') }}</th>
|
||||
<th>{{ $t('falukant.politics.open.region') }}</th>
|
||||
<th>{{ $t('falukant.politics.open.date') }}</th>
|
||||
<th>{{ $t('falukant.politics.open.candidacyWithAge') }}</th>
|
||||
<th>{{ $t('falukant.politics.open.candidacy') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -75,13 +74,13 @@
|
||||
<td>{{ e.region.name }}</td>
|
||||
<td>{{ formatDate(e.date) }}</td>
|
||||
<!-- Checkbox ganz am Ende -->
|
||||
<td :title="e.canApplyByAge === false ? $t('falukant.politics.open.minAgeHint') : null">
|
||||
<td>
|
||||
<input
|
||||
type="checkbox"
|
||||
:id="`apply-${e.id}`"
|
||||
v-model="selectedApplications"
|
||||
:value="e.id"
|
||||
:disabled="e.alreadyApplied || e.canApplyByAge === false"
|
||||
:disabled="e.alreadyApplied"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -194,7 +193,6 @@ export default {
|
||||
elections: [],
|
||||
selectedCandidates: {},
|
||||
selectedApplications: [],
|
||||
ownCharacterId: null,
|
||||
loading: {
|
||||
current: false,
|
||||
openPolitics: false,
|
||||
@@ -212,7 +210,6 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loadOwnCharacterId();
|
||||
this.loadCurrentPositions();
|
||||
},
|
||||
methods: {
|
||||
@@ -232,12 +229,9 @@ export default {
|
||||
this.loading.current = true;
|
||||
try {
|
||||
const { data } = await apiClient.get('/api/falukant/politics/overview');
|
||||
console.log('[PoliticsView] loadCurrentPositions - API response:', data);
|
||||
console.log('[PoliticsView] loadCurrentPositions - ownCharacterId at load time:', this.ownCharacterId);
|
||||
this.currentPositions = data;
|
||||
console.log('[PoliticsView] loadCurrentPositions - Loaded', data.length, 'positions');
|
||||
} catch (err) {
|
||||
console.error('[PoliticsView] Error loading current positions', err);
|
||||
console.error('Error loading current positions', err);
|
||||
} finally {
|
||||
this.loading.current = false;
|
||||
}
|
||||
@@ -247,10 +241,10 @@ export default {
|
||||
this.loading.openPolitics = true;
|
||||
try {
|
||||
const { data } = await apiClient.get('/api/falukant/politics/open');
|
||||
this.openPolitics = Array.isArray(data) ? data : [];
|
||||
this.openPolitics = data;
|
||||
// Bereits beworbene Positionen vorselektieren, damit die Checkbox
|
||||
// sichtbar markiert bleibt.
|
||||
this.selectedApplications = this.openPolitics
|
||||
this.selectedApplications = data
|
||||
.filter(e => e.alreadyApplied)
|
||||
.map(e => e.id);
|
||||
} catch (err) {
|
||||
@@ -336,44 +330,6 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
async loadOwnCharacterId() {
|
||||
try {
|
||||
const { data } = await apiClient.get('/api/falukant/info');
|
||||
console.log('[PoliticsView] loadOwnCharacterId - API response:', data);
|
||||
console.log('[PoliticsView] loadOwnCharacterId - data.character:', data.character);
|
||||
console.log('[PoliticsView] loadOwnCharacterId - data.character?.id:', data.character?.id);
|
||||
if (data.character && data.character.id) {
|
||||
this.ownCharacterId = data.character.id;
|
||||
console.log('[PoliticsView] loadOwnCharacterId - Set ownCharacterId to:', this.ownCharacterId);
|
||||
} else {
|
||||
console.warn('[PoliticsView] loadOwnCharacterId - No character ID found in response', {
|
||||
hasCharacter: !!data.character,
|
||||
characterKeys: data.character ? Object.keys(data.character) : null,
|
||||
characterId: data.character?.id
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[PoliticsView] Error loading own character ID', err);
|
||||
}
|
||||
},
|
||||
|
||||
isOwnPosition(pos) {
|
||||
console.log('[PoliticsView] isOwnPosition - Checking position:', {
|
||||
posId: pos.id,
|
||||
posCharacter: pos.character,
|
||||
posCharacterId: pos.character?.id,
|
||||
ownCharacterId: this.ownCharacterId,
|
||||
match: pos.character?.id === this.ownCharacterId
|
||||
});
|
||||
if (!this.ownCharacterId || !pos.character) {
|
||||
console.log('[PoliticsView] isOwnPosition - Returning false (missing ownCharacterId or pos.character)');
|
||||
return false;
|
||||
}
|
||||
const isMatch = pos.character.id === this.ownCharacterId;
|
||||
console.log('[PoliticsView] isOwnPosition - Result:', isMatch);
|
||||
return isMatch;
|
||||
},
|
||||
|
||||
async submitApplications() {
|
||||
try {
|
||||
const response = await apiClient.post(
|
||||
@@ -390,10 +346,6 @@ export default {
|
||||
.map(e => e.id);
|
||||
} catch (err) {
|
||||
console.error('Error submitting applications', err);
|
||||
const msg = err?.response?.data?.error === 'too_young'
|
||||
? this.$t('falukant.politics.too_young')
|
||||
: (err?.response?.data?.error || err?.message || this.$t('falukant.politics.applyError'));
|
||||
this.$root.$refs?.messageDialog?.open?.(msg, this.$t('falukant.politics.title'));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -432,13 +384,6 @@ h2 {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.politics-age-requirement {
|
||||
flex: 0 0 auto;
|
||||
margin: 0 0 10px 0;
|
||||
font-size: 0.95em;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.table-scroll {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
@@ -466,11 +411,6 @@ h2 {
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.politics-table tbody tr.own-position {
|
||||
background-color: #e0e0e0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.loading {
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
|
||||
Reference in New Issue
Block a user