You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
4.3 KiB
168 lines
4.3 KiB
<template>
|
|
<v-layout column>
|
|
<v-flex>
|
|
<v-subheader>{{ label }}</v-subheader>
|
|
</v-flex>
|
|
<v-flex>
|
|
<v-list dense>
|
|
<v-list-item
|
|
v-for="item in doc"
|
|
:key="item.key"
|
|
>
|
|
<v-list-item-content>
|
|
<v-list-item-title v-text="item.label" />
|
|
</v-list-item-content>
|
|
|
|
<v-list-item-action style="margin:0">
|
|
<v-layout>
|
|
<v-flex>
|
|
<v-btn small icon @click="viewItem(item)">
|
|
<v-icon>mdi-eye</v-icon>
|
|
</v-btn>
|
|
</v-flex>
|
|
<v-flex>
|
|
<v-btn small icon @click="deleteItem(item)">
|
|
<v-icon>mdi-delete</v-icon>
|
|
</v-btn>
|
|
</v-flex>
|
|
</v-layout>
|
|
</v-list-item-action>
|
|
</v-list-item>
|
|
</v-list>
|
|
</v-flex>
|
|
<v-flex class="text-center">
|
|
<v-btn v-if="mode !== 'adding' && canAdd" @click="add()">
|
|
<v-icon>mdi-plus-circle-outline</v-icon>
|
|
</v-btn>
|
|
|
|
<v-autocomplete
|
|
v-if="mode === 'adding'"
|
|
v-model="selectedItem"
|
|
:items="items"
|
|
:search-input.sync="search"
|
|
:loading="isLoading"
|
|
cache-items
|
|
item-text="name"
|
|
item-value="_id"
|
|
hide-no-data
|
|
hide-details
|
|
label="Find"
|
|
@change="addItem"
|
|
/>
|
|
</v-flex>
|
|
</v-layout>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
model: { prop: 'value', event: 'change' },
|
|
props: {
|
|
value: { type: Array, default: () => [] },
|
|
label: { type: String, default: 'SelectApi' },
|
|
collection: { type: String, default: '', required: true },
|
|
multiple: { type: [Number, Boolean], default: false }
|
|
},
|
|
data: () => ({
|
|
mode: '',
|
|
items: [],
|
|
isLoading: false,
|
|
selectedItem: null,
|
|
search: '',
|
|
doc: [],
|
|
byId: {},
|
|
fromValueDone: false
|
|
}),
|
|
computed: {
|
|
canAdd () {
|
|
if (this.multiple) {
|
|
if (typeof this.multiple === 'number') {
|
|
return this.doc.length < this.multiple
|
|
} else {
|
|
return true
|
|
}
|
|
} else {
|
|
return this.doc.length === 0
|
|
}
|
|
}
|
|
},
|
|
watch: {
|
|
search (val) {
|
|
val && val.length >= 3 && val !== this.select && this.querySelections(val)
|
|
},
|
|
value (val) {
|
|
if (!val || this.fromValueDone) { return }
|
|
this.doc = val.map(id => ({ id, label: null, key: null }))
|
|
this.updateLabelFromId()
|
|
this.fromValueDone = true
|
|
}
|
|
},
|
|
methods: {
|
|
add () {
|
|
this.mode = 'adding'
|
|
},
|
|
viewItem (item) {
|
|
window.open(`/admin/resources/${this.collection}/${item.id}`, '_blank')
|
|
},
|
|
deleteItem (item) {
|
|
this
|
|
.$confirm(`Supprimer <b>${item.label}</b> ?`)
|
|
.then((res) => {
|
|
if (res) {
|
|
this.doc = this.doc.filter(val => val.id !== item.id)
|
|
this.updateLabelFromId()
|
|
this.$emit('change', this.doc.map(item => item.id))
|
|
}
|
|
})
|
|
},
|
|
addItem () {
|
|
this.doc.push({ id: this.selectedItem, label: null, key: null })
|
|
this.selectedItem = null
|
|
this.mode = ''
|
|
this.search = ''
|
|
this.updateLabelFromId()
|
|
this.$emit('change', this.doc.map(item => item.id))
|
|
},
|
|
querySelections (val) {
|
|
this.isLoading = true
|
|
this.$axios.get(`/cloud/api/${this.collection}?name__regex=${val},i&projection=name:1`)
|
|
.then((res) => {
|
|
this.items = res.data.data
|
|
})
|
|
.finally(() => (this.isLoading = false))
|
|
},
|
|
getTitle (item) {
|
|
return this.byId[item] || item
|
|
},
|
|
updateLabelFromId () {
|
|
const idsToGet = []
|
|
this.doc.forEach((item) => {
|
|
if (!this.byId[item.id]) {
|
|
item.key = this.__generateKey(item.id)
|
|
item.label = item.id
|
|
this.byId[item.id] = item
|
|
}
|
|
})
|
|
|
|
for (const key in this.byId) {
|
|
if (this.byId[key].label === key) {
|
|
idsToGet.push(key)
|
|
}
|
|
}
|
|
|
|
if (!idsToGet.length) { return }
|
|
|
|
this.$axios.get(`/cloud/api/${this.collection}?_id__in=${idsToGet.join(',')}&projection=name:1`)
|
|
.then((res) => {
|
|
res.data.data.forEach((doc) => {
|
|
this.byId[doc._id].label = doc.name
|
|
})
|
|
})
|
|
},
|
|
__generateKey (id) {
|
|
const ts = (new Date()).getTime()
|
|
return `${id}${ts}`
|
|
}
|
|
|
|
}
|
|
}
|
|
</script>
|