Add cancel button to loading modal

This commit is contained in:
Linus Groh
2021-02-24 20:07:47 +01:00
parent 245c1295e5
commit fdddd8e035
11 changed files with 77 additions and 26 deletions
+33 -18
View File
@@ -7,17 +7,24 @@ import { getApiUrl, getLocationHistoryCount } from "@/util";
*
* @param {String} path API resource path
* @param {Object} [params] Query parameters
* @returns {Promise} Promise returned by the fetch function
* @param {Object} [fetchOptions]
* fetch() options (merged with config.api.fetchOptions)
* @returns {Promise<Response>} Response returned by the fetch call
*/
const fetchApi = (path, params = {}) => {
const fetchApi = (path, params = {}, fetchOptions = {}) => {
const url = getApiUrl(path);
Object.keys(params).forEach((key) =>
url.searchParams.append(key, params[key])
);
Object.keys(params).forEach((key) => url.searchParams.set(key, params[key]));
log("HTTP", `GET ${url.href}`);
return fetch(url.href, config.api.fetchOptions).catch((error) =>
log("HTTP", error, logLevels.ERROR)
);
return fetch(url.href, {
...fetchOptions,
...config.api.fetchOptions,
}).catch((error) => {
if (error.name === "AbortError") {
log("HTTP", `GET ${url.href} - Request was aborted`, logLevels.WARNING);
} else {
log("HTTP", error, logLevels.ERROR);
}
});
};
/**
@@ -107,21 +114,27 @@ export const getLastLocations = async (user, device) => {
* @param {Device} device Device name
* @param {String} start Start date and time in UTC
* @param {String} end End date and time in UTC
* @param {Object} [fetchOptions] fetch() options
* @returns {Promise<OTLocation[]>} Array of location history objects
*/
export const getUserDeviceLocationHistory = async (
user,
device,
start,
end
end,
fetchOptions
) => {
const response = await fetchApi("/api/0/locations", {
from: start,
to: end,
user,
device,
format: "json",
});
const response = await fetchApi(
"/api/0/locations",
{
from: start,
to: end,
user,
device,
format: "json",
},
fetchOptions
);
const json = await response.json();
const userDeviceLocationHistory = json.data;
log(
@@ -141,9 +154,10 @@ export const getUserDeviceLocationHistory = async (
* Devices of which the history should be fetched
* @param {String} start Start date and time in UTC
* @param {String} end End date and time in UTC
* @param {Object} [fetchOptions] fetch() options
* @returns {Promise<LocationHistory>} Location history
*/
export const getLocationHistory = async (devices, start, end) => {
export const getLocationHistory = async (devices, start, end, fetchOptions) => {
const locationHistory = {};
await Promise.all(
Object.keys(devices).map(async (user) => {
@@ -154,7 +168,8 @@ export const getLocationHistory = async (devices, start, end) => {
user,
device,
start,
end
end,
fetchOptions
);
})
);
+19 -2
View File
@@ -1,16 +1,29 @@
<template>
<modal name="loading" :click-to-close="false" adaptive>
<LoaderIcon class="loader" size="1.5x" />
<LoaderIcon class="loader-icon" size="1.5x" />
{{ $t("Loading data, please wait...") }}
<br />
<button
type="button"
class="button button-primary button-cancel"
@click="requestAbortController.abort()"
>
{{ $t("Cancel") }}
</button>
</modal>
</template>
<style scoped>
.loader {
.loader-icon {
animation: spinning 2s linear infinite;
margin-right: 5px;
}
.button-cancel {
display: block;
margin: 20px auto 0;
}
@keyframes spinning {
from {
transform: rotate(0deg);
@@ -22,11 +35,15 @@
</style>
<script>
import { mapState } from "vuex";
import { LoaderIcon } from "vue-feather-icons";
export default {
components: {
LoaderIcon,
},
computed: {
...mapState(["requestAbortController"]),
},
};
</script>
+1
View File
@@ -26,6 +26,7 @@
"OwnTracks documentation": "OwnTracks Dokumentation",
"OwnTracks on Twitter": "OwnTracks auf Twitter",
"Loading data, please wait...": "Daten werden geladen, bitte warten...",
"Cancel": "Abbrechen",
"Image of {deviceName}": "Bild von {deviceName}",
"Timestamp": "Zeitstempel",
"Location": "Standort",
+1
View File
@@ -26,6 +26,7 @@
"OwnTracks documentation": "OwnTracks documentation",
"OwnTracks on Twitter": "OwnTracks on Twitter",
"Loading data, please wait...": "Loading data, please wait...",
"Cancel": "Cancel",
"Image of {deviceName}": "Image of {deviceName}",
"Timestamp": "Timestamp",
"Location": "Location",
+1
View File
@@ -26,6 +26,7 @@
"OwnTracks documentation": "OwnTracks documentation",
"OwnTracks on Twitter": "OwnTracks on Twitter",
"Loading data, please wait...": "Loading data, please wait...",
"Cancel": "Cancel",
"Image of {deviceName}": "Image of {deviceName}",
"Timestamp": "Timestamp",
"Location": "Location",
+1
View File
@@ -26,6 +26,7 @@
"OwnTracks documentation": "OwnTracks - documentación",
"OwnTracks on Twitter": "OwnTracks en Twitter",
"Loading data, please wait...": "Cargando datos, por favor, espera...",
"Cancel": "Cancelar",
"Image of {deviceName}": "Imágen de {deviceName}",
"Timestamp": "Fecha / Hora",
"Location": "Ubicación",
+1
View File
@@ -26,6 +26,7 @@
"OwnTracks documentation": "Documentation d'OwnTracks",
"OwnTracks on Twitter": "OwnTracks sur Twitter",
"Loading data, please wait...": "Chargement des données, merci de patienter ...",
"Cancel": "Annuler",
"Image of {deviceName}": "Image de {deviceName}",
"Timestamp": "Horodatage",
"Location": "Localisation",
+15 -6
View File
@@ -184,12 +184,21 @@ const getLocationHistory = async ({ commit, state }) => {
} else {
devices = state.devices;
}
const locationHistory = await api.getLocationHistory(
devices,
state.startDateTime,
state.endDateTime
);
commit(types.SET_IS_LOADING, false);
commit(types.SET_REQUEST_ABORT_CONTROLLER, new AbortController());
let locationHistory;
try {
locationHistory = await api.getLocationHistory(
devices,
state.startDateTime,
state.endDateTime,
{ signal: state.requestAbortController.signal }
);
} catch (error) {
return;
} finally {
commit(types.SET_REQUEST_ABORT_CONTROLLER, null);
commit(types.SET_IS_LOADING, false);
}
commit(types.SET_LOCATION_HISTORY, locationHistory);
if (config.showDistanceTravelled) {
const { distanceTravelled, elevationGain, elevationLoss } = _getTravelStats(
+1
View File
@@ -33,6 +33,7 @@ export default new Vuex.Store({
distanceTravelled: 0,
elevationGain: 0,
elevationLoss: 0,
requestAbortController: null,
},
getters,
mutations,
+1
View File
@@ -14,3 +14,4 @@ export const SET_MAP_LAYER_VISIBILITY = "SET_MAP_LAYER_VISIBILITY";
export const SET_DISTANCE_TRAVELLED = "SET_DISTANCE_TRAVELLED";
export const SET_ELEVATION_GAIN = "SET_ELEVATION_GAIN";
export const SET_ELEVATION_LOSS = "SET_ELEVATION_LOSS";
export const SET_REQUEST_ABORT_CONTROLLER = "SET_REQUEST_ABORT_CONTROLLER";
+3
View File
@@ -49,4 +49,7 @@ export default {
[types.SET_ELEVATION_LOSS](state, elevationLoss) {
state.elevationLoss = elevationLoss;
},
[types.SET_REQUEST_ABORT_CONTROLLER](state, requestAbortController) {
state.requestAbortController = requestAbortController;
},
};