Add raid transport feature and related updates: Introduce new raid transport functionality in FalukantService and FalukantController, including methods for retrieving raid transport regions and handling guard counts. Update frontend components to support guard count input and display related costs. Enhance localization files to include new terms for raid transport and associated metrics in English, German, and Spanish.
This commit is contained in:
@@ -258,6 +258,13 @@
|
||||
</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
{{ $t('falukant.branch.transport.guardCount') }}
|
||||
<input v-model.number="sendVehicleDialog.guardCount" type="number" min="0" max="20" />
|
||||
</label>
|
||||
<p class="transport-guards-hint">
|
||||
{{ $t('falukant.branch.transport.guardHint', { cost: formatMoney((sendVehicleDialog.guardCount || 0) * 4) }) }}
|
||||
</p>
|
||||
<div class="modal-buttons">
|
||||
<button @click="sendVehicles" :disabled="!sendVehicleDialog.targetBranchId">
|
||||
{{ $t('falukant.branch.transport.send') }}
|
||||
@@ -407,6 +414,7 @@ export default {
|
||||
vehicleTypeId: null,
|
||||
targetBranchId: null,
|
||||
success: false,
|
||||
guardCount: 0,
|
||||
},
|
||||
repairVehicleDialog: {
|
||||
show: false,
|
||||
@@ -991,6 +999,7 @@ export default {
|
||||
vehicleTypeId: null,
|
||||
targetBranchId: null,
|
||||
success: false,
|
||||
guardCount: 0,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -1002,6 +1011,7 @@ export default {
|
||||
vehicleTypeId: vehicleTypeId,
|
||||
targetBranchId: null,
|
||||
success: false,
|
||||
guardCount: 0,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -1013,6 +1023,7 @@ export default {
|
||||
vehicleTypeId: null,
|
||||
targetBranchId: null,
|
||||
success: false,
|
||||
guardCount: 0,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -1038,6 +1049,7 @@ export default {
|
||||
targetBranchId: this.sendVehicleDialog.targetBranchId,
|
||||
productId: null,
|
||||
quantity: 0,
|
||||
guardCount: this.sendVehicleDialog.guardCount || 0,
|
||||
};
|
||||
|
||||
if (this.sendVehicleDialog.vehicleIds && this.sendVehicleDialog.vehicleIds.length > 0) {
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
<label class="form-label">
|
||||
{{ $t('falukant.underground.activities.victim') }}
|
||||
<input v-model="newVictimUsername" @input="onVictimInput" type="text" class="form-control"
|
||||
:placeholder="$t('falukant.underground.activities.victimPlaceholder')" />
|
||||
:placeholder="$t('falukant.underground.activities.victimPlaceholder')"
|
||||
:disabled="selectedType && selectedType.tr === 'raid_transport'" />
|
||||
</label>
|
||||
<div v-if="victimSuggestions.length" class="suggestions">
|
||||
<ul>
|
||||
@@ -92,6 +93,27 @@
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label v-if="selectedType && selectedType.tr === 'raid_transport'" class="form-label">
|
||||
{{ $t('falukant.underground.activities.raidRegion') }}
|
||||
<select v-model.number="newRaidRegionId" class="form-control">
|
||||
<option :value="null" disabled>{{ $t('falukant.underground.activities.raidRegionPlaceholder') }}</option>
|
||||
<option v-for="region in raidRegions" :key="region.id" :value="region.id">
|
||||
{{ region.name }}
|
||||
</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label v-if="selectedType && selectedType.tr === 'raid_transport'" class="form-label">
|
||||
{{ $t('falukant.underground.activities.bandSize') }}
|
||||
<input
|
||||
v-model.number="newRaidBandSize"
|
||||
type="number"
|
||||
min="1"
|
||||
max="20"
|
||||
class="form-control"
|
||||
/>
|
||||
</label>
|
||||
|
||||
<button class="btn-create-activity" :disabled="!canCreate" @click="createActivity">
|
||||
{{ $t('falukant.underground.activities.create') }}
|
||||
</button>
|
||||
@@ -136,6 +158,12 @@
|
||||
<template v-else-if="act.type === 'investigate_affair'">
|
||||
{{ $t(`falukant.underground.goals.${act.goal}`) }}
|
||||
</template>
|
||||
<template v-else-if="act.type === 'raid_transport'">
|
||||
{{ $t('falukant.underground.activities.raidSummary', {
|
||||
region: act.regionName || '—',
|
||||
bandSize: act.additionalInfo?.bandSize || 0
|
||||
}) }}
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<template v-if="act.type === 'investigate_affair' && hasAffairDetails(act)">
|
||||
@@ -180,6 +208,50 @@
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="act.type === 'raid_transport'">
|
||||
<div
|
||||
v-if="act.additionalInfo?.lastOutcome || act.additionalInfo?.lastTargetTransportId || hasLootDetails(act)"
|
||||
class="activity-details__block"
|
||||
>
|
||||
<div class="activity-details__label">
|
||||
{{ $t('falukant.underground.activities.raidResultTitle') }}
|
||||
</div>
|
||||
<div class="activity-details__metrics">
|
||||
<span v-if="act.additionalInfo?.lastOutcome" class="activity-metric">
|
||||
{{ $t('falukant.underground.activities.lastOutcome') }}:
|
||||
{{ $t(`falukant.underground.raidOutcomes.${act.additionalInfo.lastOutcome}`) }}
|
||||
</span>
|
||||
<span v-if="act.additionalInfo?.lastTargetTransportId" class="activity-metric">
|
||||
{{ $t('falukant.underground.activities.lastTargetTransport') }}:
|
||||
#{{ act.additionalInfo.lastTargetTransportId }}
|
||||
</span>
|
||||
</div>
|
||||
<ul v-if="getLootDetails(act).length" class="activity-details__list">
|
||||
<li v-for="entry in getLootDetails(act)" :key="entry">
|
||||
{{ entry }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="activity-details__block activity-details__metrics">
|
||||
<span class="activity-metric">
|
||||
{{ $t('falukant.underground.activities.bandSize') }}:
|
||||
{{ act.additionalInfo?.bandSize || 0 }}
|
||||
</span>
|
||||
<span v-if="hasNumericValue(act.additionalInfo?.attempts)" class="activity-metric">
|
||||
{{ $t('falukant.underground.activities.attempts') }}:
|
||||
{{ act.additionalInfo.attempts }}
|
||||
</span>
|
||||
<span v-if="hasNumericValue(act.additionalInfo?.successes)" class="activity-metric">
|
||||
{{ $t('falukant.underground.activities.successes') }}:
|
||||
{{ act.additionalInfo.successes }}
|
||||
</span>
|
||||
<span v-if="act.additionalInfo?.lastOutcome" class="activity-metric">
|
||||
{{ $t('falukant.underground.activities.lastOutcome') }}:
|
||||
{{ $t(`falukant.underground.raidOutcomes.${act.additionalInfo.lastOutcome}`) }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -250,7 +322,10 @@ export default {
|
||||
newPoliticalTargets: [],
|
||||
newSabotageTarget: 'house',
|
||||
newCorruptGoal: 'elect',
|
||||
newAffairGoal: 'expose'
|
||||
newAffairGoal: 'expose',
|
||||
raidRegions: [],
|
||||
newRaidRegionId: null,
|
||||
newRaidBandSize: 3
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -261,6 +336,9 @@ export default {
|
||||
},
|
||||
canCreate() {
|
||||
if (!this.newActivityTypeId) return false;
|
||||
if (this.selectedType?.tr === 'raid_transport') {
|
||||
return !!this.newRaidRegionId && !!this.newRaidBandSize;
|
||||
}
|
||||
const hasUser = this.newVictimUsername.trim().length > 0;
|
||||
const hasPol = this.newPoliticalTargets.length > 0;
|
||||
if (!hasUser && !hasPol) return false;
|
||||
@@ -284,6 +362,7 @@ export default {
|
||||
},
|
||||
async mounted() {
|
||||
await this.loadUndergroundTypes();
|
||||
await this.loadRaidRegions();
|
||||
if (this.undergroundTypes.length) {
|
||||
this.newActivityTypeId = this.undergroundTypes[0].id;
|
||||
}
|
||||
@@ -343,6 +422,11 @@ export default {
|
||||
if (this.selectedType.tr === 'investigate_affair') {
|
||||
payload.goal = this.newAffairGoal;
|
||||
}
|
||||
if (this.selectedType.tr === 'raid_transport') {
|
||||
payload.victimUsername = null;
|
||||
payload.regionId = this.newRaidRegionId;
|
||||
payload.bandSize = this.newRaidBandSize;
|
||||
}
|
||||
try {
|
||||
await apiClient.post(
|
||||
'/api/falukant/underground/activities',
|
||||
@@ -353,6 +437,8 @@ export default {
|
||||
this.newSabotageTarget = 'house';
|
||||
this.newCorruptGoal = 'elect';
|
||||
this.newAffairGoal = 'expose';
|
||||
this.newRaidRegionId = null;
|
||||
this.newRaidBandSize = 3;
|
||||
await this.loadActivities();
|
||||
} catch (err) {
|
||||
console.error('Error creating activity', err);
|
||||
@@ -366,6 +452,11 @@ export default {
|
||||
this.undergroundTypes = data;
|
||||
},
|
||||
|
||||
async loadRaidRegions() {
|
||||
const { data } = await apiClient.get('/api/falukant/underground/raid-regions');
|
||||
this.raidRegions = Array.isArray(data) ? data : [];
|
||||
},
|
||||
|
||||
async loadActivities() {
|
||||
this.loading.activities = true;
|
||||
try {
|
||||
@@ -407,6 +498,35 @@ export default {
|
||||
}).format(v);
|
||||
},
|
||||
|
||||
hasLootDetails(activity) {
|
||||
return this.getLootDetails(activity).length > 0;
|
||||
},
|
||||
|
||||
getLootDetails(activity) {
|
||||
const loot = activity?.additionalInfo?.lastLoot;
|
||||
if (!loot) {
|
||||
return [];
|
||||
}
|
||||
if (Array.isArray(loot)) {
|
||||
return loot
|
||||
.map((entry) => {
|
||||
if (!entry) return null;
|
||||
if (typeof entry === 'string') return entry;
|
||||
if (typeof entry === 'object') {
|
||||
const name = entry.productName || entry.product || entry.label || this.$t('falukant.underground.activities.loot');
|
||||
const amount = entry.amount ?? entry.quantity ?? entry.count ?? null;
|
||||
return amount != null ? `${name}: ${amount}` : String(name);
|
||||
}
|
||||
return String(entry);
|
||||
})
|
||||
.filter(Boolean);
|
||||
}
|
||||
if (typeof loot === 'object') {
|
||||
return Object.entries(loot).map(([key, value]) => `${key}: ${value}`);
|
||||
}
|
||||
return [String(loot)];
|
||||
},
|
||||
|
||||
hasNumericValue(value) {
|
||||
return typeof value === 'number' && !Number.isNaN(value);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user