UNPKG

quasar

Version:

Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time

275 lines (226 loc) 6.49 kB
import Vue from 'vue' import Top from './table-top.js' import TableHeader from './table-header.js' import TableBody from './table-body.js' import Bottom from './table-bottom.js' import TableGrid from './table-grid.js' import QVirtualScroll from '../virtual-scroll/QVirtualScroll.js' import { commonVirtPropsList } from '../../mixins/virtual-scroll.js' import getTableMiddle from './get-table-middle.js' import Sort from './table-sort.js' import Filter from './table-filter.js' import Pagination from './table-pagination.js' import RowSelection from './table-row-selection.js' import ColumnSelection from './table-column-selection.js' import FullscreenMixin from '../../mixins/fullscreen.js' const commonVirtPropsObj = {} commonVirtPropsList.forEach(p => { commonVirtPropsObj[p] = {} }) export default Vue.extend({ name: 'QTable', mixins: [ FullscreenMixin, Top, TableHeader, TableBody, Bottom, TableGrid, Sort, Filter, Pagination, RowSelection, ColumnSelection ], props: { data: { type: Array, default: () => [] }, rowKey: { type: String, default: 'id' }, columns: Array, loading: Boolean, binaryStateSort: Boolean, title: String, hideHeader: Boolean, hideBottom: Boolean, grid: Boolean, gridHeader: Boolean, dense: Boolean, flat: Boolean, bordered: Boolean, square: Boolean, separator: { type: String, default: 'horizontal', validator: v => ['horizontal', 'vertical', 'cell', 'none'].includes(v) }, wrapCells: Boolean, virtualScroll: Boolean, ...commonVirtPropsObj, noDataLabel: String, noResultsLabel: String, loadingLabel: String, selectedRowsLabel: Function, rowsPerPageLabel: String, paginationLabel: Function, color: { type: String, default: 'grey-8' }, tableStyle: [String, Array, Object], tableClass: [String, Array, Object], tableHeaderStyle: [String, Array, Object], tableHeaderClass: [String, Array, Object], cardStyle: [String, Array, Object], cardClass: [String, Array, Object], dark: Boolean }, data () { return { rowsExpanded: {}, innerPagination: { sortBy: null, descending: false, page: 1, rowsPerPage: 5 } } }, watch: { needsReset () { this.hasVirtScroll === true && this.$refs.virtScroll.reset() } }, computed: { hasVirtScroll () { return this.grid !== true && this.virtualScroll === true }, needsReset () { return ['tableStyle', 'tableClass', 'tableHeaderStyle', 'tableHeaderClass', 'containerClass'] .map(p => this[p]).join(';') }, computedData () { let rows = this.data.slice().map((row, i) => { row.__index = i return row }) if (rows.length === 0) { return { rowsNumber: 0, rows: [] } } if (this.isServerSide === true) { return { rows } } const { sortBy, descending, rowsPerPage } = this.computedPagination if (this.filter) { rows = this.filterMethod(rows, this.filter, this.computedCols, this.getCellValue) } if (this.columnToSort) { rows = this.sortMethod(rows, sortBy, descending) } const rowsNumber = rows.length if (rowsPerPage) { rows = rows.slice(this.firstRowIndex, this.lastRowIndex) } return { rowsNumber, rows } }, computedRows () { return this.computedData.rows }, computedRowsNumber () { return this.isServerSide === true ? this.computedPagination.rowsNumber || 0 : this.computedData.rowsNumber }, nothingToDisplay () { return this.computedRows.length === 0 }, isServerSide () { return this.computedPagination.rowsNumber !== void 0 }, cardDefaultClass () { return ` q-table__card` + (this.dark === true ? ' q-table__card--dark' : '') + (this.square === true ? ` q-table--square` : '') + (this.flat === true ? ` q-table--flat` : '') + (this.bordered === true ? ` q-table--bordered` : '') }, containerClass () { return `q-table__container q-table--${this.separator}-separator` + (this.grid === true ? ' q-table--grid' : this.cardDefaultClass) + (this.dark === true ? ` q-table--dark` : '') + (this.dense === true ? ` q-table--dense` : '') + (this.wrapCells === false ? ` q-table--no-wrap` : '') + (this.inFullscreen === true ? ` fullscreen scroll` : '') }, virtProps () { const props = {} commonVirtPropsList .forEach(p => { props[p] = this[p] }) if (props.virtualScrollItemSize === void 0) { props.virtualScrollItemSize = this.dense === true ? 28 : 48 } return props } }, render (h) { const data = { staticClass: this.containerClass } if (this.grid === false) { data.class = this.cardClass data.style = this.cardStyle } return h('div', data, [ this.getTop(h), this.grid === true ? this.getGridHeader(h) : null, this.getBody(h), this.getBottom(h) ]) }, methods: { requestServerInteraction (prop = {}) { this.$nextTick(() => { this.$emit('request', { pagination: prop.pagination || this.computedPagination, filter: prop.filter || this.filter, getCellValue: this.getCellValue }) }) }, resetVirtualScroll () { this.hasVirtScroll === true && this.$refs.virtScroll.reset() }, getBody (h) { if (this.grid === true) { return this.getGridBody(h) } const header = this.hideHeader !== true ? this.getTableHeader(h) : null return this.hasVirtScroll === true ? h(QVirtualScroll, { ref: 'virtScroll', props: { ...this.virtProps, items: this.computedRows, type: '__qtable' }, class: this.tableClass, style: this.tableStyle, scopedSlots: { before: () => header, default: this.getTableRowVirtual(h) } }) : getTableMiddle(h, { staticClass: 'scroll', class: this.tableClass, style: this.tableStyle }, [ header, this.getTableBody(h) ]) } } })