@visactor/vtable-sheet 1.23.3-alpha.0 → 1.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/cjs/components/sheet-tab-event-handler.js +2 -5
  2. package/cjs/components/sheet-tab-event-handler.js.map +1 -1
  3. package/cjs/components/vtable-sheet.d.ts +14 -0
  4. package/cjs/components/vtable-sheet.js +77 -55
  5. package/cjs/components/vtable-sheet.js.map +1 -1
  6. package/cjs/core/WorkSheet.js +3 -46
  7. package/cjs/core/WorkSheet.js.map +1 -1
  8. package/cjs/core/table-plugins.js +30 -2
  9. package/cjs/core/table-plugins.js.map +1 -1
  10. package/cjs/formula/formula-editor.d.ts +1 -1
  11. package/cjs/formula/formula-editor.js +22 -5
  12. package/cjs/formula/formula-editor.js.map +1 -1
  13. package/cjs/formula/formula-engine.d.ts +1 -0
  14. package/cjs/formula/formula-engine.js +47 -16
  15. package/cjs/formula/formula-engine.js.map +1 -1
  16. package/cjs/formula/formula-range-selector.js +1 -5
  17. package/cjs/formula/formula-range-selector.js.map +1 -1
  18. package/cjs/index.d.ts +1 -1
  19. package/cjs/index.js +1 -1
  20. package/cjs/index.js.map +1 -1
  21. package/cjs/managers/formula-manager.d.ts +3 -1
  22. package/cjs/managers/formula-manager.js +7 -5
  23. package/cjs/managers/formula-manager.js.map +1 -1
  24. package/cjs/managers/menu-manager.d.ts +7 -1
  25. package/cjs/managers/menu-manager.js +37 -4
  26. package/cjs/managers/menu-manager.js.map +1 -1
  27. package/cjs/managers/tab-drag-manager.d.ts +2 -2
  28. package/cjs/managers/tab-drag-manager.js +1 -2
  29. package/cjs/managers/tab-drag-manager.js.map +1 -1
  30. package/cjs/managers/workbook-history-manager.d.ts +53 -0
  31. package/cjs/managers/workbook-history-manager.js +294 -0
  32. package/cjs/managers/workbook-history-manager.js.map +1 -0
  33. package/cjs/styles/menu.js +1 -1
  34. package/cjs/styles/menu.js.map +1 -1
  35. package/cjs/test-shims/vtable-plugins.d.ts +5 -0
  36. package/cjs/test-shims/vtable-plugins.js +34 -0
  37. package/cjs/test-shims/vtable-plugins.js.map +1 -0
  38. package/cjs/ts-types/base.js +1 -2
  39. package/cjs/ts-types/formula.js +2 -1
  40. package/cjs/ts-types/index.d.ts +4 -0
  41. package/cjs/ts-types/index.js.map +1 -1
  42. package/dist/vtable-sheet.js +2559 -336
  43. package/dist/vtable-sheet.min.js +1 -1
  44. package/es/components/sheet-tab-event-handler.js +1 -4
  45. package/es/components/sheet-tab-event-handler.js.map +1 -1
  46. package/es/components/vtable-sheet.d.ts +14 -0
  47. package/es/components/vtable-sheet.js +76 -33
  48. package/es/components/vtable-sheet.js.map +1 -1
  49. package/es/core/WorkSheet.js +3 -46
  50. package/es/core/WorkSheet.js.map +1 -1
  51. package/es/core/table-plugins.js +31 -1
  52. package/es/core/table-plugins.js.map +1 -1
  53. package/es/formula/formula-editor.d.ts +1 -1
  54. package/es/formula/formula-editor.js +19 -4
  55. package/es/formula/formula-editor.js.map +1 -1
  56. package/es/formula/formula-engine.d.ts +1 -0
  57. package/es/formula/formula-engine.js +47 -16
  58. package/es/formula/formula-engine.js.map +1 -1
  59. package/es/formula/formula-range-selector.js +1 -5
  60. package/es/formula/formula-range-selector.js.map +1 -1
  61. package/es/index.d.ts +1 -1
  62. package/es/index.js +1 -1
  63. package/es/index.js.map +1 -1
  64. package/es/managers/formula-manager.d.ts +3 -1
  65. package/es/managers/formula-manager.js +7 -5
  66. package/es/managers/formula-manager.js.map +1 -1
  67. package/es/managers/menu-manager.d.ts +7 -1
  68. package/es/managers/menu-manager.js +37 -4
  69. package/es/managers/menu-manager.js.map +1 -1
  70. package/es/managers/tab-drag-manager.d.ts +2 -2
  71. package/es/managers/tab-drag-manager.js +1 -2
  72. package/es/managers/tab-drag-manager.js.map +1 -1
  73. package/es/managers/workbook-history-manager.d.ts +53 -0
  74. package/es/managers/workbook-history-manager.js +286 -0
  75. package/es/managers/workbook-history-manager.js.map +1 -0
  76. package/es/styles/menu.js +1 -1
  77. package/es/styles/menu.js.map +1 -1
  78. package/es/test-shims/vtable-plugins.d.ts +5 -0
  79. package/es/test-shims/vtable-plugins.js +6 -0
  80. package/es/test-shims/vtable-plugins.js.map +1 -0
  81. package/es/ts-types/base.js +1 -2
  82. package/es/ts-types/formula.js +2 -1
  83. package/es/ts-types/index.d.ts +4 -0
  84. package/es/ts-types/index.js.map +1 -1
  85. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/managers/menu-manager.ts"],"names":[],"mappings":"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","file":"menu-manager.js","sourcesContent":["import type VTableSheet from '../components/vtable-sheet';\nimport type { IVTableSheetOptions } from '../ts-types';\nimport type { MainMenuItem } from '../ts-types/base';\nimport { MainMenuItemKey } from '../ts-types/base';\n\nexport class MenuManager {\n private sheet: VTableSheet;\n private menuContainer: HTMLElement;\n private clickOutsideHandler: (e: MouseEvent) => void;\n constructor(sheet: VTableSheet) {\n this.sheet = sheet;\n this.createMainMenu();\n }\n\n createMainMenu(): HTMLElement {\n const menuIcon = `<svg t=\"1754379519717\" class=\"icon\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"1496\" width=\"24\" height=\"24\"><path d=\"M510.435876 67.959811c-245.428735 0-444.382996 198.954261-444.382996 444.373787 0 245.420549 198.954261 444.373787 444.382996 444.373787 245.410316 0 444.372763-198.953238 444.372763-444.373787C954.807616 266.914072 755.846192 67.959811 510.435876 67.959811zM510.435876 901.156184c-214.743876 0-388.831796-174.08792-388.831796-388.822586 0-214.743876 174.088944-388.831796 388.831796-388.831796 214.732619 0 388.822586 174.08792 388.822586 388.831796C899.257439 727.068264 725.167472 901.156184 510.435876 901.156184zM666.028561 329.355193 337.411171 329.355193c-15.117302 0-27.384697 15.60235-27.384697 34.844599 0 19.259646 12.267395 34.861996 27.384697 34.861996l328.618413 0c15.124466 0 27.375487-15.60235 27.375487-34.861996C693.404048 344.957543 681.15405 329.355193 666.028561 329.355193zM666.028561 486.191194 337.411171 486.191194c-15.117302 0-27.384697 15.601326-27.384697 34.852786 0 19.25146 12.267395 34.853809 27.384697 34.853809l328.618413 0c15.124466 0 27.375487-15.601326 27.375487-34.853809C693.404048 501.792521 681.15405 486.191194 666.028561 486.191194zM666.028561 625.604384 337.411171 625.604384c-15.117302 0-27.384697 15.60235-27.384697 34.845623 0 19.25146 12.267395 34.861996 27.384697 34.861996l328.618413 0c15.124466 0 27.375487-15.611559 27.375487-34.861996C693.404048 641.206734 681.15405 625.604384 666.028561 625.604384z\" fill=\"#8a8a8a\" p-id=\"1497\"></path></svg>`;\n // const menuIcon = `<svg t=\"1754379884941\" class=\"icon\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\"><path d=\"M41.79704403125004 158.46048700694445l588.8681891302084 0 0 117.0003645451389-588.8681891302084 0 0-117.0003645451389Z\" p-id=\"5684\" fill=\"#8a8a8a\"></path><path d=\"M41.79704403124998 394.9996354548611l588.8681891302086 0 0 117.0003645451389-588.8681891302086 0 0-117.0003645451389Z\" p-id=\"5685\" fill=\"#8a8a8a\"></path><path d=\"M41.79704403124998 629.4749666302083l588.8681891302084 0 0 117.0003645451389-588.8681891302084 0 0-117.0003645451389Z\" p-id=\"5686\" fill=\"#8a8a8a\"></path><path d=\"M831.596434 638.445854 642.224412 384.604518 1023.977999 384.604518Z\" p-id=\"5687\" fill=\"#8a8a8a\"></path></svg>`;\n const menu = document.createElement('div');\n menu.className = 'vtable-sheet-main-menu';\n menu.style.position = 'relative'; // 关键:为子菜单提供定位基准\n\n // 菜单按钮\n const menuButton = document.createElement('span');\n menuButton.className = 'vtable-sheet-main-menu-button';\n menuButton.innerHTML = menuIcon;\n menu.appendChild(menuButton);\n\n // 菜单项容器(直接作为 menu 的子元素)\n const menuContainer = document.createElement('div');\n menuContainer.className = 'vtable-sheet-main-menu-container';\n menu.appendChild(menuContainer); // 挂载到 menu 内部\n\n // 菜单项列表\n const menuItems = document.createElement('ul');\n menuItems.className = 'vtable-sheet-main-menu-items';\n menuContainer.appendChild(menuItems);\n\n // 动态生成菜单项\n this.sheet.getOptions().mainMenu?.items?.forEach(item => {\n const li = document.createElement('li');\n li.className = 'vtable-sheet-main-menu-item';\n li.textContent = item.name;\n li.title = item.description || ''; //title提示\n if (item.items) {\n li.classList.add('vtable-sheet-main-menu-item-has-children');\n li.onmouseenter = () => {\n const subMenu = this.createSubMenu(item.items);\n li.appendChild(subMenu);\n };\n li.onmouseleave = () => {\n li.classList.remove('vtable-sheet-main-menu-item-has-children-hover');\n if (li.querySelector('.vtable-sheet-main-menu-sub-menu')) {\n li.removeChild(li.querySelector('.vtable-sheet-main-menu-sub-menu'));\n }\n };\n }\n li.addEventListener('click', () => {\n if (item.onClick) {\n item.onClick();\n return;\n }\n if (item.menuKey) {\n this.handleMenuClick(item.menuKey);\n }\n });\n menuItems.appendChild(li);\n });\n\n // 点击事件逻辑\n menuButton.addEventListener('click', e => {\n e.stopPropagation();\n menuContainer.classList.toggle('active');\n });\n\n // 点击外部关闭菜单\n this.clickOutsideHandler = (e: MouseEvent) => {\n if (!menu.contains(e.target as Node)) {\n menuContainer.classList.remove('active');\n }\n };\n document.addEventListener('click', this.clickOutsideHandler);\n this.menuContainer = menuContainer;\n return menu;\n }\n //TODO 需要重新逻辑,需要支持多级菜单\n private createSubMenu(items: MainMenuItem[]): HTMLElement {\n // 创建子菜单容器\n const subMenuContainer = document.createElement('div');\n subMenuContainer.className = 'vtable-sheet-submenu-container';\n\n // 创建子菜单列表\n const subMenuList = document.createElement('ul');\n subMenuList.className = 'vtable-sheet-main-menu-items';\n\n // 动态生成子菜单项\n items.forEach(item => {\n const li = document.createElement('li');\n li.className = 'vtable-sheet-submenu-item';\n li.textContent = item.name;\n li.title = item.description || '';\n\n // 绑定点击事件\n li.addEventListener('click', e => {\n e.stopPropagation();\n if (item.onClick) {\n item.onClick();\n } else if (item.menuKey) {\n this.handleMenuClick(item.menuKey);\n }\n this.hideAllSubMenus(); // 点击后关闭所有子菜单\n });\n\n // 如果有嵌套子菜单\n if (item.items?.length) {\n // li.classList.add('has-submenu');\n li.classList.add('vtable-sheet-main-menu-item-has-children');\n // const arrowIcon = document.createElement('span');\n // arrowIcon.className = 'submenu-arrow';\n // arrowIcon.innerHTML = '▶';\n // li.appendChild(arrowIcon);\n\n // 鼠标悬停显示嵌套子菜单\n li.addEventListener('mouseenter', () => {\n this.hideAllSubMenus(li); // 先关闭其他子菜单\n const nestedSubMenu = this.createSubMenu(item.items);\n li.appendChild(nestedSubMenu);\n this.adjustSubMenuPosition(nestedSubMenu); // 调整定位\n });\n }\n\n subMenuList.appendChild(li);\n });\n\n subMenuContainer.appendChild(subMenuList);\n return subMenuContainer;\n }\n\n // 调整子菜单定位(避免超出视口)\n private adjustSubMenuPosition(subMenu: HTMLElement) {\n const rect = subMenu.getBoundingClientRect();\n if (rect.right > window.innerWidth) {\n subMenu.style.left = 'auto';\n subMenu.style.right = '100%'; // 改为向左展开\n }\n if (rect.bottom > window.innerHeight) {\n subMenu.style.top = 'auto';\n subMenu.style.bottom = '0'; // 向上对齐\n }\n }\n\n // 关闭所有子菜单(保留当前激活项)并隐藏主菜单\n private hideAllSubMenus(exceptElement?: HTMLElement) {\n document.querySelectorAll('.vtable-sheet-submenu-container').forEach(menu => {\n if (menu !== exceptElement?.closest('.vtable-sheet-submenu-container')) {\n menu.remove();\n }\n });\n this.menuContainer.classList.remove('active');\n }\n handleMenuClick(menuKey: MainMenuItemKey) {\n const tableInstance = this.sheet.getActiveSheet().tableInstance;\n const eventManager = this.sheet.getSpreadSheetEventManager();\n\n switch (menuKey) {\n case MainMenuItemKey.IMPORT:\n if (this.sheet.importFileToSheet) {\n this.sheet.importFileToSheet();\n }\n break;\n\n case MainMenuItemKey.EXPORT_CURRENT_SHEET_CSV:\n try {\n // 触发导出开始事件\n eventManager.emitExportStart('csv', false);\n\n if ((tableInstance as any)?.exportToCsv) {\n (tableInstance as any).exportToCsv();\n // 触发导出完成事件\n eventManager.emitExportCompleted('csv', false, 1);\n } else {\n console.warn('Please configure TableExportPlugin in VTablePluginModules');\n // 触发导出失败事件\n eventManager.emitExportError('csv', false, 'TableExportPlugin not configured');\n }\n } catch (error) {\n // 触发导出失败事件\n const errorMessage = error instanceof Error ? error.message : String(error);\n eventManager.emitExportError('csv', false, errorMessage);\n console.warn('Export to CSV failed:', errorMessage);\n }\n break;\n\n case MainMenuItemKey.EXPORT_CURRENT_SHEET_XLSX:\n try {\n // 触发导出开始事件\n eventManager.emitExportStart('xlsx', false);\n\n if ((tableInstance as any)?.exportToExcel) {\n (tableInstance as any).exportToExcel();\n // 触发导出完成事件\n eventManager.emitExportCompleted('xlsx', false, 1);\n } else {\n console.warn('Please configure TableExportPlugin in VTablePluginModules');\n // 触发导出失败事件\n eventManager.emitExportError('xlsx', false, 'TableExportPlugin not configured');\n }\n } catch (error) {\n // 触发导出失败事件\n const errorMessage = error instanceof Error ? error.message : String(error);\n eventManager.emitExportError('xlsx', false, errorMessage);\n console.warn('Export to Excel failed:', errorMessage);\n }\n break;\n\n case MainMenuItemKey.EXPORT_ALL_SHEETS_XLSX:\n try {\n // 触发导出开始事件\n eventManager.emitExportStart('xlsx', true);\n\n // 多 sheet 导出走 vtable-plugins 的导出工具,不依赖向 tableInstance 注入 exportToExcel\n if (this.sheet.exportAllSheetsToExcel) {\n this.sheet.exportAllSheetsToExcel();\n // 触发导出完成事件\n const sheetCount = this.sheet.getSheetCount();\n eventManager.emitExportCompleted('xlsx', true, sheetCount);\n } else {\n console.warn('Export all sheets method not available');\n // 触发导出失败事件\n eventManager.emitExportError('xlsx', true, 'Export all sheets method not available');\n }\n } catch (error) {\n // 触发导出失败事件\n const errorMessage = error instanceof Error ? error.message : String(error);\n eventManager.emitExportError('xlsx', true, errorMessage);\n console.warn('Export all sheets failed:', errorMessage);\n }\n break;\n\n default:\n break;\n }\n }\n\n /**\n * 清理菜单管理器,移除全局事件监听器\n */\n release(): void {\n if (this.clickOutsideHandler) {\n document.removeEventListener('click', this.clickOutsideHandler);\n this.clickOutsideHandler = null;\n }\n }\n updateMainMenu(mainMenu: IVTableSheetOptions['mainMenu']): void {\n this.release();\n this.createMainMenu();\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/managers/menu-manager.ts"],"names":[],"mappings":"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","file":"menu-manager.js","sourcesContent":["import type VTableSheet from '../components/vtable-sheet';\nimport type { IVTableSheetOptions } from '../ts-types';\nimport type { MainMenuItem } from '../ts-types/base';\nimport { MainMenuItemKey } from '../ts-types/base';\n\nexport class MenuManager {\n private sheet: VTableSheet;\n private menuContainer: HTMLElement;\n private undoButton: HTMLButtonElement | null = null;\n private redoButton: HTMLButtonElement | null = null;\n private clickOutsideHandler: (e: MouseEvent) => void;\n private historyUnsubscribe: (() => void) | null = null;\n constructor(sheet: VTableSheet) {\n this.sheet = sheet;\n }\n\n createUndoRedoOnly(): HTMLElement {\n const wrap = document.createElement('div');\n wrap.className = 'vtable-sheet-undo-redo';\n this.mountUndoRedoActions(wrap);\n return wrap;\n }\n\n createMainMenu(): HTMLElement {\n const menuIcon = `<svg t=\"1754379519717\" class=\"icon\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"1496\" width=\"24\" height=\"24\"><path d=\"M510.435876 67.959811c-245.428735 0-444.382996 198.954261-444.382996 444.373787 0 245.420549 198.954261 444.373787 444.382996 444.373787 245.410316 0 444.372763-198.953238 444.372763-444.373787C954.807616 266.914072 755.846192 67.959811 510.435876 67.959811zM510.435876 901.156184c-214.743876 0-388.831796-174.08792-388.831796-388.822586 0-214.743876 174.088944-388.831796 388.831796-388.831796 214.732619 0 388.822586 174.08792 388.822586 388.831796C899.257439 727.068264 725.167472 901.156184 510.435876 901.156184zM666.028561 329.355193 337.411171 329.355193c-15.117302 0-27.384697 15.60235-27.384697 34.844599 0 19.259646 12.267395 34.861996 27.384697 34.861996l328.618413 0c15.124466 0 27.375487-15.60235 27.375487-34.861996C693.404048 344.957543 681.15405 329.355193 666.028561 329.355193zM666.028561 486.191194 337.411171 486.191194c-15.117302 0-27.384697 15.601326-27.384697 34.852786 0 19.25146 12.267395 34.853809 27.384697 34.853809l328.618413 0c15.124466 0 27.375487-15.601326 27.375487-34.853809C693.404048 501.792521 681.15405 486.191194 666.028561 486.191194zM666.028561 625.604384 337.411171 625.604384c-15.117302 0-27.384697 15.60235-27.384697 34.845623 0 19.25146 12.267395 34.861996 27.384697 34.861996l328.618413 0c15.124466 0 27.375487-15.611559 27.375487-34.861996C693.404048 641.206734 681.15405 625.604384 666.028561 625.604384z\" fill=\"#8a8a8a\" p-id=\"1497\"></path></svg>`;\n // const menuIcon = `<svg t=\"1754379884941\" class=\"icon\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\"><path d=\"M41.79704403125004 158.46048700694445l588.8681891302084 0 0 117.0003645451389-588.8681891302084 0 0-117.0003645451389Z\" p-id=\"5684\" fill=\"#8a8a8a\"></path><path d=\"M41.79704403124998 394.9996354548611l588.8681891302086 0 0 117.0003645451389-588.8681891302086 0 0-117.0003645451389Z\" p-id=\"5685\" fill=\"#8a8a8a\"></path><path d=\"M41.79704403124998 629.4749666302083l588.8681891302084 0 0 117.0003645451389-588.8681891302084 0 0-117.0003645451389Z\" p-id=\"5686\" fill=\"#8a8a8a\"></path><path d=\"M831.596434 638.445854 642.224412 384.604518 1023.977999 384.604518Z\" p-id=\"5687\" fill=\"#8a8a8a\"></path></svg>`;\n const menu = document.createElement('div');\n menu.className = 'vtable-sheet-main-menu';\n menu.style.position = 'relative'; // 关键:为子菜单提供定位基准\n\n // 菜单按钮\n const menuButton = document.createElement('span');\n menuButton.className = 'vtable-sheet-main-menu-button';\n menuButton.innerHTML = menuIcon;\n menu.appendChild(menuButton);\n\n this.mountUndoRedoActions(menu);\n\n // 菜单项容器(直接作为 menu 的子元素)\n const menuContainer = document.createElement('div');\n menuContainer.className = 'vtable-sheet-main-menu-container';\n menu.appendChild(menuContainer); // 挂载到 menu 内部\n\n // 菜单项列表\n const menuItems = document.createElement('ul');\n menuItems.className = 'vtable-sheet-main-menu-items';\n menuContainer.appendChild(menuItems);\n\n // 动态生成菜单项\n this.sheet.getOptions().mainMenu?.items?.forEach(item => {\n const li = document.createElement('li');\n li.className = 'vtable-sheet-main-menu-item';\n li.textContent = item.name;\n li.title = item.description || ''; //title提示\n if (item.items) {\n li.classList.add('vtable-sheet-main-menu-item-has-children');\n li.onmouseenter = () => {\n const subMenu = this.createSubMenu(item.items);\n li.appendChild(subMenu);\n };\n li.onmouseleave = () => {\n li.classList.remove('vtable-sheet-main-menu-item-has-children-hover');\n if (li.querySelector('.vtable-sheet-main-menu-sub-menu')) {\n li.removeChild(li.querySelector('.vtable-sheet-main-menu-sub-menu'));\n }\n };\n }\n li.addEventListener('click', () => {\n if (item.onClick) {\n item.onClick();\n return;\n }\n if (item.menuKey) {\n this.handleMenuClick(item.menuKey);\n }\n });\n menuItems.appendChild(li);\n });\n\n // 点击事件逻辑\n menuButton.addEventListener('click', e => {\n e.stopPropagation();\n menuContainer.classList.toggle('active');\n });\n\n // 点击外部关闭菜单\n this.clickOutsideHandler = (e: MouseEvent) => {\n if (!menu.contains(e.target as Node)) {\n menuContainer.classList.remove('active');\n }\n };\n document.addEventListener('click', this.clickOutsideHandler);\n this.menuContainer = menuContainer;\n return menu;\n }\n\n private mountUndoRedoActions(container: HTMLElement): void {\n const showUndoRedo = this.sheet.getOptions().undoRedo?.show ?? true;\n if (!showUndoRedo) {\n this.undoButton = null;\n this.redoButton = null;\n this.historyUnsubscribe?.();\n this.historyUnsubscribe = null;\n return;\n }\n\n const undoIcon = `<svg width=\"1em\" height=\"1em\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-icon=\"UndoOutlined\"><path d=\"M8.707 2.293a1 1 0 0 1 0 1.414L5.414 7H14.5a7.5 7.5 0 0 1 0 15H11a1 1 0 1 1 0-2h3.5a5.5 5.5 0 1 0 0-11H5.414l3.293 3.293a1 1 0 1 1-1.414 1.414l-5-5a1 1 0 0 1 0-1.414l5-5a1 1 0 0 1 1.414 0Z\" fill=\"currentColor\"></path></svg>`;\n const redoIcon = `<svg width=\"1em\" height=\"1em\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-icon=\"RedoOutlined\"><path d=\"M15.293 2.293a1 1 0 0 0 0 1.414L18.586 7H9.5a7.5 7.5 0 0 0 0 15H13a1 1 0 1 0 0-2H9.5a5.5 5.5 0 1 1 0-11h9.086l-3.293 3.293a1 1 0 0 0 1.414 1.414l5-5a1 1 0 0 0 0-1.414l-5-5a1 1 0 0 0-1.414 0Z\" fill=\"currentColor\"></path></svg>`;\n\n const actions = document.createElement('div');\n actions.className = 'vtable-sheet-main-menu-actions';\n container.appendChild(actions);\n\n this.undoButton = document.createElement('button');\n this.undoButton.className = 'vtable-sheet-main-menu-action';\n this.undoButton.type = 'button';\n this.undoButton.title = '撤销';\n this.undoButton.innerHTML = undoIcon;\n this.undoButton.addEventListener('click', e => {\n e.stopPropagation();\n this.sheet.undo();\n });\n actions.appendChild(this.undoButton);\n\n this.redoButton = document.createElement('button');\n this.redoButton.className = 'vtable-sheet-main-menu-action';\n this.redoButton.type = 'button';\n this.redoButton.title = '重做';\n this.redoButton.innerHTML = redoIcon;\n this.redoButton.addEventListener('click', e => {\n e.stopPropagation();\n this.sheet.redo();\n });\n actions.appendChild(this.redoButton);\n\n this.historyUnsubscribe?.();\n this.historyUnsubscribe = this.sheet.getWorkbookHistoryManager().onChange(() => {\n this.updateUndoRedoState();\n });\n this.updateUndoRedoState();\n }\n\n private updateUndoRedoState(): void {\n const history = this.sheet.getWorkbookHistoryManager();\n if (this.undoButton) {\n this.undoButton.disabled = !history.canUndo();\n }\n if (this.redoButton) {\n this.redoButton.disabled = !history.canRedo();\n }\n }\n //TODO 需要重新逻辑,需要支持多级菜单\n private createSubMenu(items: MainMenuItem[]): HTMLElement {\n // 创建子菜单容器\n const subMenuContainer = document.createElement('div');\n subMenuContainer.className = 'vtable-sheet-submenu-container';\n\n // 创建子菜单列表\n const subMenuList = document.createElement('ul');\n subMenuList.className = 'vtable-sheet-main-menu-items';\n\n // 动态生成子菜单项\n items.forEach(item => {\n const li = document.createElement('li');\n li.className = 'vtable-sheet-submenu-item';\n li.textContent = item.name;\n li.title = item.description || '';\n\n // 绑定点击事件\n li.addEventListener('click', e => {\n e.stopPropagation();\n if (item.onClick) {\n item.onClick();\n } else if (item.menuKey) {\n this.handleMenuClick(item.menuKey);\n }\n this.hideAllSubMenus(); // 点击后关闭所有子菜单\n });\n\n // 如果有嵌套子菜单\n if (item.items?.length) {\n // li.classList.add('has-submenu');\n li.classList.add('vtable-sheet-main-menu-item-has-children');\n // const arrowIcon = document.createElement('span');\n // arrowIcon.className = 'submenu-arrow';\n // arrowIcon.innerHTML = '▶';\n // li.appendChild(arrowIcon);\n\n // 鼠标悬停显示嵌套子菜单\n li.addEventListener('mouseenter', () => {\n this.hideAllSubMenus(li); // 先关闭其他子菜单\n const nestedSubMenu = this.createSubMenu(item.items);\n li.appendChild(nestedSubMenu);\n this.adjustSubMenuPosition(nestedSubMenu); // 调整定位\n });\n }\n\n subMenuList.appendChild(li);\n });\n\n subMenuContainer.appendChild(subMenuList);\n return subMenuContainer;\n }\n\n // 调整子菜单定位(避免超出视口)\n private adjustSubMenuPosition(subMenu: HTMLElement) {\n const rect = subMenu.getBoundingClientRect();\n if (rect.right > window.innerWidth) {\n subMenu.style.left = 'auto';\n subMenu.style.right = '100%'; // 改为向左展开\n }\n if (rect.bottom > window.innerHeight) {\n subMenu.style.top = 'auto';\n subMenu.style.bottom = '0'; // 向上对齐\n }\n }\n\n // 关闭所有子菜单(保留当前激活项)并隐藏主菜单\n private hideAllSubMenus(exceptElement?: HTMLElement) {\n document.querySelectorAll('.vtable-sheet-submenu-container').forEach(menu => {\n if (menu !== exceptElement?.closest('.vtable-sheet-submenu-container')) {\n menu.remove();\n }\n });\n this.menuContainer.classList.remove('active');\n }\n handleMenuClick(menuKey: MainMenuItemKey) {\n const tableInstance = this.sheet.getActiveSheet().tableInstance;\n const eventManager = this.sheet.getSpreadSheetEventManager();\n\n switch (menuKey) {\n case MainMenuItemKey.IMPORT:\n if (this.sheet.importFileToSheet) {\n this.sheet.importFileToSheet();\n }\n break;\n\n case MainMenuItemKey.EXPORT_CURRENT_SHEET_CSV:\n try {\n // 触发导出开始事件\n eventManager.emitExportStart('csv', false);\n\n if ((tableInstance as any)?.exportToCsv) {\n (tableInstance as any).exportToCsv();\n // 触发导出完成事件\n eventManager.emitExportCompleted('csv', false, 1);\n } else {\n console.warn('Please configure TableExportPlugin in VTablePluginModules');\n // 触发导出失败事件\n eventManager.emitExportError('csv', false, 'TableExportPlugin not configured');\n }\n } catch (error) {\n // 触发导出失败事件\n const errorMessage = error instanceof Error ? error.message : String(error);\n eventManager.emitExportError('csv', false, errorMessage);\n console.warn('Export to CSV failed:', errorMessage);\n }\n break;\n\n case MainMenuItemKey.EXPORT_CURRENT_SHEET_XLSX:\n try {\n // 触发导出开始事件\n eventManager.emitExportStart('xlsx', false);\n\n if ((tableInstance as any)?.exportToExcel) {\n (tableInstance as any).exportToExcel();\n // 触发导出完成事件\n eventManager.emitExportCompleted('xlsx', false, 1);\n } else {\n console.warn('Please configure TableExportPlugin in VTablePluginModules');\n // 触发导出失败事件\n eventManager.emitExportError('xlsx', false, 'TableExportPlugin not configured');\n }\n } catch (error) {\n // 触发导出失败事件\n const errorMessage = error instanceof Error ? error.message : String(error);\n eventManager.emitExportError('xlsx', false, errorMessage);\n console.warn('Export to Excel failed:', errorMessage);\n }\n break;\n\n case MainMenuItemKey.EXPORT_ALL_SHEETS_XLSX:\n try {\n // 触发导出开始事件\n eventManager.emitExportStart('xlsx', true);\n\n // 多 sheet 导出走 vtable-plugins 的导出工具,不依赖向 tableInstance 注入 exportToExcel\n if (this.sheet.exportAllSheetsToExcel) {\n this.sheet.exportAllSheetsToExcel();\n // 触发导出完成事件\n const sheetCount = this.sheet.getSheetCount();\n eventManager.emitExportCompleted('xlsx', true, sheetCount);\n } else {\n console.warn('Export all sheets method not available');\n // 触发导出失败事件\n eventManager.emitExportError('xlsx', true, 'Export all sheets method not available');\n }\n } catch (error) {\n // 触发导出失败事件\n const errorMessage = error instanceof Error ? error.message : String(error);\n eventManager.emitExportError('xlsx', true, errorMessage);\n console.warn('Export all sheets failed:', errorMessage);\n }\n break;\n\n default:\n break;\n }\n }\n\n /**\n * 清理菜单管理器,移除全局事件监听器\n */\n release(): void {\n if (this.clickOutsideHandler) {\n document.removeEventListener('click', this.clickOutsideHandler);\n this.clickOutsideHandler = null;\n }\n this.historyUnsubscribe?.();\n this.historyUnsubscribe = null;\n }\n updateMainMenu(mainMenu: IVTableSheetOptions['mainMenu']): HTMLElement {\n this.release();\n return this.createMainMenu();\n }\n}\n"]}
@@ -16,8 +16,8 @@ export default class SheetTabDragManager {
16
16
  updateDragPreview(e: MouseEvent): void;
17
17
  cleanupDragPreview(): void;
18
18
  calculateDropZones(): void;
19
- getDropZoneAt(x: number, y: number): (typeof this.dragState.dropZones)[0] | null;
20
- showInsertIndicator(dropZone: (typeof this.dragState.dropZones)[0]): void;
19
+ getDropZoneAt(x: number, y: number): typeof this.dragState.dropZones[0] | null;
20
+ showInsertIndicator(dropZone: typeof this.dragState.dropZones[0]): void;
21
21
  hideInsertIndicator(): void;
22
22
  performTabReorder(sourceKey: string, targetKey: string, position: 'left' | 'right'): void;
23
23
  cleanupDragState(): void;
@@ -106,8 +106,7 @@ class SheetTabDragManager {
106
106
  }
107
107
  performTabReorder(sourceKey, targetKey, position) {
108
108
  try {
109
- this.sheet.getSheetManager().reorderSheet(sourceKey, targetKey, position), this.sheet.updateSheetTabs(),
110
- this.sheet.updateSheetMenu();
109
+ this.sheet.reorderSheet(sourceKey, targetKey, position);
111
110
  } catch (error) {}
112
111
  }
113
112
  cleanupDragState() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/managers/tab-drag-manager.ts"],"names":[],"mappings":";;AAkBA,MAAqB,mBAAmB;IAmBtC,YAAY,KAAkB;QAftB,cAAS,GAAc;YAC7B,UAAU,EAAE,KAAK;YACjB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,IAAI;YACpB,MAAM,EAAE,CAAC;YACT,MAAM,EAAE,CAAC;YACT,SAAS,EAAE,CAAC;YACZ,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,EAAE;SACd,CAAC;QAEM,oBAAe,GAAuB,IAAI,CAAC;QAKjD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QAEnB,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACzD,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC;IAKD,kBAAkB,CAAC,CAAa,EAAE,QAAgB;QAChD,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE;YACzB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,aAAa,CAAC,gCAAgC,CAAgB,CAAC;SACnH;QACD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE;YAClB,OAAO;SACR;QACD,CAAC,CAAC,cAAc,EAAE,CAAC;QAEnB,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC;QAClC,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC;QAClC,IAAI,CAAC,SAAS,CAAC,eAAe,GAAG,QAAQ,CAAC;QAC1C,IAAI,CAAC,SAAS,CAAC,cAAc,GAAG,CAAC,CAAC,MAAqB,CAAC;QAGxD,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC5D,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IAC1D,CAAC;IAMD,qBAAqB,CAAC,CAAa;QACjC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE;YACrE,OAAO;SACR;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC3D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAE3D,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE;YAC1G,IAAI,CAAC,aAAa,EAAE,CAAC;SACtB;QACD,IAAI,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;YAC7B,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;SACxB;IACH,CAAC;IAKD,mBAAmB,CAAC,CAAa;QAC/B,IAAI,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;YAC7B,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;SACrB;QAED,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAExB,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/D,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IAC7D,CAAC;IAKD,aAAa;QACX,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE;YACrE,OAAO;SACR;QACD,IAAI,CAAC,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC;QACjC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAExD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEzB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,eAAe,EAAE;YACxB,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;SAC9C;IACH,CAAC;IAKD,cAAc,CAAC,CAAa;QAC1B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;YAC9B,OAAO;SACR;QAED,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;QAE1B,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;QAC1D,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;SACpC;aAAM;YACL,IAAI,CAAC,mBAAmB,EAAE,CAAC;SAC5B;IACH,CAAC;IAKD,WAAW,CAAC,CAAa;QACvB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE;YACjE,OAAO;SACR;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;QAC1D,IAAI,QAAQ,IAAI,QAAQ,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE;YAErE,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;SAC/F;QACD,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE;YACjC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;SAC5D;IACH,CAAC;IAKD,iBAAiB;QACf,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE;YAClC,OAAO;SACR;QAED,IAAI,CAAC,SAAS,CAAC,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACvD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,GAAG,2BAA2B,CAAC;QAC/D,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,GAAG;wCACC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,WAAW;KAC5E,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC;IAC1D,CAAC;IAKD,iBAAiB,CAAC,CAAa;QAC7B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;YAC3B,OAAO;SACR;QACD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,GAAG,CAAC,IAAI,CAAC;QAC9F,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC;IAChG,CAAC;IAKD,kBAAkB;QAEhB,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;YAC1B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAChC,IAAI,CAAC,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC;SAC/B;QACD,IAAI,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE;YACjC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;SACjD;IACH,CAAC;IAKD,kBAAkB;;QAChB,IAAI,CAAC,SAAS,CAAC,SAAS,GAAG,EAAE,CAAC;QAC9B,MAAM,aAAa,GAAG,MAAA,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,0CAAE,aAAa,CAAC,8BAA8B,CAAgB,CAAC;QACpH,IAAI,CAAC,aAAa,EAAE;YAClB,OAAO;SACR;QACD,MAAM,IAAI,GAAG,aAAa,CAAC,gBAAgB,CAAC,mBAAmB,CAA4B,CAAC;QAC5F,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YACjB,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC;YACjC,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE;gBAC5D,OAAO;aACR;YAED,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC5B,OAAO,EAAE,GAAG;gBACZ,QAAQ,EAAE,MAAM;gBAChB,SAAS,EAAE,QAAQ;aACpB,CAAC,CAAC;YAGH,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC5B,OAAO,EAAE,GAAG;gBACZ,QAAQ,EAAE,OAAO;gBACjB,SAAS,EAAE,QAAQ;aACpB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAKD,aAAa,CAAC,CAAS,EAAE,CAAS;QAChC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE;YAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC;YAGlD,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE;gBACnC,SAAS;aACV;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;YACxC,IAAI,IAAI,CAAC,QAAQ,KAAK,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE;gBAC3D,OAAO,IAAI,CAAC;aACb;iBAAM,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE;gBACpE,OAAO,IAAI,CAAC;aACb;SACF;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAKD,mBAAmB,CAAC,QAA8C;;QAChE,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE;YACzB,OAAO;SACR;QACD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC;QACtD,MAAM,aAAa,GAAG,MAAA,IAAI,CAAC,KAAK;aAC7B,cAAc,EAAE;aAChB,aAAa,CAAC,8BAA8B,CAAC,0CAC5C,qBAAqB,EAAE,CAAC;QAC5B,IAAI,CAAC,aAAa,EAAE;YAClB,OAAO;SACR;QACD,IAAI,UAAkB,CAAC;QACvB,IAAI,QAAQ,CAAC,QAAQ,KAAK,MAAM,EAAE;YAChC,UAAU,GAAG,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,CAAC;SACjD;aAAM;YACL,UAAU,GAAG,IAAI,CAAC,KAAK,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,CAAC;SAClD;QACD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,UAAU,IAAI,CAAC;QACpD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;IAC/C,CAAC;IAKD,mBAAmB;QACjB,IAAI,IAAI,CAAC,eAAe,EAAE;YACxB,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;SAC7C;IACH,CAAC;IAQD,iBAAiB,CAAC,SAAiB,EAAE,SAAiB,EAAE,QAA0B;QAChF,IAAI;YACF,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;YAE1E,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;YAC7B,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;SAC9B;QAAC,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;SAC7C;IACH,CAAC;IAKD,gBAAgB;QACd,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAE1B,IAAI,CAAC,SAAS,CAAC,UAAU,GAAG,KAAK,CAAC;QAClC,IAAI,CAAC,SAAS,CAAC,eAAe,GAAG,IAAI,CAAC;QACtC,IAAI,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC;QACrC,IAAI,CAAC,SAAS,CAAC,SAAS,GAAG,EAAE,CAAC;QAC9B,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5B,CAAC;CACF;AAvSD,sCAuSC","file":"tab-drag-manager.js","sourcesContent":["import type VTableSheet from '../components/vtable-sheet';\n\n// 拖拽状态接口\ninterface DragState {\n isDragging: boolean;\n draggedSheetKey: string | null;\n draggedElement: HTMLElement | null;\n startX: number;\n startY: number;\n threshold: number;\n preview: HTMLElement | null;\n dropZones: Array<{\n element: HTMLElement;\n position: 'left' | 'right';\n targetKey: string;\n }>;\n}\n\nexport default class SheetTabDragManager {\n // 依赖的VTableSheet实例\n private sheet: VTableSheet;\n // 拖拽状态\n private dragState: DragState = {\n isDragging: false,\n draggedSheetKey: null,\n draggedElement: null,\n startX: 0,\n startY: 0,\n threshold: 5,\n preview: null,\n dropZones: []\n };\n // 插入指示器\n private insertIndicator: HTMLElement | null = null;\n private boundMouseMove: (e: MouseEvent) => void;\n private boundMouseUp: (e: MouseEvent) => void;\n\n constructor(sheet: VTableSheet) {\n this.sheet = sheet;\n // 绑定this上下文并存储函数引用\n this.boundMouseMove = e => this.handleGlobalMouseMove(e);\n this.boundMouseUp = e => this.handleGlobalMouseUp(e);\n }\n\n /**\n * 处理tab鼠标按下事件\n */\n handleTabMouseDown(e: MouseEvent, sheetKey: string): void {\n if (!this.insertIndicator) {\n this.insertIndicator = this.sheet.getRootElement().querySelector('.vtable-sheet-insert-indicator') as HTMLElement;\n }\n if (e.button !== 0) {\n return;\n }\n e.preventDefault();\n // 记录拖拽开始位置\n this.dragState.startX = e.clientX;\n this.dragState.startY = e.clientY;\n this.dragState.draggedSheetKey = sheetKey;\n this.dragState.draggedElement = e.target as HTMLElement;\n\n // 全局鼠标事件监听\n document.addEventListener('mousemove', this.boundMouseMove);\n document.addEventListener('mouseup', this.boundMouseUp);\n }\n\n /**\n * 处理全局鼠标移动事件\n *\n */\n handleGlobalMouseMove(e: MouseEvent): void {\n if (!this.dragState.draggedSheetKey || !this.dragState.draggedElement) {\n return;\n }\n const deltaX = Math.abs(e.clientX - this.dragState.startX);\n const deltaY = Math.abs(e.clientY - this.dragState.startY);\n // 判断是否超过拖拽阈值\n if (!this.dragState.isDragging && (deltaX > this.dragState.threshold || deltaY > this.dragState.threshold)) {\n this.startDragging();\n }\n if (this.dragState.isDragging) {\n this.updateDragging(e);\n }\n }\n\n /**\n * 处理全局鼠标抬起事件\n */\n handleGlobalMouseUp(e: MouseEvent): void {\n if (this.dragState.isDragging) {\n this.endDragging(e);\n }\n // 清理拖拽状态\n this.cleanupDragState();\n // 移除全局事件监听\n document.removeEventListener('mousemove', this.boundMouseMove);\n document.removeEventListener('mouseup', this.boundMouseUp);\n }\n\n /**\n * 开始拖拽\n */\n startDragging(): void {\n if (!this.dragState.draggedElement || !this.dragState.draggedSheetKey) {\n return;\n }\n this.dragState.isDragging = true;\n this.dragState.draggedElement.classList.add('dragging');\n // 创建拖拽预览\n this.createDragPreview();\n // 计算放置区域\n this.calculateDropZones();\n if (this.insertIndicator) {\n this.insertIndicator.style.display = 'block';\n }\n }\n\n /**\n * 更新拖拽状态\n */\n updateDragging(e: MouseEvent): void {\n if (!this.dragState.isDragging) {\n return;\n }\n // 更新拖拽预览位置\n this.updateDragPreview(e);\n // 检测当前鼠标位置对应的放置区域\n const dropZone = this.getDropZoneAt(e.clientX, e.clientY);\n if (dropZone) {\n this.showInsertIndicator(dropZone);\n } else {\n this.hideInsertIndicator();\n }\n }\n\n /**\n * 结束拖拽\n */\n endDragging(e: MouseEvent): void {\n if (!this.dragState.isDragging || !this.dragState.draggedSheetKey) {\n return;\n }\n // 检查是否有有效的放置目标\n const dropZone = this.getDropZoneAt(e.clientX, e.clientY);\n if (dropZone && dropZone.targetKey !== this.dragState.draggedSheetKey) {\n // 执行拖拽排序\n this.performTabReorder(this.dragState.draggedSheetKey, dropZone.targetKey, dropZone.position);\n }\n this.hideInsertIndicator();\n if (this.dragState.draggedElement) {\n this.dragState.draggedElement.classList.remove('dragging');\n }\n }\n\n /**\n * 创建拖拽预览\n */\n createDragPreview(): void {\n if (!this.dragState.draggedElement) {\n return;\n }\n // 创建拖拽预览元素\n this.dragState.preview = document.createElement('div');\n this.dragState.preview.className = 'vtable-sheet-drag-preview';\n this.dragState.preview.innerHTML = `\n <span class=\"drag-preview-text\">${this.dragState.draggedElement.textContent}</span>\n `;\n document.body.appendChild(this.dragState.preview);\n this.dragState.draggedElement.style.cursor = 'grabbing';\n }\n\n /**\n * 更新拖拽预览位置\n */\n updateDragPreview(e: MouseEvent): void {\n if (!this.dragState.preview) {\n return;\n }\n this.dragState.preview.style.left = `${e.clientX - this.dragState.preview.offsetWidth / 2}px`;\n this.dragState.preview.style.top = `${e.clientY - this.dragState.preview.offsetHeight / 2}px`;\n }\n\n /**\n * 清理拖拽预览\n */\n cleanupDragPreview(): void {\n // 移除拖拽预览元素\n if (this.dragState.preview) {\n this.dragState.preview.remove();\n this.dragState.preview = null;\n }\n if (this.dragState.draggedElement) {\n this.dragState.draggedElement.style.cursor = '';\n }\n }\n\n /**\n * 计算放置区域\n */\n calculateDropZones(): void {\n this.dragState.dropZones = [];\n const tabsContainer = this.sheet.getSheetTabElement()?.querySelector('.vtable-sheet-tabs-container') as HTMLElement;\n if (!tabsContainer) {\n return;\n }\n const tabs = tabsContainer.querySelectorAll('.vtable-sheet-tab') as NodeListOf<HTMLElement>;\n tabs.forEach(tab => {\n const sheetKey = tab.dataset.key;\n if (!sheetKey || sheetKey === this.dragState.draggedSheetKey) {\n return;\n }\n // 左侧放置区域\n this.dragState.dropZones.push({\n element: tab,\n position: 'left',\n targetKey: sheetKey\n });\n\n // 右侧放置区域\n this.dragState.dropZones.push({\n element: tab,\n position: 'right',\n targetKey: sheetKey\n });\n });\n }\n\n /**\n * 获取指定位置的放置区域\n */\n getDropZoneAt(x: number, y: number): (typeof this.dragState.dropZones)[0] | null {\n for (const zone of this.dragState.dropZones) {\n const rect = zone.element.getBoundingClientRect();\n\n // 检查Y坐标是否在tab范围内\n if (y < rect.top || y > rect.bottom) {\n continue;\n }\n const midX = rect.left + rect.width / 2;\n if (zone.position === 'left' && x >= rect.left && x <= midX) {\n return zone;\n } else if (zone.position === 'right' && x >= midX && x <= rect.right) {\n return zone;\n }\n }\n\n return null;\n }\n\n /**\n * 显示插入指示器\n */\n showInsertIndicator(dropZone: (typeof this.dragState.dropZones)[0]): void {\n if (!this.insertIndicator) {\n return;\n }\n const rect = dropZone.element.getBoundingClientRect();\n const containerRect = this.sheet\n .getRootElement()\n .querySelector('.vtable-sheet-tabs-container')\n ?.getBoundingClientRect();\n if (!containerRect) {\n return;\n }\n let indicatorX: number;\n if (dropZone.position === 'left') {\n indicatorX = rect.left - containerRect.left - 4;\n } else {\n indicatorX = rect.right - containerRect.left - 4;\n }\n this.insertIndicator.style.left = `${indicatorX}px`;\n this.insertIndicator.style.display = 'block';\n }\n\n /**\n * 隐藏插入指示器\n */\n hideInsertIndicator(): void {\n if (this.insertIndicator) {\n this.insertIndicator.style.display = 'none';\n }\n }\n\n /**\n * 执行tab排序\n * @param sourceKey 源tab的key\n * @param targetKey 目标tab的key\n * @param position 插入位置 左侧或右侧\n */\n performTabReorder(sourceKey: string, targetKey: string, position: 'left' | 'right'): void {\n try {\n this.sheet.getSheetManager().reorderSheet(sourceKey, targetKey, position);\n // 更新UI\n this.sheet.updateSheetTabs();\n this.sheet.updateSheetMenu();\n } catch (error) {\n console.error('Tab reorder failed:', error);\n }\n }\n\n /**\n * 清理拖拽状态\n */\n cleanupDragState(): void {\n this.cleanupDragPreview();\n // 重置拖拽状态\n this.dragState.isDragging = false;\n this.dragState.draggedSheetKey = null;\n this.dragState.draggedElement = null;\n this.dragState.dropZones = [];\n this.dragState.startX = 0;\n this.dragState.startY = 0;\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/managers/tab-drag-manager.ts"],"names":[],"mappings":"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","file":"tab-drag-manager.js","sourcesContent":["import type VTableSheet from '../components/vtable-sheet';\n\n// 拖拽状态接口\ninterface DragState {\n isDragging: boolean;\n draggedSheetKey: string | null;\n draggedElement: HTMLElement | null;\n startX: number;\n startY: number;\n threshold: number;\n preview: HTMLElement | null;\n dropZones: Array<{\n element: HTMLElement;\n position: 'left' | 'right';\n targetKey: string;\n }>;\n}\n\nexport default class SheetTabDragManager {\n // 依赖的VTableSheet实例\n private sheet: VTableSheet;\n // 拖拽状态\n private dragState: DragState = {\n isDragging: false,\n draggedSheetKey: null,\n draggedElement: null,\n startX: 0,\n startY: 0,\n threshold: 5,\n preview: null,\n dropZones: []\n };\n // 插入指示器\n private insertIndicator: HTMLElement | null = null;\n private boundMouseMove: (e: MouseEvent) => void;\n private boundMouseUp: (e: MouseEvent) => void;\n\n constructor(sheet: VTableSheet) {\n this.sheet = sheet;\n // 绑定this上下文并存储函数引用\n this.boundMouseMove = e => this.handleGlobalMouseMove(e);\n this.boundMouseUp = e => this.handleGlobalMouseUp(e);\n }\n\n /**\n * 处理tab鼠标按下事件\n */\n handleTabMouseDown(e: MouseEvent, sheetKey: string): void {\n if (!this.insertIndicator) {\n this.insertIndicator = this.sheet.getRootElement().querySelector('.vtable-sheet-insert-indicator') as HTMLElement;\n }\n if (e.button !== 0) {\n return;\n }\n e.preventDefault();\n // 记录拖拽开始位置\n this.dragState.startX = e.clientX;\n this.dragState.startY = e.clientY;\n this.dragState.draggedSheetKey = sheetKey;\n this.dragState.draggedElement = e.target as HTMLElement;\n\n // 全局鼠标事件监听\n document.addEventListener('mousemove', this.boundMouseMove);\n document.addEventListener('mouseup', this.boundMouseUp);\n }\n\n /**\n * 处理全局鼠标移动事件\n *\n */\n handleGlobalMouseMove(e: MouseEvent): void {\n if (!this.dragState.draggedSheetKey || !this.dragState.draggedElement) {\n return;\n }\n const deltaX = Math.abs(e.clientX - this.dragState.startX);\n const deltaY = Math.abs(e.clientY - this.dragState.startY);\n // 判断是否超过拖拽阈值\n if (!this.dragState.isDragging && (deltaX > this.dragState.threshold || deltaY > this.dragState.threshold)) {\n this.startDragging();\n }\n if (this.dragState.isDragging) {\n this.updateDragging(e);\n }\n }\n\n /**\n * 处理全局鼠标抬起事件\n */\n handleGlobalMouseUp(e: MouseEvent): void {\n if (this.dragState.isDragging) {\n this.endDragging(e);\n }\n // 清理拖拽状态\n this.cleanupDragState();\n // 移除全局事件监听\n document.removeEventListener('mousemove', this.boundMouseMove);\n document.removeEventListener('mouseup', this.boundMouseUp);\n }\n\n /**\n * 开始拖拽\n */\n startDragging(): void {\n if (!this.dragState.draggedElement || !this.dragState.draggedSheetKey) {\n return;\n }\n this.dragState.isDragging = true;\n this.dragState.draggedElement.classList.add('dragging');\n // 创建拖拽预览\n this.createDragPreview();\n // 计算放置区域\n this.calculateDropZones();\n if (this.insertIndicator) {\n this.insertIndicator.style.display = 'block';\n }\n }\n\n /**\n * 更新拖拽状态\n */\n updateDragging(e: MouseEvent): void {\n if (!this.dragState.isDragging) {\n return;\n }\n // 更新拖拽预览位置\n this.updateDragPreview(e);\n // 检测当前鼠标位置对应的放置区域\n const dropZone = this.getDropZoneAt(e.clientX, e.clientY);\n if (dropZone) {\n this.showInsertIndicator(dropZone);\n } else {\n this.hideInsertIndicator();\n }\n }\n\n /**\n * 结束拖拽\n */\n endDragging(e: MouseEvent): void {\n if (!this.dragState.isDragging || !this.dragState.draggedSheetKey) {\n return;\n }\n // 检查是否有有效的放置目标\n const dropZone = this.getDropZoneAt(e.clientX, e.clientY);\n if (dropZone && dropZone.targetKey !== this.dragState.draggedSheetKey) {\n // 执行拖拽排序\n this.performTabReorder(this.dragState.draggedSheetKey, dropZone.targetKey, dropZone.position);\n }\n this.hideInsertIndicator();\n if (this.dragState.draggedElement) {\n this.dragState.draggedElement.classList.remove('dragging');\n }\n }\n\n /**\n * 创建拖拽预览\n */\n createDragPreview(): void {\n if (!this.dragState.draggedElement) {\n return;\n }\n // 创建拖拽预览元素\n this.dragState.preview = document.createElement('div');\n this.dragState.preview.className = 'vtable-sheet-drag-preview';\n this.dragState.preview.innerHTML = `\n <span class=\"drag-preview-text\">${this.dragState.draggedElement.textContent}</span>\n `;\n document.body.appendChild(this.dragState.preview);\n this.dragState.draggedElement.style.cursor = 'grabbing';\n }\n\n /**\n * 更新拖拽预览位置\n */\n updateDragPreview(e: MouseEvent): void {\n if (!this.dragState.preview) {\n return;\n }\n this.dragState.preview.style.left = `${e.clientX - this.dragState.preview.offsetWidth / 2}px`;\n this.dragState.preview.style.top = `${e.clientY - this.dragState.preview.offsetHeight / 2}px`;\n }\n\n /**\n * 清理拖拽预览\n */\n cleanupDragPreview(): void {\n // 移除拖拽预览元素\n if (this.dragState.preview) {\n this.dragState.preview.remove();\n this.dragState.preview = null;\n }\n if (this.dragState.draggedElement) {\n this.dragState.draggedElement.style.cursor = '';\n }\n }\n\n /**\n * 计算放置区域\n */\n calculateDropZones(): void {\n this.dragState.dropZones = [];\n const tabsContainer = this.sheet.getSheetTabElement()?.querySelector('.vtable-sheet-tabs-container') as HTMLElement;\n if (!tabsContainer) {\n return;\n }\n const tabs = tabsContainer.querySelectorAll('.vtable-sheet-tab') as NodeListOf<HTMLElement>;\n tabs.forEach(tab => {\n const sheetKey = tab.dataset.key;\n if (!sheetKey || sheetKey === this.dragState.draggedSheetKey) {\n return;\n }\n // 左侧放置区域\n this.dragState.dropZones.push({\n element: tab,\n position: 'left',\n targetKey: sheetKey\n });\n\n // 右侧放置区域\n this.dragState.dropZones.push({\n element: tab,\n position: 'right',\n targetKey: sheetKey\n });\n });\n }\n\n /**\n * 获取指定位置的放置区域\n */\n getDropZoneAt(x: number, y: number): typeof this.dragState.dropZones[0] | null {\n for (const zone of this.dragState.dropZones) {\n const rect = zone.element.getBoundingClientRect();\n\n // 检查Y坐标是否在tab范围内\n if (y < rect.top || y > rect.bottom) {\n continue;\n }\n const midX = rect.left + rect.width / 2;\n if (zone.position === 'left' && x >= rect.left && x <= midX) {\n return zone;\n } else if (zone.position === 'right' && x >= midX && x <= rect.right) {\n return zone;\n }\n }\n\n return null;\n }\n\n /**\n * 显示插入指示器\n */\n showInsertIndicator(dropZone: typeof this.dragState.dropZones[0]): void {\n if (!this.insertIndicator) {\n return;\n }\n const rect = dropZone.element.getBoundingClientRect();\n const containerRect = this.sheet\n .getRootElement()\n .querySelector('.vtable-sheet-tabs-container')\n ?.getBoundingClientRect();\n if (!containerRect) {\n return;\n }\n let indicatorX: number;\n if (dropZone.position === 'left') {\n indicatorX = rect.left - containerRect.left - 4;\n } else {\n indicatorX = rect.right - containerRect.left - 4;\n }\n this.insertIndicator.style.left = `${indicatorX}px`;\n this.insertIndicator.style.display = 'block';\n }\n\n /**\n * 隐藏插入指示器\n */\n hideInsertIndicator(): void {\n if (this.insertIndicator) {\n this.insertIndicator.style.display = 'none';\n }\n }\n\n /**\n * 执行tab排序\n * @param sourceKey 源tab的key\n * @param targetKey 目标tab的key\n * @param position 插入位置 左侧或右侧\n */\n performTabReorder(sourceKey: string, targetKey: string, position: 'left' | 'right'): void {\n try {\n this.sheet.reorderSheet(sourceKey, targetKey, position);\n } catch (error) {\n console.error('Tab reorder failed:', error);\n }\n }\n\n /**\n * 清理拖拽状态\n */\n cleanupDragState(): void {\n this.cleanupDragPreview();\n // 重置拖拽状态\n this.dragState.isDragging = false;\n this.dragState.draggedSheetKey = null;\n this.dragState.draggedElement = null;\n this.dragState.dropZones = [];\n this.dragState.startX = 0;\n this.dragState.startY = 0;\n }\n}\n"]}
@@ -0,0 +1,53 @@
1
+ import type VTableSheet from '../components/vtable-sheet';
2
+ import type { ISheetDefine } from '../ts-types';
3
+ import type { HistoryTransaction } from '@visactor/vtable-plugins';
4
+ export declare class WorkbookHistoryManager {
5
+ private sheet;
6
+ private undoStack;
7
+ private redoStack;
8
+ private currentTransaction;
9
+ private maxHistory;
10
+ private enabled;
11
+ isReplaying: boolean;
12
+ private changeListeners;
13
+ constructor(sheet: VTableSheet, options?: {
14
+ maxHistory?: number;
15
+ });
16
+ canUndo(): boolean;
17
+ canRedo(): boolean;
18
+ onChange(listener: () => void): () => void;
19
+ private emitChange;
20
+ suspend(): void;
21
+ resume(): void;
22
+ startTransaction(): void;
23
+ endTransaction(): void;
24
+ clear(): void;
25
+ updateOptions(options: {
26
+ maxHistory?: number;
27
+ }): void;
28
+ undo(): void;
29
+ redo(): void;
30
+ recordTableTransaction(args: {
31
+ sheetKey?: string;
32
+ tx: HistoryTransaction;
33
+ }): void;
34
+ addSheet(args: {
35
+ sheet: ISheetDefine;
36
+ activate?: boolean;
37
+ }): void;
38
+ removeSheet(sheetKey: string): void;
39
+ renameSheet(sheetKey: string, newTitle: string): void;
40
+ reorderSheet(sourceKey: string, targetKey: string, position: 'left' | 'right'): void;
41
+ private pushTransaction;
42
+ private pushCommand;
43
+ private trimHistory;
44
+ private applyCommand;
45
+ private addSheetInternal;
46
+ private removeSheetInternal;
47
+ private renameSheetInternal;
48
+ private applyTableTransaction;
49
+ private ensureWorkSheetInstance;
50
+ private getSheetOrder;
51
+ private setSheetOrder;
52
+ private getActiveSheetKey;
53
+ }
@@ -0,0 +1,294 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: !0
5
+ }), exports.WorkbookHistoryManager = void 0;
6
+
7
+ const vtable_plugins_1 = require("@visactor/vtable-plugins");
8
+
9
+ function cloneJson(input) {
10
+ return JSON.parse(JSON.stringify(input));
11
+ }
12
+
13
+ function cloneSafe(input) {
14
+ const sc = globalThis.structuredClone;
15
+ if ("function" == typeof sc) try {
16
+ return sc(input);
17
+ } catch (_a) {}
18
+ return cloneJson(input);
19
+ }
20
+
21
+ class WorkbookHistoryManager {
22
+ constructor(sheet, options) {
23
+ var _a;
24
+ this.undoStack = [], this.redoStack = [], this.currentTransaction = null, this.enabled = !0,
25
+ this.isReplaying = !1, this.changeListeners = new Set, this.sheet = sheet, this.maxHistory = null !== (_a = null == options ? void 0 : options.maxHistory) && void 0 !== _a ? _a : 100;
26
+ }
27
+ canUndo() {
28
+ return this.undoStack.length > 0;
29
+ }
30
+ canRedo() {
31
+ return this.redoStack.length > 0;
32
+ }
33
+ onChange(listener) {
34
+ return this.changeListeners.add(listener), () => {
35
+ this.changeListeners.delete(listener);
36
+ };
37
+ }
38
+ emitChange() {
39
+ this.changeListeners.forEach((fn => {
40
+ try {
41
+ fn();
42
+ } catch (_a) {}
43
+ }));
44
+ }
45
+ suspend() {
46
+ this.enabled = !1;
47
+ }
48
+ resume() {
49
+ this.enabled = !0;
50
+ }
51
+ startTransaction() {
52
+ this.currentTransaction || (this.currentTransaction = {
53
+ commands: []
54
+ });
55
+ }
56
+ endTransaction() {
57
+ this.currentTransaction && 0 !== this.currentTransaction.commands.length ? (this.pushTransaction(this.currentTransaction),
58
+ this.currentTransaction = null) : this.currentTransaction = null;
59
+ }
60
+ clear() {
61
+ this.undoStack = [], this.redoStack = [], this.currentTransaction = null, this.emitChange();
62
+ }
63
+ updateOptions(options) {
64
+ null != options.maxHistory && (this.maxHistory = options.maxHistory, this.trimHistory(),
65
+ this.emitChange());
66
+ }
67
+ undo() {
68
+ if (0 === this.undoStack.length) return;
69
+ const tx = this.undoStack.pop();
70
+ this.isReplaying = !0, this.sheet.__workbookHistoryReplaying = !0;
71
+ try {
72
+ for (let i = tx.commands.length - 1; i >= 0; i--) this.applyCommand(tx.commands[i], "undo");
73
+ } finally {
74
+ this.isReplaying = !1, this.sheet.__workbookHistoryReplaying = !1;
75
+ }
76
+ this.redoStack.push(tx), this.emitChange();
77
+ }
78
+ redo() {
79
+ if (0 === this.redoStack.length) return;
80
+ const tx = this.redoStack.pop();
81
+ this.isReplaying = !0, this.sheet.__workbookHistoryReplaying = !0;
82
+ try {
83
+ for (const cmd of tx.commands) this.applyCommand(cmd, "redo");
84
+ } finally {
85
+ this.isReplaying = !1, this.sheet.__workbookHistoryReplaying = !1;
86
+ }
87
+ this.undoStack.push(tx), this.emitChange();
88
+ }
89
+ recordTableTransaction(args) {
90
+ var _a;
91
+ if (!this.enabled || this.isReplaying) return;
92
+ const sheetKey = null !== (_a = args.sheetKey) && void 0 !== _a ? _a : this.getActiveSheetKey();
93
+ if (!sheetKey) return;
94
+ const cmd = {
95
+ type: "table_tx",
96
+ sheetKey: sheetKey,
97
+ tx: cloneSafe(args.tx)
98
+ };
99
+ this.pushCommand(cmd);
100
+ }
101
+ addSheet(args) {
102
+ if (!this.enabled || this.isReplaying) return void this.addSheetInternal(args.sheet, args.activate);
103
+ const orderBefore = this.getSheetOrder(), activeBefore = this.getActiveSheetKey();
104
+ this.startTransaction();
105
+ try {
106
+ this.addSheetInternal(args.sheet, args.activate);
107
+ const orderAfter = this.getSheetOrder(), activeAfter = this.getActiveSheetKey(), cmd = {
108
+ type: "sheet_add",
109
+ sheet: cloneSafe(args.sheet),
110
+ orderBefore: orderBefore,
111
+ orderAfter: orderAfter,
112
+ activeBefore: activeBefore,
113
+ activeAfter: activeAfter
114
+ };
115
+ this.pushCommand(cmd);
116
+ } finally {
117
+ this.endTransaction();
118
+ }
119
+ }
120
+ removeSheet(sheetKey) {
121
+ if (!this.enabled || this.isReplaying) return void this.removeSheetInternal(sheetKey);
122
+ const sheetDefine = this.sheet.getSheetManager().getSheet(sheetKey);
123
+ if (!sheetDefine) return;
124
+ const orderBefore = this.getSheetOrder(), activeBefore = this.getActiveSheetKey();
125
+ this.startTransaction();
126
+ try {
127
+ this.removeSheetInternal(sheetKey);
128
+ const orderAfter = this.getSheetOrder(), activeAfter = this.getActiveSheetKey(), cmd = {
129
+ type: "sheet_remove",
130
+ sheet: cloneSafe(sheetDefine),
131
+ orderBefore: orderBefore,
132
+ orderAfter: orderAfter,
133
+ activeBefore: activeBefore,
134
+ activeAfter: activeAfter
135
+ };
136
+ this.pushCommand(cmd);
137
+ } finally {
138
+ this.endTransaction();
139
+ }
140
+ }
141
+ renameSheet(sheetKey, newTitle) {
142
+ const sheetDefine = this.sheet.getSheetManager().getSheet(sheetKey);
143
+ if (!sheetDefine) return;
144
+ const oldTitle = sheetDefine.sheetTitle;
145
+ if (this.enabled && !this.isReplaying) {
146
+ this.startTransaction();
147
+ try {
148
+ this.renameSheetInternal(sheetKey, newTitle);
149
+ const cmd = {
150
+ type: "sheet_rename",
151
+ sheetKey: sheetKey,
152
+ oldTitle: oldTitle,
153
+ newTitle: newTitle
154
+ };
155
+ this.pushCommand(cmd);
156
+ } finally {
157
+ this.endTransaction();
158
+ }
159
+ } else this.renameSheetInternal(sheetKey, newTitle);
160
+ }
161
+ reorderSheet(sourceKey, targetKey, position) {
162
+ if (!this.enabled || this.isReplaying) return this.sheet.getSheetManager().reorderSheet(sourceKey, targetKey, position),
163
+ this.sheet.updateSheetTabs(), void this.sheet.updateSheetMenu();
164
+ const orderBefore = this.getSheetOrder();
165
+ this.startTransaction();
166
+ try {
167
+ this.sheet.getSheetManager().reorderSheet(sourceKey, targetKey, position), this.sheet.updateSheetTabs(),
168
+ this.sheet.updateSheetMenu();
169
+ const cmd = {
170
+ type: "sheet_reorder",
171
+ orderBefore: orderBefore,
172
+ orderAfter: this.getSheetOrder()
173
+ };
174
+ this.pushCommand(cmd);
175
+ } finally {
176
+ this.endTransaction();
177
+ }
178
+ }
179
+ pushTransaction(tx) {
180
+ tx.commands.length && (this.undoStack.push(tx), this.redoStack = [], this.trimHistory(),
181
+ this.emitChange());
182
+ }
183
+ pushCommand(cmd) {
184
+ this.currentTransaction ? this.currentTransaction.commands.push(cmd) : this.pushTransaction({
185
+ commands: [ cmd ]
186
+ });
187
+ }
188
+ trimHistory() {
189
+ this.undoStack.length > this.maxHistory && this.undoStack.splice(0, this.undoStack.length - this.maxHistory);
190
+ }
191
+ applyCommand(cmd, direction) {
192
+ switch (cmd.type) {
193
+ case "sheet_add":
194
+ "undo" === direction ? (this.removeSheetInternal(cmd.sheet.sheetKey), this.setSheetOrder(cmd.orderBefore),
195
+ cmd.activeBefore && this.sheet.activateSheet(cmd.activeBefore)) : (this.addSheetInternal(cmd.sheet, !1),
196
+ this.setSheetOrder(cmd.orderAfter), cmd.activeAfter && this.sheet.activateSheet(cmd.activeAfter));
197
+ break;
198
+
199
+ case "sheet_remove":
200
+ if ("undo" === direction) {
201
+ if (this.addSheetInternal(cmd.sheet, !1), this.setSheetOrder(cmd.orderBefore), !this.sheet.getWorkSheetInstance(cmd.sheet.sheetKey)) {
202
+ const restored = this.sheet.createWorkSheetInstance(cmd.sheet);
203
+ restored.getElement().style.display = "none", this.sheet.setWorkSheetInstance(cmd.sheet.sheetKey, restored);
204
+ }
205
+ cmd.activeBefore && this.sheet.activateSheet(cmd.activeBefore);
206
+ } else this.removeSheetInternal(cmd.sheet.sheetKey), this.setSheetOrder(cmd.orderAfter),
207
+ cmd.activeAfter && this.sheet.activateSheet(cmd.activeAfter);
208
+ break;
209
+
210
+ case "sheet_rename":
211
+ {
212
+ const nextTitle = "undo" === direction ? cmd.oldTitle : cmd.newTitle;
213
+ this.renameSheetInternal(cmd.sheetKey, nextTitle);
214
+ break;
215
+ }
216
+
217
+ case "sheet_reorder":
218
+ this.setSheetOrder("undo" === direction ? cmd.orderBefore : cmd.orderAfter);
219
+ break;
220
+
221
+ case "table_tx":
222
+ this.applyTableTransaction(cmd.sheetKey, cmd.tx, direction);
223
+ }
224
+ }
225
+ addSheetInternal(sheetDefine, activate) {
226
+ this.sheet.getSheetManager().addSheet(sheetDefine), activate ? this.sheet.activateSheet(sheetDefine.sheetKey) : (this.sheet.updateSheetTabs(),
227
+ this.sheet.updateSheetMenu());
228
+ }
229
+ removeSheetInternal(sheetKey) {
230
+ const instance = this.sheet.getWorkSheetInstance(sheetKey);
231
+ instance && (instance.release(), this.sheet.deleteWorkSheetInstance(sheetKey));
232
+ const active = this.getActiveSheetKey(), newActiveSheetKey = this.sheet.getSheetManager().removeSheet(sheetKey);
233
+ try {
234
+ this.sheet.getFormulaManager().removeSheet(sheetKey);
235
+ } catch (_a) {}
236
+ newActiveSheetKey && newActiveSheetKey !== active && this.sheet.activateSheet(newActiveSheetKey),
237
+ this.sheet.updateSheetTabs(), this.sheet.updateSheetMenu();
238
+ }
239
+ renameSheetInternal(sheetKey, newTitle) {
240
+ var _a;
241
+ this.sheet.getSheetManager().renameSheet(sheetKey, newTitle), null === (_a = this.sheet.getWorkSheetInstance(sheetKey)) || void 0 === _a || _a.setTitle(newTitle),
242
+ this.sheet.getFormulaManager().updateSheetTitle(sheetKey, newTitle), this.sheet.updateSheetTabs(),
243
+ this.sheet.updateSheetMenu();
244
+ }
245
+ applyTableTransaction(sheetKey, tx, direction) {
246
+ const ws = this.ensureWorkSheetInstance(sheetKey);
247
+ ws && this.getActiveSheetKey() !== sheetKey && this.sheet.activateSheet(sheetKey);
248
+ const table = null == ws ? void 0 : ws.tableInstance;
249
+ if (!table) return;
250
+ const vtableSheet = this.sheet, apply = (cmd, dir) => {
251
+ (0, vtable_plugins_1.replayCommand)({
252
+ table: table,
253
+ vtableSheet: vtableSheet,
254
+ cmd: cmd,
255
+ direction: dir,
256
+ deleteRecordsByReference: records => {
257
+ const tableRecords = table.records || [], indexs = [];
258
+ records.forEach((rec => {
259
+ const idx = tableRecords.indexOf(rec);
260
+ idx >= 0 && indexs.push(idx);
261
+ })), indexs.length && table.deleteRecords && table.deleteRecords(indexs);
262
+ }
263
+ });
264
+ };
265
+ if ("undo" === direction) for (let i = tx.commands.length - 1; i >= 0; i--) apply(tx.commands[i], "undo"); else for (let i = 0; i < tx.commands.length; i++) apply(tx.commands[i], "redo");
266
+ }
267
+ ensureWorkSheetInstance(sheetKey) {
268
+ const existing = this.sheet.getWorkSheetInstance(sheetKey);
269
+ if (existing) return existing;
270
+ const def = this.sheet.getSheetManager().getSheet(sheetKey);
271
+ if (!def) return;
272
+ const instance = this.sheet.createWorkSheetInstance(def);
273
+ return instance.getElement().style.display = "none", this.sheet.setWorkSheetInstance(sheetKey, instance),
274
+ instance;
275
+ }
276
+ getSheetOrder() {
277
+ return this.sheet.getSheetManager().getAllSheets().map((s => s.sheetKey));
278
+ }
279
+ setSheetOrder(order) {
280
+ const all = this.sheet.getSheetManager().getAllSheets(), map = new Map(all.map((s => [ s.sheetKey, s ]))), next = [];
281
+ order.forEach((key => {
282
+ const s = map.get(key);
283
+ s && next.push(s);
284
+ })), next.length === all.length && (this.sheet.getSheetManager().sortSheets(next),
285
+ this.sheet.updateSheetTabs(), this.sheet.updateSheetMenu());
286
+ }
287
+ getActiveSheetKey() {
288
+ var _a;
289
+ return null === (_a = this.sheet.getSheetManager().getActiveSheet()) || void 0 === _a ? void 0 : _a.sheetKey;
290
+ }
291
+ }
292
+
293
+ exports.WorkbookHistoryManager = WorkbookHistoryManager;
294
+ //# sourceMappingURL=workbook-history-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/managers/workbook-history-manager.ts"],"names":[],"mappings":"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","file":"workbook-history-manager.js","sourcesContent":["import type VTableSheet from '../components/vtable-sheet';\nimport type { ISheetDefine } from '../ts-types';\nimport { replayCommand } from '@visactor/vtable-plugins';\nimport type { HistoryTransaction } from '@visactor/vtable-plugins';\n\n// 工作簿层撤销/恢复管理器:负责跨 sheet 的结构操作历史,并将单 sheet 的表格编辑(HistoryTransaction)统一纳入工作簿事务。\ntype WorkbookHistoryCommand =\n | {\n type: 'table_tx';\n sheetKey: string;\n tx: HistoryTransaction;\n }\n | {\n type: 'sheet_add';\n sheet: ISheetDefine;\n orderBefore: string[];\n orderAfter: string[];\n activeBefore: string | undefined;\n activeAfter: string | undefined;\n }\n | {\n type: 'sheet_remove';\n sheet: ISheetDefine;\n orderBefore: string[];\n orderAfter: string[];\n activeBefore: string | undefined;\n activeAfter: string | undefined;\n }\n | {\n type: 'sheet_rename';\n sheetKey: string;\n oldTitle: string;\n newTitle: string;\n }\n | {\n type: 'sheet_reorder';\n orderBefore: string[];\n orderAfter: string[];\n };\n\ntype WorkbookHistoryTx = { commands: WorkbookHistoryCommand[] };\n\nfunction cloneJson<T>(input: T): T {\n return JSON.parse(JSON.stringify(input)) as T;\n}\n\nfunction cloneSafe<T>(input: T): T {\n // table_tx 内部对象可能被后续编辑污染,入栈时做深拷贝,确保 undo/redo 回放是稳定的快照。\n const sc = (globalThis as any).structuredClone as ((v: any) => any) | undefined;\n if (typeof sc === 'function') {\n try {\n return sc(input);\n } catch {}\n }\n return cloneJson(input);\n}\n\nexport class WorkbookHistoryManager {\n private sheet: VTableSheet;\n private undoStack: WorkbookHistoryTx[] = [];\n private redoStack: WorkbookHistoryTx[] = [];\n private currentTransaction: WorkbookHistoryTx | null = null;\n private maxHistory: number;\n private enabled = true;\n isReplaying = false;\n private changeListeners: Set<() => void> = new Set();\n\n constructor(sheet: VTableSheet, options?: { maxHistory?: number }) {\n this.sheet = sheet;\n this.maxHistory = options?.maxHistory ?? 100;\n }\n\n canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n onChange(listener: () => void): () => void {\n this.changeListeners.add(listener);\n return () => {\n this.changeListeners.delete(listener);\n };\n }\n\n private emitChange(): void {\n this.changeListeners.forEach(fn => {\n try {\n fn();\n } catch {}\n });\n }\n\n suspend(): void {\n this.enabled = false;\n }\n\n resume(): void {\n this.enabled = true;\n }\n\n startTransaction(): void {\n if (this.currentTransaction) {\n return;\n }\n this.currentTransaction = { commands: [] };\n }\n\n endTransaction(): void {\n if (!this.currentTransaction || this.currentTransaction.commands.length === 0) {\n this.currentTransaction = null;\n return;\n }\n this.pushTransaction(this.currentTransaction);\n this.currentTransaction = null;\n }\n\n clear(): void {\n this.undoStack = [];\n this.redoStack = [];\n this.currentTransaction = null;\n this.emitChange();\n }\n\n updateOptions(options: { maxHistory?: number }): void {\n if (options.maxHistory != null) {\n this.maxHistory = options.maxHistory;\n this.trimHistory();\n this.emitChange();\n }\n }\n\n undo(): void {\n if (this.undoStack.length === 0) {\n return;\n }\n const tx = this.undoStack.pop()!;\n this.isReplaying = true;\n // 回放期间置标,HistoryPlugin 会跳过事件采集,避免回放回流导致历史栈污染。\n (this.sheet as any).__workbookHistoryReplaying = true;\n try {\n for (let i = tx.commands.length - 1; i >= 0; i--) {\n this.applyCommand(tx.commands[i], 'undo');\n }\n } finally {\n this.isReplaying = false;\n (this.sheet as any).__workbookHistoryReplaying = false;\n }\n this.redoStack.push(tx);\n this.emitChange();\n }\n\n redo(): void {\n if (this.redoStack.length === 0) {\n return;\n }\n const tx = this.redoStack.pop()!;\n this.isReplaying = true;\n (this.sheet as any).__workbookHistoryReplaying = true;\n try {\n for (const cmd of tx.commands) {\n this.applyCommand(cmd, 'redo');\n }\n } finally {\n this.isReplaying = false;\n (this.sheet as any).__workbookHistoryReplaying = false;\n }\n this.undoStack.push(tx);\n this.emitChange();\n }\n\n recordTableTransaction(args: { sheetKey?: string; tx: HistoryTransaction }): void {\n if (!this.enabled || this.isReplaying) {\n return;\n }\n const sheetKey = args.sheetKey ?? this.getActiveSheetKey();\n if (!sheetKey) {\n return;\n }\n const cmd: WorkbookHistoryCommand = {\n type: 'table_tx',\n sheetKey,\n tx: cloneSafe(args.tx)\n };\n this.pushCommand(cmd);\n }\n\n addSheet(args: { sheet: ISheetDefine; activate?: boolean }): void {\n if (!this.enabled || this.isReplaying) {\n this.addSheetInternal(args.sheet, args.activate);\n return;\n }\n const orderBefore = this.getSheetOrder();\n const activeBefore = this.getActiveSheetKey();\n this.startTransaction();\n try {\n this.addSheetInternal(args.sheet, args.activate);\n const orderAfter = this.getSheetOrder();\n const activeAfter = this.getActiveSheetKey();\n const cmd: WorkbookHistoryCommand = {\n type: 'sheet_add',\n sheet: cloneSafe(args.sheet),\n orderBefore,\n orderAfter,\n activeBefore,\n activeAfter\n };\n this.pushCommand(cmd);\n } finally {\n this.endTransaction();\n }\n }\n\n removeSheet(sheetKey: string): void {\n if (!this.enabled || this.isReplaying) {\n this.removeSheetInternal(sheetKey);\n return;\n }\n const sheetDefine = this.sheet.getSheetManager().getSheet(sheetKey);\n if (!sheetDefine) {\n return;\n }\n const orderBefore = this.getSheetOrder();\n const activeBefore = this.getActiveSheetKey();\n this.startTransaction();\n try {\n this.removeSheetInternal(sheetKey);\n const orderAfter = this.getSheetOrder();\n const activeAfter = this.getActiveSheetKey();\n const cmd: WorkbookHistoryCommand = {\n type: 'sheet_remove',\n sheet: cloneSafe(sheetDefine),\n orderBefore,\n orderAfter,\n activeBefore,\n activeAfter\n };\n this.pushCommand(cmd);\n } finally {\n this.endTransaction();\n }\n }\n\n renameSheet(sheetKey: string, newTitle: string): void {\n const sheetDefine = this.sheet.getSheetManager().getSheet(sheetKey);\n if (!sheetDefine) {\n return;\n }\n const oldTitle = sheetDefine.sheetTitle;\n if (!this.enabled || this.isReplaying) {\n this.renameSheetInternal(sheetKey, newTitle);\n return;\n }\n this.startTransaction();\n try {\n this.renameSheetInternal(sheetKey, newTitle);\n const cmd: WorkbookHistoryCommand = { type: 'sheet_rename', sheetKey, oldTitle, newTitle };\n this.pushCommand(cmd);\n } finally {\n this.endTransaction();\n }\n }\n\n reorderSheet(sourceKey: string, targetKey: string, position: 'left' | 'right'): void {\n if (!this.enabled || this.isReplaying) {\n this.sheet.getSheetManager().reorderSheet(sourceKey, targetKey, position);\n this.sheet.updateSheetTabs();\n this.sheet.updateSheetMenu();\n return;\n }\n const orderBefore = this.getSheetOrder();\n this.startTransaction();\n try {\n this.sheet.getSheetManager().reorderSheet(sourceKey, targetKey, position);\n this.sheet.updateSheetTabs();\n this.sheet.updateSheetMenu();\n const orderAfter = this.getSheetOrder();\n const cmd: WorkbookHistoryCommand = { type: 'sheet_reorder', orderBefore, orderAfter };\n this.pushCommand(cmd);\n } finally {\n this.endTransaction();\n }\n }\n\n private pushTransaction(tx: WorkbookHistoryTx): void {\n if (!tx.commands.length) {\n return;\n }\n this.undoStack.push(tx);\n this.redoStack = [];\n this.trimHistory();\n this.emitChange();\n }\n\n private pushCommand(cmd: WorkbookHistoryCommand): void {\n if (this.currentTransaction) {\n this.currentTransaction.commands.push(cmd);\n return;\n }\n this.pushTransaction({ commands: [cmd] });\n }\n\n private trimHistory(): void {\n if (this.undoStack.length > this.maxHistory) {\n this.undoStack.splice(0, this.undoStack.length - this.maxHistory);\n }\n }\n\n private applyCommand(cmd: WorkbookHistoryCommand, direction: 'undo' | 'redo'): void {\n switch (cmd.type) {\n case 'sheet_add': {\n if (direction === 'undo') {\n this.removeSheetInternal(cmd.sheet.sheetKey);\n this.setSheetOrder(cmd.orderBefore);\n if (cmd.activeBefore) {\n this.sheet.activateSheet(cmd.activeBefore);\n }\n } else {\n this.addSheetInternal(cmd.sheet, false);\n this.setSheetOrder(cmd.orderAfter);\n if (cmd.activeAfter) {\n this.sheet.activateSheet(cmd.activeAfter);\n }\n }\n break;\n }\n case 'sheet_remove': {\n if (direction === 'undo') {\n this.addSheetInternal(cmd.sheet, false);\n this.setSheetOrder(cmd.orderBefore);\n if (!this.sheet.getWorkSheetInstance(cmd.sheet.sheetKey)) {\n const restored = this.sheet.createWorkSheetInstance(cmd.sheet);\n restored.getElement().style.display = 'none';\n this.sheet.setWorkSheetInstance(cmd.sheet.sheetKey, restored);\n }\n if (cmd.activeBefore) {\n this.sheet.activateSheet(cmd.activeBefore);\n }\n } else {\n this.removeSheetInternal(cmd.sheet.sheetKey);\n this.setSheetOrder(cmd.orderAfter);\n if (cmd.activeAfter) {\n this.sheet.activateSheet(cmd.activeAfter);\n }\n }\n break;\n }\n case 'sheet_rename': {\n const nextTitle = direction === 'undo' ? cmd.oldTitle : cmd.newTitle;\n this.renameSheetInternal(cmd.sheetKey, nextTitle);\n break;\n }\n case 'sheet_reorder': {\n this.setSheetOrder(direction === 'undo' ? cmd.orderBefore : cmd.orderAfter);\n break;\n }\n case 'table_tx': {\n this.applyTableTransaction(cmd.sheetKey, cmd.tx, direction);\n break;\n }\n default:\n break;\n }\n }\n\n private addSheetInternal(sheetDefine: ISheetDefine, activate?: boolean): void {\n this.sheet.getSheetManager().addSheet(sheetDefine);\n if (activate) {\n this.sheet.activateSheet(sheetDefine.sheetKey);\n } else {\n this.sheet.updateSheetTabs();\n this.sheet.updateSheetMenu();\n }\n }\n\n private removeSheetInternal(sheetKey: string): void {\n const instance = this.sheet.getWorkSheetInstance(sheetKey);\n if (instance) {\n instance.release();\n this.sheet.deleteWorkSheetInstance(sheetKey);\n }\n\n const active = this.getActiveSheetKey();\n const newActiveSheetKey = this.sheet.getSheetManager().removeSheet(sheetKey);\n try {\n this.sheet.getFormulaManager().removeSheet(sheetKey);\n } catch {}\n\n if (newActiveSheetKey && newActiveSheetKey !== active) {\n this.sheet.activateSheet(newActiveSheetKey);\n }\n this.sheet.updateSheetTabs();\n this.sheet.updateSheetMenu();\n }\n\n private renameSheetInternal(sheetKey: string, newTitle: string): void {\n this.sheet.getSheetManager().renameSheet(sheetKey, newTitle);\n this.sheet.getWorkSheetInstance(sheetKey)?.setTitle(newTitle);\n this.sheet.getFormulaManager().updateSheetTitle(sheetKey, newTitle);\n this.sheet.updateSheetTabs();\n this.sheet.updateSheetMenu();\n }\n\n private applyTableTransaction(sheetKey: string, tx: HistoryTransaction, direction: 'undo' | 'redo'): void {\n const ws = this.ensureWorkSheetInstance(sheetKey);\n // 用户可能已经切换到其他 sheet;当撤销/恢复的目标 transaction 属于另一个 sheet 时,先切回对应 sheet 再回放更符合预期。\n if (ws && this.getActiveSheetKey() !== sheetKey) {\n this.sheet.activateSheet(sheetKey);\n }\n const table: any = ws?.tableInstance;\n if (!table) {\n return;\n }\n const vtableSheet: any = this.sheet as any;\n const apply = (cmd: any, dir: 'undo' | 'redo') => {\n replayCommand({\n table,\n vtableSheet,\n cmd,\n direction: dir,\n deleteRecordsByReference: (records: any[]) => {\n const tableRecords = (table.records || []) as any[];\n const indexs: number[] = [];\n records.forEach(rec => {\n const idx = tableRecords.indexOf(rec);\n if (idx >= 0) {\n indexs.push(idx);\n }\n });\n if (indexs.length && table.deleteRecords) {\n table.deleteRecords(indexs);\n }\n }\n });\n };\n\n if (direction === 'undo') {\n for (let i = tx.commands.length - 1; i >= 0; i--) {\n apply(tx.commands[i], 'undo');\n }\n } else {\n for (let i = 0; i < tx.commands.length; i++) {\n apply(tx.commands[i], 'redo');\n }\n }\n }\n\n private ensureWorkSheetInstance(sheetKey: string): any {\n const existing = this.sheet.getWorkSheetInstance(sheetKey);\n if (existing) {\n return existing;\n }\n const def = this.sheet.getSheetManager().getSheet(sheetKey);\n if (!def) {\n return undefined;\n }\n const instance = this.sheet.createWorkSheetInstance(def);\n instance.getElement().style.display = 'none';\n this.sheet.setWorkSheetInstance(sheetKey, instance);\n return instance;\n }\n\n private getSheetOrder(): string[] {\n return this.sheet\n .getSheetManager()\n .getAllSheets()\n .map(s => s.sheetKey);\n }\n\n private setSheetOrder(order: string[]): void {\n const all = this.sheet.getSheetManager().getAllSheets();\n const map = new Map(all.map(s => [s.sheetKey, s] as const));\n const next: ISheetDefine[] = [];\n order.forEach(key => {\n const s = map.get(key);\n if (s) {\n next.push(s);\n }\n });\n if (next.length === all.length) {\n this.sheet.getSheetManager().sortSheets(next);\n this.sheet.updateSheetTabs();\n this.sheet.updateSheetMenu();\n }\n }\n\n private getActiveSheetKey(): string | undefined {\n return this.sheet.getSheetManager().getActiveSheet()?.sheetKey;\n }\n}\n"]}