Enhance SaleSection component to group and display transport data

- Updated SaleSection.vue to group running transports by relevant attributes, improving data organization and readability.
- Added a new computed property to calculate vehicle counts and total quantities for grouped transports.
- Introduced a new column in the UI to display the count of vehicles associated with each transport group.
- Updated German localization file to include translation for 'runningVehicleCount', enhancing user experience for German-speaking users.
This commit is contained in:
Torsten Schulz (local)
2025-12-05 13:12:24 +01:00
parent 865ef81012
commit 656c821986
2 changed files with 60 additions and 9 deletions

View File

@@ -137,31 +137,33 @@
<th>{{ $t('falukant.branch.sale.runningTarget') }}</th> <th>{{ $t('falukant.branch.sale.runningTarget') }}</th>
<th>{{ $t('falukant.branch.sale.runningEta') }}</th> <th>{{ $t('falukant.branch.sale.runningEta') }}</th>
<th>{{ $t('falukant.branch.sale.runningRemaining') }}</th> <th>{{ $t('falukant.branch.sale.runningRemaining') }}</th>
<th>{{ $t('falukant.branch.sale.runningVehicleCount') }}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="t in runningTransports" :key="t.id"> <tr v-for="(group, index) in groupedTransports" :key="`group-${index}`">
<td> <td>
{{ t.direction === 'outgoing' {{ group.direction === 'outgoing'
? $t('falukant.branch.sale.runningDirectionOut') ? $t('falukant.branch.sale.runningDirectionOut')
: $t('falukant.branch.sale.runningDirectionIn') }} : $t('falukant.branch.sale.runningDirectionIn') }}
</td> </td>
<td> <td>
<span v-if="t.product && t.product.labelTr"> <span v-if="group.product && group.product.labelTr">
{{ $t(`falukant.product.${t.product.labelTr}`) }} {{ $t(`falukant.product.${group.product.labelTr}`) }}
</span> </span>
<span v-else class="no-product"> <span v-else class="no-product">
{{ $t('falukant.branch.sale.runningNoProduct') }} {{ $t('falukant.branch.sale.runningNoProduct') }}
</span> </span>
</td> </td>
<td> <td>
<span v-if="t.product && t.size > 0">{{ t.size }}</span> <span v-if="group.product && group.totalQuantity > 0">{{ group.totalQuantity }}</span>
<span v-else></span> <span v-else></span>
</td> </td>
<td>{{ t.sourceRegion?.name }}</td> <td>{{ group.sourceRegion?.name }}</td>
<td>{{ t.targetRegion?.name }}</td> <td>{{ group.targetRegion?.name }}</td>
<td>{{ formatEta(t) }}</td> <td>{{ formatEta({ eta: group.eta }) }}</td>
<td>{{ formatRemaining(t) }}</td> <td>{{ formatRemaining({ eta: group.eta }) }}</td>
<td>{{ group.vehicleCount }}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@@ -202,6 +204,54 @@
loadingPrices: new Set(), loadingPrices: new Set(),
}; };
}, },
computed: {
groupedTransports() {
const groups = new Map();
for (const transport of this.runningTransports) {
// Erstelle einen Schlüssel für die Gruppierung
// Wichtig: Restzeit nicht in den Schlüssel einbeziehen, da sie sich ständig ändert
const productId = transport.product?.id || null;
const productLabelTr = transport.product?.labelTr || null;
const sourceId = transport.sourceRegion?.id || null;
const targetId = transport.targetRegion?.id || null;
const direction = transport.direction;
// ETA als Zeitstempel für Gruppierung (auf Sekunden genau, um kleine Unterschiede zu ignorieren)
const eta = transport.eta ? Math.floor(new Date(transport.eta).getTime() / 1000) : null;
// Gruppierungsschlüssel: alle relevanten Eigenschaften außer Restzeit
const key = `${direction}-${productId}-${productLabelTr}-${sourceId}-${targetId}-${eta}`;
if (!groups.has(key)) {
groups.set(key, {
direction: transport.direction,
product: transport.product,
sourceRegion: transport.sourceRegion,
targetRegion: transport.targetRegion,
eta: transport.eta,
vehicleCount: 0,
totalQuantity: 0,
transports: [],
});
}
const group = groups.get(key);
group.vehicleCount += 1;
if (transport.product && transport.size > 0) {
group.totalQuantity += transport.size || 0;
}
group.transports.push(transport);
}
// Sortiere nach ETA (früheste zuerst)
return Array.from(groups.values()).sort((a, b) => {
if (!a.eta && !b.eta) return 0;
if (!a.eta) return 1;
if (!b.eta) return -1;
return new Date(a.eta).getTime() - new Date(b.eta).getTime();
});
},
},
async mounted() { async mounted() {
await this.loadInventory(); await this.loadInventory();
await this.loadTransports(); await this.loadTransports();

View File

@@ -205,6 +205,7 @@
"runningTarget": "Ziel", "runningTarget": "Ziel",
"runningEta": "Ankunft", "runningEta": "Ankunft",
"runningRemaining": "Restzeit", "runningRemaining": "Restzeit",
"runningVehicleCount": "Fahrzeuge",
"runningDirectionOut": "Ausgehend", "runningDirectionOut": "Ausgehend",
"runningDirectionIn": "Eingehend" "runningDirectionIn": "Eingehend"
}, },