Config UI: general settings wrap (#22276)

This commit is contained in:
Michael Geers 2025-07-10 19:43:43 +02:00 • committed by GitHub
parent d85f2610e0
commit 581592f03b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 124 additions and 139 deletions

View file

@ -1,114 +1,75 @@
<template>
<div class="group round-box p-4">
<div class="config-entry" data-testid="generalconfig-title">
<strong class="config-label">{{ $t("config.general.title") }}</strong>
<div class="config-text">{{ title || "---" }}</div>
<button
class="config-button btn btn-link"
type="button"
:title="$t('config.main.edit')"
tabindex="0"
@click.prevent="openModal('titleModal')"
>
<EditIcon size="xs" />
<TitleModal ref="titleModal" @changed="load" />
</button>
</div>
<div class="config-entry" data-testid="generalconfig-password">
<strong class="config-label">{{ $t("config.general.password") }}</strong>
<div class="config-text">*******</div>
<button
class="config-button btn btn-link"
type="button"
:title="$t('config.main.edit')"
tabindex="0"
@click.prevent="openModal('passwordModal')"
>
<EditIcon size="xs" />
</button>
</div>
<div class="config-entry" data-testid="generalconfig-telemetry">
<strong class="config-label">{{ $t("config.general.telemetry") }}</strong>
<div class="config-text">
{{ $t(`config.general.${telemetryEnabled ? "on" : "off"}`) }}
</div>
<button
class="config-button btn btn-link"
type="button"
:title="$t('config.main.edit')"
tabindex="0"
@click.prevent="openModal('globalSettingsModal')"
>
<EditIcon size="xs" />
</button>
</div>
<div class="config-entry" data-testid="generalconfig-experimental">
<strong class="config-label">{{ $t("config.general.experimental") }}</strong>
<div class="config-text">
{{ $t(`config.general.${hiddenFeatures ? "on" : "off"}`) }}
</div>
<button
class="config-button btn btn-link"
type="button"
:title="$t('config.main.edit')"
tabindex="0"
@click.prevent="openModal('globalSettingsModal')"
>
<EditIcon size="xs" />
</button>
</div>
<div v-if="$hiddenFeatures()" class="config-entry" data-testid="generalconfig-sponsoring">
<strong class="config-label">{{ $t("config.sponsor.title") }} 🧪</strong>
<div class="config-text" :class="sponsorStatus.cssClass">
<GeneralConfigEntry
test-id="generalconfig-title"
:label="$t('config.general.title')"
:text="title || '---'"
modal-id="titleModal"
>
</GeneralConfigEntry>
<GeneralConfigEntry
test-id="generalconfig-password"
:label="$t('config.general.password')"
text="*******"
modal-id="passwordModal"
/>
<GeneralConfigEntry
test-id="generalconfig-telemetry"
:label="$t('config.general.telemetry')"
:text="$t(`config.general.${telemetryEnabled ? 'on' : 'off'}`)"
modal-id="globalSettingsModal"
/>
<GeneralConfigEntry
test-id="generalconfig-experimental"
:label="$t('config.general.experimental')"
:text="$t(`config.general.${hiddenFeatures ? 'on' : 'off'}`)"
modal-id="globalSettingsModal"
/>
<GeneralConfigEntry
v-if="$hiddenFeatures()"
test-id="generalconfig-sponsoring"
:label="$t('config.sponsor.title')"
:text="sponsorStatus.name || '---'"
:text-class="sponsorStatus.cssClass"
modal-id="sponsorModal"
experimental
>
<template #text-prefix>
<span
v-if="sponsorStatus.expiresSoon && sponsorStatus.name"
class="d-inline-block me-1 p-1 rounded-circle bg-warning rounded-circle"
></span>
{{ sponsorStatus.name || "---" }}
</div>
<button
class="config-button btn btn-link"
type="button"
:title="$t('config.main.edit')"
tabindex="0"
@click.prevent="openModal('sponsorModal')"
>
<EditIcon size="xs" />
</button>
</div>
<div v-if="$hiddenFeatures()" class="config-entry" data-testid="generalconfig-network">
<strong class="config-label">{{ $t("config.network.title") }} 🧪</strong>
<div class="config-text">{{ networkStatus }}</div>
<button
class="config-button btn btn-link"
type="button"
:title="$t('config.main.edit')"
tabindex="0"
@click.prevent="openModal('networkModal')"
>
<EditIcon size="xs" />
</button>
</div>
<div v-if="$hiddenFeatures()" class="config-entry" data-testid="generalconfig-control">
<strong class="config-label">{{ $t("config.control.title") }} 🧪</strong>
<div class="config-text">{{ controlStatus }}</div>
<button
class="config-button btn btn-link"
type="button"
:title="$t('config.main.edit')"
tabindex="0"
@click.prevent="openModal('controlModal')"
>
<EditIcon size="xs" />
</button>
</div>
</template>
</GeneralConfigEntry>
<GeneralConfigEntry
v-if="$hiddenFeatures()"
test-id="generalconfig-network"
:label="$t('config.network.title')"
:text="networkStatus"
modal-id="networkModal"
experimental
/>
<GeneralConfigEntry
v-if="$hiddenFeatures()"
test-id="generalconfig-control"
:label="$t('config.control.title')"
:text="controlStatus"
modal-id="controlModal"
experimental
/>
<TitleModal ref="titleModal" @changed="load" />
</div>
</template>
<script>
import Modal from "bootstrap/js/dist/modal";
import TitleModal from "./TitleModal.vue";
import EditIcon from "../MaterialIcon/Edit.vue";
import GeneralConfigEntry from "./GeneralConfigEntry.vue";
import api from "@/api";
import settings from "@/settings";
import store from "@/store";
@ -116,7 +77,7 @@ import formatter from "@/mixins/formatter";
export default {
name: "GeneralConfig",
components: { TitleModal, EditIcon },
components: { TitleModal, GeneralConfigEntry },
mixins: [formatter],
emits: ["site-changed"],
data() {
@ -172,17 +133,6 @@ export default {
console.error(e);
}
},
todo() {
alert("not implemented");
},
openModal(id) {
const $el = document.getElementById(id);
if ($el) {
Modal.getOrCreateInstance($el).show();
} else {
console.error(`modal ${id} not found`);
}
},
},
};
</script>
@ -198,31 +148,4 @@ export default {
.wip {
opacity: 0.2;
}
.config-entry {
display: flex;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
gap: 0.5rem;
}
.config-label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex-shrink: 1;
flex-grow: 0;
}
.config-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex-shrink: 1;
flex-grow: 1;
text-align: right;
}
.config-button {
margin-right: -1rem;
flex-shrink: 0;
color: var(--evcc-text-default);
}
</style>

