120 lines
3.2 KiB
Vue
120 lines
3.2 KiB
Vue
<template>
|
|
<div class="d-flex justify-content-between mb-2 entry" :class="{ 'evcc-gray': !active }">
|
|
<span class="d-flex flex-nowrap">
|
|
<BatteryIcon v-if="isBattery" :soc="soc" />
|
|
<VehicleIcon v-else-if="isVehicle" :names="vehicleIcons" />
|
|
<component :is="`shopicon-regular-${icon}`" v-else></component>
|
|
</span>
|
|
<span class="text-nowrap flex-grow-1 ms-3">
|
|
{{ name }}
|
|
</span>
|
|
<span class="text-end text-nowrap ps-1 fw-bold d-flex">
|
|
<div ref="details" class="fw-normal" data-bs-toggle="tooltip" @click.stop="">
|
|
<AnimatedNumber v-if="details !== undefined" :to="details" :format="detailsFmt" />
|
|
</div>
|
|
<div ref="power" class="power" data-bs-toggle="tooltip" @click.stop="">
|
|
<AnimatedNumber :to="power" :format="kw" />
|
|
</div>
|
|
</span>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import "@h2d2/shopicons/es/regular/powersupply";
|
|
import "@h2d2/shopicons/es/regular/sun";
|
|
import "@h2d2/shopicons/es/regular/home";
|
|
import Tooltip from "bootstrap/js/dist/tooltip";
|
|
import BatteryIcon from "./BatteryIcon.vue";
|
|
import formatter from "../../mixins/formatter";
|
|
import AnimatedNumber from "../AnimatedNumber.vue";
|
|
import VehicleIcon from "../VehicleIcon";
|
|
|
|
export default {
|
|
name: "EnergyflowEntry",
|
|
components: { BatteryIcon, AnimatedNumber, VehicleIcon },
|
|
mixins: [formatter],
|
|
props: {
|
|
name: { type: String },
|
|
icon: { type: String },
|
|
vehicleIcons: { type: Array },
|
|
power: { type: Number },
|
|
powerTooltip: { type: Array },
|
|
powerInKw: { type: Boolean },
|
|
soc: { type: Number },
|
|
details: { type: Number },
|
|
detailsFmt: { type: Function },
|
|
detailsTooltip: { type: Array },
|
|
},
|
|
data() {
|
|
return { powerTooltipInstance: null, detailsTooltipInstance: null };
|
|
},
|
|
computed: {
|
|
active: function () {
|
|
return this.power > 10;
|
|
},
|
|
isBattery: function () {
|
|
return this.icon === "battery";
|
|
},
|
|
isVehicle: function () {
|
|
return this.icon === "vehicle";
|
|
},
|
|
},
|
|
watch: {
|
|
powerTooltip(newVal, oldVal) {
|
|
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
|
this.updatePowerTooltip();
|
|
}
|
|
},
|
|
detailsTooltip(newVal, oldVal) {
|
|
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
|
this.updateDetailsTooltip();
|
|
}
|
|
},
|
|
},
|
|
mounted: function () {
|
|
this.updatePowerTooltip();
|
|
this.updateDetailsTooltip();
|
|
},
|
|
methods: {
|
|
kw: function (watt) {
|
|
return this.fmtKw(watt, this.powerInKw);
|
|
},
|
|
updatePowerTooltip() {
|
|
this.powerTooltipInstance = this.updateTooltip(
|
|
this.powerTooltipInstance,
|
|
this.powerTooltip,
|
|
this.$refs.power
|
|
);
|
|
},
|
|
updateDetailsTooltip() {
|
|
this.detailsTooltipInstance = this.updateTooltip(
|
|
this.detailsTooltipInstance,
|
|
this.detailsTooltip,
|
|
this.$refs.details
|
|
);
|
|
},
|
|
updateTooltip: function (instance, content, ref) {
|
|
if (!Array.isArray(content) || !content.length) {
|
|
if (instance) {
|
|
instance.dispose();
|
|
}
|
|
return;
|
|
}
|
|
if (!instance) {
|
|
instance = new Tooltip(ref, { html: true, title: " " });
|
|
}
|
|
const html = `<div class="text-end">${content.join("<br/>")}</div>`;
|
|
instance.setContent({ ".tooltip-inner": html });
|
|
return instance;
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
<style scoped>
|
|
.entry {
|
|
transition: color var(--evcc-transition-medium) linear;
|
|
}
|
|
.power {
|
|
min-width: 75px;
|
|
}
|
|
</style>
|