UNPKG

vxe-table

Version:

A PC-end table component based on Vxe UI, supporting copy-paste, data pivot table, and high-performance virtual list table solution.

258 lines (239 loc) • 9.06 kB
import { h, ref, Ref, computed, inject, reactive, nextTick, createCommentVNode } from 'vue' import { defineVxeComponent } from '../../../ui/src/comp' import { VxeUI } from '../../../ui' import XEUtils from 'xe-utils' import { parseFile } from '../../../ui/src/utils' import { errLog } from '../../../ui/src/log' import type { VxeTablePrivateMethods, VxeTableConstructor, VxeTableMethods } from '../../../../types' const { getI18n, getIcon } = VxeUI export default defineVxeComponent({ name: 'VxeTableImportPanel', props: { defaultOptions: Object as any, storeData: Object as any }, setup (props) { const VxeUIModalComponent = VxeUI.getComponent('VxeModal') const VxeUIButtonComponent = VxeUI.getComponent('VxeButton') const VxeUISelectComponent = VxeUI.getComponent('VxeSelect') const $xeTable = inject('$xeTable', {} as VxeTableConstructor & VxeTableMethods & VxeTablePrivateMethods) const { computeImportOpts } = $xeTable.getComputeMaps() const reactData = reactive({ loading: false }) const refFileBtn = ref() as Ref<HTMLButtonElement> const computeSelectName = computed(() => { const { storeData } = props return `${storeData.filename}.${storeData.type}` }) const computeHasFile = computed(() => { const { storeData } = props return storeData.file && storeData.type }) const computeParseTypeLabel = computed(() => { const { storeData } = props const { type, typeList } = storeData if (type) { const selectItem = XEUtils.find(typeList, item => type === item.value) return selectItem ? selectItem.label : '*.*' } return `*.${typeList.map((item: any) => item.value).join(', *.')}` }) const clearFileEvent = () => { const { storeData } = props Object.assign(storeData, { filename: '', sheetName: '', type: '' }) } const selectFileEvent = () => { const { storeData, defaultOptions } = props $xeTable.readFile(defaultOptions).then((params: any) => { const { file } = params Object.assign(storeData, parseFile(file), { file }) }).catch((e: any) => e) } const showEvent = () => { nextTick(() => { const targetElem = refFileBtn.value if (targetElem) { targetElem.focus() } }) } const cancelEvent = () => { const { storeData } = props storeData.visible = false } const importEvent = () => { const { storeData, defaultOptions } = props const importOpts = computeImportOpts.value reactData.loading = true $xeTable.importByFile(storeData.file, Object.assign({}, importOpts, defaultOptions)).then(() => { reactData.loading = false storeData.visible = false }).catch(() => { reactData.loading = false }) } const renderVN = () => { const $xeGrid = $xeTable.xeGrid const { defaultOptions, storeData } = props const selectName = computeSelectName.value const hasFile = computeHasFile.value const parseTypeLabel = computeParseTypeLabel.value const slots = defaultOptions.slots || {} const topSlot = slots.top const bottomSlot = slots.bottom const defaultSlot = slots.default const footerSlot = slots.footer return VxeUIModalComponent ? h(VxeUIModalComponent, { id: 'VXE_IMPORT_MODAL', modelValue: storeData.visible, title: getI18n('vxe.import.impTitle'), className: 'vxe-table-export-popup-wrapper', width: 540, minWidth: 360, minHeight: 240, mask: true, lockView: true, showFooter: true, escClosable: true, maskClosable: true, showMaximize: true, resize: true, loading: reactData.loading, 'onUpdate:modelValue' (value: any) { storeData.visible = value }, onShow: showEvent }, { default: () => { const params = { $table: $xeTable, $grid: $xeGrid, options: defaultOptions, params: defaultOptions.params as any } return h('div', { class: 'vxe-table-export--panel' }, [ topSlot ? h('div', { class: 'vxe-table-export--panel-top' }, $xeTable.callSlot(topSlot, params)) : createCommentVNode(), h('div', { class: 'vxe-table-export--panel-body' }, defaultSlot ? $xeTable.callSlot(defaultSlot, params) : [ h('table', { class: 'vxe-table-export--panel-table', cellspacing: 0, cellpadding: 0, border: 0 }, [ h('tbody', [ h('tr', [ h('td', getI18n('vxe.import.impFile')), h('td', [ hasFile ? h('div', { class: 'vxe-table-export--selected--file', title: selectName }, [ h('span', selectName), h('i', { class: getIcon().INPUT_CLEAR, onClick: clearFileEvent }) ]) : h('button', { ref: refFileBtn, class: 'vxe-table-export--select--file', onClick: selectFileEvent }, getI18n('vxe.import.impSelect')) ]) ]), h('tr', [ h('td', getI18n('vxe.import.impType')), h('td', parseTypeLabel) ]), h('tr', [ h('td', getI18n('vxe.import.impMode')), h('td', [ VxeUISelectComponent ? h(VxeUISelectComponent, { modelValue: defaultOptions.mode, options: storeData.modeList, 'onUpdate:modelValue' (value: any) { defaultOptions.mode = value } }) : createCommentVNode() ]) ]) ]) ]) ] ), bottomSlot ? h('div', { class: 'vxe-table-export--panel-bottom' }, $xeTable.callSlot(bottomSlot, params)) : createCommentVNode() ]) }, footer () { const params = { $table: $xeTable, $grid: $xeGrid, options: defaultOptions, params: defaultOptions.params as any } return h('div', { class: 'vxe-table-export--panel-footer' }, footerSlot ? $xeTable.callSlot(footerSlot, params) : [ h('div', { class: 'vxe-table-export--panel-btns' }, [ VxeUIButtonComponent ? h(VxeUIButtonComponent, { content: getI18n('vxe.import.impCancel'), onClick: cancelEvent }) : createCommentVNode(), VxeUIButtonComponent ? h(VxeUIButtonComponent, { status: 'primary', disabled: !hasFile || reactData.loading, content: getI18n('vxe.import.impConfirm'), onClick: importEvent }) : createCommentVNode() ]) ] ) } }) : createCommentVNode() } nextTick(() => { if (!VxeUIModalComponent) { errLog('vxe.error.reqComp', ['vxe-modal']) } if (!VxeUIButtonComponent) { errLog('vxe.error.reqComp', ['vxe-button']) } if (!VxeUISelectComponent) { errLog('vxe.error.reqComp', ['vxe-select']) } }) return renderVN } })