evcc-io/assets/js/components/GlobalSettingsModal.vue
2023-03-01 11:27:48 +01:00

188 lines
4.9 KiB
Vue

<template>
<Teleport to="body">
<div
id="globalSettingsModal"
class="modal fade text-dark"
data-bs-backdrop="true"
tabindex="-1"
role="dialog"
aria-hidden="true"
>
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{{ $t("settings.title") }}</h5>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div class="modal-body">
<SponsorTokenExpires :sponsorTokenExpires="sponsorTokenExpires" />
<div class="container mx-0 px-0">
<FormRow id="settingsDesign" :label="$t('settings.theme.label')">
<SelectGroup
id="settingsDesign"
v-model="theme"
class="w-100"
:options="
THEMES.map((value) => ({
value,
name: $t(`settings.theme.${value}`),
}))
"
/>
</FormRow>
<FormRow id="settingsLanguage" :label="$t('settings.language.label')">
<select
id="settingsLanguage"
v-model="language"
class="form-select form-select-sm w-75"
>
<option value="">{{ $t("settings.language.auto") }}</option>
<option
v-for="option in languageOptions"
:key="option"
:value="option.value"
>
{{ option.name }}
</option>
</select>
</FormRow>
<FormRow id="settingsUnit" :label="$t('settings.unit.label')">
<SelectGroup
id="settingsUnit"
v-model="unit"
class="w-75"
:options="
UNITS.map((value) => ({
value,
name: $t(`settings.unit.${value}`),
}))
"
/>
</FormRow>
<FormRow
id="settingsGridDetails"
:label="$t('settings.gridDetails.label')"
>
<SelectGroup
id="settingsGridDetails"
v-model="gridDetails"
class="w-100"
:options="
GRID_DETAILS.map((value) => ({
value,
name: $t(`settings.gridDetails.${value}`),
disabled: isDisabled(value),
}))
"
/>
</FormRow>
<FormRow id="telemetryEnabled" :label="$t('settings.telemetry.label')">
<TelemetrySettings :sponsor="sponsor" class="mt-1 mb-0" />
</FormRow>
<FormRow
v-if="isNightly"
id="hiddenFeaturesEnabled"
:label="`${$t('settings.hiddenFeatures.label')} 🧪`"
>
<div class="form-check form-switch my-1">
<input
id="hiddenFeaturesEnabled"
v-model="hiddenFeatures"
class="form-check-input"
type="checkbox"
role="switch"
/>
<div class="form-check-label">
<label for="telemetryEnabled">
{{ $t("settings.hiddenFeatures.value") }}
</label>
</div>
</div>
</FormRow>
</div>
</div>
</div>
</div>
</div>
</Teleport>
</template>
<script>
import TelemetrySettings from "./TelemetrySettings.vue";
import SponsorTokenExpires from "./SponsorTokenExpires.vue";
import FormRow from "./FormRow.vue";
import SelectGroup from "./SelectGroup.vue";
import { getLocalePreference, setLocalePreference, LOCALES, removeLocalePreference } from "../i18n";
import { getThemePreference, setThemePreference, THEMES } from "../theme";
import { getUnits, setUnits, UNITS } from "../units";
import { getGridDetails, setGridDetails, GRID_DETAILS } from "../gridDetails";
import { getHiddenFeatures, setHiddenFeatures } from "../featureflags";
export default {
name: "GlobalSettingsModal",
components: { TelemetrySettings, FormRow, SelectGroup, SponsorTokenExpires },
props: {
sponsor: String,
hasPrice: Boolean,
hasCo2: Boolean,
sponsorTokenExpires: Number,
},
data: function () {
return {
theme: getThemePreference(),
language: getLocalePreference() || "",
unit: getUnits(),
gridDetails: getGridDetails(),
hiddenFeatures: getHiddenFeatures(),
THEMES,
UNITS,
GRID_DETAILS,
};
},
computed: {
languageOptions: () => {
const locales = Object.entries(LOCALES).map(([key, value]) => {
return { value: key, name: value[1] };
});
// sort by name
locales.sort((a, b) => (a.name < b.name ? -1 : 1));
return locales;
},
isNightly: () => {
return !!window?.evcc?.commit;
},
},
watch: {
unit(value) {
setUnits(value);
},
gridDetails(value) {
setGridDetails(value);
},
theme(value) {
setThemePreference(value);
},
hiddenFeatures(value) {
setHiddenFeatures(value);
},
language(value) {
const i18n = this.$root.$i18n;
if (value) {
setLocalePreference(i18n, value);
} else {
removeLocalePreference(i18n);
}
},
},
methods: {
isDisabled(option) {
return (option === "co2" && !this.hasCo2) || (option === "price" && !this.hasPrice);
},
},
};
</script>