UI: force plan start rerender on day change (#26479)
This commit is contained in:
parent
a4d704164b
commit
63ba00ba73
5 changed files with 51 additions and 41 deletions
|
|
@ -92,10 +92,11 @@ import Arrival from "./Arrival.vue";
|
|||
|
||||
import formatter from "@/mixins/formatter";
|
||||
import collector from "@/mixins/collector";
|
||||
import minuteTicker from "@/mixins/minuteTicker";
|
||||
import api from "@/api";
|
||||
import { optionStep, fmtEnergy } from "@/utils/energyOptions.ts";
|
||||
import { defineComponent, type PropType } from "vue";
|
||||
import type { CURRENCY, Timeout, Vehicle } from "@/types/evcc";
|
||||
import type { CURRENCY, Vehicle } from "@/types/evcc";
|
||||
import type {
|
||||
StaticPlan,
|
||||
StaticSocPlan,
|
||||
|
|
@ -104,7 +105,6 @@ import type {
|
|||
PlanStrategy,
|
||||
} from "./types";
|
||||
import type { Forecast } from "@/types/evcc.ts";
|
||||
const ONE_MINUTE = 60 * 1000;
|
||||
|
||||
export default defineComponent({
|
||||
name: "ChargingPlan",
|
||||
|
|
@ -114,7 +114,7 @@ export default defineComponent({
|
|||
ChargingPlansSettings: PlansSettings,
|
||||
ChargingPlanArrival: Arrival,
|
||||
},
|
||||
mixins: [formatter, collector],
|
||||
mixins: [formatter, collector, minuteTicker],
|
||||
props: {
|
||||
currency: String as PropType<CURRENCY>,
|
||||
disabled: Boolean,
|
||||
|
|
@ -148,7 +148,6 @@ export default defineComponent({
|
|||
isModalVisible: false,
|
||||
activeTab: "departure",
|
||||
targetTimeLabel: "",
|
||||
interval: null as Timeout,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -243,6 +242,9 @@ export default defineComponent({
|
|||
effectivePlanTime(): void {
|
||||
this.updateTargetTimeLabel();
|
||||
},
|
||||
everyMinute(): void {
|
||||
this.updateTargetTimeLabel();
|
||||
},
|
||||
"$i18n.locale": {
|
||||
handler(): void {
|
||||
this.updateTargetTimeLabel();
|
||||
|
|
@ -250,14 +252,8 @@ export default defineComponent({
|
|||
},
|
||||
},
|
||||
mounted(): void {
|
||||
this.interval = setInterval(this.updateTargetTimeLabel, ONE_MINUTE);
|
||||
this.updateTargetTimeLabel();
|
||||
},
|
||||
unmounted(): void {
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
modalVisible(): void {
|
||||
this.isModalVisible = true;
|
||||
|
|
|
|||
|
|
@ -38,13 +38,14 @@
|
|||
<script lang="ts">
|
||||
import { defineComponent, type PropType } from "vue";
|
||||
import formatter from "@/mixins/formatter";
|
||||
import minuteTicker from "@/mixins/minuteTicker";
|
||||
import TariffChart from "../Tariff/TariffChart.vue";
|
||||
import { SMART_COST_TYPE, type CURRENCY, type Rate, type Slot } from "@/types/evcc";
|
||||
|
||||
export default defineComponent({
|
||||
name: "ChargingPlanPreview",
|
||||
components: { TariffChart },
|
||||
mixins: [formatter],
|
||||
mixins: [formatter, minuteTicker],
|
||||
props: {
|
||||
duration: Number,
|
||||
power: Number,
|
||||
|
|
@ -55,7 +56,10 @@ export default defineComponent({
|
|||
currency: String as PropType<CURRENCY>,
|
||||
},
|
||||
data() {
|
||||
return { activeIndex: null as number | null, startTime: new Date() };
|
||||
return {
|
||||
activeIndex: null as number | null,
|
||||
startTime: new Date(),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
endTime(): Date | null {
|
||||
|
|
@ -172,6 +176,9 @@ export default defineComponent({
|
|||
rates(): void {
|
||||
this.startTime = new Date();
|
||||
},
|
||||
everyMinute(): void {
|
||||
this.startTime = new Date();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
convertDates(list: Rate[] | undefined): Rate[] {
|
||||
|
|
|
|||
|
|
@ -65,8 +65,9 @@
|
|||
<script lang="ts">
|
||||
import { defineComponent, type PropType } from "vue";
|
||||
import formatter, { POWER_UNIT } from "@/mixins/formatter";
|
||||
import minuteTicker from "@/mixins/minuteTicker";
|
||||
import AnimatedNumber from "../Helper/AnimatedNumber.vue";
|
||||
import type { CURRENCY, Timeout } from "@/types/evcc";
|
||||
import type { CURRENCY } from "@/types/evcc";
|
||||
import { ForecastType, findLowestSumSlotIndex } from "@/utils/forecast";
|
||||
import type { ForecastSlot, SolarDetails } from "./types";
|
||||
const LOCALES_WITHOUT_DAY_AFTER_TOMORROW = ["en", "tr"];
|
||||
|
|
@ -90,7 +91,7 @@ export default defineComponent({
|
|||
components: {
|
||||
AnimatedNumber,
|
||||
},
|
||||
mixins: [formatter],
|
||||
mixins: [formatter, minuteTicker],
|
||||
props: {
|
||||
type: { type: String as () => ForecastType, required: true },
|
||||
grid: { type: Array as PropType<ForecastSlot[]> },
|
||||
|
|
@ -101,7 +102,6 @@ export default defineComponent({
|
|||
data() {
|
||||
return {
|
||||
now: new Date(),
|
||||
interval: null as Timeout,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -155,16 +155,13 @@ export default defineComponent({
|
|||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
everyMinute(): void {
|
||||
this.now = new Date();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.now = new Date();
|
||||
this.interval = setInterval(() => {
|
||||
this.now = new Date();
|
||||
}, 1000 * 60);
|
||||
},
|
||||
beforeUnmount() {
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
label(key: string) {
|
||||
|
|
|
|||
|
|
@ -55,8 +55,9 @@ import "@h2d2/shopicons/es/regular/angledoublerightsmall";
|
|||
import "@h2d2/shopicons/es/regular/clock";
|
||||
import { DEFAULT_LOCALE } from "@/i18n.ts";
|
||||
import formatter from "@/mixins/formatter";
|
||||
import minuteTicker from "@/mixins/minuteTicker";
|
||||
import { defineComponent, type PropType } from "vue";
|
||||
import { SMART_COST_TYPE, type CURRENCY, type Timeout } from "@/types/evcc";
|
||||
import { SMART_COST_TYPE, type CURRENCY } from "@/types/evcc";
|
||||
|
||||
import ClimaterIcon from "../MaterialIcon/Climater.vue";
|
||||
import DynamicPriceIcon from "../MaterialIcon/DynamicPrice.vue";
|
||||
|
|
@ -85,7 +86,7 @@ export default defineComponent({
|
|||
components: {
|
||||
StatusItem,
|
||||
},
|
||||
mixins: [formatter],
|
||||
mixins: [formatter, minuteTicker],
|
||||
props: {
|
||||
vehicleSoc: { type: Number, default: 0 },
|
||||
batteryBoostActive: Boolean,
|
||||
|
|
@ -126,11 +127,6 @@ export default defineComponent({
|
|||
vehicleLimitSoc: { type: Number, default: 0 },
|
||||
},
|
||||
emits: ["open-loadpoint-settings", "open-minsoc-settings", "open-plan-modal"],
|
||||
data() {
|
||||
return {
|
||||
interval: null as Timeout,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
pvTimerActive() {
|
||||
return (
|
||||
|
|
@ -217,6 +213,9 @@ export default defineComponent({
|
|||
const t = (key: string, params?: Record<string, unknown>) =>
|
||||
this.$t(`main.vehicleStatus.${key}`, params ?? {});
|
||||
|
||||
// ensure periodic recomputation even without data change
|
||||
void this.everyMinute;
|
||||
|
||||
const items = [
|
||||
{
|
||||
id: "pvTimer",
|
||||
|
|
@ -394,17 +393,6 @@ export default defineComponent({
|
|||
return items.filter((item) => item.visible);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.interval = setInterval(() => {
|
||||
// Force reactivity update for time-dependent content
|
||||
this.$forceUpdate();
|
||||
}, 1000 * 60);
|
||||
},
|
||||
beforeUnmount() {
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openLoadpointSettings() {
|
||||
this.$emit("open-loadpoint-settings");
|
||||
|
|
|
|||
22
assets/js/mixins/minuteTicker.ts
Normal file
22
assets/js/mixins/minuteTicker.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { defineComponent } from "vue";
|
||||
import type { Timeout } from "@/types/evcc";
|
||||
|
||||
export default defineComponent({
|
||||
data() {
|
||||
return {
|
||||
everyMinute: new Date(),
|
||||
minuteInterval: null as Timeout,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.minuteInterval = setInterval(() => {
|
||||
// force time-based computed data to update at least once a minute
|
||||
this.everyMinute = new Date();
|
||||
}, 1000 * 60);
|
||||
},
|
||||
beforeUnmount() {
|
||||
if (this.minuteInterval) {
|
||||
clearInterval(this.minuteInterval);
|
||||
}
|
||||
},
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue