UNPKG

hongluan-ui

Version:
508 lines (505 loc) 21.6 kB
import { defineComponent, ref, toRefs, computed, watch, onMounted, provide, resolveComponent, openBlock, createElementBlock, normalizeClass, createElementVNode, normalizeStyle, Fragment, renderList, withDirectives, renderSlot, createTextVNode, toDisplayString, createVNode, createBlock, withCtx, createCommentVNode, vShow } from 'vue'; import { cloneDeep, findLast } from 'lodash-unified'; import '../../../hooks/index.mjs'; import '../../virtual-list/index.mjs'; import SortableIcon from './sortable.mjs'; import FilterIcon from './filter.mjs'; import Cell from './body/cell.mjs'; import { virtualTableProps, simpleTableContextKey } from './simple-table2.mjs'; import './composables/index.mjs'; import { convertCols } from './utils.mjs'; import _export_sfc from '../../../_virtual/plugin-vue_export-helper.mjs'; import FixedSizeList from '../../virtual-list/src/components/fixed-size-list.mjs'; import { useLocale } from '../../../hooks/use-locale/index.mjs'; import { useNamespace } from '../../../hooks/use-namespace/index.mjs'; import { useExpand } from './composables/use-expand.mjs'; import { useTooltip } from './composables/use-tooltip.mjs'; import { useTree } from './composables/use-tree.mjs'; const _sfc_main = defineComponent({ name: "VirtualTable", components: { Cell, SortableIcon, FilterIcon, FixedSizeList }, props: virtualTableProps, emits: ["row-click", "cell-click", "sort-change", "expand", "tree-expand", "current-change", "item-rendered"], setup(props, { emit }) { const { t } = useLocale(); const { namespace: simpleTableNS } = useNamespace("simple-table"); const { namespace } = useNamespace("virtual-table"); const tableRef = ref(); const thRefs = ref([]); const tdWidths = ref([]); const currentSelectedRow = ref(null); const { expandRowKeys, defaultExpandAll, cols, data: realData } = toRefs(props); const realColsInfo = computed(() => convertCols(cloneDeep(cols.value))); const slotNames = computed(() => realColsInfo.value.realCols.filter((c) => c.slotName).map((c) => c.slotName)); const expandSlotNames = computed(() => realColsInfo.value.realCols.filter((c) => { var _a; return (_a = c.expand) == null ? void 0 : _a.slotName; }).map((c) => { var _a; return (_a = c.expand) == null ? void 0 : _a.slotName; })); const virtualTotal = computed(() => { var _a; return (_a = props.total) != null ? _a : realData.value ? realData.value.length : 0; }); const tableClass = computed(() => [ simpleTableNS.value, props.size, props.border, { "hover": props.hover, "list": props.list, "auto-height": props.autoHeight }, props.stripe == "even" ? "striped-even" : "", props.stripe == "odd" ? "striped-odd" : "", typeof props.stripe === "boolean" && props.stripe ? "striped-odd" : "" ]); const tableStyle = computed(() => [ props.padding ? `--table-padding: ${props.padding}` : "", props.cellPadding ? `--table-td-padding: ${props.cellPadding}` : "", props.gap ? `--table-gap: ${props.gap}` : "", props.gapX ? `--table-gap-x: ${props.gapX}` : "", props.gapY ? `--table-gap-y: ${props.gapY}` : "" ]); const { toggleExpandRow, expandedKeyExisted } = useExpand({ expandRowKeys, getRowKey, defaultExpandAll }); const { isShowTooltipMap, clearTooltip, tdMouseover, tdMouseleave } = useTooltip(realColsInfo); const { tableTreeMap, hasChildren, toggleExpandTree, walkTreeNode } = useTree({ load: props.load, treeProps: props.treeProps, getRowKey, expandRowKeys, defaultExpandAll }); function getRowKey(row) { const rowKey = props.rowKey; if (!row) throw new Error("Row is required when get row identity"); if (typeof rowKey === "string") { if (rowKey.indexOf(".") < 0) { return row[rowKey] + ""; } const key = rowKey.split("."); let current = row; for (let i = 0; i < key.length; i++) { current = current[key[i]]; } return current + ""; } else if (typeof rowKey === "function") { return rowKey.call(null, row); } } const isShowCol = (col) => { return !("$show$" in col) || col.$show$; }; const toggleColumn = (index, show) => { cols.value[index].$show$ = show != null ? show : !("$show$" in cols.value[index] ? cols.value[index].$show$ : true); }; const getColFixed = (col) => { var _a; const pos = (col2) => { var _a2; return typeof col2.fixed === "string" ? col2.fixed : (_a2 = col2.fixed) == null ? void 0 : _a2.position; }; const result = { hasShadow: false, position: pos(col), distance: typeof col.fixed === "string" ? 0 : (_a = col.fixed) == null ? void 0 : _a.distance }; if (result.position === "left") { result.hasShadow = findLast(realColsInfo.value.realCols, (c) => pos(c) === "left") === col; } else if (result.position === "right") { result.hasShadow = realColsInfo.value.realCols.find((c) => pos(c) === "right") === col; } return result; }; const getHeaderRowClass = ({ row, rowIndex }) => { return typeof props.headerRowClassName === "string" ? props.headerRowClassName : props.headerRowClassName({ row, rowIndex }); }; const getHeaderRowStyle = ({ row, rowIndex }) => { return typeof props.headerRowStyle === "function" ? props.headerRowStyle({ row, rowIndex }) : props.headerRowStyle; }; const getHeaderCellClass = ({ row, column, rowIndex, columnIndex }) => { return typeof props.headerCellClassName === "string" ? props.headerCellClassName : props.headerCellClassName({ row, column, rowIndex, columnIndex }); }; const getHeaderCellStyle = ({ row, column, rowIndex, columnIndex }) => { return typeof props.headerCellStyle === "function" ? props.headerCellStyle({ row, column, rowIndex, columnIndex }) : props.headerCellStyle; }; const rowClicked = (row, rowIndex, $event) => { if (props.highlightCurrentRow) { emit("current-change", row, cloneDeep(currentSelectedRow.value)); currentSelectedRow.value = currentSelectedRow.value === row ? null : row; } emit("row-click", row, rowIndex, $event); }; const setCurrentRow = (row) => { if (props.highlightCurrentRow) { emit("current-change", row, cloneDeep(currentSelectedRow.value)); currentSelectedRow.value = row != null ? row : null; } }; const getSpan = ({ row, column, rowIndex, columnIndex }) => { const span = { rowspan: 1, colspan: 1 }; if (props.spanMethod) { const result = props.spanMethod({ row, column, rowIndex, columnIndex }); if (Array.isArray(result)) { span.rowspan = result[0]; span.colspan = result[1]; } else if (typeof result === "object") { Object.assign(span, result); } } return span; }; const toggleExpandVirtualRow = (row, rowIndex, columnIndex, slotName) => { toggleExpandRow(row, slotName); if (expandedKeyExisted(row, slotName)) { for (let start = rowIndex + 1; start < realData.value.length; start++) { if (realData.value[start]["$type$"] !== "EXPANDED_ROW" || realData.value[start]["$type$"] === "TREE_ROW" || realData.value[start]["columnIndex"] > columnIndex) { realData.value.splice(start, 0, { "$type$": "EXPANDED_ROW", refRow: row, rowIndex, columnIndex, slotName }); break; } } } else { for (let start = rowIndex + 1; start < realData.value.length; start++) { if (realData.value[start]["$type$"] === "EXPANDED_ROW") { if (realData.value[start]["columnIndex"] === columnIndex) { realData.value.splice(start, 1); break; } } else break; } } }; const toggleExpandVirtualTree = async (row, rowIndex) => { var _a, _b; await toggleExpandTree(row); let start = rowIndex + 1; while (realData.value[start]["$type$"] === "EXPANDED_ROW") { start++; } const rowKey = getRowKey(row); const level = tableTreeMap.value[rowKey].level; if ((_a = tableTreeMap.value[rowKey]) == null ? void 0 : _a.expanded) { const children = (_b = row[props.treeProps.children]) != null ? _b : []; for (let i = children.length - 1; i >= 0; i--) { const child = children[i]; child["$type$"] = "TREE_ROW"; child["$level$"] = level + 1; realData.value.splice(start, 0, children[i]); } } else { let count = 0; for (let i = start; ; i++) { if (realData.value[i]["$type$"] !== "TREE_ROW") break; if (realData.value[i]["$level$"] <= level) break; count++; const treeRowKey = getRowKey(realData.value[i]); if (tableTreeMap.value[treeRowKey]) { tableTreeMap.value[treeRowKey].expanded = false; } } realData.value.splice(start, count); } }; watch(realData, () => { walkTreeNode(realData.value); }); onMounted(() => { walkTreeNode(realData.value); tdWidths.value = thRefs.value.map((thRef) => thRef.offsetWidth + "px"); }); provide(simpleTableContextKey, { isShowCol, getColFixed }); return { t, namespace, virtualTotal, tableStyle, tableClass, tableRef, thRefs, tdWidths, isShowCol, getColFixed, realColsInfo, slotNames, expandSlotNames, realData, getHeaderRowClass, getHeaderRowStyle, getHeaderCellClass, getHeaderCellStyle, setCurrentRow, toggleExpandVirtualRow, toggleExpandVirtualTree, rowClicked, toggleColumn, getRowKey, getSpan, expandedKeyExisted, isShowTooltipMap, tdMouseleave, tdMouseover, clearTooltip, currentSelectedRow, tableTreeMap, hasChildren }; } }); function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { var _a; const _component_sortable_icon = resolveComponent("sortable-icon"); const _component_filter_icon = resolveComponent("filter-icon"); const _component_cell = resolveComponent("cell"); const _component_fixed_size_list = resolveComponent("fixed-size-list"); return openBlock(), createElementBlock("div", { class: normalizeClass(_ctx.namespace) }, [ createElementVNode("table", { class: normalizeClass(["table-header", _ctx.tableClass]), style: normalizeStyle(_ctx.tableStyle) }, [ _ctx.showHeader ? (openBlock(), createElementBlock("thead", { key: 0, class: normalizeClass({ "fixed-top": true }) }, [ (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.realColsInfo.headerRows, (row, rowIndex) => { return openBlock(), createElementBlock("tr", { key: rowIndex, class: normalizeClass(_ctx.getHeaderRowClass({ row, rowIndex })), style: normalizeStyle(_ctx.getHeaderRowStyle({ row, rowIndex })) }, [ (openBlock(true), createElementBlock(Fragment, null, renderList(row, (column, columnIndex) => { var _a2; return withDirectives((openBlock(), createElementBlock("th", { ref_for: true, ref: (el) => _ctx.thRefs[columnIndex] = el, key: columnIndex, rowspan: column.rowSpan, colspan: column.colSpan, style: normalizeStyle([ { "width": column.width ? column.width : false, "min-width": column.width ? column.width : false, "max-width": column.width ? column.width : false, ..._ctx.getHeaderCellStyle({ row, column, rowIndex, columnIndex }) }, !!column.fixed && _ctx.getColFixed(column).distance ? "--table-fixed-distance:" + _ctx.getColFixed(column).distance : "" ]), class: normalizeClass([ { ["fixed-" + _ctx.getColFixed(column).position]: !!column.fixed, "show-shadow": _ctx.getColFixed(column).hasShadow }, _ctx.getHeaderCellClass({ row, column, rowIndex, columnIndex }) ]) }, [ column.headerSlotName ? (openBlock(), createElementBlock("div", { key: 0, class: "cell", style: normalizeStyle(column.align ? `justify-content:${column.align}` : "") }, [ renderSlot(_ctx.$slots, column.headerSlotName, { col: { ...column, columnIndex } }) ], 4)) : (openBlock(), createElementBlock("div", { key: 1, class: "cell", style: normalizeStyle(column.align ? `justify-content:${column.align}` : "") }, [ createTextVNode(toDisplayString(column.title) + " ", 1), createVNode(_component_sortable_icon, { sortable: column.sortable, onSortChange: (val) => _ctx.$emit("sort-change", column.prop, val) }, null, 8, ["sortable", "onSortChange"]), ((_a2 = column.filter) == null ? void 0 : _a2.slotName) ? (openBlock(), createBlock(_component_filter_icon, { key: 0, placement: column.filter.placement, effect: column.filter.effect, "popper-class": column.filter.popperClass, trigger: column.filter.trigger }, { default: withCtx(({ close }) => [ renderSlot(_ctx.$slots, column.filter.slotName, { close }) ]), _: 2 }, 1032, ["placement", "effect", "popper-class", "trigger"])) : createCommentVNode("v-if", true) ], 4)) ], 14, ["rowspan", "colspan"])), [ [vShow, _ctx.isShowCol(column)] ]); }), 128)) ], 6); }), 128)) ])) : createCommentVNode("v-if", true) ], 6), _ctx.data === null || _ctx.data === void 0 || _ctx.data.length === 0 ? (openBlock(), createElementBlock("table", { key: 0, class: normalizeClass(["table-body no-data", _ctx.tableClass]), style: normalizeStyle(_ctx.tableStyle) }, [ createElementVNode("tbody", null, [ ((_a = _ctx.data) == null ? void 0 : _a.length) === 0 ? (openBlock(), createElementBlock("tr", { key: 0, class: "empty-content" }, [ createElementVNode("td", { colspan: _ctx.realColsInfo.realCols.length }, [ renderSlot(_ctx.$slots, "empty", {}, () => [ createTextVNode(toDisplayString(_ctx.t("hl.simpletable.emptyText")), 1) ]) ], 8, ["colspan"]) ])) : createCommentVNode("v-if", true), _ctx.data === null || _ctx.data === void 0 ? (openBlock(), createElementBlock("tr", { key: 1, class: "unknown-content" }, [ createElementVNode("td", { colspan: _ctx.realColsInfo.realCols.length }, [ renderSlot(_ctx.$slots, "unknown") ], 8, ["colspan"]) ])) : createCommentVNode("v-if", true) ]) ], 6)) : (openBlock(), createBlock(_component_fixed_size_list, { key: 1, "class-name": ["table-body", ..._ctx.tableClass], style: normalizeStyle(_ctx.tableStyle), data: _ctx.realData, total: _ctx.virtualTotal, height: _ctx.height, "item-size": _ctx.itemSize, "perf-mode": true, "scrollbar-always-on": _ctx.scrollbarAlwaysOn, cache: _ctx.cache, "container-element": "table", "inner-element": "tbody", onItemRendered: (...args) => _ctx.$emit("item-rendered", ...args) }, { default: withCtx(({ data, index: rowIndex, style }) => [ !data[rowIndex] ? (openBlock(), createElementBlock("tr", { key: 0, class: "loading-row", style: normalizeStyle(style) }, [ createElementVNode("td", { colspan: _ctx.realColsInfo.realCols.length }, [ renderSlot(_ctx.$slots, "loading", { rowIndex }) ], 8, ["colspan"]) ], 4)) : data[rowIndex]["$type$"] === "EXPANDED_ROW" ? (openBlock(), createElementBlock("tr", { key: _ctx.getRowKey(data[rowIndex]["refRow"]) + data[rowIndex]["slotName"], class: normalizeClass(["expand-row", data[rowIndex]["slotName"]]), style: normalizeStyle(style), onClick: ($event) => _ctx.$emit("row-click", data[rowIndex], rowIndex, $event) }, [ createElementVNode("td", { colspan: _ctx.realColsInfo.realCols.length }, [ renderSlot(_ctx.$slots, data[rowIndex]["slotName"], { row: data[rowIndex]["refRow"] }) ], 8, ["colspan"]) ], 14, ["onClick"])) : (openBlock(), createElementBlock("tr", { key: _ctx.getRowKey(data[rowIndex]), class: normalizeClass([ typeof _ctx.rowClassName === "string" ? _ctx.rowClassName : _ctx.rowClassName({ row: data[rowIndex], rowIndex }), _ctx.currentSelectedRow === data[rowIndex] ? "current-row" : "" ]), style: normalizeStyle([ typeof _ctx.rowStyle === "function" ? _ctx.rowStyle({ row: data[rowIndex], rowIndex }) : _ctx.rowStyle, data[rowIndex]["$level$"] && `--tree-level:${data[rowIndex]["$level$"]}`, style ]), onClick: ($event) => _ctx.$emit("row-click", data[rowIndex], rowIndex, $event) }, [ (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.realColsInfo.realCols, (column, columnIndex) => { var _a2, _b, _c; return openBlock(), createBlock(_component_cell, { key: columnIndex, column, "column-index": columnIndex, row: data[rowIndex], "row-index": rowIndex, "cell-class-name": _ctx.cellClassName, "cell-style": _ctx.cellStyle, span: _ctx.getSpan({ row: data[rowIndex], column, rowIndex, columnIndex }), expanded: _ctx.expandedKeyExisted(data[rowIndex], (_a2 = column.expand) == null ? void 0 : _a2.slotName), "tree-expanded": (_b = _ctx.tableTreeMap[_ctx.getRowKey(data[rowIndex])]) == null ? void 0 : _b.expanded, "show-tooltip": column.showTooltip && _ctx.isShowTooltipMap[rowIndex + "/" + columnIndex], "has-children": _ctx.hasChildren(data[rowIndex]), "is-loading": (_c = _ctx.tableTreeMap[_ctx.getRowKey(data[rowIndex])]) == null ? void 0 : _c.isLoading, "first-column-index": _ctx.firstColumnIndex, width: _ctx.tdWidths[columnIndex], onCellClick: ($event) => _ctx.$emit("cell-click", data[rowIndex], column, rowIndex, columnIndex, $event), onExpand: ($event) => { var _a3; return _ctx.toggleExpandVirtualRow(data[rowIndex], rowIndex, columnIndex, (_a3 = column.expand) == null ? void 0 : _a3.slotName); }, onTreeExpand: ($event) => _ctx.toggleExpandVirtualTree(data[rowIndex], rowIndex), onMouseover: ($event) => _ctx.tdMouseover($event, rowIndex, columnIndex), onMouseleave: _ctx.tdMouseleave }, { default: withCtx(() => [ renderSlot(_ctx.$slots, column.slotName, { row: { ...data[rowIndex], rowIndex, columnIndex } }) ]), _: 2 }, 1032, ["column", "column-index", "row", "row-index", "cell-class-name", "cell-style", "span", "expanded", "tree-expanded", "show-tooltip", "has-children", "is-loading", "first-column-index", "width", "onCellClick", "onExpand", "onTreeExpand", "onMouseover", "onMouseleave"]); }), 128)) ], 14, ["onClick"])) ]), _: 3 }, 8, ["class-name", "style", "data", "total", "height", "item-size", "scrollbar-always-on", "cache", "onItemRendered"])), createElementVNode("table", { class: normalizeClass(["table-footer", _ctx.tableClass]), style: normalizeStyle(_ctx.tableStyle) }, [ createElementVNode("colgroup", null, [ (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.tdWidths, (w, idx) => { return openBlock(), createElementBlock("col", { key: idx, width: w }, null, 8, ["width"]); }), 128)) ]), createElementVNode("tfoot", null, [ renderSlot(_ctx.$slots, "foot") ]) ], 6) ], 2); } var VirtualTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]); export { VirtualTable as default }; //# sourceMappingURL=virtual-table.mjs.map