From 2b8f69080db9546e0b1ef9714807024a81333cde Mon Sep 17 00:00:00 2001 From: Michael Geers Date: Wed, 4 Sep 2024 10:00:34 +0200 Subject: [PATCH 01/19] refactor: extract table --- assets/js/components/ChargingSessionTable.vue | 482 ++++++++++++++++++ assets/js/views/ChargingSessions.vue | 476 +---------------- 2 files changed, 492 insertions(+), 466 deletions(-) create mode 100644 assets/js/components/ChargingSessionTable.vue diff --git a/assets/js/components/ChargingSessionTable.vue b/assets/js/components/ChargingSessionTable.vue new file mode 100644 index 0000000000..3cb4d315b5 --- /dev/null +++ b/assets/js/components/ChargingSessionTable.vue @@ -0,0 +1,482 @@ + + + + diff --git a/assets/js/views/ChargingSessions.vue b/assets/js/views/ChargingSessions.vue index c842193755..a7f2ad28c1 100644 --- a/assets/js/views/ChargingSessions.vue +++ b/assets/js/views/ChargingSessions.vue @@ -32,171 +32,13 @@ > -
-

{{ $t("sessions.noData") }}

-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- {{ $t("sessions.date") }} - - {{ $t("sessions.loadpoint") }} - - - {{ loadpointFilter || $t("sessions.filter.filter") }} - - - - {{ $t("sessions.vehicle") }} - - - {{ vehicleFilter || $t("sessions.filter.filter") }} - - - -
-
- {{ $t("sessions.loadpoint") }} -
- - - {{ - loadpointFilter || $t("sessions.filter.filter") - }} - - -
-
-
- {{ $t("sessions.vehicle") }} -
- - - {{ vehicleFilter || $t("sessions.filter.filter") }} - - -
-
- - - {{ $t(`sessions.${column.name}`) }} - - - - {{ $t(`sessions.${column.name}`) }} - -
{{ column.unit }}
-
- {{ $t("sessions.total") }} - - {{ column.format(column.total) }} -
- {{ fmtFullDateTime(new Date(session.created), true) }} - - {{ session.loadpoint }} - - {{ session.vehicle }} - -
{{ session.loadpoint }}
-
{{ session.vehicle }}
-
- - - - - {{ column.format(column.value(session)) }} -
-
+
new Date().getMonth() + 1 }, @@ -263,7 +95,6 @@ export default { return { sessions: [], selectedSessionId: undefined, - selectedColumns: settings.sessionColumns, }; }, head() { @@ -286,206 +117,6 @@ export default { return date.getFullYear() === this.year && date.getMonth() + 1 === this.month; }); }, - filteredSessions() { - return this.currentSessions.filter(this.filterByLoadpoint).filter(this.filterByVehicle); - }, - maxColumns() { - return COLUMNS_PER_BREAKPOINT[this.breakpoint] || 1; - }, - columns() { - const columns = [ - { - name: "energy", - unit: "kWh", - total: this.chargedEnergy, - value: (session) => session.chargedEnergy, - format: (value) => this.fmtKWh(value * 1e3, true, false), - }, - { - name: "solar", - unit: "%", - total: this.solarPercentage, - value: (session) => session.solarPercentage, - format: (value) => this.fmtNumber(value, 1), - }, - { - name: "price", - unit: this.fmtCurrencySymbol(this.currency), - total: this.price, - value: (session) => session.price, - format: (value) => this.fmtMoney(value, this.currency), - }, - { - name: "avgPrice", - unit: this.pricePerKWhUnit(this.currency), - total: this.pricePerKWh, - value: (session) => session.pricePerKWh, - format: (value) => this.fmtPricePerKWh(value, this.currency, false, false), - }, - { - name: "co2", - unit: "g/kWh", - total: this.co2PerKWh, - value: (session) => session.co2PerKWh, - format: (value) => this.fmtNumber(value, 0), - }, - { - name: "chargeDuration", - unit: "h:mm", - total: this.chargeDuration, - value: (session) => session.chargeDuration, - format: (value) => this.fmtDurationNs(value, false, "h"), - }, - { - name: "avgPower", - unit: "kW", - total: this.avgPower, - value: (session) => { - if (session.chargedEnergy && session.chargeDuration) { - return session.chargedEnergy / this.nsToHours(session.chargeDuration); - } - return null; - }, - format: (value) => - value ? this.fmtKw(value * 1e3, true, false, 1) : undefined, - }, - ]; - // only columns with values are shown - return columns.filter((column) => { - if (column.name === "energy") return true; - return this.currentSessions.some((s) => column.value(s)); - }); - }, - tooMuchColumns() { - return this.columns.length > this.maxColumns; - }, - sortedColumns() { - const columns = [...this.columns]; - let sorted = []; - for (let name of this.selectedColumns) { - if (!name && columns.length) { - sorted.push(columns.shift()); - } else if (columns.some((c) => c.name === name)) { - const column = columns.find((c) => c.name === name); - sorted.push(column); - let index = columns.indexOf(column); - columns.splice(index, 1); - } - } - return sorted.concat(columns); - }, - columnsPerBreakpoint() { - return this.sortedColumns.slice(0, this.maxColumns); - }, - columnOptions() { - return this.columns.map((column) => { - return { - name: this.$t(`sessions.${column.name}`), - value: column.name, - disabled: this.columnsPerBreakpoint.find((c) => c.name === column.name), - }; - }); - }, - vehicleFilterOptions() { - const options = [ - { - name: this.$t("sessions.filter.allVehicles"), - value: "", - count: this.filterCountForVehicle(), - }, - ]; - this.vehicles.forEach((name) => { - const count = this.filterCountForVehicle(name); - options.push({ name, value: name, count }); - }); - return options; - }, - loadpointFilterOptions() { - const options = [ - { - name: this.$t("sessions.filter.allLoadpoints"), - value: "", - count: this.filterCountForLoadpoint(), - }, - ]; - this.loadpoints.forEach((name) => { - const count = this.filterCountForLoadpoint(name); - options.push({ name, value: name, count }); - }); - return options; - }, - chargedEnergy() { - return this.filteredSessions.reduce((total, s) => total + s.chargedEnergy, 0); - }, - chargeDuration() { - return this.filteredSessions.reduce((total, s) => total + s.chargeDuration, 0); - }, - price() { - return this.filteredSessions.reduce((total, s) => total + s.price, 0); - }, - avgPower() { - const { energy, hours } = this.filteredSessions - .filter((s) => s.chargedEnergy && s.chargeDuration) - .reduce( - (total, s) => { - total.energy += s.chargedEnergy; - total.hours += this.nsToHours(s.chargeDuration); - return total; - }, - { energy: 0, hours: 0 } - ); - if (energy && hours) { - return energy / hours; - } - return null; - }, - pricePerKWh() { - const total = this.filteredSessions - .filter((s) => s.price !== null) - .reduce( - (total, s) => ({ - price: total.price + s.price, - chargedEnergy: total.chargedEnergy + s.chargedEnergy, - }), - { price: 0, chargedEnergy: 0 } - ); - return total.price / total.chargedEnergy; - }, - co2PerKWh() { - const total = this.filteredSessions - .filter((s) => s.co2PerKWh !== null) - .reduce( - (total, s) => ({ - emittedCo2: total.emittedCo2 + s.chargedEnergy * s.co2PerKWh, - chargedEnergy: total.chargedEnergy + s.chargedEnergy, - }), - { emittedCo2: 0, chargedEnergy: 0 } - ); - if (total.chargedEnergy && total.emittedCo2) { - return total.emittedCo2 / total.chargedEnergy; - } - return null; - }, - solarPercentage() { - const total = this.filteredSessions - .filter((s) => s.solarPercentage !== null) - .reduce( - (total, s) => ({ - chargedSolarEnergy: - total.chargedSolarEnergy + s.chargedEnergy * (s.solarPercentage / 100), - chargedEnergy: total.chargedEnergy + s.chargedEnergy, - }), - { chargedSolarEnergy: 0, chargedEnergy: 0 } - ); - - return (100 / total.chargedEnergy) * total.chargedSolarEnergy; - }, - loadpoints() { - return [...new Set(this.currentSessions.map((s) => s.loadpoint))]; - }, - vehicles() { - return [...new Set(this.currentSessions.map((s) => s.vehicle))]; - }, vehicleList() { const vehicles = store.state.vehicles || {}; return Object.entries(vehicles).map(([name, vehicle]) => ({ name, ...vehicle })); @@ -555,37 +186,6 @@ export default { this.loadSessions(); }, methods: { - nsToHours(ns) { - return ns / 1e9 / 3600; - }, - filterByLoadpoint(session) { - return !this.loadpointFilter || session.loadpoint === this.loadpointFilter; - }, - filterByVehicle(session) { - return !this.vehicleFilter || session.vehicle === this.vehicleFilter; - }, - filterCountForVehicle(vehicle) { - return this.currentSessions - .filter(this.filterByLoadpoint) - .filter((s) => !vehicle || s.vehicle === vehicle).length; - }, - filterCountForLoadpoint(loadpoint) { - return this.currentSessions - .filter(this.filterByVehicle) - .filter((s) => !loadpoint || s.loadpoint === loadpoint).length; - }, - selectColumnPosition(index, value) { - this.selectedColumns[index] = value; - settings.sessionColumns = [...this.selectedColumns]; - }, - changeLoadpointFilter(event) { - const loadpoint = event.target.value || undefined; - this.$router.push({ query: { ...this.$route.query, loadpoint } }); - }, - changeVehicleFilter(event) { - const vehicle = event.target.value || undefined; - this.$router.push({ query: { ...this.$route.query, vehicle } }); - }, async loadSessions() { const response = await api.get("sessions"); this.sessions = response.data?.result; @@ -609,59 +209,3 @@ export default { }, }; - From 525cbd5e4e471ebf294462637011dd4202e03d70 Mon Sep 17 00:00:00 2001 From: Michael Geers Date: Wed, 4 Sep 2024 20:07:12 +0200 Subject: [PATCH 02/19] chart.js --- .eslintrc.cjs | 1 + assets/js/components/Sessions/Chart.vue | 88 +++++++++++++++++++ .../SessionDetailsModal.vue} | 15 ++-- .../SessionTable.vue} | 11 +-- assets/js/router.js | 2 +- assets/js/types/shopicons.d.ts | 2 + .../{ChargingSessions.vue => Sessions.vue} | 15 ++-- package-lock.json | 30 +++++++ package.json | 2 + 9 files changed, 145 insertions(+), 21 deletions(-) create mode 100644 assets/js/components/Sessions/Chart.vue rename assets/js/components/{ChargingSessionModal.vue => Sessions/SessionDetailsModal.vue} (95%) rename assets/js/components/{ChargingSessionTable.vue => Sessions/SessionTable.vue} (98%) create mode 100644 assets/js/types/shopicons.d.ts rename assets/js/views/{ChargingSessions.vue => Sessions.vue} (94%) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index c61e314578..d2b3f29d30 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -18,5 +18,6 @@ module.exports = { "vue/attribute-hyphenation": "off", "vue/multi-word-component-names": "off", "vue/no-reserved-component-names": "off", + "vue/no-undef-properties": "warn", }, }; diff --git a/assets/js/components/Sessions/Chart.vue b/assets/js/components/Sessions/Chart.vue new file mode 100644 index 0000000000..0a96c4c25c --- /dev/null +++ b/assets/js/components/Sessions/Chart.vue @@ -0,0 +1,88 @@ + + + diff --git a/assets/js/components/ChargingSessionModal.vue b/assets/js/components/Sessions/SessionDetailsModal.vue similarity index 95% rename from assets/js/components/ChargingSessionModal.vue rename to assets/js/components/Sessions/SessionDetailsModal.vue index a712cb765f..c5c21b37fb 100644 --- a/assets/js/components/ChargingSessionModal.vue +++ b/assets/js/components/Sessions/SessionDetailsModal.vue @@ -122,10 +122,10 @@
-