Skip to content

Commit 8be3b44

Browse files
committed
Add Vehicle table view - refactor chargepoint table view
1 parent 104ffce commit 8be3b44

7 files changed

Lines changed: 303 additions & 222 deletions

File tree

packages/modules/web_themes/koala/config.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@
77
class KoalaWebThemeConfiguration:
88
def __init__(self,
99
history_chart_range: int = 3600,
10-
card_view_breakpoint: int = 4,
11-
table_search_input_field: bool = False) -> None:
10+
chargePoint_card_view_breakpoint: int = 4,
11+
vehicle_card_view_breakpoint: int = 4,
12+
chargePoint_table_search_input_field: bool = False,
13+
vehicle_table_search_input_field: bool = False) -> None:
1214
self.history_chart_range = history_chart_range
13-
self.card_view_breakpoint = card_view_breakpoint
14-
self.table_search_input_field = table_search_input_field
15-
15+
self.chargePoint_card_view_breakpoint = chargePoint_card_view_breakpoint
16+
self.vehicle_card_view_breakpoint = vehicle_card_view_breakpoint
17+
self.chargePoint_table_search_input_field = chargePoint_table_search_input_field
18+
self.vehicle_table_search_input_field = vehicle_table_search_input_field
1619

1720
@auto_str
1821
class KoalaWebTheme:
Lines changed: 129 additions & 194 deletions
Original file line numberDiff line numberDiff line change
@@ -1,232 +1,167 @@
11
<template>
2-
<div>
3-
<BaseCarousel
4-
v-if="chargePointIds.length <= cardViewBreakpoint"
5-
:items="chargePointIds"
6-
>
7-
<template #item="{ item }">
8-
<ChargePointCard :charge-point-id="item" />
9-
</template>
10-
</BaseCarousel>
2+
<BaseCarousel
3+
v-if="chargePointIds.length <= cardViewBreakpoint"
4+
:items="chargePointIds"
5+
>
6+
<template #item="{ item }">
7+
<ChargePointCard :charge-point-id="item" />
8+
</template>
9+
</BaseCarousel>
1110

12-
<BaseTable
13-
v-else
14-
:rows="rows"
15-
:columns="mobile ? columnsMobile : columns"
16-
:search-input-visible="searchInputVisible"
17-
:table-height="mobile ? '35vh' : '40vh'"
18-
v-model:filter="filter"
19-
:columns-to-search="['vehicle', 'name']"
20-
@row-click="onRowClick($event as ChargePointRow)"
21-
>
22-
<template v-slot:body-cell-plugged="props">
23-
<q-td :props="props">
24-
<ChargePointStateIcon :charge-point-id="props.row.id" />
25-
</q-td>
26-
</template>
27-
</BaseTable>
11+
<BaseTable
12+
v-else
13+
:items="chargePointIds"
14+
:row-data="tableRowData"
15+
:column-config="mobile ? columnConfigMobile : columnConfig"
16+
:search-input-visible="searchInputVisible"
17+
:table-height="mobile ? '35vh' : '40vh'"
18+
v-model:filter="filter"
19+
:columns-to-search="['vehicle', 'name']"
20+
@row-click="onRowClick"
21+
>
22+
<template #body-cell-plugged="{ row }">
23+
<q-td>
24+
<ChargePointStateIcon :charge-point-id="row.id" />
25+
</q-td>
26+
</template>
27+
</BaseTable>
2828

29-
<!-- ChargePointCard Dialog -->
30-
<q-dialog
31-
v-model="modalChargePointCardVisible"
32-
transition-show="fade"
33-
transition-hide="fade"
34-
:backdrop-filter="$q.screen.width < 385 ? '' : 'blur(4px)'"
35-
>
36-
<div class="dialog-content">
37-
<ChargePointCard
38-
v-if="selectedChargePointId !== null"
39-
:charge-point-id="selectedChargePointId"
40-
>
41-
<template #card-footer>
42-
<div class="card-footer">
43-
<q-btn
44-
color="primary"
45-
flat
46-
no-caps
47-
v-close-popup
48-
class="close-button"
49-
size="md"
50-
>Schließen</q-btn
51-
>
52-
</div>
53-
</template>
54-
</ChargePointCard>
55-
</div>
56-
</q-dialog>
57-
</div>
29+
<!-- ChargePointCard Dialog -->
30+
<q-dialog
31+
v-model="modalChargePointCardVisible"
32+
transition-show="fade"
33+
transition-hide="fade"
34+
:backdrop-filter="$q.screen.width < 385 ? '' : 'blur(4px)'"
35+
>
36+
<div class="dialog-content">
37+
<ChargePointCard
38+
v-if="selectedChargePointId !== null"
39+
:charge-point-id="selectedChargePointId"
40+
>
41+
<template #card-footer>
42+
<div class="card-footer">
43+
<q-btn
44+
color="primary"
45+
flat
46+
no-caps
47+
v-close-popup
48+
class="close-button"
49+
size="md"
50+
>Schließen</q-btn
51+
>
52+
</div>
53+
</template>
54+
</ChargePointCard>
55+
</div>
56+
</q-dialog>
5857
</template>
5958

