Simple way to build clouds from nothing
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

<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>