mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2026-02-06 09:56:03 +00:00
replace user setting's select by location select component
This commit is contained in:
parent
e2667a1a98
commit
6aeef477fc
118
webapp/components/Select/LocationSelect.vue
Normal file
118
webapp/components/Select/LocationSelect.vue
Normal file
@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div>
|
||||
<label class="ds-input-label">
|
||||
{{ `${$t('settings.data.labelCity')}` }}
|
||||
<span v-if="locationName">{{ `- ${locationName}` }}</span>
|
||||
</label>
|
||||
<ds-select
|
||||
id="city"
|
||||
v-model="currentValue"
|
||||
:options="cities"
|
||||
icon="map-marker"
|
||||
:icon-right="null"
|
||||
:placeholder="$t('settings.data.labelCity') + ' …'"
|
||||
:loading="loadingGeo"
|
||||
@input.native="handleCityInput"
|
||||
/>
|
||||
<base-button
|
||||
v-if="locationName !== ''"
|
||||
icon="close"
|
||||
ghost
|
||||
size="small"
|
||||
style="position: relative; display: inline-block; right: -94%; top: -48px; width: 29px"
|
||||
@click.native="clearLocationName"
|
||||
></base-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { queryLocations } from '~/graphql/location'
|
||||
|
||||
let timeout
|
||||
|
||||
export default {
|
||||
name: 'LocationSelect',
|
||||
props: {
|
||||
value: {
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
const result = await this.requestGeoData(this.locationName)
|
||||
await this.$nextTick(() => {
|
||||
this.currentValue = result || this.locationName
|
||||
})
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentValue: this.value,
|
||||
loadingGeo: false,
|
||||
cities: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
locationName() {
|
||||
return typeof this.value === 'object' ? this.value.value : this.value
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
currentValue() {
|
||||
if (this.currentValue !== this.value) {
|
||||
this.$emit('input', this.currentValue)
|
||||
}
|
||||
},
|
||||
value() {
|
||||
if (this.value !== this.currentValue) {
|
||||
this.currentValue = this.value
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleCityInput(event) {
|
||||
clearTimeout(timeout)
|
||||
timeout = setTimeout(
|
||||
() => this.requestGeoData(event.target ? event.target.value.trim() : ''),
|
||||
500,
|
||||
)
|
||||
},
|
||||
processLocationsResult(places) {
|
||||
if (!places.length) {
|
||||
return []
|
||||
}
|
||||
const result = []
|
||||
places.forEach((place) => {
|
||||
result.push({
|
||||
label: place.place_name,
|
||||
value: place.place_name,
|
||||
id: place.id,
|
||||
})
|
||||
})
|
||||
|
||||
return result
|
||||
},
|
||||
async requestGeoData(value) {
|
||||
if (value === '') {
|
||||
this.cities = []
|
||||
return
|
||||
}
|
||||
this.loadingGeo = true
|
||||
|
||||
const place = encodeURIComponent(value)
|
||||
const lang = this.$i18n.locale()
|
||||
|
||||
const {
|
||||
data: { queryLocations: result },
|
||||
} = await this.$apollo.query({ query: queryLocations(), variables: { place, lang } })
|
||||
|
||||
this.cities = this.processLocationsResult(result)
|
||||
this.loadingGeo = false
|
||||
|
||||
return this.cities.find((city) => city.value === value)
|
||||
},
|
||||
clearLocationName(event) {
|
||||
event.target.value = ''
|
||||
this.$emit('input', event.target.value)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@ -11,20 +11,7 @@
|
||||
:placeholder="$t('settings.data.namePlaceholder')"
|
||||
/>
|
||||
<ds-input id="slug" model="slug" icon="at" :label="$t('settings.data.labelSlug')" />
|
||||
<!-- eslint-disable vue/use-v-on-exact -->
|
||||
<ds-select
|
||||
id="city"
|
||||
model="locationName"
|
||||
icon="map-marker"
|
||||
:options="cities"
|
||||
:label="$t('settings.data.labelCity')"
|
||||
:placeholder="$t('settings.data.labelCity')"
|
||||
:loading="loadingGeo"
|
||||
@input.native="handleCityInput"
|
||||
/>
|
||||
<ds-text class="location-hint" color="softer">
|
||||
{{ $t('settings.data.labelCityHint') }}
|
||||
</ds-text>
|
||||
<location-select model="locationName"/>
|
||||
<!-- eslint-enable vue/use-v-on-exact -->
|
||||
<ds-input
|
||||
id="about"
|
||||
@ -45,13 +32,14 @@
|
||||
<script>
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
import UniqueSlugForm from '~/components/utils/UniqueSlugForm'
|
||||
import LocationSelect from '~/components/Select/LocationSelect'
|
||||
import { updateUserMutation } from '~/graphql/User'
|
||||
import { queryLocations } from '~/graphql/location'
|
||||
|
||||
let timeout
|
||||
|
||||
export default {
|
||||
name: 'NewsFeed',
|
||||
components: {
|
||||
LocationSelect
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
cities: [],
|
||||
@ -121,52 +109,12 @@ export default {
|
||||
this.loadingData = false
|
||||
}
|
||||
},
|
||||
handleCityInput(value) {
|
||||
clearTimeout(timeout)
|
||||
timeout = setTimeout(() => this.requestGeoData(value), 500)
|
||||
},
|
||||
processLocationsResult(places) {
|
||||
if (!places.length) {
|
||||
return []
|
||||
}
|
||||
const result = []
|
||||
places.forEach((place) => {
|
||||
result.push({
|
||||
label: place.place_name,
|
||||
value: place.place_name,
|
||||
id: place.id,
|
||||
})
|
||||
})
|
||||
|
||||
return result
|
||||
},
|
||||
async requestGeoData(e) {
|
||||
const value = e.target ? e.target.value.trim() : ''
|
||||
if (value === '') {
|
||||
this.cities = []
|
||||
return
|
||||
}
|
||||
this.loadingGeo = true
|
||||
|
||||
const place = encodeURIComponent(value)
|
||||
const lang = this.$i18n.locale()
|
||||
|
||||
const {
|
||||
data: { queryLocations: res },
|
||||
} = await this.$apollo.query({ query: queryLocations(), variables: { place, lang } })
|
||||
|
||||
this.cities = this.processLocationsResult(res)
|
||||
this.loadingGeo = false
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
// .settings-form {
|
||||
// >
|
||||
.location-hint {
|
||||
margin-top: -$space-x-small - $space-xxx-small - $space-xxx-small;
|
||||
}
|
||||
// }
|
||||
</style>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user