diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 6cc3863c6a..21f956f89b 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -18,6 +18,7 @@ module.exports = { "vue/attribute-hyphenation": "off", "vue/multi-word-component-names": "off", "vue/no-reserved-component-names": "off", + "vue/no-undef-properties": "warn", "no-param-reassign": "error", }, }; diff --git a/assets/css/app.css b/assets/css/app.css index b0ee0b5719..b332d05c09 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -23,9 +23,9 @@ :root { --evcc-green: #baffcb; - --evcc-dark-green: #0fde41; - --evcc-darker-green: #0ba631; - --evcc-darkest-green: #076f20; + --evcc-dark-green: #0fde41ff; + --evcc-darker-green: #0ba631ff; + --evcc-darkest-green: #076f20ff; --evcc-darkest-green-rgb: 11, 166, 49; --evcc-yellow: #faf000; --evcc-dark-yellow: #bbb400; @@ -90,7 +90,7 @@ --evcc-grid: var(--bs-gray-medium); --evcc-background: var(--bs-gray-deep); --evcc-box: var(--bs-gray-dark); - --evcc-box-border: var(--vs-gray-darker); + --evcc-box-border: var(--bs-gray-darker); --evcc-default-text: var(--bs-white); --evcc-gray: var(--bs-gray-light); --evcc-accent1: var(--evcc-yellow); @@ -195,6 +195,10 @@ a:hover { color: inherit; } +.evcc-background { + background-color: var(--evcc-background); +} + .btn-primary, .btn-primary:focus { background-color: var(--bs-primary); diff --git a/assets/js/colors.js b/assets/js/colors.js new file mode 100644 index 0000000000..10bef91930 --- /dev/null +++ b/assets/js/colors.js @@ -0,0 +1,68 @@ +import { reactive } from "vue"; + +// alternatives +// const COLORS = [ "#40916C", "#52B788", "#74C69D", "#95D5B2", "#B7E4C7", "#D8F3DC", "#081C15", "#1B4332", "#2D6A4F"]; +// const COLORS = ["#577590", "#43AA8B", "#90BE6D", "#F9C74F", "#F8961E", "#F3722C", "#F94144"]; +// const COLORS = ["#0077b6", "#00b4d8", "#90e0ef", "#caf0f8", "#03045e"]; +// const COLORS = [ "#0077B6FF", "#0096C7FF", "#00B4D8FF", "#48CAE4FF", "#90E0EFFF", "#ADE8F4FF", "#CAF0F8FF", "#03045EFF", "#023E8AFF", +// const COLORS = [ "#0077B6FF", "#00B4D8FF", "#90E0EFFF", "#40A578FF", "#9DDE8BFF", "#F8961EFF", "#F9C74FFF", "#E6FF94FF"]; + +const colors = reactive({ + text: null, + muted: null, + border: null, + self: null, + grid: null, + pricePerKWh: "#FFB900FF", + price: "#FF912FFF", + co2PerKWh: "#00C997FF", + co2: "#00916EFF", + background: null, + selfPalette: ["#0fde41ff", "#0ba631ff", "#076f20ff", "#054e18ff", "#043611ff", "#02230bff"], + palette: [ + "#03C1EFFF", + "#FD6158FF", + "#31AB4AFF", + "#0AAFBFFF", + "#FF922EFF", + "#0F662DFF", + "#0470D4FF", + "#FFBD2FFF", + "#77C93EFF", + "#41517AFF", + "#4E1D10FF", + "#813504FF", + ], +}); + +function updateCssColors() { + const style = window.getComputedStyle(document.documentElement); + colors.text = style.getPropertyValue("--evcc-default-text"); + colors.muted = style.getPropertyValue("--bs-gray-medium"); + colors.border = style.getPropertyValue("--bs-border-color-translucent"); + colors.self = style.getPropertyValue("--evcc-self"); + colors.grid = style.getPropertyValue("--evcc-grid"); + colors.background = style.getPropertyValue("--evcc-background"); +} + +// update colors on theme change +window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", updateCssColors); +updateCssColors(); + +export const dimColor = (color) => { + return color.toLowerCase().replace(/ff$/, "20"); +}; + +export const lightenColor = (color, level = 0) => { + if (level === 0) return color.toLowerCase(); + const alpha = Math.round(255 * Math.pow(0.6, level)) + .toString(16) + .padStart(2, "0"); + return color.toLowerCase().replace(/ff$/, alpha); +}; + +export const fullColor = (color) => { + return color.toLowerCase().replace(/20$/, "ff"); +}; + +export default colors; diff --git a/assets/js/components/Config/PropertyField.vue b/assets/js/components/Config/PropertyField.vue index 66c0d3858d..35148c1ccf 100644 --- a/assets/js/components/Config/PropertyField.vue +++ b/assets/js/components/Config/PropertyField.vue @@ -48,6 +48,7 @@ :id="id" class="w-50" v-model="value" + equal-width :options="[ { value: false, name: $t('config.options.boolean.no') }, { value: true, name: $t('config.options.boolean.yes') }, diff --git a/assets/js/components/Config/UserInterfaceSettings.vue b/assets/js/components/Config/UserInterfaceSettings.vue index 815021a3b6..74bec4f1dc 100644 --- a/assets/js/components/Config/UserInterfaceSettings.vue +++ b/assets/js/components/Config/UserInterfaceSettings.vue @@ -11,6 +11,7 @@ name: $t(`settings.theme.${value}`), })) " + equal-width /> @@ -36,6 +37,7 @@ name: $t(`settings.unit.${value}`), })) " + equal-width /> diff --git a/assets/js/components/Config/VehicleModal.vue b/assets/js/components/Config/VehicleModal.vue index 342916d3d9..b9e670ed3c 100644 --- a/assets/js/components/Config/VehicleModal.vue +++ b/assets/js/components/Config/VehicleModal.vue @@ -120,6 +120,7 @@ { name: '2-phases', value: '2' }, { name: '3-phases', value: undefined }, ]" + equal-width />
diff --git a/assets/js/components/IconSelectGroup.vue b/assets/js/components/IconSelectGroup.vue new file mode 100644 index 0000000000..46b51b7560 --- /dev/null +++ b/assets/js/components/IconSelectGroup.vue @@ -0,0 +1,18 @@ + + + + + diff --git a/assets/js/components/IconSelectItem.vue b/assets/js/components/IconSelectItem.vue new file mode 100644 index 0000000000..04ddb770ff --- /dev/null +++ b/assets/js/components/IconSelectItem.vue @@ -0,0 +1,39 @@ + + + + + diff --git a/assets/js/components/MaterialIcon/Total.vue b/assets/js/components/MaterialIcon/Total.vue new file mode 100644 index 0000000000..a3d30ef82d --- /dev/null +++ b/assets/js/components/MaterialIcon/Total.vue @@ -0,0 +1,17 @@ + + + diff --git a/assets/js/components/SelectGroup.vue b/assets/js/components/SelectGroup.vue index 7c07fcdb1e..7a76bea4de 100644 --- a/assets/js/components/SelectGroup.vue +++ b/assets/js/components/SelectGroup.vue @@ -6,7 +6,7 @@ :key="option.value" type="button" class="btn btn-sm flex-grow-1 flex-shrink-1" - :class="{ active: option.value === modelValue }" + :class="{ active: option.value === modelValue, 'btn--equal': equalWidth }" :disabled="option.disabled" @click="$emit('update:modelValue', option.value)" > @@ -22,6 +22,7 @@ export default { id: String, options: Array, modelValue: [Number, String], + equalWidth: Boolean, }, emits: ["update:modelValue"], }; @@ -32,11 +33,10 @@ export default { border: 2px solid var(--evcc-default-text); border-radius: 17px; padding: 4px; + background: var(--evcc-background); } .btn { - /* equal width buttons */ - flex-basis: 0; white-space: nowrap; border-radius: 12px; padding: 0.1em 0.8em; @@ -45,6 +45,9 @@ export default { overflow-x: hidden; text-overflow: ellipsis; } +.btn--equal { + flex-basis: 0; +} .btn:hover { color: var(--evcc-gray); } diff --git a/assets/js/components/Sessions/CostHistoryChart.vue b/assets/js/components/Sessions/CostHistoryChart.vue new file mode 100644 index 0000000000..9591ea0b93 --- /dev/null +++ b/assets/js/components/Sessions/CostHistoryChart.vue @@ -0,0 +1,337 @@ + + + diff --git a/assets/js/components/Sessions/CostYearChart.vue b/assets/js/components/Sessions/CostYearChart.vue new file mode 100644 index 0000000000..c5a0979425 --- /dev/null +++ b/assets/js/components/Sessions/CostYearChart.vue @@ -0,0 +1,214 @@ + + + diff --git a/assets/js/components/Sessions/DateNavigator.vue b/assets/js/components/Sessions/DateNavigator.vue new file mode 100644 index 0000000000..8d4bec069b --- /dev/null +++ b/assets/js/components/Sessions/DateNavigator.vue @@ -0,0 +1,174 @@ + + + + + diff --git a/assets/js/components/Sessions/DateNavigatorButton.vue b/assets/js/components/Sessions/DateNavigatorButton.vue new file mode 100644 index 0000000000..923a98bd79 --- /dev/null +++ b/assets/js/components/Sessions/DateNavigatorButton.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/assets/js/components/Sessions/EnergyGroupedChart.vue b/assets/js/components/Sessions/EnergyGroupedChart.vue new file mode 100644 index 0000000000..8ca33cf63c --- /dev/null +++ b/assets/js/components/Sessions/EnergyGroupedChart.vue @@ -0,0 +1,119 @@ + + + diff --git a/assets/js/components/Sessions/EnergyHistoryChart.vue b/assets/js/components/Sessions/EnergyHistoryChart.vue new file mode 100644 index 0000000000..5d43ab27ef --- /dev/null +++ b/assets/js/components/Sessions/EnergyHistoryChart.vue @@ -0,0 +1,244 @@ + + + diff --git a/assets/js/components/Sessions/LegendList.vue b/assets/js/components/Sessions/LegendList.vue new file mode 100644 index 0000000000..9a1ccdd560 --- /dev/null +++ b/assets/js/components/Sessions/LegendList.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/assets/js/components/Sessions/PeriodSelector.vue b/assets/js/components/Sessions/PeriodSelector.vue new file mode 100644 index 0000000000..193c9c927d --- /dev/null +++ b/assets/js/components/Sessions/PeriodSelector.vue @@ -0,0 +1,35 @@ + + + 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 213c5d3630..f49c1a0008 100644 --- a/assets/js/components/ChargingSessionModal.vue +++ b/assets/js/components/Sessions/SessionDetailsModal.vue @@ -129,10 +129,10 @@
-