View file

@ -0,0 +1,62 @@
<template>
<div
class="d-flex justify-content-between flex-wrap align-items-center gap-2"
:data-testid="testId"
>
<strong class="text-truncate d-flex align-items-center"
>{{ label }}{{ experimental ? " 🧪" : "" }}</strong
>
<div class="d-flex align-items-center text-truncate">
<div
class="text-truncate align-items-center flex-grow-1 flex-shrink-1 text-end"
:class="textClass"
>
<slot name="text-prefix"></slot>
{{ text }}
</div>
<button
class="btn btn-link flex-shrink-0"
style="margin-right: -1rem; color: var(--evcc-text-default)"
type="button"
:title="$t('config.main.edit')"
tabindex="0"
@click.prevent="handleEditClick"
>
<EditIcon size="xs" />
</button>
</div>
</div>
</template>
<script>
import Modal from "bootstrap/js/dist/modal";
import EditIcon from "../MaterialIcon/Edit.vue";
export default {
name: "GeneralConfigEntry",
components: { EditIcon },
props: {
testId: { type: String, required: true },
label: { type: String, required: true },
text: { type: String, default: "---" },
textClass: { type: String, default: "" },
modalId: { type: String, required: true },
experimental: { type: Boolean, default: false },
},
emits: ["edit-clicked"],
methods: {
handleEditClick() {
this.$emit("edit-clicked");
this.openModal();
},
openModal() {
const $el = document.getElementById(this.modalId);
if ($el) {
Modal.getOrCreateInstance($el).show();
} else {
console.error(`modal ${this.modalId} not found`);
}
},
},
};
</script>