diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml
index e3a57a09..27f5c790 100644
--- a/.github/workflows/node.js.yml
+++ b/.github/workflows/node.js.yml
@@ -23,3 +23,4 @@ jobs:
cache: 'npm'
- run: npm ci
- run: npm run build
+ - run: npm run test:node
diff --git a/app/src/app.vue b/app/src/app.vue
index 6b0f4c71..62528dfc 100644
--- a/app/src/app.vue
+++ b/app/src/app.vue
@@ -73,9 +73,13 @@
tile
prominent
>
+
+
+
+
+
+
diff --git a/app/src/components/edit-location.vue b/app/src/components/edit-location.vue
index 26a20c36..82f8741e 100644
--- a/app/src/components/edit-location.vue
+++ b/app/src/components/edit-location.vue
@@ -49,7 +49,6 @@ import gql from "graphql-tag";
import EditVehicleLocationSettings from "@app/components/edit-vehicle-location-settings.vue";
import RemoveDialog from "@app/components/remove-dialog.vue";
-import deepmerge from "deepmerge";
import equal from "fast-deep-equal";
import { GQLLocation, GQLPriceList } from "@shared/sc-schema.js";
import { UpdateLocationParams } from "@shared/sc-client.js";
@@ -129,9 +128,11 @@ export default class EditLocation extends Vue {
debounceTimer?: any;
touchedFields: any = {};
- clearSaving: any = {};
+ saveTicketSeq = 0;
+ saveTickets: Record = {};
async save(field: string) {
- delete this.clearSaving[field];
+ const fieldTicket = ++this.saveTicketSeq;
+ this.saveTickets[field] = fieldTicket;
this.$set(this.saving, field, true);
if (this.debounceTimer) {
@@ -139,7 +140,14 @@ export default class EditLocation extends Vue {
}
this.debounceTimer = setTimeout(async () => {
const form: any = this.$refs.form;
- if (form.validate && form.validate()) {
+ const fieldsInRequest = Object.entries(this.saving)
+ .filter(([, value]) => value)
+ .map(([key]) => key);
+ const requestTickets: Record = {};
+ for (const key of fieldsInRequest) {
+ requestTickets[key] = this.saveTickets[key] || 0;
+ }
+ if (!form.validate || form.validate()) {
const update: UpdateLocationParams = {
id: this.location.id,
};
@@ -153,12 +161,18 @@ export default class EditLocation extends Vue {
delete update.providerData;
}
- this.clearSaving = deepmerge(this.clearSaving, this.saving);
-
- await this.$scClient.updateLocation(update);
-
- for (const [key, value] of Object.entries(this.clearSaving)) {
- if (value) {
+ try {
+ await this.$scClient.updateLocation(update);
+ } finally {
+ for (const key of fieldsInRequest) {
+ if (this.saveTickets[key] === requestTickets[key]) {
+ this.$set(this.saving, key, false);
+ }
+ }
+ }
+ } else {
+ for (const key of fieldsInRequest) {
+ if (this.saveTickets[key] === requestTickets[key]) {
this.$set(this.saving, key, false);
}
}
diff --git a/app/src/components/edit-vehicle-location-settings.vue b/app/src/components/edit-vehicle-location-settings.vue
index 8c2ae3bb..22905b7b 100644
--- a/app/src/components/edit-vehicle-location-settings.vue
+++ b/app/src/components/edit-vehicle-location-settings.vue
@@ -1,7 +1,7 @@
-
+
{{ name }}
-
-
+
-
+
+
+
+
+
+ mdi-help-circle-outline
+
+ Control if charging is allowed to split into multiple windows.
+
+
+
+
+
Low Cost
@@ -77,9 +93,8 @@