2019-07-30 10:35:29 +02:00
|
|
|
<template>
|
2019-08-22 15:57:44 +02:00
|
|
|
<div>
|
2019-09-12 11:34:01 +02:00
|
|
|
<b-field :label="$t('Find an address')">
|
2019-08-22 15:57:44 +02:00
|
|
|
<b-autocomplete
|
|
|
|
:data="data"
|
|
|
|
v-model="queryText"
|
2019-09-12 11:34:01 +02:00
|
|
|
:placeholder="$t('e.g. 10 Rue Jangot')"
|
2019-08-22 15:57:44 +02:00
|
|
|
field="description"
|
|
|
|
:loading="isFetching"
|
|
|
|
@typing="getAsyncData"
|
2019-10-14 13:07:50 +02:00
|
|
|
icon="map-marker"
|
2019-08-22 15:57:44 +02:00
|
|
|
@select="option => selected = option">
|
|
|
|
|
|
|
|
<template slot-scope="{option}">
|
|
|
|
<b>{{ option.description }}</b><br />
|
|
|
|
<i v-if="option.url != null">Local</i>
|
|
|
|
<p>
|
|
|
|
<small>{{ option.street }},  {{ option.postalCode }} {{ option.locality }}</small>
|
|
|
|
</p>
|
|
|
|
</template>
|
|
|
|
<template slot="empty">
|
2019-09-12 11:34:01 +02:00
|
|
|
<span v-if="queryText.length < 5">{{ $t('Please type at least 5 characters') }}</span>
|
|
|
|
<span v-else-if="isFetching">{{ $t('Searching…') }}</span>
|
2019-08-22 15:57:44 +02:00
|
|
|
<div v-else class="is-enabled">
|
2019-09-12 11:34:01 +02:00
|
|
|
<span>{{ $t('No results for "{queryText}"', { queryText }) }}</span>
|
2019-08-22 15:57:44 +02:00
|
|
|
<p class="control" @click="addressModalActive = true">
|
2019-09-12 11:34:01 +02:00
|
|
|
<button type="button" class="button is-primary">{{ $t('Add') }}</button>
|
2019-08-22 15:57:44 +02:00
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</b-autocomplete>
|
|
|
|
</b-field>
|
|
|
|
<b-modal :active.sync="addressModalActive" :width="640" has-modal-card scroll="keep">
|
|
|
|
<div class="modal-card" style="width: auto">
|
|
|
|
<header class="modal-card-head">
|
2019-09-12 11:34:01 +02:00
|
|
|
<p class="modal-card-title">{{ $t('Add an address') }}</p>
|
2019-08-22 15:57:44 +02:00
|
|
|
</header>
|
|
|
|
<section class="modal-card-body">
|
|
|
|
<form>
|
2019-09-12 11:34:01 +02:00
|
|
|
<b-field :label="$t('Name')">
|
2019-08-22 15:57:44 +02:00
|
|
|
<b-input aria-required="true" required v-model="selected.description" />
|
|
|
|
</b-field>
|
|
|
|
|
2019-09-12 11:34:01 +02:00
|
|
|
<b-field :label="$t('Street')">
|
2019-08-22 15:57:44 +02:00
|
|
|
<b-input v-model="selected.street" />
|
|
|
|
</b-field>
|
|
|
|
|
2019-09-12 11:34:01 +02:00
|
|
|
<b-field :label="$t('Postal Code')">
|
2019-08-22 15:57:44 +02:00
|
|
|
<b-input v-model="selected.postalCode" />
|
|
|
|
</b-field>
|
|
|
|
|
2019-09-12 11:34:01 +02:00
|
|
|
<b-field :label="$t('Locality')">
|
2019-08-22 15:57:44 +02:00
|
|
|
<b-input v-model="selected.locality" />
|
|
|
|
</b-field>
|
|
|
|
|
2019-09-12 11:34:01 +02:00
|
|
|
<b-field :label="$t('Region')">
|
2019-08-22 15:57:44 +02:00
|
|
|
<b-input v-model="selected.region" />
|
|
|
|
</b-field>
|
|
|
|
|
2019-09-12 11:34:01 +02:00
|
|
|
<b-field :label="$t('Country')">
|
2019-08-22 15:57:44 +02:00
|
|
|
<b-input v-model="selected.country" />
|
|
|
|
</b-field>
|
|
|
|
</form>
|
|
|
|
</section>
|
|
|
|
<footer class="modal-card-foot">
|
2019-09-12 11:34:01 +02:00
|
|
|
<button class="button" type="button" @click="resetPopup()">{{ $t('Clear') }}</button>
|
2019-08-22 15:57:44 +02:00
|
|
|
</footer>
|
|
|
|
</div>
|
|
|
|
</b-modal>
|
|
|
|
</div>
|
2019-07-30 10:35:29 +02:00
|
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
|
|
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
|
2019-08-22 15:57:44 +02:00
|
|
|
import { Address, IAddress } from '@/types/address.model';
|
2019-07-30 10:35:29 +02:00
|
|
|
import { ADDRESS } from '@/graphql/address';
|
2019-08-22 15:57:44 +02:00
|
|
|
import { Modal } from 'buefy/dist/components/dialog';
|
|
|
|
@Component({
|
|
|
|
components: {
|
|
|
|
Modal,
|
|
|
|
},
|
|
|
|
})
|
2019-07-30 10:35:29 +02:00
|
|
|
export default class AddressAutoComplete extends Vue {
|
|
|
|
|
|
|
|
@Prop({ required: false, default: () => [] }) initialData!: IAddress[];
|
2019-09-04 18:24:31 +02:00
|
|
|
@Prop({ required: false }) value!: IAddress;
|
2019-07-30 10:35:29 +02:00
|
|
|
|
|
|
|
data: IAddress[] = this.initialData;
|
2019-08-22 15:57:44 +02:00
|
|
|
selected: IAddress|null = new Address();
|
2019-07-30 10:35:29 +02:00
|
|
|
isFetching: boolean = false;
|
2019-09-04 18:24:31 +02:00
|
|
|
queryText: string = this.value && this.value.description || '';
|
2019-08-22 15:57:44 +02:00
|
|
|
addressModalActive: boolean = false;
|
2019-07-30 10:35:29 +02:00
|
|
|
|
|
|
|
async getAsyncData(query) {
|
2019-08-22 15:57:44 +02:00
|
|
|
if (query.length < 5) {
|
2019-07-30 10:35:29 +02:00
|
|
|
this.data = [];
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.isFetching = true;
|
|
|
|
const result = await this.$apollo.query({
|
|
|
|
query: ADDRESS,
|
2019-08-22 15:57:44 +02:00
|
|
|
fetchPolicy: 'no-cache',
|
2019-07-30 10:35:29 +02:00
|
|
|
variables: { query },
|
|
|
|
});
|
|
|
|
|
|
|
|
this.data = result.data.searchAddress as IAddress[];
|
2019-08-22 15:57:44 +02:00
|
|
|
this.isFetching = false;
|
2019-07-30 10:35:29 +02:00
|
|
|
}
|
|
|
|
|
2019-08-22 15:57:44 +02:00
|
|
|
// Watch deep because of subproperties
|
|
|
|
@Watch('selected', { deep: true })
|
2019-07-30 10:35:29 +02:00
|
|
|
updateSelected() {
|
|
|
|
this.$emit('input', this.selected);
|
|
|
|
}
|
2019-08-22 15:57:44 +02:00
|
|
|
|
|
|
|
resetPopup() {
|
|
|
|
this.selected = new Address();
|
|
|
|
}
|
2019-07-30 10:35:29 +02:00
|
|
|
}
|
|
|
|
</script>
|
2019-08-22 15:57:44 +02:00
|
|
|
<style lang="scss">
|
|
|
|
.autocomplete .dropdown-item.is-disabled .is-enabled {
|
|
|
|
opacity: 1 !important;
|
|
|
|
cursor: auto;
|
|
|
|
}
|
|
|
|
</style>
|