176 lines
4.4 KiB
Vue
176 lines
4.4 KiB
Vue
<template>
|
|
<modal :show="show" @close="close()">
|
|
<template v-slot:header>
|
|
<span class="flex flex-row flex-wrap items-center">
|
|
<input class="input input-sm" placeholder="Name" ref="nameField" type="text" v-model="name_searched">
|
|
<button class="btn btn-sm btn-red mx-2" @click="name_searched = ''">Clear</button>
|
|
|
|
<data-filter
|
|
class="my-2 mr-2"
|
|
v-for="(category, index) in getFilters"
|
|
:key="index"
|
|
:category="category.name"
|
|
:data="data_model[category.key].data">
|
|
</data-filter>
|
|
</span>
|
|
</template>
|
|
|
|
<div v-if="message.length < 1">
|
|
Loading...
|
|
</div>
|
|
<div v-else>
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th v-for="(category, index) in getColumns" :key="index" class="whitespace-nowrap">{{ category.name }}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-if="canUnselect" @click="selectItem(null)">
|
|
<td v-for="index in getColumns.length" :key="index">-</td>
|
|
</tr>
|
|
<tr v-for="item in getData" :key="item.id" @click="selectItem(item.id)">
|
|
<td v-for="(val, index) in getColumn(item)" :key="index">{{ val }}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<template v-slot:footer>
|
|
{{ getResultsCount }}
|
|
</template>
|
|
</modal>
|
|
</template>
|
|
|
|
<script>
|
|
import DataModel from '@/js/data-model'
|
|
import Utils from '@/js/utils'
|
|
|
|
import Modal from './common/Modal.vue'
|
|
import DataFilter from './common/DataFilter.vue'
|
|
|
|
export default {
|
|
model: {
|
|
prop: 'show',
|
|
event: 'close'
|
|
},
|
|
components: {
|
|
Modal,
|
|
DataFilter
|
|
},
|
|
props: {
|
|
show: {
|
|
type: Boolean,
|
|
required: true
|
|
},
|
|
route: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
routeParameters: {
|
|
type: String,
|
|
default: undefined
|
|
},
|
|
categories: {
|
|
type: Array,
|
|
required: true
|
|
},
|
|
dataModel: {
|
|
type: Object,
|
|
default: undefined
|
|
},
|
|
canUnselect: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
message: [],
|
|
previousRoute: '',
|
|
data_model: {},
|
|
name_searched: '',
|
|
}
|
|
},
|
|
methods: {
|
|
selectItem(id) {
|
|
this.$emit('item-selected', id);
|
|
this.close();
|
|
},
|
|
close() {
|
|
this.$emit('close', false);
|
|
},
|
|
getColumn(item) {
|
|
return this.getColumns.map(c => {
|
|
return this.data_model[c.key].expand(item, this.getLang);
|
|
});
|
|
}
|
|
},
|
|
computed: {
|
|
getData() {
|
|
return this.message.filter(item => {
|
|
return item.n.toLowerCase().includes(this.name_searched.toLowerCase()) &&
|
|
this.getFilters.every(f => {
|
|
return this.data_model[f.key].show(item[f.key])
|
|
});
|
|
});
|
|
},
|
|
getResultsCount() {
|
|
if (this.getData.length == 1) {
|
|
return this.getData.length + ' result'
|
|
}
|
|
return this.getData.length + ' results'
|
|
},
|
|
getColumns() {
|
|
return this.categories.filter(c => { return c.isColumn });
|
|
},
|
|
getFilters() {
|
|
return this.categories.filter(c => { return c.isFilter });
|
|
},
|
|
getLang() {
|
|
return this.$store.getters.getLang;
|
|
}
|
|
},
|
|
watch: {
|
|
show() {
|
|
if (this.show) {
|
|
let currentRoute = this.route;
|
|
if (this.routeParameters !== undefined) {
|
|
currentRoute += '?' + this.routeParameters;
|
|
}
|
|
|
|
// Fetch the message again if the route changed
|
|
if (this.previousRoute !== currentRoute) {
|
|
this.message = [];
|
|
}
|
|
this.previousRoute = currentRoute;
|
|
|
|
if (this.message.length === 0) {
|
|
this.axios.get(currentRoute)
|
|
.then(response => this.message = response.data)
|
|
.catch(error => this.$store.dispatch('addAxiosErrorMessage', error));
|
|
}
|
|
|
|
let self = this;
|
|
this.$nextTick().then(() => {
|
|
self.name_searched = '';
|
|
self.$refs.nameField.focus();
|
|
});
|
|
}
|
|
}
|
|
},
|
|
mounted() {
|
|
// Copy the data model locally to modify "checked" properties
|
|
this.categories.forEach(c => {
|
|
this.$set(this.data_model, c.key, Utils.copy(DataModel[c.key]));
|
|
});
|
|
|
|
// Overload data model if specified
|
|
if (this.dataModel !== undefined) {
|
|
for (let [key, data] of Object.entries(this.dataModel)) {
|
|
this.$set(this.data_model, key, data);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script> |