diff --git a/AGENTS.md b/AGENTS.md index 6a43b6572..2347c1edc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -173,6 +173,7 @@ Deep documentation on specific subsystems is available in `docs/agents/`. Load w - Implement accessibility features (tabindex, aria-label, keyboard handlers) - Use descriptive names for variables, functions, and event handlers - Use early returns for readability +- Prefer named computed properties over inline template expressions, even for single use. Readability beats saving lines - Use configured Axios instance for HTTP communication ### State Management diff --git a/api/api.go b/api/api.go index b764073bc..0e726d747 100644 --- a/api/api.go +++ b/api/api.go @@ -1,8 +1,6 @@ package api import ( - "context" - "io" "net/url" "time" @@ -254,11 +252,6 @@ type TitleDescriber interface { GetTitle() string } -// CsvWriter converts to csv -type CsvWriter interface { - WriteCsv(context.Context, io.Writer) error -} - // CircuitMeasurements is the measurements a circuit or load must deliver type CircuitMeasurements interface { GetChargePower() float64 diff --git a/assets/js/components/Config/HemsModal.vue b/assets/js/components/Config/HemsModal.vue index 11a1e0252..18e1a6e42 100644 --- a/assets/js/components/Config/HemsModal.vue +++ b/assets/js/components/Config/HemsModal.vue @@ -38,28 +38,23 @@ {{ $t("config.general.docsLink") }}

- @@ -117,7 +109,7 @@ import { PERIODS } from "../components/Sessions/types"; import { GROUP_ORDER, groupColor, hasColorPicker } from "../components/History/groups"; import colors, { resolveColors, deviceColorMap, darken, batteryColor } from "../colors"; import LegendList from "../components/Sessions/LegendList.vue"; -import { handleDownloadClick } from "@/utils/native"; +import DownloadButton from "../components/Helper/DownloadButton.vue"; import formatter, { POWER_UNIT } from "../mixins/formatter"; import api from "../api"; import store from "../store"; @@ -138,6 +130,7 @@ export default defineComponent({ PeriodHeader, GroupChart, LegendList, + DownloadButton, }, mixins: [formatter], props: { @@ -316,16 +309,6 @@ export default defineComponent({ } return this.fmtWh(Math.abs(sum) * 1000, POWER_UNIT.AUTO); }, - csvLink(): string { - const params = new URLSearchParams({ - format: "csv", - lang: this.$i18n?.locale, - from: this.from.toISOString(), - to: this.to.toISOString(), - aggregate: this.aggregate, - }); - return `./api/history/energy?${params.toString()}`; - }, }, watch: { fetchKey() { @@ -359,7 +342,15 @@ export default defineComponent({ }, methods: { groupColor, - handleDownloadClick, + downloadHref(): string { + const params = new URLSearchParams({ + lang: this.$i18n?.locale, + from: this.from.toISOString(), + to: this.to.toISOString(), + aggregate: this.aggregate, + }); + return `./api/history/energy?${params.toString()}`; + }, legendsForGroup(group: string): Legend[] { const items = this.entityLegends(group); const focused = this.focusedEntity[group] ?? null; @@ -571,14 +562,6 @@ export default defineComponent({ opacity: 0.8; } } -.history-csv-link { - text-decoration: none; -} -.history-csv-link:hover, -.history-csv-link:focus { - color: var(--evcc-default-text); - text-decoration: underline; -} @media (max-width: 575.98px) { /* edge-to-edge on mobile: cancel the container's px-4 padding */ .history-tile { diff --git a/assets/js/views/Sessions.vue b/assets/js/views/Sessions.vue index 8f03afb01..94ca7c7c4 100644 --- a/assets/js/views/Sessions.vue +++ b/assets/js/views/Sessions.vue @@ -157,17 +157,8 @@ @show-session="showDetails" /> -
- - {{ csvLinkLabel }} - +
+