Skip to content

Commit

Permalink
UI: use native select for vehicle change (#14254)
Browse files Browse the repository at this point in the history
  • Loading branch information
naltatis authored Jun 9, 2024
1 parent 0c318f9 commit a554b8a
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 89 deletions.
19 changes: 11 additions & 8 deletions assets/js/components/ChargingSessionModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@
<VehicleOptions
:id="session.vehicle"
class="options"
:vehicles="vehicles"
:vehicles="vehicleOptions"
connected
:selected="session.vehicle"
@change-vehicle="changeVehicle"
@remove-vehicle="removeVehicle"
>
Expand Down Expand Up @@ -202,6 +203,12 @@ export default {
solarEnergy: function () {
return this.chargedEnergy * (this.session.solarPercentage / 100);
},
vehicleOptions: function () {
return this.vehicles.map((v) => ({
name: v.title,
title: v.title,
}));
},
},
methods: {
openSessionDetailsModal() {
Expand All @@ -217,15 +224,11 @@ export default {
formatKm: function (value) {
return `${this.fmtNumber(distanceValue(value), 0)} ${distanceUnit()}`;
},
async changeVehicle(name) {
await this.updateSession({
vehicle: this.vehicles.find((v) => v.name === name)?.title,
});
async changeVehicle(title) {
await this.updateSession({ vehicle: title });
},
async removeVehicle() {
await this.updateSession({
vehicle: null,
});
await this.updateSession({ vehicle: null });
},
async updateSession(data) {
try {
Expand Down
86 changes: 42 additions & 44 deletions assets/js/components/VehicleOptions.vue
Original file line number Diff line number Diff line change
@@ -1,66 +1,64 @@
<template>
<div>
<div
:id="dropdownId"
role="button"
tabindex="0"
data-bs-toggle="dropdown"
aria-expanded="false"
data-testid="change-vehicle"
>
<slot />
</div>
<ul class="dropdown-menu dropdown-menu-start" :aria-labelledby="dropdownId">
<li>
<h6 class="dropdown-header">{{ $t("main.vehicle.changeVehicle") }}</h6>
</li>
<li v-for="vehicle in vehicles" :key="vehicle.name">
<button type="button" class="dropdown-item" @click="changeVehicle(vehicle.name)">
{{ vehicle.title }}
</button>
</li>
<li>
<button type="button" class="dropdown-item" @click="removeVehicle()">
<span v-if="connected">{{ $t("main.vehicle.unknown") }}</span>
<span v-else>{{ $t("main.vehicle.none") }}</span>
</button>
</li>
</ul>
</div>
<label
class="position-relative d-block"
:for="dropdownId"
role="button"
data-testid="change-vehicle"
>
<select :id="dropdownId" :value="selected" class="custom-select" @change="change">
<option
v-for="{ name, title } in vehicles"
:key="name"
:value="name"
:selected="name === selected"
>
{{ title }}
</option>
<hr />
<option value="" :selected="!selected">
{{ $t(`main.vehicle.${connected ? "unknown" : "none"}`) }}
</option>
</select>
<slot></slot>
</label>
</template>

<script>
import "@h2d2/shopicons/es/filled/options";
import Dropdown from "bootstrap/js/dist/dropdown";
export default {
name: "VehicleOptions",
props: {
connected: Boolean,
id: [String, Number],
vehicles: Array,
selected: String,
},
emits: ["change-vehicle", "remove-vehicle"],
computed: {
dropdownId() {
return `vehicleOptionsDropdown${this.id}`;
},
},
mounted() {
this.dropdown = new Dropdown(document.getElementById(this.dropdownId));
},
unmounted() {
this.dropdown?.dispose();
},
methods: {
changeVehicle(name) {
this.$emit("change-vehicle", name);
},
removeVehicle() {
this.$emit("remove-vehicle");
change(event) {
const name = event.target.value;
if (name) {
this.$emit("change-vehicle", name);
} else {
this.$emit("remove-vehicle");
}
},
},
};
</script>
<style></style>
<style scoped>
.custom-select {
left: 0;
top: 0;
bottom: 0;
width: 100%;
cursor: pointer;
position: absolute;
opacity: 0;
-webkit-appearance: menulist-button;
}
</style>
5 changes: 1 addition & 4 deletions assets/js/components/VehicleTitle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
v-bind="vehicleOptionsProps"
:id="id"
class="options"
:vehicles="otherVehicles"
:selected="vehicleName"
@change-vehicle="changeVehicle"
@remove-vehicle="removeVehicle"
>
Expand Down Expand Up @@ -104,9 +104,6 @@ export default {
vehicleKnown() {
return !!this.vehicleName;
},
otherVehicles() {
return this.vehicles.filter((v) => v.name !== this.vehicleName);
},
showOptions() {
return this.vehicleKnown || this.vehicles.length;
},
Expand Down
11 changes: 5 additions & 6 deletions tests/limits.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ test.describe("limitEnergy", async () => {
test("survives a reload", async ({ page }) => {
await page.goto("/");

await page.getByRole("button", { name: "blauer e-Golf" }).click();
await page.getByRole("button", { name: "grüner Honda e" }).click();
await expect(page.getByTestId("vehicle-status")).toHaveText("Connected.");

await page.getByTestId("change-vehicle").locator("select").selectOption("grüner Honda e");

await expect(page.getByTestId("limit-energy-value")).toHaveText("none");
await page.getByTestId("limit-energy").getByRole("combobox").selectOption("10 kWh (+35%)");
Expand All @@ -101,12 +102,10 @@ test.describe("limitEnergy", async () => {
test("should not be reset on vehicle change", async ({ page }) => {
await page.goto("/");

await page.getByRole("button", { name: "blauer e-Golf" }).click();
await page.getByRole("button", { name: "grüner Honda e" }).click();
await page.getByTestId("change-vehicle").locator("select").selectOption("grüner Honda e");
await page.getByTestId("limit-energy").getByRole("combobox").selectOption("10 kWh (+35%)");

await page.getByRole("button", { name: "grüner Honda e" }).click();
await page.getByRole("button", { name: "Guest vehicle" }).click();
await page.getByTestId("change-vehicle").locator("select").selectOption("Guest vehicle");
await expect(page.getByTestId("limit-energy-value")).toHaveText("10 kWh");
});
});
58 changes: 37 additions & 21 deletions tests/plan.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ test.describe("basic functionality", async () => {
const lp1 = await page.getByTestId("loadpoint").first();

// change vehicle
await lp1.getByRole("button", { name: "Guest vehicle" }).click();
await lp1.getByRole("button", { name: "Vehicle with SoC with Capacity" }).click();
await lp1
.getByTestId("change-vehicle")
.locator("select")
.selectOption("Vehicle with SoC with Capacity");

await expect(lp1.getByTestId("plan-marker")).not.toBeVisible();
await expect(lp1.getByText("Loadpoint", { exact: true })).toBeVisible();
Expand Down Expand Up @@ -77,8 +79,7 @@ test.describe("vehicle variations", async () => {

const lp1 = await page.getByTestId("loadpoint").first();

// change vehicle
await expect(lp1.getByRole("button", { name: "Guest vehicle" })).toBeVisible();
await expect(lp1.getByTestId("vehicle-name")).toHaveText("Guest vehicle");

// kWh based limit
await lp1.getByTestId("limit-energy").getByRole("combobox").selectOption("50 kWh");
Expand All @@ -95,8 +96,10 @@ test.describe("vehicle variations", async () => {
const lp1 = await page.getByTestId("loadpoint").first();

// change vehicle
await lp1.getByRole("button", { name: "Guest vehicle" }).click();
await lp1.getByRole("button", { name: "Vehicle no SoC no Capacity" }).click();
await lp1
.getByTestId("change-vehicle")
.locator("select")
.selectOption("Vehicle no SoC no Capacity");

// kWh based limit
await lp1.getByTestId("limit-energy").getByRole("combobox").selectOption("50 kWh");
Expand All @@ -113,8 +116,10 @@ test.describe("vehicle variations", async () => {
const lp1 = await page.getByTestId("loadpoint").first();

// change vehicle
await lp1.getByRole("button", { name: "Guest vehicle" }).click();
await lp1.getByRole("button", { name: "Vehicle no SoC with Capacity" }).click();
await lp1
.getByTestId("change-vehicle")
.locator("select")
.selectOption("Vehicle no SoC with Capacity");

// kWh based limit
await lp1.getByTestId("limit-energy").getByRole("combobox").selectOption("50 kWh (+50%)");
Expand All @@ -131,8 +136,10 @@ test.describe("vehicle variations", async () => {
const lp1 = await page.getByTestId("loadpoint").first();

// change vehicle
await lp1.getByRole("button", { name: "Guest vehicle" }).click();
await lp1.getByRole("button", { name: "Vehicle with SoC no Capacity" }).click();
await lp1
.getByTestId("change-vehicle")
.locator("select")
.selectOption("Vehicle with SoC no Capacity");

// soc based limit
await lp1.getByTestId("limit-soc").getByRole("combobox").selectOption("80%");
Expand All @@ -149,8 +156,10 @@ test.describe("vehicle variations", async () => {
const lp1 = await page.getByTestId("loadpoint").first();

// change vehicle
await lp1.getByRole("button", { name: "Guest vehicle" }).click();
await lp1.getByRole("button", { name: "Vehicle with SoC with Capacity" }).click();
await lp1
.getByTestId("change-vehicle")
.locator("select")
.selectOption("Vehicle with SoC with Capacity");

// soc based limit
await lp1.getByTestId("limit-soc").getByRole("combobox").selectOption("80%");
Expand All @@ -167,7 +176,7 @@ test.describe("vehicle variations", async () => {
const lp2 = await page.getByTestId("loadpoint").last();

// change vehicle
await expect(lp2.getByRole("button", { name: "Guest vehicle" })).toBeVisible();
await expect(lp2.getByTestId("vehicle-name")).toHaveText("Guest vehicle");

// soc based limit
await lp2.getByTestId("limit-soc").getByRole("combobox").selectOption("80%");
Expand All @@ -184,8 +193,10 @@ test.describe("vehicle variations", async () => {
const lp2 = await page.getByTestId("loadpoint").last();

// change vehicle
await lp2.getByRole("button", { name: "Guest vehicle" }).click();
await lp2.getByRole("button", { name: "Vehicle no SoC with Capacity" }).click();
await lp2
.getByTestId("change-vehicle")
.locator("select")
.selectOption("Vehicle no SoC with Capacity");

// soc based limit
await lp2.getByTestId("limit-soc").getByRole("combobox").selectOption("80%");
Expand Down Expand Up @@ -217,8 +228,7 @@ test.describe("preview", async () => {
const lp1 = await page.getByTestId("loadpoint").first();

// change vehicle
await lp1.getByRole("button", { name: "Guest vehicle" }).click();
await lp1.getByRole("button", { name: c.vehicle }).click();
await lp1.getByTestId("change-vehicle").locator("select").selectOption(c.vehicle);

await lp1.getByTestId("charging-plan").getByRole("button", { name: "none" }).click();

Expand Down Expand Up @@ -258,8 +268,11 @@ test.describe("warnings", async () => {
const lp1 = await page.getByTestId("loadpoint").first();

// change vehicle
await lp1.getByRole("button", { name: "Guest vehicle" }).click();
await lp1.getByRole("button", { name: "Vehicle with SoC with massive Capacity" }).click();
await lp1
.getByTestId("change-vehicle")
.locator("select")
.selectOption("Vehicle with SoC with Massive Capacity");

await lp1.getByTestId("charging-plan").getByRole("button", { name: "none" }).click();

await page.getByTestId("plan-active").click();
Expand All @@ -274,8 +287,11 @@ test.describe("warnings", async () => {
const lp1 = await page.getByTestId("loadpoint").first();

// change vehicle
await lp1.getByRole("button", { name: "Guest vehicle" }).click();
await lp1.getByRole("button", { name: "Vehicle with SoC with Capacity" }).click();
await lp1
.getByTestId("change-vehicle")
.locator("select")
.selectOption("Vehicle with SoC with Capacity");

await lp1.getByTestId("charging-plan").getByRole("button", { name: "none" }).click();

await expect(page.getByTestId("plan-entry-warnings")).not.toBeVisible();
Expand Down
3 changes: 1 addition & 2 deletions tests/vehicle-error.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ test.describe("vehicle startup error", async () => {

test("guest vehicle: normal title and no icon", async ({ page }) => {
// switch to offline vehicle
await page.getByRole("button", { name: "Broken Tesla" }).click();
await page.getByRole("button", { name: "Guest vehicle" }).click();
await page.getByTestId("change-vehicle").locator("select").selectOption("Guest vehicle");

await expect(page.getByTestId("vehicle-name")).toHaveText("Guest vehicle");
await expect(page.getByTestId("vehicle-not-reachable-icon")).not.toBeVisible();
Expand Down
6 changes: 2 additions & 4 deletions tests/vehicle-settings.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ test.describe("minSoc and limitSoc", async () => {
await page.goto("/");

// switch to offline vehicle
await page.getByRole("button", { name: "blauer e-Golf" }).click();
await page.getByRole("button", { name: "grüner Honda e" }).click();
await page.getByTestId("change-vehicle").locator("select").selectOption("grüner Honda e");

await page.getByTestId("charging-plan").getByRole("button", { name: "none" }).click();
await page.getByRole("link", { name: "Arrival" }).click();
Expand All @@ -104,8 +103,7 @@ test.describe("minSoc and limitSoc", async () => {
await page.goto("/");

// switch to offline vehicle
await page.getByRole("button", { name: "blauer e-Golf" }).click();
await page.getByRole("button", { name: "Guest vehicle" }).click();
await page.getByTestId("change-vehicle").locator("select").selectOption("Guest vehicle");

await page.getByTestId("charging-plan").getByRole("button", { name: "none" }).click();
await page.getByRole("link", { name: "Arrival" }).click();
Expand Down

0 comments on commit a554b8a

Please sign in to comment.