Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions assets/js/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const api = axios.create({
baseURL: base + "api/",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
paramsSerializer: customParamsSerializer,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ export default defineComponent({
return this.dataChanged && this.selectedActive;
},
weekdaysLabel(): string {
return this.getShortenedWeekdaysLabel(this.selectedWeekdays);
return this.fmtWeekdaysRange(this.selectedWeekdays);
},
socOptions(): SelectOption<number>[] {
// a list of entries from 5 to 100 with a step of 5
Expand Down
120 changes: 120 additions & 0 deletions assets/js/components/Config/CurrencyModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<template>
<GenericModal
id="currencyModal"
ref="modal"
:title="$t('config.currency.title')"
data-testid="currency-modal"
@open="open"
>
<p>{{ $t("config.currency.description") }}</p>
<p v-if="error" class="text-danger">{{ error }}</p>
<form ref="form" class="container mx-0 px-0" @submit.prevent="save">
<FormRow id="currency" :label="$t('config.currency.label')" :example="exampleText">
<select id="currency" v-model="selectedCurrency" class="form-select" required>
<option
v-for="currency in currencies"
:key="currency.code"
:value="currency.code"
>
{{ currency.code }} - {{ currency.name }}
</option>
</select>
</FormRow>

<div class="mt-4 d-flex justify-content-between gap-2 flex-column flex-sm-row">
<button
type="button"
class="btn btn-link text-muted btn-cancel"
data-bs-dismiss="modal"
>
{{ $t("config.general.cancel") }}
</button>

<button
type="submit"
class="btn btn-primary order-1 order-sm-2 flex-grow-1 flex-sm-grow-0 px-4"
:disabled="saving || !changed"
>
<span
v-if="saving"
class="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"
></span>
{{ $t("config.general.save") }}
</button>
</div>
</form>
</GenericModal>
</template>

<script>
import GenericModal from "../Helper/GenericModal.vue";
import FormRow from "./FormRow.vue";
import store from "@/store";
import api from "@/api";
import { CURRENCY } from "@/types/evcc";
import formatter from "@/mixins/formatter";

export default {
name: "CurrencyModal",
components: { FormRow, GenericModal },
mixins: [formatter],
emits: ["changed"],
data() {
return {
saving: false,
error: "",
selectedCurrency: "EUR",
initialCurrency: "EUR",
};
},
computed: {
currencies() {
return Object.values(CURRENCY).map((code) => ({
code,
name: this.fmtCurrencyName(code),
}));
},
changed() {
return this.selectedCurrency !== this.initialCurrency;
},
exampleText() {
const price = this.fmtPricePerKWh(0.122, this.selectedCurrency);
const amount = this.fmtMoney(20.2, this.selectedCurrency, true, true);
return this.$t("config.currency.example", { price, amount });
},
},
methods: {
reset() {
const currency = store?.state?.currency || "EUR";
this.saving = false;
this.error = "";
this.selectedCurrency = currency;
this.initialCurrency = currency;
},
async open() {
this.reset();
},
async save() {
this.saving = true;
this.error = "";
try {
await api.put("/config/currency", JSON.stringify(this.selectedCurrency));
this.$emit("changed");
this.$refs.modal.close();
} catch (e) {
this.error = e.message;
}
this.saving = false;
},
},
};
</script>
<style scoped>
.container {
margin-left: calc(var(--bs-gutter-x) * -0.5);
margin-right: calc(var(--bs-gutter-x) * -0.5);
padding-right: 0;
}
</style>
3 changes: 3 additions & 0 deletions assets/js/components/Config/DeviceModal/Actions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
v-if="testState"
v-bind="testState"
:sponsor-token-required="sponsorTokenRequired"
:currency="currency"
@test="$emit('test')"
/>

Expand Down Expand Up @@ -51,6 +52,7 @@ import { defineComponent } from "vue";
import type { PropType } from "vue";
import TestResult from "../TestResult.vue";
import { type TestState } from "../utils/test";
import type { CURRENCY } from "@/types/evcc";

export default defineComponent({
name: "DeviceModalActions",
Expand All @@ -67,6 +69,7 @@ export default defineComponent({
isSucceeded: Boolean as PropType<boolean>,
isNew: Boolean as PropType<boolean>,
sponsorTokenRequired: Boolean as PropType<boolean>,
currency: String as PropType<CURRENCY>,
},
emits: ["save", "remove", "test"],
computed: {
Expand Down
9 changes: 6 additions & 3 deletions assets/js/components/Config/DeviceModal/DeviceModalBase.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
v-bind="param"
v-model="values[param.Name]"
:service-values="serviceValues[param.Name]"
:currency="currency"
/>

<div v-if="auth.code">
Expand Down Expand Up @@ -126,6 +127,7 @@
v-bind="param"
v-model="values[param.Name]"
:service-values="serviceValues[param.Name]"
:currency="currency"
/>

<PropertyCollapsible>
Expand All @@ -137,6 +139,7 @@
v-bind="param"
v-model="values[param.Name]"
:service-values="serviceValues[param.Name]"
:currency="currency"
/>
</template>
<template v-if="$slots['collapsible-more']" #more>
Expand All @@ -155,6 +158,7 @@
:is-succeeded="succeeded"
:is-new="isNew"
:sponsor-token-required="sponsorTokenRequired"
:currency="currency"
@save="handleSave"
@remove="handleRemove"
@test="testManually"
Expand Down Expand Up @@ -182,6 +186,7 @@ import { initialAuthState, prepareAuthLogin } from "../utils/authProvider";
import sleep from "@/utils/sleep";
import { ConfigType } from "@/types/evcc";
import type { DeviceType, Timeout } from "@/types/evcc";
import { CURRENCY } from "@/types/evcc";
import {
handleError,
type DeviceValues,
Expand Down Expand Up @@ -228,6 +233,7 @@ export default defineComponent({
showMainContent: { type: Boolean, default: true },
// Optional: usage parameter for loadProducts (e.g., meter type: "pv", "battery", "aux", "ext")
usage: String,
currency: { type: String as PropType<CURRENCY>, default: CURRENCY.EUR },
// Optional: custom product name computation
getProductName: Function as PropType<
(values: DeviceValues, templateName: string | null) => string
Expand Down Expand Up @@ -494,7 +500,6 @@ export default defineComponent({
},
values: {
handler() {
this.test = initialTestState();
this.updateServiceValues();
},
deep: true,
Expand Down Expand Up @@ -665,7 +670,6 @@ export default defineComponent({
return this.device.test(this.id, this.apiData);
},
async update(force = false) {
console.log("update called", { force, isUnknown: this.test.isUnknown, id: this.id });
if (this.test.isUnknown && !force) {
const success = await performTest(
this.test,
Expand All @@ -679,7 +683,6 @@ export default defineComponent({
}
this.saving = true;
try {
console.log("calling device.update", this.apiData);
await this.device.update(this.id!, this.apiData, force);
console.log("update succeeded, closing modal");
this.saving = false;
Expand Down
Loading
Loading