UI: darker dark mode, card layout, battery card polish (#31515)

This commit is contained in:
Michael Geers 2026-07-07 20:50:11 +02:00 • committed by GitHub
parent 82a3f643a6
commit 5e25ed4b02
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 232 additions and 193 deletions

View file

@ -83,6 +83,7 @@
--bs-danger: var(--evcc-red);
--bs-danger-rgb: var(--evcc-red-rgb);
--bs-border-color-translucent: rgba(0, 0, 0, 0.05);
--bs-form-invalid-border-color: var(--bs-danger);
@ -112,7 +113,7 @@
--evcc-export: var(--evcc-yellow);
--evcc-export-contrast: var(--evcc-yellow);
--evcc-background: var(--bs-gray-deep);
--evcc-box: var(--bs-gray-dark);
--evcc-box: var(--bs-gray-darker);
--evcc-box-border: var(--bs-gray-darker);
--evcc-default-text: var(--bs-white);
--evcc-gray: var(--bs-gray-light);
@ -121,7 +122,7 @@
--evcc-accent3: var(--evcc-darker-green);
--bs-primary: var(--evcc-dark-green);
--bs-primary-dim: color-mix(in srgb, var(--bs-primary) 70%, transparent);
--bs-border-color-translucent: rgba(255, 255, 255, 0.175);
--bs-border-color-translucent: rgba(255, 255, 255, 0.08);
--bs-code-color: var(--evcc-dark-green);
--evcc-backdrop: #000000aa; /* black + transparent */
--tab-bar-background: var(--evcc-box);
@ -442,6 +443,7 @@ a:hover {
border-radius: 1rem;
padding: 1.25rem;
background-color: var(--evcc-box);
border: 1px solid var(--bs-border-color-translucent);
color: var(--evcc-default-text);
}
@ -742,9 +744,18 @@ html.app .modal-dialog {
border-radius: 1rem;
color: var(--evcc-default-text);
background: var(--evcc-box);
border: 1px solid var(--bs-border-color-translucent);
padding: 1rem;
}
/* pull boxes into the container padding so box content aligns with the page header */
@media (min-width: 576px) {
.box-pull-out {
margin-left: -1.5rem;
margin-right: -1.5rem;
}
}
.round-box--error {
box-shadow: 0 0 0.5rem var(--bs-danger);
border: 1px solid var(--bs-danger);

View file

@ -1,9 +1,9 @@
<template>
<div v-if="batteryAvailable" data-testid="battery-experimental">
<BatteryStatusCards class="mb-4" :battery="state.battery" />
<BatteryStatusCards class="mb-4 box-pull-out" :battery="state.battery" />
<BatteryHistoryCard
class="mb-4"
class="mb-4 box-pull-out"
:batteries="chartBatteries"
:now="now"
:kwh-available="kWhAvailable"
@ -11,7 +11,7 @@
/>
<BatteryConfigCard
class="mb-4"
class="mb-4 box-pull-out"
:buffer-soc="state.bufferSoc"
:priority-soc="state.prioritySoc"
:buffer-start-soc="state.bufferStartSoc"
@ -19,7 +19,11 @@
:battery="state.battery"
/>
<Card v-if="gridChargeVisible" :title="$t('batterySettings.gridChargeTab')">
<Card
v-if="gridChargeVisible"
class="box-pull-out"
:title="$t('batterySettings.gridChargeTab')"
>
<SmartCostLimit v-bind="smartCostLimitProps" />
</Card>
</div>

View file

@ -1,11 +1,11 @@
<template>
<div v-if="showSplit" class="cards cards--split gap-3">
<div v-if="showSplit" class="cards cards--split gap-4">
<BatteryStatusCard v-bind="cards[0]" />
<Card :title="$t('battery.optimizer.title')" data-testid="battery-optimizer-card">
<OptimizerInfo :suggestion="suggestion" :forecast="batteryForecast" />
</Card>
</div>
<div v-else class="cards gap-3">
<div v-else class="cards gap-4">
<BatteryStatusCard v-for="card in cards" :key="card.id" v-bind="card" />
</div>
</template>

View file

@ -1,5 +1,5 @@
<template>
<section class="evcc-card p-3 p-sm-4" :class="{ 'evcc-card--edge': edgeToEdge }">
<section class="evcc-card round-box p-3 p-sm-4" :class="{ 'evcc-card--edge': edgeToEdge }">
<div
v-if="hasHeader"
class="evcc-card-header d-flex align-items-center gap-3 flex-wrap mb-3"
@ -57,11 +57,6 @@ export default defineComponent({
</script>
<style scoped>
.evcc-card {
background: var(--evcc-box);
border: 1px solid var(--bs-border-color-translucent);
border-radius: 1rem;
}
.evcc-card-subtitle {
color: var(--evcc-gray);
}
@ -69,9 +64,10 @@ export default defineComponent({
.evcc-card--edge {
margin-left: -1.5rem;
margin-right: -1.5rem;
border-left: none;
border-right: none;
border-width: 1px 0;
border-radius: 0;
padding-left: 1.5rem !important;
padding-right: 1.5rem !important;
}
}
</style>

View file

@ -404,6 +404,7 @@ export default defineComponent({
border-radius: 2rem;
color: var(--evcc-default-text);
background: var(--evcc-box);
border: 1px solid var(--bs-border-color-translucent);
}
.details > div {

View file

@ -1,5 +1,5 @@
<template>
<div class="mb-4">
<div>
<div class="table-responsive">
<table class="table">
<thead>

View file

@ -1,5 +1,5 @@
<template>
<div class="mb-5">
<div>
<div class="chart-container my-3">
<Chart
ref="chartRef"

View file

@ -1,6 +1,6 @@
<template>
<button
class="btn btn-link position-absolute text-primary rounded"
class="btn btn-link position-absolute text-primary"
:style="buttonStyle"
:title="copied ? 'Copied!' : 'Copy to clipboard'"
@click="handleCopy"
@ -47,7 +47,6 @@ export default defineComponent({
top: this.top,
right: this.right,
padding: this.padding,
backgroundColor: "var(--evcc-box)",
};
},
},

View file

@ -251,8 +251,9 @@ export default defineComponent({
padding: 0.75rem 0;
border-top: 1px solid var(--evcc-gray-25);
}
.field:last-child {
border-bottom: 1px solid var(--evcc-gray-25);
/* card provides the outer boundary */
.field:first-child {
border-top: none;
}
.field-head {
display: flex;
@ -279,6 +280,14 @@ export default defineComponent({
text-underline-offset: 3px;
}
/* small: slightly reduced value size, rows are tighter */
@media (max-width: 767.98px) {
.field-value .large,
.field-value .fs-4 {
font-size: 1.125rem !important;
}
}
/* md and up: each field a vertical stack (label, value, caption); columns via Bootstrap grid */
@media (min-width: 768px) {
.field {
@ -289,9 +298,6 @@ export default defineComponent({
padding: 0.75rem 1.5rem;
border: none;
}
.field:last-child {
border-bottom: none;
}
/* promote label + caption so value can sit between them via order */
.field-head {
display: contents;

View file

@ -1,5 +1,5 @@
<template>
<div class="mb-5">
<div>
<div class="chart-container my-3">
<Chart
ref="chartRef"

View file

@ -1,5 +1,5 @@
<template>
<div class="mb-5">
<div>
<div v-for="(_battery, index) in evopt.res.batteries" :key="index" class="mb-3">
<div class="mb-2" style="font-size: 0.875rem; font-weight: bold">
{{ getBatteryTitle(index) }}

View file

@ -1,5 +1,5 @@
<template>
<div class="mb-4">
<div>
<div class="table-responsive">
<table class="table table-sm">
<thead>

View file

@ -1,10 +1,8 @@
<template>
<h3 class="fw-normal mb-4">{{ $t("sessions.overview") }}</h3>
<div v-if="sessions.length === 0" data-testid="sessions-nodata" class="mb-5">
<div v-if="sessions.length === 0" data-testid="sessions-nodata">
<p>{{ $t("sessions.noData") }}</p>
</div>
<div v-else class="mb-5 table-outer">
<div v-else class="table-outer">
<table class="table text-nowrap">
<thead class="sticky-top">
<tr data-testid="sessions-head">
@ -479,7 +477,7 @@ export default defineComponent({
}
.table thead,
.table tfoot {
background: var(--evcc-background);
background: var(--evcc-box);
}
.table tfoot th {
border-top-width: 2px;

View file

@ -8,7 +8,7 @@
<label :for="formId" class="col-sm-4 col-form-label pt-0 pt-sm-2">
{{ limitLabel }}
</label>
<div class="col-sm-8 col-lg-4 pe-0">
<div class="col-sm-8 col-lg-4 pe-lg-0">
<div class="input-group input-group-sm mb-1 mb-lg-0">
<div class="input-group-text">
<div class="form-check form-switch m-0">

View file

@ -16,6 +16,7 @@
<h2 class="my-4 mt-5">{{ $t("config.section.general") }}</h2>
<GeneralConfig
class="box-pull-out"
:experimental="experimental"
:sponsor-error="hasClassError('sponsorship')"
@site-changed="siteChanged"
@ -23,7 +24,7 @@
<WelcomeBanner v-if="setupRequired" />
<h2 class="my-4">{{ $t("config.section.loadpoints") }}</h2>
<div class="p-0 config-list">
<div class="p-0 config-list box-pull-out">
<DeviceCard
v-for="loadpoint in loadpoints"
:id="`loadpoint_${loadpoint.name}`"
@ -55,7 +56,7 @@
</div>
<h2 class="my-4">{{ $t("config.section.vehicles") }}</h2>
<div class="p-0 config-list">
<div class="p-0 config-list box-pull-out">
<DeviceCard
v-for="vehicle in vehicles"
:id="`vehicle_${vehicle.name}`"
@ -82,7 +83,7 @@
</div>
<h2 class="my-4 mt-5">{{ $t("config.section.consumers") }}</h2>
<div class="p-0 config-list">
<div class="p-0 config-list box-pull-out">
<MeterCard
v-for="meter in consumerMeters"
:key="meter.name"
@ -109,7 +110,7 @@
</div>
<h2 class="my-4 mt-5">{{ $t("config.section.grid") }}</h2>
<div class="p-0 config-list">
<div class="p-0 config-list box-pull-out">
<MeterCard
v-if="gridMeter"
:meter="gridMeter"
@ -127,7 +128,7 @@
/>
</div>
<h2 class="my-4 mt-5">{{ $t("config.section.meter") }}</h2>
<div class="p-0 config-list">
<div class="p-0 config-list box-pull-out">
<MeterCard
v-for="meter in pvMeters"
:key="meter.name"
@ -154,7 +155,7 @@
</div>
<h2 class="my-4 mt-5">{{ $t("config.section.additionalMeter") }}</h2>
<div class="p-0 config-list">
<div class="p-0 config-list box-pull-out">
<MeterCard
v-for="meter in extMeters"
:key="meter.name"
@ -172,7 +173,7 @@
</div>
<h2 id="tariffs" class="my-4 mt-5">{{ $t("config.tariff.title") }}</h2>
<div v-if="!!tariffsYamlSource" class="p-0 config-list">
<div v-if="!!tariffsYamlSource" class="p-0 config-list box-pull-out">
<DeviceCard
:title="$t('config.tariff.title')"
:editable="tariffsYamlSource === 'db'"
@ -191,7 +192,7 @@
</template>
</DeviceCard>
</div>
<div v-else class="p-0 config-list">
<div v-else class="p-0 config-list box-pull-out">
<TariffCard
v-if="gridTariff"
:tariff="gridTariff"
@ -252,7 +253,7 @@
<h2 class="my-4 mt-5">{{ $t("config.section.integrations") }}</h2>
<div class="p-0 config-list">
<div class="p-0 config-list box-pull-out">
<AuthProvidersCard
:providers="authProviders"
data-testid="auth-providers"
@ -374,7 +375,7 @@
</div>
<h2 class="my-4 mt-5">{{ $t("config.section.services") }}</h2>
<div class="p-0 config-list">
<div class="p-0 config-list box-pull-out">
<DeviceCard
:title="$t('config.ocpp.title')"
editable
@ -416,7 +417,10 @@
<hr class="my-5" />
<h2 class="my-4 mt-5">{{ $t("config.section.system") }}</h2>
<div data-testid="config-system" class="round-box p-4 d-flex gap-4 flex-wrap">
<div
data-testid="config-system"
class="round-box box-pull-out p-4 d-flex gap-4 flex-wrap"
>
<router-link to="/log" class="btn btn-outline-secondary">
{{ $t("config.system.logs") }}
</router-link>

View file

@ -42,13 +42,14 @@
</div>
<div v-else class="row">
<main class="col-12 d-flex flex-column">
<section v-if="forecast.solar" class="mb-5">
<div class="d-flex align-items-baseline my-4">
<h3 class="fw-normal mb-0">{{ $t("forecast.type.solar") }}</h3>
<div
v-if="showSolarAdjust"
class="form-check form-switch ms-auto mb-0 text-nowrap"
>
<Card
v-if="forecast.solar"
:title="$t('forecast.type.solar')"
edge-to-edge
class="box-pull-out mb-4"
>
<template v-if="showSolarAdjust" #actions>
<div class="form-check form-switch mb-0 text-nowrap">
<input
id="solarForecastAdjust"
:checked="solarAdjusted"
@ -62,7 +63,7 @@
<span class="d-none d-md-inline">{{ solarAdjustTextMedium }}</span>
</label>
</div>
</div>
</template>
<div class="chart-edge">
<SolarChart
:solar="solar"
@ -74,16 +75,17 @@
/>
</div>
<SolarDetails :solar="solar" />
</section>
</Card>
<section
<Card
v-if="forecast.grid"
class="mb-5"
:title="$t('forecast.type.price')"
edge-to-edge
class="box-pull-out mb-4"
:style="isGridStatic ? { order: 1 } : undefined"
>
<div class="d-flex align-items-baseline my-4">
<h3 class="fw-normal mb-0">{{ $t("forecast.type.price") }}</h3>
<div class="form-check form-switch ms-auto mb-0 text-nowrap">
<template #actions>
<div class="form-check form-switch mb-0 text-nowrap">
<input
id="priceZoom"
:checked="priceZoom"
@ -96,7 +98,7 @@
{{ $t("forecast.priceZoom") }}
</label>
</div>
</div>
</template>
<div class="chart-edge">
<PriceChart
:grid="forecast.grid"
@ -116,10 +118,14 @@
:show-feedin="showFeedin"
@toggle-feedin="toggleFeedin"
/>
</section>
</Card>
<section v-if="forecast.co2" class="mb-5">
<h3 class="fw-normal my-4">{{ $t("forecast.type.co2") }}</h3>
<Card
v-if="forecast.co2"
:title="$t('forecast.type.co2')"
edge-to-edge
class="box-pull-out mb-4"
>
<div class="chart-edge">
<Co2Chart
:co2="forecast.co2"
@ -130,7 +136,7 @@
/>
</div>
<Co2Details :co2="forecast.co2" />
</section>
</Card>
</main>
</div>
</div>
@ -141,6 +147,7 @@ import "@h2d2/shopicons/es/regular/sun";
import "@h2d2/shopicons/es/regular/eco1";
import { defineComponent } from "vue";
import Header from "../components/Top/Header.vue";
import Card from "../components/Helper/Card.vue";
import DynamicPriceIcon from "../components/MaterialIcon/DynamicPrice.vue";
import SolarChart from "../components/Forecast/SolarChart.vue";
import SolarDetails from "../components/Forecast/SolarDetails.vue";
@ -160,6 +167,7 @@ export default defineComponent({
name: "Forecast",
components: {
TopHeader: Header,
Card,
DynamicPriceIcon,
SolarChart,
SolarDetails,
@ -295,9 +303,17 @@ export default defineComponent({
max-width: 480px;
}
@media (max-width: 575.98px) {
/* cancel the card's padding for full-bleed charts */
.chart-edge {
margin-left: -1.5rem;
margin-right: -1.5rem;
}
}
@media (min-width: 576px) {
/* compensate the card border so the chart width fits without scrolling on wide screens */
.chart-edge {
margin-left: -1px;
margin-right: -1px;
}
}
</style>

View file

@ -37,7 +37,7 @@
<div
v-for="i in 3"
:key="i"
class="history-tile history-tile-skeleton mb-4"
class="history-tile history-tile-skeleton box-pull-out mb-4"
aria-hidden="true"
></div>
</div>
@ -53,7 +53,7 @@
:title="$t(`main.history.group.${group}`)"
:subtitle="groupTotalLabel(group)"
edge-to-edge
class="mb-4"
class="box-pull-out mb-4"
:data-testid="`history-section-${group}`"
>
<GroupChart

View file

@ -1,25 +1,24 @@
<template>
<div class="container px-4 safe-area-inset">
<TopHeader title="Optimize Debug 🧪" />
<OptimizeHeader
class="mt-4 mb-5"
:updated="evopt?.updated"
:status="evopt?.res?.status"
:net-cost="netCost"
:horizon-hours="horizonHours"
:currency="currency"
:charging-strategies="chargingStrategies"
:selected-strategy="optimizerChargingStrategy"
:pending="pending"
@optimize="optimizeNow"
@change-strategy="changeChargingStrategy"
/>
<Card edge-to-edge class="box-pull-out mt-4 mb-4">
<OptimizeHeader
:updated="evopt?.updated"
:status="evopt?.res?.status"
:net-cost="netCost"
:horizon-hours="horizonHours"
:currency="currency"
:charging-strategies="chargingStrategies"
:selected-strategy="optimizerChargingStrategy"
:pending="pending"
@optimize="optimizeNow"
@change-strategy="changeChargingStrategy"
/>
</Card>
<div class="row">
<main class="col-12">
<div v-if="evopt">
<!-- Optimizer Plan -->
<section class="mb-5">
<h3 class="fw-normal mb-4">Result: Charging Plan</h3>
<Card title="Result: Charging Plan" edge-to-edge class="box-pull-out mb-4">
<ChargeChart
:evopt="evopt"
:battery-details="evopt.details.batteryDetails"
@ -28,8 +27,9 @@
:battery-colors="batteryColors"
:device-colors="deviceColors"
/>
</Card>
<h3 class="fw-normal mb-4">Result: SoC Projection</h3>
<Card title="Result: SoC Projection" edge-to-edge class="box-pull-out mb-4">
<SocChart
:evopt="evopt"
:battery-details="evopt.details.batteryDetails"
@ -37,42 +37,30 @@
:currency="currency"
:battery-colors="batteryColors"
/>
</section>
</Card>
<!-- Input Parameters -->
<section class="mb-5">
<h3 class="fw-normal mb-4">Input: Grid Prices</h3>
<Card title="Input: Grid Prices" edge-to-edge class="box-pull-out mb-4">
<PriceChart
:evopt="evopt"
:timestamp="evopt.details.timestamp[0]"
:currency="currency"
/>
</Card>
<h3
class="fw-normal d-flex gap-3 flex-wrap d-flex align-items-baseline overflow-hidden mb-4"
>
<span class="d-block no-wrap text-truncate"> Input: Battery </span>
<small class="d-block no-wrap text-truncate">
{{ fmtPercentage((evopt.req.eta_c || 1) * 100, 1) }} charge
efficiency ・
{{ fmtPercentage((evopt.req.eta_d || 1) * 100, 1) }} discharge
efficiency
</small>
</h3>
<Card
title="Input: Battery"
:subtitle="batteryEfficiencySubtitle"
edge-to-edge
class="box-pull-out mb-4"
>
<BatteryConfigurationTable
:batteries="evopt.req.batteries"
:battery-details="evopt.details.batteryDetails"
:currency="currency"
/>
</section>
<hr class="my-5" />
<!-- Debugging -->
<section class="mb-5">
<h3 class="fw-normal mb-4">Time Series</h3>
</Card>
<Card title="Time Series" edge-to-edge class="box-pull-out mb-4">
<TimeSeriesDataTable
:evopt="evopt"
:battery-details="evopt.details.batteryDetails"
@ -81,33 +69,33 @@
:battery-colors="batteryColors"
:dimmed-battery-colors="dimmedBatteryColors"
/>
</Card>
<h3 class="fw-normal mb-4">Raw Data</h3>
<Card title="Raw Data" edge-to-edge class="box-pull-out mb-4">
<div class="mb-4">
<p class="mb-2">Request:</p>
<div class="position-relative">
<pre
class="p-3 rounded border overflow-auto"
style="background-color: var(--evcc-box)"
class="p-3 overflow-auto"
style="background-color: var(--evcc-gray-10)"
>{{ formattedRequest }}</pre
>
<CopyButton :content="formattedRequest" />
</div>
</div>
<div class="mb-4">
<div>
<p class="mb-2">Response:</p>
<div class="position-relative">
<pre
class="p-3 rounded border overflow-auto"
style="background-color: var(--evcc-box)"
class="p-3 overflow-auto"
style="background-color: var(--evcc-gray-10)"
>{{ formattedResponse }}</pre
>
<CopyButton :content="formattedResponse" />
</div>
</div>
</section>
</Card>
</div>
<div v-else>
<p>nothing to see here</p>
@ -120,6 +108,7 @@
<script lang="ts">
import { defineComponent } from "vue";
import Header from "../components/Top/Header.vue";
import Card from "../components/Helper/Card.vue";
import OptimizeHeader from "../components/Optimize/OptimizeHeader.vue";
import BatteryConfigurationTable from "../components/Optimize/BatteryConfigurationTable.vue";
import SocChart from "../components/Optimize/SocChart.vue";
@ -138,6 +127,7 @@ export default defineComponent({
name: "Optimize",
components: {
TopHeader: Header,
Card,
OptimizeHeader,
BatteryConfigurationTable,
SocChart,
@ -176,6 +166,11 @@ export default defineComponent({
if (!dt?.length) return 0;
return Math.round(dt.reduce((sum, s) => sum + s, 0) / 3600);
},
batteryEfficiencySubtitle(): string {
const etaC = this.fmtPercentage((this.evopt?.req.eta_c || 1) * 100, 1);
const etaD = this.fmtPercentage((this.evopt?.req.eta_d || 1) * 100, 1);
return `${etaC} charge efficiency ・ ${etaD} discharge efficiency`;
},
deviceColors() {
return deviceColorMap(store.state.deviceColors);
},

View file

@ -65,91 +65,98 @@
</IconSelectGroup>
</div>
<h3
class="fw-normal my-0 d-flex gap-3 flex-wrap d-flex align-items-baseline overflow-hidden"
<Card
:title="historyTitle"
:subtitle="historySubTitle"
edge-to-edge
class="box-pull-out mb-4"
>
<span v-if="historyTitle" class="d-block no-wrap text-truncate">
{{ historyTitle }}
</span>
<small class="d-block no-wrap text-truncate">{{ historySubTitle }}</small>
</h3>
<EnergyHistoryChart
v-if="activeType === types.SOLAR"
class="mb-5"
:sessions="currentSessions"
:color-mappings="colorMappings"
:device-colors="deviceColors"
:group-by="selectedGroup"
:period="period"
/>
<CostHistoryChart
v-else
class="mb-5"
:sessions="currentTypeSessions"
:color-mappings="colorMappings"
:device-colors="deviceColors"
:group-by="selectedGroup"
:cost-type="activeType"
:currency="currency"
:period="period"
/>
<div v-if="showExtraCharts" class="row align-items-start">
<div class="col-12 col-lg-6 mb-5">
<h3 class="fw-normal my-4">{{ firstExtraTitle }}</h3>
<div v-if="activeType === types.SOLAR">
<SolarYearChart
v-if="showSolarYearChart"
:period="period"
:sessions="currentSessions"
/>
<SolarGroupedChart
v-else
:sessions="currentSessions"
:color-mappings="colorMappings"
:device-colors="deviceColors"
:group-by="selectedGroupWithoutNone"
/>
<EnergyHistoryChart
v-if="activeType === types.SOLAR"
:sessions="currentSessions"
:color-mappings="colorMappings"
:device-colors="deviceColors"
:group-by="selectedGroup"
:period="period"
/>
<CostHistoryChart
v-else
:sessions="currentTypeSessions"
:color-mappings="colorMappings"
:device-colors="deviceColors"
:group-by="selectedGroup"
:cost-type="activeType"
:currency="currency"
:period="period"
/>
</Card>
<div v-if="showExtraCharts" class="box-pull-out">
<div class="row align-items-start">
<div class="col-12 col-lg-6 mb-4">
<Card :title="firstExtraTitle" edge-to-edge>
<div v-if="activeType === types.SOLAR">
<SolarYearChart
v-if="showSolarYearChart"
:period="period"
:sessions="currentSessions"
/>
<SolarGroupedChart
v-else
:sessions="currentSessions"
:color-mappings="colorMappings"
:device-colors="deviceColors"
:group-by="selectedGroupWithoutNone"
/>
</div>
<AvgCostGroupedChart
v-else
:sessions="currentTypeSessions"
:color-mappings="colorMappings"
:device-colors="deviceColors"
:suggested-max-price="suggestedMaxAvgCost"
:group-by="selectedGroupWithoutNone"
:cost-type="activeType"
:currency="currency"
/>
</Card>
</div>
<div class="col-12 col-lg-6 mb-4">
<Card :title="secondExtraTitle" edge-to-edge>
<EnergyGroupedChart
v-if="activeType === types.SOLAR"
:sessions="currentSessions"
:color-mappings="colorMappings"
:device-colors="deviceColors"
:group-by="selectedGroupWithoutNone"
/>
<CostGroupedChart
v-else
:sessions="currentTypeSessions"
:color-mappings="colorMappings"
:device-colors="deviceColors"
:group-by="selectedGroupWithoutNone"
:cost-type="activeType"
:currency="currency"
/>
</Card>
</div>
<AvgCostGroupedChart
v-else
:sessions="currentTypeSessions"
:color-mappings="colorMappings"
:device-colors="deviceColors"
:suggested-max-price="suggestedMaxAvgCost"
:group-by="selectedGroupWithoutNone"
:cost-type="activeType"
:currency="currency"
/>
</div>
<div class="col-12 col-lg-6 mb-5">
<h3 class="fw-normal my-4">{{ secondExtraTitle }}</h3>
<EnergyGroupedChart
v-if="activeType === types.SOLAR"
:sessions="currentSessions"
:color-mappings="colorMappings"
:device-colors="deviceColors"
:group-by="selectedGroupWithoutNone"
/>
<CostGroupedChart
v-else
:sessions="currentTypeSessions"
:color-mappings="colorMappings"
:device-colors="deviceColors"
:group-by="selectedGroupWithoutNone"
:cost-type="activeType"
:currency="currency"
/>
</div>
</div>
<SessionTable
<Card
v-if="showTable"
:sessions="currentSessions"
:vehicleFilter="vehicleFilter"
:loadpointFilter="loadpointFilter"
:currency="currency"
@show-session="showDetails"
/>
:title="$t('sessions.overview')"
edge-to-edge
class="box-pull-out mb-4"
>
<SessionTable
:sessions="currentSessions"
:vehicleFilter="vehicleFilter"
:loadpointFilter="loadpointFilter"
:currency="currency"
@show-session="showDetails"
/>
</Card>
<div class="d-flex gap-2 my-3">
<a
class="btn btn-outline-secondary"
@ -201,6 +208,7 @@ import CostHistoryChart from "../components/Sessions/CostHistoryChart.vue";
import CostGroupedChart from "../components/Sessions/CostGroupedChart.vue";
import AvgCostGroupedChart from "../components/Sessions/AvgCostGroupedChart.vue";
import Header from "../components/Top/Header.vue";
import Card from "../components/Helper/Card.vue";
import IconSelectGroup from "../components/Helper/IconSelectGroup.vue";
import IconSelectItem from "../components/Helper/IconSelectItem.vue";
import SelectGroup from "../components/Helper/SelectGroup.vue";
@ -223,6 +231,7 @@ export default defineComponent({
SessionDetailsModal,
SessionTable,
TopHeader: Header,
Card,
EnergyHistoryChart,
EnergyGroupedChart,
IconSelectGroup,