evcc-io/assets/js/components/Config/DeviceModal/Actions.vue
andig 4465100a65
Config UI: allow disabling devices (#29455)
Co-authored-by: Michael Geers <michael@geers.tv>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: andig <184815+andig@users.noreply.github.com>
2026-08-11 13:24:40 +00:00

114 lines
3.1 KiB
Vue

<template>
<div>
<slot name="before-test"></slot>
<TestResult
v-if="testState"
v-bind="testState"
:sponsor-token-required="sponsorTokenRequired"
:currency="currency"
@test="$emit('test')"
/>
<slot name="after-test"></slot>
<div class="mt-4 d-flex flex-wrap justify-content-between align-items-center gap-2">
<div class="d-flex flex-wrap align-items-center gap-1">
<button
v-if="isDeletable"
type="button"
class="btn btn-link text-danger"
tabindex="0"
@click.prevent="$emit('remove')"
>
{{ $t("config.general.delete") }}
</button>
<button
v-else
type="button"
class="btn btn-link text-muted"
data-bs-dismiss="modal"
tabindex="0"
>
{{ $t("config.general.cancel") }}
</button>
<button
v-if="isDeletable && canDisable"
type="button"
class="btn btn-link text-muted"
tabindex="0"
@click.prevent="$emit('disable', !isDisabled)"
>
{{ isDisabled ? $t("config.general.enable") : $t("config.general.disable") }}
</button>
</div>
<button
type="submit"
:class="buttonClass"
:disabled="testState.isRunning || isSaving || isSucceeded || sponsorTokenRequired"
tabindex="0"
@click.prevent="handleSave"
>
<span
v-if="isSaving"
class="spinner-border spinner-border-sm me-2"
role="status"
aria-hidden="true"
></span>
<template v-if="isSucceeded">{{ $t("config.general.saved") }}</template>
<template v-else>{{ saveButtonLabel }}</template>
</button>
</div>
</div>
</template>
<script lang="ts">
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",
components: {
TestResult,
},
props: {
isDeletable: Boolean as PropType<boolean>,
isDisabled: Boolean as PropType<boolean>,
canDisable: { type: Boolean as PropType<boolean>, default: true },
testState: {
type: Object as PropType<TestState>,
default: () => {},
},
isSaving: Boolean as PropType<boolean>,
isSucceeded: Boolean as PropType<boolean>,
isNew: Boolean as PropType<boolean>,
sponsorTokenRequired: Boolean as PropType<boolean>,
currency: String as PropType<CURRENCY>,
},
emits: ["save", "remove", "test", "disable"],
computed: {
saveButtonLabel(): string {
const { isError, isUnknown, isRunning } = this.testState;
if (isRunning) return this.$t("config.validation.running");
if (this.isSaving) return this.$t("config.general.saving");
if (isError) return this.$t("config.general.forceSave");
if (isUnknown) return this.$t("config.general.validateSave");
return this.$t("config.general.save");
},
buttonClass(): string {
if (this.isSucceeded) return "btn btn-succeeded";
if (this.testState.isError) return "btn btn-danger";
return "btn btn-primary";
},
},
methods: {
handleSave(): void {
const force = this.testState.isError;
this.$emit("save", force);
},
},
});
</script>