UNPKG

yhui-yuanhuan

Version:

A Component Library for Vue 3 based on element-plus

610 lines (605 loc) 27.5 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); var lodashUnified = require('lodash-unified'); var elementPlus = require('element-plus'); var iconsVue = require('@element-plus/icons-vue'); var index = require('../../dialog/index.js'); var setting = require('./setting.js'); var pluginVue_exportHelper = require('../../../_virtual/plugin-vue_export-helper.js'); var useComponents = require('../../../utils/useComponents.js'); const __default__ = vue.defineComponent({ name: "YhTable" }); const _sfc_main = /* @__PURE__ */ vue.defineComponent({ ...__default__, props: { actionsColumnProps: null, api: null, components: null, dialogProps: null, EntityClass: null, hideList: { default: () => [] }, id: { default: () => `table-only-one` }, router: null, pages: null, pageParam: { default: () => ({ page: 1, size: 10, total: 0 }) }, pageProps: null, permissions: null, permissionValidate: { type: Function, default: () => true }, search: null, searchDefault: { type: Function, default: () => ({}) }, searchFormProps: null, searchParam: { default: () => ({}) }, searchResultKey: { default: "data.data.list" }, searchResultTotalKey: { default: "data.data.total" }, searchSetting: null, settingStorageKey: null, tableData: null, tableProps: null, unfoldActions: { type: Boolean } }, emits: ["update:pageParam", "update:searchParam", "update:tableData", "confirm"], setup(__props, { expose, emit }) { var _a, _b, _c; const props = __props; const slots = vue.useSlots(); if (props.settingStorageKey) setting.SettingData.key = props.settingStorageKey; const tableRef = vue.ref(); function isShow(name) { var _a2; return !((_a2 = props.hideList) == null ? void 0 : _a2.includes(name)); } function isSpecialType(type) { return ["selection", "index"].includes(type); } const searchFormRef = vue.ref(); const defaultSearchSetting = { searchIcon: iconsVue.Search, searchText: "\u67E5\u8BE2", resetIcon: iconsVue.Refresh, resetText: "\u91CD\u7F6E" }; const combinedSearchingSetting = { ...defaultSearchSetting, ...props.searchSetting }; const refSearch = vue.ref(); const completeSearchItem = () => { var _a2, _b2, _c2; const length = ((_b2 = (_a2 = refSearch.value) == null ? void 0 : _a2.children) == null ? void 0 : _b2.length) || 0; const needAdd = length % 3; for (let i = 0; i < 3 - needAdd; i++) { (_c2 = refSearch.value) == null ? void 0 : _c2.appendChild(document.createElement("div")); } }; const isSearching = vue.ref(false); const doSearch = async () => { var _a2; isSearching.value = true; try { const res = await ((_a2 = props.search) == null ? void 0 : _a2.call(props, props.pageParam, true)); let list = lodashUnified.get(res, props.searchResultKey); const total = lodashUnified.get(res, props.searchResultTotalKey); if (props.EntityClass) list = list.map((it) => new props.EntityClass(it)); emit("update:tableData", list); if (isShow("searchButton")) { emit("update:pageParam", { ...props.pageParam, total }); } } catch (error) { console.log(error); isSearching.value = false; } isSearching.value = false; }; const handleSizeChange = (size) => { emit("update:pageParam", { ...props.pageParam, page: 1, size }); doSearch(); }; const handleCurrentChange = (page) => { emit("update:pageParam", { ...props.pageParam, page }); doSearch(); }; const handleClickSearch = () => { emit("update:pageParam", { ...props.pageParam, page: 1 }); doSearch(); }; const resetSearch = () => { emit("update:searchParam", props.searchDefault()); doSearch(); }; const slotItems4table = vue.computed(() => { var _a2; return ((_a2 = slots == null ? void 0 : slots.table) == null ? void 0 : _a2.call(slots)) || []; }); const settingData = vue.ref(initSettingData()); const settingButtonRef = vue.ref(); const settingPopoverRef = vue.ref(); const treeRef = vue.ref(); const isSettingPopoverVisible = vue.ref(false); function initSettingData() { const id = props.id; const slotItems = slotItems4table.value; const setting$1 = setting.SettingData.getInstance({ id, slotItems }); setting$1.watch(); return setting$1; } const tableChildren = vue.computed(() => { var _a2; if (!settingData.value) return; const propsInSetting = (_a2 = settingData.value) == null ? void 0 : _a2.columns.map((column) => column.prop); const res = settingData.value.purifiedSlotItems.filter((it) => { var _a3, _b2, _c2, _d; if (!propsInSetting) return true; const isInSettings = propsInSetting.includes((_a3 = it.props) == null ? void 0 : _a3.prop); const isActions = ((_b2 = it.props) == null ? void 0 : _b2.prop) === setting.actionsColumnProp; const isChecked = (_d = (_c2 = settingData.value) == null ? void 0 : _c2.columns.find((column) => { var _a4; return column.prop === ((_a4 = it.props) == null ? void 0 : _a4.prop); })) == null ? void 0 : _d.checked; return isInSettings && !isActions && isChecked; }).sort((a, b) => settingData.value.columns.findIndex((it) => { var _a3; return it.prop === ((_a3 = a.props) == null ? void 0 : _a3.prop); }) - settingData.value.columns.findIndex((it) => { var _a3; return it.prop === ((_a3 = b.props) == null ? void 0 : _a3.prop); })); return res; }); const hideSettings = () => { var _a2, _b2, _c2; (_c2 = (_b2 = (_a2 = settingPopoverRef == null ? void 0 : settingPopoverRef.value) == null ? void 0 : _a2.popperRef) == null ? void 0 : _b2["delayHide"]) == null ? void 0 : _c2.call(_b2); }; function isAllowDrag(data) { if (isSpecialType(data.type)) return false; return true; } function allowDrag(node) { return isAllowDrag(node.data); } function allowDrop(draggingNode, dropNode, type) { if (type === "inner") return false; if (isSpecialType(dropNode.data.type)) return false; return true; } function clearStorage() { useComponents.useHint("\u786E\u8BA4\u6062\u590D\u9ED8\u8BA4\u8BBE\u7F6E\uFF1F", async () => { settingData.value.clear(); elementPlus.ElMessage.success("\u5DF2\u6062\u590D\u9ED8\u8BA4\u8BBE\u7F6E"); }); } const actions = [ { key: "view", component: (_a = props == null ? void 0 : props.components) == null ? void 0 : _a.View, text: "\u67E5\u770B" }, { key: "edit", component: (_b = props == null ? void 0 : props.components) == null ? void 0 : _b.Edit, text: "\u7F16\u8F91" }, { key: "new", component: (_c = props == null ? void 0 : props.components) == null ? void 0 : _c.Edit, text: "\u65B0\u589E" } ]; const action = vue.ref("view"); const actionText = vue.computed(() => { var _a2; return (_a2 = actions.find((it) => it.key === action.value)) == null ? void 0 : _a2.text; }); const actionRow = vue.ref(); const isShowDetailDialog = vue.ref(false); const showDetailDialog = (type) => { var _a2; if (props.components) { isShowDetailDialog.value = true; } else if (props.pages) { if (typeof ((_a2 = props.router) == null ? void 0 : _a2.push) !== "function") return; props.router.push({ name: props.pages[type], params: type !== "add" ? { id: actionRow.value.id } : void 0 }); } else { throw new Error("action pages or components needed"); } }; const viewRow = (row) => { action.value = "view"; actionRow.value = row; showDetailDialog("view"); }; const add = () => { action.value = "new"; actionRow.value = props.EntityClass ? new props.EntityClass() : {}; showDetailDialog("add"); }; const onClickMenuItem = ({ row, command }) => { var _a2, _b2; action.value = typeof command === "string" ? command : "other"; actionRow.value = row; if (command === "edit") { showDetailDialog("edit"); } else if (command === "delete") { (_b2 = (_a2 = props.api) == null ? void 0 : _a2.del) == null ? void 0 : _b2.call(_a2); } }; const refContent = vue.ref(); const onDialogConfirm = async (p) => { var _a2, _b2, _c2, _d; if (p.type === "ok" || p.type === "publish") { try { const isPass = ((_a2 = refContent.value) == null ? void 0 : _a2["validate"]) ? await ((_c2 = (_b2 = refContent.value) == null ? void 0 : _b2["validate"]) == null ? void 0 : _c2.call(_b2)) : true; if (!isPass) { p.done(false); return; } } catch (error) { console.log("validate errors:", error); p.done(false); return; } } emit("confirm", { ...p, data: (_d = refContent.value) == null ? void 0 : _d.detail }); }; if (props.search) { doSearch(); } vue.onMounted(() => { completeSearchItem(); }); expose({ actionRow, doSearch, tableRef, searchFormRef }); return (_ctx, _cache) => { var _a2; const _component_ElCheckbox = vue.resolveComponent("ElCheckbox"); return vue.openBlock(), vue.createElementBlock("div", { class: "yh-table" }, [ vue.createElementVNode("div", { class: "yh-table-container" }, [ isShow("search") ? (vue.openBlock(), vue.createElementBlock("div", { key: 0, ref_key: "refSearch", ref: refSearch, class: "search" }, [ vue.createVNode(vue.unref(elementPlus.ElForm), vue.mergeProps({ ref_key: "searchFormRef", ref: searchFormRef, model: __props.searchParam, inline: "" }, __props.searchFormProps), { default: vue.withCtx(() => [ vue.createElementVNode("div", { class: "search-form" }, [ vue.renderSlot(_ctx.$slots, "search"), isShow("resetButton") ? (vue.openBlock(), vue.createElementBlock("div", { key: 0, class: "search-buttons" }, [ isShow("searchButton") ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [ vue.createVNode(vue.unref(elementPlus.ElButton), { type: "primary", loading: isSearching.value, icon: combinedSearchingSetting.searchIcon, onClick: handleClickSearch }, { default: vue.withCtx(() => [ vue.createTextVNode(vue.toDisplayString(combinedSearchingSetting.searchText), 1) ]), _: 1 }, 8, ["loading", "icon"]), vue.createVNode(vue.unref(elementPlus.ElButton), { icon: combinedSearchingSetting.resetIcon, onClick: resetSearch }, { default: vue.withCtx(() => [ vue.createTextVNode(vue.toDisplayString(combinedSearchingSetting.resetText), 1) ]), _: 1 }, 8, ["icon"]) ], 64)) : vue.createCommentVNode("v-if", true) ])) : vue.createCommentVNode("v-if", true), vue.renderSlot(_ctx.$slots, "searchButtons") ]) ]), _: 3 }, 16, ["model"]) ], 512)) : vue.createCommentVNode("v-if", true), vue.createElementVNode("div", { class: "table" }, [ vue.createElementVNode("div", { class: "actions-bar" }, [ isShow("addButton") && __props.permissionValidate((_a2 = __props.permissions) == null ? void 0 : _a2.add) ? (vue.openBlock(), vue.createBlock(vue.unref(elementPlus.ElButton), { key: 0, type: "primary", icon: vue.unref(iconsVue.Plus), onClick: add }, { default: vue.withCtx(() => [ vue.createTextVNode(" \u65B0\u589E ") ]), _: 1 }, 8, ["icon"])) : vue.createCommentVNode("v-if", true) ]), isShow("setting") ? (vue.openBlock(), vue.createElementBlock("div", { key: 0, class: vue.normalizeClass(["setting", { "popover-visible": isSettingPopoverVisible.value }]) }, [ vue.createVNode(vue.unref(elementPlus.ElPopover), { ref_key: "settingPopoverRef", ref: settingPopoverRef, visible: isSettingPopoverVisible.value, "onUpdate:visible": ($event) => isSettingPopoverVisible.value = $event, class: "setting-popover", "virtual-ref": settingButtonRef.value, trigger: "click", width: "auto", placement: "left-start", "append-to-body": "" }, { reference: vue.withCtx(() => { var _a3, _b2; return [ isShow("settingButton") && ((_b2 = __props.permissionValidate) == null ? void 0 : _b2.call(__props, (_a3 = __props.permissions) == null ? void 0 : _a3.add)) ? (vue.openBlock(), vue.createBlock(vue.unref(elementPlus.ElButton), { key: 0, ref_key: "settingButtonRef", ref: settingButtonRef, class: "setting-button", icon: vue.unref(iconsVue.Setting), style: { "width": "32px" }, onVClickOutside: hideSettings }, null, 8, ["icon"])) : vue.createCommentVNode("v-if", true) ]; }), default: vue.withCtx(() => { var _a3; return [ vue.createVNode(vue.unref(elementPlus.ElButton), { size: "small", text: "", onClick: clearStorage }, { default: vue.withCtx(() => [ vue.createVNode(vue.unref(elementPlus.ElIcon), { size: "12", style: { "margin-right": "4px" } }, { default: vue.withCtx(() => [ vue.createVNode(vue.unref(iconsVue.RefreshLeft)) ]), _: 1 }), vue.createElementVNode("span", null, "\u6062\u590D\u9ED8\u8BA4") ]), _: 1 }), vue.createVNode(vue.unref(elementPlus.ElTree), { ref_key: "treeRef", ref: treeRef, class: "yh-table-setting-tree", "allow-drag": allowDrag, "allow-drop": allowDrop, data: (_a3 = settingData.value) == null ? void 0 : _a3.columns, draggable: "", "default-expand-all": "", "node-key": "prop" }, { default: vue.withCtx(({ data }) => [ vue.createElementVNode("div", { class: vue.normalizeClass(["yh-drag", { disabled: !isAllowDrag(data) }]) }, [ vue.createVNode(vue.unref(elementPlus.ElIcon), { size: "12", color: "#333", style: vue.normalizeStyle([{ "margin-right": "20px" }, { opacity: !isAllowDrag(data) ? "0" : "1" }]) }, { default: vue.withCtx(() => [ vue.createVNode(vue.unref(iconsVue.Grid)) ]), _: 2 }, 1032, ["style"]), vue.createVNode(_component_ElCheckbox, { modelValue: data.checked, "onUpdate:modelValue": ($event) => data.checked = $event, class: "yh-check", label: data.label, disabled: isSpecialType(data.type) || data.disabled }, null, 8, ["modelValue", "onUpdate:modelValue", "label", "disabled"]) ], 2) ]), _: 1 }, 8, ["data"]) ]; }), _: 1 }, 8, ["visible", "onUpdate:visible", "virtual-ref"]) ], 2)) : vue.createCommentVNode("v-if", true), vue.withDirectives(vue.createVNode(vue.unref(elementPlus.ElSkeleton), { rows: 4, animated: "" }, null, 512), [ [vue.vShow, isShow("searching") ? isSearching.value : false] ]), vue.withDirectives(vue.createVNode(vue.unref(elementPlus.ElTable), vue.mergeProps({ ref_key: "tableRef", ref: tableRef, data: __props.tableData, stripe: true, border: true, "show-overflow-tooltip": true }, __props.tableProps, { "allow-drag-last-column": false }), { default: vue.withCtx(() => [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(tableChildren), (column, i) => { return vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(column), { key: i }); }), 128)), isShow("actionsColumn") ? (vue.openBlock(), vue.createBlock(vue.unref(elementPlus.ElTableColumn), vue.mergeProps({ key: 0, prop: vue.unref(setting.actionsColumnProp), label: "\u64CD\u4F5C", fixed: "right" }, __props.actionsColumnProps), { default: vue.withCtx(({ row }) => [ vue.createElementVNode("div", { class: "item-actions" }, [ isShow("viewButton") ? (vue.openBlock(), vue.createBlock(vue.unref(elementPlus.ElButton), { key: 0, type: "primary", link: "", onClick: ($event) => viewRow(row) }, { default: vue.withCtx(() => [ vue.createTextVNode("\u67E5\u770B") ]), _: 2 }, 1032, ["onClick"])) : vue.createCommentVNode("v-if", true), __props.unfoldActions ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [ isShow("editButton") ? (vue.openBlock(), vue.createBlock(vue.unref(elementPlus.ElButton), { key: 0, type: "primary", link: "", onClick: ($event) => onClickMenuItem({ row, command: "edit" }) }, { default: vue.withCtx(() => [ vue.createTextVNode(" \u7F16\u8F91") ]), _: 2 }, 1032, ["onClick"])) : vue.createCommentVNode("v-if", true), isShow("deleteButton") ? (vue.openBlock(), vue.createBlock(vue.unref(elementPlus.ElButton), { key: 1, type: "primary", link: "", class: "action-delete", onClick: ($event) => onClickMenuItem({ row, command: "delete" }) }, { default: vue.withCtx(() => [ vue.createTextVNode("\u5220\u9664") ]), _: 2 }, 1032, ["onClick"])) : vue.createCommentVNode("v-if", true), __props.unfoldActions ? vue.renderSlot(_ctx.$slots, "action", vue.normalizeProps(vue.mergeProps({ key: 2 }, { row }))) : vue.createCommentVNode("v-if", true) ], 64)) : (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 2 }, [ isShow("editButton") && isShow("deleteButton") ? (vue.openBlock(), vue.createBlock(vue.unref(elementPlus.ElDropdown), { key: 0, trigger: "click", onCommand: ($event) => onClickMenuItem({ row, command: $event }) }, { dropdown: vue.withCtx(() => [ vue.createVNode(vue.unref(elementPlus.ElDropdownMenu), { ref: "refMoreMenu", class: "actions-more" }, { default: vue.withCtx(() => { var _a3, _b2; return [ isShow("editButton") ? (vue.openBlock(), vue.createBlock(vue.unref(elementPlus.ElDropdownItem), { key: 0, disabled: !__props.permissionValidate((_a3 = __props.permissions) == null ? void 0 : _a3.edit), command: "edit" }, { default: vue.withCtx(() => [ vue.createTextVNode("\u7F16\u8F91") ]), _: 1 }, 8, ["disabled"])) : vue.createCommentVNode("v-if", true), isShow("deleteButton") ? (vue.openBlock(), vue.createBlock(vue.unref(elementPlus.ElDropdownItem), { key: 1, disabled: !__props.permissionValidate((_b2 = __props.permissions) == null ? void 0 : _b2.del), command: "delete", class: "action-delete" }, { default: vue.withCtx(() => [ vue.createTextVNode("\u5220\u9664") ]), _: 1 }, 8, ["disabled"])) : vue.createCommentVNode("v-if", true), vue.renderSlot(_ctx.$slots, "action", vue.normalizeProps(vue.guardReactiveProps({ row }))) ]; }), _: 2 }, 1536) ]), default: vue.withCtx(() => [ vue.createVNode(vue.unref(elementPlus.ElButton), { type: "primary", link: "" }, { default: vue.withCtx(() => [ vue.createTextVNode("\u66F4\u591A"), vue.createVNode(vue.unref(elementPlus.ElIcon), { size: "12", color: "var(--el-color-primary)" }, { default: vue.withCtx(() => [ vue.createVNode(vue.unref(iconsVue.ArrowDown)) ]), _: 1 }) ]), _: 1 }) ]), _: 2 }, 1032, ["onCommand"])) : vue.createCommentVNode("v-if", true) ], 64)) ]) ]), _: 3 }, 16, ["prop"])) : vue.createCommentVNode("v-if", true) ]), _: 3 }, 16, ["data"]), [ [vue.vShow, isShow("searching") ? !isSearching.value : true] ]) ]), isShow("page") ? (vue.openBlock(), vue.createElementBlock("div", { key: 1, class: "page" }, [ vue.createVNode(vue.unref(elementPlus.ElPagination), vue.mergeProps({ layout: "total, sizes, prev, pager, next, jumper", small: false, background: true, "page-sizes": [10, 20, 50, 100], "current-page": __props.pageParam.page, "page-size": __props.pageParam.size, total: __props.pageParam.total }, __props.pageProps, { "onUpdate:currentPage": ($event) => emit("update:pageParam", { ...__props.pageParam, page: $event }), "onUpdate:pageSize": ($event) => emit("update:pageParam", { ...__props.pageParam, page: $event }), onSizeChange: handleSizeChange, onCurrentChange: handleCurrentChange }), null, 16, ["current-page", "page-size", "total", "onUpdate:currentPage", "onUpdate:pageSize"]) ])) : vue.createCommentVNode("v-if", true), vue.createVNode(vue.unref(index.YhDialog), { modelValue: isShowDetailDialog.value, "onUpdate:modelValue": ($event) => isShowDetailDialog.value = $event, title: vue.unref(actionText), from: action.value, "dialog-props": __props.dialogProps, onConfirm: onDialogConfirm }, { default: vue.withCtx(() => { var _a3; return [ (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent((_a3 = actions.find((it) => it.key === action.value)) == null ? void 0 : _a3.component), { ref_key: "refContent", ref: refContent, row: actionRow.value, type: action.value }, null, 8, ["row", "type"])) ]; }), _: 1 }, 8, ["modelValue", "onUpdate:modelValue", "title", "from", "dialog-props"]) ]) ]); }; } }); var Table = /* @__PURE__ */ pluginVue_exportHelper["default"](_sfc_main, [["__file", "table.vue"]]); exports["default"] = Table; //# sourceMappingURL=table.js.map