plus-pro-components
Version:
Page level components developed based on Element Plus.
514 lines (511 loc) • 21.3 kB
JavaScript
import { defineComponent, ref, shallowRef, reactive, watchEffect, computed, useSlots, provide, watch, unref, nextTick, onMounted, onBeforeUnmount, toRefs, openBlock, createElementBlock, createBlock, createSlots, withCtx, renderSlot, createCommentVNode, withDirectives, mergeProps, createVNode, createElementVNode, renderList, normalizeProps, guardReactiveProps, isRef } from 'vue';
import { PlusPagination } from '../../pagination/index.mjs';
import { PlusRadio } from '../../radio/index.mjs';
import '../../../constants/index.mjs';
import { ElTable, ElTableColumn, vLoading } from 'element-plus';
import { filterSlots, getTableCellSlotName, getTableHeaderSlotName, getFieldSlotName, getExtraSlotName } from '../../utils/index.mjs';
import { debounce, isEqual } from 'lodash-es';
import PlusTableActionBar from './table-action-bar.vue.mjs';
import PlusTableColumn from './table-column.vue.mjs';
import PlusTableTableColumnIndex from './table-column-index.vue.mjs';
import PlusTableColumnDragSort from './table-column-drag-sort.vue.mjs';
import PlusTableTitleBar from './table-title-bar.vue.mjs';
import { DefaultPageInfo } from '../../../constants/page.mjs';
import { TableFormRefInjectionKey, TableFormFieldRefInjectionKey } from '../../../constants/form.mjs';
import { isSVGElement, isPlainObject } from '../../utils/is.mjs';
const _hoisted_1 = { class: "plus-table-expand-col" };
var _sfc_main = /* @__PURE__ */ defineComponent({
...{
name: "PlusTable",
inheritAttrs: false
},
__name: "index",
props: {
tableData: { default: () => [] },
data: { default: () => [] },
columns: { default: () => [] },
defaultSize: { default: "default" },
pagination: { type: [Boolean, Object], default: false },
actionBar: { type: [Boolean, Object], default: false },
hasIndexColumn: { type: Boolean, default: false },
titleBar: { type: [Boolean, Object], default: true },
isSelection: { type: [Boolean, String], default: false },
isRadio: { type: Boolean, default: false },
hasExpand: { type: Boolean, default: false },
loadingStatus: { type: Boolean, default: false },
height: {},
headerCellStyle: { default: () => ({
"background-color": "var(--el-fill-color-light)"
}) },
rowKey: { type: [String, Function], default: "id" },
dragSortable: { type: [Boolean, Object], default: false },
dragSortableTableColumnProps: { default: () => ({}) },
indexTableColumnProps: { default: () => ({}) },
selectionTableColumnProps: { default: () => ({
width: 40
}) },
radioTableColumnProps: { default: () => ({
width: 50
}) },
radioProps: { default: void 0 },
defaultSelectedRadioRow: { default: void 0 },
expandTableColumnProps: { default: () => ({}) },
indexContentStyle: { type: [Object, Function], default: () => ({}) },
editable: { type: [Boolean, String], default: false },
adaptive: { type: [Boolean, Object], default: false },
filterTableHeaderOverflowLabelLength: {}
},
emits: ["paginationChange", "clickAction", "clickActionConfirmCancel", "dragSortEnd", "formChange", "refresh", "edited", "cell-click", "cell-dblclick", "filterTableHeader", "radioChange"],
setup(__props, { expose: __expose, emit: __emit }) {
var _a, _b;
const props = __props;
const emit = __emit;
const radioRow = ref();
const subColumns = ref([]);
const columnsIsChange = ref(false);
const filterColumns = ref([]);
const tableInstance = shallowRef(null);
const tableWrapperInstance = ref(null);
const paginationInstance = ref(null);
const state = reactive({
subPageInfo: {
...((_a = props.pagination) == null ? void 0 : _a.modelValue) || DefaultPageInfo
},
size: props.defaultSize
});
const cachedTableData = ref([]);
watchEffect(() => {
var _a2;
cachedTableData.value = ((_a2 = props.tableData) == null ? void 0 : _a2.length) ? props.tableData : props.data;
});
const __tableData = computed(() => cachedTableData.value);
const tableDataLength = computed(() => __tableData.value.length);
const hasAdaptive = computed(() => typeof props.height === "undefined" && props.adaptive);
const slots = useSlots();
const cellSlots = filterSlots(slots, getTableCellSlotName());
const headerSlots = filterSlots(slots, getTableHeaderSlotName());
const fieldSlots = filterSlots(slots, getFieldSlotName());
const extraSlots = filterSlots(slots, getExtraSlotName());
const formRefs = shallowRef({});
provide(TableFormRefInjectionKey, formRefs);
const formFieldRefs = shallowRef({});
provide(TableFormFieldRefInjectionKey, formFieldRefs);
watch(
() => props.columns,
(val) => {
const filterOriginColumns = val.filter((item) => unref(item.hideInTable) !== true);
filterColumns.value = filterOriginColumns.map((item) => {
var _a2;
return {
...item,
headerIsChecked: (_a2 = item.headerIsChecked) != null ? _a2 : true
};
});
subColumns.value = filterOriginColumns.filter((item) => unref(item.headerIsChecked) !== false);
columnsIsChange.value = !columnsIsChange.value;
},
{
immediate: true
}
);
watch(
() => props.defaultSelectedRadioRow,
(val) => {
radioRow.value = val ? unref(props.defaultSelectedRadioRow) : {};
},
{
immediate: true
}
);
const handlePaginationChange = () => {
emit("paginationChange", { ...state.subPageInfo });
};
const handleAction = (callbackParams) => {
emit("clickAction", callbackParams);
};
const handleClickActionConfirmCancel = (callbackParams) => {
emit("clickActionConfirmCancel", callbackParams);
};
const handleFilterTableConfirm = (_columns, eventType) => {
filterColumns.value = _columns;
emit("filterTableHeader", _columns, eventType);
subColumns.value = _columns.filter(
(item) => unref(item.hideInTable) !== true && item.headerIsChecked !== false
);
};
const handleClickDensity = (size2) => {
state.size = size2;
};
const handleDragSortEnd = (newIndex, oldIndex) => {
emit("dragSortEnd", newIndex, oldIndex);
};
const handleRefresh = () => {
emit("refresh");
};
const handleFormChange = (data) => {
emit("formChange", data);
};
const handleRadioChange = (value, row, index) => {
radioRow.value = value ? row : {};
emit("radioChange", row, index, !!value);
};
const currentForm = ref();
const handleCellEdit = (row, column, type) => {
var _a2;
const rowIndex = __tableData.value.indexOf(row);
const columnIndex = column.getColumnIndex();
const columnConfig = subColumns.value[columnIndex];
if (!columnConfig) return;
if (props.editable === type) {
const currentCellForm = formRefs.value[rowIndex][columnIndex];
if (!currentCellForm) return;
document.addEventListener("click", handleStopEditClick);
if (currentForm.value) {
(_a2 = currentForm.value) == null ? void 0 : _a2.stopCellEdit();
}
currentForm.value = currentCellForm;
currentCellForm.startCellEdit();
const unwatch = watch(
() => formFieldRefs.value.valueIsReady,
(val) => {
var _a3, _b2;
if ((val == null ? void 0 : val.value) && ((_b2 = (_a3 = formFieldRefs.value) == null ? void 0 : _a3.fieldInstance) == null ? void 0 : _b2.focus) && (props.editable === "click" || props.editable === "dblclick")) {
formFieldRefs.value.fieldInstance.focus();
unwatch();
}
}
);
}
};
const handleClickCell = (row, column, cell, event) => {
handleCellEdit(row, column, "click");
emit("cell-click", row, column, cell, event);
};
const handleDoubleClickCell = (row, column, cell, event) => {
handleCellEdit(row, column, "dblclick");
emit("cell-dblclick", row, column, cell, event);
};
const handleStopEditClick = (e) => {
var _a2, _b2;
if (tableWrapperInstance.value && currentForm.value) {
const target = e == null ? void 0 : e.target;
if (target.classList.contains("el-icon")) {
return;
}
const contains = (_a2 = tableWrapperInstance.value) == null ? void 0 : _a2.contains(target);
if (!contains && !isSVGElement(target)) {
(_b2 = currentForm.value) == null ? void 0 : _b2.stopCellEdit();
emit("edited");
document.removeEventListener("click", handleStopEditClick);
}
}
};
const setAdaptive = async () => {
var _a2;
await nextTick();
if (!tableInstance.value) return;
const tableWrapper = tableInstance.value.$el;
let offsetBottom = 20;
let paginationHeight = 0;
if (isPlainObject(props.adaptive)) {
offsetBottom = (_a2 = props.adaptive.offsetBottom) != null ? _a2 : offsetBottom;
}
if (paginationInstance.value && props.pagination) {
paginationHeight = paginationInstance.value.$el.offsetHeight;
}
tableWrapper.style.height = `${window.innerHeight - tableWrapper.getBoundingClientRect().top - offsetBottom - paginationHeight}px`;
};
const debounceSetAdaptive = debounce(
setAdaptive,
isPlainObject(props.adaptive) ? (_b = props.adaptive.timeout) != null ? _b : 60 : 60
);
onMounted(() => {
if (hasAdaptive.value) {
setAdaptive();
window.addEventListener("resize", debounceSetAdaptive);
}
});
onBeforeUnmount(() => {
if (hasAdaptive.value) {
window.removeEventListener("resize", debounceSetAdaptive);
}
});
const { subPageInfo, size } = toRefs(state);
__expose({
formRefs,
tableInstance
});
return (_ctx, _cache) => {
return openBlock(), createElementBlock(
"div",
{
ref_key: "tableWrapperInstance",
ref: tableWrapperInstance,
class: "plus-table"
},
[
_ctx.titleBar ? (openBlock(), createBlock(PlusTableTitleBar, {
key: 0,
columns: filterColumns.value,
"default-size": unref(size),
"columns-is-change": columnsIsChange.value,
"title-bar": _ctx.titleBar,
onClickDensity: handleClickDensity,
onFilterTableHeader: handleFilterTableConfirm,
onRefresh: handleRefresh
}, createSlots({
title: withCtx(() => [
renderSlot(_ctx.$slots, "title")
]),
toolbar: withCtx(() => [
renderSlot(_ctx.$slots, "toolbar")
]),
_: 2
/* DYNAMIC */
}, [
_ctx.$slots["drag-sort-icon"] ? {
name: "drag-sort-icon",
fn: withCtx(() => [
renderSlot(_ctx.$slots, "drag-sort-icon")
]),
key: "0"
} : void 0,
_ctx.$slots["column-settings-icon"] ? {
name: "column-settings-icon",
fn: withCtx(() => [
renderSlot(_ctx.$slots, "column-settings-icon")
]),
key: "1"
} : void 0,
_ctx.$slots["density-icon"] ? {
name: "density-icon",
fn: withCtx(() => [
renderSlot(_ctx.$slots, "density-icon")
]),
key: "2"
} : void 0
]), 1032, ["columns", "default-size", "columns-is-change", "title-bar"])) : createCommentVNode("v-if", true),
withDirectives((openBlock(), createBlock(unref(ElTable), mergeProps({
ref_key: "tableInstance",
ref: tableInstance,
"reserve-selection": true,
data: __tableData.value,
border: true,
height: _ctx.height,
"header-cell-style": _ctx.headerCellStyle,
size: unref(size),
"row-key": _ctx.rowKey,
"highlight-current-row": "",
"scrollbar-always-on": ""
}, _ctx.$attrs, {
onCellClick: handleClickCell,
onCellDblclick: handleDoubleClickCell
}), {
default: withCtx(() => {
var _a2;
return [
createCommentVNode(" \u5355\u9009\u9009\u62E9\u680F "),
_ctx.isRadio ? (openBlock(), createBlock(
unref(ElTableColumn),
mergeProps({ key: "radio-selection" }, _ctx.radioTableColumnProps),
{
default: withCtx((scoped) => [
createVNode(unref(PlusRadio), mergeProps({
"model-value": unref(isEqual)(radioRow.value, scoped.row),
options: [{ value: true }]
}, _ctx.radioProps, {
onChange: (value) => handleRadioChange(value, scoped.row, scoped.$index)
}), null, 16, ["model-value", "onChange"])
]),
_: 1
/* STABLE */
},
16
/* FULL_PROPS */
)) : createCommentVNode("v-if", true),
createCommentVNode(" \u591A\u9009\u9009\u62E9\u680F "),
_ctx.isSelection ? (openBlock(), createBlock(
unref(ElTableColumn),
mergeProps({
key: "selection",
type: "selection"
}, _ctx.selectionTableColumnProps),
null,
16
/* FULL_PROPS */
)) : createCommentVNode("v-if", true),
createCommentVNode(" \u5E8F\u53F7\u680F "),
_ctx.hasIndexColumn ? (openBlock(), createBlock(PlusTableTableColumnIndex, {
key: 2,
"index-content-style": _ctx.indexContentStyle,
"index-table-column-props": _ctx.indexTableColumnProps,
"page-info": (_a2 = _ctx.pagination) == null ? void 0 : _a2.modelValue
}, null, 8, ["index-content-style", "index-table-column-props", "page-info"])) : createCommentVNode("v-if", true),
createCommentVNode(" \u62D6\u62FD\u884C "),
_ctx.dragSortable ? (openBlock(), createBlock(PlusTableColumnDragSort, {
key: 3,
sortable: _ctx.dragSortable,
"drag-sortable-table-column-props": _ctx.dragSortableTableColumnProps,
"table-instance": tableInstance.value,
onDragSortEnd: handleDragSortEnd
}, createSlots({
_: 2
/* DYNAMIC */
}, [
_ctx.$slots["drag-sort-icon"] ? {
name: "drag-sort-icon",
fn: withCtx(() => [
renderSlot(_ctx.$slots, "drag-sort-icon")
]),
key: "0"
} : void 0
]), 1032, ["sortable", "drag-sortable-table-column-props", "table-instance"])) : createCommentVNode("v-if", true),
createCommentVNode(" \u5C55\u5F00\u884C "),
_ctx.hasExpand ? (openBlock(), createBlock(
unref(ElTableColumn),
mergeProps({
key: 4,
type: "expand"
}, _ctx.expandTableColumnProps),
{
default: withCtx((scoped) => [
createElementVNode("div", _hoisted_1, [
renderSlot(_ctx.$slots, "expand", mergeProps({
index: scoped.$index
}, scoped))
])
]),
_: 3
/* FORWARDED */
},
16
/* FULL_PROPS */
)) : createCommentVNode("v-if", true),
renderSlot(_ctx.$slots, "default", {}, () => [
createCommentVNode("\u914D\u7F6E\u6E32\u67D3\u680F "),
createVNode(PlusTableColumn, {
columns: subColumns.value,
editable: _ctx.editable,
"table-data-length": tableDataLength.value,
onFormChange: handleFormChange
}, createSlots({
_: 2
/* DYNAMIC */
}, [
renderList(unref(headerSlots), (_, key) => {
return {
name: key,
fn: withCtx((data) => [
renderSlot(_ctx.$slots, key, normalizeProps(guardReactiveProps(data)))
])
};
}),
renderList(unref(cellSlots), (_, key) => {
return {
name: key,
fn: withCtx((data) => [
renderSlot(_ctx.$slots, key, normalizeProps(guardReactiveProps(data)))
])
};
}),
renderList(unref(fieldSlots), (_, key) => {
return {
name: key,
fn: withCtx((data) => [
renderSlot(_ctx.$slots, key, normalizeProps(guardReactiveProps(data)))
])
};
}),
renderList(unref(extraSlots), (_, key) => {
return {
name: key,
fn: withCtx((data) => [
renderSlot(_ctx.$slots, key, normalizeProps(guardReactiveProps(data)))
])
};
}),
_ctx.$slots["tooltip-icon"] ? {
name: "tooltip-icon",
fn: withCtx(() => [
renderSlot(_ctx.$slots, "tooltip-icon")
]),
key: "0"
} : void 0,
_ctx.$slots["edit-icon"] ? {
name: "edit-icon",
fn: withCtx(() => [
renderSlot(_ctx.$slots, "edit-icon")
]),
key: "1"
} : void 0
]), 1032, ["columns", "editable", "table-data-length"])
]),
createCommentVNode(" \u64CD\u4F5C\u680F "),
_ctx.actionBar ? (openBlock(), createBlock(
PlusTableActionBar,
mergeProps({ key: 5 }, _ctx.actionBar, {
onClickAction: handleAction,
onClickActionConfirmCancel: handleClickActionConfirmCancel
}),
createSlots({
_: 2
/* DYNAMIC */
}, [
_ctx.$slots["action-bar-more-icon"] ? {
name: "action-bar-more-icon",
fn: withCtx(() => [
renderSlot(_ctx.$slots, "action-bar-more-icon")
]),
key: "0"
} : void 0
]),
1040
/* FULL_PROPS, DYNAMIC_SLOTS */
)) : createCommentVNode("v-if", true)
];
}),
append: withCtx(() => [
renderSlot(_ctx.$slots, "append")
]),
empty: withCtx(() => [
renderSlot(_ctx.$slots, "empty")
]),
_: 3
/* FORWARDED */
}, 16, ["data", "height", "header-cell-style", "size", "row-key"])), [
[unref(vLoading), _ctx.loadingStatus]
]),
createCommentVNode(" \u5206\u9875 "),
_ctx.pagination ? (openBlock(), createBlock(unref(PlusPagination), mergeProps({
key: 1,
ref_key: "paginationInstance",
ref: paginationInstance,
modelValue: unref(subPageInfo),
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isRef(subPageInfo) ? subPageInfo.value = $event : null)
}, _ctx.pagination, { onChange: handlePaginationChange }), createSlots({
_: 2
/* DYNAMIC */
}, [
_ctx.$slots["pagination-left"] ? {
name: "pagination-left",
fn: withCtx(() => [
renderSlot(_ctx.$slots, "pagination-left")
]),
key: "0"
} : void 0,
_ctx.$slots["pagination-right"] ? {
name: "pagination-right",
fn: withCtx(() => [
renderSlot(_ctx.$slots, "pagination-right")
]),
key: "1"
} : void 0
]), 1040, ["modelValue"])) : createCommentVNode("v-if", true)
],
512
/* NEED_PATCH */
);
};
}
});
export { _sfc_main as default };