Add a search modal, fix for #52

This commit is contained in:
Lucas Verney 2018-11-07 20:04:00 +01:00
parent b5e54b0b90
commit 944b9842cb
5 changed files with 100 additions and 2 deletions

View File

@ -29,10 +29,13 @@
<v-icon>more_vert</v-icon> <v-icon>more_vert</v-icon>
</v-btn> </v-btn>
<v-list> <v-list>
<v-list-tile @click="isSearchModalShown = true" v-if="isMapLoaded">
<v-list-tile-title>{{ $t("menu.search") }}</v-list-tile-title>
</v-list-tile>
<v-list-tile @click="exportGPX" v-if="isExportGPXMenuEntryVisible"> <v-list-tile @click="exportGPX" v-if="isExportGPXMenuEntryVisible">
<v-list-tile-title>{{ $t("menu.exportGPX") }}</v-list-tile-title> <v-list-tile-title>{{ $t("menu.exportGPX") }}</v-list-tile-title>
</v-list-tile> </v-list-tile>
<v-list-tile @click="isShareMapViewModalShown = true" v-if="isShareMapViewMenuEntryVisible"> <v-list-tile @click="isShareMapViewModalShown = true" v-if="isMapLoaded">
<v-list-tile-title>{{ $t("menu.shareMapView") }}</v-list-tile-title> <v-list-tile-title>{{ $t("menu.shareMapView") }}</v-list-tile-title>
</v-list-tile> </v-list-tile>
<v-list-tile @click="goToAbout"> <v-list-tile @click="goToAbout">
@ -57,6 +60,7 @@
<ReportErrorModal v-model="hasReportError"></ReportErrorModal> <ReportErrorModal v-model="hasReportError"></ReportErrorModal>
<ShareMapViewModal v-model="isShareMapViewModalShown"></ShareMapViewModal> <ShareMapViewModal v-model="isShareMapViewModalShown"></ShareMapViewModal>
<ReportIssueModal v-model="isReportIssueModalShown"></ReportIssueModal> <ReportIssueModal v-model="isReportIssueModalShown"></ReportIssueModal>
<SearchModal v-model="isSearchModalShown"></SearchModal>
<router-view></router-view> <router-view></router-view>
</v-content> </v-content>
</v-app> </v-app>
@ -69,12 +73,14 @@ import { DELAY_BETWEEN_API_BATCH_REQUESTS } from '@/constants';
import ReportErrorModal from '@/components/ReportErrorModal.vue'; import ReportErrorModal from '@/components/ReportErrorModal.vue';
import ReportIssueModal from '@/components/ReportIssueModal.vue'; import ReportIssueModal from '@/components/ReportIssueModal.vue';
import SearchModal from '@/components/SearchModal.vue';
import ShareMapViewModal from '@/components/ShareMapViewModal.vue'; import ShareMapViewModal from '@/components/ShareMapViewModal.vue';
export default { export default {
components: { components: {
ReportErrorModal, ReportErrorModal,
ReportIssueModal, ReportIssueModal,
SearchModal,
ShareMapViewModal, ShareMapViewModal,
}, },
computed: { computed: {
@ -84,7 +90,7 @@ export default {
isExportGPXMenuEntryVisible() { isExportGPXMenuEntryVisible() {
return this.$store.state.location.gpx.length > 0; return this.$store.state.location.gpx.length > 0;
}, },
isShareMapViewMenuEntryVisible() { isMapLoaded() {
return this.$store.state.map.center.every(item => item !== null); return this.$store.state.map.center.every(item => item !== null);
}, },
unsentReportsLength() { unsentReportsLength() {
@ -95,6 +101,7 @@ export default {
return { return {
hasReportError: false, hasReportError: false,
isReportIssueModalShown: false, isReportIssueModalShown: false,
isSearchModalShown: false,
isSendingReports: false, isSendingReports: false,
isShareMapViewModalShown: false, isShareMapViewModalShown: false,
title: "Cycl'Assist", title: "Cycl'Assist",

View File

@ -13,6 +13,7 @@
append-icon="my_location" append-icon="my_location"
:rules="rules" :rules="rules"
v-on:input="onInputHandler" v-on:input="onInputHandler"
:menu-props="{ auto: true, overflowY: true }"
></v-combobox> ></v-combobox>
</template> </template>
@ -21,9 +22,11 @@ import { GEOCODING_API_ENDPOINT } from '@/constants';
export default { export default {
props: { props: {
clearOnSelection: Boolean,
label: String, label: String,
hint: String, hint: String,
onInput: Function, onInput: Function,
value: Boolean,
}, },
data() { data() {
return { return {
@ -83,6 +86,11 @@ export default {
label: APIItem.properties.label, label: APIItem.properties.label,
}; };
this.onInput(this.selectedItem); this.onInput(this.selectedItem);
if (this.clearOnSelection) {
this.$nextTick(() => {
this.select = null;
});
}
return; return;
} }

View File

@ -0,0 +1,75 @@
<template>
<Modal v-model="isActive">
<v-card>
<v-card-title class="headline">{{ $t('searchModal.searchModal') }}</v-card-title>
<v-card-text>
<AddressInput
:label="inputLabel"
:onInput="onManualLocationPicker"
:clearOnSelection="true"
></AddressInput>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="green darken-1"
@click="isActive = false"
dark
large
role="button"
>
{{ $t('misc.ok') }}
</v-btn>
<v-spacer></v-spacer>
</v-card-actions>
</v-card>
</Modal>
</template>
<script>
import { DEFAULT_ZOOM } from '@/constants';
import { capitalize } from '@/tools';
import AddressInput from '@/components/AddressInput.vue';
import Modal from '@/components/Modal.vue';
export default {
components: {
AddressInput,
Modal,
},
computed: {
inputLabel() {
return capitalize(this.$t('locationPicker.pickALocationManually'));
},
isActive: {
get() {
return this.value;
},
set(val) {
this.$emit('input', val);
},
},
},
methods: {
onManualLocationPicker(value) {
this.isActive = false;
this.$router.push({
name: 'SharedMap',
params: {
lat: value.latlng.lat,
lng: value.latlng.lng,
zoom: DEFAULT_ZOOM,
},
});
},
},
props: {
value: Boolean,
},
};
</script>

View File

@ -52,6 +52,7 @@
"Settings": "Settings", "Settings": "Settings",
"exportGPX": "Export GPX", "exportGPX": "Export GPX",
"reportIssue": "Report an issue", "reportIssue": "Report an issue",
"search": "Search",
"shareMapView": "Share map view" "shareMapView": "Share map view"
}, },
"misc": { "misc": {
@ -111,6 +112,9 @@
"pothole": "Pothole", "pothole": "Pothole",
"potholeDescription": "A pothole in the ground." "potholeDescription": "A pothole in the ground."
}, },
"searchModal": {
"searchModal": "Search a location"
},
"settings": { "settings": {
"autorotate": "Autorotate (current direction up)", "autorotate": "Autorotate (current direction up)",
"customTileServer": "Custom tile server", "customTileServer": "Custom tile server",

View File

@ -112,3 +112,7 @@ export function storageAvailable(type) {
&& storage.length !== 0; && storage.length !== 0;
} }
} }
export function capitalize(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}