From c2b240e7286c854a2e0e86ee3561cb231515bb0f Mon Sep 17 00:00:00 2001 From: Brett-S-OWB Date: Mon, 7 Apr 2025 15:11:02 +0200 Subject: [PATCH 1/9] Add chargepoint table view --- packages/modules/web_themes/koala/config.py | 7 +- .../source/src/components/ChargePointCard.vue | 1 + .../src/components/ChargePointInformation.vue | 253 +++++++++++++++++- .../models/chargepoint-information-models.ts | 19 ++ .../source/src/composables/useChargeModes.ts | 12 + .../source/src/css/quasar.variables.scss | 114 ++++++++ .../source/src/stores/mqtt-store-model.ts | 2 + 7 files changed, 399 insertions(+), 9 deletions(-) create mode 100644 packages/modules/web_themes/koala/source/src/components/models/chargepoint-information-models.ts create mode 100644 packages/modules/web_themes/koala/source/src/composables/useChargeModes.ts diff --git a/packages/modules/web_themes/koala/config.py b/packages/modules/web_themes/koala/config.py index dfe89a07b6..2c5da9198f 100644 --- a/packages/modules/web_themes/koala/config.py +++ b/packages/modules/web_themes/koala/config.py @@ -6,9 +6,12 @@ @auto_str class KoalaWebThemeConfiguration: def __init__(self, - history_chart_range: int = 3600) -> None: + history_chart_range: int = 3600, + card_view_breakpoint: int = 4, + table_search_input_field: bool = False) -> None: self.history_chart_range = history_chart_range - + self.card_view_breakpoint = card_view_breakpoint + self.table_search_input_field = table_search_input_field @auto_str class KoalaWebTheme: diff --git a/packages/modules/web_themes/koala/source/src/components/ChargePointCard.vue b/packages/modules/web_themes/koala/source/src/components/ChargePointCard.vue index 4cf0d9ecdb..1d5e12b6e1 100644 --- a/packages/modules/web_themes/koala/source/src/components/ChargePointCard.vue +++ b/packages/modules/web_themes/koala/source/src/components/ChargePointCard.vue @@ -44,6 +44,7 @@ :current-value="currentValue" :target-time="targetTime" /> + diff --git a/packages/modules/web_themes/koala/source/src/components/ChargePointInformation.vue b/packages/modules/web_themes/koala/source/src/components/ChargePointInformation.vue index 8c2fac320a..344b71cdbf 100644 --- a/packages/modules/web_themes/koala/source/src/components/ChargePointInformation.vue +++ b/packages/modules/web_themes/koala/source/src/components/ChargePointInformation.vue @@ -1,19 +1,258 @@ + + diff --git a/packages/modules/web_themes/koala/source/src/components/models/chargepoint-information-models.ts b/packages/modules/web_themes/koala/source/src/components/models/chargepoint-information-models.ts new file mode 100644 index 0000000000..138f4c8c50 --- /dev/null +++ b/packages/modules/web_themes/koala/source/src/components/models/chargepoint-information-models.ts @@ -0,0 +1,19 @@ +export type QTableColumn = { + name: string; + label: string; + field: string | ((row: Record) => unknown); + required?: boolean; + align?: 'left' | 'right' | 'center'; + sortable?: boolean; + sort?: ( + a: unknown, + b: unknown, + rowA: Record, + rowB: Record, + ) => number; + format?: (val: unknown, row: Record) => unknown; + style?: string | ((row: Record) => string); + classes?: string | ((row: Record) => string); + headerStyle?: string; + headerClasses?: string; +}; diff --git a/packages/modules/web_themes/koala/source/src/composables/useChargeModes.ts b/packages/modules/web_themes/koala/source/src/composables/useChargeModes.ts new file mode 100644 index 0000000000..340cd59a79 --- /dev/null +++ b/packages/modules/web_themes/koala/source/src/composables/useChargeModes.ts @@ -0,0 +1,12 @@ +export const useChargeModes = () => { + const chargeModes = [ + { value: 'instant_charging', label: 'Sofort', color: 'negative' }, + { value: 'pv_charging', label: 'PV', color: 'positive' }, + { value: 'scheduled_charging', label: 'Ziel', color: 'primary' }, + { value: 'eco_charging', label: 'Eco', color: 'secondary' }, + { value: 'stop', label: 'Stop', color: 'light' }, + ]; + return { + chargeModes, + }; +}; diff --git a/packages/modules/web_themes/koala/source/src/css/quasar.variables.scss b/packages/modules/web_themes/koala/source/src/css/quasar.variables.scss index 42a1018f06..001ade7642 100644 --- a/packages/modules/web_themes/koala/source/src/css/quasar.variables.scss +++ b/packages/modules/web_themes/koala/source/src/css/quasar.variables.scss @@ -131,6 +131,66 @@ $battery: #ba7128; .q-toggle__inner--truthy .q-toggle__thumb:after { background-color: currentColor; } + // Search input border color for table view + .white-outline-input.q-field--outlined .q-field__control:before { + border-color: var(--q-white) !important; + } + // Table styling + .sticky-header-table { + /* height or max-height is important */ + height: 310px; + + .q-table__top, + .q-table__bottom, + thead tr:first-child th { + background-color: var(--q-primary); + color: var(--q-white); + font-size: 0.9rem; + } + + thead tr th { + position: sticky; + z-index: 1; + } + + thead tr:first-child th { + top: 0; + } + + /* this is when the loading indicator appears */ + &.q-table--loading thead tr:last-child th { + /* height of all previous header rows */ + top: 48px; + } + + /* prevent scrolling behind sticky top row on focus */ + tbody { + /* height of all previous header rows */ + scroll-margin-top: 48px; + background-color: var(--q-secondary); + color: var(--q-brown-text); + } + + tbody tr, + .q-table__middle, + .q-table__grid-content + .q-virtual-scroll + .q-virtual-scroll--vertical + scroll { + background-color: var(--q-secondary); + } + + tbody tr:hover { + background-color: rgba(0, 0, 0, 0.05); + } + + // Scrollbar styling for tables - Light Theme + .q-table__middle.q-virtual-scroll { + // Firefox + scrollbar-width: thin; + scrollbar-color: var(--q-primary) var(--q-secondary); + } + } } // Dark Theme Base Colors $dark-page: #000000; // This overrides Quasar's default dark page color @@ -262,4 +322,58 @@ $dark-tab-icon: #d7d9e0; .q-toggle__inner--truthy .q-toggle__thumb:after { background-color: currentColor; } + + // Table styling - Dark Theme + .sticky-header-table { + /* height or max-height is important */ + height: 310px; + + .q-table__top, + .q-table__bottom, + thead tr:first-child th { + background-color: var(--q-primary); + color: var(--q-white); + font-size: 0.9rem; + } + + thead tr th { + position: sticky; + z-index: 1; + } + + thead tr:first-child th { + top: 0; + } + + /* this is when the loading indicator appears */ + &.q-table--loading thead tr:last-child th { + /* height of all previous header rows */ + top: 48px; + } + + /* prevent scrolling behind sticky top row on focus */ + tbody { + /* height of all previous header rows */ + scroll-margin-top: 48px; + background-color: var(--q-secondary); + color: var(--q-white); + } + + tbody tr, + .q-table__middle, + .q-table__grid-content { + background-color: var(--q-secondary); + } + + tbody tr:hover { + background-color: rgba(255, 255, 255, 0.07); + } + + // Scrollbar styling for tables - Dark Theme + .q-table__middle.q-virtual-scroll { + // Firefox + scrollbar-width: thin; + scrollbar-color: var(--q-primary) var(--q-secondary); + } + } } diff --git a/packages/modules/web_themes/koala/source/src/stores/mqtt-store-model.ts b/packages/modules/web_themes/koala/source/src/stores/mqtt-store-model.ts index b92fc357d3..f4fdddabaf 100644 --- a/packages/modules/web_themes/koala/source/src/stores/mqtt-store-model.ts +++ b/packages/modules/web_themes/koala/source/src/stores/mqtt-store-model.ts @@ -1,5 +1,7 @@ export interface ThemeConfiguration { history_chart_range: number; + card_view_breakpoint: number; + table_search_input_field: boolean; } export interface ConnectionOptions { From 390fb80a8d49cc707697d45db54cc56c75664491 Mon Sep 17 00:00:00 2001 From: Brett-S-OWB Date: Mon, 7 Apr 2025 15:27:04 +0200 Subject: [PATCH 2/9] Charge modes migrated to composable --- .../source/src/components/ChargePointModeButtons.vue | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/modules/web_themes/koala/source/src/components/ChargePointModeButtons.vue b/packages/modules/web_themes/koala/source/src/components/ChargePointModeButtons.vue index 539b811af6..e9c3824041 100644 --- a/packages/modules/web_themes/koala/source/src/components/ChargePointModeButtons.vue +++ b/packages/modules/web_themes/koala/source/src/components/ChargePointModeButtons.vue @@ -47,23 +47,16 @@ import { useMqttStore } from 'src/stores/mqtt-store'; import { computed } from 'vue'; import { Platform } from 'quasar'; +import { useChargeModes } from 'src/composables/useChargeModes'; const props = defineProps<{ chargePointId: number; }>(); const isMobile = computed(() => Platform.is.mobile); - +const { chargeModes } = useChargeModes(); const mqttStore = useMqttStore(); -const chargeModes = [ - { value: 'instant_charging', label: 'Sofort', color: 'negative' }, - { value: 'pv_charging', label: 'PV', color: 'positive' }, - { value: 'scheduled_charging', label: 'Ziel', color: 'primary' }, - { value: 'eco_charging', label: 'Eco', color: 'secondary' }, - { value: 'stop', label: 'Stop', color: 'light' }, -]; - const chargeMode = computed(() => mqttStore.chargePointConnectedVehicleChargeMode(props.chargePointId), ); From 80eb53b210741f7d0f78c5f0809db4d7bb5a53fa Mon Sep 17 00:00:00 2001 From: Brett-S-OWB Date: Mon, 7 Apr 2025 15:28:18 +0200 Subject: [PATCH 3/9] Add formating for longer text in state message --- .../source/src/components/ChargePointStateMessage.vue | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/modules/web_themes/koala/source/src/components/ChargePointStateMessage.vue b/packages/modules/web_themes/koala/source/src/components/ChargePointStateMessage.vue index cb70e4146b..9a6367bda4 100644 --- a/packages/modules/web_themes/koala/source/src/components/ChargePointStateMessage.vue +++ b/packages/modules/web_themes/koala/source/src/components/ChargePointStateMessage.vue @@ -1,6 +1,6 @@ From 06400b190b89c8e88f9358303d26451e0dea5575 Mon Sep 17 00:00:00 2001 From: Brett-S-OWB Date: Mon, 7 Apr 2025 15:48:49 +0200 Subject: [PATCH 6/9] Formatting --- .../source/src/components/ChargePointInformation.vue | 12 +++++++++--- .../koala/source/src/layouts/MainLayout.vue | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/modules/web_themes/koala/source/src/components/ChargePointInformation.vue b/packages/modules/web_themes/koala/source/src/components/ChargePointInformation.vue index 344b71cdbf..fd8ecd44ea 100644 --- a/packages/modules/web_themes/koala/source/src/components/ChargePointInformation.vue +++ b/packages/modules/web_themes/koala/source/src/components/ChargePointInformation.vue @@ -126,15 +126,21 @@ const filter = ref(''); const chargePointIds = computed(() => mqttStore.chargePointIds); -const cardViewBreakpoint = computed( ()=> mqttStore.themeConfiguration?.card_view_breakpoint || 4); -const searchInputVisible = computed(() => mqttStore.themeConfiguration?.table_search_input_field); +const cardViewBreakpoint = computed( + () => mqttStore.themeConfiguration?.card_view_breakpoint || 4, +); +const searchInputVisible = computed( + () => mqttStore.themeConfiguration?.table_search_input_field, +); const { chargeModes } = useChargeModes(); const rows = computed(() => { return chargePointIds.value.map((id) => { const chargePointName = mqttStore.chargePointName(id); - const vehicleName = mqttStore.chargePointConnectedVehicleInfo(id).value?.name || 'Kein Fahrzeug' ; + const vehicleName = + mqttStore.chargePointConnectedVehicleInfo(id).value?.name || + 'Kein Fahrzeug'; const plugState = mqttStore.chargePointPlugState(id) ? 'Ja' : 'Nein'; const chargeModeValue = mqttStore.chargePointConnectedVehicleChargeMode(id).value; diff --git a/packages/modules/web_themes/koala/source/src/layouts/MainLayout.vue b/packages/modules/web_themes/koala/source/src/layouts/MainLayout.vue index a4f10a6996..fee95d6b71 100644 --- a/packages/modules/web_themes/koala/source/src/layouts/MainLayout.vue +++ b/packages/modules/web_themes/koala/source/src/layouts/MainLayout.vue @@ -143,7 +143,7 @@ const setTheme = (mode: 'light' | 'dark' | 'auto') => { $q.dark.set(mode === 'dark'); localStorage.setItem('theme', mode); } -} +}; onMounted(() => { const savedTheme = localStorage.getItem('theme'); From 82494c938ecf30ed91e1ce03d1b9be5f986810b5 Mon Sep 17 00:00:00 2001 From: Brett-S-OWB Date: Tue, 8 Apr 2025 19:40:15 +0200 Subject: [PATCH 7/9] Quasar table moved into a reuseable component --- .../koala/source/src/components/BaseTable.vue | 106 ++++++++++++++ .../src/components/ChargePointInformation.vue | 134 +++++++----------- .../components/models/base-table-models.ts | 4 + .../models/chargepoint-information-models.ts | 31 ++-- 4 files changed, 173 insertions(+), 102 deletions(-) create mode 100644 packages/modules/web_themes/koala/source/src/components/BaseTable.vue create mode 100644 packages/modules/web_themes/koala/source/src/components/models/base-table-models.ts diff --git a/packages/modules/web_themes/koala/source/src/components/BaseTable.vue b/packages/modules/web_themes/koala/source/src/components/BaseTable.vue new file mode 100644 index 0000000000..5de3eaeff7 --- /dev/null +++ b/packages/modules/web_themes/koala/source/src/components/BaseTable.vue @@ -0,0 +1,106 @@ + + + + + diff --git a/packages/modules/web_themes/koala/source/src/components/ChargePointInformation.vue b/packages/modules/web_themes/koala/source/src/components/ChargePointInformation.vue index fd8ecd44ea..287f890b92 100644 --- a/packages/modules/web_themes/koala/source/src/components/ChargePointInformation.vue +++ b/packages/modules/web_themes/koala/source/src/components/ChargePointInformation.vue @@ -9,85 +9,55 @@ -
- - + +
+ From d6e6c4a92478909bdad6531ec9fbfc8b563faeba Mon Sep 17 00:00:00 2001 From: benderl Date: Wed, 9 Apr 2025 08:11:21 +0200 Subject: [PATCH 9/9] Update packages/modules/web_themes/koala/config.py fix flake8 error --- packages/modules/web_themes/koala/config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/modules/web_themes/koala/config.py b/packages/modules/web_themes/koala/config.py index 2c5da9198f..31dceec4c6 100644 --- a/packages/modules/web_themes/koala/config.py +++ b/packages/modules/web_themes/koala/config.py @@ -13,6 +13,7 @@ def __init__(self, self.card_view_breakpoint = card_view_breakpoint self.table_search_input_field = table_search_input_field + @auto_str class KoalaWebTheme: def __init__(self,