174 lines
4.7 KiB
Vue
174 lines
4.7 KiB
Vue
<template>
|
|
<div :style="`max-height: ${maxheight}; overflow-y: auto;`">
|
|
<div
|
|
v-for="(v, i) in rows"
|
|
:key="i"
|
|
class="field is-grouped my-0"
|
|
>
|
|
<button
|
|
class="button is-white fs-14 font-normal w-full is-justify-content-start py-1.5"
|
|
type="button"
|
|
@click="doClick(v, i)"
|
|
>
|
|
<span>{{ $stripHtml(v[name] || v.fullname || v.code || "n/a", 75) }}</span>
|
|
<span
|
|
v-if="checked[i] && notick !== true"
|
|
class="icon has-text-primary"
|
|
>
|
|
<Icon
|
|
name="material-symbols:check-rounded"
|
|
:size="17"
|
|
/>
|
|
</span>
|
|
</button>
|
|
<p
|
|
class="control py-0"
|
|
v-if="show"
|
|
>
|
|
<span
|
|
class="icon-text has-text-grey mr-2 fs-13"
|
|
v-if="show.author"
|
|
>
|
|
<SvgIcon v-bind="{ name: 'user.svg', type: 'gray', size: 15 }"></SvgIcon>
|
|
<span>{{ v[show.author] }}</span>
|
|
</span>
|
|
<span
|
|
class="icon-text has-text-grey mr-2 fs-13"
|
|
v-if="show.view"
|
|
>
|
|
<SvgIcon v-bind="{ name: 'view.svg', type: 'gray', size: 15 }"></SvgIcon>
|
|
<span>{{ v[show.view] }}</span>
|
|
</span>
|
|
<span
|
|
class="fs-13 has-text-grey"
|
|
v-if="show.time"
|
|
>{{ $dayjs(v["create_time"]).fromNow(true) }}</span
|
|
>
|
|
<span class="tooltip">
|
|
<a
|
|
class="icon ml-1"
|
|
v-if="show.link"
|
|
@click="doClick(v, i, 'newtab')"
|
|
>
|
|
<SvgIcon v-bind="{ name: 'opennew.svg', type: 'gray', size: 15 }"></SvgIcon>
|
|
</a>
|
|
<span class="tooltiptext">Mở trong tab mớ</span>
|
|
</span>
|
|
<span
|
|
class="tooltip"
|
|
v-if="show.rename"
|
|
>
|
|
<a
|
|
class="icon ml-1"
|
|
@click="$emit('rename', v, i)"
|
|
>
|
|
<SvgIcon v-bind="{ name: 'pen1.svg', type: 'gray', size: 15 }"></SvgIcon>
|
|
</a>
|
|
<span class="tooltiptext">Đổi tên</span>
|
|
</span>
|
|
<span
|
|
class="tooltip"
|
|
v-if="show.rename"
|
|
>
|
|
<a
|
|
class="icon has-text-danger ml-1"
|
|
@click="$emit('remove', v, i)"
|
|
>
|
|
<SvgIcon v-bind="{ name: 'bin1.svg', type: 'gray', size: 15 }"></SvgIcon>
|
|
</a>
|
|
<span class="tooltiptext">Xóa</span>
|
|
</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
export default {
|
|
props: ["data", "name", "maxheight", "perpage", "sort", "selects", "keyval", "show", "notick"],
|
|
data() {
|
|
return {
|
|
currentPage: 1,
|
|
total: this.data.length,
|
|
rows: this.data.slice(0, this.perpage),
|
|
selected: [],
|
|
checked: {},
|
|
time: undefined,
|
|
array: [],
|
|
};
|
|
},
|
|
created() {
|
|
this.getdata();
|
|
},
|
|
watch: {
|
|
data: function (newVal) {
|
|
this.getdata();
|
|
},
|
|
selects: function (newVal) {
|
|
this.getSelect();
|
|
},
|
|
},
|
|
methods: {
|
|
getdata() {
|
|
this.currentPage = 1;
|
|
this.array = this.$copy(this.data);
|
|
if (this.sort) {
|
|
const f = {};
|
|
if (this.show?.time) {
|
|
f.create_time = "desc";
|
|
}
|
|
|
|
if (this.sort.startsWith("-")) {
|
|
f[this.sort.slice(1)] = "desc";
|
|
} else {
|
|
f[this.sort] = "asc";
|
|
}
|
|
|
|
this.$multiSort(this.array, f);
|
|
}
|
|
this.rows = this.array.slice(0, this.perpage);
|
|
this.getSelect();
|
|
},
|
|
getSelect() {
|
|
if (!this.selects) return;
|
|
this.selected = [];
|
|
this.checked = {};
|
|
this.selects.map((v) => {
|
|
let idx = this.rows.findIndex((x) => x[this.keyval ? this.keyval : this.name] === v);
|
|
if (idx >= 0) {
|
|
this.selected.push(this.rows[idx]);
|
|
this.checked[idx] = true;
|
|
}
|
|
});
|
|
},
|
|
doClick(v, i, type) {
|
|
this.checked[i] = this.checked[i] ? false : true;
|
|
this.checked = this.$copy(this.checked);
|
|
let idx = this.selected.findIndex((x) => x.id === v.id);
|
|
idx >= 0 ? this.$remove(this.selected) : this.selected.push(v);
|
|
this.$emit("selected", v, type);
|
|
},
|
|
handleScroll(e) {
|
|
const bottom = e.target.scrollHeight - e.target.scrollTop - 5 < e.target.clientHeight;
|
|
if (bottom) {
|
|
if (this.total ? this.total > this.rows.length : true) {
|
|
this.currentPage += 1;
|
|
let arr = this.array.filter(
|
|
(ele, index) => index >= (this.currentPage - 1) * this.perpage && index < this.currentPage * this.perpage,
|
|
);
|
|
this.rows = this.rows.concat(arr);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
<style scoped>
|
|
.button.is-ghost {
|
|
color: var(--bulma-button-text-color);
|
|
}
|
|
.button.is-ghost:hover,
|
|
.button.is-ghost.is-hovered {
|
|
color: var(--bulma-button-ghost-hover-color);
|
|
}
|
|
</style>
|