Better feedback with connectivity issues when sending reports
This commit is contained in:
parent
35851802d0
commit
5c777138f4
15
src/App.vue
15
src/App.vue
@ -23,6 +23,9 @@
|
|||||||
</v-list-tile>
|
</v-list-tile>
|
||||||
</v-list>
|
</v-list>
|
||||||
</v-menu>
|
</v-menu>
|
||||||
|
<div>
|
||||||
|
<v-progress-linear v-if="isLoading" :indeterminate="true" class="progressBar"></v-progress-linear>
|
||||||
|
</div>
|
||||||
</v-toolbar>
|
</v-toolbar>
|
||||||
<v-content>
|
<v-content>
|
||||||
<router-view/>
|
<router-view/>
|
||||||
@ -32,6 +35,11 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
|
computed: {
|
||||||
|
isLoading() {
|
||||||
|
return this.$store.state.isLoading;
|
||||||
|
},
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
title: 'Cycl\'Assist',
|
title: 'Cycl\'Assist',
|
||||||
@ -61,6 +69,13 @@ export default {
|
|||||||
color: rgba(0, 0, 0, .87);
|
color: rgba(0, 0, 0, .87);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.progressBar {
|
||||||
|
margin: 0;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -15,12 +15,18 @@ export function saveReport(type, lat, lng) {
|
|||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(response => response.data)
|
.then(response => response.data)
|
||||||
.catch(exc => console.error(`Unable to post report: ${exc}.`));
|
.catch((exc) => {
|
||||||
|
console.error(`Unable to post report: ${exc}.`);
|
||||||
|
throw exc;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getReports() {
|
export function getReports() {
|
||||||
return fetch(`${BASE_URL}api/v1/reports`)
|
return fetch(`${BASE_URL}api/v1/reports`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(response => response.data)
|
.then(response => response.data)
|
||||||
.catch(exc => console.error(`Unable to fetch reports: ${exc}.`));
|
.catch((exc) => {
|
||||||
|
console.error(`Unable to fetch reports: ${exc}.`);
|
||||||
|
throw exc;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-bottom-sheet v-model="isActive">
|
<div>
|
||||||
<v-card>
|
<v-dialog v-model="error" max-width="290">
|
||||||
<v-container fluid>
|
<v-card>
|
||||||
<v-layout row wrap>
|
<v-card-title class="subheading">{{ $t('reportDialog.unableToSendTitle') }}</v-card-title>
|
||||||
<ReportTile v-for="(item, type) in REPORT_TYPES" :type="type" :imageSrc="item.image" :label="$t(item.label)" :save="saveReport" :key="type"></ReportTile>
|
|
||||||
</v-layout>
|
<v-card-text>{{ $t('reportDialog.unableToSendDescription') }} </v-card-text>
|
||||||
</v-container>
|
|
||||||
</v-card>
|
<v-card-actions>
|
||||||
</v-bottom-sheet>
|
<v-spacer></v-spacer>
|
||||||
|
|
||||||
|
<v-btn
|
||||||
|
color="red darken-1"
|
||||||
|
@click="error = false"
|
||||||
|
dark
|
||||||
|
large
|
||||||
|
>
|
||||||
|
{{ $t('misc.discard') }}
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
<v-bottom-sheet v-model="isActive">
|
||||||
|
<v-card>
|
||||||
|
<v-container fluid>
|
||||||
|
<v-layout row wrap>
|
||||||
|
<ReportTile v-for="(item, type) in REPORT_TYPES" :type="type" :imageSrc="item.image" :label="$t(item.label)" :save="saveReport" :key="type"></ReportTile>
|
||||||
|
</v-layout>
|
||||||
|
</v-container>
|
||||||
|
</v-card>
|
||||||
|
</v-bottom-sheet>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -36,19 +60,20 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
error: false,
|
||||||
REPORT_TYPES,
|
REPORT_TYPES,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
saveReport(type) {
|
saveReport(type) {
|
||||||
|
this.isActive = !this.isActive;
|
||||||
return this.$store.dispatch('saveReport', {
|
return this.$store.dispatch('saveReport', {
|
||||||
type,
|
type,
|
||||||
lat: this.lat,
|
lat: this.lat,
|
||||||
lng: this.lng,
|
lng: this.lng,
|
||||||
})
|
}).catch(() => {
|
||||||
.then(() => {
|
this.error = true;
|
||||||
this.isActive = !this.isActive;
|
});
|
||||||
});
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -21,8 +21,14 @@ export default {
|
|||||||
Settings: 'Settings',
|
Settings: 'Settings',
|
||||||
},
|
},
|
||||||
misc: {
|
misc: {
|
||||||
|
discard: 'Discard',
|
||||||
|
retry: 'Retry',
|
||||||
spaceBeforeDoublePunctuations: '',
|
spaceBeforeDoublePunctuations: '',
|
||||||
},
|
},
|
||||||
|
reportDialog: {
|
||||||
|
unableToSendDescription: 'There was a network issue preventing from sending the latest report.',
|
||||||
|
unableToSendTitle: 'Unable to send latest report',
|
||||||
|
},
|
||||||
reportLabels: {
|
reportLabels: {
|
||||||
gcum: 'GCUM',
|
gcum: 'GCUM',
|
||||||
gcumDescription: 'A car poorly parked on a bike lane. Such reports are automatically deleted after one hour, as they are by nature temporary.',
|
gcumDescription: 'A car poorly parked on a bike lane. Such reports are automatically deleted after one hour, as they are by nature temporary.',
|
||||||
|
@ -21,8 +21,14 @@ export default {
|
|||||||
Settings: 'Préférences',
|
Settings: 'Préférences',
|
||||||
},
|
},
|
||||||
misc: {
|
misc: {
|
||||||
|
discard: 'Annuler',
|
||||||
|
retry: 'Réessayer',
|
||||||
spaceBeforeDoublePunctuations: ' ',
|
spaceBeforeDoublePunctuations: ' ',
|
||||||
},
|
},
|
||||||
|
reportDialog: {
|
||||||
|
unableToSendDescription: "Une erreur de réseau empêche l'envoi du dernier signalement.",
|
||||||
|
unableToSendTitle: "Impossible d'envoyer le dernier signalement",
|
||||||
|
},
|
||||||
reportLabels: {
|
reportLabels: {
|
||||||
gcum: 'GCUM',
|
gcum: 'GCUM',
|
||||||
gcumDescription: "Une voiture (mal) garée sur la piste cyclable. Ces signalements sont automatiquement supprimés au bout d'une heure car ils sont par essence temporaires.",
|
gcumDescription: "Une voiture (mal) garée sur la piste cyclable. Ces signalements sont automatiquement supprimés au bout d'une heure car ils sont par essence temporaires.",
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
import * as api from '@/api';
|
import * as api from '@/api';
|
||||||
import { PUSH_REPORT, STORE_REPORTS } from './mutations-types';
|
import { IS_LOADING, IS_DONE_LOADING, PUSH_REPORT, STORE_REPORTS } from './mutations-types';
|
||||||
|
|
||||||
export function fetchReports({ commit }) {
|
export function fetchReports({ commit }) {
|
||||||
return api.getReports().then(
|
commit(IS_LOADING);
|
||||||
reports => commit(STORE_REPORTS, { reports }),
|
return api.getReports()
|
||||||
);
|
.then(reports => commit(STORE_REPORTS, { reports }))
|
||||||
|
.finally(() => commit(IS_DONE_LOADING));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function saveReport({ commit }, { type, lat, lng }) {
|
export function saveReport({ commit }, { type, lat, lng }) {
|
||||||
|
commit(IS_LOADING);
|
||||||
return api.saveReport(type, lat, lng)
|
return api.saveReport(type, lat, lng)
|
||||||
.then(report => commit(PUSH_REPORT, { report }));
|
.then(report => commit(PUSH_REPORT, { report }))
|
||||||
|
.finally(() => commit(IS_DONE_LOADING));
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,17 @@ import Vuex from 'vuex';
|
|||||||
import * as actions from './actions';
|
import * as actions from './actions';
|
||||||
import { initialState as state, mutations } from './mutations';
|
import { initialState as state, mutations } from './mutations';
|
||||||
|
|
||||||
|
const plugins = [];
|
||||||
|
if (process.NODE_ENV !== 'production') {
|
||||||
|
const createLogger = require('vuex/dist/logger');
|
||||||
|
plugins.push(createLogger());
|
||||||
|
}
|
||||||
|
|
||||||
Vue.use(Vuex);
|
Vue.use(Vuex);
|
||||||
|
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
actions,
|
actions,
|
||||||
state,
|
state,
|
||||||
mutations,
|
mutations,
|
||||||
|
plugins,
|
||||||
});
|
});
|
||||||
|
@ -1,2 +1,4 @@
|
|||||||
|
export const IS_LOADING = 'IS_LOADING';
|
||||||
|
export const IS_DONE_LOADING = 'IS_DONE_LOADING';
|
||||||
export const PUSH_REPORT = 'PUSH_REPORT';
|
export const PUSH_REPORT = 'PUSH_REPORT';
|
||||||
export const STORE_REPORTS = 'STORE_REPORTS';
|
export const STORE_REPORTS = 'STORE_REPORTS';
|
||||||
|
@ -1,10 +1,17 @@
|
|||||||
import * as types from './mutations-types';
|
import * as types from './mutations-types';
|
||||||
|
|
||||||
export const initialState = {
|
export const initialState = {
|
||||||
|
isLoading: false,
|
||||||
reports: [],
|
reports: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mutations = {
|
export const mutations = {
|
||||||
|
[types.IS_LOADING](state) {
|
||||||
|
state.isLoading = true;
|
||||||
|
},
|
||||||
|
[types.IS_DONE_LOADING](state) {
|
||||||
|
state.isLoading = false;
|
||||||
|
},
|
||||||
[types.STORE_REPORTS](state, { reports }) {
|
[types.STORE_REPORTS](state, { reports }) {
|
||||||
state.reports = reports;
|
state.reports = reports;
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user