197 lines
4.3 KiB
Vue

<script>
import {
prepColumns,
sorter,
renderGroupHeader,
groupByFunction,
tablefy,
pipe
} from "./helper";
import {TabulatorFull as Tabulator} from 'tabulator-tables';
import { is, sort, mergeDeepRight } from "ramda";
import localization from "./localization";
import Pagination from "./VTabulatorPagination.vue";
export default {
name: 'TabulatorFull',
components: {
Pagination
},
props: {
dataSource: {
type: Array,
default: () => []
},
columns: {
type: Array,
default: () => []
},
initialSort: {
type: String,
default: null
},
groupBy: {
type: String,
default: null
},
groupByTemplate: {
type: String,
default: null
},
groupValues: {
type: String,
default: null
},
height: {
type: String,
default: "550px"
},
groupExtraValues: {
type: String,
default: null
},
groupHeader: {
type: String,
default: null
},
pagination: {
type: Object,
default: null
},
selectOption: {
type: String,
default: null
},
filterData: {
type: String,
default: null
},
withTablefy: {
type: Boolean,
default: true
}
},
data() {
return {
refId: Math.random().toString(36).slice(4),
}
},
computed: {
data () {
if (!is(Array, this.dataSource)) return []
if (this.withTablefy) return tablefy(this.dataSource)
return this.dataSource
}
},
mounted() {
this.makeTable()
},
updated() {
this.makeTable()
},
methods: {
makeTable () {
this.table = new Tabulator(this.$refs[this.refId], this.getConfig())
},
getConfig () {
let configurator = pipe(this.__defaultCfg());
return configurator(
(x) => mergeDeepRight(x, this.__getColsCfg()),
(x) => mergeDeepRight(x, this.__getSortCfg()),
(x) => mergeDeepRight(x, this.__getGroupCfg()),
(x) => mergeDeepRight(x, this.__getGroupHeaderCfg()),
// (x) => mergeAll(x, this.__getPaginationCgs())
);
},
__defaultCfg () {
return {
locale: "ru",
langs: localization(),
height: this.height || "250px",
responsiveLayout: "collapse",
placeholder: "Нет записей",
movableColumns: true,
autoResize: false,
data: this.data,
groupStartOpen: false,
groupHeader: function (value, count) {
return value + "<span>(" + count + " записей)</span>";
},
};
},
__getColsCfg() {
let layout, columns = []
if (this.autoColumns && is(Object, this.data[0])) {
let first = this.data[0];
let keys = Object.keys(first).map((key) => ({
headerFilter: "input",
headerFilterPlaceholder: key,
title: key,
field: key,
download: false,
print: false,
vertAlign: "middle",
sorter: "string",
responsive: 0,
minWidth: 80,
maxWidth: 300,
}));
layout = "fitDataFill"
columns = sort(sorter, keys)
} else {
layout = "fitDataStretch"
columns = prepColumns(this.columns)
}
if (this.withTablefy) {
columns = tablefy(columns)
}
return {columns, layout}
},
__getSortCfg() {
if (this.initialSort) return { initialSort: this.initialSort };
return {};
},
__getGroupCfg() {
if (this.groupByTemplate)
return { groupBy: groupByFunction(this.groupByTemplate) };
if (this.groupBy) return { groupBy: this.groupBy };
return {};
},
__getGroupHeaderCfg() {
if (this.groupHeader)
return {
groupHeader: (value, count, data, group) =>
renderGroupHeader({
extra: this.groupExtraValues,
groupHeader: this.groupHeader,
value,
count,
data,
group,
}),
};
return {};
},
}
}
</script>
<template>
<div class="mb-4">
<div class="overflow-x-auto w-full">
<div
:ref="refId"
class="w-full"
/>
</div>
</div>
<div v-if="pagination">
<Pagination :params="pagination" />
</div>
</template>