60-
<style scoped>
61-
.dialog-content {
62-
width: auto;
63-
max-width: 24em;
64-
}
65-
66-
.close-button {
67-
position: absolute;
68-
bottom: 0.4em;
69-
right: 0.4em;
70-
z-index: 1;
71-
background: transparent;
72-
}
73-
74-
.card-footer {
75-
height: 1.9em;
76-
}
77-
</style>
78-
7959
<script setup lang="ts">
8060
import { computed, ref } from 'vue';
81-
import { useQuasar, Platform, QTableColumn } from 'quasar';
61+
import { Platform } from 'quasar';
8262
import { useMqttStore } from 'src/stores/mqtt-store';
63+
import { useChargeModes } from 'src/composables/useChargeModes';
8364
import BaseCarousel from 'src/components/BaseCarousel.vue';
8465
import BaseTable from 'src/components/BaseTable.vue';
8566
import ChargePointCard from 'src/components/ChargePointCard.vue';
8667
import ChargePointStateIcon from 'src/components/ChargePointStateIcon.vue';
87-
import { useChargeModes } from 'src/composables/useChargeModes';
88-
import { ChargePointRow } from 'src/components/models/charge-point-information-models';
8968
90-
const $q = useQuasar();
91-
const mobile = computed(() => Platform.is.mobile);
9269
const mqttStore = useMqttStore();
93-
const selectedChargePointId = ref<number | null>(null);
94-
const modalChargePointCardVisible = ref(false);
95-
const filter = ref('');
70+
const { chargeModes } = useChargeModes();
9671
const chargePointIds = computed(() => mqttStore.chargePointIds);
9772
const cardViewBreakpoint = computed(
98-
() => mqttStore.themeConfiguration?.card_view_breakpoint || 4,
73+
() => mqttStore.themeConfiguration?.chargePoint_card_view_breakpoint || 4,
9974
);
10075
const searchInputVisible = computed(
101-
() => mqttStore.themeConfiguration?.table_search_input_field,
76+
() => mqttStore.themeConfiguration?.chargePoint_table_search_input_field,
10277
);
103-
const { chargeModes } = useChargeModes();
104-
105-
const rows = computed<ChargePointRow[]>(() => {
106-
return chargePointIds.value.map((id) => {
107-
const chargePointName = mqttStore.chargePointName(id);
108-
const vehicleName =
78+
const mobile = computed(() => Platform.is.mobile);
79+
const selectedChargePointId = ref<number | null>(null);
80+
const modalChargePointCardVisible = ref(false);
81+
const filter = ref('');
82+
const tableRowData = computed(() => {
83+
return (id: number) => {
84+
const name = mqttStore.chargePointName(id);
85+
const vehicle =
10986
mqttStore.chargePointConnectedVehicleInfo(id).value?.name ||
11087
'Kein Fahrzeug';
111-
const plugState = mqttStore.chargePointPlugState(id) ? 'Ja' : 'Nein';
88+
const plugged = mqttStore.chargePointPlugState(id) ? 'Ja' : 'Nein';
11289
const chargeModeValue =
11390
mqttStore.chargePointConnectedVehicleChargeMode(id).value;
11491
const chargeModeObj = chargeModes.find(
11592
(mode) => mode.value === chargeModeValue,
11693
);
11794
const chargeMode = chargeModeObj ? chargeModeObj.label : chargeModeValue;
118-
const soc = Math.round(
119-
mqttStore.chargePointConnectedVehicleSoc(id).value?.soc || 0,
120-
);
121-
const socDisplay = `${soc}%`;
95+
const chargePointSoc =
96+
mqttStore.chargePointConnectedVehicleSoc(id).value?.soc;
97+
const soc =
98+
chargePointSoc !== undefined ? `${Math.round(chargePointSoc)}%` : '0%';
12299
const power = mqttStore.chargePointPower(id, 'textValue');
123-
const energyCharged = mqttStore.chargePointEnergyChargedPlugged(
124-
id,
125-
'textValue',
126-
);
100+
const charged = mqttStore.chargePointEnergyChargedPlugged(id, 'textValue');
127101
return {
128-
id: id,
129-
name: chargePointName,
130-
vehicle: vehicleName,
131-
plugged: plugState,
132-
mode: chargeMode,
133-
soc: socDisplay,
134-
power: power,
135-
charged: energyCharged,
102+
id,
103+
name,
104+
vehicle,
105+
plugged,
106+
chargeMode,
107+
soc,
108+
power,
109+
charged,
136110
};
137-
});
111+
};
138112
});
139113
140-
const columns: QTableColumn[] = [
141-
{
142-
name: 'name',
143-
label: 'Ladepunkt',
144-
field: 'name',
145-
sortable: true,
146-
align: 'left',
147-
headerStyle: 'font-weight: bold',
148-
},
149-
{
150-
name: 'vehicle',
151-
label: 'Fahrzeug',
152-
field: 'vehicle',
153-
sortable: true,
154-
align: 'left',
155-
headerStyle: 'font-weight: bold',
156-
},
157-
{
158-
name: 'plugged',
159-
label: 'Status',
160-
field: 'plugged',
161-
sortable: true,
162-
align: 'center',
163-
headerStyle: 'font-weight: bold',
164-
},
165-
{
166-
name: 'mode',
167-
label: 'Lademodus',
168-
field: 'mode',
169-
sortable: true,
170-
align: 'left',
171-
headerStyle: 'font-weight: bold',
172-
},
173-
{
174-
name: 'soc',
175-
label: 'Ladestand',
176-
field: 'soc',
177-
sortable: true,
178-
align: 'right',
179-
headerStyle: 'font-weight: bold',
180-
},
181-
{
182-
name: 'power',
183-
label: 'Leistung',
184-
field: 'power',
185-
sortable: true,
186-
align: 'right',
187-
headerStyle: 'font-weight: bold',
114+
const columnConfig = {
115+
fields: [
116+
'name',
117+
'vehicle',
118+
'plugged',
119+
'chargeMode',
120+
'soc',
121+
'power',
122+
'charged',
123+
],
124+
labels: {
125+
name: 'Ladepunkt',
126+
vehicle: 'Fahrzeug',
127+
plugged: 'Status',
128+
chargeMode: 'Lademodus',
129+
soc: 'Ladestand',
130+
power: 'Leistung',
131+
charged: 'Geladen',
188132
},
189-
{
190-
name: 'charged',
191-
label: 'Geladen',
192-
field: 'charged',
193-
sortable: true,
194-
align: 'right',
195-
headerStyle: 'font-weight: bold',
196-
},
197-
];
133+
};
198134
199-
const columnsMobile = computed((): QTableColumn[] => {
200-
return [
201-
{
202-
name: 'name',
203-
label: 'Ladepunkt',
204-
field: 'name',
205-
sortable: true,
206-
align: 'left',
207-
headerStyle: 'font-weight: bold',
208-
},
209-
{
210-
name: 'vehicle',
211-
label: 'Fahrzeug',
212-
field: 'vehicle',
213-
sortable: true,
214-
align: 'left',
215-
headerStyle: 'font-weight: bold',
216-
},
217-
{
218-
name: 'plugged',
219-
label: 'Status',
220-
field: 'plugged',
221-
sortable: true,
222-
align: 'center',
223-
headerStyle: 'font-weight: bold',
224-
},
225-
];
226-
});
135+
const columnConfigMobile = {
136+
fields: ['name', 'vehicle', 'plugged'],
137+
labels: {
138+
name: 'Ladepunkt',
139+
vehicle: 'Fahrzeug',
140+
plugged: 'Status',
141+
},
142+
};
227143
228-
const onRowClick = (row: ChargePointRow) => {
229-
selectedChargePointId.value = row.id;
144+
const onRowClick = (row: Record<string, unknown>) => {
145+
selectedChargePointId.value = row.id as number;
230146
modalChargePointCardVisible.value = true;
231147
};
232148
</script>
149+
150+
<style scoped>
151+
.dialog-content {
152+
width: auto;
153+
max-width: 24em;
154+
}
155+
156+
.close-button {
157+
position: absolute;
158+
bottom: 0.4em;
159+
right: 0.4em;
160+
z-index: 1;
161+
background: transparent;
162+
}
163+
164+
.card-footer {
165+
height: 1.9em;
166+
}
167+
</style>

packages/modules/web_themes/koala/source/src/components/VehicleCard.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
</div>
7272
<div>Ladestand: {{ vehicleSocValue }}%</div>
7373
</div>
74+
<slot name="card-footer"></slot>
7475
</q-card-section>
7576
</q-card>
7677
</template>

0 commit comments

Comments
 (0)