Improve charging sessions UI (#4927)

This commit is contained in:
Michael Geers 2022-10-26 07:51:04 +02:00 • committed by GitHub
parent cef8bb15fc
commit 5d7ca8f575
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 138 additions and 133 deletions

View file

@ -181,7 +181,7 @@ downloadCsv = "Als CSV herunterladen"
loadpoint = "Ladepunkt"
vehicle = "Fahrzeug"
energy = "Geladen"
date = "Beendet"
date = "Zeitraum"
[sessions.csv]
loadpoint = "Ladepunkt"

View file

@ -181,7 +181,7 @@ downloadCsv = "Download as CSV"
loadpoint = "Loadpoint"
vehicle = "Vehicle"
energy = "Charged"
date = "Finished"
date = "Period"
[sessions.csv]
loadpoint = "Loadpoint"

View file

@ -181,7 +181,7 @@ downloadCsv = "Parsisiųsti CSV failą"
loadpoint = "Įkroviklis"
vehicle = "Automobilis"
energy = "Įkrauta"
date = "Baigta"
date = "Laikotarpis"
[sessions.csv]
loadpoint = "Įkroviklis"

View file

@ -22,84 +22,92 @@
</a>
</div>
<div v-for="group in sessionsByMonth" :key="group.month" class="mb-5">
<div v-for="group in sessionsByMonthAndLoadpoint" :key="group.month">
<div class="mx-2">
<div class="d-flex align-items-baseline mb-3">
<div class="d-flex align-items-baseline my-5">
<h2 class="me-4 mb-0">
{{ formatGroupHeadline(group.month) }}
</h2>
<div class="large">{{ fmtKWh(totalKWh(group.sessions)) }}</div>
</div>
<ul
v-for="by in ['loadpoint', 'vehicle']"
:key="by"
class="breakdown text-gray d-sm-flex flex-sm-wrap ps-0 mb-2"
>
<li
v-for="(loadpoint, id) in groupedKWh(by, group.sessions)"
:key="id"
class="breakdown-item"
>
{{ loadpoint.name }}: {{ fmtKWh(loadpoint.energy) }}
</li>
</ul>
</div>
<div class="table-responsive mt-3">
<table class="table">
<thead>
<tr>
<th scope="col" class="d-table-cell d-sm-none">
{{ $t("sessions.loadpoint") }}
<span class="text-nowrap">
→ {{ $t("sessions.vehicle") }}
</span>
</th>
<th scope="col" class="d-none d-sm-table-cell">
{{ $t("sessions.loadpoint") }}
</th>
<th scope="col" class="d-none d-sm-table-cell">
{{ $t("sessions.vehicle") }}
</th>
<th scope="col">{{ $t("sessions.energy") }}</th>
<th scope="col">{{ $t("sessions.date") }}</th>
</tr>
</thead>
<tbody>
<tr v-for="(session, id) in group.sessions" :key="id">
<td class="d-table-cell d-sm-none">
<span
v-if="
session.loadpointDisplay || session.vehicleDisplay
"
>
<span>
{{ session.loadpointDisplay }}
</span>
<span class="text-nowrap">
→ {{ session.vehicleDisplay }}
</span>
</span>
</td>
<td class="text-nowrap d-none d-sm-table-cell">
{{ session.loadpointDisplay }}
</td>
<td class="text-nowrap d-none d-sm-table-cell">
{{ session.vehicleDisplay }}
</td>
<td class="text-nowrap">
{{ fmtKWh(session.chargedEnergy * 1e3) }}
</td>
<td class="text-nowrap">
<span class="d-block d-sm-none">
{{ fmtFullDateTime(new Date(session.finished), true) }}
</span>
<span class="d-none d-sm-block">
{{ fmtFullDateTime(new Date(session.finished), false) }}
</span>
</td>
</tr>
</tbody>
</table>
<div v-for="loadpoint in group.loadpoints" :key="loadpoint.name">
<div class="d-flex align-items-baseline mb-3">
<h3 class="me-4 mb-0">
{{ loadpoint.name }}
</h3>
<div class="large">{{ fmtKWh(loadpoint.total) }}</div>
</div>
<ul class="breakdown text-gray d-sm-flex flex-sm-wrap ps-0 mb-2">
<li
v-for="(vehicle, id) in groupedKWh(
'vehicle',
loadpoint.sessions
)"
:key="id"
class="breakdown-item"
>
{{ vehicle.name }}: {{ fmtKWh(vehicle.energy) }}
</li>
</ul>
<div class="table-responsive my-3">
<table class="table">
<thead>
<tr>
<th scope="col">{{ $t("sessions.vehicle") }}</th>
<th scope="col" class="text-end ps-sm-4 pe-md-5">
{{ $t("sessions.energy") }}
</th>
<th scope="col" class="ps-3 ps-md-4 ps-md-5">
{{ $t("sessions.date") }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(session, id) in loadpoint.sessions" :key="id">
<td>
{{ session.vehicle }}
</td>
<td class="text-nowrap text-end ps-sm-4 pe-md-5">
{{ fmtKWh(session.chargedEnergy * 1e3) }}
</td>
<td class="text-nowrap ps-3 ps-md-4 ps-md-5">
<span class="d-block d-sm-none">
{{
fmtFullDateTime(
new Date(session.created),
true
)
}}
<br />
{{
fmtFullDateTime(
new Date(session.finished),
true
)
}}
</span>
<span class="d-none d-sm-block">
{{
fmtFullDateTime(
new Date(session.created),
false
)
}}
<br />
{{
fmtFullDateTime(
new Date(session.finished),
false
)
}}
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</main>
@ -124,36 +132,23 @@ export default {
return { sessions: [] };
},
computed: {
sessionsByMonth() {
const grouped = this.sessions.reduce((groups, session) => {
const date = new Date(session.finished);
const month = `${date.getFullYear()}.${date.getMonth()}`;
if (!groups[month]) groups[month] = [];
groups[month].push(session);
return groups;
}, {});
return Object.entries(grouped).map(([month, sessions]) => {
let lastLoadpoint = "";
let lastVehicle = "";
const cleanedSession = sessions.map((session) => {
const result = { ...session };
if (!result.vehicle) {
result.vehicle = this.$t("main.vehicle.unknown");
}
if (!result.loadpoint) {
result.loadpoint = this.$t("main.loadpoint.fallbackName");
}
sessionsByMonthAndLoadpoint() {
const sessionsWithDefaults = this.sessions.map((session) => {
const loadpoint = session.loadpoint || this.$t("main.loadpoint.fallbackName");
const vehicle = session.vehicle || this.$t("main.vehicle.unknown");
return { ...session, loadpoint, vehicle };
});
const identical =
lastLoadpoint === result.loadpoint && lastVehicle === result.vehicle;
result.loadpointDisplay = identical ? null : result.loadpoint;
result.vehicleDisplay = identical ? null : result.vehicle;
const sessionsByMonth = this.groupByMonth(sessionsWithDefaults);
lastLoadpoint = result.loadpoint;
lastVehicle = result.vehicle;
return result;
});
return { month, sessions: cleanedSession };
return Object.entries(sessionsByMonth).map(([month, sessions]) => {
const loadpoints = Object.entries(this.groupByLoadpoint(sessions)).map(
([loadpoint, sessionsByLoadpoint]) => {
const total = this.totalKWh(sessionsByLoadpoint);
return { name: loadpoint, total, sessions: sessionsByLoadpoint };
}
);
return { month, loadpoints };
});
},
},
@ -165,6 +160,23 @@ export default {
const response = await api.get("sessions");
this.sessions = response.data?.result;
},
groupByMonth(sessions) {
return sessions.reduce((groups, session) => {
const date = new Date(session.finished);
const month = `${date.getFullYear()}.${date.getMonth()}`;
if (!groups[month]) groups[month] = [];
groups[month].push(session);
return groups;
}, {});
},
groupByLoadpoint(sessions) {
return sessions.reduce((groups, session) => {
const loadpoint = session.loadpoint;
if (!groups[loadpoint]) groups[loadpoint] = [];
groups[loadpoint].push(session);
return groups;
}, {});
},
totalKWh(sessions) {
return sessions.reduce((total, session) => total + session.chargedEnergy, 0) * 1e3;
},
@ -219,11 +231,4 @@ export default {
.breakdown:empty {
display: none;
}
.table td {
border-top-width: 1px;
border-bottom-width: 0;
}
.table td:empty {
border-top-width: 0;
}
</style>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
dist/index.html vendored
View file

@ -20,8 +20,8 @@
<meta name="theme-color" content="#020318" />
<title>evcc</title>
<script type="module" crossorigin src="./assets/index.170c5f46.js"></script>
<link rel="stylesheet" href="./assets/index.08f10448.css">
<script type="module" crossorigin src="./assets/index.714c7ce4.js"></script>
<link rel="stylesheet" href="./assets/index.f831c606.css">
</head>
<body>