11 KiB
P0 Végrehajtási Terv: Vehicle Components & Modal Javítások
Státusz: Tervezés alatt Dátum: 2026-06-21 Architect: Rendszer-Architect
1. Áttekintés
A P0 feladat a meglévő jármű komponensek 4 problémás területének javítása az Architect modul elemzése alapján. A terv 3 fájl módosítását írja elő, új komponensek létrehozása NÉLKÜL.
Érintett fájlok:
| # | Fájl | Művelet | Hatás |
|---|---|---|---|
| 1 | frontend/src/types/vehicle.ts |
image_url mező hozzáadása a VehicleData interfészhez |
Type safety |
| 2 | frontend/src/components/vehicle/VehicleCardStandard.vue |
5 adatkötés javítás | UI adatok helyes megjelenítése |
| 3 | frontend/src/components/vehicle/VehicleDetailModal.vue |
5. tab (TechData) integráció + Pénzügyek tab bővítés | Teljes TCO láthatóság |
2. Részletes Módosítási Terv
2.1 VehicleData típus bővítése
Fájl: frontend/src/types/vehicle.ts
export interface VehicleData {
// ... existing fields ...
image_url?: string | null; // ÚJ mező a kép URL tárolására
}
Indoklás: A VehicleCardStandard.vue :src="vehicle.image_url"-t használna, de a VehicleData interfészből hiányzik ez a mező. A backend már visszaadhat image_url-t az AssetResponse-ben (lásd assets.py:386).
2.2 VehicleCardStandard.vue - 5 adatkötés javítás
Fájl: frontend/src/components/vehicle/VehicleCardStandard.vue
| # | Probléma | Javítás | Sor |
|---|---|---|---|
| 1 | is_primary csillag gomb (megvan, de nincs szöveges badge) |
Nem változtatunk - a meglévő star toggle működik, a feladat csak a data bindings-okról szól | 119-131 |
| 2 | color mező: vehicle.individual_equipment?.color || vehicle.color || '—' |
Lecserélés erre: vehicle.individual_equipment?.color || 'N/A' |
103 |
| 3 | engine mező: vehicle.engine || vehicle.fuel_type || '—' |
Lecserélés erre: `` `${vehicle.power_kw | |
| 4 | country_code mező: vehicle.countryCode || vehicle.country_code |
Hozzáadás registration_country használatával |
62 |
| 5 | image mező: vehicle.image |
Lecserélés vehicle.image_url-re, fallback SVG placeholder |
9-10 |
Részletes módosítások:
2.2.a - Image (9-10. sor):
<img v-if="vehicle.image_url" :src="vehicle.image_url" alt="" class="..." />
<template v-else>
<svg ... ></svg> <!-- Meglévő placeholder SVG változatlan -->
</template>
2.2.b - Country (62. sor):
<span class="...">{{ vehicle.registration_country || vehicle.countryCode || vehicle.country_code || '—' }}</span>
2.2.c - Engine (95. sor):
<span class="...">{{ vehicle.power_kw ? vehicle.power_kw + ' kW' : '?' }} / {{ vehicle.engine_capacity ? vehicle.engine_capacity + ' cm³' : '?' }}</span>
2.2.d - Color (103. sor):
<span class="...">{{ vehicle.individual_equipment?.color || 'N/A' }}</span>
2.3 VehicleDetailModal.vue - TechData Tab integráció
Fájl: frontend/src/components/vehicle/VehicleDetailModal.vue
Háttér
A TechDataTab.vue LÉTEZIK (279 sor), de NINCS integrálva a modálba. Jelenleg 4 tab van (basics, finance, alerts, servicebook).
Megoldás: 5. tab hozzáadása
a) Tab gomb hozzáadása (a meglévő tab gombok után, ~866-873. sor):
<button @click="activeTab = 'techdata'" :class="activeTab === 'techdata' ? '...' : '...'">
{{ $t('vehicle.techData') || 'Műszaki adatok' }}
</button>
b) Tab content blokk hozzáadása (a servicebook tab után, ~736. sor után):
<div v-if="activeTab === 'techdata'" class="space-y-5">
<TechDataTab />
</div>
c) Import hozzáadása (script section):
import TechDataTab from '@/components/vehicles/tabs/TechDataTab.vue';
d) provide/inject kompatibilitás biztosítása:
A TechDataTab.vue inject<computed<Vehicle | null>>('vehicle')-t használ. A VehicleDetailModal.vue-ban a vehicle computed property már létezik. A provide-ot a modal szülőjének (vagy a modal-nak magának) kell biztosítania.
Megvizsgálandó: A VehicleDetailModal.vue jelenleg props-on keresztül kapja a vehicle adatokat. Ha a TechDataTab.vue inject('vehicle')-t vár, akkor vagy:
- Biztosítani kell a
provide('vehicle', computed(...))-t a modalban, VAGY - Át kell alakítani a TechDataTab-et, hogy elfogadjon egy prop-ot is.
Ajánlás: Mivel a OverviewTab.vue is ugyanezt az inject-es mintát használja, a legegyszerűbb megoldás a provide hozzáadása a VehicleDetailModal.vue-hoz:
// A script setup blokkban
import { provide, computed } from 'vue';
const vehicle = computed(() => props.vehicle || null);
provide('vehicle', vehicle);
2.4 VehicleDetailModal.vue - Pénzügyek Tab bővítés
Jelenlegi állapot
A finance tab (282-436. sor) csak GET /assets/{id}/costs-t hív (944-957. sor) és két részből áll: non-premium esetén egyszerű lista, premium esetén chart.
Bővítés: 3 új API hívás párhuzamosan
Backend endpointok (már léteznek, VERIFIKÁLVA):
| Endpoint | Visszatérési típus | Helye |
|---|---|---|
GET /api/v1/assets/vehicles/{id}/financials |
AssetFinancialsResponse |
assets.py:1245 |
GET /api/v1/assets/vehicles/{id}/insurance |
List[VehicleInsurancePolicyResponse] |
assets.py:1314 |
GET /api/v1/assets/vehicles/{id}/tax |
List[VehicleTaxObligationResponse] |
assets.py:1376 |
Store metódusok (már léteznek, VERIFIKÁLVA):
| Metódus | Param | Visszatérés |
|---|---|---|
fetchAssetFinancials(assetId) |
string |
Promise<AssetFinancials | null> |
fetchInsurancePolicies(assetId) |
string |
Promise<VehicleInsurancePolicy[]> |
fetchTaxObligations(assetId) |
string |
Promise<VehicleTaxObligation[]> |
Tervezett módosítások a VehicleDetailModal.vue-ban:
a) Új state változók (script setup):
const assetFinancials = ref<AssetFinancials | null>(null);
const insurancePolicies = ref<VehicleInsurancePolicy[]>([]);
const taxObligations = ref<VehicleTaxObligation[]>([]);
const financeLoading = ref(false);
b) Párhuzamos API hívás a loadFinanceData függvényben (~944. sor környékén):
async function loadFinanceData() {
financeLoading.value = true;
try {
const vehicleId = props.vehicle?.id?.toString();
if (!vehicleId) return;
// Promise.all a 3 új híváshoz
const [financials, policies, taxes] = await Promise.all([
vehicleStore.fetchAssetFinancials(vehicleId),
vehicleStore.fetchInsurancePolicies(vehicleId),
vehicleStore.fetchTaxObligations(vehicleId),
]);
assetFinancials.value = financials;
insurancePolicies.value = policies;
taxObligations.value = taxes;
// Meglévő costs betöltés változatlan
await loadCosts();
} catch (err) {
console.error('Failed to load finance data:', err);
} finally {
financeLoading.value = false;
}
}
c) Template bővítés - új szekciók a meglévő "Költségek" szekció ELÉ:
<div v-if="activeTab === 'finance'" class="space-y-5">
<!-- 1. ÚJ: Beszerzés & Lízing szekció -->
<div v-if="assetFinancials" class="...">
<h3>{{ $t('vehicle.financials.title') }}</h3>
<div class="grid grid-cols-2 gap-3">
<div>...purchase_price...</div>
<div>...leasing...residual_value...</div>
</div>
</div>
<!-- 2. ÚJ: Biztosítások szekció -->
<div v-if="insurancePolicies.length" class="...">
<h3>{{ $t('vehicle.insurance.title') }}</h3>
<div v-for="policy in insurancePolicies" :key="policy.id">
{{ policy.insurance_type }} - {{ policy.premium_amount }} - {{ policy.expiry_date }}
</div>
</div>
<!-- 3. ÚJ: Adók szekció -->
<div v-if="taxObligations.length" class="...">
<h3>{{ $t('vehicle.tax.title') }}</h3>
<div v-for="tax in taxObligations" :key="tax.id">
{{ tax.tax_type }} - {{ tax.amount }} - {{ tax.payment_status }}
</div>
</div>
<!-- 4. MEGLÉVŐ: Költségek szekció (változatlan) -->
<div v-if="!costsLoading">
<!-- ... existing costs content ... -->
</div>
</div>
d) Importok hozzáadása:
import type { AssetFinancials, VehicleInsurancePolicy, VehicleTaxObligation } from '@/types/vehicle';
3. Függőségi Térkép
graph TD
A[vehicle.ts - VehicleData] -->|image_url mező| B[VehicleCardStandard.vue]
A -->|Vehicle típus| C[VehicleDetailModal.vue]
C -->|provide vehicle| D[TechDataTab.vue]
C -->|Promise.all| E[vehicleStore: fetchAssetFinancials]
C -->|Promise.all| F[vehicleStore: fetchInsurancePolicies]
C -->|Promise.all| G[vehicleStore: fetchTaxObligations]
E --> H[assets.py: GET /vehicles/{id}/financials]
F --> I[assets.py: GET /vehicles/{id}/insurance]
G --> J[assets.py: GET /vehicles/{id}/tax]
4. Végrehajtási Sorrend
| Lépés | Fájl | Művelet | Függőség |
|---|---|---|---|
| 1 | types/vehicle.ts |
image_url hozzáadása |
Nincs |
| 2 | VehicleCardStandard.vue |
5 data binding javítás | 1. lépés (image_url) |
| 3 | VehicleDetailModal.vue |
TechData tab + provide hozzáadás | Nincs |
| 4 | VehicleDetailModal.vue |
Finance tab bővítés (Promise.all) | Nincs |
| 5 | - | Vite build futtatás | 1-4. lépés |
5. Kockázatok és Megjegyzések
-
TechDataTab inject függőség: Ha a
providenem működik a modalban (pl. scope issue), alternatív megoldás aTechDataTab.vueátírása prop-alapúra. Ez azonban többletkockázat, ezért először aprovide-os megoldást próbáljuk. -
FinancialsTab.vueátvételének elvetése: AFinancialsTab.vue(709 sor) már tartalmazza a 3 API hívást, de sötét témát (bg-slate-900) használ, ami nem kompatibilis a modal világos témájával. A kód lemásolása helyett a logikát közvetlenül aVehicleDetailModal.vue-ba építjük be. -
Nincs Compact variáns: A keresés nem talált Compact változatot, így csak a Standard kártyát kell javítani.
-
i18n kulcsok: A
hu.tsésen.tsfájlokba új fordítási kulcsokat kell felvenni (pl.vehicle.financials.title,vehicle.insurance.title,vehicle.tax.title,vehicle.techData).
6. Jóváhagyás
Architect: ✅ Terv elkészítve
Fejlesztő: ⏳ Jóváhagyásra vár
A terv végrehajtásához Code módba kell váltani.