panel.ts 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448
  1. import { CreateElement, VNode } from 'vue'
  2. import { VxeUI } from '../../../ui'
  3. import { formatText } from '../../../ui/src/utils'
  4. import { getTpImg, addClass, removeClass, hasControlKey } from '../../../ui/src/dom'
  5. import { errLog } from '../../../ui/src/log'
  6. import XEUtils from 'xe-utils'
  7. import type { VxeTableDefines, VxeTableConstructor, VxeTablePrivateMethods, TableReactData, TableInternalData, VxeColumnPropTypes, VxeTableCustomPanelConstructor, TableCustomPanelReactData, TableCustomPanelInternalData } from '../../../../types'
  8. import type { VxeButtonDefines, VxeRadioGroupDefines } from 'vxe-pc-ui'
  9. const { getI18n, getIcon, renderEmptyElement } = VxeUI
  10. function showDropTip ($xeTableCustomPanel: VxeTableCustomPanelConstructor, evnt: DragEvent | MouseEvent, optEl: HTMLElement | null, showLine: boolean, dragPos: string) {
  11. const customPanelInternalData = $xeTableCustomPanel.internalData
  12. const bodyWrapperElem = $xeTableCustomPanel.$refs.refBodyWrapperElem as HTMLDivElement
  13. if (!bodyWrapperElem) {
  14. return
  15. }
  16. const customBodyElem = $xeTableCustomPanel.$refs.refCustomBodyElem as HTMLDivElement
  17. if (!customBodyElem) {
  18. return
  19. }
  20. const { prevDragToChild } = customPanelInternalData
  21. const bodyWrapperRect = bodyWrapperElem.getBoundingClientRect()
  22. const customBodyRect = customBodyElem.getBoundingClientRect()
  23. const dragLineEl = $xeTableCustomPanel.$refs.refDragLineElem as HTMLDivElement
  24. if (optEl) {
  25. if (dragLineEl) {
  26. if (showLine) {
  27. const optRect = optEl.getBoundingClientRect()
  28. dragLineEl.style.display = 'block'
  29. dragLineEl.style.left = `${Math.max(0, customBodyRect.x - bodyWrapperRect.x)}px`
  30. dragLineEl.style.top = `${Math.max(1, optRect.y + bodyWrapperElem.scrollTop - bodyWrapperRect.y)}px`
  31. dragLineEl.style.height = `${optRect.height}px`
  32. dragLineEl.style.width = `${optRect.width}px`
  33. dragLineEl.setAttribute('drag-pos', dragPos)
  34. dragLineEl.setAttribute('drag-to-child', prevDragToChild ? 'y' : 'n')
  35. } else {
  36. dragLineEl.style.display = ''
  37. }
  38. }
  39. } else {
  40. if (dragLineEl) {
  41. dragLineEl.style.display = 'node'
  42. }
  43. }
  44. const dragTipEl = $xeTableCustomPanel.$refs.refDragTipElem as HTMLDivElement
  45. if (dragTipEl) {
  46. dragTipEl.style.display = 'block'
  47. dragTipEl.style.top = `${Math.min(bodyWrapperElem.clientHeight + bodyWrapperElem.scrollTop - dragTipEl.clientHeight, evnt.clientY + bodyWrapperElem.scrollTop - bodyWrapperRect.y)}px`
  48. dragTipEl.style.left = `${Math.min(bodyWrapperElem.clientWidth + bodyWrapperElem.scrollLeft - dragTipEl.clientWidth, evnt.clientX + bodyWrapperElem.scrollLeft - bodyWrapperRect.x)}px`
  49. dragTipEl.setAttribute('drag-status', showLine ? (prevDragToChild ? 'sub' : 'normal') : 'disabled')
  50. }
  51. }
  52. function hideDropTip ($xeTableCustomPanel: VxeTableCustomPanelConstructor) {
  53. const dragTipEl = $xeTableCustomPanel.$refs.refDragTipElem as HTMLDivElement
  54. const dragLineEl = $xeTableCustomPanel.$refs.refDragLineElem as HTMLDivElement
  55. if (dragTipEl) {
  56. dragTipEl.style.display = ''
  57. }
  58. if (dragLineEl) {
  59. dragLineEl.style.display = ''
  60. }
  61. }
  62. const renderDragTip = (h: CreateElement, $xeTableCustomPanel: VxeTableCustomPanelConstructor) => {
  63. const $xeTable = $xeTableCustomPanel.$xeTable
  64. const customPanelReactData = $xeTableCustomPanel.reactData
  65. const { dragTipText } = customPanelReactData
  66. const columnDragOpts = $xeTable.computeColumnDragOpts
  67. return h('div', {}, [
  68. h('div', {
  69. ref: 'refDragLineElem',
  70. class: ['vxe-table-custom-popup--drag-line', {
  71. 'is--guides': columnDragOpts.showGuidesStatus
  72. }]
  73. }),
  74. h('div', {
  75. ref: 'refDragTipElem',
  76. class: 'vxe-table-custom-popup--drag-tip'
  77. }, [
  78. h('div', {
  79. class: 'vxe-table-custom-popup--drag-tip-wrapper'
  80. }, [
  81. h('div', {
  82. class: 'vxe-table-custom-popup--drag-tip-status'
  83. }, [
  84. h('span', {
  85. class: ['vxe-table-custom-popup--drag-tip-normal-status', getIcon().TABLE_DRAG_STATUS_ROW]
  86. }),
  87. h('span', {
  88. class: ['vxe-table-custom-popup--drag-tip-sub-status', getIcon().TABLE_DRAG_STATUS_SUB_ROW]
  89. }),
  90. h('span', {
  91. class: ['vxe-table-custom-popup--drag-tip-group-status', getIcon().TABLE_DRAG_STATUS_AGG_GROUP]
  92. }),
  93. h('span', {
  94. class: ['vxe-table-custom-popup--drag-tip-values-status', getIcon().TABLE_DRAG_STATUS_AGG_VALUES]
  95. }),
  96. h('span', {
  97. class: ['vxe-table-custom-popup--drag-tip-disabled-status', getIcon().TABLE_DRAG_DISABLED]
  98. })
  99. ]),
  100. h('div', {
  101. class: 'vxe-table-custom-popup--drag-tip-content'
  102. }, `${dragTipText || ''}`)
  103. ])
  104. ])
  105. ])
  106. }
  107. const renderSimplePanel = (h: CreateElement, _vm: any) => {
  108. const VxeUIButtonComponent = VxeUI.getComponent('VxeButton')
  109. const props = _vm
  110. const $xeTable = _vm.$xeTable as VxeTableConstructor & VxeTablePrivateMethods
  111. const tableProps = $xeTable
  112. const tableReactData = $xeTable as unknown as TableReactData
  113. const $xeGrid = $xeTable.$xeGrid
  114. const $xeGantt = $xeTable.$xeGantt
  115. const { customStore } = props
  116. const { treeConfig, rowGroupConfig, aggregateConfig } = tableProps
  117. const { isCustomStatus, customColumnList } = tableReactData
  118. const customOpts = $xeTable.computeCustomOpts
  119. const { immediate } = customOpts
  120. const columnDragOpts = $xeTable.computeColumnDragOpts
  121. const { maxHeight } = customStore
  122. const { checkMethod, visibleMethod, allowVisible, allowSort, allowFixed, trigger, placement } = customOpts
  123. const isMaxFixedColumn = $xeTable.computeIsMaxFixedColumn
  124. const { isCrossDrag } = columnDragOpts
  125. const slots = customOpts.slots || {}
  126. const headerSlot = slots.header
  127. const topSlot = slots.top
  128. const bottomSlot = slots.bottom
  129. const defaultSlot = slots.default
  130. const footerSlot = slots.footer
  131. const colVNs: any[] = []
  132. const customWrapperOns: any = {}
  133. const isAllChecked = customStore.isAll
  134. const isAllIndeterminate = customStore.isIndeterminate
  135. // hover 触发
  136. if (trigger === 'hover') {
  137. customWrapperOns.mouseenter = _vm.handleWrapperMouseenterEvent
  138. customWrapperOns.mouseleave = _vm.handleWrapperMouseleaveEvent
  139. }
  140. const params = {
  141. $table: $xeTable,
  142. $grid: $xeGrid,
  143. $gantt: $xeGantt,
  144. columns: customColumnList,
  145. isAllChecked,
  146. isAllIndeterminate,
  147. isCustomStatus
  148. }
  149. XEUtils.eachTree(customColumnList, (column, index, items, path, parent) => {
  150. const isVisible = visibleMethod ? visibleMethod({ $table: $xeTable, column }) : true
  151. if (isVisible) {
  152. const isChecked = column.renderVisible
  153. const isIndeterminate = column.halfVisible
  154. const isColGroup = column.children && column.children.length
  155. const colTitle = formatText(column.getTitle(), 1)
  156. const isDisabled = checkMethod ? !checkMethod({ $table: $xeTable, column }) : false
  157. const isHidden = !isChecked
  158. colVNs.push(
  159. h('li', {
  160. key: column.id,
  161. attrs: {
  162. colid: column.id
  163. },
  164. class: ['vxe-table-custom--option', `level--${column.level}`, {
  165. 'is--hidden': isDisabled || isHidden,
  166. 'is--group': isColGroup
  167. }],
  168. on: {
  169. dragstart: _vm.sortDragstartEvent,
  170. dragend: _vm.sortDragendEvent,
  171. dragover: _vm.sortDragoverEvent
  172. }
  173. }, [
  174. allowVisible
  175. ? h('div', {
  176. class: ['vxe-table-custom--checkbox-option', {
  177. 'is--checked': isChecked,
  178. 'is--indeterminate': isIndeterminate,
  179. 'is--disabled': isDisabled
  180. }],
  181. attrs: {
  182. title: getI18n('vxe.custom.setting.colVisible')
  183. },
  184. on: {
  185. click: (evnt: MouseEvent) => {
  186. if (!isDisabled) {
  187. _vm.changeCheckboxOption(column, evnt)
  188. }
  189. }
  190. }
  191. }, [
  192. h('span', {
  193. class: ['vxe-checkbox--icon', isIndeterminate ? getIcon().TABLE_CHECKBOX_INDETERMINATE : (isChecked ? getIcon().TABLE_CHECKBOX_CHECKED : getIcon().TABLE_CHECKBOX_UNCHECKED)]
  194. })
  195. ])
  196. : renderEmptyElement($xeTable),
  197. h('div', {
  198. class: 'vxe-table-custom--name-option'
  199. }, [
  200. allowSort && ((isCrossDrag ? immediate : false) || column.level === 1)
  201. ? h('div', {
  202. class: 'vxe-table-custom--sort-option'
  203. }, [
  204. h('span', {
  205. class: ['vxe-table-custom--sort-btn', {
  206. 'is--disabled': isDisabled || isHidden
  207. }],
  208. attrs: {
  209. title: getI18n('vxe.custom.setting.sortHelpTip')
  210. },
  211. on: isDisabled || isHidden
  212. ? {}
  213. : {
  214. mousedown: _vm.sortMousedownEvent,
  215. mouseup: _vm.sortMouseupEvent
  216. }
  217. }, [
  218. h('i', {
  219. class: getIcon().TABLE_CUSTOM_SORT
  220. })
  221. ])
  222. ])
  223. : renderEmptyElement($xeTable),
  224. column.type === 'html'
  225. ? h('div', {
  226. key: '1',
  227. class: 'vxe-table-custom--checkbox-label',
  228. domProps: {
  229. innerHTML: colTitle
  230. }
  231. })
  232. : h('div', {
  233. key: '0',
  234. class: 'vxe-table-custom--checkbox-label',
  235. attrs: {
  236. title: colTitle
  237. }
  238. }, colTitle)
  239. ]),
  240. !parent && allowFixed
  241. ? h('div', {
  242. class: 'vxe-table-custom--fixed-option'
  243. }, [
  244. h(VxeUIButtonComponent, {
  245. props: {
  246. mode: 'text',
  247. icon: column.renderFixed === 'left' ? getIcon().TOOLBAR_TOOLS_FIXED_LEFT_ACTIVE : getIcon().TOOLBAR_TOOLS_FIXED_LEFT,
  248. status: column.renderFixed === 'left' ? 'primary' : '',
  249. disabled: isDisabled || isHidden || (isMaxFixedColumn && !column.renderFixed),
  250. title: getI18n(column.renderFixed === 'left' ? 'vxe.toolbar.cancelFixed' : 'vxe.toolbar.fixedLeft')
  251. },
  252. on: {
  253. click: ({ $event }: VxeButtonDefines.ClickEventParams) => {
  254. _vm.changeFixedOption(column, 'left', $event)
  255. }
  256. }
  257. }),
  258. h(VxeUIButtonComponent, {
  259. props: {
  260. mode: 'text',
  261. icon: column.renderFixed === 'right' ? getIcon().TOOLBAR_TOOLS_FIXED_RIGHT_ACTIVE : getIcon().TOOLBAR_TOOLS_FIXED_RIGHT,
  262. status: column.renderFixed === 'right' ? 'primary' : '',
  263. disabled: isDisabled || isHidden || (isMaxFixedColumn && !column.renderFixed),
  264. title: getI18n(column.renderFixed === 'right' ? 'vxe.toolbar.cancelFixed' : 'vxe.toolbar.fixedRight')
  265. },
  266. on: {
  267. click: ({ $event }: VxeButtonDefines.ClickEventParams) => {
  268. _vm.changeFixedOption(column, 'right', $event)
  269. }
  270. }
  271. })
  272. ])
  273. : renderEmptyElement($xeTable)
  274. ])
  275. )
  276. }
  277. })
  278. return h('div', {
  279. ref: 'refElem',
  280. key: 'simple',
  281. class: ['vxe-table-custom-wrapper', `placement--${placement}`, {
  282. 'is--active': customStore.visible
  283. }],
  284. style: maxHeight && !['left', 'right'].includes(placement || '')
  285. ? {
  286. maxHeight: `${maxHeight}px`
  287. }
  288. : {}
  289. }, customStore.visible
  290. ? [
  291. h('div', {
  292. ref: 'refBodyWrapperElem',
  293. class: 'vxe-table-custom-simple--body-wrapper'
  294. }, [
  295. !treeConfig && (aggregateConfig || rowGroupConfig) && $xeTable.getPivotTableAggregateSimplePanel
  296. ? h($xeTable.getPivotTableAggregateSimplePanel(), {
  297. props: {
  298. customStore
  299. }
  300. })
  301. : renderEmptyElement($xeTable),
  302. h('div', {
  303. ref: 'refCustomBodyElem',
  304. class: 'vxe-table-custom--handle-wrapper'
  305. }, [
  306. h('div', {
  307. class: 'vxe-table-custom--header'
  308. }, headerSlot
  309. ? $xeTable.callSlot(headerSlot, params, h)
  310. : [
  311. h('ul', {
  312. class: 'vxe-table-custom--panel-list'
  313. }, [
  314. h('li', {
  315. class: 'vxe-table-custom--option'
  316. }, [
  317. allowVisible
  318. ? h('div', {
  319. class: ['vxe-table-custom--checkbox-option', {
  320. 'is--checked': isAllChecked,
  321. 'is--indeterminate': isAllIndeterminate
  322. }],
  323. attrs: {
  324. title: getI18n('vxe.table.allTitle')
  325. },
  326. on: {
  327. click: _vm.allOptionEvent
  328. }
  329. }, [
  330. h('span', {
  331. class: ['vxe-checkbox--icon', isAllIndeterminate ? getIcon().TABLE_CHECKBOX_INDETERMINATE : (isAllChecked ? getIcon().TABLE_CHECKBOX_CHECKED : getIcon().TABLE_CHECKBOX_UNCHECKED)]
  332. }),
  333. h('span', {
  334. class: 'vxe-checkbox--label'
  335. }, getI18n('vxe.toolbar.customAll'))
  336. ])
  337. : h('span', {
  338. class: 'vxe-checkbox--label'
  339. }, getI18n('vxe.table.customTitle'))
  340. ])
  341. ])
  342. ]),
  343. h('div', {
  344. class: 'vxe-table-custom--body'
  345. }, [
  346. topSlot
  347. ? h('div', {
  348. class: 'vxe-table-custom--panel-top'
  349. }, $xeTable.callSlot(topSlot, params, h))
  350. : renderEmptyElement($xeTable),
  351. defaultSlot
  352. ? h('div', {
  353. class: 'vxe-table-custom--panel-body'
  354. }, $xeTable.callSlot(defaultSlot, params, h))
  355. : h('transition-group', {
  356. class: 'vxe-table-custom--panel-list',
  357. props: {
  358. name: 'vxe-table-custom--list',
  359. tag: 'ul'
  360. },
  361. on: customWrapperOns
  362. }, colVNs),
  363. bottomSlot
  364. ? h('div', {
  365. class: 'vxe-table-custom--panel-bottom'
  366. }, $xeTable.callSlot(bottomSlot, params, h))
  367. : renderEmptyElement($xeTable)
  368. ]),
  369. customOpts.showFooter
  370. ? h('div', {
  371. class: 'vxe-table-custom--footer'
  372. }, footerSlot
  373. ? $xeTable.callSlot(footerSlot, params, h)
  374. : [
  375. h('div', {
  376. class: 'vxe-table-custom--footer-buttons'
  377. }, [
  378. h(VxeUIButtonComponent, {
  379. props: {
  380. mode: 'text',
  381. content: customOpts.resetButtonText || getI18n('vxe.table.customRestore'),
  382. disabled: !isCustomStatus
  383. },
  384. on: {
  385. click: _vm.resetCustomEvent
  386. }
  387. }),
  388. immediate
  389. ? h(VxeUIButtonComponent, {
  390. props: {
  391. mode: 'text',
  392. content: customOpts.closeButtonText || getI18n('vxe.table.customClose')
  393. },
  394. on: {
  395. click: _vm.cancelCloseEvent
  396. }
  397. })
  398. : h(VxeUIButtonComponent, {
  399. props: {
  400. mode: 'text',
  401. content: customOpts.resetButtonText || getI18n('vxe.table.customCancel')
  402. },
  403. on: {
  404. click: _vm.cancelCustomEvent
  405. }
  406. }),
  407. immediate
  408. ? renderEmptyElement($xeTable)
  409. : h(VxeUIButtonComponent, {
  410. props: {
  411. mode: 'text',
  412. status: 'primary',
  413. content: customOpts.confirmButtonText || getI18n('vxe.table.customConfirm')
  414. },
  415. on: {
  416. click: _vm.confirmCustomEvent
  417. }
  418. })
  419. ])
  420. ])
  421. : null
  422. ]),
  423. renderDragTip(h, _vm)
  424. ])
  425. ]
  426. : [])
  427. }
  428. const renderPopupPanel = (h: CreateElement, $xeTableCustomPanel: VxeTableCustomPanelConstructor) => {
  429. const VxeUIModalComponent = VxeUI.getComponent('VxeModal')
  430. const VxeUIDrawerComponent = VxeUI.getComponent('VxeDrawer')
  431. const VxeUIButtonComponent = VxeUI.getComponent('VxeButton')
  432. const VxeUINumberInputComponent = VxeUI.getComponent('VxeNumberInput')
  433. const _vm = $xeTableCustomPanel as any
  434. const props = $xeTableCustomPanel
  435. const $xeTable = $xeTableCustomPanel.$xeTable as VxeTableConstructor & VxeTablePrivateMethods
  436. const tableProps = $xeTable
  437. const tableReactData = $xeTable as unknown as TableReactData
  438. const $xeGrid = $xeTable.$xeGrid
  439. const $xeGantt = $xeTable.$xeGantt
  440. const { customStore } = props
  441. const { treeConfig, rowGroupConfig, aggregateConfig, resizable: allResizable } = tableProps
  442. const { isCustomStatus, customColumnList } = tableReactData
  443. const customOpts = $xeTable.computeCustomOpts
  444. const { immediate } = customOpts
  445. const columnDragOpts = $xeTable.computeColumnDragOpts
  446. const { mode, modalOptions, drawerOptions, allowVisible, allowSort, allowFixed, allowResizable, checkMethod, visibleMethod } = customOpts
  447. const columnOpts = $xeTable.computeColumnOpts
  448. const { maxFixedSize } = columnOpts
  449. const resizableOpts = $xeTable.computeResizableOpts
  450. const { minWidth: reMinWidth, maxWidth: reMaxWidth } = resizableOpts
  451. const modalOpts = Object.assign({}, modalOptions)
  452. const drawerOpts = Object.assign({}, drawerOptions)
  453. const isMaxFixedColumn = $xeTable.computeIsMaxFixedColumn
  454. const { isCrossDrag } = columnDragOpts
  455. const slots = customOpts.slots || {}
  456. const headerSlot = slots.header
  457. const topSlot = slots.top
  458. const bottomSlot = slots.bottom
  459. const defaultSlot = slots.default
  460. const footerSlot = slots.footer
  461. const trVNs: VNode[] = []
  462. const isAllChecked = customStore.isAll
  463. const isAllIndeterminate = customStore.isIndeterminate
  464. const params = {
  465. $table: $xeTable,
  466. $grid: $xeGrid,
  467. $gantt: $xeGantt,
  468. columns: customColumnList,
  469. isAllChecked,
  470. isAllIndeterminate,
  471. isCustomStatus
  472. }
  473. XEUtils.eachTree(customColumnList, (column, index, items, path, parent) => {
  474. const isVisible = visibleMethod ? visibleMethod({ $table: $xeTable, column }) : true
  475. if (isVisible) {
  476. // 默认继承调整宽度
  477. let customMinWidth = 0
  478. let customMaxWidth = 0
  479. if (allowResizable) {
  480. const resizeParams = {
  481. $table: $xeTable,
  482. column,
  483. columnIndex: index,
  484. $columnIndex: index,
  485. $rowIndex: -1
  486. }
  487. if (reMinWidth) {
  488. customMinWidth = XEUtils.toNumber(XEUtils.isFunction(reMinWidth) ? reMinWidth(resizeParams) : reMinWidth)
  489. }
  490. if (reMaxWidth) {
  491. customMaxWidth = XEUtils.toNumber(XEUtils.isFunction(reMaxWidth) ? reMaxWidth(resizeParams) : reMaxWidth)
  492. }
  493. }
  494. const isChecked = column.renderVisible
  495. const isIndeterminate = column.halfVisible
  496. const colTitle = formatText(column.getTitle(), 1)
  497. const isColGroup = column.children && column.children.length
  498. const isDisabled = checkMethod ? !checkMethod({ $table: $xeTable, column }) : false
  499. const isHidden = !isChecked
  500. trVNs.push(
  501. h('tr', {
  502. key: column.id,
  503. attrs: {
  504. colid: column.id
  505. },
  506. class: [`vxe-table-custom-popup--row level--${column.level}`, {
  507. 'is--group': isColGroup
  508. }],
  509. on: {
  510. dragstart: _vm.sortDragstartEvent,
  511. dragend: _vm.sortDragendEvent,
  512. dragover: _vm.sortDragoverEvent
  513. }
  514. }, [
  515. allowVisible
  516. ? h('td', {
  517. class: 'vxe-table-custom-popup--column-item col--visible'
  518. }, [
  519. h('div', {
  520. class: ['vxe-table-custom--checkbox-option', {
  521. 'is--checked': isChecked,
  522. 'is--indeterminate': isIndeterminate,
  523. 'is--disabled': isDisabled
  524. }],
  525. attrs: {
  526. title: getI18n('vxe.custom.setting.colVisible')
  527. },
  528. on: {
  529. click: (evnt: MouseEvent) => {
  530. if (!isDisabled) {
  531. _vm.changeCheckboxOption(column, evnt)
  532. }
  533. }
  534. }
  535. }, [
  536. h('span', {
  537. class: ['vxe-checkbox--icon', isIndeterminate ? getIcon().TABLE_CHECKBOX_INDETERMINATE : (isChecked ? getIcon().TABLE_CHECKBOX_CHECKED : getIcon().TABLE_CHECKBOX_UNCHECKED)]
  538. })
  539. ])
  540. ])
  541. : renderEmptyElement($xeTable),
  542. h('td', {
  543. class: 'vxe-table-custom-popup--column-item col--name'
  544. }, [
  545. h('div', {
  546. class: 'vxe-table-custom-popup--name'
  547. }, [
  548. allowSort
  549. ? ((isCrossDrag ? immediate : false) || column.level === 1
  550. ? h('div', {
  551. class: ['vxe-table-custom-popup--column-sort-btn', {
  552. 'is--disabled': isDisabled || isHidden
  553. }],
  554. attrs: {
  555. title: getI18n('vxe.custom.setting.sortHelpTip')
  556. },
  557. on: (isDisabled || isHidden
  558. ? {}
  559. : {
  560. mousedown: _vm.sortMousedownEvent,
  561. mouseup: _vm.sortMouseupEvent
  562. })
  563. }, [
  564. h('i', {
  565. class: getIcon().TABLE_CUSTOM_SORT
  566. })
  567. ])
  568. : h('div', {
  569. class: 'vxe-table-custom-popup--column-sort-placeholder'
  570. }))
  571. : renderEmptyElement($xeTable),
  572. column.type === 'html'
  573. ? h('div', {
  574. key: '1',
  575. class: 'vxe-table-custom-popup--title',
  576. domProps: {
  577. innerHTML: colTitle
  578. }
  579. })
  580. : h('div', {
  581. key: '0',
  582. class: 'vxe-table-custom-popup--title',
  583. attrs: {
  584. title: colTitle
  585. }
  586. }, colTitle)
  587. ])
  588. ]),
  589. allowResizable
  590. ? h('td', {
  591. class: 'vxe-table-custom-popup--column-item col--resizable'
  592. }, [
  593. (
  594. (column.children && column.children.length) ||
  595. !(XEUtils.isBoolean(column.resizable) ? column.resizable : (columnOpts.resizable || allResizable))
  596. )
  597. ? h('span', '-')
  598. : (VxeUINumberInputComponent
  599. ? h(VxeUINumberInputComponent, {
  600. props: {
  601. type: 'integer',
  602. immediate: false,
  603. disabled: isDisabled || isHidden,
  604. value: column.renderResizeWidth,
  605. min: customMinWidth || undefined,
  606. max: customMaxWidth || undefined
  607. },
  608. on: {
  609. modelValue (value: any) {
  610. column.renderResizeWidth = Math.max(0, Number(value))
  611. },
  612. change () {
  613. _vm.changeColumnWidth(column)
  614. }
  615. }
  616. })
  617. : renderEmptyElement($xeTableCustomPanel)
  618. )
  619. ])
  620. : renderEmptyElement($xeTable),
  621. allowFixed
  622. ? h('td', {
  623. class: 'vxe-table-custom-popup--column-item col--fixed'
  624. }, [
  625. parent
  626. ? h('span', '-')
  627. : h('vxe-radio-group', {
  628. props: {
  629. value: column.renderFixed || '',
  630. type: 'button',
  631. size: 'mini',
  632. disabled: isDisabled || isHidden,
  633. options: [
  634. { label: getI18n('vxe.custom.setting.fixedLeft'), value: 'left', disabled: isDisabled || isHidden || isMaxFixedColumn },
  635. { label: getI18n('vxe.custom.setting.fixedUnset'), value: '', disabled: isDisabled || isHidden },
  636. { label: getI18n('vxe.custom.setting.fixedRight'), value: 'right', disabled: isDisabled || isHidden || isMaxFixedColumn }
  637. ]
  638. },
  639. on: {
  640. change ({ label, $event }: VxeRadioGroupDefines.ChangeEventParams) {
  641. _vm.changeFixedOption(column, label, $event)
  642. }
  643. }
  644. })
  645. ])
  646. : renderEmptyElement($xeTable)
  647. ])
  648. )
  649. }
  650. })
  651. const scopedSlots: Record<string, any> = {
  652. default: () => {
  653. return h('div', {
  654. ref: 'refBodyWrapperElem',
  655. class: 'vxe-table-custom-popup--body-wrapper'
  656. }, defaultSlot
  657. ? $xeTable.callSlot(defaultSlot, params, h)
  658. : [
  659. h('div', {
  660. ref: 'refCustomBodyElem',
  661. class: 'vxe-table-custom-popup--handle-wrapper'
  662. }, [
  663. topSlot
  664. ? h('div', {
  665. class: 'vxe-table-custom-popup--table-top'
  666. }, $xeTable.callSlot(topSlot, params, h))
  667. : renderEmptyElement($xeTable),
  668. h('div', {
  669. class: 'vxe-table-custom-popup--table-wrapper'
  670. }, [
  671. h('table', {}, [
  672. h('colgroup', {}, [
  673. allowVisible
  674. ? h('col', {
  675. class: 'vxe-table-custom-popup--table-col-seq'
  676. })
  677. : renderEmptyElement($xeTable),
  678. h('col', {
  679. class: 'vxe-table-custom-popup--table-col-title'
  680. }),
  681. allowResizable
  682. ? h('col', {
  683. class: 'vxe-table-custom-popup--table-col-width'
  684. })
  685. : renderEmptyElement($xeTable),
  686. allowFixed
  687. ? h('col', {
  688. class: 'vxe-table-custom-popup--table-col-fixed'
  689. })
  690. : renderEmptyElement($xeTable)
  691. ]),
  692. h('thead', {}, [
  693. h('tr', {}, [
  694. allowVisible
  695. ? h('th', {}, [
  696. h('div', {
  697. class: ['vxe-table-custom--checkbox-option', {
  698. 'is--checked': isAllChecked,
  699. 'is--indeterminate': isAllIndeterminate
  700. }],
  701. attrs: {
  702. title: getI18n('vxe.table.allTitle')
  703. },
  704. on: {
  705. click: _vm.allOptionEvent
  706. }
  707. }, [
  708. h('span', {
  709. class: ['vxe-checkbox--icon', isAllIndeterminate ? getIcon().TABLE_CHECKBOX_INDETERMINATE : (isAllChecked ? getIcon().TABLE_CHECKBOX_CHECKED : getIcon().TABLE_CHECKBOX_UNCHECKED)]
  710. }),
  711. h('span', {
  712. class: 'vxe-checkbox--label'
  713. }, getI18n('vxe.toolbar.customAll'))
  714. ])
  715. ])
  716. : renderEmptyElement($xeTable),
  717. h('th', {}, getI18n('vxe.custom.setting.colTitle')),
  718. allowResizable
  719. ? h('th', {}, getI18n('vxe.custom.setting.colResizable'))
  720. : renderEmptyElement($xeTable),
  721. allowFixed
  722. ? h('th', {}, getI18n(`vxe.custom.setting.${maxFixedSize ? 'colFixedMax' : 'colFixed'}`, [maxFixedSize]))
  723. : renderEmptyElement($xeTable)
  724. ])
  725. ]),
  726. h('transition-group', {
  727. class: 'vxe-table-custom--panel-list',
  728. props: {
  729. tag: 'tbody',
  730. name: 'vxe-table-custom--list'
  731. }
  732. }, trVNs)
  733. ])
  734. ]),
  735. bottomSlot
  736. ? h('div', {
  737. class: 'vxe-table-custom-popup--table-bottom'
  738. }, $xeTable.callSlot(bottomSlot, params, h))
  739. : renderEmptyElement($xeTable),
  740. renderDragTip(h, _vm)
  741. ]),
  742. !treeConfig && (aggregateConfig || rowGroupConfig) && $xeTable.getPivotTableAggregatePopupPanel
  743. ? h($xeTable.getPivotTableAggregatePopupPanel(), {
  744. props: {
  745. customStore
  746. }
  747. })
  748. : renderEmptyElement($xeTable)
  749. ])
  750. },
  751. footer: () => {
  752. if (footerSlot) {
  753. return $xeTable.callSlot(footerSlot, params, h)
  754. }
  755. return h('div', {
  756. class: 'vxe-table-custom-popup--footer'
  757. }, [
  758. h(VxeUIButtonComponent, {
  759. props: {
  760. content: customOpts.resetButtonText || getI18n('vxe.custom.cstmRestore'),
  761. disabled: !isCustomStatus
  762. },
  763. on: {
  764. click: _vm.resetCustomEvent
  765. }
  766. }),
  767. immediate
  768. ? h(VxeUIButtonComponent, {
  769. props: {
  770. content: customOpts.resetButtonText || getI18n('vxe.table.customClose')
  771. },
  772. on: {
  773. click: _vm.cancelCloseEvent
  774. }
  775. })
  776. : h(VxeUIButtonComponent, {
  777. props: {
  778. content: customOpts.resetButtonText || getI18n('vxe.custom.cstmCancel')
  779. },
  780. on: {
  781. click: _vm.cancelCustomEvent
  782. }
  783. }),
  784. immediate
  785. ? renderEmptyElement($xeTable)
  786. : h(VxeUIButtonComponent, {
  787. props: {
  788. status: 'primary',
  789. content: customOpts.confirmButtonText || getI18n('vxe.custom.cstmConfirm')
  790. },
  791. on: {
  792. click: _vm.confirmCustomEvent
  793. }
  794. })
  795. ])
  796. }
  797. }
  798. if (headerSlot) {
  799. scopedSlots.header = () => $xeTable.callSlot(headerSlot, params, h)
  800. }
  801. if (mode === 'drawer') {
  802. return VxeUIDrawerComponent
  803. ? h(VxeUIDrawerComponent, {
  804. key: 'drawer',
  805. props: {
  806. className: ['vxe-table-custom-drawer-wrapper', 'vxe-table--ignore-clear', drawerOpts.className || ''].join(' '),
  807. value: customStore.visible,
  808. title: drawerOpts.title || getI18n('vxe.custom.cstmTitle'),
  809. width: drawerOpts.width || Math.min(880, Math.floor(document.documentElement.clientWidth * 0.6)),
  810. position: drawerOpts.position,
  811. resize: !!drawerOpts.resize,
  812. escClosable: !!drawerOpts.escClosable,
  813. maskClosable: !!drawerOpts.maskClosable,
  814. destroyOnClose: true,
  815. showFooter: true
  816. },
  817. on: {
  818. input (value: any) {
  819. customStore.visible = value
  820. }
  821. },
  822. scopedSlots
  823. })
  824. : renderEmptyElement($xeTableCustomPanel)
  825. }
  826. return VxeUIModalComponent
  827. ? h(VxeUIModalComponent, {
  828. key: 'modal',
  829. props: {
  830. className: ['vxe-table-custom-popup-wrapper', 'vxe-table--ignore-clear', modalOpts.className || ''].join(' '),
  831. value: customStore.visible,
  832. title: modalOpts.title || getI18n('vxe.custom.cstmTitle'),
  833. width: modalOpts.width || Math.min(880, document.documentElement.clientWidth),
  834. minWidth: modalOpts.minWidth || 700,
  835. height: modalOpts.height || Math.min(680, document.documentElement.clientHeight),
  836. minHeight: modalOpts.minHeight || 400,
  837. showZoom: modalOpts.showZoom,
  838. showMaximize: modalOpts.showMaximize,
  839. showMinimize: modalOpts.showMinimize,
  840. mask: modalOpts.mask,
  841. lockView: modalOpts.lockView,
  842. resize: modalOpts.resize,
  843. escClosable: !!modalOpts.escClosable,
  844. maskClosable: !!modalOpts.maskClosable,
  845. destroyOnClose: true,
  846. showFooter: true
  847. },
  848. on: {
  849. input (value: any) {
  850. customStore.visible = value
  851. }
  852. },
  853. scopedSlots
  854. })
  855. : renderEmptyElement($xeTableCustomPanel)
  856. }
  857. export default {
  858. name: 'VxeTableCustomPanel',
  859. props: {
  860. customStore: {
  861. type: Object,
  862. default: () => ({})
  863. }
  864. },
  865. provide () {
  866. const $xeTableCustomPanel = this
  867. return {
  868. $xeTableCustomPanel
  869. }
  870. },
  871. inject: {
  872. $xeTable: {
  873. default: null
  874. }
  875. },
  876. data () {
  877. const reactData: TableCustomPanelReactData = {
  878. dragCol: null,
  879. dragGroupField: null,
  880. dragAggFnCol: null,
  881. dragTipText: ''
  882. }
  883. const internalData: TableCustomPanelInternalData = {
  884. // prevDragCol: undefined,
  885. // prevDragGroupField: undefined,
  886. // prevDragAggFnColid: undefined,
  887. // prevDragToChild: false,
  888. // prevDragPos: null
  889. }
  890. return {
  891. reactData,
  892. internalData
  893. }
  894. },
  895. computed: {
  896. },
  897. created () {
  898. const $xeTableCustomPanel = this as any
  899. const VxeUIModalComponent = VxeUI.getComponent('VxeModal')
  900. const VxeUIDrawerComponent = VxeUI.getComponent('VxeDrawer')
  901. const VxeUIButtonComponent = VxeUI.getComponent('VxeButton')
  902. const VxeUINumberInputComponent = VxeUI.getComponent('VxeNumberInput')
  903. const VxeUIRadioGroupComponent = VxeUI.getComponent('VxeRadioGroup')
  904. $xeTableCustomPanel.$nextTick(() => {
  905. const $xeTable = $xeTableCustomPanel.$xeTable as VxeTableConstructor & VxeTablePrivateMethods
  906. const { customOpts } = $xeTable
  907. const { mode } = customOpts
  908. if (!VxeUIModalComponent && (mode === 'modal')) {
  909. errLog('vxe.error.reqComp', ['vxe-modal'])
  910. }
  911. if (!VxeUIDrawerComponent && (mode === 'drawer')) {
  912. errLog('vxe.error.reqComp', ['vxe-drawer'])
  913. }
  914. if (!VxeUIButtonComponent) {
  915. errLog('vxe.error.reqComp', ['vxe-button'])
  916. }
  917. if (!VxeUINumberInputComponent) {
  918. errLog('vxe.error.reqComp', ['vxe-number-input'])
  919. }
  920. if (!VxeUIRadioGroupComponent) {
  921. errLog('vxe.error.reqComp', ['vxe-radio-group'])
  922. }
  923. })
  924. },
  925. render (h: CreateElement) {
  926. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  927. const $xeTable = $xeTableCustomPanel.$xeTable
  928. const customOpts = $xeTable.computeCustomOpts
  929. if (['modal', 'drawer', 'popup'].includes(`${customOpts.mode}`)) {
  930. return renderPopupPanel(h, $xeTableCustomPanel)
  931. }
  932. return renderSimplePanel(h, $xeTableCustomPanel)
  933. },
  934. methods: {
  935. handleWrapperMouseenterEvent (evnt: any) {
  936. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  937. const $xeTable = $xeTableCustomPanel.$xeTable
  938. const { customStore } = this
  939. customStore.activeWrapper = true
  940. $xeTable.customOpenEvent(evnt)
  941. },
  942. handleWrapperMouseleaveEvent (evnt: any) {
  943. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  944. const $xeTable = $xeTableCustomPanel.$xeTable
  945. const props = $xeTableCustomPanel
  946. const { customStore } = props
  947. customStore.activeWrapper = false
  948. setTimeout(() => {
  949. if (!customStore.activeBtn && !customStore.activeWrapper) {
  950. $xeTable.customCloseEvent(evnt)
  951. }
  952. }, 300)
  953. },
  954. getStoreData () {
  955. return {}
  956. },
  957. confirmCustomEvent ({ $event }: VxeButtonDefines.ClickEventParams) {
  958. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  959. const $xeTable = $xeTableCustomPanel.$xeTable
  960. const tableReactData = $xeTable as unknown as TableReactData
  961. tableReactData.isCustomStatus = true
  962. $xeTable.saveCustom()
  963. $xeTable.closeCustom()
  964. $xeTable.emitCustomEvent('confirm', $event)
  965. },
  966. cancelCloseEvent ({ $event }: VxeButtonDefines.ClickEventParams) {
  967. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  968. const $xeTable = $xeTableCustomPanel.$xeTable
  969. $xeTable.closeCustom()
  970. $xeTable.emitCustomEvent('close', $event)
  971. },
  972. cancelCustomEvent ({ $event }: VxeButtonDefines.ClickEventParams) {
  973. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  974. const $xeTable = $xeTableCustomPanel.$xeTable
  975. $xeTable.cancelCustom()
  976. $xeTable.closeCustom()
  977. $xeTable.emitCustomEvent('cancel', $event)
  978. },
  979. handleResetCustomEvent (evnt: Event) {
  980. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  981. const $xeTable = $xeTableCustomPanel.$xeTable
  982. $xeTable.resetCustom(true)
  983. $xeTable.closeCustom()
  984. $xeTable.emitCustomEvent('reset', evnt)
  985. },
  986. resetCustomEvent (evnt: Event) {
  987. if (VxeUI.modal) {
  988. VxeUI.modal.confirm({
  989. content: getI18n('vxe.custom.cstmConfirmRestore'),
  990. className: 'vxe-table--ignore-clear',
  991. escClosable: true
  992. }).then(type => {
  993. if (type === 'confirm') {
  994. this.handleResetCustomEvent(evnt)
  995. }
  996. })
  997. } else {
  998. this.handleResetCustomEvent(evnt)
  999. }
  1000. },
  1001. handleOptionCheck (column: VxeTableDefines.ColumnInfo) {
  1002. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  1003. const $xeTable = $xeTableCustomPanel.$xeTable
  1004. const tableReactData = $xeTable as unknown as TableReactData
  1005. const { customColumnList } = tableReactData
  1006. const matchObj = XEUtils.findTree(customColumnList, item => item === column)
  1007. if (matchObj && matchObj.parent) {
  1008. const { parent } = matchObj
  1009. if (parent.children && parent.children.length) {
  1010. parent.renderVisible = parent.children.every((column) => column.renderVisible)
  1011. parent.halfVisible = !parent.renderVisible && parent.children.some((column) => column.renderVisible || column.halfVisible)
  1012. this.handleOptionCheck(parent)
  1013. }
  1014. }
  1015. },
  1016. changeCheckboxOption (column: VxeTableDefines.ColumnInfo, evnt: MouseEvent) {
  1017. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  1018. const $xeTable = $xeTableCustomPanel.$xeTable
  1019. const tableReactData = $xeTable as unknown as TableReactData
  1020. const isChecked = !column.renderVisible
  1021. const customOpts = $xeTable.computeCustomOpts
  1022. if (customOpts.immediate) {
  1023. XEUtils.eachTree([column], (item) => {
  1024. item.visible = isChecked
  1025. item.renderVisible = isChecked
  1026. item.halfVisible = false
  1027. })
  1028. tableReactData.isCustomStatus = true
  1029. $xeTable.handleCustom()
  1030. $xeTable.saveCustomStore('update:visible')
  1031. } else {
  1032. XEUtils.eachTree([column], (item) => {
  1033. item.renderVisible = isChecked
  1034. item.halfVisible = false
  1035. })
  1036. }
  1037. this.handleOptionCheck(column)
  1038. $xeTable.checkCustomStatus()
  1039. $xeTable.dispatchEvent('custom-visible-change', { column, checked: isChecked }, evnt)
  1040. },
  1041. changeColumnWidth (column: VxeTableDefines.ColumnInfo) {
  1042. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  1043. const $xeTable = $xeTableCustomPanel.$xeTable
  1044. const tableReactData = $xeTable as unknown as TableReactData
  1045. const customOpts = $xeTable.computeCustomOpts
  1046. if (customOpts.immediate) {
  1047. if (column.renderResizeWidth !== column.renderWidth) {
  1048. column.resizeWidth = column.renderResizeWidth
  1049. column.renderWidth = column.renderResizeWidth
  1050. tableReactData.isCustomStatus = true
  1051. $xeTable.handleCustom()
  1052. $xeTable.saveCustomStore('update:width')
  1053. }
  1054. }
  1055. },
  1056. changeFixedOption (column: VxeTableDefines.ColumnInfo, colFixed: VxeColumnPropTypes.Fixed, evnt: Event) {
  1057. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  1058. const $xeTable = $xeTableCustomPanel.$xeTable
  1059. const tableReactData = $xeTable as unknown as TableReactData
  1060. const isMaxFixedColumn = $xeTable.computeIsMaxFixedColumn
  1061. const customOpts = $xeTable.computeCustomOpts
  1062. let targetFixed: VxeColumnPropTypes.Fixed = null
  1063. if (customOpts.immediate) {
  1064. if (column.renderFixed === colFixed) {
  1065. targetFixed = ''
  1066. XEUtils.eachTree([column], col => {
  1067. col.fixed = ''
  1068. col.renderFixed = ''
  1069. })
  1070. } else {
  1071. if (!isMaxFixedColumn || column.renderFixed) {
  1072. targetFixed = colFixed
  1073. XEUtils.eachTree([column], col => {
  1074. col.fixed = colFixed
  1075. col.renderFixed = colFixed
  1076. })
  1077. }
  1078. }
  1079. tableReactData.isCustomStatus = true
  1080. $xeTable.handleCustom()
  1081. $xeTable.saveCustomStore('update:fixed')
  1082. } else {
  1083. if (column.renderFixed === colFixed) {
  1084. targetFixed = ''
  1085. XEUtils.eachTree([column], col => {
  1086. col.renderFixed = ''
  1087. })
  1088. } else {
  1089. if (!isMaxFixedColumn || column.renderFixed) {
  1090. targetFixed = colFixed
  1091. XEUtils.eachTree([column], col => {
  1092. col.renderFixed = colFixed
  1093. })
  1094. }
  1095. }
  1096. }
  1097. if (targetFixed !== null) {
  1098. $xeTable.dispatchEvent('custom-fixed-change', { column, fixed: targetFixed }, evnt)
  1099. }
  1100. },
  1101. allOptionEvent (evnt: MouseEvent) {
  1102. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  1103. const $xeTable = $xeTableCustomPanel.$xeTable
  1104. const tableReactData = $xeTable as unknown as TableReactData
  1105. const { customStore } = tableReactData
  1106. const isAll = !customStore.isAll
  1107. $xeTable.toggleCustomAllCheckbox()
  1108. $xeTable.dispatchEvent('custom-visible-all', { checked: isAll }, evnt)
  1109. },
  1110. updateColDropTipContent () {
  1111. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  1112. const $xeTable = $xeTableCustomPanel.$xeTable
  1113. const customPanelReactData = $xeTableCustomPanel.reactData
  1114. const { dragCol } = customPanelReactData
  1115. const columnDragOpts = $xeTable.computeColumnDragOpts
  1116. const { tooltipMethod } = columnDragOpts
  1117. let tipContent = ''
  1118. if (tooltipMethod) {
  1119. const dtParams = {
  1120. $table: $xeTable,
  1121. column: dragCol as VxeTableDefines.ColumnInfo
  1122. }
  1123. tipContent = `${tooltipMethod(dtParams) || ''}`
  1124. } else {
  1125. tipContent = getI18n('vxe.custom.cstmDragTarget', [dragCol && dragCol.type !== 'html' ? dragCol.getTitle() : ''])
  1126. }
  1127. customPanelReactData.dragTipText = tipContent
  1128. },
  1129. sortMousedownEvent (evnt: MouseEvent) {
  1130. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  1131. const $xeTable = $xeTableCustomPanel.$xeTable
  1132. const customPanelReactData = $xeTableCustomPanel.reactData
  1133. const btnEl = evnt.currentTarget as HTMLElement
  1134. const cellEl = btnEl.parentElement as HTMLElement
  1135. const tdEl = cellEl.parentElement as HTMLElement
  1136. const trEl = tdEl.parentElement as HTMLElement
  1137. const colid = trEl.getAttribute('colid')
  1138. const column = $xeTable.getColumnById(colid)
  1139. trEl.draggable = true
  1140. customPanelReactData.dragCol = column
  1141. customPanelReactData.dragGroupField = null
  1142. customPanelReactData.dragAggFnCol = null
  1143. this.updateColDropTipContent()
  1144. addClass(trEl, 'active--drag-origin')
  1145. },
  1146. sortMouseupEvent (evnt: MouseEvent) {
  1147. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  1148. const customPanelReactData = $xeTableCustomPanel.reactData
  1149. const btnEl = evnt.currentTarget as HTMLElement
  1150. const cellEl = btnEl.parentElement as HTMLElement
  1151. const tdEl = cellEl.parentElement as HTMLElement
  1152. const trEl = tdEl.parentElement as HTMLElement
  1153. hideDropTip($xeTableCustomPanel)
  1154. trEl.draggable = false
  1155. customPanelReactData.dragCol = null
  1156. customPanelReactData.dragGroupField = null
  1157. customPanelReactData.dragAggFnCol = null
  1158. removeClass(trEl, 'active--drag-origin')
  1159. },
  1160. sortDragstartEvent (evnt: any) {
  1161. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  1162. const customPanelInternalData = $xeTableCustomPanel.internalData
  1163. if (evnt.dataTransfer) {
  1164. evnt.dataTransfer.setDragImage(getTpImg(), 0, 0)
  1165. }
  1166. customPanelInternalData.prevDragGroupField = null
  1167. customPanelInternalData.prevDragAggFnColid = null
  1168. },
  1169. sortDragendEvent (evnt: any) {
  1170. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  1171. const $xeTable = $xeTableCustomPanel.$xeTable
  1172. const tableProps = $xeTable
  1173. const tableReactData = $xeTable as unknown as TableReactData
  1174. const tableInternalData = $xeTable as unknown as TableInternalData
  1175. const customPanelReactData = $xeTableCustomPanel.reactData
  1176. const customPanelInternalData = $xeTableCustomPanel.internalData
  1177. const { mouseConfig } = tableProps
  1178. const { customColumnList } = tableReactData
  1179. const { collectColumn } = tableInternalData
  1180. const customOpts = $xeTable.computeCustomOpts
  1181. const { immediate } = customOpts
  1182. const trEl = evnt.currentTarget as HTMLElement
  1183. const columnDragOpts = $xeTable.computeColumnDragOpts
  1184. const { isCrossDrag, isSelfToChildDrag, isToChildDrag, dragEndMethod } = columnDragOpts
  1185. const { dragCol } = customPanelReactData
  1186. const { prevDragCol, prevDragGroupField, prevDragAggFnColid, prevDragPos, prevDragToChild } = customPanelInternalData
  1187. const dragOffsetIndex = prevDragPos === 'bottom' ? 1 : 0
  1188. if (prevDragGroupField || prevDragAggFnColid) {
  1189. if ($xeTable.handlePivotTableAggregatePanelDragendEvent) {
  1190. $xeTable.handlePivotTableAggregatePanelDragendEvent(evnt)
  1191. }
  1192. } else if (prevDragCol && dragCol) {
  1193. // 判断是否有拖动
  1194. if (prevDragCol !== dragCol) {
  1195. const dragColumn: VxeTableDefines.ColumnInfo = dragCol
  1196. const newColumn: VxeTableDefines.ColumnInfo = prevDragCol
  1197. Promise.resolve(
  1198. dragEndMethod
  1199. ? dragEndMethod({
  1200. oldColumn: dragColumn,
  1201. newColumn,
  1202. dragColumn,
  1203. dragPos: prevDragPos as any,
  1204. dragToChild: !!prevDragToChild,
  1205. offsetIndex: dragOffsetIndex
  1206. })
  1207. : true
  1208. ).then((status) => {
  1209. if (!status) {
  1210. return
  1211. }
  1212. let oafIndex = -1
  1213. let nafIndex = -1
  1214. const oldAllMaps: Record<string, any> = {}
  1215. XEUtils.eachTree([dragColumn], column => {
  1216. oldAllMaps[column.id] = column
  1217. })
  1218. let isSelfToChildStatus = false
  1219. // 只有实时拖拽支持跨层级
  1220. if (immediate) {
  1221. if (dragColumn.parentId && newColumn.parentId) {
  1222. // 子到子
  1223. if (!isCrossDrag) {
  1224. return
  1225. }
  1226. if (oldAllMaps[newColumn.id]) {
  1227. isSelfToChildStatus = true
  1228. if (!(isCrossDrag && isSelfToChildDrag)) {
  1229. if (VxeUI.modal) {
  1230. VxeUI.modal.message({
  1231. status: 'error',
  1232. content: getI18n('vxe.error.treeDragChild')
  1233. })
  1234. }
  1235. return
  1236. }
  1237. }
  1238. } else if (dragColumn.parentId) {
  1239. // 子到根
  1240. if (!isCrossDrag) {
  1241. return
  1242. }
  1243. } else if (newColumn.parentId) {
  1244. // 根到子
  1245. if (!isCrossDrag) {
  1246. return
  1247. }
  1248. if (oldAllMaps[newColumn.id]) {
  1249. isSelfToChildStatus = true
  1250. if (!(isCrossDrag && isSelfToChildDrag)) {
  1251. if (VxeUI.modal) {
  1252. VxeUI.modal.message({
  1253. status: 'error',
  1254. content: getI18n('vxe.error.treeDragChild')
  1255. })
  1256. }
  1257. return
  1258. }
  1259. }
  1260. } else {
  1261. // 根到根
  1262. }
  1263. const oldewMatchRest = XEUtils.findTree(collectColumn as VxeTableDefines.ColumnInfo[], item => item.id === dragColumn.id)
  1264. // 改变层级
  1265. if (isSelfToChildStatus && (isCrossDrag && isSelfToChildDrag)) {
  1266. if (oldewMatchRest) {
  1267. const { items: oCols, index: oIndex } = oldewMatchRest
  1268. const childList = dragColumn.children || []
  1269. childList.forEach(column => {
  1270. column.parentId = dragColumn.parentId
  1271. })
  1272. oCols.splice(oIndex, 1, ...childList)
  1273. dragColumn.children = []
  1274. }
  1275. } else {
  1276. if (oldewMatchRest) {
  1277. const { items: oCols, index: oIndex, parent: oParent } = oldewMatchRest
  1278. oCols.splice(oIndex, 1)
  1279. if (!oParent) {
  1280. oafIndex = oIndex
  1281. }
  1282. }
  1283. }
  1284. const newMatchRest = XEUtils.findTree(collectColumn as VxeTableDefines.ColumnInfo[], item => item.id === newColumn.id)
  1285. if (newMatchRest) {
  1286. const { items: nCols, index: nIndex, parent: nParent } = newMatchRest
  1287. // 转子级
  1288. if ((isCrossDrag && isToChildDrag) && prevDragToChild) {
  1289. dragColumn.parentId = newColumn.id
  1290. newColumn.children = (newColumn.children || []).concat([dragColumn])
  1291. } else {
  1292. dragColumn.parentId = newColumn.parentId
  1293. nCols.splice(nIndex + dragOffsetIndex, 0, dragColumn)
  1294. }
  1295. if (!nParent) {
  1296. nafIndex = nIndex
  1297. }
  1298. }
  1299. XEUtils.eachTree(collectColumn, (column, index, items, path, parent) => {
  1300. if (!parent) {
  1301. const sortIndex = index + 1
  1302. column.renderSortNumber = sortIndex
  1303. }
  1304. })
  1305. } else {
  1306. oafIndex = XEUtils.findIndexOf(customColumnList, item => item.id === dragColumn.id)
  1307. customColumnList.splice(oafIndex, 1)
  1308. nafIndex = XEUtils.findIndexOf(customColumnList, item => item.id === newColumn.id)
  1309. customColumnList.splice(nafIndex + dragOffsetIndex, 0, dragColumn)
  1310. }
  1311. if (mouseConfig) {
  1312. if ($xeTable.clearSelected) {
  1313. $xeTable.clearSelected()
  1314. }
  1315. if ($xeTable.clearCellAreas) {
  1316. $xeTable.clearCellAreas()
  1317. $xeTable.clearCopyCellArea()
  1318. }
  1319. }
  1320. const csParams = {
  1321. oldColumn: dragColumn,
  1322. newColumn,
  1323. dragColumn,
  1324. dragPos: prevDragPos,
  1325. offsetIndex: dragOffsetIndex,
  1326. _index: {
  1327. newIndex: nafIndex,
  1328. oldIndex: oafIndex
  1329. }
  1330. }
  1331. $xeTable.dispatchEvent('custom-sort-change', csParams, evnt)
  1332. $xeTable.dispatchEvent('column-dragend', csParams, evnt)
  1333. if (immediate) {
  1334. tableReactData.customColumnList = collectColumn.slice(0)
  1335. $xeTable.handleColDragSwapColumn()
  1336. }
  1337. }).catch(() => {
  1338. })
  1339. }
  1340. }
  1341. hideDropTip($xeTableCustomPanel)
  1342. customPanelReactData.dragCol = null
  1343. customPanelReactData.dragGroupField = null
  1344. customPanelReactData.dragAggFnCol = null
  1345. customPanelInternalData.prevDragGroupField = null
  1346. customPanelInternalData.prevDragAggFnColid = null
  1347. trEl.draggable = false
  1348. trEl.removeAttribute('drag-pos')
  1349. removeClass(trEl, 'active--drag-target')
  1350. removeClass(trEl, 'active--drag-origin')
  1351. },
  1352. sortDragoverEvent (evnt: DragEvent) {
  1353. const $xeTableCustomPanel = this as unknown as VxeTableCustomPanelConstructor
  1354. const $xeTable = $xeTableCustomPanel.$xeTable
  1355. const customPanelReactData = $xeTableCustomPanel.reactData
  1356. const customPanelInternalData = $xeTableCustomPanel.internalData
  1357. const { dragCol } = customPanelReactData
  1358. const customOpts = $xeTable.computeCustomOpts
  1359. const { immediate } = customOpts
  1360. const columnDragOpts = $xeTable.computeColumnDragOpts
  1361. const { isCrossDrag, isToChildDrag } = columnDragOpts
  1362. const optEl = evnt.currentTarget as HTMLElement
  1363. const isControlKey = hasControlKey(evnt)
  1364. const colid = optEl.getAttribute('colid')
  1365. const column = $xeTable.getColumnById(colid)
  1366. customPanelInternalData.prevDragGroupField = null
  1367. customPanelInternalData.prevDragAggFnColid = null
  1368. // 是否移入有效列
  1369. if (column && (isCrossDrag || column.level === 1)) {
  1370. evnt.preventDefault()
  1371. const offsetY = evnt.clientY - optEl.getBoundingClientRect().y
  1372. const dragPos = offsetY < optEl.clientHeight / 2 ? 'top' : 'bottom'
  1373. if (
  1374. !dragCol ||
  1375. (dragCol && dragCol.id === column.id) ||
  1376. (!isCrossDrag && column.level > 1) ||
  1377. (!immediate && column.level > 1)
  1378. ) {
  1379. showDropTip($xeTableCustomPanel, evnt, optEl, false, dragPos)
  1380. return
  1381. }
  1382. customPanelInternalData.prevDragToChild = !!((isCrossDrag && isToChildDrag) && isControlKey && immediate)
  1383. customPanelInternalData.prevDragCol = column
  1384. customPanelInternalData.prevDragPos = dragPos
  1385. showDropTip($xeTableCustomPanel, evnt, optEl, true, dragPos)
  1386. }
  1387. }
  1388. } as any
  1389. }